/* Load FMI 1.0 Model Exchange functions */ static jm_status_enu_t fmi1_capi_load_me_fcn(fmi1_capi_t* fmu) { jm_status_enu_t jm_status = jm_status_success; jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Loading functions for the model exchange interface"); LOAD_DLL_FUNCTION(fmiGetModelTypesPlatform); LOAD_DLL_FUNCTION(fmiInstantiateModel); LOAD_DLL_FUNCTION(fmiFreeModelInstance); LOAD_DLL_FUNCTION(fmiSetTime); LOAD_DLL_FUNCTION(fmiSetContinuousStates); LOAD_DLL_FUNCTION(fmiCompletedIntegratorStep); LOAD_DLL_FUNCTION(fmiInitialize); LOAD_DLL_FUNCTION(fmiGetDerivatives); LOAD_DLL_FUNCTION(fmiGetEventIndicators); LOAD_DLL_FUNCTION(fmiEventUpdate); LOAD_DLL_FUNCTION(fmiGetContinuousStates); LOAD_DLL_FUNCTION(fmiGetNominalContinuousStates); LOAD_DLL_FUNCTION(fmiGetStateValueReferences); LOAD_DLL_FUNCTION(fmiTerminate); LOAD_DLL_FUNCTION(fmiGetVersion); LOAD_DLL_FUNCTION(fmiSetDebugLogging); LOAD_DLL_FUNCTION(fmiSetReal); LOAD_DLL_FUNCTION(fmiSetInteger); LOAD_DLL_FUNCTION(fmiSetBoolean); LOAD_DLL_FUNCTION(fmiSetString); LOAD_DLL_FUNCTION(fmiGetReal); LOAD_DLL_FUNCTION(fmiGetInteger); LOAD_DLL_FUNCTION(fmiGetBoolean); LOAD_DLL_FUNCTION(fmiGetString); return jm_status; }
jm_status_enu_t jm_rmdir(jm_callbacks* cb, const char* dir) { #ifdef WIN32 const char* fmt_cmd = "rmdir /s /q %s"; #else const char* fmt_cmd = "rm -rf %s"; #endif char * buf = (char*)cb->calloc(sizeof(char), strlen(dir)+strlen(fmt_cmd)+1); if(!cb) { cb = jm_get_default_callbacks(); } if(!buf) { jm_log_error(cb,module,"Could not allocate memory"); return jm_status_error; } sprintf(buf, fmt_cmd, dir);/*safe*/ #ifdef WIN32 { char* ch = buf+strlen(fmt_cmd) - 2; while(*ch) { if(*ch == '/') *ch = '\\'; ch++; } } #endif jm_log_verbose(cb,module,"Removing %s", dir); if(system(buf)) { jm_log_error(cb,module,"Error removing %s (%s)", dir, strerror(errno)); return jm_status_error; } cb->free(buf); return jm_status_success; }
int fmi2_xml_handle_InitialUnknowns(fmi2_xml_parser_context_t *context, const char* data) { if (!data) { jm_log_verbose(context->callbacks, module, "Parsing XML element InitialUnknowns"); /* reset handles for the elements that are specific under InitialUnknowns */ fmi2_xml_set_element_handle(context, "Unknown", FMI2_XML_ELM_ID(InitialUnknown)); } return 0; }
fmi1_import_t* fmi1_import_parse_xml( fmi_import_context_t* context, const char* dirPath) { char* xmlPath; char absPath[FILENAME_MAX + 2]; jm_callbacks* cb; fmi1_import_t* fmu; if(!context) return 0; cb = context->callbacks; xmlPath = fmi_import_get_model_description_path(dirPath, context->callbacks); fmu = fmi1_import_allocate(context->callbacks); if(!fmu) { context->callbacks->free(xmlPath); return 0; } jm_log_verbose( cb, "FMILIB", "Parsing model description XML"); if(fmi1_xml_parse_model_description( fmu->md, xmlPath)) { fmi1_import_free(fmu); cb->free(xmlPath); return 0; } cb->free(xmlPath); fmu->dirPath = (char*)cb->calloc(strlen(dirPath) + 1, sizeof(char)); if(jm_get_dir_abspath(cb, dirPath, absPath, FILENAME_MAX + 2)) { fmu->location = fmi_import_create_URL_from_abs_path(cb, absPath); } if ((fmu->dirPath == NULL) || (fmu->location == 0)){ jm_log_fatal( cb, "FMILIB", "Could not allocated memory"); fmi1_import_free(fmu); cb->free(xmlPath); return 0; } strcpy(fmu->dirPath, dirPath); jm_log_verbose( cb, "FMILIB", "Parsing finished successfully"); return fmu; }
fmi2_import_t* fmi2_import_parse_xml( fmi_import_context_t* context, const char* dirPath, fmi2_xml_callbacks_t* xml_callbacks) { char* xmlPath; char absPath[FILENAME_MAX + 2]; fmi2_import_t* fmu = 0; if(strlen(dirPath) + 20 > FILENAME_MAX) { jm_log_fatal(context->callbacks, module, "Directory path for FMU is too long"); return 0; } xmlPath = fmi_import_get_model_description_path(dirPath, context->callbacks); fmu = fmi2_import_allocate(context->callbacks); if(!fmu) { context->callbacks->free(xmlPath); return 0; } if(jm_get_dir_abspath(context->callbacks, dirPath, absPath, FILENAME_MAX + 2)) { size_t len = strlen(absPath); strcpy(absPath + len, FMI_FILE_SEP "resources"); fmu->resourceLocation = fmi_import_create_URL_from_abs_path(context->callbacks, absPath); } fmu->dirPath = context->callbacks->malloc(strlen(dirPath) + 1); if (!fmu->dirPath || !fmu->resourceLocation) { jm_log_fatal( context->callbacks, "FMILIB", "Could not allocated memory"); fmi2_import_free(fmu); context->callbacks->free(xmlPath); return 0; } strcpy(fmu->dirPath, dirPath); jm_log_verbose( context->callbacks, "FMILIB", "Parsing model description XML"); if(fmi2_xml_parse_model_description( fmu->md, xmlPath, xml_callbacks)) { fmi2_import_free(fmu); fmu = 0; } context->callbacks->free(xmlPath); if(fmu) jm_log_verbose( context->callbacks, "FMILIB", "Parsing finished successfully"); return fmu; }
/* Load FMI 2.0 Model Exchange functions */ static jm_status_enu_t fmi2_capi_load_me_fcn(fmi2_capi_t* fmu, unsigned int capabilities[]) { jm_status_enu_t jm_status = jm_status_success; jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Loading functions for the model exchange interface"); jm_status = fmi2_capi_load_common_fcn(fmu, capabilities); /* Getting and setting the internal FMU state */ /* typedef fmi2Status fmi2GetFMUstateTYPE (fmi2Component, fmi2FMUstate*); typedef fmi2Status fmi2SetFMUstateTYPE (fmi2Component, fmi2FMUstate); typedef fmi2Status fmi2FreeFMUstateTYPE (fmi2Component, fmi2FMUstate*); typedef fmi2Status fmi2SerializedFMUstateSizeTYPE(fmi2Component, fmi2FMUstate, size_t*); typedef fmi2Status fmi2SerializeFMUstateTYPE (fmi2Component, fmi2FMUstate, fmi2Byte[], size_t); typedef fmi2Status fmi2DeSerializeFMUstateTYPE (fmi2Component, const fmi2Byte[], size_t, fmi2FMUstate*); */ LOAD_DLL_FUNCTION_WITH_FLAG(fmi2GetFMUstate,fmi2_me_canGetAndSetFMUstate); LOAD_DLL_FUNCTION_WITH_FLAG(fmi2SetFMUstate,fmi2_me_canGetAndSetFMUstate); LOAD_DLL_FUNCTION_WITH_FLAG(fmi2FreeFMUstate,fmi2_me_canGetAndSetFMUstate); LOAD_DLL_FUNCTION_WITH_FLAG(fmi2SerializedFMUstateSize,fmi2_me_canSerializeFMUstate); LOAD_DLL_FUNCTION_WITH_FLAG(fmi2SerializeFMUstate,fmi2_me_canSerializeFMUstate); LOAD_DLL_FUNCTION_WITH_FLAG(fmi2DeSerializeFMUstate,fmi2_me_canSerializeFMUstate); /* Getting directional derivatives */ /* typedef fmi2Status fmi2GetDirectionalDerivativeTYPE(fmi2Component, const fmi2ValueReference[], size_t, const fmi2ValueReference[], size_t, const fmi2Real[], fmi2Real[]); */ LOAD_DLL_FUNCTION_WITH_FLAG(fmi2GetDirectionalDerivative,fmi2_me_providesDirectionalDerivatives); /* Enter and exit the different modes */ /* typedef fmi2Status fmi2EnterEventModeTYPE (fmi2Component); typedef fmi2Status fmi2NewDiscreteStatesTYPE (fmi2Component, fmi2EventInfo*); typedef fmi2Status fmi2EnterContinuousTimeModeTYPE(fmi2Component); typedef fmi2Status fmi2CompletedIntegratorStepTYPE(fmi2Component, fmi2Boolean, fmi2Boolean*, fmi2Boolean*);*/ LOAD_DLL_FUNCTION(fmi2EnterEventMode); LOAD_DLL_FUNCTION(fmi2NewDiscreteStates); LOAD_DLL_FUNCTION(fmi2EnterContinuousTimeMode); LOAD_DLL_FUNCTION(fmi2CompletedIntegratorStep); /* Providing independent variables and re-initialization of caching */ /*typedef fmi2Status fmi2SetTimeTYPE (fmi2Component, fmi2Real); typedef fmi2Status fmi2SetContinuousStatesTYPE(fmi2Component, const fmi2Real[], size_t);*/ LOAD_DLL_FUNCTION(fmi2SetTime); LOAD_DLL_FUNCTION(fmi2SetContinuousStates); /* Evaluation of the model equations */ /* typedef fmi2Status fmi2GetDerivativesTYPE (fmi2Component, fmi2Real[], size_t); typedef fmi2Status fmi2GetEventIndicatorsTYPE (fmi2Component, fmi2Real[], size_t); typedef fmi2Status fmi2GetContinuousStatesTYPE (fmi2Component, fmi2Real[], size_t); typedef fmi2Status fmi2GetNominalsOfContinuousStatesTYPE(fmi2Component, fmi2Real[], size_t);*/ LOAD_DLL_FUNCTION(fmi2GetDerivatives); LOAD_DLL_FUNCTION(fmi2GetEventIndicators); LOAD_DLL_FUNCTION(fmi2GetContinuousStates); LOAD_DLL_FUNCTION(fmi2GetNominalsOfContinuousStates); return jm_status; }
int fmi1_xml_handle_VendorAnnotations(fmi1_xml_parser_context_t *context, const char* data) { if(!data) { jm_log_verbose(context->callbacks, module, "Parsing XML element VendorAnnotations"); } else { /* might give out a warning if(data[0] != 0) */ } return 0; }
fmi2_status_t fmi2_capi_setup_experiment(fmi2_capi_t* fmu, fmi2_boolean_t tolerance_defined, fmi2_real_t tolerance, fmi2_real_t start_time, fmi2_boolean_t stop_time_defined, fmi2_real_t stop_time) { assert(fmu); assert(fmu->c); jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Calling fmi2SetupExperiment"); return fmu->fmi2SetupExperiment(fmu->c, tolerance_defined, tolerance, start_time, stop_time_defined, stop_time); }
fmi1_component_t fmi1_capi_instantiate_model(fmi1_capi_t* fmu, fmi1_string_t instanceName, fmi1_string_t GUID, fmi1_boolean_t loggingOn) { fmi1_me_callback_functions_t cb; assert(fmu); cb.logger = fmu->callBackFunctions.logger; cb.allocateMemory = fmu->callBackFunctions.allocateMemory; cb.freeMemory = fmu->callBackFunctions.freeMemory; jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Calling fmiInstantiateModel"); return fmu->c = fmu->fmiInstantiateModel(instanceName, GUID, cb, loggingOn); }
jm_status_enu_t fmi2_capi_load_dll(fmi2_capi_t* fmu) { assert(fmu && fmu->dllPath); fmu->dllHandle = jm_portability_load_dll_handle(fmu->dllPath); /* Load the shared library */ if (fmu->dllHandle == NULL) { jm_log_fatal(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Could not load the FMU binary: %s", jm_portability_get_last_dll_error()); return jm_status_error; } else { jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Loaded FMU binary from %s", fmu->dllPath); return jm_status_success; } }
/* Load FMI 2.0 Co-Simulation functions */ static jm_status_enu_t fmi2_capi_load_cs_fcn(fmi2_capi_t* fmu, unsigned int capabilities[]) { jm_status_enu_t jm_status = jm_status_success; jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Loading functions for the co-simulation interface"); jm_status = fmi2_capi_load_common_fcn(fmu, capabilities); /* Getting and setting the internal FMU state */ /* typedef fmi2Status fmi2GetFMUstateTYPE (fmi2Component, fmi2FMUstate*); typedef fmi2Status fmi2SetFMUstateTYPE (fmi2Component, fmi2FMUstate); typedef fmi2Status fmi2FreeFMUstateTYPE (fmi2Component, fmi2FMUstate*); typedef fmi2Status fmi2SerializedFMUstateSizeTYPE(fmi2Component, fmi2FMUstate, size_t*); typedef fmi2Status fmi2SerializeFMUstateTYPE (fmi2Component, fmi2FMUstate, fmi2Byte[], size_t); typedef fmi2Status fmi2DeSerializeFMUstateTYPE (fmi2Component, const fmi2Byte[], size_t, fmi2FMUstate*); */ LOAD_DLL_FUNCTION_WITH_FLAG(fmi2GetFMUstate,fmi2_cs_canGetAndSetFMUstate); LOAD_DLL_FUNCTION_WITH_FLAG(fmi2SetFMUstate,fmi2_cs_canGetAndSetFMUstate); LOAD_DLL_FUNCTION_WITH_FLAG(fmi2FreeFMUstate,fmi2_cs_canGetAndSetFMUstate); LOAD_DLL_FUNCTION_WITH_FLAG(fmi2SerializedFMUstateSize,fmi2_cs_canSerializeFMUstate); LOAD_DLL_FUNCTION_WITH_FLAG(fmi2SerializeFMUstate,fmi2_cs_canSerializeFMUstate); LOAD_DLL_FUNCTION_WITH_FLAG(fmi2DeSerializeFMUstate,fmi2_cs_canSerializeFMUstate); /* Getting directional derivatives */ /* typedef fmi2Status fmi2GetDirectionalDerivativeTYPE(fmi2Component, const fmi2ValueReference[], size_t, const fmi2ValueReference[], size_t, const fmi2Real[], fmi2Real[]);*/ LOAD_DLL_FUNCTION_WITH_FLAG(fmi2GetDirectionalDerivative,fmi2_cs_providesDirectionalDerivatives); /* Simulating the slave */ /* typedef fmi2Status fmi2SetRealInputDerivativesTYPE (fmi2Component, const fmi2ValueReference [], size_t, const fmi2Integer [], const fmi2Real []); typedef fmi2Status fmi2GetRealOutputDerivativesTYPE(fmi2Component, const fmi2ValueReference [], size_t, const fmi2Integer [], fmi2Real []); */ LOAD_DLL_FUNCTION(fmi2SetRealInputDerivatives); LOAD_DLL_FUNCTION(fmi2GetRealOutputDerivatives); /* typedef fmi2Status fmi2DoStepTYPE (fmi2Component, fmi2Real, fmi2Real, fmi2Boolean); typedef fmi2Status fmi2CancelStepTYPE (fmi2Component); */ LOAD_DLL_FUNCTION(fmi2CancelStep); LOAD_DLL_FUNCTION(fmi2DoStep); /* Inquire slave status */ /* typedef fmi2Status fmi2GetStatusTYPE (fmi2Component, const fmi2StatusKind, fmi2Status* ); typedef fmi2Status fmi2GetRealStatusTYPE (fmi2Component, const fmi2StatusKind, fmi2Real* ); typedef fmi2Status fmi2GetIntegerStatusTYPE(fmi2Component, const fmi2StatusKind, fmi2Integer*); typedef fmi2Status fmi2GetBooleanStatusTYPE(fmi2Component, const fmi2StatusKind, fmi2Boolean*); typedef fmi2Status fmi2GetStringStatusTYPE (fmi2Component, const fmi2StatusKind, fmi2String* ); */ LOAD_DLL_FUNCTION(fmi2GetStatus); LOAD_DLL_FUNCTION(fmi2GetRealStatus); LOAD_DLL_FUNCTION(fmi2GetIntegerStatus); LOAD_DLL_FUNCTION(fmi2GetBooleanStatus); LOAD_DLL_FUNCTION(fmi2GetStringStatus); return jm_status; }
int fmi1_xml_handle_UnitDefinitions(fmi1_xml_parser_context_t *context, const char* data) { fmi1_xml_model_description_t* md = context->modelDescription; if(!data) { jm_log_verbose(context->callbacks, module, "Parsing XML element UnitDefinitions"); } else { jm_vector_qsort(jm_named_ptr)(&(md->unitDefinitions),jm_compare_named); jm_vector_qsort(jm_named_ptr)(&(md->displayUnitDefinitions),jm_compare_named); /* might give out a warning if(data[0] != 0) */ } return 0; }
void fmi1_import_free(fmi1_import_t* fmu) { jm_callbacks* cb = fmu->callbacks; if(!fmu) return; jm_log_verbose( fmu->callbacks, "FMILIB", "Releasing allocated library resources"); fmi1_import_destroy_dllfmu(fmu); fmi1_xml_free_model_description(fmu->md); jm_vector_free_data(char)(&fmu->logMessageBuffer); cb->free(fmu->dirPath); cb->free(fmu->location); cb->free(fmu); }
int fmi2_xml_handle_Derivatives(fmi2_xml_parser_context_t *context, const char* data) { if (!data) { jm_log_verbose(context->callbacks, module, "Parsing XML element Derivatives"); /* reset handles for the elements that are specific under Derivatives */ fmi2_xml_set_element_handle(context, "Unknown", FMI2_XML_ELM_ID(DerivativeUnknown)); } else { fmi2_xml_model_description_t* md = context->modelDescription; fmi2_xml_model_structure_t* ms = md->modelStructure; /* count the number of continuous states as the number of <Unknown> elements under <Derivatives> */ md->numberOfContinuousStates = jm_vector_get_size(jm_voidp)(&ms->derivatives); } return 0; }
void fmi2_import_destroy_dllfmu(fmi2_import_t* fmu) { if (fmu == NULL) { return; } if(fmu -> capi) { jm_log_verbose(fmu->callbacks, module, "Releasing FMU CAPI interface"); /* Free DLL handle */ fmi2_capi_free_dll(fmu -> capi); /* Destroy the C-API struct */ fmi2_capi_destroy_dllfmu(fmu -> capi); fmu -> capi = NULL; } }
/* Load FMI 1.0 Co-Simulation functions */ static jm_status_enu_t fmi1_capi_load_cs_fcn(fmi1_capi_t* fmu) { jm_status_enu_t jm_status = jm_status_success; jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Loading functions for the co-simulation interface"); /* Workaround for Dymola 2012 and SimulationX 3.x */ if (fmi1_capi_get_fcn(fmu, "fmiGetTypesPlatform",(jm_dll_function_ptr*)&fmu->fmiGetTypesPlatform) == jm_status_error) { jm_log_warning(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Could not load the FMI function 'fmiGetTypesPlatform'. %s. Trying to load fmiGetModelTypesPlatform instead.", jm_portability_get_last_dll_error()); jm_status = jm_status_warning; if (fmi1_capi_get_fcn(fmu, "fmiGetModelTypesPlatform", (jm_dll_function_ptr*)&fmu->fmiGetTypesPlatform) == jm_status_error) { jm_log_error(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Could not load the FMI function 'fmiGetModelTypesPlatform'. %s", jm_portability_get_last_dll_error()); jm_status = jm_status_error; } } LOAD_DLL_FUNCTION(fmiInstantiateSlave); LOAD_DLL_FUNCTION(fmiInitializeSlave); LOAD_DLL_FUNCTION(fmiTerminateSlave); LOAD_DLL_FUNCTION(fmiResetSlave); LOAD_DLL_FUNCTION(fmiFreeSlaveInstance); LOAD_DLL_FUNCTION(fmiSetRealInputDerivatives); LOAD_DLL_FUNCTION(fmiGetRealOutputDerivatives); LOAD_DLL_FUNCTION(fmiCancelStep); LOAD_DLL_FUNCTION(fmiDoStep); LOAD_DLL_FUNCTION(fmiGetStatus); LOAD_DLL_FUNCTION(fmiGetRealStatus); LOAD_DLL_FUNCTION(fmiGetIntegerStatus); LOAD_DLL_FUNCTION(fmiGetBooleanStatus); LOAD_DLL_FUNCTION(fmiGetStringStatus); LOAD_DLL_FUNCTION(fmiGetVersion); LOAD_DLL_FUNCTION(fmiSetDebugLogging); LOAD_DLL_FUNCTION(fmiSetReal); LOAD_DLL_FUNCTION(fmiSetInteger); LOAD_DLL_FUNCTION(fmiSetBoolean); LOAD_DLL_FUNCTION(fmiSetString); LOAD_DLL_FUNCTION(fmiGetReal); LOAD_DLL_FUNCTION(fmiGetInteger); LOAD_DLL_FUNCTION(fmiGetBoolean); LOAD_DLL_FUNCTION(fmiGetString); return jm_status; }
int fmi1_xml_handle_fmiModelDescription(fmi1_xml_parser_context_t *context, const char* data) { jm_name_ID_map_t namingConventionMap[] = {{"flat",fmi1_naming_enu_flat},{"structured", fmi1_naming_enu_structured},{0,0}}; fmi1_xml_model_description_t* md = context->modelDescription; if(!data) { if(context -> currentElmID != fmi1_xml_elmID_none) { fmi1_xml_parse_fatal(context, "fmi1_xml_model_description must be the root XML element"); return -1; } jm_log_verbose(context->callbacks, module, "Parsing XML element fmiModelDescription"); /* process the attributes */ return ( /* <xs:attribute name="fmiVersion" type="xs:normalizedString" use="required" fixed="1.0"/> */ fmi1_xml_set_attr_string(context, fmi1_xml_elmID_fmiModelDescription, fmi_attr_id_fmiVersion, 1, &(md->fmi1_xml_standard_version)) || /* <xs:attribute name="modelName" type="xs:normalizedString" use="required"> */ fmi1_xml_set_attr_string(context, fmi1_xml_elmID_fmiModelDescription, fmi_attr_id_modelName, 1, &(md->modelName)) || /* <xs:attribute name="modelIdentifier" type="xs:normalizedString" use="required"> */ fmi1_xml_set_attr_string(context, fmi1_xml_elmID_fmiModelDescription, fmi_attr_id_modelIdentifier, 1, &(md->modelIdentifier)) || /* <xs:attribute name="guid" type="xs:normalizedString" use="required"> */ fmi1_xml_set_attr_string(context, fmi1_xml_elmID_fmiModelDescription, fmi_attr_id_guid, 1, &(md->GUID)) || /* <xs:attribute name="description" type="xs:string"/> */ fmi1_xml_set_attr_string(context, fmi1_xml_elmID_fmiModelDescription, fmi_attr_id_description, 0, &(md->description)) || /* <xs:attribute name="author" type="xs:string"/> */ fmi1_xml_set_attr_string(context, fmi1_xml_elmID_fmiModelDescription, fmi_attr_id_author, 0, &(md->author)) || /* <xs:attribute name="version" type="xs:normalizedString"> */ fmi1_xml_set_attr_string(context, fmi1_xml_elmID_fmiModelDescription, fmi_attr_id_version, 0, &(md->version)) || /* <xs:attribute name="generationTool" type="xs:normalizedString"/> */ fmi1_xml_set_attr_string(context, fmi1_xml_elmID_fmiModelDescription, fmi_attr_id_generationTool, 0, &(md->generationTool)) || /* <xs:attribute name="generationDateAndTime" type="xs:dateTime"/> */ fmi1_xml_set_attr_string(context, fmi1_xml_elmID_fmiModelDescription, fmi_attr_id_generationDateAndTime, 0, &(md->generationDateAndTime)) || /* <xs:attribute name="variableNamingConvention" use="optional" default="flat"> */ fmi1_xml_set_attr_enum(context, fmi1_xml_elmID_fmiModelDescription, fmi_attr_id_variableNamingConvention, 0, (unsigned*)&(md->namingConvension), fmi1_naming_enu_flat, namingConventionMap) || /* <xs:attribute name="numberOfContinuousStates" type="xs:unsignedInt" use="required"/> */ fmi1_xml_set_attr_uint(context, fmi1_xml_elmID_fmiModelDescription, fmi_attr_id_numberOfContinuousStates, 1, &(md->numberOfContinuousStates),0) || /* <xs:attribute name="numberOfEventIndicators" type="xs:unsignedInt" use="required"/> */ fmi1_xml_set_attr_uint(context, fmi1_xml_elmID_fmiModelDescription, fmi_attr_id_numberOfEventIndicators, 1, &(md->numberOfEventIndicators),0) ); } else { /* don't do anything. might give out a warning if(data[0] != 0) */ return 0; } }
fmi_version_enu_t fmi_import_get_fmi_version( fmi_import_context_t* c, const char* fileName, const char* dirName) { fmi_version_enu_t ret = fmi_version_unknown_enu; jm_status_enu_t status; char* mdpath; jm_log_verbose(c->callbacks, MODULE, "Detecting FMI standard version"); if(!fileName || !*fileName) { jm_log_fatal(c->callbacks, MODULE, "No FMU filename specified"); return fmi_version_unknown_enu; } if(!dirName || !*dirName) { jm_log_fatal(c->callbacks, MODULE, "No temporary directory name specified"); return fmi_version_unknown_enu; } status = fmi_zip_unzip(fileName, dirName, c->callbacks); if(status == jm_status_error) return fmi_version_unknown_enu; mdpath = fmi_import_get_model_description_path(dirName, c->callbacks); ret = fmi_xml_get_fmi_version(c, mdpath); jm_log_info(c->callbacks, MODULE, "XML specifies FMI standard version %s", fmi_version_to_string(ret)); c->callbacks->free(mdpath); return ret; }
jm_status_enu_t fmi2_capi_free_dll(fmi2_capi_t* fmu) { if (fmu == NULL) { return jm_status_error; /* Return without writing any log message */ } if (fmu->dllHandle) { jm_status_enu_t status = (fmu->debugMode != 0) ? /* When running valgrind this may be convenient to track mem leaks */ jm_status_success: jm_portability_free_dll_handle(fmu->dllHandle); fmu->dllHandle = 0; if (status == jm_status_error) { /* Free the library handle */ jm_log(fmu->callbacks, FMI_CAPI_MODULE_NAME, jm_log_level_error, "Could not free the FMU binary: %s", jm_portability_get_last_dll_error()); return jm_status_error; } else { jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Successfully unloaded FMU binary"); return jm_status_success; } } return jm_status_success; }
int fmi2_xml_handle_ModelStructure(fmi2_xml_parser_context_t *context, const char* data) { fmi2_xml_model_description_t* md = context->modelDescription; if(!data) { jm_log_verbose(context->callbacks, module,"Parsing XML element ModelStructure"); /** allocate model structure */ md->modelStructure = fmi2_xml_allocate_model_structure(md->callbacks); if(!md->modelStructure) { fmi2_xml_parse_fatal(context, module, "Could not allocate memory"); return -1; } } else { /** make sure model structure information is consistent */ if(!fmi2_xml_check_model_structure(md)) { fmi2_xml_parse_fatal(context, "Model structure is not valid due to detected errors. Cannot continue."); return -1; } /* md->numberOfContinuousStates = jm_vector_get_size(jm_voidp)(&md->modelStructure->states); */ } return 0; }
fmi_import_context_t* fmi_import_allocate_context( jm_callbacks* callbacks) { jm_log_verbose(callbacks, MODULE, "Allocating FMIL context"); return fmi_xml_allocate_context(callbacks); }
const char* fmi1_capi_get_model_types_platform(fmi1_capi_t* fmu) { assert(fmu); jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Calling fmiGetModelTypesPlatform"); return fmu->fmiGetModelTypesPlatform(); }
fmi1_status_t fmi1_capi_initialize(fmi1_capi_t* fmu, fmi1_boolean_t toleranceControlled, fmi1_real_t relativeTolerance, fmi1_event_info_t* eventInfo) { assert(fmu); jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Calling fmiInitialize"); return fmu->fmiInitialize(fmu->c, toleranceControlled, relativeTolerance, eventInfo); }
void fmi1_capi_free_model_instance(fmi1_capi_t* fmu) { jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Calling fmiFreeModelInstance"); fmu->fmiFreeModelInstance(fmu->c); }
/* Load FMI 2.0 Co-Simulation functions */ static jm_status_enu_t fmi2_capi_load_cs_fcn(fmi2_capi_t* fmu, unsigned int capabilities[]) { jm_status_enu_t jm_status = jm_status_success; jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Loading functions for the co-simulation interface"); jm_status = fmi2_capi_load_common_fcn(fmu, capabilities); /* Getting and setting the internal FMU state */ /* typedef fmiStatus fmiGetFMUstateTYPE (fmiComponent, fmiFMUstate*); typedef fmiStatus fmiSetFMUstateTYPE (fmiComponent, fmiFMUstate); typedef fmiStatus fmiFreeFMUstateTYPE (fmiComponent, fmiFMUstate*); typedef fmiStatus fmiSerializedFMUstateSizeTYPE(fmiComponent, fmiFMUstate, size_t*); typedef fmiStatus fmiSerializeFMUstateTYPE (fmiComponent, fmiFMUstate, fmiByte[], size_t); typedef fmiStatus fmiDeSerializeFMUstateTYPE (fmiComponent, const fmiByte[], size_t, fmiFMUstate*); */ LOAD_DLL_FUNCTION_WITH_FLAG(fmiGetFMUstate,fmi2_cs_canGetAndSetFMUstate); LOAD_DLL_FUNCTION_WITH_FLAG(fmiSetFMUstate,fmi2_cs_canGetAndSetFMUstate); LOAD_DLL_FUNCTION_WITH_FLAG(fmiFreeFMUstate,fmi2_cs_canGetAndSetFMUstate); LOAD_DLL_FUNCTION_WITH_FLAG(fmiSerializedFMUstateSize,fmi2_cs_canSerializeFMUstate); LOAD_DLL_FUNCTION_WITH_FLAG(fmiSerializeFMUstate,fmi2_cs_canSerializeFMUstate); LOAD_DLL_FUNCTION_WITH_FLAG(fmiDeSerializeFMUstate,fmi2_cs_canSerializeFMUstate); /* Getting partial derivatives */ /* typedef fmiStatus fmiGetPartialDerivativesTYPE (fmiComponent, setMatrixElement, void*, void*, void*, void*); typedef fmiStatus fmiGetDirectionalDerivativeTYPE(fmiComponent, const fmiValueReference[], size_t, const fmiValueReference[], size_t, const fmiReal[], fmiReal[]); */ /*??? LOAD_DLL_FUNCTION_WITH_FLAG(fmiGetDirectionalDerivative,fmi2_cs_providesDirectionalDerivatives); */ /* Creation and destruction of slave instances */ /* typedef fmiComponent fmiInstantiateSlaveTYPE (fmiString, fmiString, fmiString, const fmiCallbackFunctions*, fmiBoolean, fmiBoolean); typedef void fmiFreeSlaveInstanceTYPE(fmiComponent); */ LOAD_DLL_FUNCTION(fmiInstantiateSlave); LOAD_DLL_FUNCTION(fmiFreeSlaveInstance); /* Simulating the slave */ /* typedef fmiStatus fmiInitializeSlaveTYPE(fmiComponent, fmiReal, fmiReal, fmiBoolean, fmiReal); typedef fmiStatus fmiTerminateSlaveTYPE (fmiComponent); typedef fmiStatus fmiResetSlaveTYPE (fmiComponent); */ LOAD_DLL_FUNCTION(fmiInitializeSlave); LOAD_DLL_FUNCTION(fmiTerminateSlave); LOAD_DLL_FUNCTION(fmiResetSlave); /* typedef fmiStatus fmiSetRealInputDerivativesTYPE (fmiComponent, const fmiValueReference [], size_t, const fmiInteger [], const fmiReal []); typedef fmiStatus fmiGetRealOutputDerivativesTYPE(fmiComponent, const fmiValueReference [], size_t, const fmiInteger [], fmiReal []); */ LOAD_DLL_FUNCTION(fmiSetRealInputDerivatives); LOAD_DLL_FUNCTION(fmiGetRealOutputDerivatives); /* typedef fmiStatus fmiDoStepTYPE (fmiComponent, fmiReal, fmiReal, fmiBoolean); typedef fmiStatus fmiCancelStepTYPE (fmiComponent); */ LOAD_DLL_FUNCTION(fmiCancelStep); LOAD_DLL_FUNCTION(fmiDoStep); /* Inquire slave status */ /* typedef fmiStatus fmiGetStatusTYPE (fmiComponent, const fmiStatusKind, fmiStatus* ); typedef fmiStatus fmiGetRealStatusTYPE (fmiComponent, const fmiStatusKind, fmiReal* ); typedef fmiStatus fmiGetIntegerStatusTYPE(fmiComponent, const fmiStatusKind, fmiInteger*); typedef fmiStatus fmiGetBooleanStatusTYPE(fmiComponent, const fmiStatusKind, fmiBoolean*); typedef fmiStatus fmiGetStringStatusTYPE (fmiComponent, const fmiStatusKind, fmiString* ); */ LOAD_DLL_FUNCTION(fmiGetStatus); LOAD_DLL_FUNCTION(fmiGetRealStatus); LOAD_DLL_FUNCTION(fmiGetIntegerStatus); LOAD_DLL_FUNCTION(fmiGetBooleanStatus); LOAD_DLL_FUNCTION(fmiGetStringStatus); return jm_status; }
jm_status_enu_t fmi1_cs_simulate(fmu_check_data_t* cdata) { fmi1_status_t fmistatus; jm_status_enu_t jmstatus = jm_status_success; jm_callbacks* cb = &cdata->callbacks; fmi1_import_t* fmu = cdata->fmu1; fmi1_string_t fmuGUID = fmi1_import_get_GUID(fmu); fmi1_string_t mimeType; fmi1_real_t timeout = 0.0; fmi1_boolean_t visible = fmi1_false; fmi1_boolean_t interactive = fmi1_false; fmi1_real_t tstart = fmi1_import_get_default_experiment_start(fmu); fmi1_real_t tcur = tstart; fmi1_real_t hstep; fmi1_real_t tend = fmi1_import_get_default_experiment_stop(fmu); fmi1_boolean_t StopTimeDefined = fmi1_true; mimeType = fmi1_import_get_mime_type(fmu); if( (cdata->fmu1_kind == fmi1_fmu_kind_enu_cs_standalone) || !mimeType || !mimeType[0]) { mimeType = "application/x-fmu-sharedlibrary"; } else { if( strcmp(mimeType, "application/x-fmu-sharedlibrary") != 0 ) { jm_log_info(cb, fmu_checker_module,"The FMU requests simulator with MIME type '%s'.", mimeType); printf("\nPlease, start a simulator program for MIME type '%s'\nPress enter to continue.\n", mimeType); getchar(); } } if(cdata->stopTime > 0) { tend = cdata->stopTime; } if(cdata->stepSize > 0) { hstep = cdata->stepSize; } else { hstep = (tend - tstart) / cdata->numSteps; } cdata->instanceName = "Test FMI 1.0 CS"; jm_log_verbose(cb, fmu_checker_module, "Checker will instantiate the slave with \n" "\tFMU location ='%s'\n\tMIME type = '%s'", cdata->fmuLocation, mimeType); jmstatus = fmi1_import_instantiate_slave(fmu, cdata->instanceName, cdata->fmuLocation, mimeType, timeout, visible, interactive); if (jmstatus == jm_status_error) { jm_log_fatal(cb, fmu_checker_module, "Could not instantiate the model"); return jm_status_error; } fmistatus = fmi1_import_initialize_slave(fmu, tstart, StopTimeDefined, tend); if((fmistatus == fmi1_status_ok) || (fmistatus == fmi1_status_warning)) { jm_log_info(cb, fmu_checker_module, "Initialized FMU for simulation starting at time %g", tstart); fmistatus = fmi1_status_ok; } else { jm_log_fatal(cb, fmu_checker_module, "Failed to initialize FMU for simulation (FMU status: %s)", fmi1_status_to_string(fmistatus)); jmstatus = jm_status_error; } if(jmstatus != jm_status_error) { jm_log_verbose(cb, fmu_checker_module, "Writing simulation output for start time"); if(fmi1_write_csv_data(cdata, tstart) != jm_status_success){ jmstatus = jm_status_error; } } while ((tcur < tend) && (jmstatus != jm_status_error)) { fmi1_boolean_t newStep = fmi1_true; fmi1_real_t tnext = tcur + hstep; if(tnext > tend - 1e-3*hstep) { /* last step should be on tend */ hstep = tend - tcur; tnext = tend; } jm_log_verbose(cb, fmu_checker_module, "Simulation step from time: %g until: %g", tcur, tnext); fmistatus = fmi1_import_do_step(fmu, tcur, hstep, newStep); tcur = tnext; if(fmi1_write_csv_data(cdata, tcur) != jm_status_success){ jmstatus = jm_status_error; } if((fmistatus == fmi1_status_ok) || (fmistatus == fmi1_status_warning)) { fmistatus = fmi1_status_ok; } else jmstatus = jm_status_error; } if((fmistatus != fmi1_status_ok) && (fmistatus != fmi1_status_warning)) { jm_log_fatal(cb, fmu_checker_module, "Simulation loop terminated at time %g since FMU returned status: %s", tcur, fmi1_status_to_string(fmistatus)); jmstatus = jm_status_error; } else if(jmstatus != jm_status_error) { jm_log_info(cb, fmu_checker_module, "Simulation finished successfully at time %g", tcur); } fmistatus = fmi1_import_terminate_slave(fmu); if( fmistatus != fmi1_status_ok) { jm_log_error(cb, fmu_checker_module, "fmiTerminateSlave returned status: %s", fmi1_status_to_string(fmistatus)); } fmi1_import_free_slave_instance(fmu); return jmstatus; }
fmi2_status_t fmi2_capi_exit_initialization_mode(fmi2_capi_t* fmu) { assert(fmu); assert(fmu->c); jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Calling fmi2ExitInitializationMode"); return fmu->fmi2ExitInitializationMode(fmu->c); }
/* Load FMI 1.0 Model Exchange functions */ static jm_status_enu_t fmi2_capi_load_me_fcn(fmi2_capi_t* fmu, unsigned int capabilities[]) { jm_status_enu_t jm_status = jm_status_success; jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Loading functions for the model exchange interface"); jm_status = fmi2_capi_load_common_fcn(fmu, capabilities); /* Getting and setting the internal FMU state */ /* typedef fmiStatus fmiGetFMUstateTYPE (fmiComponent, fmiFMUstate*); typedef fmiStatus fmiSetFMUstateTYPE (fmiComponent, fmiFMUstate); typedef fmiStatus fmiFreeFMUstateTYPE (fmiComponent, fmiFMUstate*); typedef fmiStatus fmiSerializedFMUstateSizeTYPE(fmiComponent, fmiFMUstate, size_t*); typedef fmiStatus fmiSerializeFMUstateTYPE (fmiComponent, fmiFMUstate, fmiByte[], size_t); typedef fmiStatus fmiDeSerializeFMUstateTYPE (fmiComponent, const fmiByte[], size_t, fmiFMUstate*); */ LOAD_DLL_FUNCTION_WITH_FLAG(fmiGetFMUstate,fmi2_me_canGetAndSetFMUstate); LOAD_DLL_FUNCTION_WITH_FLAG(fmiSetFMUstate,fmi2_me_canGetAndSetFMUstate); LOAD_DLL_FUNCTION_WITH_FLAG(fmiFreeFMUstate,fmi2_me_canGetAndSetFMUstate); LOAD_DLL_FUNCTION_WITH_FLAG(fmiSerializedFMUstateSize,fmi2_me_canSerializeFMUstate); LOAD_DLL_FUNCTION_WITH_FLAG(fmiSerializeFMUstate,fmi2_me_canSerializeFMUstate); LOAD_DLL_FUNCTION_WITH_FLAG(fmiDeSerializeFMUstate,fmi2_me_canSerializeFMUstate); /* Getting partial derivatives */ /* typedef fmiStatus fmiGetPartialDerivativesTYPE (fmiComponent, setMatrixElement, void*, void*, void*, void*); typedef fmiStatus fmiGetDirectionalDerivativeTYPE(fmiComponent, const fmiValueReference[], size_t, const fmiValueReference[], size_t, const fmiReal[], fmiReal[]); */ LOAD_DLL_FUNCTION_WITH_FLAG(fmiGetDirectionalDerivative,fmi2_me_providesDirectionalDerivatives); /* Creation and destruction of model instances and setting debug status */ /*typedef fmiComponent fmiInstantiateModelTYPE (fmiString, fmiString, fmiString, const fmiCallbackFunctions*, fmiBoolean, fmiBoolean); typedef void fmiFreeModelInstanceTYPE(fmiComponent);*/ LOAD_DLL_FUNCTION(fmiInstantiateModel); LOAD_DLL_FUNCTION(fmiFreeModelInstance); /* Providing independent variables and re-initialization of caching */ /*typedef fmiStatus fmiSetTimeTYPE (fmiComponent, fmiReal); typedef fmiStatus fmiSetContinuousStatesTYPE (fmiComponent, const fmiReal[], size_t); typedef fmiStatus fmiCompletedIntegratorStepTYPE(fmiComponent, fmiBoolean*); */ LOAD_DLL_FUNCTION(fmiSetTime); LOAD_DLL_FUNCTION(fmiSetContinuousStates); LOAD_DLL_FUNCTION(fmiCompletedIntegratorStep); /* Evaluation of the model equations */ /* typedef fmiStatus fmiInitializeModelTYPE (fmiComponent, fmiBoolean, fmiReal, fmiEventInfo*); typedef fmiStatus fmiEventUpdateTYPE (fmiComponent, fmiBoolean, fmiEventInfo*); typedef fmiStatus fmiCompletedEventIterationTYPE(fmiComponent); typedef fmiStatus fmiTerminateTYPE (fmiComponent); */ LOAD_DLL_FUNCTION(fmiInitializeModel); LOAD_DLL_FUNCTION(fmiEventUpdate); LOAD_DLL_FUNCTION_WITH_FLAG(fmiCompletedEventIteration, fmi2_me_completedEventIterationIsProvided); LOAD_DLL_FUNCTION(fmiTerminate); /* typedef fmiStatus fmiGetDerivativesTYPE (fmiComponent, fmiReal[], size_t); typedef fmiStatus fmiGetEventIndicatorsTYPE (fmiComponent, fmiReal[], size_t); typedef fmiStatus fmiGetContinuousStatesTYPE (fmiComponent, fmiReal[], size_t); typedef fmiStatus fmiGetNominalContinuousStatesTYPE(fmiComponent, fmiReal[], size_t); typedef fmiStatus fmiGetStateValueReferencesTYPE (fmiComponent, fmiValueReference[], size_t); */ LOAD_DLL_FUNCTION(fmiGetDerivatives); LOAD_DLL_FUNCTION(fmiGetEventIndicators); LOAD_DLL_FUNCTION(fmiGetContinuousStates); LOAD_DLL_FUNCTION(fmiGetNominalContinuousStates); LOAD_DLL_FUNCTION(fmiGetStateValueReferences); return jm_status; }
/* Load and destroy functions */ jm_status_enu_t fmi2_import_create_dllfmu(fmi2_import_t* fmu, fmi2_fmu_kind_enu_t fmuKind, const fmi2_callback_functions_t* callBackFunctions) { char curDir[FILENAME_MAX + 2]; char* dllDirPath = 0; char* dllFileName = 0; const char* modelIdentifier; fmi2_callback_functions_t defaultCallbacks; if (fmu == NULL) { assert(0); return jm_status_error; } if(fmu -> capi) { if(fmi2_capi_get_fmu_kind(fmu -> capi) == fmuKind) { jm_log_warning(fmu->callbacks, module, "FMU binary is already loaded"); return jm_status_success; } else fmi2_import_destroy_dllfmu(fmu); } if(fmuKind == fmi2_fmu_kind_me) modelIdentifier = fmi2_import_get_model_identifier_ME(fmu); else if(fmuKind == fmi2_fmu_kind_cs) modelIdentifier = fmi2_import_get_model_identifier_CS(fmu); else { assert(0); return jm_status_error; } if (modelIdentifier == NULL) { jm_log_error(fmu->callbacks, module, "No model identifier given"); return jm_status_error; } if( jm_portability_get_current_working_directory(curDir, FILENAME_MAX+1) != jm_status_success) { jm_log_warning(fmu->callbacks, module, "Could not get current working directory (%s)", strerror(errno)); curDir[0] = 0; }; dllDirPath = fmi_construct_dll_dir_name(fmu->callbacks, fmu->dirPath); dllFileName = fmi_construct_dll_file_name(fmu->callbacks, dllDirPath, modelIdentifier); if (!dllDirPath ||!dllFileName) { fmu->callbacks->free(dllDirPath); return jm_status_error; } if(!callBackFunctions) { jm_callbacks* cb = fmu->callbacks; defaultCallbacks.allocateMemory = cb->calloc; defaultCallbacks.freeMemory = cb->free; defaultCallbacks.componentEnvironment = fmu; defaultCallbacks.logger = fmi2_log_forwarding; defaultCallbacks.stepFinished = 0; callBackFunctions = &defaultCallbacks; } if(jm_portability_set_current_working_directory(dllDirPath) != jm_status_success) { jm_log_fatal(fmu->callbacks, module, "Could not change to the DLL directory %s", dllDirPath); if(ENOENT == errno) jm_log_fatal(fmu->callbacks, module, "No binary for this platform?"); else jm_log_fatal(fmu->callbacks, module, "System error: %s", strerror(errno)); } else { /* Allocate memory for the C-API struct */ fmu -> capi = fmi2_capi_create_dllfmu(fmu->callbacks, dllFileName, modelIdentifier, callBackFunctions, fmuKind); } /* Load the DLL handle */ if (fmu -> capi) { jm_log_info(fmu->callbacks, module, "Loading '" FMI_PLATFORM "' binary with '%s' platform types", fmi2_get_types_platform() ); if(fmi2_capi_load_dll(fmu -> capi) == jm_status_error) { fmi2_capi_destroy_dllfmu(fmu -> capi); fmu -> capi = NULL; } } if(curDir[0] && (jm_portability_set_current_working_directory(curDir) != jm_status_success)) { jm_log_error(fmu->callbacks, module, "Could not restore current working directory (%s)", strerror(errno)); } fmu->callbacks->free((jm_voidp)dllDirPath); fmu->callbacks->free((jm_voidp)dllFileName); if (fmu -> capi == NULL) { return jm_status_error; } /* Load the DLL functions */ if (fmi2_capi_load_fcn(fmu -> capi, fmi2_xml_get_capabilities(fmu->md)) == jm_status_error) { fmi2_capi_free_dll(fmu -> capi); fmi2_capi_destroy_dllfmu(fmu -> capi); fmu -> capi = NULL; return jm_status_error; } jm_log_verbose(fmu->callbacks, module, "Successfully loaded all the interface functions"); return jm_status_success; }