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 "ParsedGenerateSideset.h" 11 : #include "Conversion.h" 12 : #include "MooseMeshUtils.h" 13 : #include "CastUniquePointer.h" 14 : 15 : #include "libmesh/fparser_ad.hh" 16 : #include "libmesh/distributed_mesh.h" 17 : #include "libmesh/elem.h" 18 : #include "libmesh/fe_base.h" 19 : 20 : #include <typeinfo> 21 : 22 : registerMooseObject("MooseApp", ParsedGenerateSideset); 23 : 24 : InputParameters 25 14789 : ParsedGenerateSideset::validParams() 26 : { 27 14789 : InputParameters params = SideSetsGeneratorBase::validParams(); 28 14789 : params += FunctionParserUtils<false>::validParams(); 29 : 30 14789 : params.addRequiredParam<std::string>("combinatorial_geometry", 31 : "Function expression encoding a combinatorial geometry"); 32 14789 : params.addRequiredParam<BoundaryName>("new_sideset_name", "The name of the new sideset"); 33 : 34 14789 : params.addParam<std::vector<std::string>>( 35 : "constant_names", {}, "Vector of constants used in the parsed function"); 36 14789 : params.addParam<std::vector<std::string>>( 37 : "constant_expressions", 38 : {}, 39 : "Vector of values for the constants in constant_names (can be an FParser expression)"); 40 : 41 : // This sideset generator can only handle a single new sideset name, not a vector of names 42 14789 : params.suppressParameter<std::vector<BoundaryName>>("new_boundary"); 43 : 44 14789 : params.addClassDescription( 45 : "A MeshGenerator that adds element sides to a sideset if the centroid of the side satisfies " 46 : "the `combinatorial_geometry` expression."); 47 : 48 14789 : return params; 49 0 : } 50 : 51 248 : ParsedGenerateSideset::ParsedGenerateSideset(const InputParameters & parameters) 52 : : SideSetsGeneratorBase(parameters), 53 : FunctionParserUtils<false>(parameters), 54 248 : _function(parameters.get<std::string>("combinatorial_geometry")) 55 : { 56 248 : _boundary_names.push_back(getParam<BoundaryName>("new_sideset_name")); 57 : 58 : // Create parsed function 59 248 : _func_F = std::make_shared<SymFunction>(); 60 496 : parsedFunctionSetup(_func_F, 61 248 : _function, 62 : "x,y,z", 63 : getParam<std::vector<std::string>>("constant_names"), 64 : getParam<std::vector<std::string>>("constant_expressions"), 65 : comm()); 66 : 67 248 : _func_params.resize(3); 68 248 : } 69 : 70 : std::unique_ptr<MeshBase> 71 245 : ParsedGenerateSideset::generate() 72 : { 73 245 : std::unique_ptr<MeshBase> mesh = std::move(_input); 74 245 : if (!mesh->is_replicated()) 75 10 : mooseWarning( 76 : "ParsedGenerateSideset is not implemented for distributed meshes. Make sure the " 77 : "parsed sideset does NOT cross any mesh distribution boundaries, using the ProcessorAux"); 78 : 79 245 : setup(*mesh); 80 : 81 : // Get a reference to our BoundaryInfo object for later use 82 217 : BoundaryInfo & boundary_info = mesh->get_boundary_info(); 83 : 84 : // Get the BoundaryIDs from the mesh 85 : std::vector<boundary_id_type> boundary_ids = 86 217 : MooseMeshUtils::getBoundaryIDs(*mesh, _boundary_names, true); 87 : mooseAssert(boundary_ids.size() == 1, "Length of boundary_ids should be one"); 88 : 89 17507 : for (const auto & elem : mesh->active_element_ptr_range()) 90 : { 91 : // check if the element is included 92 8645 : if (_check_subdomains && !elementSubdomainIdInList(elem, _included_subdomain_ids)) 93 1601 : continue; 94 : 95 35000 : for (const auto side : make_range(elem->n_sides())) 96 : { 97 27956 : _fe_face->reinit(elem, side); 98 : // We'll just use the normal of the first qp 99 27956 : const Point & face_normal = _fe_face->get_normals()[0]; 100 : 101 27956 : if (!elemSideSatisfiesRequirements(elem, side, *mesh, _normal, face_normal)) 102 9396 : continue; 103 : 104 : // check expression 105 18560 : std::unique_ptr<Elem> curr_side = elem->side_ptr(side); 106 18560 : _func_params[0] = curr_side->vertex_average()(0); 107 18560 : _func_params[1] = curr_side->vertex_average()(1); 108 18560 : _func_params[2] = curr_side->vertex_average()(2); 109 18560 : if (evaluate(_func_F)) 110 : { 111 1178 : if (_replace) 112 0 : boundary_info.remove_side(elem, side); 113 1178 : boundary_info.add_side(elem, side, boundary_ids[0]); 114 : } 115 18560 : } 116 217 : } 117 217 : finalize(); 118 217 : boundary_info.sideset_name(boundary_ids[0]) = _boundary_names[0]; 119 : 120 217 : mesh->set_isnt_prepared(); 121 434 : return dynamic_pointer_cast<MeshBase>(mesh); 122 217 : }