def test_read_all_variables_using_model_variables(self): simple_alias = Dummy_FMUModelME2([("x", "y")], "NegatedAlias.fmu", os.path.join(file_path, "files", "FMUs", "XML", "ME2.0"), _connect_dll=False) opts = simple_alias.simulate_options() opts["result_handling"] = "custom" opts["result_handler"] = ResultHandlerBinaryFile(simple_alias) res = simple_alias.simulate(options=opts) for var in simple_alias.get_model_variables(): res[var]
def test_only_parameters(self): model = Dummy_FMUModelME2([], "ParameterAlias.fmu", os.path.join(file_path, "files", "FMUs", "XML", "ME2.0"), _connect_dll=False) opts = model.simulate_options() opts["result_handling"] = "custom" opts["result_handler"] = ResultHandlerBinaryFile(model) opts["filter"] = "p2" res = model.simulate(options=opts) nose.tools.assert_almost_equal(3.0, res["p2"][0])
def test_only_parameters(self): model = load_fmu("ParameterAlias.fmu") opts = model.simulate_options() opts["result_handling"] = "custom" opts["result_handler"] = ResultHandlerBinaryFile(model) opts["filter"] = "p2" res = model.simulate(options=opts) nose.tools.assert_almost_equal(model.get("p2"), res["p2"][0])
def test_enumeration_binary(self): model = Dummy_FMUModelME2([], "Friction2.fmu", os.path.join(file_path, "files", "FMUs", "XML", "ME2.0"), _connect_dll=False) data_type = model.get_variable_data_type("mode") assert data_type == fmi.FMI2_ENUMERATION opts = model.simulate_options() opts["result_handling"] = "custom" opts["result_handler"] = ResultHandlerBinaryFile(model) res = model.simulate(options=opts) res["mode"] #Check that the enumeration variable is in the dict, otherwise exception
def test_variable_alias_custom_handler(self): simple_alias = Dummy_FMUModelME2([("x", "y")], "NegatedAlias.fmu", os.path.join(file_path, "files", "FMUs", "XML", "ME2.0"), _connect_dll=False) opts = simple_alias.simulate_options() opts["result_handling"] = "custom" opts["result_handler"] = ResultHandlerBinaryFile(simple_alias) res = simple_alias.simulate(options=opts) # test that res['y'] returns a vector of the same length as the time # vector nose.tools.assert_equal(len(res['y']),len(res['time']), "Wrong size of result vector.") x = res["x"] y = res["y"] for i in range(len(x)): nose.tools.assert_equal(x[i], -y[i])
def test_variable_alias(self): simple_alias = load_fmu("NegatedAlias.fmu") opts = simple_alias.simulate_options() opts["result_handling"] = "custom" opts["result_handler"] = ResultHandlerBinaryFile(simple_alias) res = simple_alias.simulate(options=opts) # test that res['y'] returns a vector of the same length as the time # vector nose.tools.assert_equal(len(res['y']), len(res['time']), "Wrong size of result vector.") x = res["x"] y = res["y"] for i in range(len(x)): nose.tools.assert_equal(x[i], -y[i])
def __init__(self, start_time, final_time, input, model, options): """ Simulation algortihm for FMUs (Co-simulation). Parameters:: model -- fmi.FMUModelCS1 object representation of the model. options -- The options that should be used in the algorithm. For details on the options, see: * model.simulate_options('FMICSAlgOptions') or look at the docstring with help: * help(pyfmi.fmi_algorithm_drivers.FMICSAlgOptions) Valid values are: - A dict that overrides some or all of the default values provided by FMICSAlgOptions. An empty dict will thus give all options with default values. - FMICSAlgOptions object. """ self.model = model self.timings = {} self.time_start_total = timer() # set start time, final time and input trajectory self.start_time = start_time self.final_time = final_time self.input = input self.status = 0 # handle options argument if isinstance(options, dict) and not \ isinstance(options, FMICSAlgOptions): # user has passed dict with options or empty dict = default self.options = FMICSAlgOptions(options) elif isinstance(options, FMICSAlgOptions): # user has passed FMICSAlgOptions instance self.options = options else: raise InvalidAlgorithmOptionException(options) # set options self._set_options() input_traj = None if self.input: if hasattr(self.input[1],"__call__"): input_traj=(self.input[0], TrajectoryUserFunction(self.input[1])) else: input_traj=(self.input[0], TrajectoryLinearInterpolation(self.input[1][:,0], self.input[1][:,1:])) #Sets the inputs, if any self.model.set(input_traj[0], input_traj[1].eval(self.start_time)[0,:]) self.input_traj = input_traj #time_start = timer() if self.options["result_handling"] == "file": self.result_handler = ResultHandlerFile(self.model) elif self.options["result_handling"] == "binary": self.result_handler = ResultHandlerBinaryFile(self.model) elif self.options["result_handling"] == "memory": self.result_handler = ResultHandlerMemory(self.model) elif self.options["result_handling"] == "csv": self.result_handler = ResultHandlerCSV(self.model, delimiter=",") elif self.options["result_handling"] == "custom": self.result_handler = self.options["result_handler"] if self.result_handler is None: raise fmi.FMUException("The result handler needs to be specified when using a custom result handling.") if not isinstance(self.result_handler, ResultHandler): raise fmi.FMUException("The result handler needs to be a subclass of ResultHandler.") elif self.options["result_handling"] == "none": #No result handling (for performance) self.result_handler = ResultHandlerDummy(self.model) else: raise fmi.FMUException("Unknown option to result_handling.") self.result_handler.set_options(self.options) time_end = timer() #self.timings["creating_result_object"] = time_end - time_start time_start = time_end time_res_init = 0.0 # Initialize? if self.options['initialize']: if isinstance(self.model, fmi.FMUModelCS1) or isinstance(self.model, fmi_extended.FMUModelME1Extended): self.model.initialize(start_time, final_time, stop_time_defined=self.options["stop_time_defined"]) elif isinstance(self.model, fmi.FMUModelCS2): self.model.setup_experiment(start_time=start_time, stop_time_defined=self.options["stop_time_defined"], stop_time=final_time) self.model.initialize() else: raise fmi.FMUException("Unknown model.") time_res_init = timer() self.result_handler.initialize_complete() time_res_init = timer() - time_res_init elif self.model.time is None and isinstance(self.model, fmi.FMUModelCS2): raise fmi.FMUException("Setup Experiment has not been called, this has to be called prior to the initialization call.") elif self.model.time is None: raise fmi.FMUException("The model need to be initialized prior to calling the simulate method if the option 'initialize' is set to False") if abs(start_time - model.time) > 1e-14: logging.warning('The simulation start time (%f) and the current time in the model (%f) is different. Is the simulation start time correctly set?'%(start_time, model.time)) time_end = timer() self.timings["initializing_fmu"] = time_end - time_start - time_res_init time_start = time_end self.result_handler.simulation_start() self.timings["initializing_result"] = timer() - time_start - time_res_init
def __init__(self, start_time, final_time, input, model, options): """ Create a simulation algorithm using Assimulo. Parameters:: model -- fmi.FMUModel object representation of the model. options -- The options that should be used in the algorithm. For details on the options, see: * model.simulate_options('AssimuloFMIAlgOptions') or look at the docstring with help: * help(pyfmi.fmi_algorithm_drivers.AssimuloFMIAlgOptions) Valid values are: - A dict that overrides some or all of the default values provided by AssimuloFMIAlgOptions. An empty dict will thus give all options with default values. - AssimuloFMIAlgOptions object. """ self.model = model self.timings = {} self.time_start_total = timer() try: import assimulo except: raise fmi.FMUException( 'Could not find Assimulo package. Check pyfmi.check_packages()') # import Assimulo dependent classes from pyfmi.simulation.assimulo_interface import FMIODE, FMIODESENS, FMIODE2, FMIODESENS2 # set start time, final time and input trajectory self.start_time = start_time self.final_time = final_time self.input = input # handle options argument if isinstance(options, dict) and not \ isinstance(options, AssimuloFMIAlgOptions): # user has passed dict with options or empty dict = default self.options = AssimuloFMIAlgOptions(options) elif isinstance(options, AssimuloFMIAlgOptions): # user has passed AssimuloFMIAlgOptions instance self.options = options else: raise InvalidAlgorithmOptionException(options) # set options self._set_options() #time_start = timer() input_traj = None if self.input: if hasattr(self.input[1],"__call__"): input_traj=(self.input[0], TrajectoryUserFunction(self.input[1])) else: input_traj=(self.input[0], TrajectoryLinearInterpolation(self.input[1][:,0], self.input[1][:,1:])) #Sets the inputs, if any input_names = [input_traj[0]] if isinstance(input_traj[0],str) else input_traj[0] input_values = input_traj[1].eval(self.start_time)[0,:] if len(input_names) != len(input_values): raise fmi.FMUException("The number of input variables is not equal to the number of input values, please verify the input object.") self.model.set(input_names, input_values) if self.options["result_handling"] == "file": self.result_handler = ResultHandlerFile(self.model) elif self.options["result_handling"] == "binary": if self.options["sensitivities"]: logging.warning('The binary result file do not currently support storing of sensitivity results. Switching to textual result format.') self.result_handler = ResultHandlerFile(self.model) else: self.result_handler = ResultHandlerBinaryFile(self.model) elif self.options["result_handling"] == "memory": self.result_handler = ResultHandlerMemory(self.model) elif self.options["result_handling"] == "csv": self.result_handler = ResultHandlerCSV(self.model, delimiter=",") elif self.options["result_handling"] == "custom": self.result_handler = self.options["result_handler"] if self.result_handler is None: raise fmi.FMUException("The result handler needs to be specified when using a custom result handling.") if not isinstance(self.result_handler, ResultHandler): raise fmi.FMUException("The result handler needs to be a subclass of ResultHandler.") elif self.options["result_handling"] == "none": #No result handling (for performance) self.result_handler = ResultHandlerDummy(self.model) else: raise fmi.FMUException("Unknown option to result_handling.") self.result_handler.set_options(self.options) time_end = timer() #self.timings["creating_result_object"] = time_end - time_start time_start = time_end time_res_init = 0.0 # Initialize? if self.options['initialize']: try: rtol = self.solver_options['rtol'] except KeyError: rtol, atol = self.model.get_tolerances() if isinstance(self.model, fmi.FMUModelME1): self.model.time = start_time #Set start time before initialization self.model.initialize(tolerance=rtol) elif isinstance(self.model, fmi.FMUModelME2) or isinstance(self.model, fmi_coupled.CoupledFMUModelME2): self.model.setup_experiment(tolerance=rtol, start_time=self.start_time, stop_time=self.final_time) self.model.initialize() self.model.event_update() self.model.enter_continuous_time_mode() else: raise fmi.FMUException("Unknown model.") time_res_init = timer() self.result_handler.initialize_complete() time_res_init = timer() - time_res_init elif self.model.time is None and isinstance(self.model, fmi.FMUModelME2): raise fmi.FMUException("Setup Experiment has not been called, this has to be called prior to the initialization call.") elif self.model.time is None: raise fmi.FMUException("The model need to be initialized prior to calling the simulate method if the option 'initialize' is set to False") #See if there is an time event at start time if isinstance(self.model, fmi.FMUModelME1): event_info = self.model.get_event_info() if event_info.upcomingTimeEvent and event_info.nextEventTime == model.time: self.model.event_update() if abs(start_time - model.time) > 1e-14: logging.warning('The simulation start time (%f) and the current time in the model (%f) is different. Is the simulation start time correctly set?'%(start_time, model.time)) time_end = timer() self.timings["initializing_fmu"] = time_end - time_start - time_res_init time_start = time_end self.result_handler.simulation_start() self.timings["initializing_result"] = timer() - time_start + time_res_init # Sensitivities? if self.options["sensitivities"]: if self.model.get_generation_tool() != "JModelica.org" and \ self.model.get_generation_tool() != "Optimica Compiler Toolkit": if isinstance(self.model, fmi.FMUModelME2): for var in self.options["sensitivities"]: causality = self.model.get_variable_causality(var) if causality != fmi.FMI2_INPUT: raise fmi.FMUException("The sensitivity parameter is not specified as an input which is required.") else: raise fmi.FMUException("Sensitivity calculations only possible with JModelica.org generated FMUs") if self.options["solver"] != "CVode": raise fmi.FMUException("Sensitivity simulations currently only supported using the solver CVode.") #Checks to see if all the sensitivities are inside the model #else there will be an exception self.model.get(self.options["sensitivities"]) if not self.input and (isinstance(self.model, fmi.FMUModelME2) or isinstance(self.model, fmi_coupled.CoupledFMUModelME2)): if self.options["sensitivities"]: self.probl = FMIODESENS2(self.model, result_file_name=self.result_file_name, with_jacobian=self.with_jacobian, start_time=self.start_time, parameters=self.options["sensitivities"],logging=self.options["logging"], result_handler=self.result_handler) else: self.probl = FMIODE2(self.model, result_file_name=self.result_file_name, with_jacobian=self.with_jacobian, start_time=self.start_time,logging=self.options["logging"], result_handler=self.result_handler,extra_equations=self.options["extra_equations"]) elif isinstance(self.model, fmi.FMUModelME2) or isinstance(self.model, fmi_coupled.CoupledFMUModelME2): if self.options["sensitivities"]: self.probl = FMIODESENS2( self.model, input_traj, result_file_name=self.result_file_name, with_jacobian=self.with_jacobian, start_time=self.start_time,parameters=self.options["sensitivities"],logging=self.options["logging"], result_handler=self.result_handler) else: self.probl = FMIODE2( self.model, input_traj, result_file_name=self.result_file_name, with_jacobian=self.with_jacobian, start_time=self.start_time,logging=self.options["logging"], result_handler=self.result_handler, extra_equations=self.options["extra_equations"]) elif not self.input: if self.options["sensitivities"]: self.probl = FMIODESENS(self.model, result_file_name=self.result_file_name,with_jacobian=self.with_jacobian,start_time=self.start_time,parameters=self.options["sensitivities"],logging=self.options["logging"], result_handler=self.result_handler) else: self.probl = FMIODE(self.model, result_file_name=self.result_file_name,with_jacobian=self.with_jacobian,start_time=self.start_time,logging=self.options["logging"], result_handler=self.result_handler) else: if self.options["sensitivities"]: self.probl = FMIODESENS( self.model, input_traj, result_file_name=self.result_file_name,with_jacobian=self.with_jacobian,start_time=self.start_time,parameters=self.options["sensitivities"],logging=self.options["logging"], result_handler=self.result_handler) else: self.probl = FMIODE( self.model, input_traj, result_file_name=self.result_file_name,with_jacobian=self.with_jacobian,start_time=self.start_time,logging=self.options["logging"], result_handler=self.result_handler) # instantiate solver and set options self.simulator = self.solver(self.probl) self._set_solver_options()
def test_work_flow_me2(self): model = Dummy_FMUModelME2([], "bouncingBall.fmu", os.path.join(file_path, "files", "FMUs", "XML", "ME2.0"), _connect_dll=False) model.setup_experiment() model.initialize() bouncingBall = ResultHandlerBinaryFile(model) bouncingBall.set_options(model.simulate_options()) bouncingBall.simulation_start() bouncingBall.initialize_complete() bouncingBall.integration_point() bouncingBall.simulation_end() res = ResultDymolaBinary('bouncingBall_result.mat') h = res.get_variable_data('h') derh = res.get_variable_data('der(h)') g = res.get_variable_data('g') nose.tools.assert_almost_equal(h.x[0], 1.000000, 5) nose.tools.assert_almost_equal(derh.x[0], 0.000000, 5)
def test_description_not_stored(self): model = Dummy_FMUModelME1([], "CoupledClutches.fmu", os.path.join(file_path, "files", "FMUs", "XML", "ME1.0"), _connect_dll=False) model.initialize() opts = model.simulate_options() opts["result_store_variable_description"] = False result_writer = ResultHandlerBinaryFile(model) result_writer.set_options(opts) result_writer.simulation_start() result_writer.initialize_complete() result_writer.integration_point() result_writer.simulation_end() res = ResultDymolaBinary('CoupledClutches_result.mat') assert res.description[res.get_variable_index("J1.phi")] == "", "Description is not empty, " + res.description[res.get_variable_index("J1.phi")]
def test_get_description(self): model = Dummy_FMUModelME1([], "CoupledClutches.fmu", os.path.join(file_path, "files", "FMUs", "XML", "ME1.0"), _connect_dll=False) model.initialize() result_writer = ResultHandlerBinaryFile(model) result_writer.set_options(model.simulate_options()) result_writer.simulation_start() result_writer.initialize_complete() result_writer.integration_point() result_writer.simulation_end() res = ResultDymolaBinary('CoupledClutches_result.mat') assert res.description[res.get_variable_index("J1.phi")] == "Absolute rotation angle of component"
def test_get_description_unicode(self): model = Dummy_FMUModelME1([], "Description.fmu", os.path.join(file_path, "files", "FMUs", "XML", "ME1.0"), _connect_dll=False) model.initialize() result_writer = ResultHandlerBinaryFile(model) result_writer.set_options(model.simulate_options()) result_writer.simulation_start() result_writer.initialize_complete() result_writer.integration_point() result_writer.simulation_end() res = ResultDymolaBinary('Description_result.mat') desc = res.description[res.get_variable_index("x")] #This handling should in the future be nativly handled by the IO module desc = desc.encode("latin_1", "replace").decode("utf-8", "replace") assert desc == u"Test symbols '' ‘’"
def test_filter_no_variables(self): model = Dummy_FMUModelME2([], "bouncingBall.fmu", os.path.join(file_path, "files", "FMUs", "XML", "ME2.0"), _connect_dll=False) model.setup_experiment() model.initialize() model.time = 1.0 opts = model.simulate_options() opts["filter"] = "NoMatchingVariables" bouncingBall = ResultHandlerBinaryFile(model) bouncingBall.set_options(opts) bouncingBall.simulation_start() bouncingBall.initialize_complete() bouncingBall.integration_point() bouncingBall.simulation_end() res = ResultDymolaBinary('bouncingBall_result.mat') t = res.get_variable_data('time') nose.tools.assert_almost_equal(t.x[-1], 1.000000, 5)