Skip to content

Commit 54144f1

Browse files
lindsayadclaude
andcommitted
Add MFEM-native mesh generator infrastructure
Introduces MFEMMeshGenerator (abstract base + carrier pipeline), MFEMGeneratedMeshGenerator (structured Cartesian meshes in 1D/2D/3D with named boundary sets), and refactors the existing MFEM mesh hierarchy so MFEMMesh is the abstract base and MFEMFileMesh is the concrete file-reading subclass. Updates MFEMProblem::mesh() to accept any MFEMMesh subclass, bulk-renames test input files from MFEMMesh to MFEMFileMesh, and adds doc pages for MFEMGeneratedMeshGenerator, MFEMFileMesh, and MFEMElementAverageValue. Closes #32827 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 1b9961e commit 54144f1

76 files changed

Lines changed: 925 additions & 183 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# MFEMFileMesh
2+
3+
!if! function=hasCapability('mfem')
4+
5+
## Overview
6+
7+
`MFEMFileMesh` reads an `mfem::ParMesh` from file for use in an `MFEMProblem`. Exodus files are
8+
supported, along with other mesh formats listed [here](https://mfem.org/mesh-formats/).
9+
10+
As MOOSE checks for the existence of a `libMesh` MOOSE mesh at various points during setup,
11+
`MFEMFileMesh` builds a dummy MOOSE mesh of a single point alongside the MFEM mesh. This dummy
12+
mesh should not be used in an `MFEMProblem`; all MFEM objects should access the `mfem::ParMesh` via
13+
the `getMFEMParMesh()` accessor as needed.
14+
15+
## Example Input File Syntax
16+
17+
!listing test/tests/mfem/kernels/diffusion.i block=Problem Mesh
18+
19+
!syntax parameters /Mesh/MFEMFileMesh
20+
21+
!syntax inputs /Mesh/MFEMFileMesh
22+
23+
!syntax children /Mesh/MFEMFileMesh
24+
25+
!if-end!
26+
27+
!else
28+
!include mfem/mfem_warning.md

framework/doc/content/source/mfem/mesh/MFEMMesh.md

Lines changed: 0 additions & 29 deletions
This file was deleted.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# MFEMGeneratedMeshGenerator
2+
3+
!if! function=hasCapability('mfem')
4+
5+
## Overview
6+
7+
`MFEMGeneratedMeshGenerator` generates a structured Cartesian MFEM mesh for use in an
8+
`MFEMProblem`. It produces a line (1D), rectangle (2D), or box (3D) with uniformly spaced
9+
elements, and is the MFEM analog of [GeneratedMeshGenerator.md].
10+
11+
The [!param](/Mesh/MFEMGeneratedMeshGenerator/dim) parameter is required and selects the spatial
12+
dimension. Element type defaults to `QUAD` for 2D and `HEX` for 3D; `TRI` and `TET` are also
13+
supported via [!param](/Mesh/MFEMGeneratedMeshGenerator/elem_type).
14+
15+
Named boundary sets are assigned automatically so boundaries can be referenced by name in
16+
`[BCs]` blocks:
17+
18+
| Dimension | Boundary names |
19+
|-----------|----------------|
20+
| 1D | `left`, `right` |
21+
| 2D | `bottom`, `right`, `top`, `left` |
22+
| 3D | `bottom`, `front`, `right`, `back`, `left`, `top` |
23+
24+
## Example Input File Syntax
25+
26+
!listing test/tests/mfem/meshgenerators/generated/test.i block=Mesh BCs
27+
28+
!syntax parameters /Mesh/MFEMGeneratedMeshGenerator
29+
30+
!syntax inputs /Mesh/MFEMGeneratedMeshGenerator
31+
32+
!syntax children /Mesh/MFEMGeneratedMeshGenerator
33+
34+
!if-end!
35+
36+
!else
37+
!include mfem/mfem_warning.md
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# MFEMElementAverageValue
2+
3+
!if! function=hasCapability('mfem')
4+
5+
## Overview
6+
7+
Computes the volumetric average of a scalar MFEM variable over the mesh or a block-restricted
8+
subset of subdomains:
9+
10+
!equation
11+
\bar{u} = \frac{\int_\Omega u \, \mathrm{d}V}{\int_\Omega \mathrm{d}V}
12+
13+
where $\Omega$ is the full mesh domain, or the union of subdomains specified by
14+
[!param](/Postprocessors/MFEMElementAverageValue/block).
15+
16+
## Example Input File Syntax
17+
18+
!listing test/tests/mfem/meshgenerators/generated/test.i block=Postprocessors
19+
20+
!syntax parameters /Postprocessors/MFEMElementAverageValue
21+
22+
!syntax inputs /Postprocessors/MFEMElementAverageValue
23+
24+
!syntax children /Postprocessors/MFEMElementAverageValue
25+
26+
!if-end!
27+
28+
!else
29+
!include mfem/mfem_warning.md
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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+
#pragma once
13+
14+
#include "MFEMMesh.h"
15+
16+
/**
17+
* Reads an mfem::ParMesh from a file. All shared MFEM mesh plumbing lives in
18+
* MFEMMesh; this class only adds the file parameter and implements
19+
* buildSerialMFEMMesh() to load the mesh from disk.
20+
*/
21+
class MFEMFileMesh : public MFEMMesh
22+
{
23+
public:
24+
static InputParameters validParams();
25+
26+
MFEMFileMesh(const InputParameters & parameters);
27+
virtual ~MFEMFileMesh();
28+
29+
std::unique_ptr<MooseMesh> safeClone() const override;
30+
31+
protected:
32+
mfem::Mesh buildSerialMFEMMesh() override;
33+
};
34+
35+
#endif

framework/include/mfem/mesh/MFEMMesh.h

Lines changed: 17 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -11,61 +11,34 @@
1111

1212
#pragma once
1313

14-
#include "FileMesh.h"
14+
#include "MooseMesh.h"
1515

1616
/**
17-
* MFEMMesh inherits a MOOSE mesh class which allows us to work with
18-
* other MOOSE objects. It contains a pointer to the parallel MFEM mesh.
17+
* Abstract MooseMesh base for all MFEM-backed mesh types (MFEMFileMesh,
18+
* MFEMMeshGeneratorMesh). Holds the mfem::ParMesh and owns the shared
19+
* MFEM mesh interface. Subclasses implement buildSerialMFEMMesh() to
20+
* supply the serial mesh; buildMesh() handles the common post-processing
21+
* (refinement, reordering, partitioning) using the template-method pattern.
1922
*/
20-
class MFEMMesh : public FileMesh
23+
class MFEMMesh : public MooseMesh
2124
{
2225
public:
2326
static InputParameters validParams();
2427

2528
MFEMMesh(const InputParameters & parameters);
2629

27-
virtual ~MFEMMesh();
28-
29-
/**
30-
* Accessors for the _mfem_par_mesh object. If the mesh has
31-
* not been build, the methods will call the appropriate protected methods to
32-
* build them.
33-
*/
3430
mfem::ParMesh & getMFEMParMesh() { return *_mfem_par_mesh; }
3531
const mfem::ParMesh & getMFEMParMesh() const;
3632

37-
/**
38-
* Copy a shared_ptr to the mfem::ParMesh object.
39-
*/
4033
std::shared_ptr<mfem::ParMesh> getMFEMParMeshPtr() { return _mfem_par_mesh; }
4134

42-
/**
43-
* Build MFEM ParMesh and a placeholder MOOSE mesh.
44-
*/
45-
void buildMesh() override;
46-
47-
/**
48-
* Clones the mesh.
49-
*/
50-
std::unique_ptr<MooseMesh> safeClone() const override;
51-
52-
/**
53-
* Returns true if mesh displacement is required.
54-
*/
5535
bool shouldDisplace() const { return _mesh_displacement_variable.has_value(); }
5636

57-
/**
58-
* Returns an optional reference to displacement variable name.
59-
*/
6037
std::optional<std::reference_wrapper<std::string const>> getMeshDisplacementVariable() const
6138
{
6239
return _mesh_displacement_variable;
6340
}
6441

65-
/**
66-
* Displace the nodes of the mesh by the given displacement.
67-
* Does not update FE spaces for variables.
68-
*/
6942
void displace(mfem::GridFunction const & displacement);
7043

7144
bool isDistributedMesh() const override { return true; }
@@ -75,26 +48,22 @@ class MFEMMesh : public FileMesh
7548
dof_id_type nActiveElem() const override { return _mfem_par_mesh->GetGlobalNE(); }
7649
dof_id_type nActiveLocalElem() const override { return _mfem_par_mesh->GetNE(); }
7750

78-
private:
51+
void buildMesh() override;
52+
53+
protected:
7954
/**
80-
* Builds a placeholder mesh when no MOOSE mesh is required.
55+
* Build and return the serial mfem::Mesh for this object. Also responsible
56+
* for setting up the libMesh dummy placeholder (via buildDummyMooseMesh()).
8157
*/
58+
virtual mfem::Mesh buildSerialMFEMMesh() = 0;
59+
60+
/// Replaces the underlying libMesh mesh with a single-point placeholder.
8261
void buildDummyMooseMesh();
8362

84-
/**
85-
* Performs a uniform refinement on the chosen mesh nref times.
86-
*/
87-
void uniformRefinement(mfem::Mesh & mesh, const unsigned int nref) const;
63+
/// Applies uniform refinement to mesh nref times.
64+
void uniformRefinement(mfem::Mesh & mesh, unsigned int nref) const;
8865

89-
/**
90-
* Holds name of variable used for mesh displacement, if set.
91-
*/
9266
std::optional<std::string> _mesh_displacement_variable;
93-
94-
/**
95-
* Smart pointers to mfem::ParMesh object. Do not access directly.
96-
* Use the accessors instead.
97-
*/
9867
std::shared_ptr<mfem::ParMesh> _mfem_par_mesh{nullptr};
9968
};
10069

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
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+
#pragma once
13+
14+
#include "libmesh/replicated_mesh.h"
15+
16+
/**
17+
* A thin libMesh::ReplicatedMesh subclass that carries an mfem::Mesh through the
18+
* MeshGenerator pipeline. The libMesh side is always empty; it exists only to satisfy
19+
* the std::unique_ptr<MeshBase> return type of MeshGenerator::generate(). MFEM mesh
20+
* generators wrap their output in this carrier and unwrap their inputs from it.
21+
*/
22+
class MFEMMeshCarrier : public libMesh::ReplicatedMesh
23+
{
24+
public:
25+
explicit MFEMMeshCarrier(const Parallel::Communicator & comm);
26+
27+
void setMFEMMesh(mfem::Mesh mesh) { _mfem_mesh = std::move(mesh); }
28+
29+
mfem::Mesh & getMFEMMesh() { return _mfem_mesh; }
30+
const mfem::Mesh & getMFEMMesh() const { return _mfem_mesh; }
31+
32+
/// Move the held mfem::Mesh out; leaves the carrier with a default-constructed (empty) mesh.
33+
mfem::Mesh releaseMFEMMesh() { return std::move(_mfem_mesh); }
34+
35+
private:
36+
mfem::Mesh _mfem_mesh;
37+
};
38+
39+
#endif
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
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+
#pragma once
13+
14+
#include "MFEMMesh.h"
15+
16+
/**
17+
* MooseMesh subclass that consumes the MeshGenerator pipeline to build an
18+
* mfem::ParMesh. It is the MFEM analog of MeshGeneratorMesh: use it as the
19+
* [Mesh] type (or let SetupMeshAction auto-select it) whenever one or more
20+
* MFEMMeshGenerator objects are present.
21+
*
22+
* All shared MFEM mesh plumbing lives in MFEMMesh; this class implements
23+
* buildSerialMFEMMesh() to extract the mfem::Mesh from the MFEMMeshCarrier
24+
* produced by the generator pipeline.
25+
*/
26+
class MFEMMeshGeneratorMesh : public MFEMMesh
27+
{
28+
public:
29+
static InputParameters validParams();
30+
31+
MFEMMeshGeneratorMesh(const InputParameters & parameters);
32+
33+
std::unique_ptr<MooseMesh> safeClone() const override;
34+
35+
protected:
36+
mfem::Mesh buildSerialMFEMMesh() override;
37+
};
38+
39+
#endif
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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+
#pragma once
13+
14+
#include "MFEMMeshGenerator.h"
15+
16+
/**
17+
* Generates a structured Cartesian MFEM mesh: a line (1D), rectangle (2D), or
18+
* box (3D) with uniformly spaced elements. Analogous to GeneratedMeshGenerator
19+
* for the MFEM mesh pipeline.
20+
*/
21+
class MFEMGeneratedMeshGenerator : public MFEMMeshGenerator
22+
{
23+
public:
24+
static InputParameters validParams();
25+
26+
MFEMGeneratedMeshGenerator(const InputParameters & parameters);
27+
28+
protected:
29+
mfem::Mesh generateMFEMMesh() override;
30+
31+
private:
32+
const unsigned int _dim;
33+
const unsigned int _nx;
34+
const unsigned int _ny;
35+
const unsigned int _nz;
36+
const Real _xmax;
37+
const Real _ymax;
38+
const Real _zmax;
39+
};
40+
41+
#endif

0 commit comments

Comments
 (0)