26 #include "fmu_function.hpp"
27 #include "casadi_misc.hpp"
28 #include "serializing_stream.hpp"
29 #include "dae_builder_internal.hpp"
30 #include "filesystem_impl.hpp"
41 #ifdef CASADI_WITH_THREAD
42 #ifdef CASADI_WITH_THREAD_MINGW
43 #include <mingw.thread.h>
54 "declares 'canBeInstantiatedOnlyOncePerProcess' to be true. "
55 "Regenerate your FMU with this option set to false.");
60 casadi_assert(mem !=
nullptr,
"Memory is null");
64 casadi_int n_mem = std::max(
static_cast<casadi_int
>(1),
68 for (casadi_int i = 0; i < n_mem; ++i) {
93 casadi_assert(mem !=
nullptr,
"Memory is null");
116 const std::vector<std::string>& name_in,
117 const std::vector<std::string>& name_out)
120 in_.resize(name_in.size());
121 for (
size_t k = 0; k < name_in.size(); ++k) {
124 }
catch (std::exception& e) {
125 casadi_error(
"Cannot process input " + name_in[k] +
": " + std::string(e.what()));
129 out_.resize(name_out.size());
130 for (
size_t k = 0; k < name_out.size(); ++k) {
133 }
catch (std::exception& e) {
134 casadi_error(
"Cannot process output " + name_out[k] +
": " + std::string(e.what()));
139 for (
auto&& i :
out_) {
193 if (option_name ==
"print_progress") {
195 }
else if (option_name ==
"step") {
196 step_ = option_value;
197 }
else if (option_name ==
"fd_method") {
200 }
else if (option_name ==
"uses_directional_derivatives") {
202 bool v = option_value;
204 "FMU does not provide support for analytic derivatives");
206 }
else if (option_name ==
"uses_adjoint_derivatives") {
208 bool v = option_value;
210 "FMU does not provide support for adjoint derivatives");
212 }
else if (option_name ==
"enable_forward_jacobian") {
214 }
else if (option_name ==
"enable_adjoint_hessian") {
215 bool v = option_value;
217 "FMU does not provide support for adjoint derivatives");
219 }
else if (option_name ==
"fd_flip") {
221 }
else if (option_name ==
"make_symmetric") {
223 }
else if (option_name ==
"hessian_coloring") {
224 bool v = option_value;
227 "Can only change Hessian coloring if both colorings are available");
245 "Names of the inputs in the scheme"}},
248 "Names of the outputs in the scheme"}},
251 "Definitions of the scheme variables"}},
254 "Auxilliary variables"}},
257 "[DEPRECATED] Renamed uses_directional_derivatives"}},
260 "Number of forward sensitivities to be calculated [1]"}},
263 "Number of adjoint sensitivities to be calculated [1]"}},
264 {
"uses_directional_derivatives",
266 "Use the analytic forward directional derivative support in the FMU"}},
267 {
"uses_adjoint_derivatives",
269 "Use the analytic adjoint derivative support in the FMU"}},
272 "Compare forward derivatives with finite differences for validation"}},
275 "Validate entries of the Hessian for self-consistency"}},
278 "[DEPRECATED] Renamed 'validate_forward'"}},
281 "Redirect results of Hessian validation to a file instead of generating a warning"}},
284 "[DEPRECATED] Renamed 'validate_hessian'"}},
287 "Ensure Hessian is symmetric"}},
290 "Step size, scaled by nominal value"}},
293 "Allow flipping the sign of the finite difference step to keep it in bounds"}},
296 "Absolute error tolerance, scaled by nominal value"}},
299 "Relative error tolerance"}},
302 "Parallelization [SERIAL|openmp|thread]"}},
305 "Print progress during Jacobian/Hessian evaluation"}},
308 "Use forward AD implementation in class (conversion option, to be removed)"}},
311 "Use Jacobian implementation in class (conversion option, to be removed)"}},
314 "Use Hessian implementation in class (conversion option, to be removed)"}},
317 "Calculate Hessian using symmetry exploiting graph coloring (star coloring)."}},
318 {
"asymmetric_hessian_coloring",
320 "Calculate Hessian using unidirectional graph coloring (star coloring). Ensures that upper "
321 "and lower triangular parts are calculated separately, which may be desirable for "
322 "diagnostics. If both symmetric coloring ('hessian_coloring' option) and asymmetric coloring "
323 "is enabled, the symmetric coloring will be used."}},
324 {
"enable_forward_jacobian",
326 "Allow Jacobian calculation using forward mode AD."}},
327 {
"enable_adjoint_jacobian",
329 "Allow Jacobian calculation using adjoint mode AD."}},
330 {
"enable_adjoint_hessian",
332 "Use finite differencing of adjoints for Hessian calculation."}}
338 for (
auto&& op : opts) {
339 if (op.first==
"enable_ad") {
340 casadi_warning(
"Option 'enable_ad' has been renamed 'uses_directional_derivatives'");
342 }
else if (op.first==
"uses_directional_derivatives") {
344 }
else if (op.first==
"nfwd") {
346 }
else if (op.first==
"nadj") {
348 }
else if (op.first==
"uses_adjoint_derivatives") {
350 }
else if (op.first==
"validate_forward") {
352 }
else if (op.first==
"validate_hessian") {
354 }
else if (op.first==
"validate_ad") {
355 casadi_warning(
"Option 'validate_ad' has been renamed 'validate_forward'");
357 }
else if (op.first==
"check_hessian") {
358 casadi_warning(
"Option 'check_hessian' has been renamed 'validate_hessian'");
360 }
else if (op.first==
"validate_ad_file") {
362 }
else if (op.first==
"make_symmetric") {
364 }
else if (op.first==
"step") {
366 }
else if (op.first==
"fd_flip") {
368 }
else if (op.first==
"abstol") {
370 }
else if (op.first==
"reltol") {
372 }
else if (op.first==
"parallelization") {
374 }
else if (op.first==
"print_progress") {
376 }
else if (op.first==
"new_forward") {
378 }
else if (op.first==
"new_jacobian") {
380 }
else if (op.first==
"new_hessian") {
382 }
else if (op.first==
"hessian_coloring") {
384 }
else if (op.first==
"asymmetric_hessian_coloring") {
386 }
else if (op.first==
"enable_forward_jacobian") {
388 }
else if (op.first==
"enable_adjoint_jacobian") {
390 }
else if (op.first==
"enable_adjoint_hessian") {
403 "FMU does not provide support for analytic derivatives");
406 "FMU does not provide support for adjoint derivatives");
412 std::ostream& valfile = *valfile_ptr;
413 valfile <<
"Output Input Value Nominal Min Max AD FD Step Offset Stencil" << std::endl;
422 if (
verbose_) casadi_message(
"Serial evaluation");
430 #ifdef CASADI_WITH_THREAD
438 +
" not enabled during compilation. Falling back to serial evaluation");
444 std::vector<size_t> in_jac(
fmu_.
n_in(), 0);
447 for (
auto&& i :
out_) {
451 const std::vector<size_t>& iind =
fmu_.
ired(i.wrt);
453 if (iind.empty())
continue;
455 bool exists = in_jac[iind.front()] > 0;
456 for (
size_t j : iind) casadi_assert((in_jac[j] > 0) == exists,
"Jacobian not a block");
459 for (
size_t j : iind) {
466 i.cbegin = in_jac[iind.front()] - 1;
467 i.cend = i.cbegin + iind.size();
471 const std::vector<size_t>& iind =
fmu_.
ired(i.ind);
473 if (iind.empty())
continue;
475 bool exists = in_jac[iind.front()] > 0;
476 for (
size_t j : iind) casadi_assert((in_jac[j] > 0) == exists,
"Hessian not a block");
479 for (
size_t j : iind) {
486 i.rbegin = in_jac[iind.front()] - 1;
487 i.rend = i.rbegin + iind.size();
498 std::fill(in_jac.begin(), in_jac.end(), 0);
500 for (
size_t k = 0; k <
out_.size(); ++k) {
504 const std::vector<size_t>& oind =
fmu_.
ored(i.
ind);
506 if (oind.empty())
continue;
508 bool exists = in_jac[oind.front()] > 0;
509 for (
size_t j : oind) casadi_assert((in_jac[j] > 0) == exists,
"Jacobian not a block");
512 for (
size_t j : oind) {
518 i.
rbegin = in_jac[oind.front()] - 1;
534 for (
auto&& i :
in_) {
537 const std::vector<size_t>& oind =
fmu_.
ored(i.ind);
539 if (oind.empty())
continue;
541 bool exists = in_jac[oind.front()] > 0;
542 for (
size_t j : oind) casadi_assert((in_jac[j] > 0) == exists,
"Jacobian not a block");
545 for (
size_t j : oind) {
575 if (
verbose_) casadi_message(
"Jacobian graph coloring via adjoint derivatives: "
607 std::vector<bool> is_nonlin(
jac_in_.size(),
false);
608 for (casadi_int k = 0; k < hess_nnz; ++k) is_nonlin[hess_row[k]] =
true;
610 std::vector<casadi_int> lin;
611 for (casadi_int c = 0; c <
jac_in_.size(); ++c) {
619 casadi_int max_hessian_colors = 0;
625 +
" -> " +
str(max_hessian_colors) +
" directions");
634 if (
verbose_) casadi_message(
"Hessian unidirectional coloring with "
645 casadi_message(
"Hessian calculation for " +
str(
nonlin_.size()) +
" variables");
668 casadi_int jac_iw, jac_w;
669 casadi_jac_work(&
jac_prob_, &jac_iw, &jac_w);
675 casadi_jac_work(&
adj_prob_, &jac_iw, &jac_w);
685 std::vector<std::string>* scheme_in,
686 std::vector<std::string>* scheme_out,
687 const std::vector<std::string>& name_in,
688 const std::vector<std::string>& name_out) {
690 if (scheme_in) scheme_in->clear();
691 if (scheme_out) scheme_out->clear();
693 for (
const std::string& n : name_in) {
696 }
catch (std::exception& e) {
697 casadi_error(
"Cannot process input " + n +
": " + std::string(e.what()));
701 for (
const std::string& n : name_out) {
704 }
catch (std::exception& e) {
705 casadi_error(
"Cannot process output " + n +
": " + std::string(e.what()));
710 std::set<std::string> s(scheme_in->begin(), scheme_in->end());
711 scheme_in->assign(s.begin(), s.end());
715 std::set<std::string> s(scheme_out->begin(), scheme_out->end());
716 scheme_out->assign(s.begin(), s.end());
721 std::vector<std::string>* name_in, std::vector<std::string>* name_out) {
727 std::string pref, rem;
736 if (name_in) name_in->push_back(rem);
738 casadi_error(
"Cannot process: " + n);
744 if (name_out) name_out->push_back(rem);
746 }
else if (pref ==
"fwd") {
750 if (name_in) name_in->push_back(rem);
751 }
else if (pref ==
"adj") {
755 if (name_out) name_out->push_back(rem);
758 casadi_error(
"No such prefix: " + pref);
764 if (name_in) name_in->push_back(n);
771 std::vector<std::string>* name_in, std::vector<std::string>* name_out) {
777 std::string pref, rem;
781 casadi_assert(
has_prefix(rem),
"Two arguments expected for Jacobian block");
785 casadi_assert(
has_prefix(rem),
"Two arguments expected for Jacobian block");
789 std::string sens = pref;
795 if (name_out) name_out->push_back(rem);
797 if (name_in) name_in->push_back(sens);
798 }
else if (pref ==
"out") {
802 if (name_in) name_in->push_back(sens);
804 if (name_in) name_out->push_back(rem);
806 casadi_error(
"No such prefix: " + pref);
812 if (name_in) name_in->push_back(pref);
814 if (name_in) name_in->push_back(rem);
818 std::string out = pref;
824 if (name_out) name_out->push_back(out);
826 if (name_out) name_out->push_back(rem);
828 casadi_error(
"No such prefix: " + pref);
834 if (name_out) name_out->push_back(pref);
836 if (name_in) name_in->push_back(rem);
839 }
else if (pref ==
"fwd") {
843 if (name_out) name_out->push_back(rem);
844 }
else if (pref ==
"adj") {
848 if (name_in) name_in->push_back(rem);
851 casadi_error(
"No such prefix: " + pref);
857 if (name_out) name_out->push_back(n);
864 switch (
in_.at(i).type) {
881 switch (
out_.at(i).type) {
903 switch (
in_.at(i).type) {
918 switch (
out_.at(i).type) {
925 casadi_warning(
"FmuFunction::get_nominal_out not implemented for OutputType::JAC");
928 casadi_warning(
"FmuFunction::get_nominal_out not implemented for OutputType::JAC_TRANS");
931 casadi_warning(
"FmuFunction::get_nominal_out not implemented for OutputType::JAC_ADJ_OUT");
934 casadi_warning(
"FmuFunction::get_nominal_out not implemented for OutputType::JAC_REG_ADJ");
937 casadi_warning(
"FmuFunction::get_nominal_out not implemented for OutputType::HESS");
948 casadi_assert(m !=
nullptr,
"Memory is null");
949 setup(mem, arg, res, iw, w);
954 bool need_jac =
false, need_fwd =
false, need_adj =
false, need_hess =
false;
955 for (
size_t k = 0; k <
out_.size(); ++k) {
957 switch (
out_[k].type) {
978 double *aseed =
nullptr, *asens =
nullptr, *jac_nz =
nullptr, *hess_nz =
nullptr;
992 for (
size_t i = 0; i <
in_.size(); ++i) {
994 const std::vector<size_t>& oind =
fmu_.
ored(
in_[i].ind);
995 for (casadi_int d = 0; d <
nadj_; ++d) {
998 for (
size_t k = 0; k < oind.size(); ++k) aseed[oind[k] + aseed_off] = arg[i][k + off];
1009 for (casadi_int task = 0; task <
max_n_tasks_; ++task) {
1032 casadi_message(
"Evaluating regular outputs, forward sens, extended Jacobian");
1050 for (
size_t k = 0; k <
out_.size(); ++k) {
1055 switch (
out_[k].type) {
1057 casadi_get_sub(r,
jac_sp_, jac_nz,
1061 casadi_get_sub(w,
jac_sp_, jac_nz,
1067 for (casadi_int d = 0; d <
nadj_; ++d) {
1068 size_t asens_off = d *
fmu_.
n_in();
1069 for (
size_t id :
fmu_.
ired(
out_[k].wrt)) *r++ = asens[
id + asens_off];
1073 casadi_get_sub(r,
hess_sp_, hess_nz,
1085 bool need_nondiff,
bool need_jac,
bool need_fwd,
bool need_adj,
bool need_hess)
const {
1090 || (!need_jac && !need_adj && !need_hess)) {
1092 flag =
eval_task(m, 0, 1, need_nondiff, need_jac, need_fwd, need_adj, need_hess);
1096 #pragma omp parallel reduction(||:flag)
1099 casadi_int task = omp_get_thread_num();
1101 casadi_int num_threads = omp_get_num_threads();
1103 casadi_int num_used_threads = std::min(num_threads, n_task);
1105 if (task < num_used_threads) {
1107 flag =
eval_task(s, task, num_used_threads, need_nondiff && task == 0,
1108 need_jac, need_fwd && task <
nfwd_, need_adj, need_hess);
1118 #ifdef CASADI_WITH_THREAD
1120 std::vector<int> flag_task(n_task);
1122 std::vector<std::thread> threads;
1123 for (casadi_int task = 0; task < n_task; ++task) {
1124 threads.emplace_back(
1125 [&, task](
int* fl) {
1127 *fl =
eval_task(s, task, n_task, need_nondiff && task == 0,
1128 need_jac, need_fwd && task <
nfwd_, need_adj, need_hess);
1129 }, &flag_task[task]);
1132 for (
auto&& th : threads) th.join();
1134 for (
int fl : flag_task) flag = flag || fl;
1146 bool need_nondiff,
bool need_jac,
bool need_fwd,
bool need_adj,
bool need_hess)
const {
1148 for (
size_t k = 0; k <
in_.size(); ++k) {
1154 for (
size_t k = 0; k <
out_.size(); ++k) {
1163 for (
size_t k = 0; k <
out_.size(); ++k) {
1172 casadi_int d_begin = (task *
nfwd_) / n_task;
1173 casadi_int d_end = ((task + 1) *
nfwd_) / n_task;
1175 for (casadi_int d = d_begin; d < d_end; ++d) {
1178 task + 1, n_task, d - d_begin + 1, d_end - d_begin);
1180 for (
size_t k = 0; k <
in_.size(); ++k) {
1186 for (
size_t k = 0; k <
out_.size(); ++k) {
1194 for (
size_t k = 0; k <
out_.size(); ++k) {
1209 for (casadi_int c = c_begin; c < c_end; ++c) {
1212 task + 1, n_task, c - c_begin + 1, c_end - c_begin);
1230 for (casadi_int d = 0; d <
nadj_; ++d) {
1232 size_t asens_off = d *
fmu_.
n_in();
1243 casadi_assert(need_jac,
"Inconsistent options");
1248 for (casadi_int c = c_begin; c < c_end; ++c) {
1251 "Seeding variable %d/%d\n", task + 1, n_task, c - c_begin + 1, c_end - c_begin);
1267 }
else if (need_adj) {
1269 casadi_int d_begin = (task *
nadj_) / n_task;
1270 casadi_int d_end = ((task + 1) *
nadj_) / n_task;
1272 for (casadi_int d = d_begin; d < d_end; ++d) {
1275 task + 1, n_task, d - d_begin + 1, d_end - d_begin);
1277 for (
size_t k = 0; k <
in_.size(); ++k) {
1283 casadi_int wrt_id = -1;
1284 for (casadi_int
id :
jac_in_) {
1290 for (casadi_int
id :
jac_in_) {
1299 casadi_int n_hc = hc.
size2();
1300 const casadi_int *hc_colind = hc.
colind(), *hc_row = hc.
row();
1304 casadi_int c_begin = (task * n_hc) / n_task;
1305 casadi_int c_end = ((task + 1) * n_hc) / n_task;
1307 std::vector<double> x, h;
1309 for (casadi_int c = c_begin; c < c_end; ++c) {
1312 task + 1, n_task, c - c_begin + 1, c_end - c_begin);
1314 casadi_int v_begin = hc_colind[c];
1315 casadi_int v_end = hc_colind[c + 1];
1316 casadi_int nv = v_end - v_begin;
1320 for (casadi_int v = 0; v < nv; ++v) {
1322 casadi_int ind1 = hc_row[v_begin + v];
1323 casadi_int
id =
jac_in_.at(ind1);
1325 x[v] = m->
ibuf_.at(
id);
1340 if (!std::isnan(h[v])) {
1341 m->
ibuf_.at(
id) += h[v];
1359 for (
size_t k = 0; k <
in_.size(); ++k) {
1365 casadi_int wrt_id = -1;
1366 for (casadi_int
id :
jac_in_) {
1372 for (casadi_int
id :
jac_in_) {
1393 for (casadi_int v = 0; v < nv; ++v) {
1395 casadi_int ind1 = hc_row[v_begin + v];
1396 casadi_int
id =
jac_in_.at(ind1);
1398 m->
ibuf_.at(
id) = x[v];
1401 for (casadi_int k = hess_colind[ind1]; k < hess_colind[ind1 + 1]; ++k) {
1404 if (std::isnan(h[v])) {
1409 casadi_int id2 =
jac_in_.at(hess_row[k]);
1428 for (casadi_int c = 0; c < n; ++c) {
1430 for (casadi_int k = colind[c]; k < colind[c + 1]; ++k) {
1432 casadi_int r = row[k];
1434 casadi_int k_tr = iw[r]++;
1441 hess_nz[k] = hess_nz[k_tr];
1444 hess_nz[k_tr] = hess_nz[k];
1453 double nz = hess_nz[k], nz_tr = hess_nz[k_tr];
1455 if (std::isnan(nz) || std::isinf(nz)) {
1456 std::stringstream ss;
1457 ss <<
"Second derivative w.r.t. " <<
fmu_.
desc_in(m, id_r) <<
" and "
1459 casadi_warning(ss.str());
1460 }
else if (std::isnan(nz_tr) || std::isinf(nz_tr)) {
1461 std::stringstream ss;
1462 ss <<
"Second derivative w.r.t. " <<
fmu_.
desc_in(m, id_c) <<
" and "
1464 casadi_warning(ss.str());
1467 double nz_max = std::fmax(std::fabs(nz), std::fabs(nz_tr));
1469 if (nz_max >
abstol_ && std::fabs(nz - nz_tr) > nz_max *
reltol_) {
1470 std::stringstream ss;
1471 ss <<
"Hessian appears nonsymmetric. Got " << nz <<
" vs. " << nz_tr
1472 <<
" for second derivative w.r.t. " <<
fmu_.
desc_in(m, id_r) <<
" and "
1473 <<
fmu_.
desc_in(m, id_c) <<
", hess_nz = " << k <<
"/" << k_tr;
1474 casadi_warning(ss.str());
1479 if (
make_symmetric_) hess_nz[k] = hess_nz[k_tr] = 0.5 * (hess_nz[k] + hess_nz[k_tr]);
1497 return s.find(
'_') < s.size();
1502 casadi_assert_dev(!s.empty());
1503 size_t pos = s.find(
'_');
1504 casadi_assert(pos < s.size(),
"Cannot process \"" + s +
"\"");
1506 std::string r = s.substr(0, pos);
1508 if (rem) *rem = s.substr(pos+1, std::string::npos);
1524 for (
auto&& e :
in_) {
1532 if (
nfwd_ > 1)
return false;
1535 if (
nadj_ > 1)
return false;
1543 for (
auto&& e :
out_) {
1559 const std::vector<std::string>& s_in,
1560 const std::vector<std::string>& s_out,
1562 const Dict& opts)
const {
1571 std::vector<std::string> s_in_mod = s_in, s_out_mod = s_out;
1572 for (std::string& s : s_in_mod) std::replace(s.begin(), s.end(),
':',
'_');
1573 for (std::string& s : s_out_mod) std::replace(s.begin(), s.end(),
':',
'_');
1579 }
catch (std::exception& e) {
1580 casadi_warning(
"FmuFunction::factory call for constructing " + name +
" from " +
name_
1581 +
" failed:\n" + std::string(e.what()) +
"\nFalling back to base class implementation");
1595 const std::vector<std::string>& onames,
const Dict& opts)
const {
1618 const std::vector<std::string>& inames,
1619 const std::vector<std::string>& onames,
1620 const Dict& opts)
const {
1628 opts1[
"nfwd"] = nfwd;
1644 const std::vector<std::string>& inames,
1645 const std::vector<std::string>& onames,
1646 const Dict& opts)
const {
1653 opts1[
"nadj"] = nadj;
1672 bool symmetric)
const {
1688 casadi_error(
"Implementation error");
1709 casadi_assert_dev(
in_.size()==
n_in_);
1711 s.
pack(
"FmuFunction::in::type",
static_cast<int>(e.type));
1712 s.
pack(
"FmuFunction::in::ind", e.ind);
1716 s.
pack(
"FmuFunction::out::type",
static_cast<int>(e.type));
1717 s.
pack(
"FmuFunction::out::ind", e.ind);
1718 s.
pack(
"FmuFunction::out::wrt", e.wrt);
1719 s.
pack(
"FmuFunction::out::rbegin", e.rbegin);
1720 s.
pack(
"FmuFunction::out::rend", e.rend);
1721 s.
pack(
"FmuFunction::out::cbegin", e.cbegin);
1722 s.
pack(
"FmuFunction::out::cend", e.cend);
1757 s.
pack(
"FmuFunction::fd",
static_cast<int>(
fd_));
1779 s.
version(
"FmuFunction", 6, 6);
1786 s.
unpack(
"FmuFunction::in::type", t);
1788 s.
unpack(
"FmuFunction::in::ind", e.ind);
1793 s.
unpack(
"FmuFunction::out::type", t);
1795 s.
unpack(
"FmuFunction::out::ind", e.ind);
1796 s.
unpack(
"FmuFunction::out::wrt", e.wrt);
1797 s.
unpack(
"FmuFunction::out::rbegin", e.rbegin);
1798 s.
unpack(
"FmuFunction::out::rend", e.rend);
1799 s.
unpack(
"FmuFunction::out::cbegin", e.cbegin);
1800 s.
unpack(
"FmuFunction::out::cend", e.cend);
1838 s.
unpack(
"FmuFunction::fd", fd);
1840 int parallelization = 0;
1841 s.
unpack(
"FmuFunction::parallelization", parallelization);
Helper class for Serialization.
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
void version(const std::string &name, int v)
static std::unique_ptr< std::ostream > ofstream_ptr(const std::string &path, std::ios_base::openmode mode=std::ios_base::out)
bool has_jacobian() const override
Full Jacobian.
Sparsity hess_uni_colors_
Function get_forward(casadi_int nfwd, const std::string &name, const std::vector< std::string > &inames, const std::vector< std::string > &onames, const Dict &opts) const override
Return function that calculates forward derivatives.
std::vector< InputStruct > in_
casadi_jac_prob< double > jac_prob_
casadi_jac_prob< double > adj_prob_
~FmuFunction() override
Destructor.
Function get_jacobian(const std::string &name, const std::vector< std::string > &inames, const std::vector< std::string > &onames, const Dict &opts) const override
Full Jacobian.
std::vector< casadi_int > sp_trans_map_
Function factory(const std::string &name, const std::vector< std::string > &s_in, const std::vector< std::string > &s_out, const Function::AuxOut &aux, const Dict &opts) const override
Function get_reverse(casadi_int nadj, const std::string &name, const std::vector< std::string > &inames, const std::vector< std::string > &onames, const Dict &opts) const override
Reverse mode AD.
int eval(const double **arg, double **res, casadi_int *iw, double *w, void *mem) const override
Evaluate numerically.
void init(const Dict &opts) override
Initialize.
Sparsity get_jac_sparsity(casadi_int oind, casadi_int iind, bool symmetric) const override
Return sparsity of Jacobian of an output respect to an input.
void finalize_hessian(FmuMemory *m, double *hess_nz, casadi_int *iw) const
bool has_forward(casadi_int nfwd) const override
Return function that calculates forward derivatives.
std::vector< casadi_int > nonlin_
Dict get_stats(void *mem) const override
Get all statistics.
Parallelization parallelization_
casadi_int nfwd_
Number of sensitivities.
std::string validate_ad_file_
void check_mem_count(casadi_int n) const override
Check for validatity of memory object count.
bool enable_adjoint_hessian_
bool has_reverse(casadi_int nadj) const override
Reverse mode AD.
std::vector< Sparsity > sp_trans_
static void identify_io(std::vector< std::string > *scheme_in, std::vector< std::string > *scheme_out, const std::vector< std::string > &name_in, const std::vector< std::string > &name_out)
bool has_jac_sparsity(casadi_int oind, casadi_int iind) const override
Return sparsity of Jacobian of an output respect to an input.
bool enable_adjoint_jacobian_
bool asymmetric_hessian_coloring_
Sparsity get_sparsity_in(casadi_int i) override
Retreive sparsities.
std::vector< casadi_int > which_hess_color_
int eval_task(FmuMemory *m, casadi_int task, casadi_int n_task, bool need_nondiff, bool need_jac, bool need_fwd, bool need_adj, bool need_hess) const
static const Options options_
Options.
bool uses_directional_derivatives_
Sparsity get_sparsity_out(casadi_int i) override
Retreive sparsities.
std::vector< OutputStruct > out_
std::vector< double > get_nominal_in(casadi_int i) const override
Retreive nominal values.
casadi_int max_jac_tasks_
casadi_int max_hess_tasks_
FmuFunction(const std::string &name, const Fmu &fmu, const std::vector< std::string > &name_in, const std::vector< std::string > &name_out)
Constructor.
std::vector< size_t > jac_in_
void free_mem(void *mem) const override
Free memory block.
int eval_all(FmuMemory *m, casadi_int n_task, bool need_nondiff, bool need_jac, bool need_fwd, bool need_adj, bool need_hess) const
void change_option(const std::string &option_name, const GenericType &option_value) override
Change option after object creation for debugging.
bool enable_forward_jacobian_
int init_mem(void *mem) const override
Initalize memory block.
std::vector< double > get_nominal_out(casadi_int i) const override
Retreive nominal values.
std::vector< size_t > jac_out_
std::vector< double > jac_nom_in_
bool uses_adjoint_derivatives_
void * alloc_mem() const override
Create memory block.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
size_t index_out(const std::string &n) const
size_t index_in(const std::string &n) const
void set(FmuMemory *m, size_t ind, const double *value) const
void get_fwd(FmuMemory *m, casadi_int nsens, const casadi_int *id, double *v) const
const std::vector< size_t > & ored(size_t ind) const
int eval_adj(FmuMemory *m) const
void get_stats(FmuMemory *m, Dict *stats, const std::vector< std::string > &name_in, const InputStruct *in) const
Get stats.
Sparsity hess_sparsity(const std::vector< size_t > &r, const std::vector< size_t > &c) const
bool can_be_instantiated_only_once_per_process() const
Does the FMU declare restrictions on instantiation?
std::vector< double > all_nominal_out(size_t ind) const
bool provides_adjoint_derivatives() const
Does the FMU provide support for adjoint directional derivatives.
Sparsity jac_sparsity(const std::vector< size_t > &osub, const std::vector< size_t > &isub) const
int eval_fwd(FmuMemory *m, bool independent_seeds) const
double nominal_in(size_t ind) const
FmuMemory * alloc_mem(const FmuFunction &f) const
Create memory block.
void get_adj(FmuMemory *m, casadi_int nsens, const casadi_int *id, double *v) const
double max_in(size_t ind) const
void set_fwd(FmuMemory *m, casadi_int nseed, const casadi_int *id, const double *v) const
size_t n_out() const
Get the number of scheme outputs.
const std::string & instance_name() const
Name of the FMU.
std::vector< double > all_nominal_in(size_t ind) const
double min_in(size_t ind) const
void free_mem(void *mem) const
Free memory block.
FmuInternal * get() const
void set_adj(FmuMemory *m, casadi_int nseed, const casadi_int *id, const double *v) const
int init_mem(FmuMemory *m) const
Initalize memory block.
bool provides_directional_derivatives() const
Does the FMU provide support for forward directional derivatives.
int eval(FmuMemory *m) const
const std::vector< size_t > & ired(size_t ind) const
void request_adj(FmuMemory *m, casadi_int nsens, const casadi_int *id, const casadi_int *wrt_id) const
size_t n_in() const
Get the number of scheme inputs.
void free_instance(void *instance) const
void request(FmuMemory *m, size_t ind) const
void request_fwd(FmuMemory *m, casadi_int nsens, const casadi_int *id, const casadi_int *wrt_id) const
std::string desc_in(FmuMemory *m, size_t id, bool more=true) const
Internal class for Function.
casadi_int size1_in(casadi_int ind) const
Input/output dimensions.
void alloc_iw(size_t sz_iw, bool persistent=false)
Ensure required length of iw field.
Dict get_stats(void *mem) const override
Get all statistics.
void init(const Dict &opts) override
Initialize.
virtual bool has_forward(casadi_int nfwd) const
Return function that calculates forward derivatives.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
virtual Function factory(const std::string &name, const std::vector< std::string > &s_in, const std::vector< std::string > &s_out, const Function::AuxOut &aux, const Dict &opts) const
virtual std::vector< double > get_nominal_out(casadi_int ind) const
size_t n_in_
Number of inputs and outputs.
casadi_int size1_out(casadi_int ind) const
Input/output dimensions.
casadi_int nnz_in() const
Number of input/output nonzeros.
static const Options options_
Options.
virtual std::vector< double > get_nominal_in(casadi_int ind) const
const Sparsity & sparsity_out(casadi_int ind) const
Input/output sparsity.
void alloc_w(size_t sz_w, bool persistent=false)
Ensure required length of w field.
casadi_int nnz_out() const
Number of input/output nonzeros.
void setup(void *mem, const double **arg, double **res, casadi_int *iw, double *w) const
Set the (persistent and temporary) work vectors.
void change_option(const std::string &option_name, const GenericType &option_value) override
Change option after object creation for debugging.
std::vector< std::string > name_out_
virtual Function get_forward(casadi_int nfwd, const std::string &name, const std::vector< std::string > &inames, const std::vector< std::string > &onames, const Dict &opts) const
Return function that calculates forward derivatives.
std::vector< std::string > name_in_
Input and output scheme.
std::map< std::string, std::vector< std::string > > AuxOut
bool is_null() const
Is a null pointer?
Generic data type, can hold different types such as bool, casadi_int, std::string etc.
std::string to_string() const
Convert to a type.
void construct(const Dict &opts)
Construct.
virtual int init_mem(void *mem) const
Initalize memory block.
void print(const char *fmt,...) const
C-style formatted printing during evaluation.
bool verbose_
Verbose printout.
void clear_mem()
Clear all memory (called from destructor)
Helper class for Serialization.
void version(const std::string &name, int v)
void pack(const Sparsity &e)
Serializes an object to the output stream.
std::string class_name() const
Get class name.
std::vector< casadi_int > erase(const std::vector< casadi_int > &rr, const std::vector< casadi_int > &cc, bool ind1=false)
Erase rows and/or columns of a matrix.
casadi_int size1() const
Get the number of rows.
static Sparsity dense(casadi_int nrow, casadi_int ncol=1)
Create a dense rectangular sparsity pattern *.
Sparsity T() const
Transpose the matrix.
Sparsity star_coloring_new(std::vector< casadi_int > &which_color, const Dict &opts=Dict()) const
Perform a star coloring of a symmetric matrix:
casadi_int nnz() const
Get the number of (structural) non-zeros.
casadi_int size2() const
Get the number of columns.
const casadi_int * row() const
Get a reference to row-vector,.
Sparsity uni_coloring(const Sparsity &AT=Sparsity(), casadi_int cutoff=std::numeric_limits< casadi_int >::max()) const
Perform a unidirectional coloring: A greedy distance-2 coloring algorithm.
const casadi_int * colind() const
Get a reference to the colindex of all column element (see class description)
std::vector< casadi_int > range(casadi_int start, casadi_int stop, casadi_int step, casadi_int len)
Range function.
bool has_prefix(const std::string &s)
void casadi_copy(const T1 *x, casadi_int n, T1 *y)
COPY: y <-x.
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
Parallelization
Type of parallelization.
std::string to_string(TypeFmi2 v)
const double nan
Not a number.
T * get_ptr(std::vector< T > &v)
Get a pointer to the data contained in the vector.
void casadi_trans(const T1 *x, const casadi_int *sp_x, T1 *y, const casadi_int *sp_y, casadi_int *tmp)
TRANS: y <- trans(x) , w work vector (length >= rows x)
std::string pop_prefix(const std::string &s, std::string *rem)
std::vector< size_t > wrt_
casadi_jac_data< double > adj_data
std::vector< bool > omarked_
std::vector< double > ibuf_
casadi_jac_data< double > jac_data
std::vector< FmuMemory * > slaves
std::vector< bool > imarked_
Options metadata for a class.
static OutputStruct parse(const std::string &n, const Fmu *fmu, std::vector< std::string > *name_in=nullptr, std::vector< std::string > *name_out=nullptr)