Smith  0.1
Smith is an implicit thermal structural mechanics simulation code.
thermomechanics.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 
13 #pragma once
14 
15 #include "mfem.hpp"
16 
18 #include "smith/physics/boundary_conditions/components.hpp"
24 
25 namespace smith {
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<smith::Mesh> smith_mesh, int cycle = 0,
53  double time = 0.0)
54  : Thermomechanics(std::make_unique<EquationSolver>(thermal_nonlin_opts, thermal_lin_opts, smith_mesh->getComm()),
55  thermal_timestepping,
56  std::make_unique<EquationSolver>(solid_nonlin_opts, solid_lin_opts, smith_mesh->getComm()),
57  solid_timestepping, physics_name, smith_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<smith::Mesh> smith_mesh, int cycle = 0,
76  double time = 0.0)
77  : BasePhysics(physics_name, smith_mesh),
78  thermal_(std::move(thermal_solver), thermal_timestepping, physics_name + "thermal", smith_mesh,
79  {"displacement"}, cycle, time),
80  solid_(std::move(solid_solver), solid_timestepping, physics_name + "mechanical", smith_mesh, {"temperature"},
81  cycle, time)
82  {
83  SLIC_ERROR_ROOT_IF(mfemParMesh().Dimension() != dim,
84  std::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(
172  std::format("State '{}' requested from solid mechanics module '{}', but it doesn't exist", 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(
200  std::format("setState for state named '{}' requested from thermomechanics module '{}', but it doesn't exist",
201  state_name, 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(std::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  SMITH_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 smith::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  SMITH_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 smith::FiniteElementState& displacement() const { return solid_.displacement(); };
546 
552  const smith::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 smith
#define SMITH_HOST_DEVICE
Macro that evaluates to __host__ __device__ when compiling with nvcc or amdclang and does nothing on ...
Definition: accelerator.hpp:37
The base interface class for a generic PDE solver.
This is the abstract base class for a generic forward solver.
std::string name_
Name of the physics module.
std::vector< const smith::FiniteElementState * > states_
List of finite element primal states associated with this physics module.
int cycle_
Current cycle (forward pass time iteration count)
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 & mfemParMesh() const
Returns a reference to the mfem ParMesh object.
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.
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.
std::shared_ptr< QuadratureData< T > > createQuadratureDataBuffer(T initial_state)
Create a shared ptr to a quadrature data buffer for the given material type.
void setDisplacement(Callable displacement)
Set the underlying finite element state to a prescribed displacement.
const smith::FiniteElementState & temperature() const
Get the temperature state.
virtual std::vector< std::string > stateNames() const override
Get a vector of the finite element state solution variable names.
const FiniteElementState & adjoint(const std::string &state_name) const override
Accessor for getting named finite element adjoint fields from the physics modules.
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.
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 setHeatFluxBCs(FluxType flux_function)
Set the thermal flux boundary condition.
void advanceTimestep(double dt) override
Advance the timestep.
void addHeatSource(HeatSourceType source_function)
Set the thermal source function.
void setState(const std::string &state_name, const FiniteElementState &state) override
Set the primal solution field (displacement, velocity, temperature) for the underlying thermomechanic...
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...
void setTemperature(std::function< double(const mfem::Vector &x, double t)> temperature)
Set the underlying finite element state to a prescribed temperature.
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< smith::Mesh > smith_mesh, int cycle=0, double time=0.0)
Construct a new coupled Thermal-SolidMechanics object.
const smith::FiniteElementState & displacement() const
Get the displacement state.
H1< order, dim > displacement_field
the function space for the displacement field
void setFixedBCs(Domain &domain, Components components=Component::ALL)
Shortcut to set selected components of displacements to zero for all time.
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 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 setDisplacementBCs(AppliedDisplacementFunction applied_displacement, Domain &domain, Components components=Component::ALL)
Set essential displacement boundary conditions on selected components.
void completeSetup() override
Complete the initialization and allocation of the data structures.
void setMaterial(DependsOn< active_parameters... >, const MaterialType &material, Domain &domain, std::shared_ptr< QuadratureData< StateType >> qdata)
Set the thermomechanical material response.
H1< order > temperature_field
the function space for the temperature field
void addBodyForce(BodyForceType body_force_function)
Set the body forcefunction.
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< smith::Mesh > smith_mesh, int cycle=0, double time=0.0)
Construct a new coupled Thermal-SolidMechanics object.
An object containing the solver for a heat transfer PDE.
Accelerator functionality.
Definition: smith.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:45
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 > reference_temperature
The reference temperature for thermal expansion.
std::optional< input::CoefficientInputOptions > coef_thermal_expansion
The isotropic coefficient of thermal expansion.
This is an adaptor class that makes a thermomechanical material usable by the solid mechanics module,...
SMITH_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
typename ThermalMechanicalMaterial::State State
internal variables for the wrapped material model
MechanicalMaterialInterface(ThermalMechanicalMaterial m)
constructor
const ThermalMechanicalMaterial mat
the wrapped material model
This is an adaptor class that makes a thermomechanical material usable by the thermal module,...
SMITH_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
typename ThermalMechanicalMaterial::State State
internal variables for the wrapped material model
const ThermalMechanicalMaterial mat
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.