]> gerrit.simantics Code Review - simantics/fmil.git/blob - org.simantics.fmil.core/native/FMILibrary/Test/FMI2/fmi2_import_cs_test.c
Add FMILibrary-2.0.3 to org.simantics.fmil.core\native.
[simantics/fmil.git] / org.simantics.fmil.core / native / FMILibrary / Test / FMI2 / fmi2_import_cs_test.c
1 /*\r
2     Copyright (C) 2012 Modelon AB\r
3 \r
4     This program is free software: you can redistribute it and/or modify\r
5     it under the terms of the BSD style license.\r
6 \r
7     This program is distributed in the hope that it will be useful,\r
8     but WITHOUT ANY WARRANTY; without even the implied warranty of\r
9     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
10     FMILIB_License.txt file for more details.\r
11 \r
12     You should have received a copy of the FMILIB_License.txt file\r
13     along with this program. If not, contact Modelon AB <http://www.modelon.com>.\r
14 */\r
15 \r
16 #include <stdio.h>\r
17 #include <stdlib.h>\r
18 #include <stdarg.h>\r
19 \r
20 #include "config_test.h"\r
21 \r
22 #include <fmilib.h>\r
23 #include <JM/jm_portability.h>\r
24 \r
25 \r
26 #define BUFFER 1000\r
27 \r
28 void importlogger(jm_callbacks* c, jm_string module, jm_log_level_enu_t log_level, jm_string message)\r
29 {\r
30         printf("module = %s, log level = %s: %s\n", module, jm_log_level_to_string(log_level), message);\r
31 }\r
32 \r
33 /* Logger function used by the FMU internally */\r
34 \r
35 void fmilogger(fmi2_component_t c, fmi2_string_t instanceName, fmi2_status_t status, fmi2_string_t category, fmi2_string_t message, ...)\r
36 {\r
37     /* int len;\r
38         char msg[BUFFER]; */\r
39         va_list argp;   \r
40         va_start(argp, message);\r
41         /* len = jm_vsnprintf(msg, BUFFER, message, argp); */\r
42         fmi2_log_forwarding_v(c, instanceName, status, category, message, argp);\r
43         va_end(argp);\r
44 }\r
45 \r
46 void do_exit(int code)\r
47 {\r
48         printf("Press 'Enter' to exit\n");\r
49         /* getchar(); */\r
50         exit(code);\r
51 }\r
52 \r
53 int test_simulate_cs(fmi2_import_t* fmu)\r
54 {\r
55         fmi2_status_t fmistatus;\r
56         jm_status_enu_t jmstatus;\r
57 \r
58         fmi2_string_t instanceName = "Test CS model instance";\r
59         fmi2_string_t fmuGUID;\r
60         fmi2_string_t fmuLocation = "";\r
61         fmi2_boolean_t visible = fmi2_false;\r
62         fmi2_real_t relativeTol = 1e-4;\r
63 /*      fmi2_boolean_t loggingOn = fmi2_true; */\r
64         \r
65         /* fmi2_real_t simulation_results[] = {-0.001878, -1.722275}; */\r
66         fmi2_real_t simulation_results[] = {0.0143633,   -1.62417};\r
67         fmi2_value_reference_t compare_real_variables_vr[] = {0, 1};\r
68         size_t k;\r
69 \r
70         fmi2_real_t tstart = 0.0;\r
71         fmi2_real_t tcur = tstart;\r
72         fmi2_real_t hstep = 0.1;\r
73         fmi2_real_t tend = 2.0;\r
74         fmi2_boolean_t StopTimeDefined = fmi2_false;\r
75 \r
76         if (sizeof(compare_real_variables_vr)/sizeof(fmi2_value_reference_t) != sizeof(simulation_results)/sizeof(fmi2_real_t)) {\r
77                 printf("Number of simulation values and reference values are different\n");\r
78                 do_exit(CTEST_RETURN_FAIL);\r
79         }\r
80 \r
81         printf("Version returned from FMU:   %s\n", fmi2_import_get_version(fmu));\r
82         printf("Platform type returned:      %s\n", fmi2_import_get_types_platform(fmu));\r
83 \r
84         fmuGUID = fmi2_import_get_GUID(fmu);\r
85     printf("GUID:      %s\n", fmuGUID);\r
86 \r
87 \r
88     jmstatus = fmi2_import_instantiate(fmu, instanceName, fmi2_cosimulation, fmuLocation, visible);\r
89         if (jmstatus == jm_status_error) {\r
90                 printf("fmi2_import_instantiate failed\n");\r
91                 do_exit(CTEST_RETURN_FAIL);\r
92         }\r
93 \r
94         fmistatus = fmi2_import_setup_experiment(fmu, fmi2_true,\r
95             relativeTol, tstart, StopTimeDefined, tend);\r
96     if(fmistatus != fmi2_status_ok) {\r
97         printf("fmi2_import_setup_experiment failed\n");\r
98         do_exit(CTEST_RETURN_FAIL);\r
99     }\r
100 \r
101         fmistatus = fmi2_import_enter_initialization_mode(fmu);\r
102     if(fmistatus != fmi2_status_ok) {\r
103         printf("fmi2_import_enter_initialization_mode failed\n");\r
104         do_exit(CTEST_RETURN_FAIL);\r
105     }\r
106 \r
107         fmistatus = fmi2_import_exit_initialization_mode(fmu);\r
108     if(fmistatus != fmi2_status_ok) {\r
109         printf("fmi2_import_exit_initialization_mode failed\n");\r
110         do_exit(CTEST_RETURN_FAIL);\r
111     }        \r
112 \r
113         tcur = tstart;\r
114         printf("%10s %10s\n", "Ball height", "Ball speed");\r
115         while (tcur < tend) {\r
116                 fmi2_boolean_t newStep = fmi2_true;\r
117 #if 0 /* Prints a real value.. */\r
118                 fmi2_real_t rvalue;\r
119                 fmi2_value_reference_t vr = 0;\r
120 \r
121                 fmistatus = fmi2_import_get_real(fmu, &vr, 1, &rvalue);\r
122                 printf("rvalue = %f\n", rvalue);\r
123 #endif \r
124                 fmistatus = fmi2_import_do_step(fmu, tcur, hstep, newStep);\r
125 \r
126                 for (k = 0; k < sizeof(compare_real_variables_vr)/sizeof(fmi2_value_reference_t); k++) {\r
127                         fmi2_value_reference_t vr = compare_real_variables_vr[k];\r
128                         fmi2_real_t rvalue;\r
129                         fmistatus = fmi2_import_get_real(fmu, &vr, 1, &rvalue);\r
130                 }\r
131                 {\r
132                         fmi2_real_t val[2];\r
133                         fmi2_import_get_real(fmu, compare_real_variables_vr, 2, val);\r
134                         printf("%10g %10g\n", val[0],val[1]);\r
135                 }\r
136 \r
137                 tcur += hstep;\r
138         }\r
139 \r
140         printf("Simulation finished. Checking results\n");\r
141 \r
142         /* Validate result */\r
143         for (k = 0; k < sizeof(compare_real_variables_vr)/sizeof(fmi2_value_reference_t); k++) {\r
144                 fmi2_value_reference_t vr = compare_real_variables_vr[k];\r
145                 fmi2_real_t rvalue;\r
146                 fmi2_real_t res;        \r
147                 fmistatus = fmi2_import_get_real(fmu, &vr, 1, &rvalue);\r
148                 res = rvalue - simulation_results[k];\r
149                 res = res > 0 ? res: -res; /* Take abs */\r
150                 if (res > 3e-3) {\r
151                         printf("Simulation results is wrong!\n");\r
152                         printf("State [%u]  %g != %g, |res| = %g\n", (unsigned)k, rvalue, simulation_results[k], res);\r
153                         printf("\n");\r
154                         do_exit(CTEST_RETURN_FAIL);\r
155                 }\r
156         }\r
157 \r
158         fmistatus = fmi2_import_terminate(fmu);\r
159 \r
160         fmi2_import_free_instance(fmu);\r
161 \r
162         return 0;\r
163 }\r
164 \r
165 int main(int argc, char *argv[])\r
166 {\r
167         fmi2_callback_functions_t callBackFunctions;\r
168         const char* FMUPath;\r
169         const char* tmpPath;\r
170         jm_callbacks callbacks;\r
171         fmi_import_context_t* context;\r
172         fmi_version_enu_t version;\r
173         jm_status_enu_t status;\r
174         int k;\r
175 \r
176         fmi2_import_t* fmu;     \r
177 \r
178         if(argc < 3) {\r
179                 printf("Usage: %s <fmu_file> <temporary_dir>\n", argv[0]);\r
180                 do_exit(CTEST_RETURN_FAIL);\r
181         } \r
182         for (k = 0; k < argc; k ++)\r
183                 printf("argv[%d] = %s\n", k, argv[k]);\r
184 \r
185         FMUPath = argv[1];\r
186         tmpPath = argv[2];\r
187 \r
188 \r
189         callbacks.malloc = malloc;\r
190     callbacks.calloc = calloc;\r
191     callbacks.realloc = realloc;\r
192     callbacks.free = free;\r
193     callbacks.logger = importlogger;\r
194         callbacks.log_level = jm_log_level_debug;\r
195     callbacks.context = 0;\r
196 \r
197 #ifdef FMILIB_GENERATE_BUILD_STAMP\r
198         printf("Library build stamp:\n%s\n", fmilib_get_build_stamp());\r
199 #endif\r
200 \r
201         context = fmi_import_allocate_context(&callbacks);\r
202 \r
203         version = fmi_import_get_fmi_version(context, FMUPath, tmpPath);\r
204 \r
205         if(version != fmi_version_2_0_enu) {\r
206                 printf("The code only supports version 2.0\n");\r
207                 do_exit(CTEST_RETURN_FAIL);\r
208         }\r
209 \r
210         fmu = fmi2_import_parse_xml(context, tmpPath, 0);\r
211 \r
212         if(!fmu) {\r
213                 printf("Error parsing XML, exiting\n");\r
214                 do_exit(CTEST_RETURN_FAIL);\r
215         }\r
216         \r
217         if(fmi2_import_get_fmu_kind(fmu) == fmi2_fmu_kind_me) {\r
218                 printf("Only CS 2.0 is supported by this code\n");\r
219                 do_exit(CTEST_RETURN_FAIL);\r
220         }\r
221 \r
222         callBackFunctions.logger = fmi2_log_forwarding;\r
223         callBackFunctions.allocateMemory = calloc;\r
224         callBackFunctions.freeMemory = free;\r
225         callBackFunctions.componentEnvironment = fmu;\r
226 \r
227         status = fmi2_import_create_dllfmu(fmu, fmi2_fmu_kind_cs, &callBackFunctions);\r
228         if (status == jm_status_error) {\r
229                 printf("Could not create the DLL loading mechanism(C-API) (error: %s).\n", fmi2_import_get_last_error(fmu));\r
230                 do_exit(CTEST_RETURN_FAIL);\r
231         }\r
232 \r
233         test_simulate_cs(fmu);\r
234 \r
235         fmi2_import_destroy_dllfmu(fmu);\r
236 \r
237         fmi2_import_free(fmu);\r
238         fmi_import_free_context(context);\r
239         \r
240         printf("Everything seems to be OK since you got this far=)!\n");\r
241 \r
242         do_exit(CTEST_RETURN_SUCCESS);\r
243 \r
244         return 0;\r
245 }\r
246 \r
247 \r