Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions framework/doc/content/source/mfem/mesh/MFEMFileMesh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# MFEMFileMesh

!if! function=hasCapability('mfem')

## Overview

`MFEMFileMesh` reads an `mfem::ParMesh` from file for use in an `MFEMProblem`. Exodus files are
supported, along with other mesh formats listed [here](https://mfem.org/mesh-formats/).

As MOOSE checks for the existence of a `libMesh` MOOSE mesh at various points during setup,
`MFEMFileMesh` builds a dummy MOOSE mesh of a single point alongside the MFEM mesh. This dummy
mesh should not be used in an `MFEMProblem`; all MFEM objects should access the `mfem::ParMesh` via
the `getMFEMParMesh()` accessor as needed.

## Example Input File Syntax

!listing test/tests/mfem/kernels/diffusion.i block=Problem Mesh

!syntax parameters /Mesh/MFEMFileMesh

!syntax inputs /Mesh/MFEMFileMesh

!syntax children /Mesh/MFEMFileMesh

!if-end!

!else
!include mfem/mfem_warning.md
29 changes: 0 additions & 29 deletions framework/doc/content/source/mfem/mesh/MFEMMesh.md

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# MFEMGeneratedMeshGenerator

!if! function=hasCapability('mfem')

## Overview

`MFEMGeneratedMeshGenerator` generates a structured Cartesian MFEM mesh for use in an
`MFEMProblem`. It produces a line (1D), rectangle (2D), or box (3D) with uniformly spaced
elements, and is the MFEM analog of [GeneratedMeshGenerator.md].

The [!param](/Mesh/MFEMGeneratedMeshGenerator/dim) parameter is required and selects the spatial
dimension. Element type defaults to `QUAD` for 2D and `HEX` for 3D; `TRI` and `TET` are also
supported via [!param](/Mesh/MFEMGeneratedMeshGenerator/elem_type).

Named boundary sets are assigned automatically so boundaries can be referenced by name in
`[BCs]` blocks:

| Dimension | Boundary names |
|-----------|----------------|
| 1D | `left`, `right` |
| 2D | `bottom`, `right`, `top`, `left` |
| 3D | `bottom`, `front`, `right`, `back`, `left`, `top` |

## Example Input File Syntax

!listing test/tests/mfem/meshgenerators/generated/test.i block=Mesh BCs

!syntax parameters /Mesh/MFEMGeneratedMeshGenerator

!syntax inputs /Mesh/MFEMGeneratedMeshGenerator

!syntax children /Mesh/MFEMGeneratedMeshGenerator

!if-end!

!else
!include mfem/mfem_warning.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# MFEMElementAverageValue

!if! function=hasCapability('mfem')

## Overview

Computes the volumetric average of a scalar MFEM variable over the mesh or a block-restricted
subset of subdomains:

!equation
\bar{u} = \frac{\int_\Omega u \, \mathrm{d}V}{\int_\Omega \mathrm{d}V}

where $\Omega$ is the full mesh domain, or the union of subdomains specified by
[!param](/Postprocessors/MFEMElementAverageValue/block).

## Example Input File Syntax

!listing test/tests/mfem/meshgenerators/generated/test.i block=Postprocessors

!syntax parameters /Postprocessors/MFEMElementAverageValue

!syntax inputs /Postprocessors/MFEMElementAverageValue

!syntax children /Postprocessors/MFEMElementAverageValue

!if-end!

!else
!include mfem/mfem_warning.md
35 changes: 35 additions & 0 deletions framework/include/mfem/mesh/MFEMFileMesh.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//* This file is part of the MOOSE framework
//* https://mooseframework.inl.gov
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#ifdef MOOSE_MFEM_ENABLED

#pragma once

#include "MFEMMesh.h"

/**
* Reads an mfem::ParMesh from a file. All shared MFEM mesh plumbing lives in
* MFEMMesh; this class only adds the file parameter and implements
* buildSerialMFEMMesh() to load the mesh from disk.
*/
class MFEMFileMesh : public MFEMMesh
{
public:
static InputParameters validParams();

MFEMFileMesh(const InputParameters & parameters);
virtual ~MFEMFileMesh();

std::unique_ptr<MooseMesh> safeClone() const override;

protected:
mfem::Mesh buildSerialMFEMMesh() override;
};

#endif
65 changes: 17 additions & 48 deletions framework/include/mfem/mesh/MFEMMesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,61 +11,34 @@

#pragma once

#include "FileMesh.h"
#include "MooseMesh.h"

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

MFEMMesh(const InputParameters & parameters);

virtual ~MFEMMesh();

/**
* Accessors for the _mfem_par_mesh object. If the mesh has
* not been build, the methods will call the appropriate protected methods to
* build them.
*/
mfem::ParMesh & getMFEMParMesh() { return *_mfem_par_mesh; }
const mfem::ParMesh & getMFEMParMesh() const;

/**
* Copy a shared_ptr to the mfem::ParMesh object.
*/
std::shared_ptr<mfem::ParMesh> getMFEMParMeshPtr() { return _mfem_par_mesh; }

/**
* Build MFEM ParMesh and a placeholder MOOSE mesh.
*/
void buildMesh() override;

/**
* Clones the mesh.
*/
std::unique_ptr<MooseMesh> safeClone() const override;

/**
* Returns true if mesh displacement is required.
*/
bool shouldDisplace() const { return _mesh_displacement_variable.has_value(); }

/**
* Returns an optional reference to displacement variable name.
*/
std::optional<std::reference_wrapper<std::string const>> getMeshDisplacementVariable() const
{
return _mesh_displacement_variable;
}

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

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

private:
void buildMesh() override;

protected:
/**
* Builds a placeholder mesh when no MOOSE mesh is required.
* Build and return the serial mfem::Mesh for this object. Also responsible
* for setting up the libMesh dummy placeholder (via buildDummyMooseMesh()).
*/
virtual mfem::Mesh buildSerialMFEMMesh() = 0;

/// Replaces the underlying libMesh mesh with a single-point placeholder.
void buildDummyMooseMesh();

/**
* Performs a uniform refinement on the chosen mesh nref times.
*/
void uniformRefinement(mfem::Mesh & mesh, const unsigned int nref) const;
/// Applies uniform refinement to mesh nref times.
void uniformRefinement(mfem::Mesh & mesh, unsigned int nref) const;

/**
* Holds name of variable used for mesh displacement, if set.
*/
std::optional<std::string> _mesh_displacement_variable;

/**
* Smart pointers to mfem::ParMesh object. Do not access directly.
* Use the accessors instead.
*/
std::shared_ptr<mfem::ParMesh> _mfem_par_mesh{nullptr};
};

Expand Down
39 changes: 39 additions & 0 deletions framework/include/mfem/mesh/MFEMMeshCarrier.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//* This file is part of the MOOSE framework
//* https://mooseframework.inl.gov
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#ifdef MOOSE_MFEM_ENABLED

#pragma once

#include "libmesh/replicated_mesh.h"

/**
* A thin libMesh::ReplicatedMesh subclass that carries an mfem::Mesh through the
* MeshGenerator pipeline. The libMesh side is always empty; it exists only to satisfy
* the std::unique_ptr<MeshBase> return type of MeshGenerator::generate(). MFEM mesh
* generators wrap their output in this carrier and unwrap their inputs from it.
*/
class MFEMMeshCarrier : public libMesh::ReplicatedMesh
{
public:
explicit MFEMMeshCarrier(const Parallel::Communicator & comm);

void setMFEMMesh(mfem::Mesh mesh) { _mfem_mesh = std::move(mesh); }

mfem::Mesh & getMFEMMesh() { return _mfem_mesh; }
const mfem::Mesh & getMFEMMesh() const { return _mfem_mesh; }

/// Move the held mfem::Mesh out; leaves the carrier with a default-constructed (empty) mesh.
mfem::Mesh releaseMFEMMesh() { return std::move(_mfem_mesh); }

private:
mfem::Mesh _mfem_mesh;
};

#endif
39 changes: 39 additions & 0 deletions framework/include/mfem/mesh/MFEMMeshGeneratorMesh.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//* This file is part of the MOOSE framework
//* https://mooseframework.inl.gov
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#ifdef MOOSE_MFEM_ENABLED

#pragma once

#include "MFEMMesh.h"

/**
* MooseMesh subclass that consumes the MeshGenerator pipeline to build an
* mfem::ParMesh. It is the MFEM analog of MeshGeneratorMesh: use it as the
* [Mesh] type (or let SetupMeshAction auto-select it) whenever one or more
* MFEMMeshGenerator objects are present.
*
* All shared MFEM mesh plumbing lives in MFEMMesh; this class implements
* buildSerialMFEMMesh() to extract the mfem::Mesh from the MFEMMeshCarrier
* produced by the generator pipeline.
*/
class MFEMMeshGeneratorMesh : public MFEMMesh
{
public:
static InputParameters validParams();

MFEMMeshGeneratorMesh(const InputParameters & parameters);

std::unique_ptr<MooseMesh> safeClone() const override;

protected:
mfem::Mesh buildSerialMFEMMesh() override;
};

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//* This file is part of the MOOSE framework
//* https://mooseframework.inl.gov
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#ifdef MOOSE_MFEM_ENABLED

#pragma once

#include "MFEMMeshGenerator.h"

/**
* Generates a structured Cartesian MFEM mesh: a line (1D), rectangle (2D), or
* box (3D) with uniformly spaced elements. Analogous to GeneratedMeshGenerator
* for the MFEM mesh pipeline.
*/
class MFEMGeneratedMeshGenerator : public MFEMMeshGenerator
{
public:
static InputParameters validParams();

MFEMGeneratedMeshGenerator(const InputParameters & parameters);

protected:
mfem::Mesh generateMFEMMesh() override;

private:
const unsigned int _dim;
const unsigned int _nx;
const unsigned int _ny;
const unsigned int _nz;
const Real _xmax;
const Real _ymax;
const Real _zmax;
};

#endif
Loading