LCOV - code coverage report
Current view: top level - src/meshgenerators - ParsedGenerateSideset.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 48 50 96.0 %
Date: 2026-05-29 20:35:17 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 "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 : }

Generated by: LCOV version 1.14