LCOV - code coverage report
Current view: top level - src/meshgenerators - StackGenerator.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 63 69 91.3 %
Date: 2025-07-17 01:28:37 Functions: 4 4 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 "StackGenerator.h"
      11             : #include "CastUniquePointer.h"
      12             : 
      13             : #include "libmesh/replicated_mesh.h"
      14             : #include "libmesh/distributed_mesh.h"
      15             : #include "libmesh/boundary_info.h"
      16             : #include "libmesh/mesh_modification.h"
      17             : #include "libmesh/bounding_box.h"
      18             : #include "libmesh/mesh_tools.h"
      19             : #include "libmesh/point.h"
      20             : #include "MooseMeshUtils.h"
      21             : 
      22             : #include <typeinfo>
      23             : 
      24             : registerMooseObject("MooseApp", StackGenerator);
      25             : 
      26             : InputParameters
      27       14305 : StackGenerator::validParams()
      28             : {
      29       14305 :   InputParameters params = MeshGenerator::validParams();
      30             : 
      31       14305 :   MooseEnum dims("2=2 3=3");
      32       14305 :   params.addRequiredParam<MooseEnum>("dim", dims, "The dimension of the mesh to be generated");
      33             : 
      34       14305 :   params.addRequiredParam<std::vector<MeshGeneratorName>>("inputs",
      35             :                                                           "The meshes we want to stitch together");
      36             : 
      37       14305 :   params.addParam<Real>("bottom_height", 0, "The height of the bottom of the final mesh");
      38             : 
      39             :   // y boundary names (2D case)
      40       14305 :   params.addParam<BoundaryName>("top_boundary", "top", "name of the top (y) boundary");
      41       14305 :   params.addParam<BoundaryName>("bottom_boundary", "bottom", "name of the bottom (y) boundary");
      42             : 
      43             :   // z boundary names (3D case)
      44       14305 :   params.addParam<BoundaryName>("front_boundary", "front", "name of the front (z) boundary");
      45       14305 :   params.addParam<BoundaryName>("back_boundary", "back", "name of the back (z) boundary");
      46             : 
      47       14305 :   params.addClassDescription("Use the supplied meshes and stitch them on top of each other");
      48             : 
      49       28610 :   return params;
      50       14305 : }
      51             : 
      52          20 : StackGenerator::StackGenerator(const InputParameters & parameters)
      53             :   : MeshGenerator(parameters),
      54          20 :     _dim(getParam<MooseEnum>("dim")),
      55          20 :     _mesh_ptrs(getMeshes("inputs")),
      56          20 :     _input_names(getParam<std::vector<MeshGeneratorName>>("inputs")),
      57          40 :     _bottom_height(getParam<Real>("bottom_height"))
      58             : {
      59          20 : }
      60             : 
      61             : std::unique_ptr<MeshBase>
      62          20 : StackGenerator::generate()
      63             : {
      64          20 :   std::unique_ptr<ReplicatedMesh> mesh = dynamic_pointer_cast<ReplicatedMesh>(*_mesh_ptrs[0]);
      65          20 :   if (mesh == nullptr)
      66           0 :     mooseError("StackGenerator only works with ReplicatedMesh : mesh from Meshgenerator ",
      67           0 :                _input_names[0],
      68             :                "is not a ReplicatedMesh.");
      69             : 
      70          20 :   int dim = static_cast<int>(_dim);
      71             : 
      72          20 :   if (dim != int(mesh->mesh_dimension()))
      73           0 :     paramError("dim",
      74             :                "incompatible mesh dimensions: dim=",
      75             :                dim,
      76             :                " and first mesh dimension is ",
      77           0 :                mesh->mesh_dimension());
      78             : 
      79             :   // Reserve spaces for the other meshes (no need to store the first one another time)
      80          20 :   _meshes.reserve(_input_names.size() - 1);
      81             : 
      82             :   // Read in all of the other meshes
      83          72 :   for (MooseIndex(_input_names) i = 1; i < _input_names.size(); ++i)
      84          52 :     _meshes.push_back(dynamic_pointer_cast<ReplicatedMesh>(*_mesh_ptrs[i]));
      85             : 
      86             :   // Check that the casts didn't fail, and that the dimensions match
      87          68 :   for (MooseIndex(_meshes) i = 0; i < _meshes.size(); ++i)
      88             :   {
      89          52 :     if (_meshes[i] == nullptr)
      90           0 :       mooseError("StackGenerator only works with ReplicatedMesh : mesh from Meshgenerator ",
      91           0 :                  _input_names[i + 1],
      92             :                  "is not a ReplicatedMesh.");
      93          52 :     if (static_cast<int>(_meshes[i]->mesh_dimension()) != dim)
      94           4 :       mooseError("Mesh from MeshGenerator : ", _input_names[i + 1], " is not in ", _dim, "D.");
      95             :   }
      96             : 
      97             :   // Getting the boundaries provided by the user
      98             :   std::vector<BoundaryName> boundary_names = {getParam<BoundaryName>("top_boundary"),
      99          48 :                                               getParam<BoundaryName>("bottom_boundary")};
     100          16 :   if (dim == 3)
     101          24 :     boundary_names = {getParam<BoundaryName>("front_boundary"),
     102          24 :                       getParam<BoundaryName>("back_boundary")};
     103             : 
     104             :   std::vector<boundary_id_type> ids =
     105          16 :       MooseMeshUtils::getBoundaryIDs(*_meshes[0], boundary_names, true);
     106             : 
     107             :   mooseAssert(ids.size() == boundary_names.size(),
     108             :               "Unexpected number of ids returned for MooseMeshUtils::getBoundaryIDs");
     109             : 
     110          16 :   boundary_id_type first = ids[0], second = ids[1];
     111             : 
     112             :   // Getting the width of each mesh
     113          16 :   std::vector<Real> heights;
     114          16 :   heights.push_back(computeWidth(*mesh, _dim) + _bottom_height);
     115          64 :   for (MooseIndex(_meshes) i = 0; i < _meshes.size(); ++i)
     116          48 :     heights.push_back(computeWidth(*_meshes[i], _dim) + *heights.rbegin());
     117             : 
     118             :   // Move the first mesh at the provided height
     119          16 :   switch (_dim)
     120             :   {
     121           8 :     case 2:
     122           8 :       MeshTools::Modification::translate(*mesh, 0, _bottom_height, 0);
     123           8 :       break;
     124           8 :     case 3:
     125           8 :       MeshTools::Modification::translate(*mesh, 0, 0, _bottom_height);
     126           8 :       break;
     127             :   }
     128             : 
     129             :   // Move all of the other meshes in the right spots then stitch them one by one to the first one
     130          64 :   for (MooseIndex(_meshes) i = 0; i < _meshes.size(); ++i)
     131             :   {
     132          48 :     switch (_dim)
     133             :     {
     134          24 :       case 2:
     135          24 :         MeshTools::Modification::translate(*_meshes[i], 0, heights[i], 0);
     136          24 :         break;
     137          24 :       case 3:
     138          24 :         MeshTools::Modification::translate(*_meshes[i], 0, 0, heights[i]);
     139          24 :         break;
     140             :     }
     141          96 :     mesh->stitch_meshes(
     142          48 :         *_meshes[i], first, second, TOLERANCE, /*clear_stitched_boundary_ids=*/true);
     143             :   }
     144             : 
     145          32 :   return dynamic_pointer_cast<MeshBase>(mesh);
     146          56 : }
     147             : 
     148             : Real
     149          64 : StackGenerator::computeWidth(const MeshBase & mesh, const int & dim)
     150             : {
     151          64 :   BoundingBox bbox = MeshTools::create_bounding_box(mesh);
     152          64 :   return bbox.max()(dim - 1) - bbox.min()(dim - 1);
     153             : }

Generated by: LCOV version 1.14