Serac  0.1
Serac is an implicit thermal strucural mechanics simulation code.
thermomechanics.hpp
Go to the documentation of this file.
1 // Copyright (c) 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 
18 #include "serac/physics/boundary_conditions/components.hpp"
24 
25 namespace serac {
26 
32 template <int order, int dim, typename... parameter_space>
33 class Thermomechanics : public BasePhysics {
34  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  const std::string& physics_name, std::shared_ptr<serac::Mesh> serac_mesh, int cycle = 0,
53  double time = 0.0)
54  : Thermomechanics(std::make_unique<EquationSolver>(thermal_nonlin_opts, thermal_lin_opts, serac_mesh->getComm()),
55  thermal_timestepping,
56  std::make_unique<EquationSolver>(solid_nonlin_opts, solid_lin_opts, serac_mesh->getComm()),
57  solid_timestepping, physics_name, serac_mesh, cycle, time)
58  {
59  }
60 
73  Thermomechanics(std::unique_ptr<EquationSolver> thermal_solver, TimesteppingOptions thermal_timestepping,
74  std::unique_ptr<EquationSolver> solid_solver, TimesteppingOptions solid_timestepping,
75  const std::string& physics_name, std::shared_ptr<serac::Mesh> serac_mesh, int cycle = 0,
76  double time = 0.0)
77  : BasePhysics(physics_name, serac_mesh),
78  thermal_(std::move(thermal_solver), thermal_timestepping, physics_name + "thermal", serac_mesh,
79  {"displacement"}, cycle, time),
80  solid_(std::move(solid_solver), solid_timestepping, physics_name + "mechanical", serac_mesh, {"temperature"},
81  cycle, time)
82  {
83  SLIC_ERROR_ROOT_IF(mfemParMesh().Dimension() != dim,
84  axom::fmt::format("Compile time dimension and runtime mesh dimension mismatch"));
85 
86  states_.push_back(&thermal_.temperature());
87  states_.push_back(&solid_.velocity());
88  states_.push_back(&solid_.displacement());
89  }
90 
101  Thermomechanics(const HeatTransferInputOptions& thermal_options, const SolidMechanicsInputOptions& solid_options,
102  const std::string& physics_name, std::string mesh_tag, int cycle = 0, double time = 0.0)
103  : Thermomechanics(thermal_options.nonlin_solver_options, thermal_options.lin_solver_options,
104  thermal_options.timestepping_options, solid_options.nonlin_solver_options,
105  solid_options.lin_solver_options, solid_options.timestepping_options, physics_name, mesh_tag,
106  cycle, time)
107  {
108  }
109 
119  Thermomechanics(const ThermomechanicsInputOptions& options, const std::string& physics_name, std::string mesh_tag,
120  int cycle = 0, double time = 0.0)
121  : Thermomechanics(options.thermal_options, options.solid_options, physics_name, mesh_tag, cycle, time)
122  {
123  if (options.coef_thermal_expansion) {
124  std::unique_ptr<mfem::Coefficient> cte(options.coef_thermal_expansion->constructScalar());
125  std::unique_ptr<mfem::Coefficient> ref_temp(options.reference_temperature->constructScalar());
126 
127  // setThermalExpansion(std::move(cte), std::move(ref_temp));
128  }
129  }
130 
136  void completeSetup() override
137  {
138  thermal_.completeSetup();
139  solid_.completeSetup();
140  }
141 
148  void resetStates(int cycle = 0, double time = 0.0) override
149  {
151  thermal_.resetStates(cycle, time);
152  solid_.resetStates(cycle, time);
153  }
154 
161  const FiniteElementState& state(const std::string& state_name) const override
162  {
163  if (state_name == "displacement") {
164  return solid_.displacement();
165  } else if (state_name == "velocity") {
166  return solid_.velocity();
167  } else if (state_name == "temperature") {
168  return thermal_.temperature();
169  }
170 
171  SLIC_ERROR_ROOT(axom::fmt::format("State '{}' requested from solid mechanics module '{}', but it doesn't exist",
172  state_name, name_));
173  return solid_.displacement();
174  }
175 
186  void setState(const std::string& state_name, const FiniteElementState& state) override
187  {
188  if (state_name == "displacement") {
189  const_cast<FiniteElementState&>(solid_.displacement()) = state;
190  return;
191  } else if (state_name == "velocity") {
192  const_cast<FiniteElementState&>(solid_.velocity()) = state;
193  return;
194  } else if (state_name == "temperature") {
195  const_cast<FiniteElementState&>(thermal_.temperature()) = state;
196  return;
197  }
198 
199  SLIC_ERROR_ROOT(axom::fmt::format(
200  "setState for state named '{}' requested from thermomechanics module '{}', but it doesn't exist", state_name,
201  name_));
202  }
203 
209  virtual std::vector<std::string> stateNames() const override
210  {
211  return std::vector<std::string>{"displacement", "velocity", "temperature"};
212  }
213 
220  const FiniteElementState& adjoint(const std::string& state_name) const override
221  {
222  if (state_name == "displacement") {
223  return solid_.adjoint("displacement");
224  } else if (state_name == "temperature") {
225  return thermal_.adjoint("temperature");
226  }
227 
228  SLIC_ERROR_ROOT(axom::fmt::format("Adjoint '{}' requested from solid mechanics module '{}', but it doesn't exist",
229  state_name, name_));
230  return solid_.displacement();
231  }
232 
238  void advanceTimestep(double dt) override
239  {
240  thermal_.setParameter(0, solid_.displacement());
241  thermal_.advanceTimestep(dt);
242 
243  solid_.setParameter(0, thermal_.temperature());
244  solid_.advanceTimestep(dt);
245 
246  cycle_ += 1;
247  time_ += dt;
248  }
249 
257  template <typename T>
258  std::shared_ptr<QuadratureData<T>> createQuadratureDataBuffer(T initial_state)
259  {
260  return solid_.createQuadratureDataBuffer(initial_state);
261  }
262 
269  template <typename ThermalMechanicalMaterial>
271  using State = typename ThermalMechanicalMaterial::State;
272 
273  const ThermalMechanicalMaterial mat;
274 
276  ThermalMaterialInterface(const ThermalMechanicalMaterial& m) : mat(m)
277  {
278  // empty
279  }
280 
294  template <typename T1, typename T2, typename T3, typename T4, typename... param_types>
295  SERAC_HOST_DEVICE auto operator()(const T1& /* x */, const T2& temperature, const T3& temperature_gradient,
296  const T4& displacement, param_types... parameters) const
297  {
298  // BT: this will not update the state correctly. I just want to get the code compiling before plumbing the
299  // state variables.
300  State state{};
301 
302  auto [u, du_dX] = displacement;
303  auto [T, heat_capacity, s0, q0] = mat(state, du_dX, temperature, temperature_gradient, parameters...);
304 
305  return serac::tuple{heat_capacity, q0};
306  }
307  };
308 
315  template <typename ThermalMechanicalMaterial>
317  using State = typename ThermalMechanicalMaterial::State;
318 
319  const ThermalMechanicalMaterial mat;
320 
321  const double density;
322 
324  MechanicalMaterialInterface(ThermalMechanicalMaterial m) : mat(m), density(m.density)
325  {
326  // empty
327  }
328 
340  template <typename T1, typename T2, typename... param_types>
341  SERAC_HOST_DEVICE auto operator()(State& state, const T1& displacement_gradient, const T2& temperature,
342  param_types... parameters) const
343  {
344  auto [theta, dtheta_dX] = temperature;
345  auto [T, heat_capacity, s0, q0] = mat(state, displacement_gradient, theta, dtheta_dX, parameters...);
346  return T;
347  }
348  };
349 
375  template <int... active_parameters, typename MaterialType, typename StateType>
376  void setMaterial(DependsOn<active_parameters...>, const MaterialType& material, Domain& domain,
377  std::shared_ptr<QuadratureData<StateType>> qdata)
378  {
379  // note: these parameter indices are offset by 1 since, internally, this module uses the first parameter
380  // to communicate the temperature and displacement field information to the other physics module
381  //
383  domain);
385  domain, qdata);
386  }
387 
389  template <typename MaterialType, typename StateType = Empty>
390  void setMaterial(const MaterialType& material, Domain& domain,
391  std::shared_ptr<QuadratureData<StateType>> qdata = EmptyQData)
392  {
393  setMaterial(DependsOn<>{}, material, domain, 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 
426  template <typename AppliedDisplacementFunction>
427  void setDisplacementBCs(AppliedDisplacementFunction applied_displacement, Domain& domain,
428  Components components = Component::ALL)
429  {
430  solid_.setDisplacementBCs(applied_displacement, domain, components);
431  }
432 
442  void setFixedBCs(Domain& domain, Components components = Component::ALL) { solid_.setFixedBCs(domain, components); }
443 
467  template <typename FluxType>
468  void setHeatFluxBCs(FluxType flux_function)
469  {
470  thermal_.setFluxBCs(flux_function);
471  }
472 
478  template <typename Callable>
480  {
481  solid_.setDisplacement(displacement);
482  }
483 
489  void setTemperature(std::function<double(const mfem::Vector& x, double t)> temperature)
490  {
491  thermal_.setTemperature(temperature);
492  }
493 
509  template <typename BodyForceType>
510  void addBodyForce(BodyForceType body_force_function)
511  {
512  solid_.addBodyForce(body_force_function);
513  }
514 
534  template <typename HeatSourceType>
535  void addHeatSource(HeatSourceType source_function)
536  {
537  thermal_.setSource(source_function);
538  }
539 
545  const serac::FiniteElementState& displacement() const { return solid_.displacement(); };
546 
552  const serac::FiniteElementState& temperature() const { return thermal_.temperature(); };
553 
554  protected:
557 
559  HeatTransfer<order, dim, Parameters<displacement_field, parameter_space...>> thermal_;
560 
562  SolidMechanics<order, dim, Parameters<temperature_field, parameter_space...>> solid_;
563 };
564 
565 } // 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.
const mfem::ParMesh & mfemParMesh() const
Returns a reference to the mfem ParMesh object.
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.
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 ...
A set to flag components of a vector field.
Definition: components.hpp:29
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.
The operator-split thermal-structural solver.
void addHeatSource(HeatSourceType source_function)
Set the thermal source function.
void setMaterial(DependsOn< active_parameters... >, const MaterialType &material, Domain &domain, std::shared_ptr< QuadratureData< StateType >> qdata)
Set the thermomechanical material response.
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.
void setFixedBCs(Domain &domain, Components components=Component::ALL)
Shortcut to set selected components of displacements to zero for all time.
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 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.
void setMaterial(const MaterialType &material, Domain &domain, 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, dim > displacement_field
the function space for the displacement field
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, const std::string &physics_name, std::shared_ptr< serac::Mesh > serac_mesh, int cycle=0, double time=0.0)
Construct a new coupled Thermal-SolidMechanics object.
void setDisplacement(Callable displacement)
Set the underlying finite element state to a prescribed displacement.
virtual std::vector< std::string > stateNames() const override
Get a vector of the finite element state solution variable names.
void setDisplacementBCs(AppliedDisplacementFunction applied_displacement, Domain &domain, Components components=Component::ALL)
Set essential displacement boundary conditions on selected components.
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.
Thermomechanics(std::unique_ptr< EquationSolver > thermal_solver, TimesteppingOptions thermal_timestepping, std::unique_ptr< EquationSolver > solid_solver, TimesteppingOptions solid_timestepping, const std::string &physics_name, std::shared_ptr< serac::Mesh > serac_mesh, int cycle=0, double time=0.0)
Construct a new coupled Thermal-SolidMechanics object.
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.
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.
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:36
std::shared_ptr< QuadratureData< Empty > > EmptyQData
a single instance of a QuadratureData container of Emptys, since they are all interchangeable
The material and load types for the solid functional physics module.
Tools for tagging a set of components of a vector field for boundary condition enforcement.
a class for representing a geometric region that can be used for integration
Definition: domain.hpp:33
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:21
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,...
MechanicalMaterialInterface(ThermalMechanicalMaterial m)
constructor
typename ThermalMechanicalMaterial::State State
internal variables for the wrapped material model
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.