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 : }