17 namespace time_integrator
20 const Eigen::MatrixXd &x_prevs,
21 const Eigen::MatrixXd &v_prevs,
22 const Eigen::MatrixXd &a_prevs,
34 for (
int i = 0; i < n; i++)
47 const int ndof =
x_prev().size();
48 const int history =
x_prevs().size();
49 Eigen::MatrixXd values(ndof, history);
50 for (
int i = 0; i < history; ++i)
53 for (
int i = 0; i < history; ++i)
56 for (
int i = 0; i < history; ++i)
65 const int ndof =
x_prevs_.front().size();
67 Eigen::MatrixXd
x(ndof, history), v(ndof, history), a(ndof, history);
68 for (
int i = 0; i < history; ++i)
80 writer.
write_long(group +
"/history_length", history);
86 const std::string &group,
87 const double expected_dt,
88 const std::function<
void(Eigen::MatrixXd &)> &transform)
90 for (
const std::string &key : {
"x",
"v",
"a",
"dynamic_order",
"history_length",
"dt"})
91 if (!reader.
exists(group +
"/" + key))
93 const long order = reader.
read_long(group +
"/dynamic_order");
96 const long history = reader.
read_long(group +
"/history_length");
98 log_and_throw_error(
"Checkpoint history length {} is incompatible with {}.", history, group);
99 const double stored_dt = reader.
read_double(group +
"/dt");
100 if (std::abs(stored_dt - expected_dt) > 1e-12 * std::max({1.0, std::abs(stored_dt), std::abs(expected_dt)}))
101 log_and_throw_error(
"Checkpoint dt {} does not match configured dt {}.", stored_dt, expected_dt);
103 Eigen::MatrixXd v = reader.
read_matrix(group +
"/v");
104 Eigen::MatrixXd a = reader.
read_matrix(group +
"/a");
105 if (
x.rows() == 0 ||
x.cols() != history || v.rows() !=
x.rows() || a.rows() !=
x.rows()
106 || v.cols() != history || a.cols() != history)
109 if (expected_rows >= 0 &&
x.rows() != expected_rows)
111 "Checkpoint integrator {} has {} rows; expected {}.",
112 group,
x.rows(), expected_rows);
119 init(
x, v, a, stored_dt);
126 const std::string type = params.is_object() ? params[
"type"] : params;
128 std::shared_ptr<ImplicitTimeIntegrator> integrator;
129 if (type ==
"implict_euler" || type ==
"ImplicitEuler")
133 else if (type ==
"implict_newmark" || type ==
"ImplicitNewmark")
135 integrator = std::make_shared<ImplicitNewmark>(
dynamic_order);
139 integrator = std::make_shared<BDF>(type ==
"BDF" ? 1 : std::stoi(type.substr(3)),
dynamic_order);
143 logger().error(
"Unknown time integrator ({})", type);
144 throw std::runtime_error(fmt::format(
"Unknown time integrator ({})", type));
147 if (params.is_object())
148 integrator->set_parameters(params);
157 const std::string type = params.is_object() ? params[
"type"] : params;
158 if (type !=
"implict_euler" && type !=
"ImplicitEuler"
162 "BDF-specific transient formulations require ImplicitEuler or BDF, got {}.",
166 auto integrator = std::make_shared<BDF>(
168 ? std::stoi(type.substr(3))
171 if (params.is_object() && params.contains(
"steps"))
172 integrator->set_parameters(params);
178 static const std::vector<std::string> names = {
179 std::string(
"ImplicitEuler"),
180 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 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.
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.
virtual void save_state(const std::string &state_path) const
Legacy State persistence. Non-legacy code uses serialize_checkpoint().
double dt_
Time step size.
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.
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)