Exemple #1
0
 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]
Exemple #2
0
 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])
Exemple #4
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
Exemple #5
0
 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])
Exemple #7
0
    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
Exemple #8
0
    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()
Exemple #9
0
    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)
Exemple #10
0
 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")]
Exemple #11
0
 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"
Exemple #12
0
 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 '' ‘’"
Exemple #13
0
    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)