Serac  0.1
Serac is an implicit thermal strucural mechanics simulation code.
thermomechanics.hpp
Go to the documentation of this file.
1 // Copyright (c) 2019-2024, Lawrence Livermore National Security, LLC and
2 // other Serac Project Developers. See the top-level LICENSE file for
3 // details.
4 //
5 // SPDX-License-Identifier: (BSD-3-Clause)
6 
13 #pragma once
14 
15 #include "mfem.hpp"
16 
23 
24 namespace serac {
25 
31 template <int order, int dim, typename... parameter_space>
32 class Thermomechanics : public BasePhysics {
33 public:
49  Thermomechanics(const NonlinearSolverOptions thermal_nonlin_opts, const LinearSolverOptions thermal_lin_opts,
50  TimesteppingOptions thermal_timestepping, const NonlinearSolverOptions solid_nonlin_opts,
51  const LinearSolverOptions solid_lin_opts, TimesteppingOptions solid_timestepping,
52  GeometricNonlinearities geom_nonlin, const std::string& physics_name, std::string mesh_tag,
53  int cycle = 0, double time = 0.0)
55  std::make_unique<EquationSolver>(thermal_nonlin_opts, thermal_lin_opts,
56  StateManager::mesh(mesh_tag).GetComm()),
57  thermal_timestepping,
58  std::make_unique<EquationSolver>(solid_nonlin_opts, solid_lin_opts, StateManager::mesh(mesh_tag).GetComm()),
59  solid_timestepping, geom_nonlin, physics_name, mesh_tag, cycle, time)
60  {
61  }
62 
76  Thermomechanics(std::unique_ptr<EquationSolver> thermal_solver, TimesteppingOptions thermal_timestepping,
77  std::unique_ptr<EquationSolver> solid_solver, TimesteppingOptions solid_timestepping,
78  GeometricNonlinearities geom_nonlin, const std::string& physics_name, std::string mesh_tag,
79  int cycle = 0, double time = 0.0)
80  : BasePhysics(physics_name, mesh_tag),
81  thermal_(std::move(thermal_solver), thermal_timestepping, physics_name + "thermal", mesh_tag, {"displacement"},
82  cycle, time),
83  solid_(std::move(solid_solver), solid_timestepping, geom_nonlin, physics_name + "mechanical", mesh_tag,
84  {"temperature"}, cycle, time)
85  {
86  SLIC_ERROR_ROOT_IF(mesh_.Dimension() != dim,
87  axom::fmt::format("Compile time dimension and runtime mesh dimension mismatch"));
88 
89  states_.push_back(&thermal_.temperature());
90  states_.push_back(&solid_.velocity());
91  states_.push_back(&solid_.displacement());
92  }
93 
104  Thermomechanics(const HeatTransferInputOptions& thermal_options, const SolidMechanicsInputOptions& solid_options,
105  const std::string& physics_name, std::string mesh_tag, int cycle = 0, double time = 0.0)
106  : Thermomechanics(thermal_options.nonlin_solver_options, thermal_options.lin_solver_options,
107  thermal_options.timestepping_options, solid_options.nonlin_solver_options,
108  solid_options.lin_solver_options, solid_options.timestepping_options, solid_options.geom_nonlin,
109  physics_name, mesh_tag, cycle, time)
110  {
111  }
112 
122  Thermomechanics(const ThermomechanicsInputOptions& options, const std::string& physics_name, std::string mesh_tag,
123  int cycle = 0, double time = 0.0)
124  : Thermomechanics(options.thermal_options, options.solid_options, physics_name, mesh_tag, cycle, time)
125  {
126  if (options.coef_thermal_expansion) {
127  std::unique_ptr<mfem::Coefficient> cte(options.coef_thermal_expansion->constructScalar());
128  std::unique_ptr<mfem::Coefficient> ref_temp(options.reference_temperature->constructScalar());
129 
130  // setThermalExpansion(std::move(cte), std::move(ref_temp));
131  }
132  }
133 
139  void completeSetup() override
140  {
141  thermal_.completeSetup();
142  solid_.completeSetup();
143  }
144 
151  void resetStates(int cycle = 0, double time = 0.0) override
152  {
154  thermal_.resetStates(cycle, time);
155  solid_.resetStates(cycle, time);
156  }
157 
164  const FiniteElementState& state(const std::string& state_name) const override
165  {
166  if (state_name == "displacement") {
167  return solid_.displacement();
168  } else if (state_name == "velocity") {
169  return solid_.velocity();
170  } else if (state_name == "temperature") {
171  return thermal_.temperature();
172  }
173 
174  SLIC_ERROR_ROOT(axom::fmt::format("State '{}' requested from solid mechanics module '{}', but it doesn't exist",
175  state_name, name_));
176  return solid_.displacement();
177  }
178 
189  void setState(const std::string& state_name, const FiniteElementState& state) override
190  {
191  if (state_name == "displacement") {
192  const_cast<FiniteElementState&>(solid_.displacement()) = state;
193  return;
194  } else if (state_name == "velocity") {
195  const_cast<FiniteElementState&>(solid_.velocity()) = state;
196  return;
197  } else if (state_name == "temperature") {
198  const_cast<FiniteElementState&>(thermal_.temperature()) = state;
199  return;
200  }
201 
202  SLIC_ERROR_ROOT(axom::fmt::format(
203  "setState for state named '{}' requested from thermomechanics module '{}', but it doesn't exist", state_name,
204  name_));
205  }
206 
212  virtual std::vector<std::string> stateNames() const override
213  {
214  return std::vector<std::string>{"displacement", "velocity", "temperature"};
215  }
216 
223  const FiniteElementState& adjoint(const std::string& state_name) const override
224  {
225  if (state_name == "displacement") {
226  return solid_.adjoint("displacement");
227  } else if (state_name == "temperature") {
228  return thermal_.adjoint("temperature");
229  }
230 
231  SLIC_ERROR_ROOT(axom::fmt::format("Adjoint '{}' requested from solid mechanics module '{}', but it doesn't exist",
232  state_name, name_));
233  return solid_.displacement();
234  }
235 
241  void advanceTimestep(double dt) override
242  {
243  thermal_.setParameter(0, solid_.displacement());
244  thermal_.advanceTimestep(dt);
245 
246  solid_.setParameter(0, thermal_.temperature());
247  solid_.advanceTimestep(dt);
248 
249  cycle_ += 1;
250  time_ += dt;
251  }
252 
260  template <typename T>
261  std::shared_ptr<QuadratureData<T>> createQuadratureDataBuffer(T initial_state)
262  {
263  return solid_.createQuadratureDataBuffer(initial_state);
264  }
265 
272  template <typename ThermalMechanicalMaterial>
274  using State = typename ThermalMechanicalMaterial::State;
275 
276  const ThermalMechanicalMaterial mat;
277 
279  ThermalMaterialInterface(const ThermalMechanicalMaterial& m) : mat(m)
280  {
281  // empty
282  }
283 
297  template <typename T1, typename T2, typename T3, typename T4, typename... param_types>
298  SERAC_HOST_DEVICE auto operator()(const T1& /* x */, const T2& temperature, const T3& temperature_gradient,
299  const T4& displacement, param_types... parameters) const
300  {
301  // BT: this will not update the state correctly. I just want to get the code compiling before plumbing the
302  // state variables.
303  State state{};
304 
305  auto [u, du_dX] = displacement;
306  auto [T, heat_capacity, s0, q0] = mat(state, du_dX, temperature, temperature_gradient, parameters...);
307 
308  return serac::tuple{heat_capacity, q0};
309  }
310  };
311 
318  template <typename ThermalMechanicalMaterial>
320  using State = typename ThermalMechanicalMaterial::State;
321 
322  const ThermalMechanicalMaterial mat;
323 
324  const double density;
325 
327  MechanicalMaterialInterface(const ThermalMechanicalMaterial& m) : mat(m), density(m.density)
328  {
329  // empty
330  }
331 
343  template <typename T1, typename T2, typename... param_types>
344  SERAC_HOST_DEVICE auto operator()(State& state, const T1& displacement_gradient, const T2& temperature,
345  param_types... parameters) const
346  {
347  auto [theta, dtheta_dX] = temperature;
348  auto [T, heat_capacity, s0, q0] = mat(state, displacement_gradient, theta, dtheta_dX, parameters...);
349  return T;
350  }
351  };
352 
377  template <int... active_parameters, typename MaterialType, typename StateType>
378  void setMaterial(DependsOn<active_parameters...>, MaterialType material,
379  std::shared_ptr<QuadratureData<StateType>> qdata)
380  {
381  // note: these parameter indices are offset by 1 since, internally, this module uses the first parameter
382  // to communicate the temperature and displacement field information to the other physics module
383  //
386  qdata);
387  }
388 
390  template <typename MaterialType, typename StateType = Empty>
391  void setMaterial(MaterialType material, std::shared_ptr<QuadratureData<StateType>> qdata = EmptyQData)
392  {
393  setMaterial(DependsOn<>{}, material, qdata);
394  }
395 
402  void setTemperatureBCs(const std::set<int>& temperature_attributes,
403  std::function<double(const mfem::Vector& x, double t)> prescribed_value)
404  {
405  thermal_.setTemperatureBCs(temperature_attributes, prescribed_value);
406  }
407 
414  void setDisplacementBCs(const std::set<int>& displacement_attributes,
415  std::function<void(const mfem::Vector& x, mfem::Vector& disp)> prescribed_value)
416  {
417  solid_.setDisplacementBCs(displacement_attributes, prescribed_value);
418  }
419 
443  template <typename FluxType>
444  void setHeatFluxBCs(FluxType flux_function)
445  {
446  thermal_.setFluxBCs(flux_function);
447  }
448 
454  void setDisplacement(std::function<void(const mfem::Vector& x, mfem::Vector& u)> displacement)
455  {
456  solid_.setDisplacement(displacement);
457  }
458 
464  void setTemperature(std::function<double(const mfem::Vector& x, double t)> temperature)
465  {
466  thermal_.setTemperature(temperature);
467  }
468 
484  template <typename BodyForceType>
485  void addBodyForce(BodyForceType body_force_function)
486  {
487  solid_.addBodyForce(body_force_function);
488  }
489 
509  template <typename HeatSourceType>
510  void addHeatSource(HeatSourceType source_function)
511  {
512  thermal_.setSource(source_function);
513  }
514 
520  const serac::FiniteElementState& displacement() const { return solid_.displacement(); };
521 
527  const serac::FiniteElementState& temperature() const { return thermal_.temperature(); };
528 
529 protected:
532 
534  HeatTransfer<order, dim, Parameters<displacement_field, parameter_space...>> thermal_;
535 
537  SolidMechanics<order, dim, Parameters<temperature_field, parameter_space...>> solid_;
538 };
539 
540 } // namespace serac
#define SERAC_HOST_DEVICE
Macro that evaluates to __host__ __device__ when compiling with nvcc and does nothing on a host compi...
Definition: accelerator.hpp:38
The base interface class for a generic PDE solver.
This is the abstract base class for a generic forward solver.
mfem::ParMesh & mesh_
The primary mesh.
int cycle_
Current cycle (forward pass time iteration count)
std::vector< const serac::FiniteElementState * > states_
List of finite element primal states associated with this physics module.
virtual double time() const
Get the current forward-solution time.
double time_
Current time for the forward pass.
virtual int cycle() const
Get the current forward-solution cycle iteration number.
const mfem::ParMesh & mesh() const
Returns a reference to the mesh object.
std::string name_
Name of the physics module.
void initializeBasePhysicsStates(int cycle, double time)
Protected, non-virtual method to reset physics states to zero. This does not reset design parameters ...
This class manages the objects typically required to solve a nonlinear set of equations arising from ...
Class for encapsulating the critical MFEM components of a primal finite element field.
An object containing the solver for a heat transfer PDE.
Manages the lifetimes of FEState objects such that restarts are abstracted from physics modules.
The operator-split thermal-structural solver.
void addHeatSource(HeatSourceType source_function)
Set the thermal source function.
Thermomechanics(const HeatTransferInputOptions &thermal_options, const SolidMechanicsInputOptions &solid_options, const std::string &physics_name, std::string mesh_tag, int cycle=0, double time=0.0)
Construct a new Thermal-SolidMechanics Functional object from input file options.
Thermomechanics(const NonlinearSolverOptions thermal_nonlin_opts, const LinearSolverOptions thermal_lin_opts, TimesteppingOptions thermal_timestepping, const NonlinearSolverOptions solid_nonlin_opts, const LinearSolverOptions solid_lin_opts, TimesteppingOptions solid_timestepping, GeometricNonlinearities geom_nonlin, const std::string &physics_name, std::string mesh_tag, int cycle=0, double time=0.0)
Construct a new coupled Thermal-SolidMechanics object.
void setMaterial(MaterialType material, std::shared_ptr< QuadratureData< StateType >> qdata=EmptyQData)
This is an overloaded member function, provided for convenience. It differs from the above function o...
H1< order > temperature_field
the function space for the temperature field
const FiniteElementState & adjoint(const std::string &state_name) const override
Accessor for getting named finite element adjoint fields from the physics modules.
std::shared_ptr< QuadratureData< T > > createQuadratureDataBuffer(T initial_state)
Create a shared ptr to a quadrature data buffer for the given material type.
void advanceTimestep(double dt) override
Advance the timestep.
void setState(const std::string &state_name, const FiniteElementState &state) override
Set the primal solution field (displacement, velocity, temperature) for the underlying thermomechanic...
void setDisplacementBCs(const std::set< int > &displacement_attributes, std::function< void(const mfem::Vector &x, mfem::Vector &disp)> prescribed_value)
Set essential displacement boundary conditions (strongly enforced)
void resetStates(int cycle=0, double time=0.0) override
Method to reset physics states to zero. This does not reset design parameters or shape.
void setTemperature(std::function< double(const mfem::Vector &x, double t)> temperature)
Set the underlying finite element state to a prescribed temperature.
H1< order, dim > displacement_field
the function space for the displacement field
virtual std::vector< std::string > stateNames() const override
Get a vector of the finite element state solution variable names.
void setMaterial(DependsOn< active_parameters... >, MaterialType material, std::shared_ptr< QuadratureData< StateType >> qdata)
Set the thermomechanical material response.
void addBodyForce(BodyForceType body_force_function)
Set the body forcefunction.
void setHeatFluxBCs(FluxType flux_function)
Set the thermal flux boundary condition.
SolidMechanics< order, dim, Parameters< temperature_field, parameter_space... > > solid_
Submodule to compute the mechanics.
const FiniteElementState & state(const std::string &state_name) const override
Accessor for getting named finite element state primal fields from the physics modules.
void setTemperatureBCs(const std::set< int > &temperature_attributes, std::function< double(const mfem::Vector &x, double t)> prescribed_value)
Set essential temperature boundary conditions (strongly enforced)
HeatTransfer< order, dim, Parameters< displacement_field, parameter_space... > > thermal_
Submodule to compute the heat transfer physics.
void setDisplacement(std::function< void(const mfem::Vector &x, mfem::Vector &u)> displacement)
Set the underlying finite element state to a prescribed displacement.
Thermomechanics(const ThermomechanicsInputOptions &options, const std::string &physics_name, std::string mesh_tag, int cycle=0, double time=0.0)
Construct a new Thermal-SolidMechanics Functional object from input file options.
const serac::FiniteElementState & displacement() const
Get the displacement state.
Thermomechanics(std::unique_ptr< EquationSolver > thermal_solver, TimesteppingOptions thermal_timestepping, std::unique_ptr< EquationSolver > solid_solver, TimesteppingOptions solid_timestepping, GeometricNonlinearities geom_nonlin, const std::string &physics_name, std::string mesh_tag, int cycle=0, double time=0.0)
Construct a new coupled Thermal-SolidMechanics object.
void completeSetup() override
Complete the initialization and allocation of the data structures.
const serac::FiniteElementState & temperature() const
Get the temperature state.
An object containing the solver for a heat transfer PDE.
Accelerator functionality.
Definition: serac.cpp:38
std::shared_ptr< QuadratureData< Empty > > EmptyQData
a single instance of a QuadratureData container of Emptys, since they are all interchangeable
GeometricNonlinearities
Enum to set the geometric nonlinearity flag.
Definition: common.hpp:32
The material and load types for the solid functional physics module.
An object containing the solver for total Lagrangian finite deformation solid mechanics.
H1 elements of order p.
Stores all information held in the input file that is used to configure the solver.
Parameters for an iterative linear solution scheme.
Nonlinear solution scheme parameters.
a struct that is used in the physics modules to clarify which template arguments are user-controlled ...
Definition: common.hpp:23
A class for storing and access user-defined types at quadrature points.
Stores all information held in the input file that is used to configure the solver.
Stores all information held in the input file that is used to configure the thermal structural solver...
std::optional< input::CoefficientInputOptions > coef_thermal_expansion
The isotropic coefficient of thermal expansion.
std::optional< input::CoefficientInputOptions > reference_temperature
The reference temperature for thermal expansion.
This is an adaptor class that makes a thermomechanical material usable by the solid mechanics module,...
typename ThermalMechanicalMaterial::State State
internal variables for the wrapped material model
MechanicalMaterialInterface(const ThermalMechanicalMaterial &m)
constructor
SERAC_HOST_DEVICE auto operator()(State &state, const T1 &displacement_gradient, const T2 &temperature, param_types... parameters) const
glue code to evaluate a thermomechanical material and extract the stress
const ThermalMechanicalMaterial mat
the wrapped material model
This is an adaptor class that makes a thermomechanical material usable by the thermal module,...
SERAC_HOST_DEVICE auto operator()(const T1 &, const T2 &temperature, const T3 &temperature_gradient, const T4 &displacement, param_types... parameters) const
glue code to evaluate a thermomechanical material and extract the thermal outputs
ThermalMaterialInterface(const ThermalMechanicalMaterial &m)
constructor
const ThermalMechanicalMaterial mat
the wrapped material model
typename ThermalMechanicalMaterial::State State
internal variables for the wrapped material model
A timestep and boundary condition enforcement method for a dynamic solver.
This is a class that mimics most of std::tuple's interface, except that it is usable in CUDA kernels ...
Definition: tuple.hpp:28
The material and load types for the thermal functional physics module.
An object containing all input file options for the solver for thermal structural solver.