21 class DirichletBoundaryConditions;
22 class BoundaryConditionManager;
29 template <
typename Space,
typename Time =
void*>
50 FieldStore(std::shared_ptr<Mesh> mesh,
size_t storage_size = 50);
68 template <
typename Space>
71 shape_disp_.push_back(smith::createFieldState<Space>(*graph_, Space{}, type.name, mesh_->tag()));
79 template <
typename Space>
82 to_params_index_[type.name] = params_.size();
83 params_.push_back(smith::createFieldState<Space>(*graph_, Space{}, type.name, mesh_->tag()));
101 template <
typename Space>
103 std::shared_ptr<TimeIntegrationRule> time_rule)
105 type.unknown_index =
static_cast<int>(num_unknowns_);
106 to_states_index_[type.name] = states_.size();
107 to_unknown_index_[type.name] = num_unknowns_;
108 FieldState new_field = smith::createFieldState<Space>(*graph_, Space{}, type.name, mesh_->tag());
109 states_.push_back(new_field);
110 auto latest_bc = addBoundaryConditions(new_field.get());
112 SLIC_ERROR_IF(num_unknowns_ != boundary_conditions_.size(),
113 "Inconcistency between num unknowns and boundary condition size");
115 SLIC_ERROR_IF(!time_rule,
"Invalid time_rule");
119 independent_name_to_rule_index_[type.name] = time_integration_rules_.size();
120 time_integration_rules_.push_back({time_rule, mapping});
153 template <
typename Space>
157 if (derivative == TimeDerivative::VAL) {
162 suffix =
"_ddot_old";
164 SLIC_ERROR(
"Unsupported TimeDerivative");
167 std::string name = name_override.empty() ? independent_field.
name + suffix : name_override;
169 if (independent_name_to_rule_index_.count(independent_field.
name)) {
170 size_t rule_idx = independent_name_to_rule_index_.at(independent_field.
name);
171 auto& mapping = time_integration_rules_[rule_idx].second;
172 if (derivative == TimeDerivative::VAL) {
173 mapping.history_name = name;
175 mapping.dot_name = name;
177 mapping.ddot_name = name;
180 SLIC_WARNING(
"Adding dependent time integration field for independent field '"
181 << independent_field.
name <<
"' which has no registered TimeIntegrationRule.");
184 to_states_index_[name] = states_.size();
185 states_.push_back(smith::createFieldState<Space>(*graph_, Space{}, name, mesh_->tag()));
195 void addWeakFormUnknownArg(std::string weak_form_name, std::string argument_name,
size_t argument_index);
203 void addWeakFormArg(std::string weak_form_name, std::string argument_name,
size_t argument_index);
245 template <
typename... FieldTypes>
246 std::vector<const mfem::ParFiniteElementSpace*>
createSpaces(
const std::string& weak_form_name,
247 const std::string& reaction_field_name,
251 std::vector<const mfem::ParFiniteElementSpace*>
spaces;
253 auto register_field = [&](
auto type) {
256 if (type.unknown_index >= 0) {
261 (register_field(types), ...);
293 std::vector<std::vector<size_t>>
indexMap(
const std::vector<std::string>& residual_names)
const;
367 std::vector<FieldState>
getStates(
const std::string& weak_form_name)
const;
377 const std::vector<FieldState>& state_fields,
378 const std::vector<FieldState>& param_fields)
const;
384 const std::shared_ptr<smith::Mesh>&
getMesh()
const;
390 const std::shared_ptr<gretl::DataStore>&
graph()
const;
393 std::shared_ptr<Mesh> mesh_;
394 std::shared_ptr<gretl::DataStore> graph_;
396 std::vector<FieldState> shape_disp_;
397 std::vector<FieldState> params_;
398 std::vector<FieldState> states_;
400 std::map<std::string, size_t> to_states_index_;
401 std::map<std::string, size_t> to_params_index_;
403 size_t num_unknowns_ = 0;
404 std::map<std::string, size_t> to_unknown_index_;
405 std::vector<std::shared_ptr<DirichletBoundaryConditions>> boundary_conditions_;
408 std::string field_name;
409 size_t field_index_in_residual;
412 std::shared_ptr<DirichletBoundaryConditions> addBoundaryConditions(
FEFieldPtr field);
414 std::map<std::string, std::vector<FieldLabel>> weak_form_name_to_unknown_name_index_;
416 std::map<std::string, std::vector<size_t>> weak_form_name_to_field_indices_;
417 std::map<std::string, std::vector<std::string>> weak_form_name_to_field_names_;
419 std::map<std::string, std::string> weak_form_to_test_field_;
421 std::vector<std::pair<std::shared_ptr<TimeIntegrationRule>, TimeIntegrationMapping>> time_integration_rules_;
422 std::map<std::string, size_t> independent_name_to_rule_index_;
431 template <
int spatial_dim,
typename TestSpaceType,
typename... InputSpaceTypes>
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 TimeDiscretizedWeakForm and register its fields in the FieldStore.
gretl::State< FEFieldPtr, FEDualPtr > FieldState
typedef
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.
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.
const std::vector< std::pair< std::shared_ptr< TimeIntegrationRule >, TimeIntegrationMapping > > & getTimeIntegrationRules() const
Get all registered time integration rules and their mappings.
void addParameter(FieldType< Space > type)
Add a parameter field to the store.
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::vector< const BoundaryConditionManager * > getBoundaryConditionManagers() const
Get the boundary condition managers for all independent fields.
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.
std::shared_ptr< DirichletBoundaryConditions > getBoundaryConditions(size_t unknown_index) const
Get the Dirichlet boundary conditions for an independent field by its unknown index.
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.
FieldStore(std::shared_ptr< Mesh > mesh, size_t storage_size=50)
Construct a new FieldStore object.
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.
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.
size_t getNumUnknowns() const
Get the number of unknowns in the field 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.
Representation of a field type with a name and an optional unknown index.
std::string name
Name of the field.
FieldType(std::string n, int unknown_index_=-1)
Construct a new FieldType object.
int unknown_index
Index of the unknown in the solver.
a struct that is used in the physics modules to clarify which template arguments are user-controlled ...
Provides templated implementations for discretizing values, velocities and accelerations from current...