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 "FileMesh.h" 11 : #include "Parser.h" 12 : #include "MooseUtils.h" 13 : #include "Moose.h" 14 : #include "MooseApp.h" 15 : #include "FileMeshGenerator.h" 16 : 17 : #include "libmesh/exodusII_io.h" 18 : #include "libmesh/mesh_tools.h" 19 : #include "libmesh/nemesis_io.h" 20 : #include "libmesh/parallel_mesh.h" 21 : 22 : using libMesh::ExodusII_IO; 23 : using libMesh::Nemesis_IO; 24 : 25 : registerMooseObject("MooseApp", FileMesh); 26 : 27 : InputParameters 28 54859 : FileMesh::validParams() 29 : { 30 54859 : InputParameters params = MooseMesh::validParams(); 31 54859 : params.addRequiredParam<MeshFileName>("file", "The name of the mesh file to read"); 32 54859 : MooseEnum dims("1=1 2 3", "1"); 33 54859 : params.addParam<MooseEnum>("dim", 34 : dims, 35 : "This is only required for certain mesh formats where " 36 : "the dimension of the mesh cannot be autodetected. " 37 : "In particular you must supply this for GMSH meshes. " 38 : "Note: This is completely ignored for ExodusII meshes!"); 39 164577 : params.addParam<bool>("clear_spline_nodes", 40 109718 : false, 41 : "If clear_spline_nodes=true, IsoGeometric Analyis spline nodes " 42 : "and constraints are removed from an IGA mesh, after which only " 43 : "C^0 Rational-Bernstein-Bezier elements will remain."); 44 54859 : params.addClassDescription("Read a mesh from a file."); 45 109718 : return params; 46 54859 : } 47 : 48 3752 : FileMesh::FileMesh(const InputParameters & parameters) 49 3752 : : MooseMesh(parameters), _file_name(getParam<MeshFileName>("file")) 50 : { 51 3752 : } 52 : 53 751 : FileMesh::FileMesh(const FileMesh & other_mesh) 54 751 : : MooseMesh(other_mesh), _file_name(other_mesh._file_name) 55 : { 56 751 : } 57 : 58 8312 : FileMesh::~FileMesh() {} 59 : 60 : std::unique_ptr<MooseMesh> 61 747 : FileMesh::safeClone() const 62 : { 63 747 : return _app.getFactory().copyConstruct(*this); 64 : } 65 : 66 : void 67 3239 : FileMesh::buildMesh() 68 : { 69 3239 : TIME_SECTION("buildMesh", 2, "Reading Mesh"); 70 : 71 : // This dimension should get overridden if the mesh reader can determine the dimension 72 3239 : getMesh().set_mesh_dimension(getParam<MooseEnum>("dim")); 73 : 74 3239 : if (_is_nemesis) 75 : { 76 : // Nemesis_IO only takes a reference to DistributedMesh, so we can't be quite so short here. 77 56 : DistributedMesh & pmesh = cast_ref<DistributedMesh &>(getMesh()); 78 56 : Nemesis_IO(pmesh).read(_file_name); 79 : 80 56 : getMesh().allow_renumbering(false); 81 : 82 : // Even if we want repartitioning when load balancing later, we'll 83 : // begin with the default partitioning defined by the Nemesis 84 : // file. 85 56 : bool skip_partitioning_later = getMesh().skip_partitioning(); 86 56 : getMesh().skip_partitioning(true); 87 56 : getMesh().prepare_for_use(); 88 56 : getMesh().skip_partitioning(skip_partitioning_later); 89 : } 90 : else // not reading Nemesis files 91 : { 92 : // See if the user has requested reading a solution from the file. If so, we'll need to read 93 : // the mesh with the exodus reader instead of using mesh.read(). This will read the mesh on 94 : // every processor 95 : 96 3328 : if (_app.getExodusFileRestart() && (_file_name.rfind(".exd") < _file_name.size() || 97 145 : _file_name.rfind(".e") < _file_name.size())) 98 : { 99 145 : MooseUtils::checkFileReadable(_file_name); 100 : 101 145 : auto exreader = std::make_shared<ExodusII_IO>(getMesh()); 102 145 : _app.setExReaderForRestart(std::move(exreader)); 103 145 : exreader->read(_file_name); 104 : 105 145 : getMesh().allow_renumbering(false); 106 145 : getMesh().prepare_for_use(); 107 145 : } 108 : else 109 : { 110 3038 : _file_name = FileMeshGenerator::deduceCheckpointPath(*this, _file_name); 111 : 112 : // If we are reading a mesh while restarting, then we might have 113 : // a solution file that relies on that mesh partitioning and/or 114 : // numbering. In that case, we need to turn off repartitioning 115 : // and renumbering, at least at first. 116 3038 : bool restarting = _file_name.rfind(".cpa.gz") < _file_name.size(); 117 : 118 3038 : const bool skip_partitioning_later = restarting && getMesh().skip_partitioning(); 119 3038 : const bool allow_renumbering_later = restarting && getMesh().allow_renumbering(); 120 : 121 3038 : if (restarting) 122 : { 123 229 : getMesh().skip_partitioning(true); 124 229 : getMesh().allow_renumbering(false); 125 : } 126 : 127 3038 : MooseUtils::checkFileReadable(_file_name); 128 3030 : getMesh().read(_file_name); 129 : 130 3030 : if (getParam<bool>("clear_spline_nodes")) 131 0 : MeshTools::clear_spline_nodes(getMesh()); 132 : 133 3030 : _app.possiblyLoadRestartableMetaData(MooseApp::MESH_META_DATA, _file_name); 134 : 135 3030 : if (restarting) 136 : { 137 225 : getMesh().allow_renumbering(allow_renumbering_later); 138 225 : getMesh().skip_partitioning(skip_partitioning_later); 139 : } 140 : } 141 : } 142 3231 : } 143 : 144 : void 145 0 : FileMesh::read(const std::string & file_name) 146 : { 147 0 : if (dynamic_cast<DistributedMesh *>(&getMesh()) && !_is_nemesis) 148 0 : getMesh().read(file_name, /*mesh_data=*/NULL, /*skip_renumber=*/false); 149 : else 150 0 : getMesh().read(file_name, /*mesh_data=*/NULL, /*skip_renumber=*/true); 151 0 : }