LCOV - code coverage report
Current view: top level - src/userobjects - InterfaceMeshCut2DUserObject.C (source / functions) Hit Total Coverage
Test: idaholab/moose xfem: #31405 (292dce) with base fef103 Lines: 64 77 83.1 %
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 "InterfaceMeshCut2DUserObject.h"
      11             : #include "XFEMMovingInterfaceVelocityBase.h"
      12             : 
      13             : registerMooseObject("XFEMApp", InterfaceMeshCut2DUserObject);
      14             : 
      15             : InputParameters
      16          32 : InterfaceMeshCut2DUserObject::validParams()
      17             : {
      18          32 :   InputParameters params = InterfaceMeshCutUserObjectBase::validParams();
      19          32 :   params.addClassDescription("A userobject to cut a 2D mesh using a 1D cutter mesh.");
      20          32 :   return params;
      21           0 : }
      22             : 
      23          16 : InterfaceMeshCut2DUserObject::InterfaceMeshCut2DUserObject(const InputParameters & parameters)
      24          16 :   : InterfaceMeshCutUserObjectBase(parameters)
      25             : {
      26         704 :   for (const auto & elem : _cutter_mesh->element_ptr_range())
      27         336 :     if (elem->type() != EDGE2)
      28           0 :       mooseError(
      29          16 :           "InterfaceMeshCut2DUserObject currently only supports EDGE2 element in the cut mesh.");
      30          16 : }
      31             : 
      32             : void
      33          68 : InterfaceMeshCut2DUserObject::calculateNormals()
      34             : {
      35             :   _element_normals.clear();
      36             : 
      37        1256 :   for (const auto & elem : _cutter_mesh->element_ptr_range())
      38             :   {
      39        1120 :     Point a = elem->node_ref(1);
      40        1120 :     Point b = elem->node_ref(0);
      41             : 
      42        1120 :     Point normal_ab = Point(-(b - a)(1), (b - a)(0), 0);
      43        1120 :     normal_ab /= normal_ab.norm();
      44             : 
      45        1120 :     _element_normals.insert(std::make_pair(elem->id(), normal_ab));
      46          68 :   }
      47          68 : }
      48             : 
      49             : Point
      50        1660 : InterfaceMeshCut2DUserObject::nodeNormal(const unsigned int & node_id)
      51             : {
      52             :   Point normal(0.0);
      53             : 
      54        4860 :   for (const auto & node_neigh_elem_id : _node_to_elem_map[node_id])
      55             :   {
      56        3200 :     const auto & elem = _cutter_mesh->elem_ref(node_neigh_elem_id);
      57             : 
      58        3200 :     Point a = elem.node_ref(1);
      59        3200 :     Point b = elem.node_ref(0);
      60             : 
      61        3200 :     Point normal_ab = Point(-(b - a)(1), (b - a)(0), 0);
      62        3200 :     normal_ab /= normal_ab.norm();
      63             : 
      64             :     normal += normal_ab;
      65             :   }
      66             : 
      67        1660 :   unsigned int num = _node_to_elem_map[node_id].size();
      68             : 
      69        1660 :   if (num == 0)
      70           0 :     mooseError("InterfaceMeshCut2DUserObject, the node is not found in node_to_elem_map in "
      71             :                "calculting its normal.");
      72             : 
      73        1660 :   return normal / num;
      74             : }
      75             : 
      76             : bool
      77        1017 : InterfaceMeshCut2DUserObject::cutElementByGeometry(const Elem * elem,
      78             :                                                    std::vector<Xfem::CutEdge> & cut_edges,
      79             :                                                    std::vector<Xfem::CutNode> & cut_nodes) const
      80             : {
      81             :   mooseAssert(elem->dim() == 2, "Dimension of element to be cut must be 2");
      82             : 
      83             :   bool elem_cut = false;
      84             : 
      85       51642 :   for (const auto & cut_elem : _cutter_mesh->element_ptr_range())
      86             :   {
      87       24804 :     unsigned int n_sides = elem->n_sides();
      88             : 
      89      124020 :     for (unsigned int i = 0; i < n_sides; ++i)
      90             :     {
      91       99216 :       std::unique_ptr<const Elem> curr_side = elem->side_ptr(i);
      92             : 
      93             :       mooseAssert(curr_side->type() == EDGE2, "Element side type must be EDGE2.");
      94             : 
      95             :       const Node * node1 = curr_side->node_ptr(0);
      96             :       const Node * node2 = curr_side->node_ptr(1);
      97       99216 :       Real seg_int_frac = 0.0;
      98             : 
      99       99216 :       const std::pair<Point, Point> elem_endpoints(cut_elem->node_ref(0), cut_elem->node_ref(1));
     100             : 
     101       99216 :       if (Xfem::intersectSegmentWithCutLine(*node1, *node2, elem_endpoints, 1.0, seg_int_frac))
     102             :       {
     103         348 :         if (seg_int_frac > Xfem::tol && seg_int_frac < 1.0 - Xfem::tol)
     104             :         {
     105             :           elem_cut = true;
     106             :           Xfem::CutEdge mycut;
     107         348 :           mycut._id1 = node1->id();
     108         348 :           mycut._id2 = node2->id();
     109         348 :           mycut._distance = seg_int_frac;
     110         348 :           mycut._host_side_id = i;
     111         348 :           cut_edges.push_back(mycut);
     112         348 :         }
     113           0 :         else if (seg_int_frac < Xfem::tol)
     114             :         {
     115             :           elem_cut = true;
     116             :           Xfem::CutNode mycut;
     117           0 :           mycut._id = node1->id();
     118           0 :           mycut._host_id = i;
     119           0 :           cut_nodes.push_back(mycut);
     120             :         }
     121             :       }
     122       99216 :     }
     123        1017 :   }
     124        1017 :   return elem_cut;
     125             : }
     126             : 
     127             : bool
     128           0 : InterfaceMeshCut2DUserObject::cutElementByGeometry(const Elem * /* elem*/,
     129             :                                                    std::vector<Xfem::CutFace> & /*cut_faces*/) const
     130             : {
     131           0 :   mooseError("invalid method for InterfaceMeshCut2DUserObject");
     132             :   return false;
     133             : }
     134             : 
     135             : bool
     136           0 : InterfaceMeshCut2DUserObject::cutFragmentByGeometry(
     137             :     std::vector<std::vector<Point>> & /*frag_edges*/,
     138             :     std::vector<Xfem::CutEdge> & /*cut_edges*/) const
     139             : {
     140           0 :   mooseError("cutFragmentByGeometry not yet implemented for InterfaceMeshCut2DUserObject");
     141             :   return false;
     142             : }
     143             : 
     144             : bool
     145           0 : InterfaceMeshCut2DUserObject::cutFragmentByGeometry(
     146             :     std::vector<std::vector<Point>> & /*frag_faces*/,
     147             :     std::vector<Xfem::CutFace> & /*cut_faces*/) const
     148             : {
     149           0 :   mooseError("invalid method for InterfaceMeshCut2DUserObject");
     150             :   return false;
     151             : }
     152             : 
     153             : Real
     154       42795 : InterfaceMeshCut2DUserObject::calculateSignedDistance(Point p) const
     155             : {
     156             :   Real min_dist = std::numeric_limits<Real>::max();
     157             : 
     158     3206982 :   for (const auto & cut_elem : _cutter_mesh->element_ptr_range())
     159             :   {
     160     1560696 :     Point a = cut_elem->node_ref(0);
     161     1560696 :     Point b = cut_elem->node_ref(1);
     162             : 
     163             :     Point c = p - a;
     164     1560696 :     Point v = (b - a) / (b - a).norm();
     165     1560696 :     Real d = (b - a).norm();
     166             :     Real t = v * c;
     167             : 
     168             :     Real dist;
     169             :     Point nearest_point;
     170             : 
     171     1560696 :     if (t < 0)
     172             :     {
     173      742872 :       dist = (p - a).norm();
     174             :       nearest_point = a;
     175             :     }
     176      817824 :     else if (t > d)
     177             :     {
     178      733968 :       dist = (p - b).norm();
     179             :       nearest_point = b;
     180             :     }
     181             :     else
     182             :     {
     183             :       v *= t;
     184       83856 :       dist = (p - a - v).norm();
     185             :       nearest_point = (a + v);
     186             :     }
     187             : 
     188             :     Point p_nearest_point = nearest_point - p;
     189             : 
     190     1560696 :     Point normal_ab = Point(-(b - a)(1), (b - a)(0), 0);
     191             : 
     192     1560696 :     if (normal_ab * p_nearest_point < 0)
     193     1266774 :       dist = -dist;
     194             : 
     195     1560696 :     if (std::abs(dist) < std::abs(min_dist))
     196             :       min_dist = dist;
     197       42795 :   }
     198             : 
     199       42795 :   return min_dist;
     200             : }

Generated by: LCOV version 1.14