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 57676 : FileMesh::validParams() 29 : { 30 57676 : InputParameters params = MooseMesh::validParams(); 31 57676 : params.addRequiredParam<MeshFileName>("file", "The name of the mesh file to read"); 32 57676 : MooseEnum dims("1=1 2 3", "1"); 33 57676 : 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 173028 : params.addParam<bool>("clear_spline_nodes", 40 115352 : 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 57676 : params.addClassDescription("Read a mesh from a file."); 45 115352 : return params; 46 57676 : } 47 : 48 4150 : FileMesh::FileMesh(const InputParameters & parameters) 49 4150 : : MooseMesh(parameters), _file_name(getParam<MeshFileName>("file")) 50 : { 51 4150 : } 52 : 53 814 : FileMesh::FileMesh(const FileMesh & other_mesh) 54 814 : : MooseMesh(other_mesh), _file_name(other_mesh._file_name) 55 : { 56 814 : } 57 : 58 9132 : FileMesh::~FileMesh() {} 59 : 60 : std::unique_ptr<MooseMesh> 61 810 : FileMesh::safeClone() const 62 : { 63 810 : return _app.getFactory().copyConstruct(*this); 64 : } 65 : 66 : void 67 3534 : FileMesh::buildMesh() 68 : { 69 3534 : TIME_SECTION("buildMesh", 2, "Reading Mesh"); 70 : 71 : // This dimension should get overridden if the mesh reader can determine the dimension 72 3534 : getMesh().set_mesh_dimension(getParam<MooseEnum>("dim")); 73 : 74 3534 : if (_is_nemesis) 75 : { 76 : // Nemesis_IO only takes a reference to DistributedMesh, so we can't be quite so short here. 77 60 : DistributedMesh & pmesh = cast_ref<DistributedMesh &>(getMesh()); 78 60 : Nemesis_IO(pmesh).read(_file_name); 79 : 80 60 : 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 60 : bool skip_partitioning_later = getMesh().skip_partitioning(); 86 60 : getMesh().skip_partitioning(true); 87 60 : getMesh().prepare_for_use(); 88 60 : 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 3631 : if (_app.getExodusFileRestart() && (_file_name.rfind(".exd") < _file_name.size() || 97 157 : _file_name.rfind(".e") < _file_name.size())) 98 : { 99 157 : MooseUtils::checkFileReadable(_file_name); 100 : 101 157 : auto exreader = std::make_shared<ExodusII_IO>(getMesh()); 102 157 : _app.setExReaderForRestart(std::move(exreader)); 103 157 : exreader->read(_file_name); 104 : 105 157 : getMesh().allow_renumbering(false); 106 157 : getMesh().prepare_for_use(); 107 157 : } 108 : else 109 : { 110 3317 : _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 3317 : bool restarting = _file_name.rfind(".cpa.gz") < _file_name.size(); 117 : 118 3317 : const bool skip_partitioning_later = restarting && getMesh().skip_partitioning(); 119 3317 : const bool allow_renumbering_later = restarting && getMesh().allow_renumbering(); 120 : 121 3317 : if (restarting) 122 : { 123 250 : getMesh().skip_partitioning(true); 124 250 : getMesh().allow_renumbering(false); 125 : } 126 : 127 3317 : MooseUtils::checkFileReadable(_file_name); 128 3309 : getMesh().read(_file_name); 129 : 130 3309 : if (getParam<bool>("clear_spline_nodes")) 131 0 : MeshTools::clear_spline_nodes(getMesh()); 132 : 133 3309 : _app.possiblyLoadRestartableMetaData(MooseApp::MESH_META_DATA, _file_name); 134 : 135 3309 : if (restarting) 136 : { 137 246 : getMesh().allow_renumbering(allow_renumbering_later); 138 246 : getMesh().skip_partitioning(skip_partitioning_later); 139 : } 140 : } 141 : } 142 3526 : } 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 : }