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 = ResultHandlerCSV(model) bouncingBall.set_options(model.simulate_options()) bouncingBall.simulation_start() bouncingBall.initialize_complete() bouncingBall.integration_point() bouncingBall.simulation_end() res = ResultCSVTextual('bouncingBall_result.csv') 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, 1.000000, 5) nose.tools.assert_almost_equal(derh.x, 0.000000, 5)
class SciEstAlg(AlgorithmBase): """ Estimation algortihm for FMUs. """ def __init__(self, parameters, measurements, input, model, options): """ Estimation algortihm for FMUs . 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('SciEstAlgOptions') or look at the docstring with help: * help(pyfmi.fmi_algorithm_drivers.SciEstAlgAlgOptions) Valid values are: - A dict that overrides some or all of the default values provided by SciEstAlgOptions. An empty dict will thus give all options with default values. - SciEstAlgOptions object. """ self.model = model # set start time, final time and input trajectory self.parameters = parameters self.measurements = measurements self.input = input # handle options argument if isinstance(options, dict) and not \ isinstance(options, SciEstAlgOptions): # user has passed dict with options or empty dict = default self.options = SciEstAlgOptions(options) elif isinstance(options, SciEstAlgOptions): # user has passed FMICSAlgOptions instance self.options = options else: raise InvalidAlgorithmOptionException(options) # set options self._set_options() self.result_handler = ResultHandlerCSV(self.model) self.result_handler.set_options(self.options) self.result_handler.initialize_complete() def _set_options(self): """ Helper function that sets options for FMICS algorithm. """ self.options["filter"] = self.parameters if isinstance(self.options["scaling"], str) and self.options["scaling"] == "Default": scale = [] for i,parameter in enumerate(self.parameters): scale.append(self.model.get_variable_nominal(parameter)) self.options["scaling"] = N.array(scale) if self.options["simulate_options"] == "Default": self.options["simulate_options"] = self.model.simulate_options() #Modifiy necessary options: self.options["simulate_options"]['ncp'] = self.measurements[1].shape[0] - 1 #Store at the same points as measurment data self.options["simulate_options"]['filter'] = self.measurements[0] #Only store the measurement variables (efficiency) if "solver" in self.options["simulate_options"]: solver = self.options["simulate_options"]["solver"] self.options["simulate_options"][solver+"_options"]["verbosity"] = 50 #Disable printout (efficiency) self.options["simulate_options"][solver+"_options"]["store_event_points"] = False #Disable extra store points def _set_solver_options(self): """ Helper function that sets options for the solver. """ pass def solve(self): """ Runs the estimation. """ import scipy as sci import scipy.optimize as sciopt from pyfmi.fmi_util import parameter_estimation_f #Define callback global niter niter = 0 def parameter_estimation_callback(y): global niter if niter % 10 == 0: print(" iter parameters ") #print '{:>5d} {:>15e}'.format(niter+1, parameter_estimation_f(y, self.parameters, self.measurements, self.model, self.input, self.options)) print('{:>5d} '.format(niter+1) + str(y)) niter += 1 #End of simulation, stop the clock time_start = timer() p0 = [] for i,parameter in enumerate(self.parameters): p0.append(self.model.get(parameter)/self.options["scaling"][i]) print('\nRunning solver: ' + self.options["method"]) print(' Initial parameters (scaled): ' + str(N.array(p0).flatten())) print(' ') res = sciopt.minimize(parameter_estimation_f, p0, args=(self.parameters, self.measurements, self.model, self.input, self.options), method=self.options["method"], bounds=None, constraints=(), tol=self.options["tolerance"], callback=parameter_estimation_callback) for i in range(len(self.parameters)): res["x"][i] = res["x"][i]*self.options["scaling"][i] self.res = res self.status = res["success"] #End of simulation, stop the clock time_stop = timer() if not res["success"]: print('Estimation failed: ' + res["message"]) else: print('\nEstimation terminated successfully!') print(' Found parameters: ' + str(res["x"])) print('Elapsed estimation time: ' + str(time_stop-time_start) + ' seconds.\n') def get_result(self): """ Write result to file, load result data and create an SciEstResult object. Returns:: The SciEstResult object. """ for i,parameter in enumerate(self.parameters): self.model.set(parameter, self.res["x"][i]) self.result_handler.simulation_start() self.model.time = self.measurements[1][0,0] self.result_handler.integration_point() self.result_handler.simulation_end() self.model.reset() for i,parameter in enumerate(self.parameters): self.model.set(parameter, self.res["x"][i]) return FMIResult(self.model, self.options["result_file_name"], None, self.result_handler.get_result(), self.options, status=self.status) @classmethod def get_default_options(cls): """ Get an instance of the options class for the SciEstAlg algorithm, prefilled with default values. (Class method.) """ return SciEstAlgOptions()
class SciEstAlg(AlgorithmBase): """ Estimation algortihm for FMUs. """ def __init__(self, parameters, measurements, input, model, options): """ Estimation algortihm for FMUs . 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('SciEstAlgOptions') or look at the docstring with help: * help(pyfmi.fmi_algorithm_drivers.SciEstAlgAlgOptions) Valid values are: - A dict that overrides some or all of the default values provided by SciEstAlgOptions. An empty dict will thus give all options with default values. - SciEstAlgOptions object. """ self.model = model # set start time, final time and input trajectory self.parameters = parameters self.measurements = measurements self.input = input # handle options argument if isinstance(options, dict) and not \ isinstance(options, SciEstAlgOptions): # user has passed dict with options or empty dict = default self.options = SciEstAlgOptions(options) elif isinstance(options, SciEstAlgOptions): # user has passed FMICSAlgOptions instance self.options = options else: raise InvalidAlgorithmOptionException(options) # set options self._set_options() self.result_handler = ResultHandlerCSV(self.model) self.result_handler.set_options(self.options) self.result_handler.initialize_complete() def _set_options(self): """ Helper function that sets options for FMICS algorithm. """ self.options["filter"] = self.parameters if isinstance(self.options["scaling"], str) and self.options["scaling"] == "Default": scale = [] for i,parameter in enumerate(self.parameters): scale.append(self.model.get_variable_nominal(parameter)) self.options["scaling"] = N.array(scale) if self.options["simulate_options"] == "Default": self.options["simulate_options"] = self.model.simulate_options() #Modifiy necessary options: self.options["simulate_options"]['ncp'] = self.measurements[1].shape[0] - 1 #Store at the same points as measurment data self.options["simulate_options"]['filter'] = self.measurements[0] #Only store the measurement variables (efficiency) if "solver" in self.options["simulate_options"]: solver = self.options["simulate_options"]["solver"] self.options["simulate_options"][solver+"_options"]["verbosity"] = 50 #Disable printout (efficiency) self.options["simulate_options"][solver+"_options"]["store_event_points"] = False #Disable extra store points def _set_solver_options(self): """ Helper function that sets options for the solver. """ pass def solve(self): """ Runs the estimation. """ import scipy as sci import scipy.optimize as sciopt from pyfmi.fmi_util import parameter_estimation_f #Define callback global niter niter = 0 def parameter_estimation_callback(y): global niter if niter % 10 == 0: print(" iter parameters ") #print '{:>5d} {:>15e}'.format(niter+1, parameter_estimation_f(y, self.parameters, self.measurements, self.model, self.input, self.options)) print('{:>5d} '.format(niter+1) + str(y)) niter += 1 #End of simulation, stop the clock time_start = timer() p0 = [] for i,parameter in enumerate(self.parameters): p0.append(self.model.get(parameter)/self.options["scaling"][i]) print('\nRunning solver: ' + self.options["method"]) print(' Initial parameters (scaled): ' + str(N.array(p0).flatten())) print(' ') res = sciopt.minimize(parameter_estimation_f, p0, args=(self.parameters, self.measurements, self.model, self.input, self.options), method=self.options["method"], bounds=None, constraints=(), tol=self.options["tolerance"], callback=parameter_estimation_callback) for i in range(len(self.parameters)): res["x"][i] = res["x"][i]*self.options["scaling"][i] self.res = res self.status = res["success"] #End of simulation, stop the clock time_stop = timer() if not res["success"]: print('Estimation failed: ' + res["message"]) else: print('\nEstimation terminated successfully!') print(' Found parameters: ' + str(res["x"])) print('Elapsed estimation time: ' + str(time_stop-time_start) + ' seconds.\n') def get_result(self): """ Write result to file, load result data and create an SciEstResult object. Returns:: The SciEstResult object. """ for i,parameter in enumerate(self.parameters): self.model.set(parameter, self.res["x"][i]) self.result_handler.simulation_start() self.model.time = self.measurements[1][0,0] self.result_handler.integration_point() self.result_handler.simulation_end() self.model.reset() for i,parameter in enumerate(self.parameters): self.model.set(parameter, self.res["x"][i]) return FMIResult(self.model, self.options["result_file_name"], None, self.result_handler.get_result(), self.options, status=self.status) @classmethod def get_default_options(cls): """ Get an instance of the options class for the SciEstAlg algorithm, prefilled with default values. (Class method.) """ return SciEstAlgOptions()