https://mooseframework.inl.gov
Loading...
Searching...
No Matches
MFEMMesh.C
Go to the documentation of this file.
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#ifdef MOOSE_MFEM_ENABLED
11
12#include "MFEMMesh.h"
13#include "MooseApp.h"
14#include "libmesh/mesh_generation.h"
15
16#include <fstream>
17
19
22{
24 params.addParam<unsigned int>(
25 "serial_refine",
26 0,
27 "Number of serial refinements to perform on the mesh. Equivalent to uniform_refine.");
28 params.addParam<unsigned int>(
29 "uniform_refine",
30 0,
31 "Number of serial refinements to perform on the mesh. Equivalent to serial_refine");
32 params.addParam<unsigned int>(
33 "parallel_refine", 0, "Number of parallel refinements to perform on the mesh.");
34 params.addParam<std::string>("displacement", "Optional variable to use for mesh displacement.");
35 params.addParam<bool>("nonconforming",
36 false,
37 "Ensures the mesh is non-conforming: necessary for refining quad/hex "
38 "meshes and load (re)balancing.");
39 params.addParam<bool>("reorder_mesh",
40 false,
41 "Determines whether we reorder the mesh to improve dynamic partitioning. "
42 "Only Hilbert sorting is supported at present.");
43
44 params.addClassDescription("Class to read in and store an mfem::ParMesh from file.");
45
46 return params;
47}
48
49MFEMMesh::MFEMMesh(const InputParameters & parameters) : FileMesh(parameters) {}
50
52
53void
55{
56 // MooseMesh::init() handles the libMesh dummy mesh:
57 // - recovery: reads the libMesh mesh back from its checkpoint file
58 // - normal run: calls buildMesh(), which for MFEMMesh builds both the
59 // dummy libMesh mesh and the MFEM ParMesh
61
63 {
64 // MooseMesh::init() already restored the libMesh dummy mesh from its checkpoint.
65 // Now restore the MFEM parallel mesh from its own checkpoint file.
66 const auto checkpoint_file = _app.getRestartRecoverFileBase() + _app.checkpointSuffix() +
67 ".mfem.mesh." + std::to_string(this->processor_id());
68 std::ifstream input(checkpoint_file);
69 if (!input)
70 mooseError("Unable to open MFEM recovery mesh file '", checkpoint_file, "'.");
71
72 _mfem_par_mesh = std::make_shared<mfem::ParMesh>(this->comm().get(), input);
73
74 if (isParamSetByUser("displacement"))
75 _mesh_displacement_variable.emplace(getParam<std::string>("displacement"));
76 }
77}
78
79void
81{
82 TIME_SECTION("buildMesh", 2, "Reading Mesh");
83
84 // Build the MFEM ParMesh from a serial MFEM mesh
85 mfem::Mesh mfem_ser_mesh(getFileName());
86
87 if (isParamSetByUser("serial_refine") && isParamSetByUser("uniform_refine"))
89 "Cannot define serial_refine and uniform_refine to be nonzero at the same time (they "
90 "are the same variable). Please choose one.\n");
91
92 uniformRefinement(mfem_ser_mesh,
93 isParamSetByUser("serial_refine") ? getParam<unsigned int>("serial_refine")
94 : getParam<unsigned int>("uniform_refine"));
95
96 // MFEM supports load balancing of parallel non-conforming meshes
97 // with a space-filling curve partitioning, and we can improve it
98 // by re-ordering the mesh. For now, we only support the Hilbert
99 // ordering, although there is one other option.
100 if (getParam<bool>("reorder_mesh"))
101 {
102 mfem::Array<int> ordering;
103 mfem_ser_mesh.GetHilbertElementOrdering(ordering);
104 mfem_ser_mesh.ReorderElements(ordering);
105 }
106
107 // Make sure mesh is in non-conforming mode to enable local refinement of
108 // quadrilaterals/hexahedra (c.f. MFEM example 6p). The argument (true/false)
109 // determines whether a simplex mesh is considered to be non-conforming.
110 if (getParam<bool>("nonconforming"))
111 mfem_ser_mesh.EnsureNCMesh(true);
112
113 // multi app should take the mpi comm from moose so is split correctly??
114 auto comm = this->comm().get();
115 _mfem_par_mesh = std::make_shared<mfem::ParMesh>(comm, mfem_ser_mesh);
116
117 // Perform parallel refinements
118 uniformRefinement(*_mfem_par_mesh, getParam<unsigned int>("parallel_refine"));
119
120 if (isParamSetByUser("displacement"))
121 _mesh_displacement_variable.emplace(getParam<std::string>("displacement"));
122
123 // Build a dummy MOOSE mesh to enable this class to work with other MOOSE classes.
125}
126
127std::vector<std::filesystem::path>
128MFEMMesh::writeRecoveryFiles(const std::filesystem::path & file_base)
129{
131
132 mooseAssert(_mfem_par_mesh, "MFEM parallel mesh is not initialized");
133
134 const auto checkpoint_file =
135 file_base.string() + ".mfem.mesh." + std::to_string(this->processor_id());
136 std::ofstream output(checkpoint_file);
137 if (!output)
138 mooseError("Unable to open MFEM recovery mesh file '", checkpoint_file, "' for writing.");
139
140 _mfem_par_mesh->ParPrint(output);
141 return {checkpoint_file};
142}
143
144void
145MFEMMesh::displace(mfem::GridFunction const & displacement)
146{
147 _mfem_par_mesh->EnsureNodes();
148 mfem::GridFunction * nodes = _mfem_par_mesh->GetNodes();
149
150 *nodes += displacement;
151}
152
153void
155{
156 auto & dummy = static_cast<UnstructuredMesh &>(getMesh());
157 MeshTools::Generation::build_point(dummy);
158 if (dimension() >= 2)
159 MeshTools::Generation::build_square(dummy, 1, 1, 0., 1., 0., 1., ElemType::QUAD9);
160}
161
162void
163MFEMMesh::uniformRefinement(mfem::Mesh & mesh, const unsigned int nref) const
164{
165 for (unsigned int i = 0; i < nref; ++i)
166 mesh.UniformRefinement();
167}
168
169std::unique_ptr<MooseMesh>
171{
172 return _app.getFactory().copyConstruct(*this);
173}
174
175#endif
registerMooseObject("MooseApp", MFEMMesh)
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
std::unique_ptr< T > copyConstruct(const T &object)
Copy constructs the object object.
Definition Factory.h:358
virtual std::string getFileName() const override
Returns the name of the mesh file read to produce this mesh if any or an empty string otherwise.
Definition FileMesh.h:31
static InputParameters validParams()
Definition FileMesh.C:28
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object.
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump.
MFEMMesh inherits a MOOSE mesh class which allows us to work with other MOOSE objects.
Definition MFEMMesh.h:21
virtual ~MFEMMesh()
Definition MFEMMesh.C:51
std::optional< std::string > _mesh_displacement_variable
Holds name of variable used for mesh displacement, if set.
Definition MFEMMesh.h:95
std::unique_ptr< MooseMesh > safeClone() const override
Clones the mesh.
Definition MFEMMesh.C:170
unsigned int dimension() const override
Returns MeshBase::mesh_dimension(), (not MeshBase::spatial_dimension()!) of the underlying libMesh me...
Definition MFEMMesh.h:75
std::vector< std::filesystem::path > writeRecoveryFiles(const std::filesystem::path &file_base) override
Write the mesh files needed for recovery/checkpointing.
Definition MFEMMesh.C:128
static InputParameters validParams()
Definition MFEMMesh.C:21
void uniformRefinement(mfem::Mesh &mesh, const unsigned int nref) const
Performs a uniform refinement on the chosen mesh nref times.
Definition MFEMMesh.C:163
void displace(mfem::GridFunction const &displacement)
Displace the nodes of the mesh by the given displacement.
Definition MFEMMesh.C:145
void buildDummyMooseMesh()
Builds a placeholder mesh when no MOOSE mesh is required.
Definition MFEMMesh.C:154
void init() override
Build MFEM ParMesh and a placeholder MOOSE mesh.
Definition MFEMMesh.C:54
std::shared_ptr< mfem::ParMesh > _mfem_par_mesh
Smart pointers to mfem::ParMesh object.
Definition MFEMMesh.h:101
MFEMMesh(const InputParameters &parameters)
Definition MFEMMesh.C:49
void buildMesh() override
Must be overridden by child classes.
Definition MFEMMesh.C:80
Factory & getFactory()
Retrieve a writable reference to the Factory associated with this App.
Definition MooseApp.h:407
static const std::string & checkpointSuffix()
The file suffix for the checkpoint mesh.
Definition MooseApp.C:3039
bool isUltimateMaster() const
Whether or not this app is the ultimate master app.
Definition MooseApp.h:866
std::string getRestartRecoverFileBase() const
The file_base for the recovery file.
Definition MooseApp.h:500
bool isRecovering() const
Whether or not this is a "recover" calculation.
Definition MooseApp.C:1669
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
Definition MooseBase.h:457
bool isParamSetByUser(const std::string &name) const
Test if the supplied parameter is set by a user, as opposed to not set or set to default.
Definition MooseBase.h:205
virtual std::vector< std::filesystem::path > writeRecoveryFiles(const std::filesystem::path &file_base)
Write the mesh files needed for recovery/checkpointing.
Definition MooseMesh.C:2978
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
Definition MooseMesh.C:3549
virtual void init()
Initialize the Mesh object.
Definition MooseMesh.C:2929
bool allowRecovery() const
Returns whether this mesh is allowed to read a recovery file.
Definition MooseMesh.h:1575
MooseApp & _app
The MOOSE application this is associated with.
Definition MooseBase.h:375
processor_id_type processor_id() const
const Parallel::Communicator & comm() const
MeshBase & mesh