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 14857 : ParsedGenerateSideset::validParams() 26 : { 27 14857 : InputParameters params = SideSetsGeneratorBase::validParams(); 28 14857 : params += FunctionParserUtils<false>::validParams(); 29 : 30 14857 : params.addRequiredParam<std::string>("combinatorial_geometry", 31 : "Function expression encoding a combinatorial geometry"); 32 14857 : params.addRequiredParam<BoundaryName>("new_sideset_name", "The name of the new sideset"); 33 : 34 14857 : params.addParam<std::vector<std::string>>( 35 : "constant_names", {}, "Vector of constants used in the parsed function"); 36 14857 : 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 14857 : params.suppressParameter<std::vector<BoundaryName>>("new_boundary"); 43 : 44 14857 : 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 14857 : return params; 49 0 : } 50 : 51 282 : ParsedGenerateSideset::ParsedGenerateSideset(const InputParameters & parameters) 52 : : SideSetsGeneratorBase(parameters), 53 : FunctionParserUtils<false>(parameters), 54 282 : _function(parameters.get<std::string>("combinatorial_geometry")) 55 : { 56 282 : _boundary_names.push_back(getParam<BoundaryName>("new_sideset_name")); 57 : 58 : // Create parsed function 59 282 : _func_F = std::make_shared<SymFunction>(); 60 564 : parsedFunctionSetup(_func_F, 61 282 : _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 282 : _func_params.resize(3); 68 282 : } 69 : 70 : std::unique_ptr<MeshBase> 71 278 : ParsedGenerateSideset::generate() 72 : { 73 278 : std::unique_ptr<MeshBase> mesh = std::move(_input); 74 278 : if (!mesh->is_replicated()) 75 12 : 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 278 : setup(*mesh); 80 : 81 : // Get a reference to our BoundaryInfo object for later use 82 250 : BoundaryInfo & boundary_info = mesh->get_boundary_info(); 83 : 84 : // Get the BoundaryIDs from the mesh 85 : std::vector<boundary_id_type> boundary_ids = 86 250 : MooseMeshUtils::getBoundaryIDs(*mesh, _boundary_names, true); 87 : mooseAssert(boundary_ids.size() == 1, "Length of boundary_ids should be one"); 88 : 89 21626 : for (const auto & elem : mesh->active_element_ptr_range()) 90 : { 91 : // check if the element is included 92 10688 : if (_check_subdomains && !elementSubdomainIdInList(elem, _included_subdomain_ids)) 93 1779 : continue; 94 : 95 44373 : for (const auto side : make_range(elem->n_sides())) 96 : { 97 35464 : _fe_face->reinit(elem, side); 98 : // We'll just use the normal of the first qp 99 35464 : const Point & face_normal = _fe_face->get_normals()[0]; 100 : 101 35464 : if (!elemSideSatisfiesRequirements(elem, side, *mesh, _normal, face_normal)) 102 10563 : continue; 103 : 104 : // check expression 105 24901 : std::unique_ptr<Elem> curr_side = elem->side_ptr(side); 106 24901 : _func_params[0] = curr_side->vertex_average()(0); 107 24901 : _func_params[1] = curr_side->vertex_average()(1); 108 24901 : _func_params[2] = curr_side->vertex_average()(2); 109 24901 : if (evaluate(_func_F)) 110 : { 111 1317 : if (_replace) 112 0 : boundary_info.remove_side(elem, side); 113 1317 : boundary_info.add_side(elem, side, boundary_ids[0]); 114 : } 115 24901 : } 116 250 : } 117 250 : finalize(); 118 250 : boundary_info.sideset_name(boundary_ids[0]) = _boundary_names[0]; 119 : 120 250 : mesh->set_isnt_prepared(); 121 500 : return dynamic_pointer_cast<MeshBase>(mesh); 122 250 : }