LCOV - code coverage report
Current view: top level - src/userobjects - GeometricCut2DUserObject.C (source / functions) Hit Total Coverage
Test: idaholab/moose xfem: #31405 (292dce) with base fef103 Lines: 56 65 86.2 %
Date: 2025-09-04 07:58:55 Functions: 5 7 71.4 %
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 "GeometricCut2DUserObject.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         416 : GeometricCut2DUserObject::validParams()
      22             : {
      23         416 :   InputParameters params = GeometricCutUserObject::validParams();
      24         832 :   params.addParam<Real>("time_start_cut", 0.0, "Start time of geometric cut propagation");
      25         832 :   params.addParam<Real>("time_end_cut", 0.0, "End time of geometric cut propagation");
      26         416 :   params.addClassDescription("Base class for 2D XFEM Geometric Cut UserObjects");
      27         416 :   return params;
      28           0 : }
      29             : 
      30         208 : GeometricCut2DUserObject::GeometricCut2DUserObject(const InputParameters & parameters)
      31         208 :   : GeometricCutUserObject(parameters), _cut_line_endpoints(), _cut_time_ranges()
      32             : {
      33         208 :   _cut_time_ranges.push_back(
      34         832 :       std::make_pair(getParam<Real>("time_start_cut"), getParam<Real>("time_end_cut")));
      35         208 : }
      36             : 
      37             : bool
      38       46000 : GeometricCut2DUserObject::cutElementByGeometry(const Elem * elem,
      39             :                                                std::vector<Xfem::CutEdge> & cut_edges,
      40             :                                                std::vector<Xfem::CutNode> & cut_nodes) const
      41             : {
      42             :   bool cut_elem = false;
      43             : 
      44      105644 :   for (unsigned int cut = 0; cut < _cut_line_endpoints.size(); ++cut)
      45             :   {
      46       59644 :     Real fraction = cutFraction(cut);
      47             : 
      48       59644 :     if (fraction > 0.0)
      49             :     {
      50       47630 :       unsigned int n_sides = elem->n_sides();
      51             : 
      52      221080 :       for (unsigned int i = 0; i < n_sides; ++i)
      53             :       {
      54             :         // This returns the lowest-order type of side, which should always
      55             :         // be an EDGE2 here because this class is for 2D only.
      56      173450 :         std::unique_ptr<const Elem> curr_side = elem->side_ptr(i);
      57      173450 :         if (curr_side->type() != EDGE2)
      58           0 :           mooseError("In cutElementByGeometry element side must be EDGE2, but type is: ",
      59           0 :                      libMesh::Utility::enum_to_string(curr_side->type()),
      60             :                      " base element type is: ",
      61           0 :                      libMesh::Utility::enum_to_string(elem->type()));
      62             : 
      63             :         const Node * node1 = curr_side->node_ptr(0);
      64             :         const Node * node2 = curr_side->node_ptr(1);
      65      173450 :         Real seg_int_frac = 0.0;
      66             : 
      67      173450 :         if (Xfem::intersectSegmentWithCutLine(
      68             :                 *node1, *node2, _cut_line_endpoints[cut], fraction, seg_int_frac))
      69             :         {
      70       14045 :           if (seg_int_frac > Xfem::tol && seg_int_frac < 1.0 - Xfem::tol)
      71             :           {
      72             :             cut_elem = true;
      73             :             Xfem::CutEdge mycut;
      74       13508 :             mycut._id1 = node1->id();
      75       13508 :             mycut._id2 = node2->id();
      76       13508 :             mycut._distance = seg_int_frac;
      77       13508 :             mycut._host_side_id = i;
      78       13508 :             cut_edges.push_back(mycut);
      79       13508 :           }
      80         537 :           else if (seg_int_frac < Xfem::tol)
      81             :           {
      82             :             cut_elem = true;
      83             :             Xfem::CutNode mycut;
      84         270 :             mycut._id = node1->id();
      85         270 :             mycut._host_id = i;
      86         270 :             cut_nodes.push_back(mycut);
      87             :           }
      88             :         }
      89      173450 :       }
      90             :     }
      91             :   }
      92       46000 :   return cut_elem;
      93             : }
      94             : 
      95             : bool
      96           0 : GeometricCut2DUserObject::cutElementByGeometry(const Elem * /*elem*/,
      97             :                                                std::vector<Xfem::CutFace> & /*cut_faces*/) const
      98             : {
      99           0 :   mooseError("Invalid method: must use vector of element edges for 2D mesh cutting");
     100             :   return false;
     101             : }
     102             : 
     103             : bool
     104        7537 : GeometricCut2DUserObject::cutFragmentByGeometry(std::vector<std::vector<Point>> & frag_edges,
     105             :                                                 std::vector<Xfem::CutEdge> & cut_edges) const
     106             : {
     107             :   bool cut_frag = false;
     108             : 
     109       17582 :   for (unsigned int cut = 0; cut < _cut_line_endpoints.size(); ++cut)
     110             :   {
     111       10045 :     Real fraction = cutFraction(cut);
     112             : 
     113       10045 :     if (fraction > 0.0)
     114             :     {
     115        9343 :       unsigned int n_sides = frag_edges.size();
     116             : 
     117       44720 :       for (unsigned int i = 0; i < n_sides; ++i)
     118             :       {
     119       35377 :         Real seg_int_frac = 0.0;
     120             : 
     121       35377 :         if (Xfem::intersectSegmentWithCutLine(frag_edges[i][0],
     122       35377 :                                               frag_edges[i][1],
     123             :                                               _cut_line_endpoints[cut],
     124             :                                               fraction,
     125             :                                               seg_int_frac))
     126             :         {
     127             :           cut_frag = true;
     128             :           Xfem::CutEdge mycut;
     129        9894 :           mycut._id1 = i;
     130        9894 :           mycut._id2 = (i < (n_sides - 1) ? (i + 1) : 0);
     131        9894 :           mycut._distance = seg_int_frac;
     132        9894 :           mycut._host_side_id = i;
     133        9894 :           cut_edges.push_back(mycut);
     134             :         }
     135             :       }
     136             :     }
     137             :   }
     138        7537 :   return cut_frag;
     139             : }
     140             : 
     141             : bool
     142           0 : GeometricCut2DUserObject::cutFragmentByGeometry(std::vector<std::vector<Point>> & /*frag_faces*/,
     143             :                                                 std::vector<Xfem::CutFace> & /*cut_faces*/) const
     144             : {
     145           0 :   mooseError("Invalid method: must use vector of element edges for 2D mesh cutting");
     146             :   return false;
     147             : }
     148             : 
     149             : Real
     150       69689 : GeometricCut2DUserObject::cutFraction(unsigned int cut_num) const
     151             : {
     152             :   mooseAssert(_cut_time_ranges.size() > cut_num,
     153             :               "cut_num is outside the bounds of _cut_time_ranges");
     154             : 
     155             :   Real fraction = 0.0;
     156             : 
     157       69689 :   if (_t >= _cut_time_ranges[cut_num].first)
     158             :   {
     159       66842 :     if (_t >= _cut_time_ranges[cut_num].second)
     160             :       fraction = 1.0;
     161             :     else
     162             :     {
     163       13271 :       Real denominator = _cut_time_ranges[cut_num].second - _cut_time_ranges[cut_num].first;
     164       13271 :       if (MooseUtils::absoluteFuzzyEqual(denominator, 0.0))
     165           0 :         mooseError("time_start_cut and time_end_cut cannot have the same value");
     166       13271 :       fraction = (_t - _cut_time_ranges[cut_num].first) / denominator;
     167             :     }
     168             :   }
     169       69689 :   return fraction;
     170             : }

Generated by: LCOV version 1.14