PolyFEM
Loading...
Searching...
No Matches
BDF.cpp
Go to the documentation of this file.
1#include "BDF.hpp"
2
4
6{
7 BDF::BDF(const int order, const DynamicOrder dynamic_order)
8 : ImplicitTimeIntegrator(dynamic_order)
9 {
10 if (order < 1 || order > 6)
11 log_and_throw_error("BDF order must be 1 ≤ n ≤ 6");
12 max_steps_ = order;
13 }
14
15 void BDF::set_parameters(const json &params)
16 {
17 max_steps_ = params.at("steps");
18 if (max_steps_ < 1 || max_steps_ > 6)
19 log_and_throw_error("BDF steps must be 1 ≤ n ≤ 6");
20 }
21
22 const std::vector<double> &BDF::alphas(const int i)
23 {
24 static const std::array<std::vector<double>, 6> _alphas = {{
25 {1},
26 {4.0 / 3.0, -1.0 / 3.0},
27 {18.0 / 11.0, -9.0 / 11.0, 2.0 / 11.0},
28 {48.0 / 25.0, -36.0 / 25.0, 16.0 / 25.0, -3.0 / 25.0},
29 {300.0 / 137.0, -300.0 / 137.0, 200.0 / 137.0, -75.0 / 137.0, 12.0 / 137.0},
30 {360.0 / 147.0, -450.0 / 147.0, 400.0 / 147.0, -225.0 / 147.0, 72.0 / 147.0, -10.0 / 147.0},
31 }};
32 assert(i >= 0 && i < _alphas.size());
33 return _alphas[i];
34 }
35
36 double BDF::betas(const int i)
37 {
38 static const std::array<double, 6> _betas = {{
39 1.0,
40 2.0 / 3.0,
41 6.0 / 11.0,
42 12.0 / 25.0,
43 60.0 / 137.0,
44 60.0 / 147.0,
45 }};
46 assert(i >= 0 && i < _betas.size());
47 return _betas[i];
48 }
49
50 Eigen::VectorXd BDF::weighted_sum_x_prevs() const
51 {
52 const std::vector<double> &alpha = alphas(steps() - 1);
53
54 Eigen::VectorXd sum = Eigen::VectorXd::Zero(x_prev().size());
55 for (int i = 0; i < steps(); i++)
56 {
57 sum += alpha[i] * x_prevs_[i];
58 }
59
60 return sum;
61 }
62
63 Eigen::VectorXd BDF::weighted_sum_v_prevs() const
64 {
65 const std::vector<double> &alpha = alphas(steps() - 1);
66
67 Eigen::VectorXd sum = Eigen::VectorXd::Zero(v_prev().size());
68 for (int i = 0; i < steps(); i++)
69 {
70 sum += alpha[i] * v_prevs_[i];
71 }
72
73 return sum;
74 }
75
76 void BDF::update_quantities(const Eigen::VectorXd &x)
77 {
78 const Eigen::VectorXd v = compute_velocity(x);
79 const Eigen::VectorXd a = compute_acceleration(v);
80
81 x_prevs_.push_front(x);
82 v_prevs_.push_front(v);
83 a_prevs_.push_front(a);
84
85 if (steps() > max_steps())
86 {
87 x_prevs_.pop_back();
88 v_prevs_.pop_back();
89 a_prevs_.pop_back();
90 }
91 assert(x_prevs_.size() <= max_steps());
92 assert(x_prevs_.size() == v_prevs_.size());
93 assert(x_prevs_.size() == a_prevs_.size());
94 }
95
96 Eigen::VectorXd BDF::x_tilde() const
97 {
99 return weighted_sum_x_prevs();
100
101 return weighted_sum_x_prevs() + betas(steps() - 1) * dt() * weighted_sum_v_prevs();
102 }
103
104 Eigen::VectorXd BDF::compute_velocity(const Eigen::VectorXd &x) const
105 {
106 return (x - weighted_sum_x_prevs()) / beta_dt();
107 }
108
109 Eigen::VectorXd BDF::compute_acceleration(const Eigen::VectorXd &v) const
110 {
112 return Eigen::VectorXd::Zero(v.size());
113
114 return (v - weighted_sum_v_prevs()) / beta_dt();
115 }
116
118 {
120 return beta_dt();
121
122 const double beta = betas(steps() - 1);
123 return beta * beta * dt() * dt();
124 }
125
126 double BDF::dv_dx(const unsigned i) const
127 {
128 if (i == 0)
129 return 1 / beta_dt();
130 if (i >= steps())
131 return 0;
132 return -alphas(steps() - 1)[i] / beta_dt();
133 }
134
135 double BDF::beta_dt() const
136 {
137 return betas(steps() - 1) * dt();
138 }
139} // namespace polyfem::time_integrator
int x
double dv_dx(const unsigned prev_ti=0) const override
Compute the derivative of the velocity with respect to the solution.
Definition BDF.cpp:126
Eigen::VectorXd compute_velocity(const Eigen::VectorXd &x) const override
Compute the current velocity given the current solution and using the stored previous solution(s).
Definition BDF.cpp:104
void set_parameters(const json &params) override
Set the number of steps parameters from a json object.
Definition BDF.cpp:15
static double betas(const int i)
Retrieve the value of beta used for BDF with i steps.
Definition BDF.cpp:36
Eigen::VectorXd weighted_sum_v_prevs() const
Compute the weighted sum of the previous velocities.
Definition BDF.cpp:63
int max_steps_
The maximum number of steps to use for integration.
Definition BDF.hpp:98
int max_steps() const override
Get the maximum number of steps to use for integration.
Definition BDF.hpp:95
BDF(const int order=1, const DynamicOrder dynamic_order=DynamicOrder::Second)
Definition BDF.cpp:7
Eigen::VectorXd weighted_sum_x_prevs() const
Compute the weighted sum of the previous solutions.
Definition BDF.cpp:50
static const std::vector< double > & alphas(const int i)
Retrieve the alphas used for BDF with i steps.
Definition BDF.cpp:22
void update_quantities(const Eigen::VectorXd &x) override
Update the time integration quantities (i.e., , , and ).
Definition BDF.cpp:76
Eigen::VectorXd compute_acceleration(const Eigen::VectorXd &v) const override
Compute the current acceleration given the current velocity and using the stored previous velocity(s)...
Definition BDF.cpp:109
double acceleration_scaling() const override
Compute the acceleration scaling used to scale forces when integrating a second order ODE.
Definition BDF.cpp:117
double beta_dt() const
Compute .
Definition BDF.cpp:135
Eigen::VectorXd x_tilde() const override
Compute the predicted solution to be used in the inertia term .
Definition BDF.cpp:96
Implicit time integrator of a second order ODE (equivently a system of coupled first order ODEs).
const Eigen::VectorXd & v_prev() const
Get the most recent previous velocity value.
std::deque< Eigen::VectorXd > x_prevs_
Store the necessary previous values of the solution for single or multi-step integration.
const Eigen::VectorXd & x_prev() const
Get the most recent previous solution value.
const double & dt() const
Access the time step size.
std::deque< Eigen::VectorXd > a_prevs_
Store the necessary previous values of the acceleration for single or multi-step integration.
int steps() const
Get the current number of steps to use for integration.
std::deque< Eigen::VectorXd > v_prevs_
Store the necessary previous values of the velocity for single or multi-step integration.
nlohmann::json json
Definition Common.hpp:9
void log_and_throw_error(const std::string &msg)
Definition Logger.cpp:73