LCOV - code coverage report
Current view: top level - src/userobjects - ComboCutUserObject.C (source / functions) Hit Total Coverage
Test: idaholab/moose xfem: #31405 (292dce) with base fef103 Lines: 42 66 63.6 %
Date: 2025-09-04 07:58:55 Functions: 6 8 75.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 "ComboCutUserObject.h"
      11             : 
      12             : registerMooseObject("XFEMApp", ComboCutUserObject);
      13             : 
      14             : InputParameters
      15          16 : ComboCutUserObject::validParams()
      16             : {
      17          16 :   InputParameters params = GeometricCutUserObject::validParams();
      18          16 :   params.addClassDescription("Combine multiple geometric cut userobjects.");
      19          32 :   params.addRequiredParam<std::vector<UserObjectName>>(
      20             :       "geometric_cut_userobjects", "Vector of geometric cut userobjects to combine");
      21          32 :   params.addRequiredParam<std::vector<std::vector<CutSubdomainID>>>(
      22             :       "cut_subdomain_combinations",
      23             :       "Possible combinations of the cut subdomain IDs. The sequence of each combination should "
      24             :       "follow the sequence provided in the geometric_cut_userobjects parameter. Use semicolons to "
      25             :       "separate different combinations.");
      26          32 :   params.addRequiredParam<std::vector<CutSubdomainID>>(
      27             :       "cut_subdomains", "Resulting combined cut subdomain IDs for each of the combination.");
      28             : 
      29          16 :   return params;
      30           0 : }
      31             : 
      32           8 : ComboCutUserObject::ComboCutUserObject(const InputParameters & parameters)
      33             :   : GeometricCutUserObject(parameters),
      34          16 :     _cut_names(getParam<std::vector<UserObjectName>>("geometric_cut_userobjects")),
      35           8 :     _num_cuts(_cut_names.size()),
      36           8 :     _cuts(_num_cuts),
      37          16 :     _keys(getParam<std::vector<std::vector<CutSubdomainID>>>("cut_subdomain_combinations")),
      38          32 :     _vals(getParam<std::vector<CutSubdomainID>>("cut_subdomains"))
      39             : {
      40          24 :   for (unsigned int i = 0; i < _num_cuts; i++)
      41          16 :     _cuts[i] = &getUserObjectByName<GeometricCutUserObject>(_cut_names[i]);
      42             : 
      43           8 :   buildMap();
      44           8 : }
      45             : 
      46             : void
      47           8 : ComboCutUserObject::buildMap()
      48             : {
      49          40 :   for (const auto & combo : _keys)
      50          32 :     if (combo.size() != _num_cuts)
      51           0 :       mooseError("Expected multiples of ", _num_cuts, " keys, but got ", combo.size(), " keys.");
      52             : 
      53           8 :   unsigned int num_combos = _keys.size();
      54             : 
      55           8 :   if (_vals.size() != num_combos)
      56           0 :     mooseError("Expected one value for each of the combination, got ",
      57             :                num_combos,
      58             :                " combinations, but got ",
      59           0 :                _vals.size(),
      60             :                " values.");
      61             : 
      62          40 :   for (unsigned int i = 0; i < num_combos; i++)
      63          32 :     _combo_ids.emplace(_keys[i], _vals[i]);
      64           8 : }
      65             : 
      66             : bool
      67         405 : ComboCutUserObject::cutElementByGeometry(const Elem * elem,
      68             :                                          std::vector<Xfem::CutEdge> & cut_edges,
      69             :                                          std::vector<Xfem::CutNode> & cut_nodes) const
      70             : {
      71             :   unsigned int i_want_to_cut = 0;
      72        1215 :   for (auto cut : _cuts)
      73         810 :     if (cut->cutElementByGeometry(elem, cut_edges, cut_nodes))
      74         150 :       i_want_to_cut++;
      75             : 
      76             :   // TODO: Currently we error out if more than one cut userobject wants to do the cutting. We need
      77             :   // to remove this limitation once we add the ability to handle multiple cuts.
      78         405 :   if (i_want_to_cut > 1)
      79           0 :     mooseError("More than one GeometricCutUserObject want to cut the same element.");
      80             : 
      81         405 :   return i_want_to_cut > 0;
      82             : }
      83             : 
      84             : bool
      85           0 : ComboCutUserObject::cutElementByGeometry(const Elem * elem,
      86             :                                          std::vector<Xfem::CutFace> & cut_faces) const
      87             : {
      88             :   unsigned int i_want_to_cut = 0;
      89           0 :   for (auto cut : _cuts)
      90           0 :     if (cut->cutElementByGeometry(elem, cut_faces))
      91           0 :       i_want_to_cut++;
      92             : 
      93             :   // TODO: Currently we error out if more than one cut userobject wants to do the cutting. We need
      94             :   // to remove this limitation once we add the ability to handle multiple cuts.
      95           0 :   if (i_want_to_cut > 1)
      96           0 :     mooseError("More than one GeometricCutUserObject want to cut the same element.");
      97             : 
      98           0 :   return i_want_to_cut > 0;
      99             : }
     100             : 
     101             : bool
     102          60 : ComboCutUserObject::cutFragmentByGeometry(std::vector<std::vector<Point>> & frag_edges,
     103             :                                           std::vector<Xfem::CutEdge> & cut_edges) const
     104             : {
     105             :   unsigned int i_want_to_cut = 0;
     106         180 :   for (auto cut : _cuts)
     107         120 :     if (cut->cutFragmentByGeometry(frag_edges, cut_edges))
     108           0 :       i_want_to_cut++;
     109             : 
     110             :   // TODO: Currently we error out if more than one cut userobject wants to do the cutting. We need
     111             :   // to remove this limitation once we add the ability to handle multiple cuts.
     112          60 :   if (i_want_to_cut > 1)
     113           0 :     mooseError("More than one GeometricCutUserObject want to cut the same fragment.");
     114             : 
     115          60 :   return i_want_to_cut > 0;
     116             : }
     117             : 
     118             : bool
     119           0 : ComboCutUserObject::cutFragmentByGeometry(std::vector<std::vector<Point>> & frag_faces,
     120             :                                           std::vector<Xfem::CutFace> & cut_faces) const
     121             : {
     122             :   unsigned int i_want_to_cut = 0;
     123           0 :   for (auto cut : _cuts)
     124           0 :     if (cut->cutFragmentByGeometry(frag_faces, cut_faces))
     125           0 :       i_want_to_cut++;
     126             : 
     127             :   // TODO: Currently we error out if more than one cut userobject wants to do the cutting. We need
     128             :   // to remove this limitation once we add the ability to handle multiple cuts.
     129           0 :   if (i_want_to_cut > 1)
     130           0 :     mooseError("More than one GeometricCutUserObject want to cut the same fragment.");
     131             : 
     132           0 :   return i_want_to_cut > 0;
     133             : }
     134             : 
     135             : CutSubdomainID
     136        1890 : ComboCutUserObject::getCutSubdomainID(const Node * node) const
     137             : {
     138             :   std::vector<CutSubdomainID> combo_key;
     139        5670 :   for (auto cut : _cuts)
     140        3780 :     combo_key.push_back(cut->getCutSubdomainID(node));
     141             : 
     142             :   try
     143             :   {
     144        1890 :     CutSubdomainID combo_id = _combo_ids.at(combo_key);
     145        1890 :     return combo_id;
     146             :   }
     147           0 :   catch (std::out_of_range &)
     148             :   {
     149           0 :     throw MooseException(name() + ": Unknown cut subdomain combination.");
     150           0 :   }
     151        1890 : }

Generated by: LCOV version 1.14