14 namespace time_integrator
17 const Eigen::MatrixXd &x_prevs,
18 const Eigen::MatrixXd &v_prevs,
19 const Eigen::MatrixXd &a_prevs,
31 for (
int i = 0; i < n; i++)
46 const int ndof =
x_prevs_.front().size();
48 Eigen::MatrixXd
x(ndof, history), v(ndof, history), a(ndof, history);
49 for (
int i = 0; i < history; ++i)
61 writer.
write_long(group +
"/history_length", history);
67 const std::string &group,
68 const double expected_dt,
69 const std::function<
void(Eigen::MatrixXd &)> &transform)
71 for (
const std::string &key : {
"x",
"v",
"a",
"dynamic_order",
"history_length",
"dt"})
72 if (!reader.
exists(group +
"/" + key))
74 const long order = reader.
read_long(group +
"/dynamic_order");
77 const long history = reader.
read_long(group +
"/history_length");
79 log_and_throw_error(
"Checkpoint history length {} is incompatible with {}.", history, group);
80 const double stored_dt = reader.
read_double(group +
"/dt");
81 if (std::abs(stored_dt - expected_dt) > 1e-12 * std::max({1.0, std::abs(stored_dt), std::abs(expected_dt)}))
82 log_and_throw_error(
"Checkpoint dt {} does not match configured dt {}.", stored_dt, expected_dt);
84 Eigen::MatrixXd v = reader.
read_matrix(group +
"/v");
85 Eigen::MatrixXd a = reader.
read_matrix(group +
"/a");
86 if (
x.rows() == 0 ||
x.cols() != history || v.rows() !=
x.rows() || a.rows() !=
x.rows()
87 || v.cols() != history || a.cols() != history)
90 if (expected_rows >= 0 &&
x.rows() != expected_rows)
92 "Checkpoint integrator {} has {} rows; expected {}.",
93 group,
x.rows(), expected_rows);
100 init(
x, v, a, stored_dt);
107 const std::string type = params.is_object() ? params[
"type"] : params;
109 std::shared_ptr<ImplicitTimeIntegrator> integrator;
110 if (type ==
"implict_euler" || type ==
"ImplicitEuler")
114 else if (type ==
"implict_newmark" || type ==
"ImplicitNewmark")
116 integrator = std::make_shared<ImplicitNewmark>(
dynamic_order);
120 integrator = std::make_shared<BDF>(type ==
"BDF" ? 1 : std::stoi(type.substr(3)),
dynamic_order);
124 logger().error(
"Unknown time integrator ({})", type);
125 throw std::runtime_error(fmt::format(
"Unknown time integrator ({})", type));
128 if (params.is_object())
129 integrator->set_parameters(params);
138 const std::string type = params.is_object() ? params[
"type"] : params;
139 if (type !=
"implict_euler" && type !=
"ImplicitEuler"
143 "BDF-specific transient formulations require ImplicitEuler or BDF, got {}.",
147 auto integrator = std::make_shared<BDF>(
149 ? std::stoi(type.substr(3))
152 if (params.is_object() && params.contains(
"steps"))
153 integrator->set_parameters(params);
159 static const std::vector<std::string> names = {
160 std::string(
"ImplicitEuler"),
161 std::string(
"ImplicitNewmark"),
long read_long(const std::string &path) const
double read_double(const std::string &path) const
Eigen::MatrixXd read_matrix(const std::string &path) const
bool exists(const std::string &path) const
void write_matrix(const std::string &path, const Eigen::MatrixXd &value)
void write_double(const std::string &path, double value)
void write_long(const std::string &path, long value)
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 std::deque< Eigen::VectorXd > & a_prevs() const
Get the (relevant) history of previous acceleration value.
DynamicOrder dynamic_order() const
static std::shared_ptr< ImplicitTimeIntegrator > construct_time_integrator(const json ¶ms, DynamicOrder dynamic_order=DynamicOrder::Second)
Factory method for constructing an implicit time integrator.
void serialize_checkpoint(io::CheckpointWriter &writer, const std::string &group) const
virtual int max_steps() const
Get the maximum number of steps to use for integration.
const double & dt() const
Access the time step size.
void deserialize_checkpoint(const io::CheckpointReader &reader, const std::string &group, double expected_dt, const std::function< void(Eigen::MatrixXd &)> &transform={})
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 ¶ms, DynamicOrder dynamic_order=DynamicOrder::Second)
Construct a BDF integrator for algorithms using BDF-specific operations.
const DynamicOrder dynamic_order_
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.
double dt_
Time step size.
bool startswith(const std::string &str, const std::string &prefix)
spdlog::logger & logger()
Retrieves the current logger.
void log_and_throw_error(const std::string &msg)