LCOV - code coverage report
Current view: top level - src/meshgenerators - RefineBlockGenerator.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 70 72 97.2 %
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 "RefineBlockGenerator.h"
      11             : #include "MooseMeshUtils.h"
      12             : 
      13             : #include "libmesh/elem.h"
      14             : #include "libmesh/mesh_refinement.h"
      15             : #include "CastUniquePointer.h"
      16             : 
      17             : registerMooseObject("MooseApp", RefineBlockGenerator);
      18             : 
      19             : InputParameters
      20       14949 : RefineBlockGenerator::validParams()
      21             : {
      22       14949 :   InputParameters params = MeshGenerator::validParams();
      23             : 
      24       14949 :   params.addClassDescription("Mesh generator which refines one or more blocks in an existing mesh");
      25       14949 :   params.addRequiredParam<MeshGeneratorName>("input", "Input mesh to refine");
      26       14949 :   params.addRequiredParam<std::vector<SubdomainName>>("block", "The list of blocks to be refined");
      27       14949 :   params.addRequiredParam<std::vector<unsigned int>>(
      28             :       "refinement",
      29             :       "Minimum amount of times to refine each block, corresponding to their index in 'block'");
      30       44847 :   params.addParam<bool>(
      31             :       "enable_neighbor_refinement",
      32       29898 :       true,
      33             :       "Toggles whether neighboring level one elements should be refined or not. Defaults to true. "
      34             :       "False may lead to unsupported mesh non-conformality without great care.");
      35       44847 :   params.addParam<Real>(
      36       29898 :       "max_element_volume", 1e8, "If elements are above that size, they will be refined more");
      37             : 
      38       14949 :   return params;
      39           0 : }
      40             : 
      41         344 : RefineBlockGenerator::RefineBlockGenerator(const InputParameters & parameters)
      42             :   : MeshGenerator(parameters),
      43         344 :     _input(getMesh("input")),
      44         344 :     _block(getParam<std::vector<SubdomainName>>("block")),
      45         344 :     _refinement(getParam<std::vector<unsigned int>>("refinement")),
      46         344 :     _enable_neighbor_refinement(getParam<bool>("enable_neighbor_refinement")),
      47         688 :     _max_element_volume(getParam<Real>("max_element_volume"))
      48             : {
      49         344 :   if (_block.size() != _refinement.size())
      50           4 :     paramError("refinement", "The blocks and refinement parameter vectors should be the same size");
      51         340 : }
      52             : 
      53             : std::unique_ptr<MeshBase>
      54         330 : RefineBlockGenerator::generate()
      55             : {
      56             :   // Get the list of block ids from the block names
      57             :   const auto block_ids =
      58         330 :       MooseMeshUtils::getSubdomainIDs(*_input, getParam<std::vector<SubdomainName>>("block"));
      59             : 
      60             :   // Check that the block ids/names exist in the mesh
      61         330 :   std::set<SubdomainID> mesh_blocks;
      62         330 :   _input->subdomain_ids(mesh_blocks);
      63             : 
      64        1166 :   for (std::size_t i = 0; i < block_ids.size(); ++i)
      65         840 :     if (!MooseMeshUtils::hasSubdomainID(*_input, block_ids[i]))
      66           4 :       paramError("block",
      67             :                  "The block '",
      68           4 :                  getParam<std::vector<SubdomainName>>("block")[i],
      69             :                  "' was not found within the mesh");
      70             : 
      71         326 :   std::unique_ptr<MeshBase> mesh = std::move(_input);
      72         326 :   int max = *std::max_element(_refinement.begin(), _refinement.end());
      73             : 
      74         326 :   if (max > 0 && !mesh->is_replicated() && !mesh->is_prepared())
      75             :     // refinement requires that (or at least it asserts that) the mesh is either replicated or
      76             :     // prepared
      77          28 :     mesh->prepare_for_use();
      78             : 
      79         326 :   auto mesh_ptr = recursive_refine(block_ids, mesh, _refinement, max);
      80             : 
      81         326 :   if (max > 0 && !mesh_ptr->is_replicated() && !mesh_ptr->is_prepared())
      82             :     // refinement requires that (or at least it asserts that) the mesh is either replicated or
      83             :     // prepared
      84           0 :     mesh_ptr->prepare_for_use();
      85             : 
      86             :   // Refine elements that are too big
      87         326 :   bool found_element_to_refine = true;
      88         326 :   bool refined_on_size = false;
      89         988 :   while (found_element_to_refine)
      90             :   {
      91         336 :     found_element_to_refine = false;
      92        1182 :     for (auto bid : block_ids)
      93      530282 :       for (auto & elem : mesh_ptr->active_subdomain_elements_ptr_range(bid))
      94      264718 :         if (elem->volume() >= _max_element_volume)
      95             :         {
      96          27 :           elem->set_refinement_flag(Elem::REFINE);
      97          27 :           found_element_to_refine = true;
      98         846 :         }
      99             :     // Refinement needs to be done on all ranks at the same time
     100         336 :     mesh_ptr->comm().max(found_element_to_refine);
     101             : 
     102         336 :     if (found_element_to_refine)
     103             :     {
     104          10 :       libMesh::MeshRefinement refinedmesh(*mesh_ptr);
     105          10 :       if (!_enable_neighbor_refinement)
     106          10 :         refinedmesh.face_level_mismatch_limit() = 0;
     107          10 :       refinedmesh.refine_elements();
     108          10 :       refined_on_size = true;
     109          10 :     }
     110             :   }
     111             : 
     112         326 :   if (refined_on_size || max > 0)
     113         280 :     mesh_ptr->set_isnt_prepared();
     114             : 
     115         652 :   return mesh_ptr;
     116         326 : }
     117             : 
     118             : std::unique_ptr<MeshBase>
     119         689 : RefineBlockGenerator::recursive_refine(std::vector<subdomain_id_type> block_ids,
     120             :                                        std::unique_ptr<MeshBase> & mesh,
     121             :                                        std::vector<unsigned int> refinement,
     122             :                                        unsigned int max,
     123             :                                        unsigned int ref_step)
     124             : {
     125         689 :   if (ref_step == max)
     126         326 :     return dynamic_pointer_cast<MeshBase>(mesh);
     127        1383 :   for (std::size_t i = 0; i < block_ids.size(); i++)
     128             :   {
     129        1020 :     if (refinement[i] > 0 && refinement[i] > ref_step)
     130             :     {
     131       83301 :       for (const auto & elem : mesh->active_subdomain_elements_ptr_range(block_ids[i]))
     132       42014 :         elem->set_refinement_flag(Elem::REFINE);
     133             :     }
     134             :   }
     135         363 :   libMesh::MeshRefinement refinedmesh(*mesh);
     136         363 :   if (!_enable_neighbor_refinement)
     137         240 :     refinedmesh.face_level_mismatch_limit() = 0;
     138         363 :   refinedmesh.refine_elements();
     139             : 
     140         363 :   ref_step++;
     141         363 :   return recursive_refine(block_ids, mesh, refinement, max, ref_step);
     142         363 : }

Generated by: LCOV version 1.14