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 != 0,
"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) {
88 casadi_assert(mem !=
nullptr,
"Memory is null");
111 const std::vector<std::string>& name_in,
112 const std::vector<std::string>& name_out)
115 in_.resize(name_in.size());
116 for (
size_t k = 0; k < name_in.size(); ++k) {
119 }
catch (std::exception& e) {
120 casadi_error(
"Cannot process input " + name_in[k] +
": " + std::string(e.what()));
124 out_.resize(name_out.size());
125 for (
size_t k = 0; k < name_out.size(); ++k) {
128 }
catch (std::exception& e) {
129 casadi_error(
"Cannot process output " + name_out[k] +
": " + std::string(e.what()));
134 for (
auto&& i :
out_) {
183 if (option_name ==
"print_progress") {
200 "Names of the inputs in the scheme"}},
203 "Names of the outputs in the scheme"}},
206 "Definitions of the scheme variables"}},
209 "Auxilliary variables"}},
212 "[DEPRECATED] Renamed uses_directional_derivatives"}},
215 "Number of forward sensitivities to be calculated [1]"}},
218 "Number of adjoint sensitivities to be calculated [1]"}},
219 {
"uses_directional_derivatives",
221 "Use the analytic forward directional derivative support in the FMU"}},
224 "Compare forward derivatives with finite differences for validation"}},
227 "Validate entries of the Hessian for self-consistency"}},
230 "[DEPRECATED] Renamed 'validate_forward'"}},
233 "Redirect results of Hessian validation to a file instead of generating a warning"}},
236 "[DEPRECATED] Renamed 'validate_hessian'"}},
239 "Ensure Hessian is symmetric"}},
242 "Step size, scaled by nominal value"}},
245 "Absolute error tolerance, scaled by nominal value"}},
248 "Relative error tolerance"}},
251 "Parallelization [SERIAL|openmp|thread]"}},
254 "Print progress during Jacobian/Hessian evaluation"}},
257 "Use forward AD implementation in class (conversion option, to be removed)"}},
260 "Use Jacobian implementation in class (conversion option, to be removed)"}},
263 "Use Hessian implementation in class (conversion option, to be removed)"}},
266 "Enable the use of graph coloring (star coloring) for Hessian calculation. "
267 "Note that disabling the coloring can improve symmetry check diagnostics."}}
273 for (
auto&& op : opts) {
274 if (op.first==
"enable_ad") {
275 casadi_warning(
"Option 'enable_ad' has been renamed 'uses_directional_derivatives'");
277 }
else if (op.first==
"uses_directional_derivatives") {
279 }
else if (op.first==
"nfwd") {
281 }
else if (op.first==
"nadj") {
283 }
else if (op.first==
"uses_adjoint_derivatives") {
285 }
else if (op.first==
"validate_forward") {
287 }
else if (op.first==
"validate_hessian") {
289 }
else if (op.first==
"validate_ad") {
290 casadi_warning(
"Option 'validate_ad' has been renamed 'validate_forward'");
292 }
else if (op.first==
"check_hessian") {
293 casadi_warning(
"Option 'check_hessian' has been renamed 'validate_hessian'");
295 }
else if (op.first==
"validate_ad_file") {
297 }
else if (op.first==
"make_symmetric") {
299 }
else if (op.first==
"step") {
301 }
else if (op.first==
"abstol") {
303 }
else if (op.first==
"reltol") {
305 }
else if (op.first==
"parallelization") {
307 }
else if (op.first==
"print_progress") {
309 }
else if (op.first==
"new_forward") {
311 }
else if (op.first==
"new_jacobian") {
313 }
else if (op.first==
"new_hessian") {
315 }
else if (op.first==
"hessian_coloring") {
328 "FMU does not provide support for analytic derivatives");
331 "FMU does not provide support for adjoint derivatives");
335 std::ofstream valfile;
337 valfile <<
"Output Input Value Nominal Min Max AD FD Step Offset Stencil" << std::endl;
346 if (
verbose_) casadi_message(
"Serial evaluation");
354 #ifdef CASADI_WITH_THREAD
362 +
" not enabled during compilation. Falling back to serial evaluation");
368 std::vector<size_t> in_jac(
fmu_.
n_in(), 0);
371 for (
auto&& i :
out_) {
375 const std::vector<size_t>& iind =
fmu_.
ired(i.wrt);
377 if (iind.empty())
continue;
379 bool exists = in_jac[iind.front()] > 0;
380 for (
size_t j : iind) casadi_assert((in_jac[j] > 0) == exists,
"Jacobian not a block");
383 for (
size_t j : iind) {
390 i.cbegin = in_jac[iind.front()] - 1;
391 i.cend = i.cbegin + iind.size();
395 const std::vector<size_t>& iind =
fmu_.
ired(i.ind);
397 if (iind.empty())
continue;
399 bool exists = in_jac[iind.front()] > 0;
400 for (
size_t j : iind) casadi_assert((in_jac[j] > 0) == exists,
"Hessian not a block");
403 for (
size_t j : iind) {
410 i.rbegin = in_jac[iind.front()] - 1;
411 i.rend = i.rbegin + iind.size();
422 std::fill(in_jac.begin(), in_jac.end(), 0);
424 for (
size_t k = 0; k <
out_.size(); ++k) {
428 const std::vector<size_t>& oind =
fmu_.
ored(i.
ind);
430 if (oind.empty())
continue;
432 bool exists = in_jac[oind.front()] > 0;
433 for (
size_t j : oind) casadi_assert((in_jac[j] > 0) == exists,
"Jacobian not a block");
436 for (
size_t j : oind) {
442 i.
rbegin = in_jac[oind.front()] - 1;
458 for (
auto&& i :
in_) {
461 const std::vector<size_t>& oind =
fmu_.
ored(i.ind);
463 if (oind.empty())
continue;
465 bool exists = in_jac[oind.front()] > 0;
466 for (
size_t j : oind) casadi_assert((in_jac[j] > 0) == exists,
"Jacobian not a block");
469 for (
size_t j : oind) {
515 std::vector<bool> is_nonlin(
jac_in_.size(),
false);
516 for (casadi_int k = 0; k < hess_nnz; ++k) is_nonlin[hess_row[k]] =
true;
518 for (casadi_int c = 0; c <
jac_in_.size(); ++c) {
519 if (is_nonlin[c])
nonlin_.push_back(c);
528 std::vector<casadi_int> zind;
529 for (casadi_int c = 0; c <
jac_in_.size(); ++c) {
530 if (!is_nonlin[c]) zind.push_back(c);
537 if (
verbose_) casadi_message(
"Hessian calculation for " +
str(
nonlin_.size()) +
" variables");
562 casadi_int jac_iw, jac_w;
563 casadi_jac_work(&
p_, &jac_iw, &jac_w);
569 std::vector<std::string>* scheme_in,
570 std::vector<std::string>* scheme_out,
571 const std::vector<std::string>& name_in,
572 const std::vector<std::string>& name_out) {
574 if (scheme_in) scheme_in->clear();
575 if (scheme_out) scheme_out->clear();
577 for (
const std::string& n : name_in) {
580 }
catch (std::exception& e) {
581 casadi_error(
"Cannot process input " + n +
": " + std::string(e.what()));
585 for (
const std::string& n : name_out) {
588 }
catch (std::exception& e) {
589 casadi_error(
"Cannot process output " + n +
": " + std::string(e.what()));
594 std::set<std::string> s(scheme_in->begin(), scheme_in->end());
595 scheme_in->assign(s.begin(), s.end());
599 std::set<std::string> s(scheme_out->begin(), scheme_out->end());
600 scheme_out->assign(s.begin(), s.end());
605 std::vector<std::string>* name_in, std::vector<std::string>* name_out) {
611 std::string pref, rem;
620 if (name_in) name_in->push_back(rem);
622 casadi_error(
"Cannot process: " + n);
628 if (name_out) name_out->push_back(rem);
630 }
else if (pref ==
"fwd") {
634 if (name_in) name_in->push_back(rem);
635 }
else if (pref ==
"adj") {
639 if (name_out) name_out->push_back(rem);
642 casadi_error(
"No such prefix: " + pref);
648 if (name_in) name_in->push_back(n);
655 std::vector<std::string>* name_in, std::vector<std::string>* name_out) {
661 std::string pref, rem;
665 casadi_assert(
has_prefix(rem),
"Two arguments expected for Jacobian block");
669 casadi_assert(
has_prefix(rem),
"Two arguments expected for Jacobian block");
673 std::string sens = pref;
679 if (name_out) name_out->push_back(rem);
681 if (name_in) name_in->push_back(sens);
682 }
else if (pref ==
"out") {
686 if (name_in) name_in->push_back(sens);
688 if (name_in) name_out->push_back(rem);
690 casadi_error(
"No such prefix: " + pref);
696 if (name_in) name_in->push_back(pref);
698 if (name_in) name_in->push_back(rem);
702 std::string out = pref;
708 if (name_out) name_out->push_back(out);
710 if (name_out) name_out->push_back(rem);
712 casadi_error(
"No such prefix: " + pref);
718 if (name_out) name_out->push_back(pref);
720 if (name_in) name_in->push_back(rem);
723 }
else if (pref ==
"fwd") {
727 if (name_out) name_out->push_back(rem);
728 }
else if (pref ==
"adj") {
732 if (name_in) name_in->push_back(rem);
735 casadi_error(
"No such prefix: " + pref);
741 if (name_out) name_out->push_back(n);
748 switch (
in_.at(i).type) {
765 switch (
out_.at(i).type) {
787 switch (
in_.at(i).type) {
804 switch (
out_.at(i).type) {
812 casadi_warning(
"FmuFunction::get_nominal_out not implemented for OutputType::JAC");
815 casadi_warning(
"FmuFunction::get_nominal_out not implemented for OutputType::JAC_TRANS");
818 casadi_warning(
"FmuFunction::get_nominal_out not implemented for OutputType::JAC_ADJ_OUT");
821 casadi_warning(
"FmuFunction::get_nominal_out not implemented for OutputType::JAC_REG_ADJ");
824 casadi_warning(
"FmuFunction::get_nominal_out not implemented for OutputType::HESS");
835 casadi_assert(m != 0,
"Memory is null");
837 setup(mem, arg, res, iw, w);
840 bool need_jac =
false, need_fwd =
false, need_adj =
false, need_hess =
false;
841 for (
size_t k = 0; k <
out_.size(); ++k) {
843 switch (
out_[k].type) {
864 double *aseed = 0, *asens = 0, *jac_nz = 0, *hess_nz = 0;
878 for (
size_t i = 0; i <
in_.size(); ++i) {
880 const std::vector<size_t>& oind =
fmu_.
ored(
in_[i].ind);
881 for (casadi_int d = 0; d <
nadj_; ++d) {
884 for (
size_t k = 0; k < oind.size(); ++k) aseed[oind[k] + aseed_off] = arg[i][k + off];
895 for (casadi_int task = 0; task <
max_n_tasks_; ++task) {
905 casadi_jac_init(&
p_, &s->
d, &iw, &w);
916 if (
verbose_) casadi_message(
"Evaluating regular outputs, forward sens, extended Jacobian");
920 if (
verbose_) casadi_message(
"Evaluating extended Hessian");
928 for (
size_t k = 0; k <
out_.size(); ++k) {
933 switch (
out_[k].type) {
935 casadi_get_sub(r,
jac_sp_, jac_nz,
939 casadi_get_sub(w,
jac_sp_, jac_nz,
946 for (casadi_int d = 0; d <
nadj_; ++d) {
948 for (
size_t id :
fmu_.
ired(
out_[k].wrt)) *r++ = asens[
id + asens_off];
953 casadi_get_sub(r,
hess_sp_, hess_nz,
965 bool need_nondiff,
bool need_jac,
bool need_fwd,
bool need_adj,
bool need_hess)
const {
970 || (!need_jac && !need_adj && !need_hess)) {
972 flag =
eval_task(m, 0, 1, need_nondiff, need_jac, need_fwd, need_adj, need_hess);
976 #pragma omp parallel reduction(||:flag)
979 casadi_int task = omp_get_thread_num();
981 casadi_int num_threads = omp_get_num_threads();
983 casadi_int num_used_threads = std::min(num_threads, n_task);
985 if (task < num_used_threads) {
987 flag =
eval_task(s, task, num_used_threads, need_nondiff && task == 0,
988 need_jac, need_fwd && task <
nfwd_, need_adj, need_hess);
998 #ifdef CASADI_WITH_THREAD
1000 std::vector<int> flag_task(n_task);
1002 std::vector<std::thread> threads;
1003 for (casadi_int task = 0; task < n_task; ++task) {
1004 threads.emplace_back(
1005 [&, task](
int* fl) {
1007 *fl =
eval_task(s, task, n_task, need_nondiff && task == 0,
1008 need_jac, need_fwd && task <
nfwd_, need_adj, need_hess);
1009 }, &flag_task[task]);
1012 for (
auto&& th : threads) th.join();
1014 for (
int fl : flag_task) flag = flag || fl;
1026 bool need_nondiff,
bool need_jac,
bool need_fwd,
bool need_adj,
bool need_hess)
const {
1028 for (
size_t k = 0; k <
in_.size(); ++k) {
1034 for (
size_t k = 0; k <
out_.size(); ++k) {
1043 for (
size_t k = 0; k <
out_.size(); ++k) {
1052 casadi_int d_begin = (task *
nfwd_) / n_task;
1053 casadi_int d_end = ((task + 1) *
nfwd_) / n_task;
1055 for (casadi_int d = d_begin; d < d_end; ++d) {
1058 task + 1, n_task, d - d_begin + 1, d_end - d_begin);
1060 for (
size_t k = 0; k <
in_.size(); ++k) {
1066 for (
size_t k = 0; k <
out_.size(); ++k) {
1074 for (
size_t k = 0; k <
out_.size(); ++k) {
1087 for (casadi_int c = c_begin; c < c_end; ++c) {
1090 task + 1, n_task, c - c_begin + 1, c_end - c_begin);
1092 casadi_jac_pre(&
p_, &m->
d, c);
1099 casadi_jac_scale(&
p_, &m->
d);
1102 for (casadi_int i = 0; i < m->
d.
nsens; ++i) {
1108 for (casadi_int d = 0; d <
nadj_; ++d) {
1110 size_t asens_off = d *
fmu_.
n_in();
1111 for (casadi_int i = 0; i < m->
d.
nsens; ++i) {
1118 }
else if (need_adj) {
1120 casadi_int d_begin = (task *
nadj_) / n_task;
1121 casadi_int d_end = ((task + 1) *
nadj_) / n_task;
1123 for (casadi_int d = d_begin; d < d_end; ++d) {
1126 task + 1, n_task, d - d_begin + 1, d_end - d_begin);
1128 for (
size_t k = 0; k <
in_.size(); ++k) {
1134 for (
size_t k = 0; k <
out_.size(); ++k) {
1142 for (
size_t k = 0; k <
out_.size(); ++k) {
1157 casadi_int c_begin = (task * n_hc) / n_task;
1158 casadi_int c_end = ((task + 1) * n_hc) / n_task;
1160 std::vector<double> x, h;
1162 for (casadi_int c = c_begin; c < c_end; ++c) {
1165 task + 1, n_task, c - c_begin + 1, c_end - c_begin);
1167 casadi_int v_begin = hc_colind[c];
1168 casadi_int v_end = hc_colind[c + 1];
1169 casadi_int nv = v_end - v_begin;
1173 for (casadi_int v = 0; v < nv; ++v) {
1175 casadi_int ind1 = hc_row[v_begin + v];
1176 casadi_int
id =
jac_in_.at(ind1);
1178 x[v] = m->
ibuf_.at(
id);
1185 std::stringstream ss;
1186 ss <<
"Cannot perturb " <<
fmu_.
desc_in(m,
id) <<
" at " << x[v]
1188 casadi_warning(ss.str());
1195 m->
ibuf_.at(
id) += h[v];
1212 casadi_jac_pre(&
p_, &m->
d, c1);
1219 casadi_jac_scale(&
p_, &m->
d);
1221 for (casadi_int i = 0; i < m->
d.
nsens; ++i)
1226 for (casadi_int v = 0; v < nv; ++v) {
1227 casadi_int ind1 = hc_row[v_begin + v];
1228 for (casadi_int k = hess_colind[ind1]; k < hess_colind[ind1 + 1]; ++k) {
1229 casadi_int id2 =
jac_in_.at(hess_row[k]);
1234 for (casadi_int v = 0; v < nv; ++v) {
1236 casadi_int ind1 = hc_row[v_begin + v];
1237 casadi_int
id =
jac_in_.at(ind1);
1239 m->
ibuf_.at(
id) = x[v];
1242 for (casadi_int k = hess_colind[ind1]; k < hess_colind[ind1 + 1]; ++k) {
1243 casadi_int id2 =
jac_in_.at(hess_row[k]);
1268 for (casadi_int c = 0; c < n; ++c) {
1270 for (casadi_int k = colind[c]; k < colind[c + 1]; ++k) {
1272 casadi_int r = row[k];
1274 casadi_int k_tr = iw[r]++;
1278 double nz = hess_nz[k], nz_tr = hess_nz[k_tr];
1280 if (std::isnan(nz) || std::isinf(nz)) {
1281 std::stringstream ss;
1282 ss <<
"Second derivative w.r.t. " <<
fmu_.
desc_in(m, id_r) <<
" and "
1284 casadi_warning(ss.str());
1291 double nz_max = std::fmax(std::fabs(nz), std::fabs(nz_tr));
1293 if (nz_max >
abstol_ && std::fabs(nz - nz_tr) > nz_max *
reltol_) {
1294 std::stringstream ss;
1295 ss <<
"Hessian appears nonsymmetric. Got " << nz <<
" vs. " << nz_tr
1296 <<
" for second derivative w.r.t. " <<
fmu_.
desc_in(m, id_r) <<
" and "
1297 <<
fmu_.
desc_in(m, id_c) <<
", hess_nz = " << k <<
"/" << k_tr;
1298 casadi_warning(ss.str());
1310 std::fill(iw, iw + n, 0);
1313 for (casadi_int k = 0; k < hess_colors_nnz; ++k)
1314 iw[hess_colors_row[k]] = 1;
1318 for (casadi_int c = 0; c < n; ++c) {
1320 for (casadi_int k = colind[c]; k < colind[c + 1]; ++k) {
1322 casadi_int r = row[k];
1324 casadi_int k_tr = iw[r]++;
1326 if (std::isnan(hess_nz[k])) {
1327 hess_nz[k] = hess_nz[k_tr];
1340 for (casadi_int c = 0; c < n; ++c) {
1342 for (casadi_int k = colind[c]; k < colind[c + 1]; ++k) {
1344 casadi_int r = row[k];
1346 casadi_int k_tr = iw[r]++;
1348 if (r < c) hess_nz[k] = hess_nz[k_tr] = 0.5 * (hess_nz[k] + hess_nz[k_tr]);
1364 return s.find(
'_') < s.size();
1369 casadi_assert_dev(!s.empty());
1370 size_t pos = s.find(
'_');
1371 casadi_assert(pos < s.size(),
"Cannot process \"" + s +
"\"");
1373 std::string r = s.substr(0, pos);
1375 if (rem) *rem = s.substr(pos+1, std::string::npos);
1391 for (
auto&& e :
in_) {
1399 if (
nfwd_ > 1)
return false;
1402 if (
nadj_ > 1)
return false;
1410 for (
auto&& e :
out_) {
1426 const std::vector<std::string>& s_in,
1427 const std::vector<std::string>& s_out,
1429 const Dict& opts)
const {
1438 std::vector<std::string> s_in_mod = s_in, s_out_mod = s_out;
1439 for (std::string& s : s_in_mod) std::replace(s.begin(), s.end(),
':',
'_');
1440 for (std::string& s : s_out_mod) std::replace(s.begin(), s.end(),
':',
'_');
1446 }
catch (std::exception& e) {
1447 casadi_warning(
"FmuFunction::factory call for constructing " + name +
" from " +
name_
1448 +
" failed:\n" + std::string(e.what()) +
"\nFalling back to base class implementation");
1462 const std::vector<std::string>& onames,
const Dict& opts)
const {
1485 const std::vector<std::string>& inames,
1486 const std::vector<std::string>& onames,
1487 const Dict& opts)
const {
1495 opts1[
"nfwd"] = nfwd;
1511 const std::vector<std::string>& inames,
1512 const std::vector<std::string>& onames,
1513 const Dict& opts)
const {
1520 opts1[
"nadj"] = nadj;
1548 bool symmetric)
const {
1564 casadi_error(
"Implementation error");
1585 casadi_assert_dev(
in_.size()==
n_in_);
1587 s.
pack(
"FmuFunction::in::type",
static_cast<int>(e.type));
1588 s.
pack(
"FmuFunction::in::ind", e.ind);
1592 s.
pack(
"FmuFunction::out::type",
static_cast<int>(e.type));
1593 s.
pack(
"FmuFunction::out::ind", e.ind);
1594 s.
pack(
"FmuFunction::out::wrt", e.wrt);
1595 s.
pack(
"FmuFunction::out::rbegin", e.rbegin);
1596 s.
pack(
"FmuFunction::out::rend", e.rend);
1597 s.
pack(
"FmuFunction::out::cbegin", e.cbegin);
1598 s.
pack(
"FmuFunction::out::cend", e.cend);
1626 s.
pack(
"FmuFunction::fd",
static_cast<int>(
fd_));
1651 s.
unpack(
"FmuFunction::in::type", t);
1653 s.
unpack(
"FmuFunction::in::ind", e.ind);
1658 s.
unpack(
"FmuFunction::out::type", t);
1660 s.
unpack(
"FmuFunction::out::ind", e.ind);
1661 s.
unpack(
"FmuFunction::out::wrt", e.wrt);
1662 s.
unpack(
"FmuFunction::out::rbegin", e.rbegin);
1663 s.
unpack(
"FmuFunction::out::rend", e.rend);
1664 s.
unpack(
"FmuFunction::out::cbegin", e.cbegin);
1665 s.
unpack(
"FmuFunction::out::cend", e.cend);
1696 s.
unpack(
"FmuFunction::fd", fd);
1698 int parallelization = 0;
1699 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 void open(std::ofstream &, const std::string &path, std::ios_base::openmode mode=std::ios_base::out)
bool has_jacobian() const override
Full Jacobian.
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_
~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
casadi_jac_prob< double > p_
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.
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 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.
Sparsity get_sparsity_in(casadi_int i) override
Retreive sparsities.
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 make_symmetric(double *hess_nz, casadi_int *iw) const
void change_option(const std::string &option_name, const GenericType &option_value) override
Change option after object creation for debugging.
int init_mem(void *mem) const override
Initalize memory block.
void remove_nans(double *hess_nz, casadi_int *iw) const
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 check_hessian(FmuMemory *m, const double *hess_nz, casadi_int *iw) const
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
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
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
Generic data type, can hold different types such as bool, casadi_int, std::string etc.
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.
Sparsity star_coloring(casadi_int ordering=1, casadi_int cutoff=std::numeric_limits< casadi_int >::max()) const
Perform a star coloring of a symmetric matrix:
static Sparsity dense(casadi_int nrow, casadi_int ncol=1)
Create a dense rectangular sparsity pattern *.
Sparsity T() const
Transpose the 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_
std::vector< bool > omarked_
casadi_jac_data< double > d
std::vector< double > ibuf_
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=0, std::vector< std::string > *name_out=0)