Serac  0.1
Serac is an implicit thermal strucural mechanics simulation code.
state_manager.hpp
Go to the documentation of this file.
1 // Copyright (c) 2019-2024, Lawrence Livermore National Security, LLC and
2 // other Serac Project Developers. See the top-level LICENSE file for
3 // details.
4 //
5 // SPDX-License-Identifier: (BSD-3-Clause)
6 
13 #pragma once
14 
15 #include <optional>
16 #include <unordered_map>
17 
18 #include "mfem.hpp"
19 #include "axom/sidre/core/MFEMSidreDataCollection.hpp"
20 
25 
26 namespace serac {
27 
29 constexpr int SHAPE_ORDER = 1;
30 
33 
36 
41 class StateManager {
42 public:
48  static void initialize(axom::sidre::DataStore& ds, const std::string& output_directory);
49 
61  template <typename FunctionSpace>
62  static FiniteElementState newState(FunctionSpace space, const std::string& state_name, const std::string& mesh_tag)
63  {
64  SLIC_ERROR_ROOT_IF(!ds_, "Serac's data store was not initialized - call StateManager::initialize first");
65  SLIC_ERROR_ROOT_IF(datacolls_.find(mesh_tag) == datacolls_.end(),
66  axom::fmt::format("Mesh tag '{}' not found in the data store", mesh_tag));
67  SLIC_ERROR_ROOT_IF(named_states_.find(state_name) != named_states_.end(),
68  axom::fmt::format("StateManager already contains a state named '{}'", state_name));
69 
70  auto state = FiniteElementState(mesh(mesh_tag), space, state_name);
71 
72  storeState(state);
73  return state;
74  }
75 
83  static FiniteElementState newState(const mfem::ParFiniteElementSpace& space, const std::string& state_name);
84 
90  static void storeState(FiniteElementState& state);
91 
103  template <typename FunctionSpace>
104  static FiniteElementDual newDual(FunctionSpace space, const std::string& dual_name, const std::string& mesh_tag)
105  {
106  SLIC_ERROR_ROOT_IF(!ds_, "Serac's data store was not initialized - call StateManager::initialize first");
107  SLIC_ERROR_ROOT_IF(datacolls_.find(mesh_tag) == datacolls_.end(),
108  axom::fmt::format("Mesh tag '{}' not found in the data store", mesh_tag));
109  SLIC_ERROR_ROOT_IF(named_states_.find(dual_name) != named_duals_.end(),
110  axom::fmt::format("StateManager already contains a dual named '{}'", dual_name));
111 
112  auto dual = FiniteElementDual(mesh(mesh_tag), space, dual_name);
113 
114  storeDual(dual);
115  return dual;
116  }
124  static FiniteElementDual newDual(const mfem::ParFiniteElementSpace& space, const std::string& dual_name);
125 
131  static void storeDual(FiniteElementDual& dual);
132 
141  static void updateState(const FiniteElementState& state)
142  {
143  SLIC_ERROR_ROOT_IF(named_states_.find(state.name()) == named_states_.end(),
144  axom::fmt::format("State manager does not contain state named '{}'", state.name()));
145 
146  state.fillGridFunction(*named_states_[state.name()]);
147  }
148 
157  static void updateDual(const FiniteElementDual& dual)
158  {
159  SLIC_ERROR_ROOT_IF(named_duals_.find(dual.name()) == named_duals_.end(),
160  axom::fmt::format("State manager does not contain dual named '{}'", dual.name()));
161 
162  dual.space().GetRestrictionMatrix()->MultTranspose(dual, *named_duals_[dual.name()]);
163  }
164 
171  static void save(const double t, const int cycle, const std::string& mesh_tag);
172 
179  static double load(const int cycle_to_load, const std::string& mesh_tag)
180  {
181  // FIXME: Assumes that if one DataCollection is going to be reloaded all DataCollections will be
182  is_restart_ = true;
183  return newDataCollection(mesh_tag, cycle_to_load);
184  }
185 
195  static void reset()
196  {
197  named_states_.clear();
198  named_duals_.clear();
199  shape_displacements_.clear();
200  datacolls_.clear();
201  output_dir_.clear();
202  is_restart_ = false;
203  ds_ = nullptr;
204  };
205 
212  static mfem::ParMesh& setMesh(std::unique_ptr<mfem::ParMesh> pmesh, const std::string& mesh_tag);
213 
219  static mfem::ParMesh& mesh(const std::string& mesh_tag);
220 
230  static FiniteElementState& shapeDisplacement(const std::string& mesh_tag);
231 
238  static void loadCheckpointedStates(int cycle_to_load,
239  std::vector<std::reference_wrapper<FiniteElementState>> states_to_load);
240 
250  static FiniteElementDual& shapeDisplacementSensitivity(const std::string& mesh_tag);
251 
260  static std::string collectionID(const mfem::ParMesh* pmesh);
261 
263  static bool isRestart() { return is_restart_; }
264 
273  static int cycle(std::string mesh_tag);
274 
283  static double time(std::string mesh_tag);
284 
285 private:
292  static double newDataCollection(const std::string& name, const std::optional<int> cycle_to_load = {});
293 
299  static void constructShapeFields(const std::string& mesh_tag);
300 
305  static std::unordered_map<std::string, axom::sidre::MFEMSidreDataCollection> datacolls_;
306 
308  static std::unordered_map<std::string, std::unique_ptr<FiniteElementState>> shape_displacements_;
309 
313  static bool is_restart_;
314 
316  static axom::sidre::DataStore* ds_;
318  static std::string output_dir_;
319 
321  static std::unordered_map<std::string, mfem::ParGridFunction*> named_states_;
323  static std::unordered_map<std::string, mfem::ParGridFunction*> named_duals_;
324 };
325 
326 } // namespace serac
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< std::reference_wrapper< FiniteElementState >> states_to_load)
loads the finite element states from a previously checkpointed cycle
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 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 double load(const int cycle_to_load, const std::string &mesh_tag)
Loads an existing DataCollection.
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 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.
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.
Definition: serac.cpp:38
constexpr int SHAPE_ORDER
Polynomial order used to discretize the shape displacement field.
constexpr H1< SHAPE_ORDER, 2 > SHAPE_DIM_2
Function space for shape displacement on dimension 2 meshes.
constexpr H1< SHAPE_ORDER, 3 > SHAPE_DIM_3
Function space for shape displacement on dimension 2 meshes.
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.
H1 elements of order p.
Dual number struct (value plus gradient)
Definition: dual.hpp:29