def atest_identicalNamesSameTypes_throws(): with pytest.raises(Exception): with ExampleArchive('Adder') as a, ExampleArchive('Adder') as b: md_a = read_model_description(str(b.root)) md_b = read_model_description(str(a.root)) instance_a = 'a' instance_b = 'a' fmu_a = FMU2Slave( guid=md_a.guid, unzipDirectory=a.root, modelIdentifier=md_a.coSimulation.modelIdentifier, instanceName=instance_a, fmiCallLogger=None) fmu_b = FMU2Slave( guid=md_b.guid, unzipDirectory=b.root, modelIdentifier=md_b.coSimulation.modelIdentifier, instanceName=instance_b, fmiCallLogger=None) fmu_a.instantiate() fmu_b.instantiate()
def test_generate_model_description_generates_valid_model_description(tmp_path): filename = str(tmp_path / "modelDescription.xml") model_description = generate_model_description( model_name="Test Model", model_identifier="test-model", guid=str(uuid4()), inputs=["x", "y"], outputs=["z"], ) try: model_description.write(filename, encoding="utf-8", xml_declaration=True) read_model_description(filename, validate_model_structure=True) except Exception as e: pytest.fail(str(e))
def test_multipleInstantiationsAllDifferentInstanceNames_canSimulate(): for idx, pname in enumerate(get_correct_examples()): with ExampleArchive(pname) as archive: print(archive.model_description) # seems like fmpy does not accept Path objects path = str(archive.root) md = read_model_description(str(archive.root)) instance_a = str(idx) + 'a' instance_b = str(idx) + 'b' fmu_a = FMU2Slave(guid=md.guid, unzipDirectory=archive.root, modelIdentifier=md.coSimulation.modelIdentifier, instanceName=instance_a, fmiCallLogger=None) fmu_b = FMU2Slave(guid=md.guid, unzipDirectory=archive.root, modelIdentifier=md.coSimulation.modelIdentifier, instanceName=instance_b, fmiCallLogger=None) fmu_a.instantiate() fmu_b.instantiate()
def __init__(self, fmu_path, opts=None): self.logger = logging.getLogger(type(self).__name__) try: self.logger.debug("Loading FMU") self.fmu_path = fmu_path self.model_description = read_model_description(self.fmu_path) self.fmu_args = { 'guid': self.model_description.guid, 'modelIdentifier': self.model_description.coSimulation.modelIdentifier, 'instanceName': None, 'fmiCallLogger': None } except Exception as e: self.logger.error(e) self.opts = opts self.start = None self.end = None self.timeline = None self.input_names = list() self.input_values = list() self.output_names = list() self.parameter_names = list() self.input = None self.parameter_df = pd.DataFrame() self.res = None
def add_fmu(self, fmu_name, fmu_loc, step_size, inputs = [], outputs=[], exist=False, solver_name = 'Cvode', variable=False, **kwargs): if 'validate' in kwargs.keys(): validate=kwargs['validate'] else: validate=True m_desc = read_model_description(fmu_loc, validate=validate) fmi_type = 'CoSimulation' if m_desc.coSimulation is not None else 'ModelExchange' if fmi_type == 'CoSimulation': fmu_temp = FmuCsAdapter(fmu_loc, instanceName=fmu_name, step_size = step_size, inputs = inputs, outputs=outputs, exist=exist, validate=validate) elif fmi_type == 'ModelExchange': fmu_temp = FmuMeAdapter(fmu_loc, instanceName=fmu_name, step_size = step_size, inputs = inputs, outputs=outputs, solver_name = solver_name, validate=validate) if fmu_name not in self.simulator_dict.keys(): self.simulator_dict[fmu_name] = ['fmu', fmu_temp, step_size, outputs, variable] if self.logging: print("Added FMU simulator '%s' to the world" %(fmu_name)) else: print(f"Please specify a unique name for simulator. {fmu_name} already exists.")
def simulate_fmu(filename, validate=True, start_time=None, stop_time=None, step_size=None, sample_interval=None, fmi_type=None, start_values={}, input=None, output=None, timeout=None, fmi_logging=False): modelDescription = read_model_description(filename, validate=validate) if fmi_type is None: # determine the FMI type automatically fmi_type = 'CoSimulation' if modelDescription.coSimulation is not None else 'ModelExchange' defaultExperiment = modelDescription.defaultExperiment if start_time is None: if defaultExperiment is not None and defaultExperiment.startTime is not None: start_time = defaultExperiment.startTime else: start_time = 0.0 if stop_time is None: if defaultExperiment is not None: stop_time = defaultExperiment.stopTime else: stop_time = 1.0 if step_size is None: total_time = stop_time - start_time step_size = 10**(np.round(np.log10(total_time)) - 3) unzipdir = extract(filename) if fmi_type == 'ModelExchange': simfun = simulateME1 if modelDescription.fmiVersion == '1.0' else simulateME2 elif fmi_type == 'CoSimulation': simfun = simulateCS else: raise Exception( 'fmi_tpye must be either "ModelExchange" or "CoSimulation"') if sample_interval is None: sample_interval = (stop_time - start_time) / 500 # simulate_fmu the FMU result = simfun(modelDescription, unzipdir, start_time, stop_time, step_size, start_values, input, output, sample_interval, timeout, fmi_logging) # clean up shutil.rmtree(unzipdir) return result
def test_bicycle(): with ExampleArchive('BicycleKinematic') as a: md_a = read_model_description(str(a.root)) fmu_a = FMU2Slave(guid=md_a.guid, unzipDirectory=a.root, modelIdentifier=md_a.coSimulation.modelIdentifier, instanceName='a', fmiCallLogger=None) fmu_a.instantiate() fmu_a.doStep(0, 1)
def setUpClass(cls): # store various useful FMU arguments from the model description cls._model_description = read_model_description(fmu_path) cls._fmi_types = [] if cls._model_description.coSimulation is not None: cls._fmi_types.append('CoSimulation') if cls._model_description.modelExchange is not None: cls._fmi_types.append('ModelExchange') if not cls._fmi_types: raise Exception('fmi_type must contain at least "ModelExchange" or "CoSimulation"') cls._experiment = cls._model_description.defaultExperiment if cls._experiment is not None and cls._experiment.startTime is not None: cls._start_time = cls._experiment.startTime else: cls._start_time = 0.0 start_time = float(cls._start_time) if cls._experiment is not None and cls._experiment.stopTime is not None: cls._stop_time = cls._experiment.stopTime else: cls._stop_time = start_time + 1.0 stop_time = float(cls._stop_time) if cls._experiment is not None: cls._relative_tolerance = cls._experiment.tolerance total_time = stop_time - start_time cls._step_size = 10 ** (np.round(np.log10(total_time)) - 3) if 'CoSimulation' in cls._fmi_types and cls._experiment is not None and cls._experiment.stepSize is not None: cls._output_interval = cls._experiment.stepSize while (stop_time - start_time) / cls._output_interval > 1000: cls._output_interval *= 2 if path.isfile(path.join(fmu_path, 'modelDescription.xml')): cls._unzipdir = fmu_path cls._tempdir = None else: cls._tempdir = extract(fmu_path) cls._unzipdir = cls._tempdir
def test_Adder(): with ExampleArchive('Adder') as a: md_a = read_model_description(str(a.root)) instance_a = 'a' fmu_a = FMU2Slave(guid=md_a.guid, unzipDirectory=a.root, modelIdentifier=md_a.coSimulation.modelIdentifier, instanceName=instance_a, fmiCallLogger=None) fmu_a.instantiate() # set input a fmu_a.setReal([1], [1]) # set input b fmu_a.setReal([2], [2]) fmu_a.doStep(0, 1) # read output s = fmu_a.getReal([0])[0] assert s == 3
def simulate_fmu(filename, validate=True, start_time=None, stop_time=None, solver='CVode', step_size=None, relative_tolerance=None, output_interval=None, record_events=True, fmi_type=None, use_source_code=False, start_values={}, apply_default_start_values=False, input=None, output=None, timeout=None, debug_logging=False, logger=None, fmi_call_logger=None, step_finished=None, model_description=None): """ Simulate an FMU Parameters: filename filename of the FMU or directory with extracted FMU validate validate the FMU start_time simulation start time (None: use default experiment or 0 if not defined) stop_time simulation stop time (None: use default experiment or start_time + 1 if not defined) solver solver to use for model exchange ('Euler' or 'CVode') step_size step size for the 'Euler' solver relative_tolerance relative tolerance for the 'CVode' solver output_interval interval for sampling the output record_events record outputs at events (model exchange only) fmi_type FMI type for the simulation (None: determine from FMU) use_source_code compile the shared library (requires C sources) start_values dictionary of variable name -> value pairs apply_default_start_values apply the start values from the model description input a structured numpy array that contains the input (see :class:`Input`) output list of variables to record (None: record outputs) timeout timeout for the simulation debug_logging enable the FMU's debug logging fmi_call_logger callback function to log FMI calls logger callback function passed to the FMU (experimental) step_finished callback to interact with the simulation (experimental) model_description the previously loaded model description (experimental) Returns: result a structured numpy array that contains the result """ from fmpy import supported_platforms from fmpy.model_description import read_model_description if not use_source_code and platform not in supported_platforms(filename): raise Exception( "The current platform (%s) is not supported by the FMU." % platform) if model_description is None: model_description = read_model_description(filename, validate=validate) else: model_description = model_description if fmi_type is None: # determine the FMI type automatically fmi_type = 'CoSimulation' if model_description.coSimulation is not None else 'ModelExchange' if fmi_type not in ['ModelExchange', 'CoSimulation']: raise Exception( 'fmi_type must be one of "ModelExchange" or "CoSimulation"') experiment = model_description.defaultExperiment if start_time is None: if experiment is not None and experiment.startTime is not None: start_time = experiment.startTime else: start_time = 0.0 if stop_time is None: if experiment is not None and experiment.stopTime is not None: stop_time = experiment.stopTime else: stop_time = start_time + 1.0 if relative_tolerance is None: if experiment is not None and experiment.tolerance is not None: relative_tolerance = experiment.tolerance else: relative_tolerance = 1e-5 if step_size is None: total_time = stop_time - start_time step_size = 10**(np.round(np.log10(total_time)) - 3) if os.path.isfile(os.path.join(filename, 'modelDescription.xml')): unzipdir = filename tempdir = None else: tempdir = extract(filename) unzipdir = tempdir # common FMU constructor arguments fmu_args = { 'guid': model_description.guid, 'unzipDirectory': unzipdir, 'instanceName': None, 'fmiCallLogger': fmi_call_logger } if use_source_code: from .util import compile_dll # compile the shared library from the C sources fmu_args['libraryPath'] = compile_dll( model_description=model_description, sources_dir=os.path.join(unzipdir, 'sources')) if logger is None: logger = printLogMessage if model_description.fmiVersion == '1.0': callbacks = fmi1CallbackFunctions() callbacks.logger = fmi1CallbackLoggerTYPE(logger) callbacks.allocateMemory = fmi1CallbackAllocateMemoryTYPE( allocateMemory) callbacks.freeMemory = fmi1CallbackFreeMemoryTYPE(freeMemory) callbacks.stepFinished = None else: callbacks = fmi2CallbackFunctions() callbacks.logger = fmi2CallbackLoggerTYPE(logger) callbacks.allocateMemory = fmi2CallbackAllocateMemoryTYPE( allocateMemory) callbacks.freeMemory = fmi2CallbackFreeMemoryTYPE(freeMemory) # simulate_fmu the FMU if fmi_type == 'ModelExchange' and model_description.modelExchange is not None: fmu_args[ 'modelIdentifier'] = model_description.modelExchange.modelIdentifier result = simulateME(model_description, fmu_args, start_time, stop_time, solver, step_size, relative_tolerance, start_values, apply_default_start_values, input, output, output_interval, record_events, timeout, callbacks, debug_logging, step_finished) elif fmi_type == 'CoSimulation' and model_description.coSimulation is not None: fmu_args[ 'modelIdentifier'] = model_description.coSimulation.modelIdentifier result = simulateCS(model_description, fmu_args, start_time, stop_time, start_values, apply_default_start_values, input, output, output_interval, timeout, callbacks, debug_logging, step_finished) else: raise Exception('FMI type "%s" is not supported by the FMU' % fmi_type) # clean up if tempdir is not None: shutil.rmtree(tempdir) return result
def simulate_fmu(filename, validate=True, start_time=None, stop_time=None, solver='CVode', step_size=None, relative_tolerance=None, output_interval=None, record_events=True, fmi_type=None, start_values={}, apply_default_start_values=False, input=None, output=None, timeout=None, debug_logging=False, visible=False, logger=None, fmi_call_logger=None, step_finished=None, model_description=None, fmu_instance=None): """ Simulate an FMU Parameters: filename filename of the FMU or directory with extracted FMU validate validate the FMU start_time simulation start time (None: use default experiment or 0 if not defined) stop_time simulation stop time (None: use default experiment or start_time + 1 if not defined) solver solver to use for model exchange ('Euler' or 'CVode') step_size step size for the 'Euler' solver relative_tolerance relative tolerance for the 'CVode' solver and FMI 2.0 co-simulation FMUs output_interval interval for sampling the output record_events record outputs at events (model exchange only) fmi_type FMI type for the simulation (None: determine from FMU) start_values dictionary of variable name -> value pairs apply_default_start_values apply the start values from the model description input a structured numpy array that contains the input (see :class:`Input`) output list of variables to record (None: record outputs) timeout timeout for the simulation debug_logging enable the FMU's debug logging visible interactive mode (True) or batch mode (False) fmi_call_logger callback function to log FMI calls logger callback function passed to the FMU (experimental) step_finished callback to interact with the simulation (experimental) model_description the previously loaded model description (experimental) fmu_instance the previously instantiated FMU (experimental) Returns: result a structured numpy array that contains the result """ from fmpy import supported_platforms from fmpy.model_description import read_model_description platforms = supported_platforms(filename) # use 32-bit DLL remoting use_remoting = platform == 'win64' and 'win64' not in platforms and 'win32' in platforms if fmu_instance is None and platform not in platforms and not use_remoting: raise Exception("The current platform (%s) is not supported by the FMU." % platform) if model_description is None: model_description = read_model_description(filename, validate=validate) else: model_description = model_description if fmi_type is None: if fmu_instance is not None: # determine FMI type from the FMU instance fmi_type = 'CoSimulation' if type(fmu_instance) in [FMU1Slave, FMU2Slave, fmi3.FMU3Slave] else 'ModelExchange' else: # determine the FMI type automatically fmi_type = 'CoSimulation' if model_description.coSimulation is not None else 'ModelExchange' if fmi_type not in ['ModelExchange', 'CoSimulation']: raise Exception('fmi_type must be one of "ModelExchange" or "CoSimulation"') experiment = model_description.defaultExperiment if start_time is None: if experiment is not None and experiment.startTime is not None: start_time = experiment.startTime else: start_time = 0.0 if stop_time is None: if experiment is not None and experiment.stopTime is not None: stop_time = experiment.stopTime else: stop_time = start_time + 1.0 if relative_tolerance is None and experiment is not None: relative_tolerance = experiment.tolerance if step_size is None: total_time = stop_time - start_time step_size = 10 ** (np.round(np.log10(total_time)) - 3) if output_interval is None and fmi_type == 'CoSimulation' and experiment is not None and experiment.stepSize is not None: output_interval = experiment.stepSize while (stop_time - start_time) / output_interval > 1000: output_interval *= 2 if os.path.isfile(os.path.join(filename, 'modelDescription.xml')): unzipdir = filename tempdir = None else: tempdir = extract(filename) unzipdir = tempdir if use_remoting: # start 32-bit server from subprocess import Popen server_path = os.path.dirname(__file__) server_path = os.path.join(server_path, 'remoting', 'server.exe') if fmi_type == 'ModelExchange': model_identifier = model_description.modelExchange.modelIdentifier else: model_identifier = model_description.coSimulation.modelIdentifier dll_path = os.path.join(unzipdir, 'binaries', 'win32', model_identifier + '.dll') server = Popen([server_path, dll_path]) else: server = None if fmu_instance is None: fmu = instantiate_fmu(unzipdir, model_description, fmi_type, visible, debug_logging, logger, fmi_call_logger, use_remoting) else: fmu = fmu_instance # simulate_fmu the FMU if fmi_type == 'ModelExchange': result = simulateME(model_description, fmu, start_time, stop_time, solver, step_size, relative_tolerance, start_values, apply_default_start_values, input, output, output_interval, record_events, timeout, step_finished) elif fmi_type == 'CoSimulation': result = simulateCS(model_description, fmu, start_time, stop_time, relative_tolerance, start_values, apply_default_start_values, input, output, output_interval, timeout, step_finished) if fmu_instance is None: fmu.freeInstance() if server is not None: server.kill() # clean up if tempdir is not None: shutil.rmtree(tempdir, ignore_errors=True) return result
def simulate_fmu(filename, validate=True, start_time=None, stop_time=None, solver='CVode', step_size=None, output_interval=None, fmi_type=None, start_values={}, input=None, output=None, timeout=None, fmi_logging=False): modelDescription = read_model_description(filename, validate=validate) if fmi_type is None: # determine the FMI type automatically fmi_type = 'CoSimulation' if modelDescription.coSimulation is not None else 'ModelExchange' if fmi_type not in ['ModelExchange', 'CoSimulation']: raise Exception( 'fmi_tpye must be one of "ModelExchange" or "CoSimulation"') defaultExperiment = modelDescription.defaultExperiment if start_time is None: if defaultExperiment is not None and defaultExperiment.startTime is not None: start_time = defaultExperiment.startTime else: start_time = 0.0 if stop_time is None: if defaultExperiment is not None: stop_time = defaultExperiment.stopTime else: stop_time = 1.0 if step_size is None: total_time = stop_time - start_time step_size = 10**(np.round(np.log10(total_time)) - 3) unzipdir = extract(filename) if output_interval is None: output_interval = (stop_time - start_time) / 500 # common FMU constructor arguments fmu_args = { 'guid': modelDescription.guid, 'unzipDirectory': unzipdir, 'instanceName': None, 'logFMICalls': fmi_logging } # simulate_fmu the FMU if fmi_type == 'ModelExchange': fmu_args[ 'modelIdentifier'] = modelDescription.modelExchange.modelIdentifier result = simulateME(modelDescription, fmu_args, start_time, stop_time, solver, step_size, start_values, input, output, output_interval, timeout, fmi_logging) elif fmi_type == 'CoSimulation': fmu_args[ 'modelIdentifier'] = modelDescription.coSimulation.modelIdentifier result = simulateCS(modelDescription, fmu_args, start_time, stop_time, start_values, input, output, output_interval, timeout, fmi_logging) # clean up shutil.rmtree(unzipdir) return result
def simulate_fmu(filename, validate: bool = True, start_time: Union[float, str] = None, stop_time: Union[float, str] = None, solver: str = 'CVode', step_size: Union[float, str] = None, relative_tolerance: Union[float, str] = None, output_interval: Union[float, str] = None, record_events: bool = True, fmi_type: str = None, start_values: Dict[str, Any] = {}, apply_default_start_values: bool = False, input: np.ndarray = None, output: Sequence[str] = None, timeout: Union[float, str] = None, debug_logging: bool = False, visible: bool = False, logger: Callable = None, fmi_call_logger: Callable[[str], None] = None, step_finished: Callable[[float, Recorder], bool] = None, model_description: ModelDescription = None, fmu_instance: _FMU = None, set_input_derivatives: bool = False, remote_platform: str = 'auto', early_return_allowed: bool = False, use_event_mode: bool = False, initialize: bool = True, terminate: bool = True, fmu_state: Union[bytes, c_void_p] = None) -> SimulationResult: """ Simulate an FMU Parameters: filename filename of the FMU or directory with extracted FMU validate validate the FMU and start values start_time simulation start time (None: use default experiment or 0 if not defined) stop_time simulation stop time (None: use default experiment or start_time + 1 if not defined) solver solver to use for model exchange ('Euler' or 'CVode') step_size step size for the 'Euler' solver relative_tolerance relative tolerance for the 'CVode' solver and FMI 2.0 co-simulation FMUs output_interval interval for sampling the output record_events record outputs at events (model exchange only) fmi_type FMI type for the simulation (None: determine from FMU) start_values dictionary of variable name -> value pairs apply_default_start_values apply the start values from the model description input a structured numpy array that contains the input (see :class:`Input`) output list of variables to record (None: record outputs) timeout timeout for the simulation debug_logging enable the FMU's debug logging visible interactive mode (True) or batch mode (False) fmi_call_logger callback function to log FMI calls logger callback function passed to the FMU (experimental) step_finished callback to interact with the simulation (experimental) model_description the previously loaded model description (experimental) fmu_instance the previously instantiated FMU (experimental) set_input_derivatives set the input derivatives (FMI 2.0 Co-Simulation only) remote_platform platform to use for remoting server ('auto': determine automatically if current platform is not supported, None: no remoting; experimental) early_return_allowed allow early return in FMI 3.0 Co-Simulation use_event_mode use event mode in FMI 3.0 Co-Simulation if the FMU supports it initialize initialize the FMU terminate terminate the FMU fmu_state the FMU state or serialized FMU state to initialize the FMU Returns: result a structured numpy array that contains the result """ from fmpy import supported_platforms from fmpy.model_description import read_model_description from fmpy.util import can_simulate platforms = supported_platforms(filename) if fmu_instance is None and platform not in platforms and remote_platform is None: raise Exception(f"The current platform ({platform}) is not supported by the FMU.") can_sim, remote_platform = can_simulate(platforms, remote_platform) if not can_sim: raise Exception(f"The FMU cannot be simulated on the current platform ({platform}).") if model_description is None: model_description = read_model_description(filename, validate=validate) if fmi_type is None: if fmu_instance is not None: # determine FMI type from the FMU instance fmi_type = 'CoSimulation' if type(fmu_instance) in [FMU1Slave, FMU2Slave, fmi3.FMU3Slave] else 'ModelExchange' else: # determine the FMI type automatically fmi_type = 'CoSimulation' if model_description.coSimulation is not None else 'ModelExchange' if fmi_type not in ['ModelExchange', 'CoSimulation']: raise Exception('fmi_type must be one of "ModelExchange" or "CoSimulation"') if initialize is False: if fmi_type != 'CoSimulation': raise Exception("If initialize is False, the interface type must be 'CoSimulation'.") if fmu_instance is None and fmu_state is None: raise Exception("If initialize is False, fmu_instance or fmu_state must be provided.") experiment = model_description.defaultExperiment if start_time is None: if experiment is not None and experiment.startTime is not None: start_time = experiment.startTime else: start_time = 0.0 start_time = float(start_time) if stop_time is None: if experiment is not None and experiment.stopTime is not None: stop_time = experiment.stopTime else: stop_time = start_time + 1.0 stop_time = float(stop_time) if relative_tolerance is None and experiment is not None: relative_tolerance = experiment.tolerance if step_size is None: total_time = stop_time - start_time step_size = 10 ** (np.round(np.log10(total_time)) - 3) if output_interval is None and fmi_type == 'CoSimulation': co_simulation = model_description.coSimulation if co_simulation is not None and co_simulation.fixedInternalStepSize is not None: output_interval = float(model_description.coSimulation.fixedInternalStepSize) elif experiment is not None and experiment.stepSize is not None: output_interval = float(experiment.stepSize) if output_interval is not None: while (stop_time - start_time) / output_interval > 1000: output_interval *= 2 if os.path.isfile(os.path.join(filename, 'modelDescription.xml')): unzipdir = filename tempdir = None else: required_paths = ['resources', 'binaries/'] if remote_platform: required_paths.append(os.path.join('binaries', remote_platform)) tempdir = extract(filename, include=None if remote_platform else lambda n: n.startswith(tuple(required_paths))) unzipdir = tempdir if remote_platform: add_remoting(unzipdir, host_platform=platform, remote_platform=remote_platform) if fmu_instance is None: fmu = instantiate_fmu(unzipdir, model_description, fmi_type, visible, debug_logging, logger, fmi_call_logger, None, early_return_allowed, use_event_mode) else: fmu = fmu_instance if fmu_state is not None: if model_description.fmiVersion == '2.0' or model_description.fmiVersion.startswith('3.0'): if isinstance(fmu_state, bytes): fmu_state = fmu.deserializeFMUState(fmu_state) fmu.setFMUState(fmu_state) fmu.freeFMUState(fmu_state) else: fmu.setFMUState(fmu_state) else: raise Exception(f"Setting the FMU state is not supported for FMI version {model_description.fmiVersion}.") initialize = False # simulate_fmu the FMU if fmi_type == 'ModelExchange': result = simulateME(model_description, fmu, start_time, stop_time, solver, step_size, relative_tolerance, start_values, apply_default_start_values, input, output, output_interval, record_events, timeout, step_finished, validate) elif fmi_type == 'CoSimulation': result = simulateCS(model_description, fmu, start_time, stop_time, relative_tolerance, start_values, apply_default_start_values, input, output, output_interval, timeout, step_finished, set_input_derivatives, use_event_mode, early_return_allowed, validate, initialize, terminate) if fmu_instance is None: fmu.freeInstance() # clean up if tempdir is not None: shutil.rmtree(tempdir, ignore_errors=True) return result