LCOV - code coverage report
Current view: top level - src/meshgenerators - ParsedGenerateNodeset.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 47 49 95.9 %
Date: 2025-07-17 01:28:37 Functions: 3 3 100.0 %
Legend: Lines: hit not hit

          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 "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             : 
      22             : registerMooseObject("MooseApp", ParsedGenerateNodeset);
      23             : 
      24             : InputParameters
      25       14445 : ParsedGenerateNodeset::validParams()
      26             : {
      27       14445 :   InputParameters params = NodeSetsGeneratorBase::validParams();
      28       14445 :   params += FunctionParserUtils<false>::validParams();
      29             : 
      30       14445 :   params.addRequiredParam<BoundaryName>("new_nodeset_name", "The name of the new nodeset");
      31             : 
      32       14445 :   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       14445 :   params.addParam<std::vector<std::string>>(
      36             :       "constant_names", {}, "Vector of constants used in the parsed function");
      37       14445 :   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 nodeset generator can only handle a single new nodeset name, not a vector of names
      43       14445 :   params.suppressParameter<std::vector<BoundaryName>>("new_nodeset");
      44             : 
      45       14445 :   params.addClassDescription("A MeshGenerator that adds nodes to a nodeset if the "
      46             :                              "node satisfies the `expression` expression.");
      47       14445 :   params.addParamNamesToGroup("expression constant_names constant_expressions",
      48             :                               "Parsed expression");
      49       14445 :   return params;
      50           0 : }
      51             : 
      52          92 : ParsedGenerateNodeset::ParsedGenerateNodeset(const InputParameters & parameters)
      53             :   : NodeSetsGeneratorBase(parameters),
      54             :     FunctionParserUtils<false>(parameters),
      55          92 :     _function(parameters.get<std::string>("expression"))
      56             : {
      57          92 :   _nodeset_names.push_back(getParam<BoundaryName>("new_nodeset_name"));
      58             : 
      59             :   // Create parsed function
      60          92 :   _func_F = std::make_shared<SymFunction>();
      61         180 :   parsedFunctionSetup(_func_F,
      62          92 :                       _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          88 :   _func_params.resize(3);
      69          88 : }
      70             : 
      71             : std::unique_ptr<MeshBase>
      72          88 : ParsedGenerateNodeset::generate()
      73             : {
      74          88 :   std::unique_ptr<MeshBase> mesh = std::move(_input);
      75          88 :   setup(*mesh);
      76             : 
      77          64 :   if (!mesh->is_replicated())
      78           0 :     mooseError("Not implemented for distributed meshes");
      79             : 
      80             :   // Get a reference to our BoundaryInfo object for later use
      81          64 :   BoundaryInfo & boundary_info = mesh->get_boundary_info();
      82             : 
      83             :   // Get a reference to the node to nodeset map
      84          64 :   const auto & nodeset_map = boundary_info.get_nodeset_map();
      85             : 
      86             :   // Get the BoundaryIDs from the mesh
      87             :   std::vector<boundary_id_type> nodeset_ids =
      88          64 :       MooseMeshUtils::getBoundaryIDs(*mesh, _nodeset_names, true);
      89             :   mooseAssert(nodeset_ids.size() == 1, "Length of nodeset_ids should be one");
      90             : 
      91             :   // Loop over nodes
      92        8576 :   for (const auto curr_node : as_range(mesh->active_nodes_begin(), mesh->active_nodes_end()))
      93             :   {
      94             :     // Get all nodesets the node is currently a part of
      95        4256 :     const auto & node_nodesets_iters = nodeset_map.equal_range(curr_node);
      96             : 
      97             :     // Copy into a vector to accommodate this developer's low skills
      98        4256 :     std::vector<BoundaryID> node_nodesets;
      99       10272 :     for (auto i = node_nodesets_iters.first; i != node_nodesets_iters.second; ++i)
     100        6016 :       node_nodesets.push_back(i->second);
     101             : 
     102             :     // Get all the elements the node is a part of
     103        4256 :     const auto & node_elems = _node_to_elem_map[curr_node->id()];
     104             : 
     105             :     // Check all the constraints specified in base class
     106        4256 :     if (!nodeSatisfiesRequirements(curr_node, node_nodesets, node_elems, *mesh))
     107        3152 :       continue;
     108             : 
     109             :     // Check expression
     110        1104 :     _func_params[0] = (*curr_node)(0);
     111        1104 :     _func_params[1] = (*curr_node)(1);
     112        1104 :     _func_params[2] = (*curr_node)(2);
     113        1104 :     if (evaluate(_func_F))
     114             :     {
     115         752 :       if (_replace)
     116             :       {
     117         160 :         for (const auto nodeset_id : node_nodesets)
     118          96 :           boundary_info.remove_node(curr_node, nodeset_id);
     119             :       }
     120         752 :       boundary_info.add_node(curr_node, nodeset_ids[0]);
     121             :     }
     122        4320 :   }
     123          64 :   boundary_info.nodeset_name(nodeset_ids[0]) = _nodeset_names[0];
     124             : 
     125             :   // TODO: consider if a new nodeset actually impacts preparedness
     126          64 :   mesh->set_isnt_prepared();
     127         128 :   return dynamic_pointer_cast<MeshBase>(mesh);
     128          64 : }

Generated by: LCOV version 1.14