Smith  0.1
Smith is an implicit thermal structural mechanics simulation code.
thermo_mechanics_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 
12 #pragma once
13 
14 #include "smith/differentiable_numerics/field_store.hpp"
17 #include "smith/differentiable_numerics/multiphysics_time_integrator.hpp"
23 
24 namespace smith {
25 
40 template <int dim, int disp_order, int temp_order,
41  typename DisplacementTimeRule = QuasiStaticSecondOrderTimeIntegrationRule,
42  typename TemperatureTimeRule = BackwardEulerFirstOrderTimeIntegrationRule, typename... parameter_space>
44  static_assert(DisplacementTimeRule::num_states == 4,
45  "ThermoMechanicsSystem requires a 4-state displacement time rule");
46  static_assert(TemperatureTimeRule::num_states == 2, "ThermoMechanicsSystem requires a 2-state temperature time rule");
47 
52  H1<disp_order, dim>, H1<temp_order>, H1<temp_order>, parameter_space...>>;
53 
58  H1<disp_order, dim>, H1<disp_order, dim>, parameter_space...>>;
59 
60  // Cycle-zero weak form: test field = acceleration, inputs: u, v, a, temp, temp_old, params...
65  H1<temp_order>, parameter_space...>>;
66 
67  std::shared_ptr<SolidWeakFormType> solid_weak_form;
68  std::shared_ptr<ThermalWeakFormType> thermal_weak_form;
69  std::shared_ptr<CycleZeroWeakFormType> cycle_zero_weak_form;
70  std::shared_ptr<DirichletBoundaryConditions> disp_bc;
71  std::shared_ptr<DirichletBoundaryConditions> temperature_bc;
72  std::shared_ptr<DisplacementTimeRule> disp_time_rule;
73  std::shared_ptr<TemperatureTimeRule> temperature_time_rule;
74 
79  std::vector<FieldState> getStateFields() const
80  {
81  return {field_store->getField(prefix("displacement_solve_state")),
82  field_store->getField(prefix("displacement")),
83  field_store->getField(prefix("velocity")),
84  field_store->getField(prefix("acceleration")),
85  field_store->getField(prefix("temperature_solve_state")),
86  field_store->getField(prefix("temperature"))};
87  }
88 
93  std::vector<ReactionInfo> getReactionInfos() const
94  {
95  return {{prefix("solid_force"), &field_store->getField(prefix("displacement")).get()->space()},
96  {prefix("thermal_flux"), &field_store->getField(prefix("temperature")).get()->space()}};
97  }
98 
104  std::unique_ptr<DifferentiablePhysics> createDifferentiablePhysics(std::string physics_name)
105  {
106  return std::make_unique<DifferentiablePhysics>(field_store->getMesh(), field_store->graph(),
107  field_store->getShapeDisp(), getStateFields(), getParameterFields(),
108  advancer, physics_name, getReactionInfos());
109  }
110 
121  template <typename MaterialType>
122  void setMaterial(const MaterialType& material, const std::string& domain_name)
123  {
124  auto captured_disp_rule = disp_time_rule;
125  auto captured_temp_rule = temperature_time_rule;
126 
127  solid_weak_form->addBodyIntegral(
128  domain_name, [=](auto t_info, auto /*X*/, auto u, auto u_old, auto v_old, auto a_old, auto temperature,
129  auto temperature_old, auto... params) {
130  auto [u_current, v_current, a_current] = captured_disp_rule->interpolate(t_info, u, u_old, v_old, a_old);
131  auto T = captured_temp_rule->value(t_info, temperature, temperature_old);
132 
133  typename MaterialType::State state;
134  auto [pk, C_v, s0, q0] = material(t_info.dt(), state, get<DERIVATIVE>(u_current), get<DERIVATIVE>(v_current),
135  get<VALUE>(T), get<DERIVATIVE>(T), params...);
136  return smith::tuple{get<VALUE>(a_current) * material.density, pk};
137  });
138 
139  thermal_weak_form->addBodyIntegral(domain_name, [=](auto t_info, auto /*X*/, auto T, auto T_old, auto disp,
140  auto disp_old, auto v_old, auto a_old, auto... params) {
141  auto [T_current, T_dot] = captured_temp_rule->interpolate(t_info, T, T_old);
142  auto [u, v, a] = captured_disp_rule->interpolate(t_info, disp, disp_old, v_old, a_old);
143 
144  typename MaterialType::State state;
145  auto [pk, C_v, s0, q0] = material(t_info.dt(), state, get<DERIVATIVE>(u), get<DERIVATIVE>(v),
146  get<VALUE>(T_current), get<DERIVATIVE>(T_current), params...);
147  auto dT_dt = get<VALUE>(T_dot);
148  return smith::tuple{C_v * dT_dt - s0, -q0};
149  });
150 
151  // Cycle-zero: u and v are given, solve for a; temperature at initial condition
152  cycle_zero_weak_form->addBodyIntegral(domain_name, [=](auto t_info, auto /*X*/, auto u, auto v, auto a,
153  auto temperature, auto temperature_old, auto... params) {
154  auto T = captured_temp_rule->value(t_info, temperature, temperature_old);
155 
156  typename MaterialType::State state;
157  auto [pk, C_v, s0, q0] = material(t_info.dt(), state, get<DERIVATIVE>(u), get<DERIVATIVE>(v), get<VALUE>(T),
158  get<DERIVATIVE>(T), params...);
159  return smith::tuple{get<VALUE>(a) * material.density, pk};
160  });
161  }
162 
166  template <int... active_parameters, typename BodyForceType>
167  void addSolidBodyForce(DependsOn<active_parameters...> depends_on, const std::string& domain_name,
168  BodyForceType force_function)
169  {
170  auto captured_disp_rule = disp_time_rule;
171  auto captured_temp_rule = temperature_time_rule;
172 
173  solid_weak_form->addBodySource(
174  depends_on, domain_name,
175  [=](auto t_info, auto X, auto u, auto u_old, auto v_old, auto a_old, auto temperature, auto temperature_old,
176  auto... params) {
177  auto [u_current, v_current, a_current] = captured_disp_rule->interpolate(t_info, u, u_old, v_old, a_old);
178  auto [current_T, T_dot] = captured_temp_rule->interpolate(t_info, temperature, temperature_old);
179  return force_function(t_info.time(), X, u_current, v_current, a_current, current_T, T_dot, params...);
180  });
181  }
182 
186  template <typename BodyForceType>
187  void addSolidBodyForce(const std::string& domain_name, BodyForceType force_function)
188  {
189  addSolidBodyForceAllParams(domain_name, force_function, std::make_index_sequence<6 + sizeof...(parameter_space)>{});
190  }
191 
195  template <int... active_parameters, typename SurfaceFluxType>
196  void addSolidTraction(DependsOn<active_parameters...> depends_on, const std::string& domain_name,
197  SurfaceFluxType flux_function)
198  {
199  auto captured_disp_rule = disp_time_rule;
200  auto captured_temp_rule = temperature_time_rule;
201 
202  solid_weak_form->addBoundaryFlux(
203  depends_on, domain_name,
204  [=](auto t_info, auto X, auto n, auto u, auto u_old, auto v_old, auto a_old, auto temperature,
205  auto temperature_old, auto... params) {
206  auto [u_current, v_current, a_current] = captured_disp_rule->interpolate(t_info, u, u_old, v_old, a_old);
207  auto [current_T, T_dot] = captured_temp_rule->interpolate(t_info, temperature, temperature_old);
208  return flux_function(t_info.time(), X, n, u_current, v_current, a_current, current_T, T_dot, params...);
209  });
210  }
211 
215  template <typename SurfaceFluxType>
216  void addSolidTraction(const std::string& domain_name, SurfaceFluxType flux_function)
217  {
218  addSolidTractionAllParams(domain_name, flux_function, std::make_index_sequence<6 + sizeof...(parameter_space)>{},
219  std::make_index_sequence<5 + sizeof...(parameter_space)>{});
220  }
221 
225  template <int... active_parameters, typename BodySourceType>
226  void addHeatSource(DependsOn<active_parameters...> depends_on, const std::string& domain_name,
227  BodySourceType source_function)
228  {
229  auto captured_disp_rule = disp_time_rule;
230  auto captured_temp_rule = temperature_time_rule;
231 
232  thermal_weak_form->addBodySource(
233  depends_on, domain_name,
234  [=](auto t_info, auto X, auto T, auto T_old, auto disp, auto disp_old, auto v_old, auto a_old, auto... params) {
235  auto [current_u, v_current, a_current] =
236  captured_disp_rule->interpolate(t_info, disp, disp_old, v_old, a_old);
237  auto [T_current, T_dot] = captured_temp_rule->interpolate(t_info, T, T_old);
238  return source_function(t_info.time(), X, current_u, v_current, a_current, T_current, T_dot, params...);
239  });
240  }
241 
245  template <typename BodySourceType>
246  void addHeatSource(const std::string& domain_name, BodySourceType source_function)
247  {
248  addHeatSourceAllParams(domain_name, source_function, std::make_index_sequence<6 + sizeof...(parameter_space)>{});
249  }
250 
254  template <int... active_parameters, typename SurfaceFluxType>
255  void addHeatFlux(DependsOn<active_parameters...> depends_on, const std::string& domain_name,
256  SurfaceFluxType flux_function)
257  {
258  auto captured_disp_rule = disp_time_rule;
259  auto captured_temp_rule = temperature_time_rule;
260 
261  thermal_weak_form->addBoundaryFlux(depends_on, domain_name,
262  [=](auto t_info, auto X, auto n, auto T, auto T_old, auto disp, auto disp_old,
263  auto v_old, auto a_old, auto... params) {
264  auto [current_u, v_current, a_current] =
265  captured_disp_rule->interpolate(t_info, disp, disp_old, v_old, a_old);
266  auto [T_current, T_dot] = captured_temp_rule->interpolate(t_info, T, T_old);
267  return -flux_function(t_info.time(), X, n, current_u, v_current, a_current,
268  T_current, T_dot, params...);
269  });
270  }
271 
275  template <typename SurfaceFluxType>
276  void addHeatFlux(const std::string& domain_name, SurfaceFluxType flux_function)
277  {
278  addHeatFluxAllParams(domain_name, flux_function, std::make_index_sequence<6 + sizeof...(parameter_space)>{});
279  }
280 
284  template <int... active_parameters, typename PressureType>
285  void addPressure(DependsOn<active_parameters...> depends_on, const std::string& domain_name,
286  PressureType pressure_function)
287  {
288  auto captured_disp_rule = disp_time_rule;
289  auto captured_temp_rule = temperature_time_rule;
290 
291  solid_weak_form->addBoundaryIntegral(
292  depends_on, domain_name,
293  [=](auto t_info, auto X, auto u, auto u_old, auto v_old, auto a_old, auto temperature, auto temperature_old,
294  auto... params) {
295  auto [u_current, v_current, a_current] = captured_disp_rule->interpolate(t_info, u, u_old, v_old, a_old);
296  auto [T_current, T_dot] = captured_temp_rule->interpolate(t_info, temperature, temperature_old);
297 
298  auto x_current = X + u_current;
299  auto n_deformed = cross(get<DERIVATIVE>(x_current));
300  auto n_shape_norm = norm(cross(get<DERIVATIVE>(X)));
301 
302  auto pressure = pressure_function(t_info.time(), get<VALUE>(X), u_current, v_current, a_current, T_current,
303  T_dot, get<VALUE>(params)...);
304 
305  return pressure * n_deformed * (1.0 / n_shape_norm);
306  });
307  }
308 
312  template <typename PressureType>
313  void addPressure(const std::string& domain_name, PressureType pressure_function)
314  {
315  addPressureAllParams(domain_name, pressure_function, std::make_index_sequence<6 + sizeof...(parameter_space)>{});
316  }
317 
318  private:
319  template <typename BodyForceType, std::size_t... Is>
320  void addSolidBodyForceAllParams(const std::string& domain_name, BodyForceType force_function,
321  std::index_sequence<Is...>)
322  {
323  addSolidBodyForce(DependsOn<static_cast<int>(Is)...>{}, domain_name, force_function);
324  }
325 
326  template <typename SurfaceFluxType, std::size_t... MainIs, std::size_t... CycleZeroIs>
327  void addSolidTractionAllParams(const std::string& domain_name, SurfaceFluxType flux_function,
328  std::index_sequence<MainIs...>, std::index_sequence<CycleZeroIs...>)
329  {
330  addSolidTraction(DependsOn<static_cast<int>(MainIs)...>{}, domain_name, flux_function);
331 
332  auto captured_temp_rule = temperature_time_rule;
333  cycle_zero_weak_form->addBoundaryFlux(
334  DependsOn<static_cast<int>(CycleZeroIs)...>{}, domain_name,
335  [=](auto t_info, auto X, auto n, auto u, auto v, auto a, auto temperature, auto temperature_old,
336  auto... params) {
337  auto [current_T, T_dot] = captured_temp_rule->interpolate(t_info, temperature, temperature_old);
338  return flux_function(t_info.time(), X, n, u, v, a, current_T, T_dot, params...);
339  });
340  }
341 
342  template <typename PressureType, std::size_t... Is>
343  void addPressureAllParams(const std::string& domain_name, PressureType pressure_function, std::index_sequence<Is...>)
344  {
345  addPressure(DependsOn<static_cast<int>(Is)...>{}, domain_name, pressure_function);
346  }
347 
348  template <typename BodySourceType, std::size_t... Is>
349  void addHeatSourceAllParams(const std::string& domain_name, BodySourceType source_function,
350  std::index_sequence<Is...>)
351  {
352  addHeatSource(DependsOn<static_cast<int>(Is)...>{}, domain_name, source_function);
353  }
354 
355  template <typename SurfaceFluxType, std::size_t... Is>
356  void addHeatFluxAllParams(const std::string& domain_name, SurfaceFluxType flux_function, std::index_sequence<Is...>)
357  {
358  addHeatFlux(DependsOn<static_cast<int>(Is)...>{}, domain_name, flux_function);
359  }
360 };
361 
373 template <int dim, int disp_order, int temp_order, typename DisplacementTimeRule, typename TemperatureTimeRule,
374  typename... parameter_space>
375 ThermoMechanicsSystem<dim, disp_order, temp_order, DisplacementTimeRule, TemperatureTimeRule, parameter_space...>
376 buildThermoMechanicsSystem(std::shared_ptr<Mesh> mesh, std::shared_ptr<CoupledSystemSolver> solver,
377  DisplacementTimeRule disp_rule, TemperatureTimeRule temp_rule, std::string prepend_name = "",
378  std::shared_ptr<CoupledSystemSolver> cycle_zero_solver = nullptr,
379  FieldType<parameter_space>... parameter_types)
380 {
381  auto field_store = std::make_shared<FieldStore>(mesh, 100);
382 
383  auto prefix = [&](const std::string& name) {
384  if (prepend_name.empty()) {
385  return name;
386  }
387  return prepend_name + "_" + name;
388  };
389 
390  FieldType<H1<1, dim>> shape_disp_type(prefix("shape_displacement"));
391  field_store->addShapeDisp(shape_disp_type);
392 
393  // Displacement fields (4-state second-order)
394  auto disp_time_rule_ptr = std::make_shared<DisplacementTimeRule>(disp_rule);
395  FieldType<H1<disp_order, dim>> disp_type(prefix("displacement_solve_state"));
396  auto disp_bc = field_store->addIndependent(disp_type, disp_time_rule_ptr);
397  auto disp_old_type = field_store->addDependent(disp_type, FieldStore::TimeDerivative::VAL, prefix("displacement"));
398  auto velo_old_type = field_store->addDependent(disp_type, FieldStore::TimeDerivative::DOT, prefix("velocity"));
399  auto accel_old_type = field_store->addDependent(disp_type, FieldStore::TimeDerivative::DDOT, prefix("acceleration"));
400 
401  // Temperature fields (2-state first-order)
402  auto temperature_time_rule_ptr = std::make_shared<TemperatureTimeRule>(temp_rule);
403  FieldType<H1<temp_order>> temperature_type(prefix("temperature_solve_state"));
404  auto temperature_bc = field_store->addIndependent(temperature_type, temperature_time_rule_ptr);
405  auto temperature_old_type =
406  field_store->addDependent(temperature_type, FieldStore::TimeDerivative::VAL, prefix("temperature"));
407 
408  std::vector<FieldState> parameter_fields;
409  (field_store->addParameter(FieldType<parameter_space>(prefix("param_" + parameter_types.name))), ...);
410  (parameter_fields.push_back(field_store->getField(prefix("param_" + parameter_types.name))), ...);
411 
412  using SystemType =
413  ThermoMechanicsSystem<dim, disp_order, temp_order, DisplacementTimeRule, TemperatureTimeRule, parameter_space...>;
414 
415  // Solid mechanics weak form (u, u_old, v_old, a_old, temp, temp_old, params...)
416  std::string solid_force_name = prefix("solid_force");
417  auto solid_weak_form = std::make_shared<typename SystemType::SolidWeakFormType>(
418  solid_force_name, field_store->getMesh(), field_store->getField(disp_type.name).get()->space(),
419  field_store->createSpaces(solid_force_name, disp_type.name, disp_type, disp_old_type, velo_old_type,
420  accel_old_type, temperature_type, temperature_old_type,
421  FieldType<parameter_space>(prefix("param_" + parameter_types.name))...));
422 
423  // Thermal weak form (temp, temp_old, u, u_old, v_old, a_old, params...)
424  std::string thermal_flux_name = prefix("thermal_flux");
425  auto thermal_weak_form = std::make_shared<typename SystemType::ThermalWeakFormType>(
426  thermal_flux_name, field_store->getMesh(), field_store->getField(temperature_type.name).get()->space(),
427  field_store->createSpaces(thermal_flux_name, temperature_type.name, temperature_type, temperature_old_type,
428  disp_type, disp_old_type, velo_old_type, accel_old_type,
429  FieldType<parameter_space>(prefix("param_" + parameter_types.name))...));
430 
431  // Cycle-zero weak form (u, v, a, temp, temp_old, params...)
432  std::string cycle_zero_name = prefix("solid_reaction");
433  auto cycle_zero_weak_form = std::make_shared<typename SystemType::CycleZeroWeakFormType>(
434  cycle_zero_name, field_store->getMesh(), field_store->getField(accel_old_type.name).get()->space(),
435  field_store->createSpaces(cycle_zero_name, accel_old_type.name, disp_type, velo_old_type, accel_old_type,
436  temperature_type, temperature_old_type,
437  FieldType<parameter_space>(prefix("param_" + parameter_types.name))...));
438 
439  if (cycle_zero_solver == nullptr) {
440  cycle_zero_solver = solver->singleBlockSolver(0);
441  }
442  SLIC_ERROR_IF(cycle_zero_solver == nullptr,
443  "Could not derive a cycle-zero solver for block 0 from the provided thermo-mechanics solver.");
444 
445  // Build solver and advancer
446  std::vector<std::shared_ptr<WeakForm>> weak_forms{solid_weak_form, thermal_weak_form};
447  auto advancer = std::make_shared<MultiphysicsTimeIntegrator>(field_store, weak_forms, solver, cycle_zero_weak_form,
448  cycle_zero_solver);
449 
450  return SystemType{{field_store, solver, advancer, parameter_fields, prepend_name},
451  solid_weak_form,
452  thermal_weak_form,
453  cycle_zero_weak_form,
454  disp_bc,
455  temperature_bc,
456  disp_time_rule_ptr,
457  temperature_time_rule_ptr};
458 }
459 
463 template <int dim, int disp_order, int temp_order, typename DisplacementTimeRule, typename TemperatureTimeRule,
464  typename... parameter_space>
465 auto buildThermoMechanicsSystem(std::shared_ptr<Mesh> mesh, std::shared_ptr<CoupledSystemSolver> solver,
466  DisplacementTimeRule disp_rule, TemperatureTimeRule temp_rule, std::string prepend_name,
467  FieldType<parameter_space>... parameter_types)
468 {
469  return buildThermoMechanicsSystem<dim, disp_order, temp_order>(mesh, solver, disp_rule, temp_rule,
470  std::move(prepend_name), nullptr, parameter_types...);
471 }
472 
476 template <int dim, int disp_order, int temp_order, typename DisplacementTimeRule, typename TemperatureTimeRule,
477  typename... parameter_space>
478 auto buildThermoMechanicsSystem(std::shared_ptr<Mesh> mesh, std::shared_ptr<CoupledSystemSolver> solver,
479  DisplacementTimeRule disp_rule, TemperatureTimeRule temp_rule,
480  std::shared_ptr<CoupledSystemSolver> cycle_zero_solver,
481  FieldType<parameter_space>... parameter_types)
482 {
483  return buildThermoMechanicsSystem<dim, disp_order, temp_order>(mesh, solver, disp_rule, temp_rule, "",
484  cycle_zero_solver, parameter_types...);
485 }
486 
490 template <int dim, int disp_order, int temp_order, typename DisplacementTimeRule, typename TemperatureTimeRule,
491  typename... parameter_space>
492 auto buildThermoMechanicsSystem(std::shared_ptr<Mesh> mesh, std::shared_ptr<CoupledSystemSolver> solver,
493  DisplacementTimeRule disp_rule, TemperatureTimeRule temp_rule,
494  FieldType<parameter_space>... parameter_types)
495 {
496  return buildThermoMechanicsSystem<dim, disp_order, temp_order>(mesh, solver, disp_rule, temp_rule, "", nullptr,
497  parameter_types...);
498 }
499 
500 } // namespace smith
Defines a BasePhysics implementation backed by FieldState objects and a gretl computational graph.
Contains DirichletBoundaryConditions class for interaction with the differentiable solve interfaces.
Accelerator functionality.
Definition: smith.cpp:36
SMITH_HOST_DEVICE auto cross(const tensor< T, 3, 2 > &A)
compute the cross product of the columns of A: A(:,1) x A(:,2)
Definition: tensor.hpp:966
ThermoMechanicsSystem< dim, disp_order, temp_order, DisplacementTimeRule, TemperatureTimeRule, parameter_space... > buildThermoMechanicsSystem(std::shared_ptr< Mesh > mesh, std::shared_ptr< CoupledSystemSolver > solver, DisplacementTimeRule disp_rule, TemperatureTimeRule temp_rule, std::string prepend_name="", std::shared_ptr< CoupledSystemSolver > cycle_zero_solver=nullptr, FieldType< parameter_space >... parameter_types)
Factory function to build a thermo-mechanical system.
constexpr SMITH_HOST_DEVICE auto norm(const isotropic_tensor< T, m, m > &I)
compute the Frobenius norm (sqrt(tr(dot(transpose(I), I)))) of an isotropic tensor
mfem::future::tuple< T... > tuple
Expose MFEM tuple in the Smith namespace.
Definition: tuple.hpp:241
This file contains nonlinear block solver interfaces and helpers.
@ DOT
The first time derivative.
@ DDOT
The second time derivative.
Representation of a field type with a name and an optional unknown index.
Definition: field_store.hpp:30
std::string name
Name of the field.
Definition: field_store.hpp:37
H1 elements of order p.
a struct that is used in the physics modules to clarify which template arguments are user-controlled ...
Definition: common.hpp:45
Base struct for physics systems containing common members and helper functions.
Definition: system_base.hpp:60
std::string prefix(const std::string &name) const
Helper function to prepend the physics name to a string.
Definition: system_base.hpp:78
std::shared_ptr< StateAdvancer > advancer
The state advancer.
Definition: system_base.hpp:63
std::shared_ptr< FieldStore > field_store
Field store managing the system's fields.
Definition: system_base.hpp:61
const std::vector< FieldState > & getParameterFields() const
Get the list of all parameter fields.
Definition: system_base.hpp:71
Container for a coupled thermo-mechanical system with configurable time integration.
void addSolidBodyForce(const std::string &domain_name, BodyForceType force_function)
Add a body force to the solid mechanics part of the system.
std::shared_ptr< SolidWeakFormType > solid_weak_form
Solid mechanics weak form.
std::unique_ptr< DifferentiablePhysics > createDifferentiablePhysics(std::string physics_name)
Create a DifferentiablePhysics object for this system.
std::shared_ptr< CycleZeroWeakFormType > cycle_zero_weak_form
Cycle-zero weak form.
void addSolidTraction(const std::string &domain_name, SurfaceFluxType flux_function)
Add a surface traction to the solid mechanics part.
void addPressure(DependsOn< active_parameters... > depends_on, const std::string &domain_name, PressureType pressure_function)
Add a pressure boundary condition (follower force) to the solid part (with DependsOn).
void addHeatFlux(DependsOn< active_parameters... > depends_on, const std::string &domain_name, SurfaceFluxType flux_function)
Add a boundary heat flux to the thermal part (with DependsOn).
std::shared_ptr< DisplacementTimeRule > disp_time_rule
Time integration for displacement.
std::vector< ReactionInfo > getReactionInfos() const
Get information about reaction fields for this system.
void addHeatSource(DependsOn< active_parameters... > depends_on, const std::string &domain_name, BodySourceType source_function)
Add a body heat source to the thermal part (with DependsOn).
void addHeatSource(const std::string &domain_name, BodySourceType source_function)
Add a body heat source to the thermal part.
std::shared_ptr< DirichletBoundaryConditions > temperature_bc
Temperature boundary conditions.
std::shared_ptr< DirichletBoundaryConditions > disp_bc
Displacement boundary conditions.
void addPressure(const std::string &domain_name, PressureType pressure_function)
Add a pressure boundary condition (follower force) to the solid part.
std::shared_ptr< TemperatureTimeRule > temperature_time_rule
Time integration for temperature.
std::vector< FieldState > getStateFields() const
Get the list of all state fields (disp_pred, disp, vel, accel, temp_pred, temp).
std::shared_ptr< ThermalWeakFormType > thermal_weak_form
Thermal weak form.
void addHeatFlux(const std::string &domain_name, SurfaceFluxType flux_function)
Add a boundary heat flux to the thermal part.
void setMaterial(const MaterialType &material, const std::string &domain_name)
Set the material model for a domain, defining integrals for solid and thermal weak forms.
void addSolidTraction(DependsOn< active_parameters... > depends_on, const std::string &domain_name, SurfaceFluxType flux_function)
Add a surface traction to the solid mechanics part (with DependsOn).
void addSolidBodyForce(DependsOn< active_parameters... > depends_on, const std::string &domain_name, BodyForceType force_function)
Add a body force to the solid mechanics part of the system (with DependsOn).
Defines the SystemBase struct for common system functionality.
Wraps FunctionalWeakForm to provide TimeInfo (time, dt, cycle) to integrands instead of just time.
Provides templated implementations for discretizing values, velocities and accelerations from current...
Specifies interface for evaluating weak form residuals and their gradients.