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