Пример #1
0
void* FMI2ModelExchangeConstructor_OMC(int fmi_log_level, char* working_directory, char* instanceName, int debugLogging)
{
  FMI2ModelExchange* FMI2ME = malloc(sizeof(FMI2ModelExchange));
  FMI2ME->FMILogLevel = fmi_log_level;
  /* JM callbacks */
  FMI2ME->JMCallbacks.malloc = malloc;
  FMI2ME->JMCallbacks.calloc = calloc;
  FMI2ME->JMCallbacks.realloc = realloc;
  FMI2ME->JMCallbacks.free = free;
  FMI2ME->JMCallbacks.logger = importlogger;
  FMI2ME->JMCallbacks.log_level = FMI2ME->FMILogLevel;
  FMI2ME->JMCallbacks.context = 0;
  FMI2ME->FMIImportContext = fmi_import_allocate_context(&FMI2ME->JMCallbacks);
  /* FMI callback functions */
  FMI2ME->FMICallbackFunctions.logger = fmi2logger;
  FMI2ME->FMICallbackFunctions.allocateMemory = calloc;
  FMI2ME->FMICallbackFunctions.freeMemory = free;
  /* parse the xml file */
  FMI2ME->FMIWorkingDirectory = (char*) malloc(strlen(working_directory)+1);
  strcpy(FMI2ME->FMIWorkingDirectory, working_directory);
  FMI2ME->FMIImportInstance = fmi2_import_parse_xml(FMI2ME->FMIImportContext, FMI2ME->FMIWorkingDirectory, NULL);
  if(!FMI2ME->FMIImportInstance) {
    fprintf(stderr, "Error parsing the XML file contained in %s\n", FMI2ME->FMIWorkingDirectory);
    return 0;
  }
  /* Load the binary (dll/so) */
  jm_status_enu_t status;
  status = fmi2_import_create_dllfmu(FMI2ME->FMIImportInstance, fmi2_import_get_fmu_kind(FMI2ME->FMIImportInstance), &FMI2ME->FMICallbackFunctions);
  if (status == jm_status_error) {
    fprintf(stderr, "Could not create the DLL loading mechanism(C-API).\n");
    return 0;
  }
  FMI2ME->FMIInstanceName = (char*) malloc(strlen(instanceName)+1);
  strcpy(FMI2ME->FMIInstanceName, instanceName);
  FMI2ME->FMIDebugLogging = debugLogging;
  fmi2_import_instantiate_model(FMI2ME->FMIImportInstance, FMI2ME->FMIInstanceName, NULL, fmi2_false);
  fmi2_import_set_debug_logging(FMI2ME->FMIImportInstance, FMI2ME->FMIDebugLogging, 0, NULL);
  FMI2ME->FMIToleranceControlled = fmi2_true;
  FMI2ME->FMIRelativeTolerance = 0.001;
  FMI2ME->FMIEventInfo = malloc(sizeof(fmi2_event_info_t));
  fmi2_import_initialize_model(FMI2ME->FMIImportInstance, FMI2ME->FMIToleranceControlled, FMI2ME->FMIRelativeTolerance, FMI2ME->FMIEventInfo);
  return FMI2ME;
}
Пример #2
0
void* FMI2ModelExchangeConstructor_OMC(int fmi_log_level, char* working_directory, char* instanceName, int debugLogging)
{
  FMI2ModelExchange* FMI2ME = malloc(sizeof(FMI2ModelExchange));
  jm_status_enu_t status, instantiateModelStatus;
  FMI2ME->FMILogLevel = fmi_log_level;
  /* JM callbacks */
  FMI2ME->JMCallbacks.malloc = malloc;
  FMI2ME->JMCallbacks.calloc = calloc;
  FMI2ME->JMCallbacks.realloc = realloc;
  FMI2ME->JMCallbacks.free = free;
  FMI2ME->JMCallbacks.logger = importlogger;
  FMI2ME->JMCallbacks.log_level = FMI2ME->FMILogLevel;
  FMI2ME->JMCallbacks.context = 0;
  FMI2ME->FMIImportContext = fmi_import_allocate_context(&FMI2ME->JMCallbacks);
  /* parse the xml file */
  FMI2ME->FMIWorkingDirectory = (char*) malloc(strlen(working_directory)+1);
  strcpy(FMI2ME->FMIWorkingDirectory, working_directory);
  FMI2ME->FMIImportInstance = fmi2_import_parse_xml(FMI2ME->FMIImportContext, FMI2ME->FMIWorkingDirectory, NULL);
  if(!FMI2ME->FMIImportInstance) {
    FMI2ME->FMISolvingMode = fmi2_none_mode;
    ModelicaFormatError("Error parsing the XML file contained in %s\n", FMI2ME->FMIWorkingDirectory);
    return 0;
  }
  /* FMI callback functions */
  FMI2ME->FMICallbackFunctions.logger = fmi2logger;
  FMI2ME->FMICallbackFunctions.allocateMemory = calloc;
  FMI2ME->FMICallbackFunctions.freeMemory = free;
  FMI2ME->FMICallbackFunctions.componentEnvironment = FMI2ME->FMIImportInstance;
  /* Load the binary (dll/so) */
  status = fmi2_import_create_dllfmu(FMI2ME->FMIImportInstance, fmi2_import_get_fmu_kind(FMI2ME->FMIImportInstance), &FMI2ME->FMICallbackFunctions);
  if (status == jm_status_error) {
    FMI2ME->FMISolvingMode = fmi2_none_mode;
    ModelicaFormatError("Loading of FMU dynamic link library failed with status : %s\n", jm_log_level_to_string(status));
    return 0;
  }
  FMI2ME->FMIInstanceName = (char*) malloc(strlen(instanceName)+1);
  strcpy(FMI2ME->FMIInstanceName, instanceName);
  FMI2ME->FMIDebugLogging = debugLogging;
  instantiateModelStatus = fmi2_import_instantiate(FMI2ME->FMIImportInstance, FMI2ME->FMIInstanceName, fmi2_model_exchange, NULL, fmi2_false);
  if (instantiateModelStatus == jm_status_error) {
    FMI2ME->FMISolvingMode = fmi2_none_mode;
    ModelicaFormatError("fmi2InstantiateModel failed with status : %s\n", jm_log_level_to_string(instantiateModelStatus));
    return 0;
  }
  /* Only call fmi2SetDebugLogging if debugLogging is true */
  if (FMI2ME->FMIDebugLogging) {
    int i;
    size_t categoriesSize = 0;
    fmi2_status_t debugLoggingStatus;
    fmi2_string_t *categories;
    /* Read the log categories size */
    categoriesSize = fmi2_import_get_log_categories_num(FMI2ME->FMIImportInstance);
    categories = (fmi2_string_t*)malloc(categoriesSize*sizeof(fmi2_string_t));
    for (i = 0 ; i < categoriesSize ; i++) {
      categories[i] = fmi2_import_get_log_category(FMI2ME->FMIImportInstance, i);
    }
    debugLoggingStatus = fmi2_import_set_debug_logging(FMI2ME->FMIImportInstance, FMI2ME->FMIDebugLogging, categoriesSize, categories);
    if (debugLoggingStatus != fmi2_status_ok && debugLoggingStatus != fmi2_status_warning) {
      ModelicaFormatMessage("fmi2SetDebugLogging failed with status : %s\n", fmi1_status_to_string(debugLoggingStatus));
    }
  }
  FMI2ME->FMIToleranceControlled = fmi2_true;
  FMI2ME->FMIRelativeTolerance = 0.001;
  FMI2ME->FMIEventInfo = malloc(sizeof(fmi2_event_info_t));
  FMI2ME->FMISolvingMode = fmi2_instantiated_mode;
  return FMI2ME;
}
int test_simulate_me(fmi2_import_t* fmu)
{	
	fmi2_status_t fmistatus;
	jm_status_enu_t jmstatus;
	fmi2_real_t tstart = 0.0;
	fmi2_real_t tcur;
	fmi2_real_t hcur;
	fmi2_real_t hdef = 0.1;
	fmi2_real_t tend = 2.0;
	size_t n_states;
	size_t n_event_indicators;
	fmi2_real_t* states;
	fmi2_real_t states_end_results[] = {0.362000, -3.962000};
	fmi2_real_t* states_der;
	fmi2_real_t* event_indicators;
	fmi2_real_t* event_indicators_prev;
	fmi2_boolean_t callEventUpdate;
	fmi2_boolean_t terminateSimulation = fmi2_false;
	fmi2_boolean_t toleranceControlled = fmi2_true;
	fmi2_real_t relativeTolerance = 0.001;
	fmi2_event_info_t eventInfo;
	size_t k;

	printf("Version returned from FMU:   %s\n", fmi2_import_get_version(fmu));
	printf("Platform type returned:      %s\n", fmi2_import_get_types_platform(fmu));

	n_states = fmi2_import_get_number_of_continuous_states(fmu);
	n_event_indicators = fmi2_import_get_number_of_event_indicators(fmu);

	if (sizeof(states_end_results)/sizeof(fmi2_real_t) != n_states) {
		printf("Number of states and results have different length n_states = %u n_results = %u\n", (unsigned)n_states, (unsigned)sizeof(states_end_results));
		do_exit(CTEST_RETURN_FAIL);
	}

	states = calloc(n_states, sizeof(double));
	states_der = calloc(n_states, sizeof(double));
	event_indicators = calloc(n_event_indicators, sizeof(double));
	event_indicators_prev = calloc(n_event_indicators, sizeof(double));

	jmstatus = fmi2_import_instantiate(fmu, "Test ME model instance",fmi2_model_exchange,0,0);
	if (jmstatus == jm_status_error) {
		printf("fmi2_import_instantiate failed\n");
		do_exit(CTEST_RETURN_FAIL);
	}

	fmistatus = fmi2_import_set_debug_logging(fmu, fmi2_false,0,0);
	printf("fmi2_import_set_debug_logging:  %s\n", fmi2_status_to_string(fmistatus));	
	fmi2_import_set_debug_logging(fmu, fmi2_true, 0, 0);

    fmistatus = fmi2_import_setup_experiment(fmu, toleranceControlled,
        relativeTolerance, tstart, fmi2_false, 0.0);

    fmistatus = fmi2_import_enter_initialization_mode(fmu);
    fmistatus = fmi2_import_exit_initialization_mode(fmu);

	tcur = tstart;
	hcur = hdef;
	callEventUpdate = fmi2_false;

	eventInfo.newDiscreteStatesNeeded           = fmi2_false;
	eventInfo.terminateSimulation               = fmi2_false;
	eventInfo.nominalsOfContinuousStatesChanged = fmi2_false;
	eventInfo.valuesOfContinuousStatesChanged   = fmi2_true;
	eventInfo.nextEventTimeDefined              = fmi2_false;
	eventInfo.nextEventTime                     = -0.0;

    /* fmiExitInitializationMode leaves FMU in event mode */
    do_event_iteration(fmu, &eventInfo);
    fmi2_import_enter_continuous_time_mode(fmu);

	fmistatus = fmi2_import_get_continuous_states(fmu, states, n_states);
	fmistatus = fmi2_import_get_event_indicators(fmu, event_indicators, n_event_indicators);

	while ((tcur < tend) && (!(eventInfo.terminateSimulation || terminateSimulation))) {
		size_t k;
        fmi2_real_t tlast;
		int zero_crossing_event = 0;

		fmistatus = fmi2_import_set_time(fmu, tcur);

        { /* Swap event_indicators and event_indicators_prev so that we can get new indicators */
            fmi2_real_t *temp = event_indicators;
            event_indicators = event_indicators_prev;
            event_indicators_prev = temp;
        }
		fmistatus = fmi2_import_get_event_indicators(fmu, event_indicators, n_event_indicators);

		/* Check if an event indicator has triggered */
		for (k = 0; k < n_event_indicators; k++) {
			if ((event_indicators[k] > 0) != (event_indicators_prev[k] > 0)) {
				zero_crossing_event = 1;
				break;
			}
		}

		/* Handle any events */
		if (callEventUpdate || zero_crossing_event ||
		  (eventInfo.nextEventTimeDefined && tcur == eventInfo.nextEventTime)) {
            fmistatus = fmi2_import_enter_event_mode(fmu);
            do_event_iteration(fmu, &eventInfo);
            fmistatus = fmi2_import_enter_continuous_time_mode(fmu);

			fmistatus = fmi2_import_get_continuous_states(fmu, states, n_states);
			fmistatus = fmi2_import_get_event_indicators(fmu, event_indicators, n_event_indicators);
		}

		/* Calculate next time step */
        tlast = tcur;
        tcur += hdef;
		if (eventInfo.nextEventTimeDefined && (tcur >= eventInfo.nextEventTime)) {
            tcur = eventInfo.nextEventTime;
		}
        hcur = tcur - tlast;
		if(tcur > tend - hcur/1e16) {
			tcur = tend;				
			hcur = tcur - tlast;
		}

		/* Integrate a step */
		fmistatus = fmi2_import_get_derivatives(fmu, states_der, n_states);
		for (k = 0; k < n_states; k++) {
			states[k] = states[k] + hcur*states_der[k];	
			if (k == 0) printf("Ball height state[%u] = %f\n", (unsigned)k, states[k]);
		}

		/* Set states */
		fmistatus = fmi2_import_set_continuous_states(fmu, states, n_states);
		/* Step is complete */
		fmistatus = fmi2_import_completed_integrator_step(fmu, fmi2_true, &callEventUpdate,
                                                          &terminateSimulation);
	}	

	/* Validate result */
	for (k = 0; k < n_states; k++) {
		fmi2_real_t res = states[k] - states_end_results[k];
		res = res > 0 ? res: -res; /* Take abs */
		if (res > 1e-10) {
			printf("Simulation results is wrong  states[%u] %f != %f, |res| = %f\n", (unsigned)k, states[k], states_end_results[k], res);
			do_exit(CTEST_RETURN_FAIL);
		}
	}
	

	fmistatus = fmi2_import_terminate(fmu);

	fmi2_import_free_instance(fmu);

	free(states);
	free(states_der);
	free(event_indicators);
	free(event_indicators_prev);

	return 0;
}