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) {
90 casadi_assert(mem !=
nullptr,
"Memory is null");
113 const std::vector<std::string>& name_in,
114 const std::vector<std::string>& name_out)
117 in_.resize(name_in.size());
118 for (
size_t k = 0; k < name_in.size(); ++k) {
121 }
catch (std::exception& e) {
122 casadi_error(
"Cannot process input " + name_in[k] +
": " + std::string(e.what()));
126 out_.resize(name_out.size());
127 for (
size_t k = 0; k < name_out.size(); ++k) {
130 }
catch (std::exception& e) {
131 casadi_error(
"Cannot process output " + name_out[k] +
": " + std::string(e.what()));
136 for (
auto&& i :
out_) {
190 if (option_name ==
"print_progress") {
192 }
else if (option_name ==
"step") {
193 step_ = option_value;
194 }
else if (option_name ==
"fd_method") {
197 }
else if (option_name ==
"uses_directional_derivatives") {
199 bool v = option_value;
201 "FMU does not provide support for analytic derivatives");
203 }
else if (option_name ==
"uses_adjoint_derivatives") {
205 bool v = option_value;
207 "FMU does not provide support for adjoint derivatives");
209 }
else if (option_name ==
"enable_forward_jacobian") {
211 }
else if (option_name ==
"enable_adjoint_hessian") {
212 bool v = option_value;
214 "FMU does not provide support for adjoint derivatives");
216 }
else if (option_name ==
"fd_flip") {
218 }
else if (option_name ==
"make_symmetric") {
220 }
else if (option_name ==
"hessian_coloring") {
221 bool v = option_value;
224 "Can only change Hessian coloring if both colorings are available");
242 "Names of the inputs in the scheme"}},
245 "Names of the outputs in the scheme"}},
248 "Definitions of the scheme variables"}},
251 "Auxilliary variables"}},
254 "[DEPRECATED] Renamed uses_directional_derivatives"}},
257 "Number of forward sensitivities to be calculated [1]"}},
260 "Number of adjoint sensitivities to be calculated [1]"}},
261 {
"uses_directional_derivatives",
263 "Use the analytic forward directional derivative support in the FMU"}},
264 {
"uses_adjoint_derivatives",
266 "Use the analytic adjoint derivative support in the FMU"}},
269 "Compare forward derivatives with finite differences for validation"}},
272 "Validate entries of the Hessian for self-consistency"}},
275 "[DEPRECATED] Renamed 'validate_forward'"}},
278 "Redirect results of Hessian validation to a file instead of generating a warning"}},
281 "[DEPRECATED] Renamed 'validate_hessian'"}},
284 "Ensure Hessian is symmetric"}},
287 "Step size, scaled by nominal value"}},
290 "Allow flipping the sign of the finite difference step to keep it in bounds"}},
293 "Absolute error tolerance, scaled by nominal value"}},
296 "Relative error tolerance"}},
299 "Parallelization [SERIAL|openmp|thread]"}},
302 "Print progress during Jacobian/Hessian evaluation"}},
305 "Use forward AD implementation in class (conversion option, to be removed)"}},
308 "Use Jacobian implementation in class (conversion option, to be removed)"}},
311 "Use Hessian implementation in class (conversion option, to be removed)"}},
314 "Calculate Hessian using symmetry exploiting graph coloring (star coloring)."}},
315 {
"asymmetric_hessian_coloring",
317 "Calculate Hessian using unidirectional graph coloring (star coloring). Ensures that upper "
318 "and lower triangular parts are calculated separately, which may be desirable for "
319 "diagnostics. If both symmetric coloring ('hessian_coloring' option) and asymmetric coloring "
320 "is enabled, the symmetric coloring will be used."}},
321 {
"enable_forward_jacobian",
323 "Allow Jacobian calculation using forward mode AD."}},
324 {
"enable_adjoint_jacobian",
326 "Allow Jacobian calculation using adjoint mode AD."}},
327 {
"enable_adjoint_hessian",
329 "Use finite differencing of adjoints for Hessian calculation."}}
335 for (
auto&& op : opts) {
336 if (op.first==
"enable_ad") {
337 casadi_warning(
"Option 'enable_ad' has been renamed 'uses_directional_derivatives'");
339 }
else if (op.first==
"uses_directional_derivatives") {
341 }
else if (op.first==
"nfwd") {
343 }
else if (op.first==
"nadj") {
345 }
else if (op.first==
"uses_adjoint_derivatives") {
347 }
else if (op.first==
"validate_forward") {
349 }
else if (op.first==
"validate_hessian") {
351 }
else if (op.first==
"validate_ad") {
352 casadi_warning(
"Option 'validate_ad' has been renamed 'validate_forward'");
354 }
else if (op.first==
"check_hessian") {
355 casadi_warning(
"Option 'check_hessian' has been renamed 'validate_hessian'");
357 }
else if (op.first==
"validate_ad_file") {
359 }
else if (op.first==
"make_symmetric") {
361 }
else if (op.first==
"step") {
363 }
else if (op.first==
"fd_flip") {
365 }
else if (op.first==
"abstol") {
367 }
else if (op.first==
"reltol") {
369 }
else if (op.first==
"parallelization") {
371 }
else if (op.first==
"print_progress") {
373 }
else if (op.first==
"new_forward") {
375 }
else if (op.first==
"new_jacobian") {
377 }
else if (op.first==
"new_hessian") {
379 }
else if (op.first==
"hessian_coloring") {
381 }
else if (op.first==
"asymmetric_hessian_coloring") {
383 }
else if (op.first==
"enable_forward_jacobian") {
385 }
else if (op.first==
"enable_adjoint_jacobian") {
387 }
else if (op.first==
"enable_adjoint_hessian") {
400 "FMU does not provide support for analytic derivatives");
403 "FMU does not provide support for adjoint derivatives");
409 std::ostream& valfile = *valfile_ptr;
410 valfile <<
"Output Input Value Nominal Min Max AD FD Step Offset Stencil" << std::endl;
419 if (
verbose_) casadi_message(
"Serial evaluation");
427 #ifdef CASADI_WITH_THREAD
435 +
" not enabled during compilation. Falling back to serial evaluation");
441 std::vector<size_t> in_jac(
fmu_.
n_in(), 0);
444 for (
auto&& i :
out_) {
448 const std::vector<size_t>& iind =
fmu_.
ired(i.wrt);
450 if (iind.empty())
continue;
452 bool exists = in_jac[iind.front()] > 0;
453 for (
size_t j : iind) casadi_assert((in_jac[j] > 0) == exists,
"Jacobian not a block");
456 for (
size_t j : iind) {
463 i.cbegin = in_jac[iind.front()] - 1;
464 i.cend = i.cbegin + iind.size();
468 const std::vector<size_t>& iind =
fmu_.
ired(i.ind);
470 if (iind.empty())
continue;
472 bool exists = in_jac[iind.front()] > 0;
473 for (
size_t j : iind) casadi_assert((in_jac[j] > 0) == exists,
"Hessian not a block");
476 for (
size_t j : iind) {
483 i.rbegin = in_jac[iind.front()] - 1;
484 i.rend = i.rbegin + iind.size();
495 std::fill(in_jac.begin(), in_jac.end(), 0);
497 for (
size_t k = 0; k <
out_.size(); ++k) {
501 const std::vector<size_t>& oind =
fmu_.
ored(i.
ind);
503 if (oind.empty())
continue;
505 bool exists = in_jac[oind.front()] > 0;
506 for (
size_t j : oind) casadi_assert((in_jac[j] > 0) == exists,
"Jacobian not a block");
509 for (
size_t j : oind) {
515 i.
rbegin = in_jac[oind.front()] - 1;
531 for (
auto&& i :
in_) {
534 const std::vector<size_t>& oind =
fmu_.
ored(i.ind);
536 if (oind.empty())
continue;
538 bool exists = in_jac[oind.front()] > 0;
539 for (
size_t j : oind) casadi_assert((in_jac[j] > 0) == exists,
"Jacobian not a block");
542 for (
size_t j : oind) {
572 if (
verbose_) casadi_message(
"Jacobian graph coloring via adjoint derivatives: "
604 std::vector<bool> is_nonlin(
jac_in_.size(),
false);
605 for (casadi_int k = 0; k < hess_nnz; ++k) is_nonlin[hess_row[k]] =
true;
607 std::vector<casadi_int> lin;
608 for (casadi_int c = 0; c <
jac_in_.size(); ++c) {
616 casadi_int max_hessian_colors = 0;
622 +
" -> " +
str(max_hessian_colors) +
" directions");
631 if (
verbose_) casadi_message(
"Hessian unidirectional coloring with "
642 casadi_message(
"Hessian calculation for " +
str(
nonlin_.size()) +
" variables");
665 casadi_int jac_iw, jac_w;
666 casadi_jac_work(&
jac_prob_, &jac_iw, &jac_w);
672 casadi_jac_work(&
adj_prob_, &jac_iw, &jac_w);
682 std::vector<std::string>* scheme_in,
683 std::vector<std::string>* scheme_out,
684 const std::vector<std::string>& name_in,
685 const std::vector<std::string>& name_out) {
687 if (scheme_in) scheme_in->clear();
688 if (scheme_out) scheme_out->clear();
690 for (
const std::string& n : name_in) {
693 }
catch (std::exception& e) {
694 casadi_error(
"Cannot process input " + n +
": " + std::string(e.what()));
698 for (
const std::string& n : name_out) {
701 }
catch (std::exception& e) {
702 casadi_error(
"Cannot process output " + n +
": " + std::string(e.what()));
707 std::set<std::string> s(scheme_in->begin(), scheme_in->end());
708 scheme_in->assign(s.begin(), s.end());
712 std::set<std::string> s(scheme_out->begin(), scheme_out->end());
713 scheme_out->assign(s.begin(), s.end());
718 std::vector<std::string>* name_in, std::vector<std::string>* name_out) {
724 std::string pref, rem;
733 if (name_in) name_in->push_back(rem);
735 casadi_error(
"Cannot process: " + n);
741 if (name_out) name_out->push_back(rem);
743 }
else if (pref ==
"fwd") {
747 if (name_in) name_in->push_back(rem);
748 }
else if (pref ==
"adj") {
752 if (name_out) name_out->push_back(rem);
755 casadi_error(
"No such prefix: " + pref);
761 if (name_in) name_in->push_back(n);
768 std::vector<std::string>* name_in, std::vector<std::string>* name_out) {
774 std::string pref, rem;
778 casadi_assert(
has_prefix(rem),
"Two arguments expected for Jacobian block");
782 casadi_assert(
has_prefix(rem),
"Two arguments expected for Jacobian block");
786 std::string sens = pref;
792 if (name_out) name_out->push_back(rem);
794 if (name_in) name_in->push_back(sens);
795 }
else if (pref ==
"out") {
799 if (name_in) name_in->push_back(sens);
801 if (name_in) name_out->push_back(rem);
803 casadi_error(
"No such prefix: " + pref);
809 if (name_in) name_in->push_back(pref);
811 if (name_in) name_in->push_back(rem);
815 std::string out = pref;
821 if (name_out) name_out->push_back(out);
823 if (name_out) name_out->push_back(rem);
825 casadi_error(
"No such prefix: " + pref);
831 if (name_out) name_out->push_back(pref);
833 if (name_in) name_in->push_back(rem);
836 }
else if (pref ==
"fwd") {
840 if (name_out) name_out->push_back(rem);
841 }
else if (pref ==
"adj") {
845 if (name_in) name_in->push_back(rem);
848 casadi_error(
"No such prefix: " + pref);
854 if (name_out) name_out->push_back(n);
861 switch (
in_.at(i).type) {
878 switch (
out_.at(i).type) {
900 switch (
in_.at(i).type) {
915 switch (
out_.at(i).type) {
922 casadi_warning(
"FmuFunction::get_nominal_out not implemented for OutputType::JAC");
925 casadi_warning(
"FmuFunction::get_nominal_out not implemented for OutputType::JAC_TRANS");
928 casadi_warning(
"FmuFunction::get_nominal_out not implemented for OutputType::JAC_ADJ_OUT");
931 casadi_warning(
"FmuFunction::get_nominal_out not implemented for OutputType::JAC_REG_ADJ");
934 casadi_warning(
"FmuFunction::get_nominal_out not implemented for OutputType::HESS");
945 casadi_assert(m !=
nullptr,
"Memory is null");
947 setup(mem, arg, res, iw, w);
950 bool need_jac =
false, need_fwd =
false, need_adj =
false, need_hess =
false;
951 for (
size_t k = 0; k <
out_.size(); ++k) {
953 switch (
out_[k].type) {
974 double *aseed =
nullptr, *asens =
nullptr, *jac_nz =
nullptr, *hess_nz =
nullptr;
988 for (
size_t i = 0; i <
in_.size(); ++i) {
990 const std::vector<size_t>& oind =
fmu_.
ored(
in_[i].ind);
991 for (casadi_int d = 0; d <
nadj_; ++d) {
994 for (
size_t k = 0; k < oind.size(); ++k) aseed[oind[k] + aseed_off] = arg[i][k + off];
1005 for (casadi_int task = 0; task <
max_n_tasks_; ++task) {
1028 casadi_message(
"Evaluating regular outputs, forward sens, extended Jacobian");
1046 for (
size_t k = 0; k <
out_.size(); ++k) {
1051 switch (
out_[k].type) {
1053 casadi_get_sub(r,
jac_sp_, jac_nz,
1057 casadi_get_sub(w,
jac_sp_, jac_nz,
1063 for (casadi_int d = 0; d <
nadj_; ++d) {
1064 size_t asens_off = d *
fmu_.
n_in();
1065 for (
size_t id :
fmu_.
ired(
out_[k].wrt)) *r++ = asens[
id + asens_off];
1069 casadi_get_sub(r,
hess_sp_, hess_nz,
1081 bool need_nondiff,
bool need_jac,
bool need_fwd,
bool need_adj,
bool need_hess)
const {
1086 || (!need_jac && !need_adj && !need_hess)) {
1088 flag =
eval_task(m, 0, 1, need_nondiff, need_jac, need_fwd, need_adj, need_hess);
1092 #pragma omp parallel reduction(||:flag)
1095 casadi_int task = omp_get_thread_num();
1097 casadi_int num_threads = omp_get_num_threads();
1099 casadi_int num_used_threads = std::min(num_threads, n_task);
1101 if (task < num_used_threads) {
1103 flag =
eval_task(s, task, num_used_threads, need_nondiff && task == 0,
1104 need_jac, need_fwd && task <
nfwd_, need_adj, need_hess);
1114 #ifdef CASADI_WITH_THREAD
1116 std::vector<int> flag_task(n_task);
1118 std::vector<std::thread> threads;
1119 for (casadi_int task = 0; task < n_task; ++task) {
1120 threads.emplace_back(
1121 [&, task](
int* fl) {
1123 *fl =
eval_task(s, task, n_task, need_nondiff && task == 0,
1124 need_jac, need_fwd && task <
nfwd_, need_adj, need_hess);
1125 }, &flag_task[task]);
1128 for (
auto&& th : threads) th.join();
1130 for (
int fl : flag_task) flag = flag || fl;
1142 bool need_nondiff,
bool need_jac,
bool need_fwd,
bool need_adj,
bool need_hess)
const {
1144 for (
size_t k = 0; k <
in_.size(); ++k) {
1150 for (
size_t k = 0; k <
out_.size(); ++k) {
1159 for (
size_t k = 0; k <
out_.size(); ++k) {
1168 casadi_int d_begin = (task *
nfwd_) / n_task;
1169 casadi_int d_end = ((task + 1) *
nfwd_) / n_task;
1171 for (casadi_int d = d_begin; d < d_end; ++d) {
1174 task + 1, n_task, d - d_begin + 1, d_end - d_begin);
1176 for (
size_t k = 0; k <
in_.size(); ++k) {
1182 for (
size_t k = 0; k <
out_.size(); ++k) {
1190 for (
size_t k = 0; k <
out_.size(); ++k) {
1205 for (casadi_int c = c_begin; c < c_end; ++c) {
1208 task + 1, n_task, c - c_begin + 1, c_end - c_begin);
1226 for (casadi_int d = 0; d <
nadj_; ++d) {
1228 size_t asens_off = d *
fmu_.
n_in();
1239 casadi_assert(need_jac,
"Inconsistent options");
1244 for (casadi_int c = c_begin; c < c_end; ++c) {
1247 "Seeding variable %d/%d\n", task + 1, n_task, c - c_begin + 1, c_end - c_begin);
1263 }
else if (need_adj) {
1265 casadi_int d_begin = (task *
nadj_) / n_task;
1266 casadi_int d_end = ((task + 1) *
nadj_) / n_task;
1268 for (casadi_int d = d_begin; d < d_end; ++d) {
1271 task + 1, n_task, d - d_begin + 1, d_end - d_begin);
1273 for (
size_t k = 0; k <
in_.size(); ++k) {
1279 casadi_int wrt_id = -1;
1280 for (casadi_int
id :
jac_in_) {
1286 for (casadi_int
id :
jac_in_) {
1295 casadi_int n_hc = hc.
size2();
1296 const casadi_int *hc_colind = hc.
colind(), *hc_row = hc.
row();
1300 casadi_int c_begin = (task * n_hc) / n_task;
1301 casadi_int c_end = ((task + 1) * n_hc) / n_task;
1303 std::vector<double> x, h;
1305 for (casadi_int c = c_begin; c < c_end; ++c) {
1308 task + 1, n_task, c - c_begin + 1, c_end - c_begin);
1310 casadi_int v_begin = hc_colind[c];
1311 casadi_int v_end = hc_colind[c + 1];
1312 casadi_int nv = v_end - v_begin;
1316 for (casadi_int v = 0; v < nv; ++v) {
1318 casadi_int ind1 = hc_row[v_begin + v];
1319 casadi_int
id =
jac_in_.at(ind1);
1321 x[v] = m->
ibuf_.at(
id);
1336 if (!std::isnan(h[v])) {
1337 m->
ibuf_.at(
id) += h[v];
1355 for (
size_t k = 0; k <
in_.size(); ++k) {
1361 casadi_int wrt_id = -1;
1362 for (casadi_int
id :
jac_in_) {
1368 for (casadi_int
id :
jac_in_) {
1389 for (casadi_int v = 0; v < nv; ++v) {
1391 casadi_int ind1 = hc_row[v_begin + v];
1392 casadi_int
id =
jac_in_.at(ind1);
1394 m->
ibuf_.at(
id) = x[v];
1397 for (casadi_int k = hess_colind[ind1]; k < hess_colind[ind1 + 1]; ++k) {
1400 if (std::isnan(h[v])) {
1405 casadi_int id2 =
jac_in_.at(hess_row[k]);
1424 for (casadi_int c = 0; c < n; ++c) {
1426 for (casadi_int k = colind[c]; k < colind[c + 1]; ++k) {
1428 casadi_int r = row[k];
1430 casadi_int k_tr = iw[r]++;
1437 hess_nz[k] = hess_nz[k_tr];
1440 hess_nz[k_tr] = hess_nz[k];
1449 double nz = hess_nz[k], nz_tr = hess_nz[k_tr];
1451 if (std::isnan(nz) || std::isinf(nz)) {
1452 std::stringstream ss;
1453 ss <<
"Second derivative w.r.t. " <<
fmu_.
desc_in(m, id_r) <<
" and "
1455 casadi_warning(ss.str());
1456 }
else if (std::isnan(nz_tr) || std::isinf(nz_tr)) {
1457 std::stringstream ss;
1458 ss <<
"Second derivative w.r.t. " <<
fmu_.
desc_in(m, id_c) <<
" and "
1460 casadi_warning(ss.str());
1463 double nz_max = std::fmax(std::fabs(nz), std::fabs(nz_tr));
1465 if (nz_max >
abstol_ && std::fabs(nz - nz_tr) > nz_max *
reltol_) {
1466 std::stringstream ss;
1467 ss <<
"Hessian appears nonsymmetric. Got " << nz <<
" vs. " << nz_tr
1468 <<
" for second derivative w.r.t. " <<
fmu_.
desc_in(m, id_r) <<
" and "
1469 <<
fmu_.
desc_in(m, id_c) <<
", hess_nz = " << k <<
"/" << k_tr;
1470 casadi_warning(ss.str());
1475 if (
make_symmetric_) hess_nz[k] = hess_nz[k_tr] = 0.5 * (hess_nz[k] + hess_nz[k_tr]);
1493 return s.find(
'_') < s.size();
1498 casadi_assert_dev(!s.empty());
1499 size_t pos = s.find(
'_');
1500 casadi_assert(pos < s.size(),
"Cannot process \"" + s +
"\"");
1502 std::string r = s.substr(0, pos);
1504 if (rem) *rem = s.substr(pos+1, std::string::npos);
1520 for (
auto&& e :
in_) {
1528 if (
nfwd_ > 1)
return false;
1531 if (
nadj_ > 1)
return false;
1539 for (
auto&& e :
out_) {
1555 const std::vector<std::string>& s_in,
1556 const std::vector<std::string>& s_out,
1558 const Dict& opts)
const {
1567 std::vector<std::string> s_in_mod = s_in, s_out_mod = s_out;
1568 for (std::string& s : s_in_mod) std::replace(s.begin(), s.end(),
':',
'_');
1569 for (std::string& s : s_out_mod) std::replace(s.begin(), s.end(),
':',
'_');
1575 }
catch (std::exception& e) {
1576 casadi_warning(
"FmuFunction::factory call for constructing " + name +
" from " +
name_
1577 +
" failed:\n" + std::string(e.what()) +
"\nFalling back to base class implementation");
1591 const std::vector<std::string>& onames,
const Dict& opts)
const {
1614 const std::vector<std::string>& inames,
1615 const std::vector<std::string>& onames,
1616 const Dict& opts)
const {
1624 opts1[
"nfwd"] = nfwd;
1640 const std::vector<std::string>& inames,
1641 const std::vector<std::string>& onames,
1642 const Dict& opts)
const {
1649 opts1[
"nadj"] = nadj;
1668 bool symmetric)
const {
1684 casadi_error(
"Implementation error");
1705 casadi_assert_dev(
in_.size()==
n_in_);
1707 s.
pack(
"FmuFunction::in::type",
static_cast<int>(e.type));
1708 s.
pack(
"FmuFunction::in::ind", e.ind);
1712 s.
pack(
"FmuFunction::out::type",
static_cast<int>(e.type));
1713 s.
pack(
"FmuFunction::out::ind", e.ind);
1714 s.
pack(
"FmuFunction::out::wrt", e.wrt);
1715 s.
pack(
"FmuFunction::out::rbegin", e.rbegin);
1716 s.
pack(
"FmuFunction::out::rend", e.rend);
1717 s.
pack(
"FmuFunction::out::cbegin", e.cbegin);
1718 s.
pack(
"FmuFunction::out::cend", e.cend);
1753 s.
pack(
"FmuFunction::fd",
static_cast<int>(
fd_));
1775 s.
version(
"FmuFunction", 6, 6);
1782 s.
unpack(
"FmuFunction::in::type", t);
1784 s.
unpack(
"FmuFunction::in::ind", e.ind);
1789 s.
unpack(
"FmuFunction::out::type", t);
1791 s.
unpack(
"FmuFunction::out::ind", e.ind);
1792 s.
unpack(
"FmuFunction::out::wrt", e.wrt);
1793 s.
unpack(
"FmuFunction::out::rbegin", e.rbegin);
1794 s.
unpack(
"FmuFunction::out::rend", e.rend);
1795 s.
unpack(
"FmuFunction::out::cbegin", e.cbegin);
1796 s.
unpack(
"FmuFunction::out::cend", e.cend);
1834 s.
unpack(
"FmuFunction::fd", fd);
1836 int parallelization = 0;
1837 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)