22 class DirichletBoundaryConditions;
23 class BoundaryConditionManager;
30 const mfem::ParFiniteElementSpace*
space =
nullptr;
46 template <
typename Space,
typename Time =
void*>
70 FieldStore(std::shared_ptr<Mesh> mesh,
size_t storage_size = 50, std::string prepend_name =
"");
79 std::string
prefix(
const std::string& base)
const;
97 template <
typename Space>
100 type.name =
prefix(type.name);
101 shape_disp_.push_back(smith::createFieldState<Space>(*graph_, Space{}, type.name, mesh_->tag()));
109 template <
typename Space>
112 type.name =
prefix(type.name);
113 if (to_params_index_.count(type.name)) {
116 auto& existing = params_[to_params_index_.at(type.name)];
117 SLIC_ERROR_ROOT_IF(existing.get()->space().GetVDim() != Space::components,
118 axom::fmt::format(
"Parameter '{}' re-registered with a different space "
119 "(existing vdim={}, new vdim={})",
120 type.name, existing.get()->space().GetVDim(), Space::components));
123 to_params_index_[type.name] = params_.size();
124 params_.push_back(smith::createFieldState<Space>(*graph_, Space{}, type.name, mesh_->tag()));
141 template <
typename Space>
143 std::shared_ptr<TimeIntegrationRule> time_rule)
145 type.name =
prefix(type.name);
146 type.is_unknown =
true;
147 to_states_index_[type.name] = states_.size();
148 FieldState new_field = smith::createFieldState<Space>(*graph_, Space{}, type.name, mesh_->tag());
149 states_.push_back(new_field);
150 is_solve_state_.push_back(
true);
151 auto latest_bc = addBoundaryConditions(new_field.get());
152 boundary_conditions_[type.name] = latest_bc;
154 SLIC_ERROR_IF(!time_rule,
"Invalid time_rule");
158 independent_name_to_rule_index_[type.name] = time_integration_rules_.size();
159 time_integration_rules_.push_back({time_rule, mapping});
186 template <
typename Space>
190 if (derivative == TimeDerivative::VAL) {
195 suffix =
"_ddot_old";
197 SLIC_ERROR(
"Unsupported TimeDerivative");
200 std::string name = name_override.empty() ? independent_field.
name + suffix :
prefix(name_override);
202 if (independent_name_to_rule_index_.count(independent_field.
name)) {
203 size_t rule_idx = independent_name_to_rule_index_.at(independent_field.
name);
204 auto& mapping = time_integration_rules_[rule_idx].second;
205 if (derivative == TimeDerivative::VAL) {
206 mapping.history_name = name;
208 mapping.dot_name = name;
210 mapping.ddot_name = name;
213 SLIC_WARNING(
"Adding dependent time integration field for independent field '"
214 << independent_field.
name <<
"' which has no registered TimeIntegrationRule.");
217 to_states_index_[name] = states_.size();
218 states_.push_back(smith::createFieldState<Space>(*graph_, Space{}, name, mesh_->tag()));
219 is_solve_state_.push_back(
false);
229 void addWeakFormUnknownArg(std::string weak_form_name, std::string argument_name,
size_t argument_index);
237 void addWeakFormArg(std::string weak_form_name, std::string argument_name,
size_t argument_index);
289 template <
typename... FieldTypes>
290 std::vector<const mfem::ParFiniteElementSpace*>
createSpaces(
const std::string& weak_form_name,
291 const std::string& reaction_field_name,
295 std::vector<const mfem::ParFiniteElementSpace*>
spaces;
297 auto register_field = [&](
auto type) {
300 if (type.is_unknown) {
305 (register_field(types), ...);
337 std::vector<std::vector<size_t>>
indexMap(
const std::vector<std::string>& residual_names)
const;
355 const std::vector<std::string>& weak_form_names)
const;
359 const std::vector<std::string>& field_names)
const;
366 bool hasField(
const std::string& field_name)
const;
420 std::vector<FieldState>
getStates(
const std::string& weak_form_name)
const;
430 const std::vector<FieldState>& state_fields,
431 const std::vector<FieldState>& param_fields)
const;
456 const std::shared_ptr<smith::Mesh>&
getMesh()
const;
461 std::shared_ptr<DirichletBoundaryConditions>
getBoundaryConditions(
const std::string& field_name)
const;
467 const std::shared_ptr<gretl::DataStore>&
graph()
const;
470 std::string resolveFieldName(
const std::string& field_name)
const;
472 std::shared_ptr<Mesh> mesh_;
473 std::shared_ptr<gretl::DataStore> graph_;
474 std::string prepend_name_;
476 std::vector<FieldState> shape_disp_;
477 std::vector<FieldState> params_;
478 std::vector<FieldState> states_;
479 std::vector<bool> is_solve_state_;
481 std::map<std::string, size_t> to_states_index_;
482 std::map<std::string, size_t> to_params_index_;
485 std::map<std::string, std::shared_ptr<DirichletBoundaryConditions>> boundary_conditions_;
488 std::string field_name;
489 size_t field_index_in_residual;
492 std::shared_ptr<DirichletBoundaryConditions> addBoundaryConditions(
FEFieldPtr field);
494 std::map<std::string, std::vector<FieldLabel>> weak_form_name_to_unknown_name_index_;
496 std::map<std::string, std::vector<size_t>> weak_form_name_to_field_indices_;
497 std::map<std::string, std::vector<std::string>> weak_form_name_to_field_names_;
499 std::vector<std::pair<std::string, std::string>> weak_form_to_test_field_;
500 std::set<std::string> internal_weak_forms_;
502 std::vector<std::pair<std::shared_ptr<TimeIntegrationRule>, TimeIntegrationMapping>> time_integration_rules_;
503 std::map<std::string, size_t> independent_name_to_rule_index_;
512 template <
int spatial_dim,
typename TestSpaceType,
typename... InputSpaceTypes>
525 inline std::shared_ptr<FieldStore>
fieldStore(std::shared_ptr<Mesh> mesh, std::size_t storage_size = 200,
526 std::string prefix =
"")
528 return std::make_shared<FieldStore>(std::move(mesh), storage_size, std::move(prefix));
Smith mesh class which assists in constructing the appropriate parallel mfem meshes and registering a...
Accelerator functionality.
std::vector< const mfem::ParFiniteElementSpace * > spaces(const std::vector< FieldState > &states, const std::vector< FieldState > ¶ms={})
Get the spaces from the primal fields of a vector of field states.
std::shared_ptr< FiniteElementState > FEFieldPtr
typedef
auto createWeakForm(std::string name, FieldType< TestSpaceType > test_type, FieldStore &field_store, FieldType< InputSpaceTypes >... field_types)
Create a FunctionalWeakForm and register its fields in the FieldStore.
gretl::State< FEFieldPtr, FEDualPtr > FieldState
typedef
std::shared_ptr< FieldStore > fieldStore(std::shared_ptr< Mesh > mesh, std::size_t storage_size=200, std::string prefix="")
Construct a shared_ptr<FieldStore> over a mesh. Inline call-site helper for standalone-physics setup;...
Mapping between primary and history/derivative fields for time integration.
std::string history_name
Previous time step value field name.
std::string primary_name
Primary unknown field name.
std::string ddot_name
Second time derivative field name.
std::string dot_name
First time derivative field name.
Manages storage and metadata for fields, parameters, and weak forms.
void printMap()
Print the internal field maps for debugging.
std::vector< FieldState > getOutputFieldStates() const
Get the list of physical, non-solve state fields suitable for output.
const std::vector< FieldState > & getParameterFields() const
Get the list of all parameter fields.
const std::vector< std::pair< std::shared_ptr< TimeIntegrationRule >, TimeIntegrationMapping > > & getTimeIntegrationRules() const
Get all registered time integration rules and their mappings.
bool hasField(const std::string &field_name) const
Check whether a field exists.
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.
std::string prefix(const std::string &base) const
Apply this store's namespace prefix to a base name.
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 > addIndependent(FieldType< Space > &type, std::shared_ptr< TimeIntegrationRule > time_rule)
Add an independent field (a solver unknown) to the store.
const std::shared_ptr< smith::Mesh > & getMesh() const
Get associated mesh shared by all registered fields.
const std::vector< FieldState > & getStateFields() const
Get the list of all state fields.
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.
TimeDerivative
Enum for different types of time derivatives.
@ DDDOT
The third time derivative.
@ DOT
The first time derivative.
@ DDOT
The second time derivative.
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 ¶m_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.
std::vector< FieldState > getStates(const std::string &weak_form_name) const
Get the state fields associated with a weak form.
void addShapeDisp(FieldType< Space > &type)
Add a shape displacement field to the store.
FieldState getShapeDisp() const
Get the shape displacement field.
std::vector< const BoundaryConditionManager * > getBoundaryConditionManagers(const std::vector< std::string > &weak_form_names) const
Get the boundary condition managers for the given weak forms, one per residual row.
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.
std::vector< const mfem::ParFiniteElementSpace * > createSpaces(const std::string &weak_form_name, const std::string &reaction_field_name, FieldTypes... types)
Register all input fields for a weak form and return their FE spaces.
auto addDependent(FieldType< Space > independent_field, TimeDerivative derivative, std::string name_override="")
Add a dependent field (history value, velocity, or acceleration) to the store.
std::vector< FieldState > getStatesFromVectors(const std::string &weak_form_name, const std::vector< FieldState > &state_fields, const std::vector< FieldState > ¶m_fields) const
Extract state fields for a weak form from provided state and parameter vectors.
std::shared_ptr< DirichletBoundaryConditions > getBoundaryConditions(const std::string &field_name) const
Get the boundary conditions for a given field name.
std::vector< const BoundaryConditionManager * > getBoundaryConditionManagersForFields(const std::vector< std::string > &field_names) const
Get ordered boundary condition managers corresponding to an ordered list of fields.
void addParameter(FieldType< Space > &type)
Add a parameter field to the store.
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.
std::vector< ReactionInfo > getReactionInfos() const
Get information about reaction fields.
FieldStore(std::shared_ptr< Mesh > mesh, size_t storage_size=50, std::string prepend_name="")
Construct a new FieldStore object.
void markWeakFormInternal(const std::string &weak_form_name)
Mark a weak form as internal so it is excluded from getReactionInfos().
Representation of a field type with a name and a flag indicating whether it is an active Jacobian unk...
bool is_unknown
True if this field is a Jacobian variable in the current weak-form context.
std::string name
Name of the field.
Space space_type
The finite element space type.
FieldType(std::string n, bool is_unknown_=false)
Construct a new FieldType object.
a struct that is used in the physics modules to clarify which template arguments are user-controlled ...
Information about a dual field.
std::string name
The name of the dual field.
const mfem::ParFiniteElementSpace * space
The finite element space of the dual field.
Provides templated implementations for discretizing values, velocities and accelerations from current...