Smith  0.1
Smith is an implicit thermal structural mechanics simulation code.
time_integration_rule.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 
14 #pragma once
15 
16 #include <tuple>
17 #include "smith/physics/common.hpp"
19 
20 namespace smith {
21 
24  public:
26  virtual ~TimeIntegrationRule() {}
27 
29  virtual bool requiresInitialAccelerationSolve() const { return false; }
30 
33  virtual FieldState corrected_value(const TimeInfo& t, const std::vector<FieldState>& states) const = 0;
34 
36  virtual int num_args() const = 0;
37 
40  virtual FieldState corrected_dot(const TimeInfo& t, const std::vector<FieldState>& states) const = 0;
41 
44  virtual FieldState corrected_ddot(const TimeInfo& t, const std::vector<FieldState>& states) const = 0;
45 };
46 
52  public:
53  static constexpr int num_states = 2;
54 
57 
59  int num_args() const override { return num_states; }
60 
62  template <typename T1, typename T2>
63  SMITH_HOST_DEVICE auto value(const TimeInfo& /*t*/, const T1& field_new, const T2& /*field_old*/) const
64  {
65  return field_new;
66  }
67 
69  template <typename T1, typename T2>
70  SMITH_HOST_DEVICE auto dot(const TimeInfo& t, const T1& field_new, const T2& field_old) const
71  {
72  return (1.0 / t.dt()) * (field_new - field_old);
73  }
74 
76  template <typename T1, typename T2>
77  SMITH_HOST_DEVICE auto interpolate(const TimeInfo& t, const T1& field_new, const T2& field_old) const
78  {
79  return std::make_tuple(value(t, field_new, field_old), dot(t, field_new, field_old));
80  }
81 
83  FieldState corrected_value(const TimeInfo& t, const std::vector<FieldState>& states) const override
84  {
85  return value(t, states[0], states[1]);
86  }
87 
89  FieldState corrected_dot(const TimeInfo& t, const std::vector<FieldState>& states) const override
90  {
91  return dot(t, states[0], states[1]);
92  }
93 
95  FieldState corrected_ddot(const TimeInfo& /*t*/, const std::vector<FieldState>& states) const override
96  {
97  SLIC_ERROR("BackwardEulerFirstOrderTimeIntegrationRule does not support second derivatives.");
98  return states[0];
99  }
100 };
101 
106  public:
107  static constexpr int num_states = 1;
108 
111 
113  int num_args() const override { return num_states; }
114 
116  template <typename T1>
118  SMITH_HOST_DEVICE auto value(const TimeInfo& /*t*/, const T1& field_new) const
119  {
120  return field_new;
121  }
122 
124  template <typename T1>
126  SMITH_HOST_DEVICE auto dot(const TimeInfo& /*t*/, const T1& /*field_new*/) const
127  {
128  return zero{};
129  }
130 
132  template <typename T1>
133  SMITH_HOST_DEVICE auto interpolate(const TimeInfo& t, const T1& field_new) const
134  {
135  return std::make_tuple(value(t, field_new), dot(t, field_new));
136  }
137 
139  FieldState corrected_value(const TimeInfo& t, const std::vector<FieldState>& states) const override
140  {
141  return value(t, states[0]);
142  }
143 
145  FieldState corrected_dot(const TimeInfo& /*t*/, const std::vector<FieldState>& states) const override
146  {
147  return zeroCopy(states[0]);
148  }
149 
151  FieldState corrected_ddot(const TimeInfo& /*t*/, const std::vector<FieldState>& states) const override
152  {
153  SLIC_ERROR("QuasiStaticRule does not support second derivatives.");
154  return states[0];
155  }
156 };
157 
160  public:
161  static constexpr int num_states = 1;
162 
163  int num_args() const override { return num_states; }
164 
168  template <typename T1>
169  SMITH_HOST_DEVICE auto value(const TimeInfo& /*t*/, const T1& field_new) const
170  {
171  return field_new;
172  }
173 
177  template <typename T1>
178  SMITH_HOST_DEVICE auto dot(const TimeInfo& /*t*/, const T1& /*field_new*/) const
179  {
180  return zero{};
181  }
182 
186  template <typename T1>
187  SMITH_HOST_DEVICE auto ddot(const TimeInfo& /*t*/, const T1& /*field_new*/) const
188  {
189  return zero{};
190  }
191 
195  template <typename T1>
196  SMITH_HOST_DEVICE auto interpolate(const TimeInfo& t, const T1& field_new) const
197  {
198  return std::make_tuple(value(t, field_new), dot(t, field_new), ddot(t, field_new));
199  }
200 
201  FieldState corrected_value(const TimeInfo& t, const std::vector<FieldState>& states) const override
202  {
203  return value(t, states[0]);
204  }
205 
206  FieldState corrected_dot(const TimeInfo& /*t*/, const std::vector<FieldState>& states) const override
207  {
208  return zeroCopy(states[0]);
209  }
210 
211  FieldState corrected_ddot(const TimeInfo& /*t*/, const std::vector<FieldState>& states) const override
212  {
213  return zeroCopy(states[0]);
214  }
215 };
216 
220 
226  public:
227  static constexpr int num_states = 4;
228 
231 
233  int num_args() const override { return num_states; }
234 
236  bool requiresInitialAccelerationSolve() const override { return true; }
237 
239  template <typename T1, typename T2, typename T3, typename T4>
240  SMITH_HOST_DEVICE auto value([[maybe_unused]] const TimeInfo& t, [[maybe_unused]] const T1& field_new,
241  [[maybe_unused]] const T2& field_old, [[maybe_unused]] const T3& velo_old,
242  [[maybe_unused]] const T4& accel_old) const
243  {
244  auto regular_value = field_new + (field_old - field_old);
245  auto cycle_zero_correction = field_old - field_new;
246  if (t.isCycleZeroEvaluation()) {
247  return regular_value + cycle_zero_correction;
248  }
249  return regular_value + (cycle_zero_correction - cycle_zero_correction);
250  }
251 
253  template <typename T1, typename T2, typename T3, typename T4>
254  SMITH_HOST_DEVICE auto dot([[maybe_unused]] const TimeInfo& t, [[maybe_unused]] const T1& field_new,
255  [[maybe_unused]] const T2& field_old, [[maybe_unused]] const T3& velo_old,
256  [[maybe_unused]] const T4& accel_old) const
257  {
258  auto regular_dot = (2.0 / t.dt()) * (field_new - field_old) - velo_old;
259  auto cycle_zero_correction = velo_old - regular_dot;
260  if (t.isCycleZeroEvaluation()) {
261  return regular_dot + cycle_zero_correction;
262  }
263  return regular_dot + (cycle_zero_correction - cycle_zero_correction);
264  }
265 
267  template <typename T1, typename T2, typename T3, typename T4>
268  SMITH_HOST_DEVICE auto ddot([[maybe_unused]] const TimeInfo& t, [[maybe_unused]] const T1& field_new,
269  [[maybe_unused]] const T2& field_old, [[maybe_unused]] const T3& velo_old,
270  [[maybe_unused]] const T4& accel_old) const
271  {
272  auto dt = t.dt();
273  auto regular_ddot = (4.0 / (dt * dt)) * (field_new - field_old) - (4.0 / dt) * velo_old - accel_old;
274  auto cycle_zero_correction = accel_old - regular_ddot;
275  if (t.isCycleZeroEvaluation()) {
276  return regular_ddot + cycle_zero_correction;
277  }
278  return regular_ddot + (cycle_zero_correction - cycle_zero_correction);
279  }
280 
282  template <typename T1, typename T2, typename T3, typename T4>
283  SMITH_HOST_DEVICE auto interpolate(const TimeInfo& t, const T1& field_new, const T2& field_old, const T3& velo_old,
284  const T4& accel_old) const
285  {
286  return std::make_tuple(value(t, field_new, field_old, velo_old, accel_old),
287  dot(t, field_new, field_old, velo_old, accel_old),
288  ddot(t, field_new, field_old, velo_old, accel_old));
289  }
290 
292  FieldState corrected_value(const TimeInfo& t, const std::vector<FieldState>& states) const override
293  {
294  return value(t, states[0], states[1], states[2], states[3]);
295  }
296 
298  FieldState corrected_dot(const TimeInfo& t, const std::vector<FieldState>& states) const override
299  {
300  return dot(t, states[0], states[1], states[2], states[3]);
301  }
302 
304  FieldState corrected_ddot(const TimeInfo& t, const std::vector<FieldState>& states) const override
305  {
306  return ddot(t, states[0], states[1], states[2], states[3]);
307  }
308 };
309 
315  public:
316  static constexpr int num_states = 4;
317 
320 
322  int num_args() const override { return num_states; }
323 
325  bool requiresInitialAccelerationSolve() const override { return false; }
326 
328  template <typename T1, typename T2, typename T3, typename T4>
329  SMITH_HOST_DEVICE auto value([[maybe_unused]] const TimeInfo& t, [[maybe_unused]] const T1& field_new,
330  [[maybe_unused]] const T2& field_old, [[maybe_unused]] const T3& velo_old,
331  [[maybe_unused]] const T4& accel_old) const
332  {
333  return field_new;
334  }
335 
337  template <typename T1, typename T2, typename T3, typename T4>
338  SMITH_HOST_DEVICE auto dot([[maybe_unused]] const TimeInfo& t, [[maybe_unused]] const T1& field_new,
339  [[maybe_unused]] const T2& field_old, [[maybe_unused]] const T3& velo_old,
340  [[maybe_unused]] const T4& accel_old) const
341  {
342  return (1.0 / t.dt()) * (field_new - field_old);
343  }
344 
346  template <typename T1, typename T2, typename T3, typename T4>
347  SMITH_HOST_DEVICE auto ddot([[maybe_unused]] const TimeInfo& t, [[maybe_unused]] const T1& field_new,
348  [[maybe_unused]] const T2& field_old, [[maybe_unused]] const T3& velo_old,
349  [[maybe_unused]] const T4& accel_old) const
350  {
351  return zero{};
352  }
353 
355  template <typename T1, typename T2, typename T3, typename T4>
356  SMITH_HOST_DEVICE auto interpolate(const TimeInfo& t, const T1& field_new, const T2& field_old, const T3& velo_old,
357  const T4& accel_old) const
358  {
359  return std::make_tuple(value(t, field_new, field_old, velo_old, accel_old),
360  dot(t, field_new, field_old, velo_old, accel_old),
361  ddot(t, field_new, field_old, velo_old, accel_old));
362  }
363 
365  FieldState corrected_value(const TimeInfo& t, const std::vector<FieldState>& states) const override
366  {
367  return value(t, states[0], states[1], states[2], states[3]);
368  }
369 
371  FieldState corrected_dot(const TimeInfo& t, const std::vector<FieldState>& states) const override
372  {
373  return dot(t, states[0], states[1], states[2], states[3]);
374  }
375 
377  FieldState corrected_ddot(const TimeInfo& /*t*/, const std::vector<FieldState>& states) const override
378  {
379  return zeroCopy(states[0]);
380  }
381 };
382 
383 } // 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
encodes rules for time discretizing first order odes (involving first time derivatives)....
SMITH_HOST_DEVICE auto dot(const TimeInfo &t, const T1 &field_new, const T2 &field_old) const
evaluate time derivative discretization of the ode state as used by the integration rule
FieldState corrected_value(const TimeInfo &t, const std::vector< FieldState > &states) const override
This is an overloaded member function, provided for convenience. It differs from the above function o...
FieldState corrected_ddot(const TimeInfo &, const std::vector< FieldState > &states) const override
This is an overloaded member function, provided for convenience. It differs from the above function o...
static constexpr int num_states
number of states required by this rule (compile-time)
FieldState corrected_dot(const TimeInfo &t, const std::vector< FieldState > &states) const override
This is an overloaded member function, provided for convenience. It differs from the above function o...
SMITH_HOST_DEVICE auto value(const TimeInfo &, const T1 &field_new, const T2 &) const
evaluate value of the ode state as used by the integration rule
int num_args() const override
get the number of states required by the rule
SMITH_HOST_DEVICE auto interpolate(const TimeInfo &t, const T1 &field_new, const T2 &field_old) const
interpolate all derived quantities in one call
encodes rules for time discretizing first order odes where time derivatives are zero....
FieldState corrected_dot(const TimeInfo &, const std::vector< FieldState > &states) const override
This is an overloaded member function, provided for convenience. It differs from the above function o...
SMITH_HOST_DEVICE auto dot(const TimeInfo &, const T1 &) const
evaluate time derivative discretization of the ode state as used by the integration rule
int num_args() const override
get the number of states required by the rule
FieldState corrected_value(const TimeInfo &t, const std::vector< FieldState > &states) const override
This is an overloaded member function, provided for convenience. It differs from the above function o...
FieldState corrected_ddot(const TimeInfo &, const std::vector< FieldState > &states) const override
This is an overloaded member function, provided for convenience. It differs from the above function o...
SMITH_HOST_DEVICE auto interpolate(const TimeInfo &t, const T1 &field_new) const
interpolate all derived quantities in one call
SMITH_HOST_DEVICE auto value(const TimeInfo &, const T1 &field_new) const
evaluate value of the ode state as used by the integration rule
static constexpr int num_states
number of states required by this rule (compile-time)
encodes rules for static postprocessing fields with zero time derivatives.
FieldState corrected_dot(const TimeInfo &, const std::vector< FieldState > &states) const override
update the current value of the independent variable's first time derivative, given the predicted val...
SMITH_HOST_DEVICE auto interpolate(const TimeInfo &t, const T1 &field_new) const
Return value, first derivative, and second derivative for a static field.
SMITH_HOST_DEVICE auto ddot(const TimeInfo &, const T1 &) const
Return zero second derivative for a static field.
FieldState corrected_value(const TimeInfo &t, const std::vector< FieldState > &states) const override
update the current value of the independent variable, given the predicted value of the current indepe...
SMITH_HOST_DEVICE auto value(const TimeInfo &, const T1 &field_new) const
Return the static field value.
int num_args() const override
get the number of states required by the rule
static constexpr int num_states
number of states required by this rule (compile-time)
SMITH_HOST_DEVICE auto dot(const TimeInfo &, const T1 &) const
Return zero first derivative for a static field.
FieldState corrected_ddot(const TimeInfo &, const std::vector< FieldState > &states) const override
update the current value of the independent variable's second time derivative, given the predicted va...
Abstract time integration rule for discretizing odes in time.
virtual ~TimeIntegrationRule()
destructor
virtual FieldState corrected_ddot(const TimeInfo &t, const std::vector< FieldState > &states) const =0
update the current value of the independent variable's second time derivative, given the predicted va...
virtual FieldState corrected_value(const TimeInfo &t, const std::vector< FieldState > &states) const =0
update the current value of the independent variable, given the predicted value of the current indepe...
virtual bool requiresInitialAccelerationSolve() const
whether this rule needs a cycle-zero initial acceleration solve
virtual FieldState corrected_dot(const TimeInfo &t, const std::vector< FieldState > &states) const =0
update the current value of the independent variable's first time derivative, given the predicted val...
virtual int num_args() const =0
get the number of states required by the rule
A file defining some enums and structs that are used by the different physics modules.
Accelerator functionality.
Definition: smith.cpp:36
gretl::State< FEFieldPtr, FEDualPtr > FieldState
typedef
Definition: field_state.hpp:22
FieldState zeroCopy(const FieldState &x)
gretl-function to make a deep-copy of a FieldState and initialize it to 0.
Definition: field_state.cpp:76
encodes rules for time discretizing second order odes (involving first and second time derivatives)....
SMITH_HOST_DEVICE auto value([[maybe_unused]] const TimeInfo &t, [[maybe_unused]] const T1 &field_new, [[maybe_unused]] const T2 &field_old, [[maybe_unused]] const T3 &velo_old, [[maybe_unused]] const T4 &accel_old) const
evaluate value of the ode state as used by the integration rule
int num_args() const override
get the number of states required by the rule
SMITH_HOST_DEVICE auto interpolate(const TimeInfo &t, const T1 &field_new, const T2 &field_old, const T3 &velo_old, const T4 &accel_old) const
interpolate all derived quantities in one call
FieldState corrected_ddot(const TimeInfo &t, const std::vector< FieldState > &states) const override
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool requiresInitialAccelerationSolve() const override
implicit second-order dynamics needs the cycle-zero acceleration solve
FieldState corrected_dot(const TimeInfo &t, const std::vector< FieldState > &states) const override
This is an overloaded member function, provided for convenience. It differs from the above function o...
static constexpr int num_states
number of states required by this rule (compile-time)
SMITH_HOST_DEVICE auto dot([[maybe_unused]] const TimeInfo &t, [[maybe_unused]] const T1 &field_new, [[maybe_unused]] const T2 &field_old, [[maybe_unused]] const T3 &velo_old, [[maybe_unused]] const T4 &accel_old) const
evaluate time derivative discretization of the ode state as used by the integration rule
SMITH_HOST_DEVICE auto ddot([[maybe_unused]] const TimeInfo &t, [[maybe_unused]] const T1 &field_new, [[maybe_unused]] const T2 &field_old, [[maybe_unused]] const T3 &velo_old, [[maybe_unused]] const T4 &accel_old) const
evaluate time derivative discretization of the ode state as used by the integration rule
FieldState corrected_value(const TimeInfo &t, const std::vector< FieldState > &states) const override
This is an overloaded member function, provided for convenience. It differs from the above function o...
encodes rules for time discretizing second order odes (involving first and second time derivatives)....
SMITH_HOST_DEVICE auto ddot([[maybe_unused]] const TimeInfo &t, [[maybe_unused]] const T1 &field_new, [[maybe_unused]] const T2 &field_old, [[maybe_unused]] const T3 &velo_old, [[maybe_unused]] const T4 &accel_old) const
evaluate time derivative discretization of the ode state as used by the integration rule
FieldState corrected_value(const TimeInfo &t, const std::vector< FieldState > &states) const override
This is an overloaded member function, provided for convenience. It differs from the above function o...
FieldState corrected_ddot(const TimeInfo &, const std::vector< FieldState > &states) const override
This is an overloaded member function, provided for convenience. It differs from the above function o...
FieldState corrected_dot(const TimeInfo &t, const std::vector< FieldState > &states) const override
This is an overloaded member function, provided for convenience. It differs from the above function o...
int num_args() const override
get the number of states required by the rule
bool requiresInitialAccelerationSolve() const override
quasi-static second-order rules do not need the cycle-zero acceleration solve
SMITH_HOST_DEVICE auto dot([[maybe_unused]] const TimeInfo &t, [[maybe_unused]] const T1 &field_new, [[maybe_unused]] const T2 &field_old, [[maybe_unused]] const T3 &velo_old, [[maybe_unused]] const T4 &accel_old) const
evaluate time derivative discretization of the ode state as used by the integration rule
SMITH_HOST_DEVICE auto value([[maybe_unused]] const TimeInfo &t, [[maybe_unused]] const T1 &field_new, [[maybe_unused]] const T2 &field_old, [[maybe_unused]] const T3 &velo_old, [[maybe_unused]] const T4 &accel_old) const
evaluate value of the ode state as used by the integration rule
static constexpr int num_states
number of states required by this rule (compile-time)
SMITH_HOST_DEVICE auto interpolate(const TimeInfo &t, const T1 &field_new, const T2 &field_old, const T3 &velo_old, const T4 &accel_old) const
interpolate all derived quantities in one call
struct storing time and timestep information
Definition: common.hpp:18
double dt() const
accessor for dt
Definition: common.hpp:36
A sentinel struct for eliding no-op tensor operations.
Definition: tensor.hpp:122