16 #include <unordered_map>
25 #include "axom/sidre/core/MFEMSidreDataCollection.hpp"
33 #include "serac/numerics/functional/geometry.hpp"
48 static void initialize(axom::sidre::DataStore& ds,
const std::string& output_directory);
55 static bool hasState(
const std::string& name) {
return named_states_.find(name) != named_states_.end(); }
68 template <
typename FunctionSpace>
71 SLIC_ERROR_ROOT_IF(!ds_,
"Serac's data store was not initialized - call StateManager::initialize first");
72 SLIC_ERROR_ROOT_IF(!
hasMesh(mesh_tag), axom::fmt::format(
"Mesh tag '{}' not found in the data store", mesh_tag));
73 SLIC_ERROR_ROOT_IF(
hasState(state_name),
74 axom::fmt::format(
"StateManager already contains a state named '{}'", state_name));
105 template <
typename T>
108 SLIC_ERROR_ROOT_IF(!ds_,
"Serac's data store was not initialized - call StateManager::initialize first");
109 SLIC_ERROR_ROOT_IF(!
hasMesh(mesh_tag),
110 axom::fmt::format(
"Serac's state manager does not have a mesh with given tag '{}'", mesh_tag));
112 constexpr
const char* qds_group_name =
"quadraturedatas";
115 auto& datacoll = datacolls_.at(mesh_tag);
116 axom::sidre::Group* bp_group = datacoll.GetBPGroup();
118 for (std::size_t i = 0; i < detail::qdata_geometries.size(); ++i) {
119 auto geom_type = detail::qdata_geometries[i];
122 if ((*qdata).data.find(geom_type) != (*qdata).data.end()) {
123 auto geom_name = detail::qdata_geometry_names[i];
126 auto states = (*qdata)[geom_type];
129 auto num_states =
static_cast<axom::IndexType
>(states.size());
130 SLIC_ERROR_ROOT_IF(num_states == 0,
"Number of States should be more than 0 at this point.");
131 auto state_size =
static_cast<axom::IndexType
>(
sizeof(*(states.begin())));
132 auto total_size = num_states * state_size;
134 auto num_uint8s = total_size /
static_cast<axom::IndexType
>(
sizeof(std::uint8_t));
137 axom::sidre::Group* qdatas_group = bp_group->createGroup(qds_group_name);
141 axom::sidre::Group* geom_group = qdatas_group->createGroup(std::string(geom_name));
142 geom_group->createViewScalar(
"num_states", num_states);
143 geom_group->createViewScalar(
"state_size", state_size);
144 geom_group->createViewScalar(
"total_size", total_size);
148 axom::sidre::View* states_view = geom_group->createView(
"states");
149 states_view->setExternalDataPtr(axom::sidre::UINT8_ID, num_uint8s, states.data());
154 SLIC_ERROR_ROOT_IF(!bp_group->hasGroup(qds_group_name),
155 axom::fmt::format(
"Loaded Sidre Datastore did not have group for Quadrature Datas"));
156 axom::sidre::Group* qdatas_group = bp_group->getGroup(qds_group_name);
158 !qdatas_group->hasGroup(std::string(geom_name)),
159 axom::fmt::format(
"Loaded Sidre Datastore did not have group for Quadrature Data geometry type '{}'",
160 std::string(geom_name)));
161 axom::sidre::Group* geom_group = qdatas_group->getGroup(std::string(geom_name));
164 auto verify_size = [](axom::sidre::Group* group,
int value,
const std::string& view_name,
165 const std::string& err_msg) {
167 !group->hasView(view_name),
168 axom::fmt::format(
"Loaded Sidre Datastore does not have value '{}' for Quadrature Data.", view_name));
169 auto prev_value = group->getView(view_name)->getData<axom::IndexType>();
170 SLIC_ERROR_IF(value != prev_value, axom::fmt::format(err_msg, value, prev_value));
172 verify_size(geom_group, num_states,
"num_states",
173 "Current number of Quadrature Data States '{}' does not match value in restart '{}'.");
174 verify_size(geom_group, state_size,
"state_size",
175 "Current size of Quadrature Data State '{}' does not match value in restart '{}'.");
176 verify_size(geom_group, total_size,
"total_size",
177 "Current total size of Quadrature Data States '{}' does not match value in restart '{}'.");
180 SLIC_ERROR_ROOT_IF(!geom_group->hasView(
"states"),
181 "Loaded Quadrature Data geometry Sidre view did not have 'states'");
182 axom::sidre::View* states_view = geom_group->getView(
"states");
183 states_view->setExternalDataPtr(states.data());
198 datacoll.LoadExternalData();
213 template <
typename T>
215 int order,
int dim, T initial_state)
219 std::array<uint32_t, mfem::Geometry::NUM_GEOMETRIES> elems =
geometry_counts(domain);
220 std::array<uint32_t, mfem::Geometry::NUM_GEOMETRIES> qpts_per_elem{};
222 std::vector<mfem::Geometry::Type> geometries;
224 geometries = {mfem::Geometry::TRIANGLE, mfem::Geometry::SQUARE};
226 geometries = {mfem::Geometry::TETRAHEDRON, mfem::Geometry::CUBE};
229 for (
auto geom : geometries) {
233 auto qdata = std::make_shared<QuadratureData<T>>(elems, qpts_per_elem, initial_state);
234 storeQuadratureData<T>(mesh_tag, qdata);
243 static bool hasDual(
const std::string& name) {
return named_duals_.find(name) != named_duals_.end(); }
256 template <
typename FunctionSpace>
259 SLIC_ERROR_ROOT_IF(!ds_,
"Serac's data store was not initialized - call StateManager::initialize first");
260 SLIC_ERROR_ROOT_IF(!
hasMesh(mesh_tag), axom::fmt::format(
"Mesh tag '{}' not found in the data store", mesh_tag));
261 SLIC_ERROR_ROOT_IF(
hasDual(dual_name),
262 axom::fmt::format(
"StateManager already contains a dual named '{}'", dual_name));
296 axom::fmt::format(
"State manager does not contain state named '{}'", state.
name()));
312 axom::fmt::format(
"State manager does not contain dual named '{}'",
dual.name()));
314 dual.space().GetRestrictionMatrix()->MultTranspose(
dual, *named_duals_[
dual.name()]);
323 static void save(
const double t,
const int cycle,
const std::string& mesh_tag);
331 static double load(
const int cycle_to_load,
const std::string& mesh_tag)
335 return newDataCollection(mesh_tag, cycle_to_load);
349 named_states_.clear();
350 named_duals_.clear();
351 shape_displacements_.clear();
352 shape_displacement_duals_.clear();
364 static bool hasMesh(
const std::string& mesh_tag) {
return datacolls_.find(mesh_tag) != datacolls_.end(); }
372 static mfem::ParMesh&
setMesh(std::unique_ptr<mfem::ParMesh> pmesh,
const std::string& mesh_tag);
379 static mfem::ParMesh&
mesh(
const std::string& mesh_tag);
430 static std::string
collectionID(
const mfem::ParMesh* pmesh);
443 static int cycle(std::string mesh_tag);
453 static double time(std::string mesh_tag);
462 static double newDataCollection(
const std::string& mesh_tag,
const std::optional<int> cycle_to_load = {});
469 static std::string getCollectionName(
const std::string& mesh_tag) {
return mesh_tag +
"_datacoll"; }
476 static void constructShapeFields(
const std::string& mesh_tag);
482 static std::unordered_map<std::string, axom::sidre::MFEMSidreDataCollection> datacolls_;
485 static std::unordered_map<std::string, std::unique_ptr<FiniteElementState>> shape_displacements_;
487 static std::unordered_map<std::string, std::unique_ptr<FiniteElementDual>> shape_displacement_duals_;
492 static bool is_restart_;
495 static axom::sidre::DataStore* ds_;
497 static std::string output_dir_;
500 static std::unordered_map<std::string, mfem::ParGridFunction*> named_states_;
502 static std::unordered_map<std::string, mfem::ParGridFunction*> named_duals_;
506 void checkMesh(
const mfem::ParMesh& pmesh,
bool is_restart =
false);
Class for encapsulating the dual vector space of a finite element space (i.e. the space of linear for...
Class for encapsulating the critical MFEM components of a primal finite element field.
void fillGridFunction(mfem::ParGridFunction &grid_function) const
Fill a user-provided grid function based on the underlying true vector.
std::string name() const
Returns the name of the FEState (field)
Manages the lifetimes of FEState objects such that restarts are abstracted from physics modules.
static void loadCheckpointedStates(int cycle_to_load, std::vector< FiniteElementState * > states_to_load)
loads the finite element states from a previously checkpointed cycle
static bool hasDual(const std::string &name)
Checks if StateManager has a dual with the given name.
static FiniteElementDual & shapeDisplacementDual(const std::string &mesh_tag)
Get the shape displacement finite element dual.
static void initialize(axom::sidre::DataStore &ds, const std::string &output_directory)
Initializes the StateManager with a sidre DataStore (into which state will be written/read)
static void updateState(const FiniteElementState &state)
Updates the StateManager-owned grid function using the values from a given FiniteElementState.
static bool isRestart()
Returns true if data was loaded into a DataCollection.
static std::shared_ptr< QuadratureData< T > > newQuadratureDataBuffer(const std::string &mesh_tag, const Domain &domain, int order, int dim, T initial_state)
Create a shared ptr to a quadrature data buffer for the given material type.
static void updateDual(const FiniteElementDual &dual)
Updates the StateManager-owned grid function using the values from a given FiniteElementDual.
static void storeDual(FiniteElementDual &dual)
Store a pre-constructed finite element dual in the state manager.
static int cycle(std::string mesh_tag)
Get the current cycle (iteration number) from the underlying datacollection.
static bool hasState(const std::string &name)
Checks if StateManager has a state with the given name.
static double load(const int cycle_to_load, const std::string &mesh_tag)
Loads an existing DataCollection.
static void storeQuadratureData(const std::string &mesh_tag, std::shared_ptr< QuadratureData< T >> qdata)
Store a pre-constructed Quadrature Data in the state manager.
static double time(std::string mesh_tag)
Get the current simulation time from the underlying datacollection.
static bool hasMesh(const std::string &mesh_tag)
Checks if StateManager has a mesh with the given mesh_tag.
static FiniteElementState newState(FunctionSpace space, const std::string &state_name, const std::string &mesh_tag)
Factory method for creating a new FEState object.
static std::string collectionID(const mfem::ParMesh *pmesh)
Returns the datacollection ID for a given mesh.
static void reset()
Resets the underlying global datacollection object.
static FiniteElementDual newDual(FunctionSpace space, const std::string &dual_name, const std::string &mesh_tag)
Factory method for creating a new FEDual object.
static mfem::ParMesh & mesh(const std::string &mesh_tag)
Returns a non-owning reference to mesh held by StateManager.
static void storeState(FiniteElementState &state)
Store a pre-constructed finite element state in the state manager.
static void save(const double t, const int cycle, const std::string &mesh_tag)
Updates the Conduit Blueprint state in the datastore and saves to a file.
static FiniteElementState & shapeDisplacement(const std::string &mesh_tag)
Get the shape displacement finite element state.
static mfem::ParMesh & setMesh(std::unique_ptr< mfem::ParMesh > pmesh, const std::string &mesh_tag)
Gives ownership of mesh to StateManager.
static FiniteElementDual & shapeDisplacementSensitivity(const std::string &mesh_tag)
Get the shape displacement sensitivity finite element dual.
many of the functions in this file amount to extracting element indices from an mesh_t like
Defines common types and helper functions for using the residual and scalar_objective classes.
This file contains helper traits and enumerations for classifying finite elements.
This contains a class that represents the dual of a finite element vector space, i....
This file contains the declaration of structure that manages the MFEM objects that make up the state ...
This file contains the all the necessary functions and macros required for logging as well as a helpe...
Accelerator functionality.
constexpr int num_quadrature_points(mfem::Geometry::Type g, int Q)
return the number of quadrature points in a Gauss-Legendre rule with parameter "Q"
std::array< uint32_t, mfem::Geometry::NUM_GEOMETRIES > geometry_counts(const Domain &domain)
count the number of elements of each geometry in a domain
void checkMesh(const mfem::ParMesh &pmesh, bool is_restart)
Check that a mesh satisfies our required properties.
dual(double, T) -> dual< T >
class template argument deduction guide for type dual.
This file contains the declaration of the structures that manage quadrature point data.
a class for representing a geometric region that can be used for integration
a small POD class for tracking function space metadata
A class for storing and access user-defined types at quadrature points.
Dual number struct (value plus gradient)