Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 0.0% 0 / 0 / 85
Functions: 0.0% 0 / 0 / 7
Branches: 0.0% 0 / 0 / 112

OMCompiler/SimulationRuntime/c/moo/info.cpp
Line Branch Exec Source
1 /*
2 * This file belongs to the OpenModelica Run-Time System
3 *
4 * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC), c/o Linköpings
5 * universitet, Department of Computer and Information Science, SE-58183 Linköping, Sweden. All rights
6 * reserved.
7 *
8 * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF THE BSD NEW LICENSE OR THE
9 * AGPL VERSION 3 LICENSE OR THE OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8. ANY
10 * USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES RECIPIENT'S
11 * ACCEPTANCE OF THE BSD NEW LICENSE OR THE OSMC PUBLIC LICENSE OR THE AGPL
12 * VERSION 3, ACCORDING TO RECIPIENTS CHOICE.
13 *
14 * The OpenModelica software and the OSMC (Open Source Modelica Consortium) Public License
15 * (OSMC-PL) are obtained from OSMC, either from the above address, from the URLs:
16 * http://www.openmodelica.org or https://github.com/OpenModelica/ or
17 * http://www.ida.liu.se/projects/OpenModelica, and in the OpenModelica distribution. GNU
18 * AGPL version 3 is obtained from: https://www.gnu.org/licenses/licenses.html#GPL. The BSD NEW
19 * License is obtained from: http://www.opensource.org/licenses/BSD-3-Clause.
20 *
21 * This program is distributed WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY
23 * SET FORTH IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF
24 * OSMC-PL.
25 *
26 */
27
28 #include "info.h"
29 #include "../simulation/options.h"
30
31 #include <base/log.h>
32
33
34 namespace OpenModelica {
35
36 ✗ InfoGDOP::InfoGDOP(DATA* data, threadData_t* threadData, int argc, char** argv) :
37 ✗ data(data), threadData(threadData), argc(argc), argv(argv)
38 {
39 ✗ set_user_solver();
40 ✗ set_l2bn_options();
41 ✗ }
42
43 ✗ void InfoGDOP::set_user_solver() {
44 ✗ const char* flag_solver = (data->simulationInfo->solverMethod ? data->simulationInfo->solverMethod : omc_flagValue[FLAG_S]);
45 ✗ if (!flag_solver) return;
46
47 ✗ for (int solver = 1; solver < S_MAX; solver++) {
48 ✗ if (std::string(SOLVER_METHOD_NAME[solver]) == flag_solver) {
49 ✗ user_ode_solver = static_cast<SOLVER_METHOD>(solver);
50 ✗ return;
51 }
52 }
53 }
54
55 ✗ void InfoGDOP::set_l2bn_options() {
56 ✗ const char* cflags = omc_flagValue[FLAG_MOO_L2BN_P1_ITERATIONS];
57 ✗ l2bn_phase_one_iterations = (cflags ? atoi(cflags) : 0);
58
59 ✗ cflags = omc_flagValue[FLAG_MOO_L2BN_P2_ITERATIONS];
60 ✗ l2bn_phase_two_iterations = (cflags ? atoi(cflags) : 0);
61
62 ✗ cflags = omc_flagValue[FLAG_MOO_L2BN_P2_LEVEL];
63 ✗ l2bn_phase_two_level = (cflags ? atof(cflags) : 0.0);
64 ✗ }
65
66 ✗ void InfoGDOP::set_time_horizon(int steps) {
67 ✗ t0 = data->simulationInfo->startTime;
68 ✗ tf = data->simulationInfo->stopTime;
69 ✗ intervals = static_cast<int>(round((tf - t0)/data->simulationInfo->stepSize));
70 ✗ stages = steps;
71 ✗ }
72
73 ✗ void InfoGDOP::set_omc_flags(NLP::NLPSolverSettings& nlp_solver_settings) {
74 ✗ const char* cflags = omc_flagValue[FLAG_OPTIMIZER_NP];
75 ✗ set_time_horizon(cflags ? atoi(cflags) : 3);
76
77 ✗ nlp_solver_settings.set(NLP::Option::Tolerance, data->simulationInfo->tolerance);
78
79 // Linear solver
80 ✗ cflags = omc_flagValue[FLAG_LS_IPOPT];
81 ✗ if (cflags) {
82 ✗ std::string opt(cflags);
83 std::string lower;
84 ✗ std::transform(opt.begin(), opt.end(), std::back_inserter(lower), ::tolower);
85
86 using LS = NLP::LinearSolverOption;
87 ✗ if (lower == "mumps") {
88 ✗ nlp_solver_settings.set(NLP::Option::LinearSolver, LS::MUMPS);
89 ✗ } else if (lower == "ma27") {
90 ✗ nlp_solver_settings.set(NLP::Option::LinearSolver, LS::MA27);
91 ✗ } else if (lower == "ma57") {
92 ✗ nlp_solver_settings.set(NLP::Option::LinearSolver, LS::MA57);
93 ✗ } else if (lower == "ma77") {
94 ✗ nlp_solver_settings.set(NLP::Option::LinearSolver, LS::MA77);
95 ✗ } else if (lower == "ma86") {
96 ✗ nlp_solver_settings.set(NLP::Option::LinearSolver, LS::MA86);
97 ✗ } else if (lower == "ma97") {
98 ✗ nlp_solver_settings.set(NLP::Option::LinearSolver, LS::MA97);
99 } else {
100 ✗ Log::warning("Unsupported linear solver option: %s", cflags);
101 }
102 }
103
104 // Maximum iterations
105 ✗ cflags = omc_flagValue[FLAG_IPOPT_MAX_ITER];
106 ✗ if (cflags) {
107 try {
108 ✗ nlp_solver_settings.set(NLP::Option::Iterations, std::stoi(cflags));
109 ✗ } catch (...) {
110 ✗ Log::warning("Invalid integer for Iterations: %s", cflags);
111 ✗ }
112 }
113
114 // Hessian option
115 ✗ cflags = omc_flagValue[FLAG_IPOPT_HESSE];
116 ✗ if (cflags) {
117 ✗ std::string opt(cflags);
118 std::string lower;
119 ✗ std::transform(opt.begin(), opt.end(), std::back_inserter(lower), ::tolower);
120
121 using H = NLP::HessianOption;
122 ✗ if (lower == "bfgs" || lower == "lbfgs") {
123 ✗ nlp_solver_settings.set(NLP::Option::Hessian, H::LBFGS);
124 ✗ } else if (lower == "const" || lower == "qp") {
125 ✗ nlp_solver_settings.set(NLP::Option::Hessian, H::Const);
126 ✗ } else if (lower == "exact") {
127 ✗ nlp_solver_settings.set(NLP::Option::Hessian, H::Exact);
128 } else {
129 ✗ Log::warning("Unsupported Hessian option: %s (use LBFGS, QP, or Exact)", cflags);
130 }
131 }
132 ✗ }
133
134 ✗ ExchangeJacobians::ExchangeJacobians(InfoGDOP& info) :
135 /* set OpenModelica Jacobian ptrs, allocate memory, initilization of A, B, C, D */
136 ✗ A(info,
137 ✗ info.data->callback->INDEX_JAC_A,
138 ✗ info.data->callback->initialAnalyticJacobianA),
139 ✗ B(info,
140 ✗ info.data->callback->INDEX_JAC_B,
141 ✗ info.data->callback->initialAnalyticJacobianB),
142 ✗ C(info,
143 ✗ info.data->callback->INDEX_JAC_C,
144 ✗ info.data->callback->initialAnalyticJacobianC,
145 ✗ info.mayer_exists ? info.x_size + static_cast<int>(info.lagrange_exists) : -1),
146 ✗ D(info,
147 ✗ info.data->callback->INDEX_JAC_D,
148 ✗ info.data->callback->initialAnalyticJacobianD,
149 -1,
150 ✗ info.mayer_exists ? C.sparsity.row_nnz(0) : 0) {}
151
152 ✗ ExchangeHessians::ExchangeHessians(InfoGDOP& info) :
153 ✗ A(info, info.exc_jac->A),
154 ✗ B(info, info.exc_jac->B),
155 ✗ C(info, info.exc_jac->C),
156 ✗ D(info, info.exc_jac->D) {}
157
158
159 } // namespace OpenModelica
160