26 #include "rosenbrock.hpp"
27 #include "rosenbrock_tableau.hpp"
32 int CASADI_INTEGRATOR_ROSENBROCK_EXPORT
35 plugin->name =
"rosenbrock";
37 plugin->version = CASADI_VERSION;
60 "Tolerance on the scaled Newton step when making the algebraic states "
61 "consistent [1e-3]"}},
64 "Maximum number of Newton iterations for consistent algebraic states [20]"}}
77 for (
auto&& op : opts) {
78 if (op.first ==
"init_tol") {
79 init_tol_ = op.second;
80 }
else if (op.first ==
"init_max_iter") {
81 init_max_iter_ = op.second;
86 set_iteration_matrix();
90 set_rosenbrock_prob();
100 void Rosenbrock::set_iteration_matrix() {
106 const casadi_int blk[4] = {IVP_ODE_X, IVP_ALG_X, IVP_ODE_Z, IVP_ALG_Z};
107 for (casadi_int k = 0; k < 4; ++k) {
108 std::vector<casadi_int> r =
sp_jac_[blk[k]].get_row(), c =
sp_jac_[blk[k]].get_col();
109 casadi_int r_off = blk[k] == IVP_ALG_X || blk[k] == IVP_ALG_Z ?
nx1_ : 0;
110 casadi_int c_off = blk[k] == IVP_ODE_Z || blk[k] == IVP_ALG_Z ?
nx1_ : 0;
111 for (
size_t i = 0; i < r.size(); ++i) {
112 iter_map_.push_back(sp_iter_.
get_nz(r[i] + r_off, c[i] + c_off));
115 for (casadi_int i = 0; i <
nx1_; ++i) iter_map_.push_back(sp_iter_.
get_nz(i, i));
117 sp_iter_.
qr_sparse(sp_iter_v_, sp_iter_r_, iter_prinv_, iter_pc_);
118 if (
nz1_ > 0)
sp_jac_[IVP_ALG_Z].qr_sparse(sp_alg_v_, sp_alg_r_, alg_prinv_, alg_pc_);
121 void Rosenbrock::set_coefficients() {
123 using namespace rosenbrock_tableau;
126 std::vector<long double> Gi(s * s, 0);
127 for (casadi_int j = 0; j < s; ++j) {
128 Gi[j * s + j] = 1 /
gamma;
129 for (casadi_int i = j + 1; i < s; ++i) {
131 for (casadi_int k = j; k < i; ++k) acc += gamma_ij[i][k] * Gi[k * s + j];
132 Gi[i * s + j] = -acc /
gamma;
139 gamma_sum_.assign(s, 0);
142 for (casadi_int i = 0; i < s; ++i) {
143 long double alpha_i = 0, gamma_i =
gamma;
144 for (casadi_int j = 0; j < i; ++j) {
145 alpha_i +=
alpha[i][j];
148 for (casadi_int k = j; k < i; ++k) aij += alpha[i][k] * Gi[k * s + j];
149 a_[i * s + j] =
static_cast<double>(aij);
150 c_[i * s + j] =
static_cast<double>(-Gi[i * s + j]);
152 alpha_[i] =
static_cast<double>(alpha_i);
153 gamma_sum_[i] =
static_cast<double>(gamma_i);
154 long double mi = 0, mhi = 0;
155 for (casadi_int k = i; k < s; ++k) {
156 mi +=
b[k] * Gi[k * s + i];
157 mhi +=
bhat[k] * Gi[k * s + i];
159 m_[i] =
static_cast<double>(mi);
160 m_err_[i] =
static_cast<double>(mi - mhi);
166 for (casadi_int q = 0; q <
n_dense; ++q) {
167 for (casadi_int i = 0; i < s; ++i) {
169 for (casadi_int k = i; k < s; ++k) mi += b_dense[q][k] * Gi[k * s + i];
170 m_dense_[q * s + i] =
static_cast<double>(mi);
175 void Rosenbrock::set_rosenbrock_prob() {
187 pr_.
sp_alg_v =
nz1_ > 0 ?
static_cast<const casadi_int*
>(sp_alg_v_) :
nullptr;
188 pr_.
sp_alg_r =
nz1_ > 0 ?
static_cast<const casadi_int*
>(sp_alg_r_) :
nullptr;
193 casadi_rosenbrock_setup(&pr_);
198 casadi_rosenbrock_setup(&pr_nom_);
203 casadi_int*& iw,
double*& w)
const {
207 casadi_rosenbrock_set_work(&m->r, &arg, &res, &iw, &w);
209 m->r_nom.prob = &pr_nom_;
210 casadi_rosenbrock_set_work(&m->r_nom, &arg, &res, &iw, &w);
211 m->r.nom = &m->r_nom;
217 return casadi_rosenbrock(&m->d, &m->r);
222 codegen_rosenbrock_prob(g,
"pe",
"p");
223 g <<
"e.prob = &pe;\n";
224 g <<
"casadi_rosenbrock_set_work(&e, &arg, &res, &iw, &w);\n";
226 static_cast<const Rosenbrock*
>(
root())->codegen_rosenbrock_prob(g,
"pen",
"pn");
227 g <<
"en.prob = &pen;\n";
228 g <<
"casadi_rosenbrock_set_work(&en, &arg, &res, &iw, &w);\n";
229 g <<
"e.nom = &en;\n";
233 void Rosenbrock::codegen_rosenbrock_prob(
CodeGenerator& g,
const std::string& pe,
234 const std::string& p)
const {
236 auto set = [&](
const std::string& field,
const std::string& value) ->
void {
237 g << pe <<
"." << field <<
" = " << value <<
";\n";
242 set(
"gamma_sum", g.
constant(gamma_sum_));
243 set(
"sp_iter", g.
sparsity(sp_iter_));
244 set(
"iter_map", g.
constant(iter_map_));
245 set(
"sp_iter_v", g.
sparsity(sp_iter_v_));
246 set(
"sp_iter_r", g.
sparsity(sp_iter_r_));
247 set(
"iter_prinv", g.
constant(iter_prinv_));
248 set(
"iter_pc", g.
constant(iter_pc_));
249 set(
"sp_alg_v",
nz1_ > 0 ? g.
sparsity(sp_alg_v_) :
"0");
250 set(
"sp_alg_r",
nz1_ > 0 ? g.
sparsity(sp_alg_r_) :
"0");
251 set(
"alg_prinv",
nz1_ > 0 ? g.
constant(alg_prinv_) :
"0");
255 g <<
"casadi_rosenbrock_setup(&" << pe <<
");\n";
260 s.
unpack(
"Rosenbrock::init_tol", init_tol_);
261 s.
unpack(
"Rosenbrock::init_max_iter", init_max_iter_);
262 set_iteration_matrix();
266 set_rosenbrock_prob();
272 s.
pack(
"Rosenbrock::init_tol", init_tol_);
273 s.
pack(
"Rosenbrock::init_max_iter", init_max_iter_);
Helper class for C code generation.
std::string constant(const std::vector< casadi_int > &v)
Represent an array constant; adding it when new.
std::string sparsity(const Sparsity &sp, bool canonical=true)
void add_auxiliary(Auxiliary f, const std::vector< std::string > &inst={"casadi_real"})
Add a built-in auxiliary function.
Helper class for Serialization.
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
void version(const std::string &name, int v)
size_t sz_res() const
Get required length of res field.
size_t sz_w() const
Get required length of w field.
void alloc_w(size_t sz_w, bool persistent=false)
Ensure required length of w field.
size_t sz_arg() const
Get required length of arg field.
size_t sz_iw() const
Get required length of iw field.
static void registerPlugin(const Plugin &plugin, bool needs_lock=true)
Register an integrator in the factory.
void clear_mem()
Clear all memory (called from destructor)
'rosenbrock' plugin for Integrator
int kernel(RuntimeIntegratorMemory *m) const override
Call the kernel of the method: returns 1 while a task is requested.
static const std::string meta_doc
A documentation string.
static Integrator * creator(const std::string &name, const Function &dae, double t0, const std::vector< double > &tout)
Create a new integrator.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
~Rosenbrock() override
Destructor.
Rosenbrock(const std::string &name, const Function &dae, double t0, const std::vector< double > &tout)
Constructor.
void init(const Dict &opts) override
Initialize.
void codegen_method(CodeGenerator &g) const override
Generate code for the problem and data of the method, variables pe and e.
void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const override
Set the (persistent) work vectors.
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize into MX.
static const Options options_
Options.
Base class of one-step integrators driven by a reverse communication kernel.
void set_ivp_prob()
Shared problem structure, from the method coefficients.
std::vector< double > m_dense_
std::vector< double > alpha_
std::vector< Sparsity > sp_jac_
void set_nominal_prob()
Problem of the nominal integration whose steps are replayed, if any.
casadi_ivp_prob< double > p_nom_
const RuntimeIntegrator * root() const
Integrator at the start of the chain of derivatives.
void init(const Dict &opts) override
Initialize: functions of the kernel tasks.
casadi_ivp_prob< double > p_
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const override
Set the (persistent) work vectors.
std::vector< double > m_err_
void alloc_ivp_work()
Work vectors of the shared kernel data.
static const Options options_
Options.
Helper class for Serialization.
void version(const std::string &name, int v)
void pack(const Sparsity &e)
Serializes an object to the output stream.
casadi_int get_nz(casadi_int rr, casadi_int cc) const
Nonzero index of entry (rr, cc), or -1 if it is a structural zero.
static Sparsity diag(casadi_int nrow)
Create a diagonal sparsity pattern.
void qr_sparse(Sparsity &V, Sparsity &R, std::vector< casadi_int > &prinv, std::vector< casadi_int > &pc, bool amd=true) const
Symbolic QR factorization.
const long double alpha[8][8]
const long double bhat[8]
const long double gamma_ij[8][8]
const casadi_int n_stages
const casadi_int order_embedded
void CASADI_INTEGRATOR_ROSENBROCK_EXPORT casadi_load_integrator_rosenbrock()
int CASADI_INTEGRATOR_ROSENBROCK_EXPORT casadi_register_integrator_rosenbrock(Integrator::Plugin *plugin)
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
T * get_ptr(std::vector< T > &v)
Get a pointer to the data contained in the vector.
Options metadata for a class.
const casadi_int * sp_alg_r
const casadi_int * sp_iter_v
const casadi_int * iter_pc
const casadi_int * sp_iter
const casadi_ivp_prob< T1 > * ivp
const casadi_int * alg_pc
const casadi_int * iter_prinv
const casadi_int * sp_iter_r
const casadi_int * alg_prinv
const casadi_int * iter_map
const casadi_int * sp_alg_v