2 Copyright (C) 2012 Modelon AB
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the BSD style license.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 FMILIB_License.txt file for more details.
12 You should have received a copy of the FMILIB_License.txt file
13 along with this program. If not, contact Modelon AB <http://www.modelon.com>.
19 #include <JM/jm_named_ptr.h>
20 #include <FMI2/fmi2_types.h>
21 #include <FMI2/fmi2_functions.h>
22 #include <FMI2/fmi2_enums.h>
\r
23 #include <FMI2/fmi2_capi.h>
25 #include "fmi2_import_impl.h"
26 #include "fmi2_import_variable_list_impl.h"
29 static const char* module = "FMILIB";
31 /*#include "fmi2_import_vendor_annotations_impl.h"
32 #include "fmi2_import_parser.h"
34 fmi2_import_t* fmi2_import_allocate(jm_callbacks* cb) {
35 fmi2_import_t* fmu = (fmi2_import_t*)cb->calloc(1, sizeof(fmi2_import_t));
37 if(!fmu || (jm_vector_init(char)(&fmu->logMessageBufferCoded,JM_MAX_ERROR_MESSAGE_SIZE,cb) < JM_MAX_ERROR_MESSAGE_SIZE)) {
38 jm_log_fatal(cb, module, "Could not allocate memory");
39 if(fmu) cb->free(fmu);
43 fmu->resourceLocation = 0;
46 fmu->md = fmi2_xml_allocate_model_description(cb);
47 jm_vector_init(char)(&fmu->logMessageBufferExpanded,0,cb);
57 const char* fmi2_import_get_last_error(fmi2_import_t* fmu) {
\r
58 return jm_get_last_error(fmu->callbacks);
\r
61 fmi2_import_t* fmi2_import_parse_xml( fmi_import_context_t* context, const char* dirPath, fmi2_xml_callbacks_t* xml_callbacks) {
63 char absPath[FILENAME_MAX + 2];
64 fmi2_import_t* fmu = 0;
65 int configuration = 0;
67 if(strlen(dirPath) + 20 > FILENAME_MAX) {
68 jm_log_fatal(context->callbacks, module, "Directory path for FMU is too long");
72 xmlPath = fmi_import_get_model_description_path(dirPath, context->callbacks);
73 fmu = fmi2_import_allocate(context->callbacks);
76 context->callbacks->free(xmlPath);
80 if(jm_get_dir_abspath(context->callbacks, dirPath, absPath, FILENAME_MAX + 2)) {
\r
81 size_t len = strlen(absPath);
\r
82 strcpy(absPath + len, FMI_FILE_SEP "resources");
\r
83 fmu->resourceLocation = fmi_import_create_URL_from_abs_path(context->callbacks, absPath);
\r
85 fmu->dirPath = context->callbacks->malloc(strlen(dirPath) + 1);
86 if (!fmu->dirPath || !fmu->resourceLocation) {
87 jm_log_fatal( context->callbacks, "FMILIB", "Could not allocated memory");
88 fmi2_import_free(fmu);
89 context->callbacks->free(xmlPath);
92 strcpy(fmu->dirPath, dirPath);
94 jm_log_verbose( context->callbacks, "FMILIB", "Parsing model description XML");
96 /* convert the import configuration to the xml configuration */
97 if (context->configuration & FMI_IMPORT_NAME_CHECK) {
98 configuration |= FMI2_XML_NAME_CHECK;
101 if (fmi2_xml_parse_model_description( fmu->md, xmlPath, xml_callbacks, configuration)) {
102 fmi2_import_free(fmu);
105 context->callbacks->free(xmlPath);
108 jm_log_verbose( context->callbacks, "FMILIB", "Parsing finished successfully");
113 void fmi2_import_free(fmi2_import_t* fmu) {
118 jm_log_verbose( fmu->callbacks, "FMILIB", "Releasing allocated library resources");
120 fmi2_import_destroy_dllfmu(fmu);
\r
121 fmi2_xml_free_model_description(fmu->md);
122 jm_vector_free_data(char)(&fmu->logMessageBufferCoded);
123 jm_vector_free_data(char)(&fmu->logMessageBufferExpanded);
125 cb->free(fmu->resourceLocation);
126 cb->free(fmu->dirPath);
130 int fmi2_import_check_has_FMU(fmi2_import_t* fmu) {
132 jm_log_error(fmu->callbacks, module,"No FMU is loaded");
138 const char* fmi2_import_get_model_name(fmi2_import_t* fmu) {
139 if(!fmi2_import_check_has_FMU(fmu)) return 0;
141 return fmi2_xml_get_model_name(fmu->md);
144 unsigned int fmi2_import_get_capability(fmi2_import_t* fmu , fmi2_capabilities_enu_t id) {
145 if(!fmi2_import_check_has_FMU(fmu)) return 0;
147 return fmi2_xml_get_capability(fmu->md, id);
151 const char* fmi2_import_get_model_identifier_ME(fmi2_import_t* fmu) {
152 if(!fmi2_import_check_has_FMU(fmu)) return 0;
154 return fmi2_xml_get_model_identifier_ME(fmu->md);
157 const char* fmi2_import_get_model_identifier_CS(fmi2_import_t* fmu) {
158 if(!fmi2_import_check_has_FMU(fmu)) return 0;
160 return fmi2_xml_get_model_identifier_CS(fmu->md);
163 const char* fmi2_import_get_GUID(fmi2_import_t* fmu){
164 if(!fmi2_import_check_has_FMU(fmu)) return 0;
166 return fmi2_xml_get_GUID(fmu->md);
169 const char* fmi2_import_get_description(fmi2_import_t* fmu) {
170 if(!fmi2_import_check_has_FMU(fmu)) return 0;
172 return fmi2_xml_get_description(fmu->md);
175 const char* fmi2_import_get_author(fmi2_import_t* fmu) {
176 if(!fmi2_import_check_has_FMU(fmu)) return 0;
178 return fmi2_xml_get_author(fmu->md);
181 const char* fmi2_import_get_license(fmi2_import_t* fmu) {
182 if(!fmi2_import_check_has_FMU(fmu)) return 0;
184 return fmi2_xml_get_license(fmu->md);
186 const char* fmi2_import_get_copyright(fmi2_import_t* fmu) {
187 if(!fmi2_import_check_has_FMU(fmu)) return 0;
189 return fmi2_xml_get_copyright(fmu->md);
192 const char* fmi2_import_get_model_standard_version(fmi2_import_t* fmu) {
193 if(!fmi2_import_check_has_FMU(fmu)) return 0;
195 return fmi2_xml_get_model_standard_version(fmu->md);
198 const char* fmi2_import_get_model_version(fmi2_import_t* fmu) {
199 if(!fmi2_import_check_has_FMU(fmu)) return 0;
201 return fmi2_xml_get_model_version(fmu->md);
204 const char* fmi2_import_get_generation_tool(fmi2_import_t* fmu) {
205 if(!fmi2_import_check_has_FMU(fmu)) return 0;
207 return fmi2_xml_get_generation_tool(fmu->md);
210 const char* fmi2_import_get_generation_date_and_time(fmi2_import_t* fmu) {
211 if(!fmi2_import_check_has_FMU(fmu)) return 0;
213 return fmi2_xml_get_generation_date_and_time(fmu->md);
216 fmi2_variable_naming_convension_enu_t fmi2_import_get_naming_convention(fmi2_import_t* fmu) {
218 jm_log_error(fmu->callbacks, module,"No FMU is loaded");
219 return fmi2_naming_enu_unknown;
221 return fmi2_xml_get_naming_convention(fmu->md);
224 size_t fmi2_import_get_number_of_continuous_states(fmi2_import_t* fmu) {
225 if(!fmi2_import_check_has_FMU(fmu)) return 0;
227 return fmi2_xml_get_number_of_continuous_states(fmu->md);
230 size_t fmi2_import_get_number_of_event_indicators(fmi2_import_t* fmu) {
231 if(!fmi2_import_check_has_FMU(fmu)) return 0;
233 return fmi2_xml_get_number_of_event_indicators(fmu->md);
236 double fmi2_import_get_default_experiment_start(fmi2_import_t* fmu) {
237 if(!fmi2_import_check_has_FMU(fmu)) return 0;
239 return fmi2_xml_get_default_experiment_start(fmu->md);
242 double fmi2_import_get_default_experiment_stop(fmi2_import_t* fmu) {
243 if(!fmi2_import_check_has_FMU(fmu)) return 0;
245 return fmi2_xml_get_default_experiment_stop(fmu->md);
248 double fmi2_import_get_default_experiment_tolerance(fmi2_import_t* fmu) {
249 if(!fmi2_import_check_has_FMU(fmu)) return 0;
251 return fmi2_xml_get_default_experiment_tolerance(fmu->md);
254 double fmi2_import_get_default_experiment_step(fmi2_import_t* fmu) {
255 if(!fmi2_import_check_has_FMU(fmu)) return 0;
257 return fmi2_xml_get_default_experiment_step(fmu->md);
260 fmi2_import_unit_definitions_t* fmi2_import_get_unit_definitions(fmi2_import_t* fmu) {
261 if(!fmi2_import_check_has_FMU(fmu)) return 0;
263 return fmi2_xml_get_unit_definitions(fmu->md);
266 unsigned int fmi2_import_get_unit_definitions_number(fmi2_import_unit_definitions_t* ud) {
267 return fmi2_xml_get_unit_definitions_number(ud);
270 fmi2_import_type_definitions_t* fmi2_import_get_type_definitions(fmi2_import_t* fmu) {
271 if(!fmi2_import_check_has_FMU(fmu)) return 0;
273 return fmi2_xml_get_type_definitions(fmu->md);
276 fmi2_import_variable_list_t* fmi2_import_vector_to_varlist(fmi2_import_t* fmu, jm_vector(jm_voidp)* vars) {
277 fmi2_import_variable_list_t* vl;
281 nv = jm_vector_get_size(jm_voidp)(vars);
282 vl = fmi2_import_alloc_variable_list(fmu, nv);
284 for(i = 0; i< nv; i++) {
285 jm_vector_set_item(jm_voidp)(&vl->variables, i, jm_vector_get_item(jm_voidp)(vars, i));
291 /* Get the list of all the variables in the model */
292 /* 0 - original order as found in the XML file; 1 - sorted alfabetically by variable name; 2 sorted by types/value references. */
293 fmi2_import_variable_list_t* fmi2_import_get_variable_list(fmi2_import_t* fmu, int sortOrder) {
294 if(!fmi2_import_check_has_FMU(fmu)) return 0;
297 return fmi2_import_vector_to_varlist(fmu, fmi2_xml_get_variables_original_order(fmu->md));
299 fmi2_import_variable_list_t* vl;
301 jm_vector(jm_named_ptr)* vars = fmi2_xml_get_variables_alphabetical_order(fmu->md);
303 nv = jm_vector_get_size(jm_named_ptr)(vars);
304 vl = fmi2_import_alloc_variable_list(fmu, nv);
306 for(i = 0; i< nv; i++) {
307 jm_vector_set_item(jm_voidp)(&vl->variables, i, jm_vector_get_item(jm_named_ptr)(vars, i).ptr);
312 return fmi2_import_vector_to_varlist(fmu, fmi2_xml_get_variables_vr_order(fmu->md));
319 fmi2_fmu_kind_enu_t fmi2_import_get_fmu_kind(fmi2_import_t* fmu) {
320 return fmi2_xml_get_fmu_kind(fmu->md);
323 size_t fmi2_import_get_vendors_num(fmi2_import_t* fmu){
324 if(!fmi2_import_check_has_FMU(fmu)) return 0;
326 return fmi2_xml_get_vendors_num(fmu->md);
329 const char* fmi2_import_get_vendor_name(fmi2_import_t* fmu, size_t index){
330 if(!fmi2_import_check_has_FMU(fmu)) return 0;
332 return fmi2_xml_get_vendor_name(fmu->md, index);
335 /** \brief Get the number of log categories defined in the XML */
336 size_t fmi2_import_get_log_categories_num(fmi2_import_t* fmu) {
337 if(!fmi2_import_check_has_FMU(fmu)) return 0;
339 return jm_vector_get_size(jm_string)(fmi2_xml_get_log_categories(fmu->md));
342 /** \brief Get the log category by index */
343 const char* fmi2_import_get_log_category(fmi2_import_t* fmu, size_t index) {
344 if(!fmi2_import_check_has_FMU(fmu)) return 0;
346 return jm_vector_get_item(jm_string)(fmi2_xml_get_log_categories(fmu->md), index);
349 /** \brief Get the log category description by index */
350 const char* fmi2_import_get_log_category_description(fmi2_import_t* fmu, size_t index) {
351 if(!fmi2_import_check_has_FMU(fmu)) return 0;
353 return jm_vector_get_item(jm_string)(fmi2_xml_get_log_category_descriptions(fmu->md), index);
356 /** \brief Get the number of source files for ME defined in the XML */
\r
357 size_t fmi2_import_get_source_files_me_num(fmi2_import_t* fmu) {
358 if(!fmi2_import_check_has_FMU(fmu)) return 0;
360 return jm_vector_get_size(jm_string)(fmi2_xml_get_source_files_me(fmu->md));
363 /** \brief Get the ME source file by index */
\r
364 const char* fmi2_import_get_source_file_me(fmi2_import_t* fmu, size_t index) {
365 if(!fmi2_import_check_has_FMU(fmu)) return 0;
367 return jm_vector_get_item(jm_string)(fmi2_xml_get_source_files_me(fmu->md), index);
370 /** \brief Get the number of source files for CS defined in the XML */
\r
371 size_t fmi2_import_get_source_files_cs_num(fmi2_import_t* fmu) {
372 if(!fmi2_import_check_has_FMU(fmu)) return 0;
374 return jm_vector_get_size(jm_string)(fmi2_xml_get_source_files_cs(fmu->md));
377 /** \brief Get the CS source file by index */
\r
378 const char* fmi2_import_get_source_file_cs(fmi2_import_t* fmu, size_t index) {
379 if(!fmi2_import_check_has_FMU(fmu)) return 0;
381 return jm_vector_get_item(jm_string)(fmi2_xml_get_source_files_cs(fmu->md), index);
385 fmi2_import_variable_list_t* fmi2_import_get_outputs_list(fmi2_import_t* fmu) {
386 if(!fmi2_import_check_has_FMU(fmu)) return 0;
387 return fmi2_import_vector_to_varlist(fmu, fmi2_xml_get_outputs(fmi2_xml_get_model_structure(fmu->md)));
390 fmi2_import_variable_list_t* fmi2_import_get_derivatives_list(fmi2_import_t* fmu){
391 if(!fmi2_import_check_has_FMU(fmu)) return 0;
392 return fmi2_import_vector_to_varlist(fmu, fmi2_xml_get_derivatives(fmi2_xml_get_model_structure(fmu->md)));
395 fmi2_import_variable_list_t* fmi2_import_get_discrete_states_list(fmi2_import_t* fmu) {
396 if(!fmi2_import_check_has_FMU(fmu)) return 0;
397 return fmi2_import_vector_to_varlist(fmu, fmi2_xml_get_discrete_states(fmi2_xml_get_model_structure(fmu->md)));
400 fmi2_import_variable_list_t* fmi2_import_get_initial_unknowns_list(fmi2_import_t* fmu) {
401 if(!fmi2_import_check_has_FMU(fmu)) return 0;
402 return fmi2_import_vector_to_varlist(fmu, fmi2_xml_get_initial_unknowns(fmi2_xml_get_model_structure(fmu->md)));
405 void fmi2_import_get_outputs_dependencies(fmi2_import_t* fmu,size_t** startIndex, size_t** dependency, char** factorKind) {
406 fmi2_xml_model_structure_t* ms;
407 if(!fmi2_import_check_has_FMU(fmu)) {
411 ms = fmi2_xml_get_model_structure(fmu->md);
413 fmi2_xml_get_outputs_dependencies(ms, startIndex, dependency, factorKind);
416 void fmi2_import_get_derivatives_dependencies(fmi2_import_t* fmu,size_t** startIndex, size_t** dependency, char** factorKind) {
417 fmi2_xml_model_structure_t* ms;
418 if(!fmi2_import_check_has_FMU(fmu)) {
422 ms = fmi2_xml_get_model_structure(fmu->md);
424 fmi2_xml_get_derivatives_dependencies(ms, startIndex, dependency, factorKind);
427 void fmi2_import_get_discrete_states_dependencies(fmi2_import_t* fmu,size_t** startIndex, size_t** dependency, char** factorKind) {
428 fmi2_xml_model_structure_t* ms;
429 if(!fmi2_import_check_has_FMU(fmu)) {
433 ms = fmi2_xml_get_model_structure(fmu->md);
435 fmi2_xml_get_discrete_states_dependencies(ms, startIndex, dependency, factorKind);
438 void fmi2_import_get_initial_unknowns_dependencies(fmi2_import_t* fmu,size_t** startIndex, size_t** dependency, char** factorKind) {
439 fmi2_xml_model_structure_t* ms;
440 if(!fmi2_import_check_has_FMU(fmu)) {
444 ms = fmi2_xml_get_model_structure(fmu->md);
446 fmi2_xml_get_initial_unknowns_dependencies(ms, startIndex, dependency, factorKind);