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) {
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_) {
185 if (option_name ==
"print_progress") {
202 "Names of the inputs in the scheme"}},
205 "Names of the outputs in the scheme"}},
208 "Definitions of the scheme variables"}},
211 "Auxilliary variables"}},
214 "[DEPRECATED] Renamed uses_directional_derivatives"}},
217 "Number of forward sensitivities to be calculated [1]"}},
220 "Number of adjoint sensitivities to be calculated [1]"}},
221 {
"uses_directional_derivatives",
223 "Use the analytic forward directional derivative support in the FMU"}},
226 "Compare forward derivatives with finite differences for validation"}},
229 "Validate entries of the Hessian for self-consistency"}},
232 "[DEPRECATED] Renamed 'validate_forward'"}},
235 "Redirect results of Hessian validation to a file instead of generating a warning"}},
238 "[DEPRECATED] Renamed 'validate_hessian'"}},
241 "Ensure Hessian is symmetric"}},
244 "Step size, scaled by nominal value"}},
247 "Absolute error tolerance, scaled by nominal value"}},
250 "Relative error tolerance"}},
253 "Parallelization [SERIAL|openmp|thread]"}},
256 "Print progress during Jacobian/Hessian evaluation"}},
259 "Use forward AD implementation in class (conversion option, to be removed)"}},
262 "Use Jacobian implementation in class (conversion option, to be removed)"}},
265 "Use Hessian implementation in class (conversion option, to be removed)"}},
268 "Enable the use of graph coloring (star coloring) for Hessian calculation. "
269 "Note that disabling the coloring can improve symmetry check diagnostics."}}
275 for (
auto&& op : opts) {
276 if (op.first==
"enable_ad") {
277 casadi_warning(
"Option 'enable_ad' has been renamed 'uses_directional_derivatives'");
279 }
else if (op.first==
"uses_directional_derivatives") {
281 }
else if (op.first==
"nfwd") {
283 }
else if (op.first==
"nadj") {
285 }
else if (op.first==
"uses_adjoint_derivatives") {
287 }
else if (op.first==
"validate_forward") {
289 }
else if (op.first==
"validate_hessian") {
291 }
else if (op.first==
"validate_ad") {
292 casadi_warning(
"Option 'validate_ad' has been renamed 'validate_forward'");
294 }
else if (op.first==
"check_hessian") {
295 casadi_warning(
"Option 'check_hessian' has been renamed 'validate_hessian'");
297 }
else if (op.first==
"validate_ad_file") {
299 }
else if (op.first==
"make_symmetric") {
301 }
else if (op.first==
"step") {
303 }
else if (op.first==
"abstol") {
305 }
else if (op.first==
"reltol") {
307 }
else if (op.first==
"parallelization") {
309 }
else if (op.first==
"print_progress") {
311 }
else if (op.first==
"new_forward") {
313 }
else if (op.first==
"new_jacobian") {
315 }
else if (op.first==
"new_hessian") {
317 }
else if (op.first==
"hessian_coloring") {
330 "FMU does not provide support for analytic derivatives");
333 "FMU does not provide support for adjoint derivatives");
338 std::ostream& valfile = *valfile_ptr;
339 valfile <<
"Output Input Value Nominal Min Max AD FD Step Offset Stencil" << std::endl;
348 if (
verbose_) casadi_message(
"Serial evaluation");
356 #ifdef CASADI_WITH_THREAD
364 +
" not enabled during compilation. Falling back to serial evaluation");
370 std::vector<size_t> in_jac(
fmu_.
n_in(), 0);
373 for (
auto&& i :
out_) {
377 const std::vector<size_t>& iind =
fmu_.
ired(i.wrt);
379 if (iind.empty())
continue;
381 bool exists = in_jac[iind.front()] > 0;
382 for (
size_t j : iind) casadi_assert((in_jac[j] > 0) == exists,
"Jacobian not a block");
385 for (
size_t j : iind) {
392 i.cbegin = in_jac[iind.front()] - 1;
393 i.cend = i.cbegin + iind.size();
397 const std::vector<size_t>& iind =
fmu_.
ired(i.ind);
399 if (iind.empty())
continue;
401 bool exists = in_jac[iind.front()] > 0;
402 for (
size_t j : iind) casadi_assert((in_jac[j] > 0) == exists,
"Hessian not a block");
405 for (
size_t j : iind) {
412 i.rbegin = in_jac[iind.front()] - 1;
413 i.rend = i.rbegin + iind.size();
424 std::fill(in_jac.begin(), in_jac.end(), 0);
426 for (
size_t k = 0; k <
out_.size(); ++k) {
430 const std::vector<size_t>& oind =
fmu_.
ored(i.
ind);
432 if (oind.empty())
continue;
434 bool exists = in_jac[oind.front()] > 0;
435 for (
size_t j : oind) casadi_assert((in_jac[j] > 0) == exists,
"Jacobian not a block");
438 for (
size_t j : oind) {
444 i.
rbegin = in_jac[oind.front()] - 1;
460 for (
auto&& i :
in_) {
463 const std::vector<size_t>& oind =
fmu_.
ored(i.ind);
465 if (oind.empty())
continue;
467 bool exists = in_jac[oind.front()] > 0;
468 for (
size_t j : oind) casadi_assert((in_jac[j] > 0) == exists,
"Jacobian not a block");
471 for (
size_t j : oind) {
517 std::vector<bool> is_nonlin(
jac_in_.size(),
false);
518 for (casadi_int k = 0; k < hess_nnz; ++k) is_nonlin[hess_row[k]] =
true;
520 for (casadi_int c = 0; c <
jac_in_.size(); ++c) {
521 if (is_nonlin[c])
nonlin_.push_back(c);
530 std::vector<casadi_int> zind;
531 for (casadi_int c = 0; c <
jac_in_.size(); ++c) {
532 if (!is_nonlin[c]) zind.push_back(c);
539 if (
verbose_) casadi_message(
"Hessian calculation for " +
str(
nonlin_.size()) +
" variables");
564 casadi_int jac_iw, jac_w;
565 casadi_jac_work(&
p_, &jac_iw, &jac_w);
571 std::vector<std::string>* scheme_in,
572 std::vector<std::string>* scheme_out,
573 const std::vector<std::string>& name_in,
574 const std::vector<std::string>& name_out) {
576 if (scheme_in) scheme_in->clear();
577 if (scheme_out) scheme_out->clear();
579 for (
const std::string& n : name_in) {
582 }
catch (std::exception& e) {
583 casadi_error(
"Cannot process input " + n +
": " + std::string(e.what()));
587 for (
const std::string& n : name_out) {
590 }
catch (std::exception& e) {
591 casadi_error(
"Cannot process output " + n +
": " + std::string(e.what()));
596 std::set<std::string> s(scheme_in->begin(), scheme_in->end());
597 scheme_in->assign(s.begin(), s.end());
601 std::set<std::string> s(scheme_out->begin(), scheme_out->end());
602 scheme_out->assign(s.begin(), s.end());
607 std::vector<std::string>* name_in, std::vector<std::string>* name_out) {
613 std::string pref, rem;
622 if (name_in) name_in->push_back(rem);
624 casadi_error(
"Cannot process: " + n);
630 if (name_out) name_out->push_back(rem);
632 }
else if (pref ==
"fwd") {
636 if (name_in) name_in->push_back(rem);
637 }
else if (pref ==
"adj") {
641 if (name_out) name_out->push_back(rem);
644 casadi_error(
"No such prefix: " + pref);
650 if (name_in) name_in->push_back(n);
657 std::vector<std::string>* name_in, std::vector<std::string>* name_out) {
663 std::string pref, rem;
667 casadi_assert(
has_prefix(rem),
"Two arguments expected for Jacobian block");
671 casadi_assert(
has_prefix(rem),
"Two arguments expected for Jacobian block");
675 std::string sens = pref;
681 if (name_out) name_out->push_back(rem);
683 if (name_in) name_in->push_back(sens);
684 }
else if (pref ==
"out") {
688 if (name_in) name_in->push_back(sens);
690 if (name_in) name_out->push_back(rem);
692 casadi_error(
"No such prefix: " + pref);
698 if (name_in) name_in->push_back(pref);
700 if (name_in) name_in->push_back(rem);
704 std::string out = pref;
710 if (name_out) name_out->push_back(out);
712 if (name_out) name_out->push_back(rem);
714 casadi_error(
"No such prefix: " + pref);
720 if (name_out) name_out->push_back(pref);
722 if (name_in) name_in->push_back(rem);
725 }
else if (pref ==
"fwd") {
729 if (name_out) name_out->push_back(rem);
730 }
else if (pref ==
"adj") {
734 if (name_in) name_in->push_back(rem);
737 casadi_error(
"No such prefix: " + pref);
743 if (name_out) name_out->push_back(n);
750 switch (
in_.at(i).type) {
767 switch (
out_.at(i).type) {
789 switch (
in_.at(i).type) {
806 switch (
out_.at(i).type) {
814 casadi_warning(
"FmuFunction::get_nominal_out not implemented for OutputType::JAC");
817 casadi_warning(
"FmuFunction::get_nominal_out not implemented for OutputType::JAC_TRANS");
820 casadi_warning(
"FmuFunction::get_nominal_out not implemented for OutputType::JAC_ADJ_OUT");
823 casadi_warning(
"FmuFunction::get_nominal_out not implemented for OutputType::JAC_REG_ADJ");
826 casadi_warning(
"FmuFunction::get_nominal_out not implemented for OutputType::HESS");
837 casadi_assert(m != 0,
"Memory is null");
839 setup(mem, arg, res, iw, w);
842 bool need_jac =
false, need_fwd =
false, need_adj =
false, need_hess =
false;
843 for (
size_t k = 0; k <
out_.size(); ++k) {
845 switch (
out_[k].type) {
866 double *aseed = 0, *asens = 0, *jac_nz = 0, *hess_nz = 0;
880 for (
size_t i = 0; i <
in_.size(); ++i) {
882 const std::vector<size_t>& oind =
fmu_.
ored(
in_[i].ind);
883 for (casadi_int d = 0; d <
nadj_; ++d) {
886 for (
size_t k = 0; k < oind.size(); ++k) aseed[oind[k] + aseed_off] = arg[i][k + off];
897 for (casadi_int task = 0; task <
max_n_tasks_; ++task) {
907 casadi_jac_init(&
p_, &s->
d, &iw, &w);
918 if (
verbose_) casadi_message(
"Evaluating regular outputs, forward sens, extended Jacobian");
922 if (
verbose_) casadi_message(
"Evaluating extended Hessian");
930 for (
size_t k = 0; k <
out_.size(); ++k) {
935 switch (
out_[k].type) {
937 casadi_get_sub(r,
jac_sp_, jac_nz,
941 casadi_get_sub(w,
jac_sp_, jac_nz,
948 for (casadi_int d = 0; d <
nadj_; ++d) {
950 for (
size_t id :
fmu_.
ired(
out_[k].wrt)) *r++ = asens[
id + asens_off];
955 casadi_get_sub(r,
hess_sp_, hess_nz,
967 bool need_nondiff,
bool need_jac,
bool need_fwd,
bool need_adj,
bool need_hess)
const {
972 || (!need_jac && !need_adj && !need_hess)) {
974 flag =
eval_task(m, 0, 1, need_nondiff, need_jac, need_fwd, need_adj, need_hess);
978 #pragma omp parallel reduction(||:flag)
981 casadi_int task = omp_get_thread_num();
983 casadi_int num_threads = omp_get_num_threads();
985 casadi_int num_used_threads = std::min(num_threads, n_task);
987 if (task < num_used_threads) {
989 flag =
eval_task(s, task, num_used_threads, need_nondiff && task == 0,
990 need_jac, need_fwd && task <
nfwd_, need_adj, need_hess);
1000 #ifdef CASADI_WITH_THREAD
1002 std::vector<int> flag_task(n_task);
1004 std::vector<std::thread> threads;
1005 for (casadi_int task = 0; task < n_task; ++task) {
1006 threads.emplace_back(
1007 [&, task](
int* fl) {
1009 *fl =
eval_task(s, task, n_task, need_nondiff && task == 0,
1010 need_jac, need_fwd && task <
nfwd_, need_adj, need_hess);
1011 }, &flag_task[task]);
1014 for (
auto&& th : threads) th.join();
1016 for (
int fl : flag_task) flag = flag || fl;
1028 bool need_nondiff,
bool need_jac,
bool need_fwd,
bool need_adj,
bool need_hess)
const {
1030 for (
size_t k = 0; k <
in_.size(); ++k) {
1036 for (
size_t k = 0; k <
out_.size(); ++k) {
1045 for (
size_t k = 0; k <
out_.size(); ++k) {
1054 casadi_int d_begin = (task *
nfwd_) / n_task;
1055 casadi_int d_end = ((task + 1) *
nfwd_) / n_task;
1057 for (casadi_int d = d_begin; d < d_end; ++d) {
1060 task + 1, n_task, d - d_begin + 1, d_end - d_begin);
1062 for (
size_t k = 0; k <
in_.size(); ++k) {
1068 for (
size_t k = 0; k <
out_.size(); ++k) {
1076 for (
size_t k = 0; k <
out_.size(); ++k) {
1089 for (casadi_int c = c_begin; c < c_end; ++c) {
1092 task + 1, n_task, c - c_begin + 1, c_end - c_begin);
1094 casadi_jac_pre(&
p_, &m->
d, c);
1101 casadi_jac_scale(&
p_, &m->
d);
1104 for (casadi_int i = 0; i < m->
d.
nsens; ++i) {
1110 for (casadi_int d = 0; d <
nadj_; ++d) {
1112 size_t asens_off = d *
fmu_.
n_in();
1113 for (casadi_int i = 0; i < m->
d.
nsens; ++i) {
1120 }
else if (need_adj) {
1122 casadi_int d_begin = (task *
nadj_) / n_task;
1123 casadi_int d_end = ((task + 1) *
nadj_) / n_task;
1125 for (casadi_int d = d_begin; d < d_end; ++d) {
1128 task + 1, n_task, d - d_begin + 1, d_end - d_begin);
1130 for (
size_t k = 0; k <
in_.size(); ++k) {
1136 for (
size_t k = 0; k <
out_.size(); ++k) {
1144 for (
size_t k = 0; k <
out_.size(); ++k) {
1159 casadi_int c_begin = (task * n_hc) / n_task;
1160 casadi_int c_end = ((task + 1) * n_hc) / n_task;
1162 std::vector<double> x, h;
1164 for (casadi_int c = c_begin; c < c_end; ++c) {
1167 task + 1, n_task, c - c_begin + 1, c_end - c_begin);
1169 casadi_int v_begin = hc_colind[c];
1170 casadi_int v_end = hc_colind[c + 1];
1171 casadi_int nv = v_end - v_begin;
1175 for (casadi_int v = 0; v < nv; ++v) {
1177 casadi_int ind1 = hc_row[v_begin + v];
1178 casadi_int
id =
jac_in_.at(ind1);
1180 x[v] = m->
ibuf_.at(
id);
1187 std::stringstream ss;
1188 ss <<
"Cannot perturb " <<
fmu_.
desc_in(m,
id) <<
" at " << x[v]
1190 casadi_warning(ss.str());
1197 m->
ibuf_.at(
id) += h[v];
1214 casadi_jac_pre(&
p_, &m->
d, c1);
1221 casadi_jac_scale(&
p_, &m->
d);
1223 for (casadi_int i = 0; i < m->
d.
nsens; ++i)
1228 for (casadi_int v = 0; v < nv; ++v) {
1229 casadi_int ind1 = hc_row[v_begin + v];
1230 for (casadi_int k = hess_colind[ind1]; k < hess_colind[ind1 + 1]; ++k) {
1231 casadi_int id2 =
jac_in_.at(hess_row[k]);
1236 for (casadi_int v = 0; v < nv; ++v) {
1238 casadi_int ind1 = hc_row[v_begin + v];
1239 casadi_int
id =
jac_in_.at(ind1);
1241 m->
ibuf_.at(
id) = x[v];
1244 for (casadi_int k = hess_colind[ind1]; k < hess_colind[ind1 + 1]; ++k) {
1245 casadi_int id2 =
jac_in_.at(hess_row[k]);
1270 for (casadi_int c = 0; c < n; ++c) {
1272 for (casadi_int k = colind[c]; k < colind[c + 1]; ++k) {
1274 casadi_int r = row[k];
1276 casadi_int k_tr = iw[r]++;
1280 double nz = hess_nz[k], nz_tr = hess_nz[k_tr];
1282 if (std::isnan(nz) || std::isinf(nz)) {
1283 std::stringstream ss;
1284 ss <<
"Second derivative w.r.t. " <<
fmu_.
desc_in(m, id_r) <<
" and "
1286 casadi_warning(ss.str());
1293 double nz_max = std::fmax(std::fabs(nz), std::fabs(nz_tr));
1295 if (nz_max >
abstol_ && std::fabs(nz - nz_tr) > nz_max *
reltol_) {
1296 std::stringstream ss;
1297 ss <<
"Hessian appears nonsymmetric. Got " << nz <<
" vs. " << nz_tr
1298 <<
" for second derivative w.r.t. " <<
fmu_.
desc_in(m, id_r) <<
" and "
1299 <<
fmu_.
desc_in(m, id_c) <<
", hess_nz = " << k <<
"/" << k_tr;
1300 casadi_warning(ss.str());
1312 std::fill(iw, iw + n, 0);
1315 for (casadi_int k = 0; k < hess_colors_nnz; ++k)
1316 iw[hess_colors_row[k]] = 1;
1320 for (casadi_int c = 0; c < n; ++c) {
1322 for (casadi_int k = colind[c]; k < colind[c + 1]; ++k) {
1324 casadi_int r = row[k];
1326 casadi_int k_tr = iw[r]++;
1328 if (std::isnan(hess_nz[k])) {
1329 hess_nz[k] = hess_nz[k_tr];
1342 for (casadi_int c = 0; c < n; ++c) {
1344 for (casadi_int k = colind[c]; k < colind[c + 1]; ++k) {
1346 casadi_int r = row[k];
1348 casadi_int k_tr = iw[r]++;
1350 if (r < c) hess_nz[k] = hess_nz[k_tr] = 0.5 * (hess_nz[k] + hess_nz[k_tr]);
1366 return s.find(
'_') < s.size();
1371 casadi_assert_dev(!s.empty());
1372 size_t pos = s.find(
'_');
1373 casadi_assert(pos < s.size(),
"Cannot process \"" + s +
"\"");
1375 std::string r = s.substr(0, pos);
1377 if (rem) *rem = s.substr(pos+1, std::string::npos);
1393 for (
auto&& e :
in_) {
1401 if (
nfwd_ > 1)
return false;
1404 if (
nadj_ > 1)
return false;
1412 for (
auto&& e :
out_) {
1428 const std::vector<std::string>& s_in,
1429 const std::vector<std::string>& s_out,
1431 const Dict& opts)
const {
1440 std::vector<std::string> s_in_mod = s_in, s_out_mod = s_out;
1441 for (std::string& s : s_in_mod) std::replace(s.begin(), s.end(),
':',
'_');
1442 for (std::string& s : s_out_mod) std::replace(s.begin(), s.end(),
':',
'_');
1448 }
catch (std::exception& e) {
1449 casadi_warning(
"FmuFunction::factory call for constructing " + name +
" from " +
name_
1450 +
" failed:\n" + std::string(e.what()) +
"\nFalling back to base class implementation");
1464 const std::vector<std::string>& onames,
const Dict& opts)
const {
1487 const std::vector<std::string>& inames,
1488 const std::vector<std::string>& onames,
1489 const Dict& opts)
const {
1497 opts1[
"nfwd"] = nfwd;
1513 const std::vector<std::string>& inames,
1514 const std::vector<std::string>& onames,
1515 const Dict& opts)
const {
1522 opts1[
"nadj"] = nadj;
1550 bool symmetric)
const {
1566 casadi_error(
"Implementation error");
1587 casadi_assert_dev(
in_.size()==
n_in_);
1589 s.
pack(
"FmuFunction::in::type",
static_cast<int>(e.type));
1590 s.
pack(
"FmuFunction::in::ind", e.ind);
1594 s.
pack(
"FmuFunction::out::type",
static_cast<int>(e.type));
1595 s.
pack(
"FmuFunction::out::ind", e.ind);
1596 s.
pack(
"FmuFunction::out::wrt", e.wrt);
1597 s.
pack(
"FmuFunction::out::rbegin", e.rbegin);
1598 s.
pack(
"FmuFunction::out::rend", e.rend);
1599 s.
pack(
"FmuFunction::out::cbegin", e.cbegin);
1600 s.
pack(
"FmuFunction::out::cend", e.cend);
1630 s.
pack(
"FmuFunction::fd",
static_cast<int>(
fd_));
1648 s.
version(
"FmuFunction", 3, 4);
1655 s.
unpack(
"FmuFunction::in::type", t);
1657 s.
unpack(
"FmuFunction::in::ind", e.ind);
1662 s.
unpack(
"FmuFunction::out::type", t);
1664 s.
unpack(
"FmuFunction::out::ind", e.ind);
1665 s.
unpack(
"FmuFunction::out::wrt", e.wrt);
1666 s.
unpack(
"FmuFunction::out::rbegin", e.rbegin);
1667 s.
unpack(
"FmuFunction::out::rend", e.rend);
1668 s.
unpack(
"FmuFunction::out::cbegin", e.cbegin);
1669 s.
unpack(
"FmuFunction::out::cend", e.cend);
1702 s.
unpack(
"FmuFunction::fd", fd);
1704 int parallelization = 0;
1705 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.
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
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
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)