Smith  0.1
Smith is an implicit thermal structural mechanics simulation code.
field_store.cpp
1 // Copyright (c) Lawrence Livermore National Security, LLC and
2 // other Smith Project Developers. See the top-level LICENSE file for
3 // details.
4 //
5 // SPDX-License-Identifier: (BSD-3-Clause)
6 
7 #include "smith/differentiable_numerics/field_store.hpp"
10 #include "gretl/wang_checkpoint_strategy.hpp"
11 
12 namespace smith {
13 
14 FieldStore::FieldStore(std::shared_ptr<Mesh> mesh, size_t storage_size)
15  : mesh_(mesh),
16  graph_(std::make_shared<gretl::DataStore>(std::make_unique<gretl::WangCheckpointStrategy>(storage_size)))
17 {
18 }
19 
20 std::shared_ptr<DirichletBoundaryConditions> FieldStore::addBoundaryConditions(FEFieldPtr field)
21 {
22  boundary_conditions_.push_back(std::make_shared<DirichletBoundaryConditions>(mesh_->mfemParMesh(), field->space()));
23  return boundary_conditions_.back();
24 }
25 
26 void FieldStore::addWeakFormUnknownArg(std::string weak_form_name, std::string argument_name, size_t argument_index)
27 {
28  FieldLabel argument_name_and_index{.field_name = argument_name, .field_index_in_residual = argument_index};
29  if (weak_form_name_to_unknown_name_index_.count(weak_form_name)) {
30  weak_form_name_to_unknown_name_index_.at(weak_form_name).push_back(argument_name_and_index);
31  } else {
32  weak_form_name_to_unknown_name_index_[weak_form_name] = std::vector<FieldLabel>{argument_name_and_index};
33  }
34 }
35 
36 void FieldStore::addWeakFormArg(std::string weak_form_name, std::string argument_name, size_t argument_index)
37 {
38  // Store the field name instead of index to avoid confusion between states_ and params_ indices
39  if (weak_form_name_to_field_names_.count(weak_form_name)) {
40  weak_form_name_to_field_names_.at(weak_form_name).push_back(argument_name);
41  } else {
42  weak_form_name_to_field_names_[weak_form_name] = std::vector<std::string>{argument_name};
43  }
44  SLIC_ERROR_IF(argument_index + 1 != weak_form_name_to_field_names_.at(weak_form_name).size(),
45  "Invalid order for adding weak form arguments.");
46 }
47 
49 {
50  for (auto& keyval : weak_form_name_to_unknown_name_index_) {
51  std::cout << "for residual: " << keyval.first << " ";
52  for (auto& name_index : keyval.second) {
53  std::cout << "arg " << name_index.field_name << " at " << name_index.field_index_in_residual << ", ";
54  }
55  std::cout << std::endl;
56  }
57 }
58 
59 std::vector<std::vector<size_t>> FieldStore::indexMap(const std::vector<std::string>& residual_names) const
60 {
61  std::vector<std::vector<size_t>> block_indices(residual_names.size());
62 
63  for (size_t res_i = 0; res_i < residual_names.size(); ++res_i) {
64  std::vector<size_t>& res_indices = block_indices[res_i];
65  res_indices = std::vector<size_t>(num_unknowns_, invalid_block_index);
66  const std::string& res_name = residual_names[res_i];
67  const auto& arg_info = weak_form_name_to_unknown_name_index_.at(res_name);
68 
69  for (const auto& field_name_and_arg_index : arg_info) {
70  const std::string field_name = field_name_and_arg_index.field_name;
71  size_t unknown_index = to_unknown_index_.at(field_name);
72  SLIC_ASSERT(unknown_index < num_unknowns_);
73  res_indices[unknown_index] = field_name_and_arg_index.field_index_in_residual;
74  }
75  }
76 
77  return block_indices;
78 }
79 
80 std::vector<const BoundaryConditionManager*> FieldStore::getBoundaryConditionManagers() const
81 {
82  std::vector<const BoundaryConditionManager*> bcs;
83  for (auto& bc : boundary_conditions_) {
84  bcs.push_back(&bc->getBoundaryConditionManager());
85  }
86  return bcs;
87 }
88 
89 std::shared_ptr<DirichletBoundaryConditions> FieldStore::getBoundaryConditions(size_t unknown_index) const
90 {
91  SLIC_ERROR_IF(unknown_index >= boundary_conditions_.size(), "Unknown index out of bounds for boundary conditions");
92  return boundary_conditions_[unknown_index];
93 }
94 
95 size_t FieldStore::getFieldIndex(const std::string& field_name) const
96 {
97  if (to_states_index_.count(field_name)) {
98  return to_states_index_.at(field_name);
99  }
100  if (to_params_index_.count(field_name)) {
101  return to_params_index_.at(field_name);
102  }
103  SLIC_ERROR("Field or parameter '" << field_name << "' not found in getFieldIndex");
104  return 0; // unreachable
105 }
106 
107 FieldState FieldStore::getField(const std::string& field_name) const
108 {
109  // Check if it's a state field
110  if (to_states_index_.count(field_name)) {
111  size_t field_index = to_states_index_.at(field_name);
112  return states_[field_index];
113  }
114  // Otherwise check if it's a parameter
115  if (to_params_index_.count(field_name)) {
116  size_t param_index = to_params_index_.at(field_name);
117  return params_[param_index];
118  }
119  SLIC_ERROR("Field or parameter '" << field_name << "' not found");
120  return states_[0]; // unreachable, but needed for compilation
121 }
122 
123 FieldState FieldStore::getParameter(const std::string& param_name) const
124 {
125  size_t param_index = to_params_index_.at(param_name);
126  return params_[param_index];
127 }
128 
129 void FieldStore::setField(const std::string& field_name, FieldState updated_field)
130 {
131  size_t field_index = getFieldIndex(field_name);
132  states_[field_index] = updated_field;
133 }
134 
135 FieldState FieldStore::getShapeDisp() const { return shape_disp_[0]; }
136 
137 const std::vector<FieldState>& FieldStore::getAllFields() const { return states_; }
138 
139 std::vector<FieldState> FieldStore::getStates(const std::string& weak_form_name) const
140 {
141  // Validate that weak form is registered
142  SLIC_ERROR_ROOT_IF(
143  weak_form_name_to_field_names_.count(weak_form_name) == 0,
144  axom::fmt::format("Weak form '{}' not found in FieldStore. Did you forget to call addResireaction()?",
145  weak_form_name));
146 
147  auto field_names = weak_form_name_to_field_names_.at(weak_form_name);
148  std::vector<FieldState> fields_for_residual;
149  for (auto& name : field_names) {
150  // Validate that field exists
151  SLIC_ERROR_ROOT_IF(
152  to_states_index_.count(name) == 0 && to_params_index_.count(name) == 0,
153  axom::fmt::format("Field '{}' (required by weak form '{}') not found in FieldStore", name, weak_form_name));
154 
155  // Only include state fields, not parameters
156  // Parameters are passed separately to avoid duplication in block_solve
157  if (to_states_index_.count(name)) {
158  fields_for_residual.push_back(getField(name));
159  }
160  }
161  return fields_for_residual;
162 }
163 
164 std::vector<FieldState> FieldStore::getStatesFromVectors(const std::string& weak_form_name,
165  const std::vector<FieldState>& state_fields,
166  const std::vector<FieldState>& param_fields) const
167 {
168  // Validate that weak form is registered
169  SLIC_ERROR_ROOT_IF(
170  weak_form_name_to_field_names_.count(weak_form_name) == 0,
171  axom::fmt::format("Weak form '{}' not found in FieldStore. Did you forget to call addResireaction()?",
172  weak_form_name));
173 
174  auto field_names = weak_form_name_to_field_names_.at(weak_form_name);
175  std::vector<FieldState> fields_for_residual;
176  for (auto& name : field_names) {
177  // Check if it's a state field
178  if (to_states_index_.count(name)) {
179  size_t idx = to_states_index_.at(name);
180  SLIC_ERROR_ROOT_IF(idx >= state_fields.size(),
181  axom::fmt::format("State field index {} out of bounds (size={}) for field '{}'", idx,
182  state_fields.size(), name));
183  fields_for_residual.push_back(state_fields[idx]);
184  }
185  // Otherwise check if it's a parameter
186  else if (to_params_index_.count(name)) {
187  size_t idx = to_params_index_.at(name);
188  SLIC_ERROR_ROOT_IF(idx >= param_fields.size(),
189  axom::fmt::format("Parameter field index {} out of bounds (size={}) for field '{}'", idx,
190  param_fields.size(), name));
191  fields_for_residual.push_back(param_fields[idx]);
192  } else {
193  SLIC_ERROR_ROOT(axom::fmt::format("Field or parameter '{}' (required by weak form '{}') not found in FieldStore",
194  name, weak_form_name));
195  }
196  }
197  return fields_for_residual;
198 }
199 
200 const std::shared_ptr<smith::Mesh>& FieldStore::getMesh() const { return mesh_; }
201 
202 const std::shared_ptr<gretl::DataStore>& FieldStore::graph() const { return graph_; }
203 
204 const std::vector<std::pair<std::shared_ptr<TimeIntegrationRule>, FieldStore::TimeIntegrationMapping>>&
206 {
207  return time_integration_rules_;
208 }
209 
210 size_t FieldStore::getUnknownIndex(const std::string& field_name) const { return to_unknown_index_.at(field_name); }
211 
212 void FieldStore::setField(size_t index, FieldState updated_field) { states_[index] = updated_field; }
213 
214 void FieldStore::addWeakFormReaction(std::string weak_form_name, std::string field_name)
215 {
216  weak_form_to_test_field_[weak_form_name] = field_name;
217 }
218 
219 std::string FieldStore::getWeakFormReaction(const std::string& weak_form_name) const
220 {
221  return weak_form_to_test_field_.at(weak_form_name);
222 }
223 
224 } // namespace smith
Contains DirichletBoundaryConditions class for interaction with the differentiable solve interfaces.
Accelerator functionality.
Definition: smith.cpp:36
std::shared_ptr< FiniteElementState > FEFieldPtr
typedef
Definition: field_state.hpp:20
gretl::State< FEFieldPtr, FEDualPtr > FieldState
typedef
Definition: field_state.hpp:22
Methods for solving systems of equations as given by WeakForms. Tracks these operations on the gretl ...
Mapping between primary and history/derivative fields for time integration.
size_t getUnknownIndex(const std::string &field_name) const
Get the unknown index of a field by name.
void printMap()
Print the internal field maps for debugging.
Definition: field_store.cpp:48
const std::vector< std::pair< std::shared_ptr< TimeIntegrationRule >, TimeIntegrationMapping > > & getTimeIntegrationRules() const
Get all registered time integration rules and their mappings.
const std::vector< FieldState > & getAllFields() const
Get all fields stored in the FieldStore.
std::vector< std::vector< size_t > > indexMap(const std::vector< std::string > &residual_names) const
Generate an index map for the residuals.
Definition: field_store.cpp:59
std::vector< const BoundaryConditionManager * > getBoundaryConditionManagers() const
Get the boundary condition managers for all independent fields.
Definition: field_store.cpp:80
std::string getWeakFormReaction(const std::string &weak_form_name) const
Get the name of the reaction (test) field for a weak form.
std::shared_ptr< DirichletBoundaryConditions > getBoundaryConditions(size_t unknown_index) const
Get the Dirichlet boundary conditions for an independent field by its unknown index.
Definition: field_store.cpp:89
const std::shared_ptr< smith::Mesh > & getMesh() const
Get the associated mesh.
void setField(const std::string &field_name, FieldState updated_field)
Update a field in the store by name.
void addWeakFormArg(std::string weak_form_name, std::string argument_name, size_t argument_index)
Register an argument to a weak form.
Definition: field_store.cpp:36
FieldStore(std::shared_ptr< Mesh > mesh, size_t storage_size=50)
Construct a new FieldStore object.
Definition: field_store.cpp:14
void addWeakFormReaction(std::string weak_form_name, std::string field_name)
Register the reaction (test) field for a weak form.
FieldState getParameter(const std::string &param_name) const
Get a parameter field by name.
size_t getFieldIndex(const std::string &field_name) const
Get the internal index of a field by name.
Definition: field_store.cpp:95
std::vector< FieldState > getStates(const std::string &weak_form_name) const
Get the state fields associated with a weak form.
FieldState getShapeDisp() const
Get the shape displacement field.
void addWeakFormUnknownArg(std::string weak_form_name, std::string argument_name, size_t argument_index)
Register an argument to a weak form as an unknown.
Definition: field_store.cpp:26
std::vector< FieldState > getStatesFromVectors(const std::string &weak_form_name, const std::vector< FieldState > &state_fields, const std::vector< FieldState > &param_fields) const
Extract state fields for a weak form from provided state and parameter vectors.
FieldState getField(const std::string &field_name) const
Get a FieldState by name.
const std::shared_ptr< gretl::DataStore > & graph() const
Get the associated data store graph.