LCOV - code coverage report
Current view: top level - src/userobjects - GeometricCut3DUserObject.C (source / functions) Hit Total Coverage
Test: idaholab/moose xfem: #31405 (292dce) with base fef103 Lines: 45 57 78.9 %
Date: 2025-09-04 07:58:55 Functions: 6 9 66.7 %
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 "GeometricCut3DUserObject.h"
      11             : 
      12             : // MOOSE includes
      13             : #include "MooseError.h"
      14             : 
      15             : #include "libmesh/string_to_enum.h"
      16             : 
      17             : // XFEM includes
      18             : #include "XFEMFuncs.h"
      19             : 
      20             : InputParameters
      21         112 : GeometricCut3DUserObject::validParams()
      22             : {
      23         112 :   InputParameters params = GeometricCutUserObject::validParams();
      24         112 :   params.addClassDescription("Base class for 3D XFEM Geometric Cut UserObjects");
      25         112 :   return params;
      26           0 : }
      27             : 
      28          56 : GeometricCut3DUserObject::GeometricCut3DUserObject(const InputParameters & parameters)
      29          56 :   : GeometricCutUserObject(parameters), _center(), _normal()
      30             : {
      31          56 : }
      32             : 
      33             : bool
      34           0 : GeometricCut3DUserObject::cutElementByGeometry(const Elem * /*elem*/,
      35             :                                                std::vector<Xfem::CutEdge> & /*cut_edges*/,
      36             :                                                std::vector<Xfem::CutNode> & /*cut_nodes*/) const
      37             : {
      38           0 :   mooseError("Invalid method: must use vector of element faces for 3D mesh cutting");
      39             :   return false;
      40             : }
      41             : 
      42             : bool
      43       16956 : GeometricCut3DUserObject::cutElementByGeometry(const Elem * elem,
      44             :                                                std::vector<Xfem::CutFace> & cut_faces) const
      45             : // TODO: Time evolving cuts not yet supported in 3D (hence the lack of use of the time variable)
      46             : {
      47             :   bool cut_elem = false;
      48             : 
      49       97316 :   for (unsigned int i = 0; i < elem->n_sides(); ++i)
      50             :   {
      51             :     // This returns the lowest-order type of side.
      52       80360 :     std::unique_ptr<const Elem> curr_side = elem->side_ptr(i);
      53       80360 :     if (curr_side->dim() != 2)
      54           0 :       mooseError("In cutElementByGeometry dimension of side must be 2, but it is ",
      55           0 :                  curr_side->dim());
      56       80360 :     unsigned int n_edges = curr_side->n_sides();
      57             : 
      58             :     std::vector<unsigned int> cut_edges;
      59             :     std::vector<Real> cut_pos;
      60             : 
      61      359048 :     for (unsigned int j = 0; j < n_edges; j++)
      62             :     {
      63             :       // This returns the lowest-order type of side.
      64      278688 :       std::unique_ptr<const Elem> curr_edge = curr_side->side_ptr(j);
      65      278688 :       if (curr_edge->type() != EDGE2)
      66           0 :         mooseError("In cutElementByGeometry face edge must be EDGE2, but type is: ",
      67           0 :                    libMesh::Utility::enum_to_string(curr_edge->type()),
      68             :                    " base element type is: ",
      69           0 :                    libMesh::Utility::enum_to_string(elem->type()));
      70             :       const Node * node1 = curr_edge->node_ptr(0);
      71             :       const Node * node2 = curr_edge->node_ptr(1);
      72             : 
      73             :       Point intersection;
      74      278688 :       if (intersectWithEdge(*node1, *node2, intersection))
      75             :       {
      76       20804 :         cut_edges.push_back(j);
      77       20804 :         cut_pos.push_back(getRelativePosition(*node1, *node2, intersection));
      78             :       }
      79      278688 :     }
      80             : 
      81       80360 :     if (cut_edges.size() == 2)
      82             :     {
      83             :       cut_elem = true;
      84             :       Xfem::CutFace mycut;
      85       10130 :       mycut._face_id = i;
      86       10130 :       mycut._face_edge.push_back(cut_edges[0]);
      87       10130 :       mycut._face_edge.push_back(cut_edges[1]);
      88       10130 :       mycut._position.push_back(cut_pos[0]);
      89       10130 :       mycut._position.push_back(cut_pos[1]);
      90       10130 :       cut_faces.push_back(mycut);
      91             :     }
      92       80360 :   }
      93             : 
      94       16956 :   return cut_elem;
      95             : }
      96             : 
      97             : bool
      98           0 : GeometricCut3DUserObject::cutFragmentByGeometry(std::vector<std::vector<Point>> & /*frag_edges*/,
      99             :                                                 std::vector<Xfem::CutEdge> & /*cut_edges*/) const
     100             : {
     101           0 :   mooseError("Invalid method: must use vector of element faces for 3D mesh cutting");
     102             :   return false;
     103             : }
     104             : 
     105             : bool
     106           0 : GeometricCut3DUserObject::cutFragmentByGeometry(std::vector<std::vector<Point>> & /*frag_faces*/,
     107             :                                                 std::vector<Xfem::CutFace> & /*cut_faces*/) const
     108             : {
     109             :   // TODO: Need this for branching in 3D
     110           0 :   mooseError("cutFragmentByGeometry not yet implemented for 3D mesh cutting");
     111             :   return false;
     112             : }
     113             : 
     114             : bool
     115      278688 : GeometricCut3DUserObject::intersectWithEdge(const Point & p1, const Point & p2, Point & pint) const
     116             : {
     117             :   bool has_intersection = false;
     118      278688 :   double plane_point[3] = {_center(0), _center(1), _center(2)};
     119      278688 :   double plane_normal[3] = {_normal(0), _normal(1), _normal(2)};
     120      278688 :   double edge_point1[3] = {p1(0), p1(1), p1(2)};
     121      278688 :   double edge_point2[3] = {p2(0), p2(1), p2(2)};
     122      278688 :   double cut_point[3] = {0.0, 0.0, 0.0};
     123             : 
     124      278688 :   if (Xfem::plane_normal_line_exp_int_3d(
     125             :           plane_point, plane_normal, edge_point1, edge_point2, cut_point) == 1)
     126             :   {
     127      141032 :     Point temp_p(cut_point[0], cut_point[1], cut_point[2]);
     128      141032 :     if (isInsideCutPlane(temp_p) && isInsideEdge(p1, p2, temp_p))
     129             :     {
     130       20804 :       pint = temp_p;
     131             :       has_intersection = true;
     132             :     }
     133             :   }
     134      278688 :   return has_intersection;
     135             : }
     136             : 
     137             : bool
     138       69876 : GeometricCut3DUserObject::isInsideEdge(const Point & p1, const Point & p2, const Point & p) const
     139             : {
     140             :   Real dotp1 = (p1 - p) * (p2 - p1);
     141             :   Real dotp2 = (p2 - p) * (p2 - p1);
     142       69876 :   return (dotp1 * dotp2 <= 0.0);
     143             : }
     144             : 
     145             : Real
     146       20804 : GeometricCut3DUserObject::getRelativePosition(const Point & p1,
     147             :                                               const Point & p2,
     148             :                                               const Point & p) const
     149             : {
     150             :   // get the relative position of p from p1
     151       20804 :   Real full_len = (p2 - p1).norm();
     152       20804 :   Real len_p1_p = (p - p1).norm();
     153       20804 :   return len_p1_p / full_len;
     154             : }

Generated by: LCOV version 1.14