https://mooseframework.inl.gov
ParsedGenerateNodeset.C
Go to the documentation of this file.
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 "ParsedGenerateNodeset.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 
23 
26 {
29 
30  params.addRequiredParam<BoundaryName>("new_nodeset_name", "The name of the new nodeset");
31 
32  params.addRequiredParam<std::string>("expression",
33  "Function expression describing the geometric constraints "
34  "that the node must meet to be included in the nodeset");
35  params.addParam<std::vector<std::string>>(
36  "constant_names", {}, "Vector of constants used in the parsed function");
37  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  params.addParam<bool>(
43  "allow_distributed_meshes",
44  false,
45  "Can be used to avoid erroring on distributed meshes, when it is known to be safe. For "
46  "example, when only using a parsed expression to select nodes.");
47 
48  // This nodeset generator can only handle a single new nodeset name, not a vector of names
49  params.suppressParameter<std::vector<BoundaryName>>("new_nodeset");
50 
51  params.addClassDescription("A MeshGenerator that adds nodes to a nodeset if the "
52  "node satisfies the `expression` expression.");
53  params.addParamNamesToGroup("expression constant_names constant_expressions",
54  "Parsed expression");
55  params.addParamNamesToGroup("allow_distributed_meshes", "Advanced");
56  return params;
57 }
58 
60  : NodeSetsGeneratorBase(parameters),
61  FunctionParserUtils<false>(parameters),
62  _function(parameters.get<std::string>("expression"))
63 {
64  _nodeset_names.push_back(getParam<BoundaryName>("new_nodeset_name"));
65 
66  // Create parsed function
67  _func_F = std::make_shared<SymFunction>();
69  _function,
70  "x,y,z",
71  getParam<std::vector<std::string>>("constant_names"),
72  getParam<std::vector<std::string>>("constant_expressions"),
73  comm());
74 
75  _func_params.resize(3);
76 }
77 
78 std::unique_ptr<MeshBase>
80 {
81  std::unique_ptr<MeshBase> mesh = std::move(_input);
82  setup(*mesh);
83 
84  if (!getParam<bool>("allow_distributed_meshes") && !mesh->is_replicated())
85  mooseError("Not implemented for distributed meshes");
86 
87  // Get a reference to our BoundaryInfo object for later use
88  BoundaryInfo & boundary_info = mesh->get_boundary_info();
89 
90  // Get a reference to the node to nodeset map
91  const auto & nodeset_map = boundary_info.get_nodeset_map();
92 
93  // Get the BoundaryIDs from the mesh
94  std::vector<boundary_id_type> nodeset_ids =
96  mooseAssert(nodeset_ids.size() == 1, "Length of nodeset_ids should be one");
97 
98  // Loop over nodes
99  for (const auto curr_node : as_range(mesh->active_nodes_begin(), mesh->active_nodes_end()))
100  {
101  // Get all nodesets the node is currently a part of
102  const auto & node_nodesets_iters = nodeset_map.equal_range(curr_node);
103 
104  // Copy into a vector to accommodate this developer's low skills
105  std::vector<BoundaryID> node_nodesets;
106  for (auto i = node_nodesets_iters.first; i != node_nodesets_iters.second; ++i)
107  node_nodesets.push_back(i->second);
108 
109  // Get all the elements the node is a part of
110  const auto & node_elems = _node_to_elem_map[curr_node->id()];
111 
112  // Check all the constraints specified in base class
113  if (!nodeSatisfiesRequirements(curr_node, node_nodesets, node_elems, *mesh))
114  continue;
115 
116  // Check expression
117  _func_params[0] = (*curr_node)(0);
118  _func_params[1] = (*curr_node)(1);
119  _func_params[2] = (*curr_node)(2);
120  if (evaluate(_func_F))
121  {
122  if (_replace)
123  {
124  for (const auto nodeset_id : node_nodesets)
125  boundary_info.remove_node(curr_node, nodeset_id);
126  }
127  boundary_info.add_node(curr_node, nodeset_ids[0]);
128  }
129  }
130  boundary_info.nodeset_name(nodeset_ids[0]) = _nodeset_names[0];
131 
132  // TODO: consider if a new nodeset actually impacts preparedness
133  mesh->set_isnt_prepared();
134  return dynamic_pointer_cast<MeshBase>(mesh);
135 }
SymFunctionPtr _func_F
function parser object describing the combinatorial geometry
GenericReal< is_ad > evaluate(SymFunctionPtr &, const std::string &object_name="")
Evaluate FParser object and check EvalError.
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
Definition: MooseBase.h:388
std::string _function
function expression
ParsedGenerateNodeset(const InputParameters &parameters)
bool nodeSatisfiesRequirements(const Node *node, const std::vector< BoundaryID > &node_nodesets, const std::vector< dof_id_type > &node_elems, const MeshBase &mesh) const
Determines whether the given node satisfies the user-specified constraints.
T * get(const std::unique_ptr< T > &u)
The MooseUtils::get() specializations are used to support making forwards-compatible code changes fro...
Definition: MooseUtils.h:1133
MeshBase & mesh
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
const Parallel::Communicator & comm() const
std::unique_ptr< T_DEST, T_DELETER > dynamic_pointer_cast(std::unique_ptr< T_SRC, T_DELETER > &src)
These are reworked from https://stackoverflow.com/a/11003103.
void addRequiredParam(const std::string &name, const std::string &doc_string)
This method adds a parameter and documentation string to the InputParameters object that will be extr...
std::vector< BoundaryName > _nodeset_names
The list of new nodeset names.
void suppressParameter(const std::string &name)
This method suppresses an inherited parameter so that it isn&#39;t required or valid in the derived class...
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
MeshGenerator for defining a nodeset by a parsed expression.
std::vector< BoundaryID > getBoundaryIDs(const libMesh::MeshBase &mesh, const std::vector< BoundaryName > &boundary_name, bool generate_unknown, const std::set< BoundaryID > &mesh_boundary_ids)
Gets the boundary IDs with their names.
registerMooseObject("MooseApp", ParsedGenerateNodeset)
void parsedFunctionSetup(SymFunctionPtr &function, const std::string &expression, const std::string &variables, const std::vector< std::string > &constant_names, const std::vector< std::string > &constant_expressions, const libMesh::Parallel::Communicator &comm) const
Performs setup steps on a SymFunction.
static InputParameters validParams()
std::unique_ptr< MeshBase > & _input
the mesh to add the nodesets to
const bool _replace
Whether or not to remove the old nodesets (all of them, if any) when adding nodesets.
std::vector< GenericReal< is_ad > > _func_params
Array to stage the parameters passed to the functions when calling Eval.
std::unordered_map< dof_id_type, std::vector< dof_id_type > > _node_to_elem_map
A map from nodes (ids) to local elements (ids) which comprise the node.
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
Definition: MooseBase.h:271
void setup(MeshBase &mesh)
This method prepares a few attributes which are commonly needed for nodeset generation such as a map ...
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump...
static InputParameters validParams()
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object...
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
static InputParameters validParams()
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
This method takes a space delimited list of parameter names and adds them to the specified group name...