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)
8 {
9 if (order < 1 || order > 6)
10 log_and_throw_error("BDF order must be 1 ≤ n ≤ 6");
11 max_steps_ = order;
12 }
13
14 void BDF::set_parameters(const json &params)
15 {
16 max_steps_ = params.at("steps");
17 if (max_steps_ < 1 || max_steps_ > 6)
18 log_and_throw_error("BDF steps must be 1 ≤ n ≤ 6");
19 }
20
21 const std::vector<double> &BDF::alphas(const int i)
22 {
23 static const std::array<std::vector<double>, 6> _alphas = {{
24 {1},
25 {4.0 / 3.0, -1.0 / 3.0},
26 {18.0 / 11.0, -9.0 / 11.0, 2.0 / 11.0},
27 {48.0 / 25.0, -36.0 / 25.0, 16.0 / 25.0, -3.0 / 25.0},
28 {300.0 / 137.0, -300.0 / 137.0, 200.0 / 137.0, -75.0 / 137.0, 12.0 / 137.0},
29 {360.0 / 147.0, -450.0 / 147.0, 400.0 / 147.0, -225.0 / 147.0, 72.0 / 147.0, -10.0 / 147.0},
30 }};
31 assert(i >= 0 && i < _alphas.size());
32 return _alphas[i];
33 }
34
35 double BDF::betas(const int i)
36 {
37 static const std::array<double, 6> _betas = {{
38 1.0,
39 2.0 / 3.0,
40 6.0 / 11.0,
41 12.0 / 25.0,
42 60.0 / 137.0,
43 60.0 / 147.0,
44 }};
45 assert(i >= 0 && i < _betas.size());
46 return _betas[i];
47 }
48
49 Eigen::VectorXd BDF::weighted_sum_x_prevs() const
50 {
51 const std::vector<double> &alpha = alphas(steps() - 1);
52
53 Eigen::VectorXd sum = Eigen::VectorXd::Zero(x_prev().size());
54 for (int i = 0; i < steps(); i++)
55 {
56 sum += alpha[i] * x_prevs_[i];
57 }
58
59 return sum;
60 }
61
62 Eigen::VectorXd BDF::weighted_sum_v_prevs() const
63 {
64 const std::vector<double> &alpha = alphas(steps() - 1);
65
66 Eigen::VectorXd sum = Eigen::VectorXd::Zero(v_prev().size());
67 for (int i = 0; i < steps(); i++)
68 {
69 sum += alpha[i] * v_prevs_[i];
70 }
71
72 return sum;
73 }
74
75 void BDF::update_quantities(const Eigen::VectorXd &x)
76 {
77 const Eigen::VectorXd v = compute_velocity(x);
78 const Eigen::VectorXd a = compute_acceleration(v);
79
80 x_prevs_.push_front(x);
81 v_prevs_.push_front(v);
82 a_prevs_.push_front(a);
83
84 if (steps() > max_steps())
85 {
86 x_prevs_.pop_back();
87 v_prevs_.pop_back();
88 a_prevs_.pop_back();
89 }
90 assert(x_prevs_.size() <= max_steps());
91 assert(x_prevs_.size() == v_prevs_.size());
92 assert(x_prevs_.size() == a_prevs_.size());
93 }
94
95 Eigen::VectorXd BDF::x_tilde() const
96 {
97 return weighted_sum_x_prevs() + betas(steps() - 1) * dt() * weighted_sum_v_prevs();
98 }
99
100 Eigen::VectorXd BDF::compute_velocity(const Eigen::VectorXd &x) const
101 {
102 return (x - weighted_sum_x_prevs()) / beta_dt();
103 }
104
105 Eigen::VectorXd BDF::compute_acceleration(const Eigen::VectorXd &v) const
106 {
107 return (v - weighted_sum_v_prevs()) / beta_dt();
108 }
109
111 {
112 const double beta = betas(steps() - 1);
113 return beta * beta * dt() * dt();
114 }
115
116 double BDF::dv_dx(const unsigned i) const
117 {
118 if (i == 0)
119 return 1 / beta_dt();
120 if (i >= steps())
121 return 0;
122 return -alphas(steps() - 1)[i] / beta_dt();
123 }
124
125 double BDF::beta_dt() const
126 {
127 return betas(steps() - 1) * dt();
128 }
129} // 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:116
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:100
void set_parameters(const json &params) override
Set the number of steps parameters from a json object.
Definition BDF.cpp:14
static double betas(const int i)
Retrieve the value of beta used for BDF with i steps.
Definition BDF.cpp:35
Eigen::VectorXd weighted_sum_v_prevs() const
Compute the weighted sum of the previous velocities.
Definition BDF.cpp:62
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
Eigen::VectorXd weighted_sum_x_prevs() const
Compute the weighted sum of the previous solutions.
Definition BDF.cpp:49
static const std::vector< double > & alphas(const int i)
Retrieve the alphas used for BDF with i steps.
Definition BDF.cpp:21
BDF(const int order=1)
Definition BDF.cpp:7
void update_quantities(const Eigen::VectorXd &x) override
Update the time integration quantities (i.e., , , and ).
Definition BDF.cpp:75
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:105
double acceleration_scaling() const override
Compute the acceleration scaling used to scale forces when integrating a second order ODE.
Definition BDF.cpp:110
double beta_dt() const
Compute .
Definition BDF.cpp:125
Eigen::VectorXd x_tilde() const override
Compute the predicted solution to be used in the inertia term .
Definition BDF.cpp:95
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:71