PolyFEM
Loading...
Searching...
No Matches
ImplicitTimeIntegrator.cpp
Go to the documentation of this file.
2
6
10
11#include <fstream>
12
13namespace polyfem
14{
15 using namespace io;
16 namespace time_integrator
17 {
19 const Eigen::MatrixXd &x_prevs,
20 const Eigen::MatrixXd &v_prevs,
21 const Eigen::MatrixXd &a_prevs,
22 double dt)
23 {
24 assert(x_prevs.cols() > 0 && x_prevs.cols() <= max_steps());
25 assert(x_prevs.cols() == v_prevs.cols());
26 assert(x_prevs.cols() == a_prevs.cols());
27
28 x_prevs_.clear();
29 v_prevs_.clear();
30 a_prevs_.clear();
31
32 const int n = std::min(int(x_prevs.cols()), max_steps());
33 for (int i = 0; i < n; i++)
34 {
35 x_prevs_.push_back(x_prevs.col(i));
36 v_prevs_.push_back(v_prevs.col(i));
37 a_prevs_.push_back(a_prevs.col(i));
38 }
39
40 assert(dt > 0);
41 dt_ = dt;
42 }
43
44 void ImplicitTimeIntegrator::save_state(const std::string &state_path) const
45 {
46 assert(!state_path.empty());
47
48 const int ndof = x_prev().size();
49 const int prev_steps = x_prevs().size();
50
51 Eigen::MatrixXd tmp(ndof, prev_steps);
52
53 for (int i = 0; i < prev_steps; ++i)
54 tmp.col(i) = x_prevs()[i];
55 write_matrix(state_path, "u", tmp, /*replace=*/true);
56
57 for (int i = 0; i < prev_steps; ++i)
58 tmp.col(i) = v_prevs()[i];
59 write_matrix(state_path, "v", tmp, /*replace=*/false);
60
61 for (int i = 0; i < prev_steps; ++i)
62 tmp.col(i) = a_prevs()[i];
63 write_matrix(state_path, "a", tmp, /*replace=*/false);
64 }
65
66 std::shared_ptr<ImplicitTimeIntegrator> ImplicitTimeIntegrator::construct_time_integrator(
67 const json &params,
68 const DynamicOrder dynamic_order)
69 {
70 const std::string type = params.is_object() ? params["type"] : params;
71
72 std::shared_ptr<ImplicitTimeIntegrator> integrator;
73 if (type == "implict_euler" || type == "ImplicitEuler")
74 {
75 integrator = std::make_shared<ImplicitEuler>(dynamic_order);
76 }
77 else if (type == "implict_newmark" || type == "ImplicitNewmark")
78 {
79 integrator = std::make_shared<ImplicitNewmark>(dynamic_order);
80 }
81 else if (utils::StringUtils::startswith(type, "BDF"))
82 {
83 integrator = std::make_shared<BDF>(type == "BDF" ? 1 : std::stoi(type.substr(3)), dynamic_order);
84 }
85 else
86 {
87 logger().error("Unknown time integrator ({})", type);
88 throw std::runtime_error(fmt::format("Unknown time integrator ({})", type));
89 }
90
91 if (params.is_object())
92 integrator->set_parameters(params);
93
94 return integrator;
95 }
96
98 const json &params,
99 const DynamicOrder dynamic_order)
100 {
101 const std::string type = params.is_object() ? params["type"] : params;
102 if (type != "implict_euler" && type != "ImplicitEuler"
103 && !utils::StringUtils::startswith(type, "BDF"))
104 {
106 "BDF-specific transient formulations require ImplicitEuler or BDF, got {}.",
107 type);
108 }
109
110 auto integrator = std::make_shared<BDF>(
111 utils::StringUtils::startswith(type, "BDF") && type != "BDF"
112 ? std::stoi(type.substr(3))
113 : 1,
114 dynamic_order);
115 if (params.is_object() && params.contains("steps"))
116 integrator->set_parameters(params);
117 return integrator;
118 }
119
121 {
122 static const std::vector<std::string> names = {
123 std::string("ImplicitEuler"),
124 std::string("ImplicitNewmark"),
125 std::string("BDF"),
126 };
127 return names;
128 }
129 } // namespace time_integrator
130} // namespace polyfem
const std::deque< Eigen::VectorXd > & v_prevs() const
Get the (relevant) history of 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 std::deque< Eigen::VectorXd > & a_prevs() const
Get the (relevant) history of previous acceleration value.
static std::shared_ptr< ImplicitTimeIntegrator > construct_time_integrator(const json &params, DynamicOrder dynamic_order=DynamicOrder::Second)
Factory method for constructing an implicit time integrator.
virtual int max_steps() const
Get the maximum number of steps to use for integration.
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.
static std::shared_ptr< BDF > construct_bdf_integrator(const json &params, DynamicOrder dynamic_order=DynamicOrder::Second)
Construct a BDF integrator for algorithms using BDF-specific operations.
virtual void init(const Eigen::MatrixXd &x_prevs, const Eigen::MatrixXd &v_prevs, const Eigen::MatrixXd &a_prevs, double dt)
Initialize the time integrator with the previous values for , , and .
const std::deque< Eigen::VectorXd > & x_prevs() const
Get the (relevant) history of previous solution value.
std::deque< Eigen::VectorXd > v_prevs_
Store the necessary previous values of the velocity for single or multi-step integration.
static const std::vector< std::string > & get_time_integrator_names()
Get a vector of the names of possible ImplicitTimeIntegrators.
virtual void save_state(const std::string &state_path) const
Save the values of , , and .
bool write_matrix(const std::string &path, const Mat &mat)
Writes a matrix to a file. Determines the file format based on the path's extension.
Definition MatrixIO.cpp:42
bool startswith(const std::string &str, const std::string &prefix)
spdlog::logger & logger()
Retrieves the current logger.
Definition Logger.cpp:44
nlohmann::json json
Definition Common.hpp:9
void log_and_throw_error(const std::string &msg)
Definition Logger.cpp:73