LCOV - code coverage report
Current view: top level - src/userobjects - CircleCutUserObject.C (source / functions) Hit Total Coverage
Test: idaholab/moose xfem: #31405 (292dce) with base fef103 Lines: 30 35 85.7 %
Date: 2025-09-04 07:58:55 Functions: 4 5 80.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #include "CircleCutUserObject.h"
      11             : 
      12             : // MOOSE includes
      13             : #include "MooseError.h"
      14             : 
      15             : // XFEM includes
      16             : #include "XFEMFuncs.h"
      17             : 
      18             : registerMooseObject("XFEMApp", CircleCutUserObject);
      19             : 
      20             : InputParameters
      21          16 : CircleCutUserObject::validParams()
      22             : {
      23             :   // Get input parameters from parent class
      24          16 :   InputParameters params = GeometricCut3DUserObject::validParams();
      25             : 
      26             :   // Add required parameters
      27          32 :   params.addRequiredParam<std::vector<Real>>("cut_data",
      28             :                                              "Vector of Real values providing cut information");
      29             :   // Class description
      30          16 :   params.addClassDescription("Creates a UserObject for circular cuts on 3D meshes for XFEM");
      31             :   // Return the parameters
      32          16 :   return params;
      33           0 : }
      34             : 
      35           8 : CircleCutUserObject::CircleCutUserObject(const InputParameters & parameters)
      36          24 :   : GeometricCut3DUserObject(parameters), _cut_data(getParam<std::vector<Real>>("cut_data"))
      37             : {
      38             :   // Set up constant parameters
      39             :   const int cut_data_len = 9;
      40             : 
      41             :   // Throw error if length of cut_data is incorrect
      42           8 :   if (_cut_data.size() != cut_data_len)
      43           0 :     mooseError("Length of CircleCutUserObject cut_data must be 9");
      44             : 
      45             :   // Assign cut_data to vars used to construct cuts
      46           8 :   _center = Point(_cut_data[0], _cut_data[1], _cut_data[2]);
      47           8 :   _vertices.push_back(Point(_cut_data[3], _cut_data[4], _cut_data[5]));
      48           8 :   _vertices.push_back(Point(_cut_data[6], _cut_data[7], _cut_data[8]));
      49             : 
      50             :   std::pair<Point, Point> rays = std::make_pair(_vertices[0] - _center, _vertices[1] - _center);
      51             : 
      52           8 :   _normal = rays.first.cross(rays.second);
      53           8 :   Xfem::normalizePoint(_normal);
      54             : 
      55             :   std::pair<Real, Real> ray_radii =
      56           8 :       std::make_pair(std::sqrt(rays.first.norm_sq()), std::sqrt(rays.second.norm_sq()));
      57             : 
      58           8 :   if (std::abs(ray_radii.first - ray_radii.second) > 1e-10)
      59           0 :     mooseError("CircleCutUserObject only works for a circular cut");
      60             : 
      61           8 :   _radius = 0.5 * (ray_radii.first + ray_radii.second);
      62           8 :   _angle = std::acos((rays.first * rays.second) / (ray_radii.first * ray_radii.second));
      63           8 : }
      64             : 
      65             : bool
      66        7840 : CircleCutUserObject::isInsideCutPlane(Point p) const
      67             : {
      68             :   Point ray = p - _center;
      69        7840 :   if (std::abs(ray * _normal) < 1e-15 && std::sqrt(ray.norm_sq()) < _radius)
      70             :     return true;
      71             :   return false;
      72             : }
      73             : 
      74             : const std::vector<Point>
      75           4 : CircleCutUserObject::getCrackFrontPoints(unsigned int number_crack_front_points) const
      76             : {
      77           4 :   std::vector<Point> crack_front_points(number_crack_front_points);
      78             :   Point v1 = _vertices[0] - _center;
      79           4 :   Point v2 = _normal.cross(v1);
      80           4 :   v1 /= v1.norm();
      81           4 :   v2 /= v2.norm();
      82             :   // parametric circle in 3D: center + r * cos(theta) * v1 + r * sin(theta) * v2
      83          44 :   for (unsigned int i = 0; i < number_crack_front_points; ++i)
      84             :   {
      85          40 :     Real theta = 2.0 * libMesh::pi / number_crack_front_points * i;
      86          40 :     crack_front_points[i] =
      87          40 :         _center + _radius * std::cos(theta) * v1 + _radius * std::sin(theta) * v2;
      88             :   }
      89             : 
      90           4 :   return crack_front_points;
      91             : }
      92             : 
      93             : const std::vector<RealVectorValue>
      94           0 : CircleCutUserObject::getCrackPlaneNormals(unsigned int /*num_crack_front_points*/) const
      95             : {
      96           0 :   mooseError("getCrackPlaneNormals() is not implemented for this object.");
      97             : }

Generated by: LCOV version 1.14