Smith  0.1
Smith is an implicit thermal structural mechanics simulation code.
state_variable_system.hpp
Go to the documentation of this file.
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 
29 #pragma once
30 
31 #include "smith/differentiable_numerics/field_store.hpp"
35 #include "smith/differentiable_numerics/multiphysics_time_integrator.hpp"
42 
43 namespace smith {
44 
57 template <int dim, typename StateSpace, typename InternalVarTimeRule = BackwardEulerFirstOrderTimeIntegrationRule,
58  typename Coupling = std::tuple<>>
61 
62  static_assert(InternalVarTimeRule::num_states == 2,
63  "InternalVariableSystem requires a 2-state time integration rule");
64 
68 
69  std::shared_ptr<InternalVariableWeakFormType> internal_variable_weak_form;
70  std::shared_ptr<DirichletBoundaryConditions> internal_variable_bc;
71  std::shared_ptr<InternalVarTimeRule> internal_variable_time_rule;
72  std::shared_ptr<const Coupling> coupling;
73 
84  template <typename EvolutionType>
85  void addEvolution(const std::string& domain_name, EvolutionType evolution_law)
86  {
87  auto captured_time_rule = internal_variable_time_rule;
88  auto captured_coupling = coupling;
89  internal_variable_weak_form->addBodyIntegral(domain_name, [=](auto t_info, auto /*X*/, auto... raw_args) {
91  *captured_time_rule, *captured_coupling, t_info,
92  [&](auto alpha_current, auto alpha_dot, auto... interpolated_params) {
93  auto residual_val =
94  evolution_law(t_info, get<VALUE>(alpha_current), get<VALUE>(alpha_dot), interpolated_params...);
95  tensor<double, dim> flux{};
96  return smith::tuple{residual_val, flux};
97  },
98  raw_args...);
99  });
100  }
101 };
102 
103 // ---------------------------------------------------------------------------
104 // Phase 1: registerInternalVariableFields
105 // ---------------------------------------------------------------------------
106 
115 template <int dim, typename StateSpace, typename InternalVarTimeRule, typename... parameter_space>
116 auto registerInternalVariableFields(std::shared_ptr<FieldStore> field_store,
117  FieldType<parameter_space>... parameter_types)
118 {
119  auto internal_variable_time_rule = std::make_shared<InternalVarTimeRule>();
120  FieldType<StateSpace> state_type("state_solve_state");
121  field_store->addIndependent(state_type, internal_variable_time_rule);
122  field_store->addDependent(state_type, FieldStore::TimeDerivative::VAL, "state");
123 
124  if constexpr (sizeof...(parameter_space) > 0) {
125  auto prefix_param = [&](auto& pt) {
126  pt.name = "param_" + pt.name;
127  field_store->addParameter(pt);
128  };
129  (prefix_param(parameter_types), ...);
130  }
131 
133  field_store, FieldType<StateSpace>(field_store->prefix("state_solve_state")),
134  FieldType<StateSpace>(field_store->prefix("state"))};
135 }
136 
137 template <int dim, typename StateSpace, typename InternalVarTimeRule, typename... parameter_space>
139 auto registerStateVariableFields(std::shared_ptr<FieldStore> field_store, FieldType<parameter_space>... parameter_types)
140 {
141  return registerInternalVariableFields<dim, StateSpace, InternalVarTimeRule>(field_store, parameter_types...);
142 }
143 
144 // ---------------------------------------------------------------------------
145 // Phase 2: buildInternalVariableSystem
146 // ---------------------------------------------------------------------------
147 
151 namespace detail {
152 
156 template <int dim, typename StateSpace, typename InternalVarTimeRule, typename Coupling>
157  requires detail::is_coupling_packs_v<Coupling>
158 auto buildInternalVariableSystemImpl(std::shared_ptr<FieldStore> field_store, const Coupling& coupling,
159  std::shared_ptr<SystemSolver> solver)
160 {
161  auto internal_variable_time_rule = std::make_shared<InternalVarTimeRule>();
162 
163  FieldType<StateSpace> state_type(field_store->prefix("state_solve_state"), true);
164  FieldType<StateSpace> state_old_type(field_store->prefix("state"));
165 
166  auto internal_variable_bc = field_store->getBoundaryConditions(state_type.name);
167 
169 
170  std::string internal_variable_residual_name = field_store->prefix("state_residual");
171  auto internal_variable_weak_form =
172  detail::buildWeakFormWithCoupling<typename SystemType::InternalVariableWeakFormType>(
173  field_store, internal_variable_residual_name, state_type.name, state_type, state_old_type,
175 
176  auto sys = std::make_shared<SystemType>(field_store, solver,
177  std::vector<std::shared_ptr<WeakForm>>{internal_variable_weak_form});
178  sys->internal_variable_bc = internal_variable_bc;
179  sys->internal_variable_time_rule = internal_variable_time_rule;
180  sys->coupling = std::make_shared<Coupling>(coupling);
181  sys->internal_variable_weak_form = internal_variable_weak_form;
182 
183  return sys;
184 }
185 
186 } // namespace detail
187 
193 template <typename SelfFields>
194  requires(detail::has_time_rule_v<SelfFields>)
195 auto buildInternalVariableSystem(std::shared_ptr<SystemSolver> solver, const SelfFields& self_fields)
196 {
197  constexpr int dim = SelfFields::dim;
198  using StateSpace = typename std::tuple_element_t<0, decltype(self_fields.fields)>::space_type;
199  using InternalVarTimeRule = typename std::decay_t<SelfFields>::time_rule_type;
200  auto field_store = self_fields.field_store;
201  auto coupling = detail::collectCouplingFields();
202  return detail::buildInternalVariableSystemImpl<dim, StateSpace, InternalVarTimeRule>(field_store, coupling, solver);
203 }
204 
208 template <typename SelfFields, typename... PFs>
209  requires(detail::has_time_rule_v<SelfFields>)
210 auto buildInternalVariableSystem(std::shared_ptr<SystemSolver> solver, const SelfFields& self_fields,
211  const CouplingFields<PFs...>& coupled)
212 {
213  constexpr int dim = SelfFields::dim;
214  using StateSpace = typename std::tuple_element_t<0, decltype(self_fields.fields)>::space_type;
215  using InternalVarTimeRule = typename std::decay_t<SelfFields>::time_rule_type;
216  auto field_store = self_fields.field_store;
217  auto coupling = detail::collectCouplingFields(coupled);
218  return detail::buildInternalVariableSystemImpl<dim, StateSpace, InternalVarTimeRule>(field_store, coupling, solver);
219 }
220 
224 template <typename SelfFields, typename... ParamSpaces>
225  requires(detail::has_time_rule_v<SelfFields>)
226 auto buildInternalVariableSystem(std::shared_ptr<SystemSolver> solver, const SelfFields& self_fields,
227  const ParamFields<ParamSpaces...>& params)
228 {
229  constexpr int dim = SelfFields::dim;
230  using StateSpace = typename std::tuple_element_t<0, decltype(self_fields.fields)>::space_type;
231  using InternalVarTimeRule = typename std::decay_t<SelfFields>::time_rule_type;
232  auto field_store = self_fields.field_store;
233  auto coupling = detail::collectCouplingFields(params);
234  return detail::buildInternalVariableSystemImpl<dim, StateSpace, InternalVarTimeRule>(field_store, coupling, solver);
235 }
236 
240 template <typename SelfFields, typename... PFs, typename... ParamSpaces>
241  requires(detail::has_time_rule_v<SelfFields>)
242 auto buildInternalVariableSystem(std::shared_ptr<SystemSolver> solver, const SelfFields& self_fields,
243  const CouplingFields<PFs...>& coupled, const ParamFields<ParamSpaces...>& params)
244 {
245  constexpr int dim = SelfFields::dim;
246  using StateSpace = typename std::tuple_element_t<0, decltype(self_fields.fields)>::space_type;
247  using InternalVarTimeRule = typename std::decay_t<SelfFields>::time_rule_type;
248  auto field_store = self_fields.field_store;
249  auto coupling = detail::collectCouplingFields(coupled, params);
250  return detail::buildInternalVariableSystemImpl<dim, StateSpace, InternalVarTimeRule>(field_store, coupling, solver);
251 }
252 
253 } // namespace smith
Coupling pack types and helpers for injecting explicit coupled-physics fields into weak form paramete...
Defines a BasePhysics implementation backed by FieldState objects and a gretl computational graph.
Contains DirichletBoundaryConditions class for interaction with the differentiable solve interfaces.
Implements the WeakForm interface using smith::ShapeAwareFunctional. Allows for generic specification...
decltype(auto) applyTimeRuleAndCoupling(const Rule &rule, const Coupling &coupling, const TimeInfoT &t_info, Callback &&callback, const RawArgs &... raw_args)
Interpolate self time-rule states then coupling segments, then invoke callback.
auto collectCouplingFields()
Collect no coupling or parameter packs.
auto flattenCouplingFields(const PacksTuple &packs)
Concatenate each pack's .fields tuple — used to derive trailing weak-form parameter spaces.
requires detail::is_coupling_packs_v< Coupling > auto buildInternalVariableSystemImpl(std::shared_ptr< FieldStore > field_store, const Coupling &coupling, std::shared_ptr< SystemSolver > solver)
Internal builder for an internal-variable system after public registration and coupling collection.
Accelerator functionality.
Definition: smith.cpp:36
auto registerStateVariableFields(std::shared_ptr< FieldStore > field_store, FieldType< parameter_space >... parameter_types)
Backward-compatible alias for registerInternalVariableFields.
requires(detail::has_time_rule_v< SelfFields >) auto buildSolidMechanicsSystem(std
Build a SolidMechanicsSystem from already-registered field packs.
mfem::future::tuple< T... > tuple
Expose MFEM tuple in the Smith namespace.
Definition: tuple.hpp:241
auto registerInternalVariableFields(std::shared_ptr< FieldStore > field_store, FieldType< parameter_space >... parameter_types)
Register state variable fields into a FieldStore.
This file contains nonlinear block solver interfaces and helpers.
Interface and implementations for advancing from one step to the next. Typically these are time integ...
Representation of a field type with a name and a flag indicating whether it is an active Jacobian unk...
Definition: field_store.hpp:47
std::string name
Name of the field.
Definition: field_store.hpp:56
System for a single internal variable using a two-state first-order rule.
void addEvolution(const std::string &domain_name, EvolutionType evolution_law)
Register an ODE evolution law for the internal variable.
std::shared_ptr< InternalVarTimeRule > internal_variable_time_rule
Time integration rule.
std::shared_ptr< DirichletBoundaryConditions > internal_variable_bc
Internal variable BCs.
std::shared_ptr< InternalVariableWeakFormType > internal_variable_weak_form
Internal variable weak form.
std::shared_ptr< const Coupling > coupling
Coupling metadata.
Fields returned by a physics register function, carrying time rule type information.
Base struct for physics systems containing common members and helper functions.
Definition: system_base.hpp:52
SystemBase()=default
Construct an empty system shell.
Defines the SystemBase struct for common system functionality.
Provides templated implementations for discretizing values, velocities and accelerations from current...
Specifies interface for evaluating weak form residuals and their gradients.