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 "MeshCollectionGenerator.h" 11 : 12 : #include "CastUniquePointer.h" 13 : #include "MooseUtils.h" 14 : 15 : #include "libmesh/replicated_mesh.h" 16 : #include "libmesh/unstructured_mesh.h" 17 : 18 : registerMooseObject("MooseApp", MeshCollectionGenerator); 19 : 20 : InputParameters 21 14697 : MeshCollectionGenerator::validParams() 22 : { 23 14697 : InputParameters params = MeshGenerator::validParams(); 24 14697 : params.addClassDescription("Collects multiple meshes into a single (unconnected) mesh."); 25 14697 : params.addRequiredParam<std::vector<MeshGeneratorName>>("inputs", "The input MeshGenerators."); 26 14697 : return params; 27 0 : } 28 : 29 212 : MeshCollectionGenerator::MeshCollectionGenerator(const InputParameters & parameters) 30 : : MeshGenerator(parameters), 31 212 : _input_names(getParam<std::vector<MeshGeneratorName>>("inputs")), 32 424 : _meshes(getMeshes("inputs")) 33 : { 34 : // error check 35 212 : if (_input_names.empty()) 36 0 : paramError("input_names", "You need to specify at least one MeshGenerator as an input."); 37 212 : } 38 : 39 : std::unique_ptr<MeshBase> 40 203 : MeshCollectionGenerator::generate() 41 : { 42 : // merge all meshes into the first one 43 203 : auto mesh = dynamic_pointer_cast<UnstructuredMesh>(std::move(*_meshes[0])); 44 203 : if (!mesh) 45 0 : paramError("inputs", _input_names[0], " is not a valid unstructured mesh"); 46 : 47 : // Read in all of the other meshes 48 406 : for (MooseIndex(_meshes) i = 1; i < _meshes.size(); ++i) 49 : { 50 203 : auto other_mesh = dynamic_pointer_cast<UnstructuredMesh>(std::move(*_meshes[i])); 51 203 : if (!other_mesh) 52 0 : paramError("inputs", _input_names[i], " is not a valid unstructured mesh"); 53 : 54 203 : dof_id_type node_delta = mesh->max_node_id(); 55 203 : dof_id_type elem_delta = mesh->max_elem_id(); 56 : 57 : unique_id_type unique_delta = 58 : #ifdef LIBMESH_ENABLE_UNIQUE_ID 59 203 : mesh->parallel_max_unique_id(); 60 : #else 61 : 0; 62 : #endif 63 : 64 : // Copy mesh data over from the other mesh 65 203 : mesh->copy_nodes_and_elements(*other_mesh, 66 : /*skip_find_neighbors = */ false, 67 : elem_delta, 68 : node_delta, 69 : unique_delta); 70 : 71 : // Copy BoundaryInfo from other_mesh too. We do this via the 72 : // list APIs rather than element-by-element for speed. 73 203 : BoundaryInfo & boundary = mesh->get_boundary_info(); 74 203 : const BoundaryInfo & other_boundary = other_mesh->get_boundary_info(); 75 : 76 11157 : for (const auto & t : other_boundary.build_node_list()) 77 11157 : boundary.add_node(std::get<0>(t) + node_delta, std::get<1>(t)); 78 : 79 14499 : for (const auto & t : other_boundary.build_side_list()) 80 14499 : boundary.add_side(std::get<0>(t) + elem_delta, std::get<1>(t), std::get<2>(t)); 81 : 82 203 : for (const auto & t : other_boundary.build_edge_list()) 83 203 : boundary.add_edge(std::get<0>(t) + elem_delta, std::get<1>(t), std::get<2>(t)); 84 : 85 203 : for (const auto & t : other_boundary.build_shellface_list()) 86 203 : boundary.add_shellface(std::get<0>(t) + elem_delta, std::get<1>(t), std::get<2>(t)); 87 : 88 203 : const auto & boundary_ids = boundary.get_boundary_ids(); 89 203 : const auto & other_boundary_ids = other_boundary.get_boundary_ids(); 90 1157 : for (auto id : other_boundary_ids) 91 : { 92 : // check if the boundary id already exists with a different name 93 954 : if (boundary_ids.count(id)) 94 : { 95 1146 : if (boundary.get_sideset_name(id) != "" && 96 192 : boundary.get_sideset_name(id) != other_boundary.get_sideset_name(id)) 97 0 : mooseError("A sideset with id ", 98 : id, 99 : " exists but has different names in the merged meshes ('", 100 0 : boundary.get_sideset_name(id), 101 : "' vs.'", 102 0 : other_boundary.get_sideset_name(id), 103 : "')."); 104 : 105 954 : boundary.sideset_name(id) = other_boundary.get_sideset_name(id); 106 : 107 1146 : if (boundary.get_nodeset_name(id) != "" && 108 192 : boundary.get_nodeset_name(id) != other_boundary.get_nodeset_name(id)) 109 0 : mooseError("A nodeset with id ", 110 : id, 111 : " exists but has different names in the merged meshes ('", 112 0 : boundary.get_nodeset_name(id), 113 : "' vs.'", 114 0 : other_boundary.get_nodeset_name(id), 115 : "')."); 116 : 117 954 : boundary.nodeset_name(id) = other_boundary.get_nodeset_name(id); 118 : } 119 : } 120 203 : } 121 : 122 203 : mesh->set_isnt_prepared(); 123 406 : return dynamic_pointer_cast<MeshBase>(mesh); 124 203 : }