Using Sidre with MFEM¶
Note
The functionality described in this page is only available if Axom is
configured with MFEM and if the CMake variable
AXOM_ENABLE_MFEM_SIDRE_DATACOLLECTION
is set to ON
The MFEMSidreDataCollection
class implements MFEM’s
DataCollection
interface for recording simulation data. Specifically, it
knows about fields (mfem::GridFunction
objects) and the mesh on which
these fields are defined.
The MFEMSidreDataCollection
class internally organizes its data according
to the Mesh Blueprint, a hierarchical schema for describing mesh data.
See the Conduit page for more information on the Mesh Blueprint.
In this page, we first discuss how MFEM objects can
be associated with the MFEMSidreDataCollection
. We then explain the process
and options available when Saving Data to a File. The workflow for reading
saved data back in is discussed in Restarting a Simulation.
Associating MFEM Objects with an MFEMSidreDataCollection¶
We begin to describe the data in an MFEMSidreDataCollection
object by
registering an MFEM mesh with an instance of the class when we create the
data collection:
// Initialize the datacollection with the mesh
// Note: all fields (added with RegisterField) must be on this mesh
axom::sidre::MFEMSidreDataCollection dc("sidre_mfem_datacoll_vis_ex", mesh);
The MFEM mesh can also be registered after construction:
dc.SetMesh(/* mfem::Mesh* */ mesh);
Note
There is a 1-1 relationship between MFEMSidreDataCollection
objects and
MFEM meshes. That is, multiple meshes cannot be associated with a single
MFEMSidreDataCollection
.
After a mesh has been registered, fields can be association with the
MFEMSidreDataCollection
object:
// Note: Any number of fields can be registered
dc.RegisterField("solution", &soln);
Special kinds of fields (material-dependent fields, material set volume fraction fields, and species set values fields) require additional setup before they can be registered - see Mixed-material Fields for more informantion.
Saving Data to a File¶
The data in an instance of the MFEMSidreDataCollection
class can be saved
to a file using a variety of protocols. These files can be visualized with
tools like VisIt
or used to restart a simulation by loading them back into an instance of the
MFEMSidreDataCollection
class (see Restarting a Simulation).
Current options for output protocols/formats include:
sidre_hdf5
sidre_conduit_json
sidre_json
conduit_hdf5
Note
The AXOM_USE_HDF5
CMake build option must be enabled to use
HDF5-based formats.
Before saving, simulation state metadata should be updated. Currently, this metadata consists of:
cycle
, the current iteration number for the simulationtime
, the current simulation timetime_step
, the current simulation time step (sometimes calleddt
)
Each of these variables has a corresponding setter function:
// Save the initial state
dc.SetCycle(0); // Iteration counter
dc.SetTime(0.0); // Simulation time
dc.SetTimeStep(dt); // Time step
Note
There are also corresponding accessors for these state quantities (GetCycle
, GetTime
, GetTimeStep
).
Once state information has been updated, the complete simulation state can be written to a file:
// Filename and protocol, both of which are optional
dc.Save("sidre_mfem_datacoll_vis_ex", sidre_protocol);
Note
By default, saved files will be written to the current working directory.
To write to/read from a different directory, use SetPrefixPath
to
change the directory location of where the MFEMSidreDataCollection
object’s data will be written.
See the sidre_mfem_datacollection_vis
example for a more thorough example
of the above functionality.
Restarting a Simulation¶
Experimental support for complete reconstruction of a simulation mesh, fields,
and qfields is also provided by the MFEMSidreDataCollection
class. That is,
when an output file is read in using the MFEMSidreDataCollection::Load()
method, the data read in will be used to reconstruct MFEM objects than can be
accessed with the GetField
, GetQField
, and GetMesh
methods.
Warning
Currently, an MFEMSidreDataCollection
object must own the mesh and field
data in order to completely reconstruct simulation state. Mesh data
ownership can be configured with the owns_mesh_data
constructor option
(should be set to true
), and field data ownership requires that each
GridFunction
object be unallocated when passed to the
RegisterField()
method, which performs the allocation within Sidre-owned
memory. After registration, a GridFunction
object can be used normally.
The same conditions apply for QuadratureFunction
objects.
A complete demonstration of functionality is provided in the
sidre_mfem_datacollection_restart
example, which is a stripped-down
example of how a simulation code might utilize the automatic reconstruction logic when loading in a datastore.
Note
The mesh/field reconstruction logic requires that the saved file was created
with an MFEMSidreDataCollection
object. In Mesh Blueprint terms, the following
constraints are imposed on the structure of the data:
There must be a coordinate set named
coords
There must be a topology named
mesh
with corresponding attributes stored in a field namedmesh_material_attribute
There must be a topology named
boundary
with corresponding attributes stored in a field namedboundary_material_attribute
Mixed-material Fields¶
The Mesh Blueprint provides support for mixed-material simulations through
its material set construct. Material metadata (stored in
mfem::GridFunction
objects) can be registered with the
MFEMSidreDataCollection
like any other field (with the
RegisterField()
method), given that some additional setup is performed
and the field names match a specific naming convention.
Currently, there are three kinds of special fields that can be associated with mixed-material metadata:
Volume fraction fields in a material set (the per-element volume fraction of a given material)
Material-dependent fields (a different set of values for each material)
Species set fields (a different set of values for each material and for each dimension)
Material sets are defined by associating a volume fraction field name with a material set name:
// Inform the DataCollection that volume fraction information for a material set
// called "matset" will be in fields called "volume_fraction"
dc.AssociateMaterialSet("volume_fraction", "matset");
Once this association has been made, corresponding fields can be registered.
Their names must follow the format <associated volume fraction field name>_<material id>
, for example:
dc.RegisterField("volume_fraction_001", vol_frac_1);
dc.RegisterField("volume_fraction_002", vol_frac_2);
Material-dependent fields are defined by associating a field name with a material set name:
// Inform the DataCollection of a material-dependent field "density" associated
// with a material set called "matset"
dc.AssociateMaterialDependentField("density", "matset");
Material-specific values can be registered with a name in the format <associated dependent field name>_<material id>
:
dc.RegisterField("density", density_independent);
dc.RegisterField("density_001", density_dependent_1);
dc.RegisterField("density_002", density_dependent_2);
Species sets are defined by associating a field name with a species set name and corresponding material set name:
// Inform the DataCollection that species set data for the species set "specset"
// associated with material set "matset" will be in fields called "partial_density"
constexpr bool volume_dependent = false;
dc.AssociateSpeciesSet("partial_density", "specset", "matset", volume_dependent);
Species set values can be registered with the name in the format <associated field name>_<material id>_<component>
:
dc.RegisterField("partial_density_001_001", partial_density_1_1);
dc.RegisterField("partial_density_001_002", partial_density_1_2);
dc.RegisterField("partial_density_002_001", partial_density_2_1);
dc.RegisterField("partial_density_002_002", partial_density_2_2);