Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 12.9% 11 / 0 / 85
Functions: 75.0% 3 / 0 / 4
Branches: 5.6% 3 / 0 / 54

OMCompiler/SimulationRuntime/c/simulation/solver/external_input.c
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 <string.h>
29 #include <setjmp.h>
30
31 #include "openmodelica.h"
32 #include "openmodelica_func.h"
33 #include "simulation_data.h"
34
35 #include "util/omc_error.h"
36 #include "util/omc_file.h"
37 #include "gc/omc_gc.h"
38 #include "util/read_csv.h"
39 #include "util/libcsv.h"
40 #include "util/read_matlab4.h"
41
42 #include "simulation/simulation_runtime.h"
43 #include "simulation/solver/solver_main.h"
44 #include "simulation/solver/model_help.h"
45 #include "simulation/options.h"
46
47 static inline void externalInputallocate2(DATA* data, const char *filename);
48
49 1 int externalInputallocate(DATA* data)
50 {
51 int i, j;
52 const char * csv_input_file_opt = NULL;
53 1 const char * csv_input_file = NULL;
54
55 1 csv_input_file_opt = (char*)omc_flagValue[FLAG_INPUT_CSV];
56
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 if(!csv_input_file_opt) {
57 1 data->simulationInfo->external_input.active = 0;
58 1 return 0;
59 }
60
61 // If '-inputPath' is specified, prefix the csv input file name with that path.
62 ✗ if (omc_flag[FLAG_INPUT_PATH]) {
63 ✗ GC_asprintf(&csv_input_file, "%s/%s", omc_flagValue[FLAG_INPUT_PATH], csv_input_file_opt);
64 }
65 else {
66 ✗ csv_input_file = csv_input_file_opt;
67 }
68
69 ✗ externalInputallocate2(data, csv_input_file);
70
71 ✗ if(OMC_ACTIVE_STREAM(OMC_LOG_SIMULATION))
72 {
73 printf("\nExternal Input");
74 printf("\n========================================================");
75 ✗ for(i = 0; i < data->simulationInfo->external_input.n; ++i){
76 ✗ printf("\nInput: t=%f \t", data->simulationInfo->external_input.t[i]);
77 ✗ for(j = 0; j < data->modelData->nInputVars; ++j){
78 ✗ printf("u%d(t)= %f \t",j+1,data->simulationInfo->external_input.u[i][j]);
79 }
80 }
81 printf("\n========================================================\n");
82 }
83
84 ✗ data->simulationInfo->external_input.i = 0;
85 ✗ return 0;
86 }
87
88
89
90 ✗ void externalInputallocate2(DATA* data, const char *filename){
91 int i, j, k;
92 ✗ struct csv_data *res = read_csv(filename);
93 char ** names;
94 int * indx;
95 ✗ const int nu = data->modelData->nInputVars;
96
97 ✗ if (NULL == res) {
98 ✗ fprintf(stderr, "Failed to read CSV-file %s", filename);
99 ✗ EXIT(1);
100 }
101
102 ✗ data->modelData->nInputVars = nu;
103 ✗ data->simulationInfo->external_input.n = res->numsteps;
104 ✗ data->simulationInfo->external_input.N = data->simulationInfo->external_input.n;
105
106 ✗ data->simulationInfo->external_input.u = (modelica_real**)calloc(data->simulationInfo->external_input.n+1, sizeof(modelica_real*));
107
108 ✗ names = (char**)malloc(nu * sizeof(char*));
109
110 /* One value per scalar input, inputs missing in the CSV file stay 0. */
111 ✗ for(i = 0; i<data->simulationInfo->external_input.n; ++i){
112 ✗ data->simulationInfo->external_input.u[i] = (modelica_real*)calloc(nu, sizeof(modelica_real));
113 }
114
115 ✗ data->simulationInfo->external_input.t = (modelica_real*)calloc(data->simulationInfo->external_input.n+1, sizeof(modelica_real));
116
117 ✗ data->callback->inputNames(data, names);
118
119 ✗ indx = (int*)malloc(nu*sizeof(int));
120 ✗ for(i = 0; i < nu; ++i){
121 ✗ indx[i] = -1;
122 ✗ for(j = 0; j < res->numvars; ++j){
123 ✗ if(strcmp(names[i], res->variables[j]) == 0){
124 ✗ indx[i] = j;
125 ✗ break;
126 }
127 }
128 }
129
130 ✗ for(i = 0, k= 0; i < data->simulationInfo->external_input.n; ++i)
131 ✗ data->simulationInfo->external_input.t[i] = res->data[k++];
132
133 ✗ for(j = 0; j < nu; ++j){
134 ✗ if(indx[j] != -1){
135 ✗ k = (indx[j])*data->simulationInfo->external_input.n;
136 ✗ for(i = 0; i < data->simulationInfo->external_input.n; ++i){
137 ✗ data->simulationInfo->external_input.u[i][j] = res->data[k++];
138 }
139 }
140 }
141
142 ✗ omc_free_csv_reader(res);
143 ✗ free(names);
144 ✗ free(indx);
145 ✗ data->simulationInfo->external_input.active = data->simulationInfo->external_input.n > 0;
146 ✗ }
147
148 1 int externalInputFree(DATA* data)
149 {
150
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if(data->simulationInfo->external_input.active){
151 int j;
152
153 ✗ free(data->simulationInfo->external_input.t);
154 ✗ for(j = 0; j < data->simulationInfo->external_input.N; ++j)
155 ✗ free(data->simulationInfo->external_input.u[j]);
156 ✗ free(data->simulationInfo->external_input.u);
157 ✗ data->simulationInfo->external_input.active = 0;
158 }
159 1 return 0;
160 }
161
162
163 62 int externalInputUpdate(DATA* data)
164 {
165 double u1, u2;
166 double t, t1, t2;
167 long double dt;
168 int i;
169
170
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62 times.
62 if(!data->simulationInfo->external_input.active){
171 return -1;
172 }
173
174 ✗ t = data->localData[0]->timeValue;
175 ✗ t1 = data->simulationInfo->external_input.t[data->simulationInfo->external_input.i];
176 ✗ t2 = data->simulationInfo->external_input.t[data->simulationInfo->external_input.i+1];
177
178 ✗ while(data->simulationInfo->external_input.i > 0 && t < t1){
179 ✗ --data->simulationInfo->external_input.i;
180 ✗ t1 = data->simulationInfo->external_input.t[data->simulationInfo->external_input.i];
181 ✗ t2 = data->simulationInfo->external_input.t[data->simulationInfo->external_input.i+1];
182 }
183
184 while(t > t2
185 ✗ && data->simulationInfo->external_input.i+1 < (data->simulationInfo->external_input.n-1)){
186 ✗ ++data->simulationInfo->external_input.i;
187 ✗ t1 = data->simulationInfo->external_input.t[data->simulationInfo->external_input.i];
188 ✗ t2 = data->simulationInfo->external_input.t[data->simulationInfo->external_input.i+1];
189 }
190
191 ✗ if(t == t1){
192 ✗ for(i = 0; i < data->modelData->nInputVars; ++i){
193 ✗ data->simulationInfo->inputVars[i] = data->simulationInfo->external_input.u[data->simulationInfo->external_input.i][i];
194 }
195 return 1;
196 ✗ }else if(t == t2){
197 ✗ for(i = 0; i < data->modelData->nInputVars; ++i){
198 ✗ data->simulationInfo->inputVars[i] = data->simulationInfo->external_input.u[data->simulationInfo->external_input.i+1][i];
199 }
200 return 1;
201 }
202
203 ✗ dt = (data->simulationInfo->external_input.t[data->simulationInfo->external_input.i+1] - data->simulationInfo->external_input.t[data->simulationInfo->external_input.i]);
204 ✗ for(i = 0; i < data->modelData->nInputVars; ++i){
205 ✗ u1 = data->simulationInfo->external_input.u[data->simulationInfo->external_input.i][i];
206 ✗ u2 = data->simulationInfo->external_input.u[data->simulationInfo->external_input.i+1][i];
207
208 ✗ if(u1 != u2){
209 ✗ data->simulationInfo->inputVars[i] = (u1*(dt+t1-t)+(t-t1)*u2)/dt;
210 }else{
211 ✗ data->simulationInfo->inputVars[i] = u1;
212 }
213 }
214 return 0;
215 }
216
217