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 "SubdomainsFromPartitionerGenerator.h" 11 : #include "CastUniquePointer.h" 12 : #include "MooseMeshUtils.h" 13 : 14 : #include "libmesh/elem.h" 15 : #include "libmesh/partitioner.h" 16 : 17 : registerMooseObject("MooseApp", SubdomainsFromPartitionerGenerator); 18 : 19 : InputParameters 20 3085 : SubdomainsFromPartitionerGenerator::validParams() 21 : { 22 3085 : InputParameters params = MeshGenerator::validParams(); 23 12340 : params.addRequiredParam<MeshGeneratorName>("input", "The mesh we want to modify"); 24 6170 : params.addClassDescription( 25 : "Changes the subdomain ID of elements based on the output of the partitioner"); 26 12340 : params.addParam<std::vector<SubdomainName>>( 27 : "included_subdomains", "Only change subdomain ID only for elements in those subdomains"); 28 9255 : params.addParam<subdomain_id_type>("offset", 29 6170 : 0, 30 : "Offset to apply to the subdomain IDs. Default type is a " 31 : "short integer, do not use a large value!"); 32 9255 : params.addRequiredParam<unsigned int>("num_partitions", 33 : "Number of partitioners to get from the partitioner"); 34 3085 : return params; 35 0 : } 36 : 37 12 : SubdomainsFromPartitionerGenerator::SubdomainsFromPartitionerGenerator( 38 12 : const InputParameters & parameters) 39 : : MeshGenerator(parameters), 40 12 : _input(getMesh("input")), 41 36 : _offset(getParam<subdomain_id_type>("offset")) 42 : { 43 12 : } 44 : 45 : std::unique_ptr<MeshBase> 46 12 : SubdomainsFromPartitionerGenerator::generate() 47 : { 48 12 : std::unique_ptr<MeshBase> mesh = std::move(_input); 49 : 50 36 : if (getParam<unsigned int>("num_partitions") != n_processors()) 51 0 : paramWarning("num_partitions", 52 : "Partitioner may error with num_partitions != number of MPI processors"); 53 : 54 : // Process the block restriction, if any 55 12 : std::set<SubdomainID> restricted_ids; 56 24 : bool has_restriction = getParam<std::vector<SubdomainName>>("included_subdomains").size(); 57 12 : if (has_restriction) 58 : { 59 24 : const auto & names = getParam<std::vector<SubdomainName>>("included_subdomains"); 60 24 : for (const auto & name : names) 61 : { 62 : // check that the subdomain exists in the mesh 63 12 : if (!MooseMeshUtils::hasSubdomainName(*mesh, name)) 64 0 : paramError("included_subdomains", "The block '", name, "' was not found in the mesh"); 65 : 66 12 : restricted_ids.insert(MooseMeshUtils::getSubdomainID(name, *mesh)); 67 : } 68 : } 69 : 70 : // Extract the mesh 71 12 : auto block_mesh = buildMeshBaseObject(); 72 12 : if (has_restriction) 73 48 : MooseMeshUtils::convertBlockToMesh( 74 12 : *mesh, *block_mesh, getParam<std::vector<SubdomainName>>("included_subdomains")); 75 : else 76 0 : block_mesh = mesh->clone(); 77 : 78 : // Get the partitioner 79 12 : const auto & partitioner = mesh->partitioner(); 80 : 81 : // Partition this mesh 82 24 : partitioner->partition(*block_mesh, getParam<unsigned int>("num_partitions")); 83 12 : auto pl = block_mesh->sub_point_locator(); 84 : 85 : // Loop over the elements 86 84 : for (const auto & elem : mesh->element_ptr_range()) 87 : { 88 72 : if (has_restriction && restricted_ids.count(elem->subdomain_id()) == 0) 89 12 : continue; 90 : 91 : // Get the element from point locator 92 60 : const Elem * const block_mesh_elem = (*pl)(elem->vertex_average()); 93 : 94 : // Get a new subdomain id from the partition of the block mesh 95 60 : elem->subdomain_id() = _offset + block_mesh_elem->processor_id(); 96 12 : } 97 : 98 12 : mesh->unset_is_prepared(); 99 24 : return dynamic_pointer_cast<MeshBase>(mesh); 100 12 : }