Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 3 / 0 / 3
Functions: 100.0% 1 / 0 / 1
Branches: 50.0% 1 / 0 / 2

OMCompiler/SimulationRuntime/c/simulation/solver/model_help.h
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 #ifndef MODEL_HELP_H
28 #define MODEL_HELP_H
29 #include "../../omc_dll.h"
30
31 #include <math.h>
32
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36
37 #include "../../simulation_data.h"
38
39 DLLDataDirection extern int maxEventIterations;
40 DLLDataDirection extern double linearSparseSolverMaxDensity;
41 DLLDataDirection extern int linearSparseSolverMinSize;
42 DLLDataDirection extern double nonlinearSparseSolverMaxDensity;
43 DLLDataDirection extern int nonlinearSparseSolverMinSize;
44 DLLDataDirection extern double newtonXTol;
45 DLLDataDirection extern double newtonFTol;
46 DLLDataDirection extern int newtonMaxSteps;
47 DLLDataDirection extern int maxJacUpdate[4];
48 DLLDataDirection extern double maxStepFactor;
49 DLLDataDirection extern double steadyStateTol;
50 DLLDataDirection extern const size_t SIZERINGBUFFER;
51 DLLDataDirection extern int compiledInDAEMode;
52 DLLDataDirection extern int compiledWithSymSolver;
53 DLLDataDirection extern double numericalDifferentiationDeltaXlinearize;
54 DLLDataDirection extern double numericalDifferentiationDeltaXsolver;
55 DLLDataDirection extern double homAdaptBend;
56 DLLDataDirection extern double homHEps;
57 DLLDataDirection extern int homMaxLambdaSteps;
58 DLLDataDirection extern int homMaxNewtonSteps;
59 DLLDataDirection extern int homMaxTries;
60 DLLDataDirection extern double homTauDecreasingFactor;
61 DLLDataDirection extern double homTauDecreasingFactorPredictor;
62 DLLDataDirection extern double homTauIncreasingFactor;
63 DLLDataDirection extern double homTauIncreasingThreshold;
64 DLLDataDirection extern double homTauMax;
65 DLLDataDirection extern double homTauMin;
66 DLLDataDirection extern double homTauStart;
67 DLLDataDirection extern int homBacktraceStrategy;
68
69 /**
70 * @brief Unsigned finite-difference step for one column of a numerical Jacobian.
71 *
72 * DASKR's DMATD and IDA's ida_ls difference over `delta_h*max(|y|,|h*y'|)`,
73 * floored at the unknown's error weight `1/wt = rtol*|y| + atol`. The floor is
74 * a tolerance, not a differencing step: an unknown below it is zero as far as
75 * the error control is concerned and its magnitude is no scale to difference
76 * over, but `1/wt` is `tolerance` times the nominal where the step wants
77 * `delta_h` times it. So take the nominal there instead.
78 *
79 * @param y Value of the unknown.
80 * @param hyprime Step size times its derivative.
81 * @param ewtInv Its error weight inverted, `rtol*|y| + atol`.
82 * @param nominal Its nominal value, scaled by -jacobianNominalFactor.
83 * @return double The step, unsigned.
84 */
85 28 static inline double numericalJacobianStep(double y, double hyprime, double ewtInv, double nominal)
86 {
87 28 const double scale = fmax(fabs(y), fabs(hyprime));
88
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 return numericalDifferentiationDeltaXsolver * (scale > ewtInv ? scale : fmax(ewtInv, nominal));
89 }
90
91 void allocModelDataVars(MODEL_DATA* modelData, modelica_boolean allocAlias, threadData_t* threadData);
92
93 void freeModelDataVars(MODEL_DATA* modelData);
94 void freeModelDataVarArrays(MODEL_DATA* modelData);
95
96 void scalarAllocArrayAttributes(MODEL_DATA* modelData);
97
98 void initializeDataStruc(DATA *data, threadData_t *threadData);
99
100 void deInitializeDataStruc(DATA *data);
101
102 void allocIndexMap(MODEL_DATA* modelData, SIMULATION_INFO* simulationInfo);
103
104 void updateDiscreteSystem(DATA *data, threadData_t *threadData);
105
106 void saveZeroCrossings(DATA *data, threadData_t *threadData);
107
108 void copyStartValuestoInitValues(DATA *data);
109
110 void printAllVars(DATA *data, int ringSegment, int stream);
111 void printRelations(DATA *data, int stream);
112 void printZeroCrossings(DATA *data, int stream);
113 void printParameters(DATA *data, int stream);
114 void printSparseStructure(SPARSE_PATTERN *sparsePattern, int sizeRows, int sizeCols, int stream, const char*);
115 modelica_boolean sparsitySanityCheck(SPARSE_PATTERN *sparsePattern, int nlsSize, int stream);
116
117 void overwriteOldSimulationData(DATA *data);
118 void continueSimulationData(DATA *data);
119 void copyRingBufferSimulationData(DATA *data, threadData_t *threadData, SIMULATION_DATA **destData, RINGBUFFER* destRing);
120 void printRingBufferSimulationData(RINGBUFFER* rb, DATA* data);
121
122 void restoreExtrapolationDataOld(DATA *data);
123
124 void setAllVarsToStart(SIMULATION_DATA *simulationData, const SIMULATION_INFO *simulationInfo, const MODEL_DATA *modelData);
125 void setAllParamsToStart(SIMULATION_INFO *simulationInfo, const MODEL_DATA *modelData);
126
127 void restoreOldValues(DATA *data);
128
129 void storePreValues(DATA *data);
130
131 void updateRelationsPre(DATA *data);
132
133 modelica_boolean checkRelations(DATA *data);
134
135 void printHysteresisRelations(DATA *data);
136 void activateHysteresis(DATA* data);
137 void storeRelations(DATA* data);
138 void setZCtol(double relativeTol);
139
140 int getNextSampleTimeFMU(DATA *data, double *nextSampleEvent);
141 void updateNextSampleEvent(DATA *data, threadData_t *threadData);
142
143 void storeOldValues(DATA *data);
144
145 modelica_integer _event_integer(modelica_real x, modelica_integer index, DATA *data);
146 modelica_real _event_floor(modelica_real x, modelica_integer index, DATA *data);
147 modelica_real _event_ceil(modelica_real x, modelica_integer index, DATA *data);
148 modelica_integer _event_mod_integer(modelica_integer x1, modelica_integer x2, modelica_integer index, DATA *data, threadData_t *threadData);
149 modelica_real _event_mod_real(modelica_real x1, modelica_real x2, modelica_integer index, DATA *data, threadData_t *threadData);
150 modelica_integer _event_div_integer(modelica_integer x1, modelica_integer x2, modelica_integer index, DATA *data, threadData_t *threadData);
151 modelica_real _event_div_real(modelica_real x1, modelica_real x2, modelica_integer index, DATA *data, threadData_t *threadData);
152
153 /* functions used for relation which
154 * are not used as zero-crossings
155 */
156 static inline modelica_boolean Less(double a, double b) { return a < b; }
157 static inline modelica_boolean LessEq(double a, double b) { return a <= b; }
158 static inline modelica_boolean Greater(double a, double b) { return a > b; }
159 static inline modelica_boolean GreaterEq(double a, double b) { return a >= b; }
160
161 /* functions used to evaluate relation in
162 * zero-crossing with hysteresis effect
163 */
164 modelica_boolean LessZC(double a, double b, double a_nominal, double b_nominal, modelica_boolean);
165 modelica_boolean LessEqZC(double a, double b, double a_nominal, double b_nominal, modelica_boolean);
166 modelica_boolean GreaterZC(double a, double b, double a_nominal, double b_nominal, modelica_boolean);
167 modelica_boolean GreaterEqZC(double a, double b, double a_nominal, double b_nominal, modelica_boolean);
168
169
170 /**
171 * @brief Relation function for compare functions.
172 *
173 * Used for cases where exp1 or exp2 are discrete.
174 *
175 * Two cases:
176 * 1. During initialization or discrete calls or not continuous mode: Use op_w(exp1,exp2) and update relations[index] and return result in res.
177 * 2. Else (Not discrete call or in continuous mode) : Only return pre-value of relation in res
178 *
179 * @param[in] data Pointer to data struct
180 * @param[out] res Gets overwritten with result of relation.
181 * @param[in] exp1 First value (left side of relation).
182 * @param[in] exp2 Second value (right side of relation).
183 * @param[in] index Index of relation in data->simulationInfo->relations.
184 * @param[in] op_w Comparison function, e.g. Less.
185 */
186 static inline void relation(DATA* data, modelica_boolean* res, double exp1, double exp2, int index, modelica_boolean(*op_w)(double, double))
187 {
188 if(data->simulationInfo->initial || !(data->simulationInfo->discreteCall == 0 || data->simulationInfo->solveContinuous) )
189 {
190 *res = op_w(exp1,exp2);
191 data->simulationInfo->relations[index] = *res;
192 }
193 else
194 {
195 *res = data->simulationInfo->relationsPre[index];
196 }
197 }
198
199 /**
200 * @brief Relation hysteresis function for compare functions.
201 *
202 * Used for cases where exp1 and exp2 are continuous.
203 *
204 * Three cases:
205 * 1. During initialization: Use op_w(exp1,exp2) and update relations[index] and return result in res.
206 * 2. No descrete call or in continuous case: Only return pre-value of relation in res
207 * 3. Else (events, zero-crossing): Use op_w_zc(exp1,exp2,...) to update relations[index] and return result in res.
208 *
209 * @param[in] data Pointer to data struct
210 * @param[out] res Gets overwritten with result of relation.
211 * @param[in] exp1 First value (left side of relation).
212 * @param[in] exp2 Second value (right side of relation).
213 * @param[in] index Index of relation in data->simulationInfo->relations.
214 * @param[in] op_w Comparison function, e.g. Less.
215 * @param[in] op_w_zc Matching comparison function of op_w for zero-crossing, e.g. LessZC.
216 */
217 static inline void relationhysteresis(DATA* data, modelica_boolean* res, double exp1, double exp2, double exp1_nominal, double exp2_nominal, int index, modelica_boolean(*op_w)(double, double), modelica_boolean(*op_w_zc)(double, double, double, double, modelica_boolean))
218 {
219 if(data->simulationInfo->initial)
220 {
221 *res = op_w(exp1,exp2);
222 data->simulationInfo->relations[index] = *res;
223 }
224 else if(data->simulationInfo->discreteCall == 0 || data->simulationInfo->solveContinuous)
225 {
226 *res = data->simulationInfo->relationsPre[index];
227 }
228 else
229 {
230 *res = op_w_zc(exp1, exp2, exp1_nominal, exp2_nominal, data->simulationInfo->storedRelations[index]);
231 data->simulationInfo->relations[index] = *res;
232 }
233 }
234
235 DLLDataDirection extern int measure_time_flag;
236
237 #ifdef __cplusplus
238 }
239 #endif
240
241 #endif
242