16 #include <unordered_map>
25 #include "axom/sidre/core/MFEMSidreDataCollection.hpp"
33 #include "smith/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_,
"Smith's data store was not initialized - call StateManager::initialize first");
72 SLIC_ERROR_ROOT_IF(!
hasMesh(mesh_tag), std::format(
"Mesh tag '{}' not found in the data store", mesh_tag));
73 SLIC_ERROR_ROOT_IF(
hasState(state_name),
74 std::format(
"StateManager already contains a state named '{}'", state_name));
105 template <
typename T>
108 SLIC_ERROR_ROOT_IF(!ds_,
"Smith's data store was not initialized - call StateManager::initialize first");
109 SLIC_ERROR_ROOT_IF(!
hasMesh(mesh_tag),
110 std::format(
"Smith'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 std::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 std::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));
163 verifyQuadratureDataSize(
164 geom_group, num_states,
"num_states",
165 "Current number of Quadrature Data States '{}' does not match value in restart '{}'.");
166 verifyQuadratureDataSize(geom_group, state_size,
"state_size",
167 "Current size of Quadrature Data State '{}' does not match value in restart '{}'.");
168 verifyQuadratureDataSize(
169 geom_group, total_size,
"total_size",
170 "Current total size of Quadrature Data States '{}' does not match value in restart '{}'.");
173 SLIC_ERROR_ROOT_IF(!geom_group->hasView(
"states"),
174 "Loaded Quadrature Data geometry Sidre view did not have 'states'");
175 axom::sidre::View* states_view = geom_group->getView(
"states");
176 states_view->setExternalDataPtr(states.data());
191 datacoll.LoadExternalData();
206 template <
typename T>
208 int order,
int dim, T initial_state)
212 std::array<uint32_t, mfem::Geometry::NUM_GEOMETRIES> elems =
geometry_counts(domain);
213 std::array<uint32_t, mfem::Geometry::NUM_GEOMETRIES> qpts_per_elem{};
215 std::vector<mfem::Geometry::Type> geometries;
217 geometries = {mfem::Geometry::TRIANGLE, mfem::Geometry::SQUARE};
219 geometries = {mfem::Geometry::TETRAHEDRON, mfem::Geometry::CUBE};
222 for (
auto geom : geometries) {
226 auto qdata = std::make_shared<QuadratureData<T>>(elems, qpts_per_elem, initial_state);
227 storeQuadratureData<T>(mesh_tag, qdata);
236 static bool hasDual(
const std::string& name) {
return named_duals_.find(name) != named_duals_.end(); }
249 template <
typename FunctionSpace>
252 SLIC_ERROR_ROOT_IF(!ds_,
"Smith's data store was not initialized - call StateManager::initialize first");
253 SLIC_ERROR_ROOT_IF(!
hasMesh(mesh_tag), std::format(
"Mesh tag '{}' not found in the data store", mesh_tag));
254 SLIC_ERROR_ROOT_IF(
hasDual(dual_name), std::format(
"StateManager already contains a dual named '{}'", dual_name));
288 std::format(
"State manager does not contain state named '{}'", state.
name()));
304 std::format(
"State manager does not contain dual named '{}'",
dual.name()));
306 dual.space().GetRestrictionMatrix()->MultTranspose(
dual, *named_duals_[
dual.name()]);
315 static void save(
const double t,
const int cycle,
const std::string& mesh_tag);
323 static double load(
const int cycle_to_load,
const std::string& mesh_tag)
327 return newDataCollection(mesh_tag, cycle_to_load);
341 named_states_.clear();
342 named_duals_.clear();
343 shape_displacements_.clear();
344 shape_displacement_duals_.clear();
356 static bool hasMesh(
const std::string& mesh_tag) {
return datacolls_.find(mesh_tag) != datacolls_.end(); }
364 static mfem::ParMesh&
setMesh(std::unique_ptr<mfem::ParMesh> pmesh,
const std::string& mesh_tag);
371 static mfem::ParMesh&
mesh(
const std::string& mesh_tag);
422 static std::string
collectionID(
const mfem::ParMesh* pmesh);
435 static int cycle(std::string mesh_tag);
445 static double time(std::string mesh_tag);
456 static void verifyQuadratureDataSize(axom::sidre::Group* group, axom::IndexType value,
const char* view_name,
459 SLIC_ERROR_IF(!group->hasView(view_name),
460 std::format(
"Loaded Sidre Datastore does not have value '{}' for Quadrature Data.", view_name));
461 auto prev_value = group->getView(view_name)->getData<axom::IndexType>();
462 SLIC_ERROR_IF(value != prev_value, std::vformat(err_msg, std::make_format_args(value, prev_value)));
471 static double newDataCollection(
const std::string& mesh_tag,
const std::optional<int> cycle_to_load = {});
478 static std::string getCollectionName(
const std::string& mesh_tag) {
return mesh_tag +
"_datacoll"; }
485 static void constructShapeFields(
const std::string& mesh_tag);
491 static std::unordered_map<std::string, axom::sidre::MFEMSidreDataCollection> datacolls_;
494 static std::unordered_map<std::string, std::unique_ptr<FiniteElementState>> shape_displacements_;
496 static std::unordered_map<std::string, std::unique_ptr<FiniteElementDual>> shape_displacement_duals_;
501 static bool is_restart_;
504 static axom::sidre::DataStore* ds_;
506 static std::string output_dir_;
509 static std::unordered_map<std::string, mfem::ParGridFunction*> named_states_;
511 static std::unordered_map<std::string, mfem::ParGridFunction*> named_duals_;
515 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 storeState(FiniteElementState &state)
Store a pre-constructed finite element state in the state manager.
static FiniteElementState & shapeDisplacement(const std::string &mesh_tag)
Get the shape displacement finite element state.
static FiniteElementDual & shapeDisplacementSensitivity(const std::string &mesh_tag)
Get the shape displacement sensitivity finite element dual.
static std::string collectionID(const mfem::ParMesh *pmesh)
Returns the datacollection ID for a given mesh.
static FiniteElementDual newDual(FunctionSpace space, const std::string &dual_name, const std::string &mesh_tag)
Factory method for creating a new FEDual object.
static void reset()
Resets the underlying global datacollection object.
static void updateDual(const FiniteElementDual &dual)
Updates the StateManager-owned grid function using the values from a given FiniteElementDual.
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 bool isRestart()
Returns true if data was loaded into a DataCollection.
static int cycle(std::string mesh_tag)
Get the current cycle (iteration number) from the underlying datacollection.
static bool hasMesh(const std::string &mesh_tag)
Checks if StateManager has a mesh with the given mesh_tag.
static void updateState(const FiniteElementState &state)
Updates the StateManager-owned grid function using the values from a given FiniteElementState.
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 mfem::ParMesh & setMesh(std::unique_ptr< mfem::ParMesh > pmesh, const std::string &mesh_tag)
Gives ownership of mesh to StateManager.
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 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 bool hasState(const std::string &name)
Checks if StateManager has a state with the given name.
static double time(std::string mesh_tag)
Get the current simulation time from the underlying datacollection.
static FiniteElementState newState(FunctionSpace space, const std::string &state_name, const std::string &mesh_tag)
Factory method for creating a new FEState object.
static double load(const int cycle_to_load, const std::string &mesh_tag)
Loads an existing DataCollection.
static mfem::ParMesh & mesh(const std::string &mesh_tag)
Returns a non-owning reference to mesh held by StateManager.
static void storeDual(FiniteElementDual &dual)
Store a pre-constructed finite element dual in the state manager.
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 loadCheckpointedStates(int cycle_to_load, std::vector< FiniteElementState * > states_to_load)
loads the finite element states from a previously checkpointed cycle
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.
std::array< uint32_t, mfem::Geometry::NUM_GEOMETRIES > geometry_counts(const Domain &domain)
count the number of elements of each geometry in a domain
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"
dual(double, T) -> dual< T >
class template argument deduction guide for type dual.
void checkMesh(const mfem::ParMesh &pmesh, bool is_restart)
Check that a mesh satisfies our required properties.
mfem::ParFiniteElementSpace & space(FieldState field)
Get the space from the primal field of a field states.
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)