def __init__(self, fmu_location, instanceName=None, start_time=0, tolerance=1e-06, stop_time=100, step_size=1.0e-3, inputs=[], outputs=[], solver_name='Cvode', show_fmu_info=False, exist=False, validate=True): assert (fmu_location is not None), "Must specify FMU location" self.fmu_location = fmu_location if instanceName is None: instanceID = int(random() * 1000) self.instanceName = 'fmu' + str(instanceID) print('FMU instance created as: ' + self.instanceName) else: self.instanceName = instanceName self.tolerance = tolerance self.start_time = start_time self.stop_time = stop_time self.step_size = step_size self.inputs = inputs self.outputs = outputs self.solver_name = solver_name self.validate = validate if show_fmu_info: dump(self.fmu_location) self.exist = exist self.setup()
def validate(fmu_archive: str, use_fmpy: bool = True, use_fmucheck: bool = False, use_vdmcheck: bool = False): if (use_fmpy and not has_fmpy()): raise ImportError( "Cannot validate exported module using fmpy, the module could not be loaded. Ensure that the package is installed." ) valid = True if (use_fmpy): from fmpy import dump, simulate_fmu dump(fmu_archive) try: res = simulate_fmu(fmu_archive) except Exception as e: valid = False return repr(e) return None
def main(): import argparse import textwrap description = """\ Simulate an FMU Example: > python -m fmpy.simulate Rectifier.fmu """ parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description=textwrap.dedent(description)) parser.add_argument('command', choices=['info', 'simulate'], help="Command to execute") parser.add_argument('fmu_filename', help="filename of the FMU") parser.add_argument('--solver', choices=['Euler', 'CVode'], default='CVode', help="solver to use for Model Exchange") parser.add_argument('--input-file', help="CSV file to use as input") parser.add_argument('--output-variables', nargs='+', help="Variables to record") parser.add_argument('--output-file', help="CSV to store the results") parser.add_argument('--num-samples', default=500, type=int, help="number of samples to record") parser.add_argument('--step-size', type=float, help="step size for fixed-step solvers") parser.add_argument('--start-time', type=float, help="start time for the simulation") parser.add_argument('--stop-time', type=float, help="stop time for the simulation") parser.add_argument('--show-plot', action='store_true', help="plot the results") parser.add_argument('--timeout', type=float, help="max. time to wait for the simulation to finish") parser.add_argument('--fmi-logging', action='store_true', help="enable FMI logging") parser.add_argument('--start-values', nargs='+', help="name-value pairs of start values") args = parser.parse_args() if args.command == 'info': from fmpy import dump dump(args.fmu_filename) elif args.command == 'simulate': from fmpy import simulate_fmu from fmpy.util import read_csv, write_csv, plot_result if args.start_values: if len(args.start_values) % 2 != 0: raise Exception("Start values must be name-value pairs.") start_values = { k: v for k, v in zip(args.start_values[::2], args.start_values[1::2]) } else: start_values = {} input = read_csv(args.input_file) if args.input_file else None result = simulate_fmu(args.fmu_filename, validate=True, start_time=args.start_time, stop_time=args.stop_time, solver=args.solver, step_size=args.step_size, output_interval=None, fmi_type=None, start_values=start_values, input=input, output=args.output_variables, timeout=args.timeout, fmi_logging=args.fmi_logging) if args.output_file: write_csv(args.output_file, result) if args.show_plot: plot_result(result=result, window_title=args.fmu_filename)
# In[1]: import numpy as np import fmpy from fmpy import read_model_description, extract from fmpy.fmi2 import FMU2Slave from fmpy.util import plot_result, download_test_file import shutil import time as TIME import keyboard # In[2]: fmu_filename = 'Vehicle.fmu' fmpy.dump(fmu_filename) # In[22]: def simulate_custom_input(show_plot=True): # define the model name and simulation parameters start_time = 0.0 step_size = 0.001 stop_time = 20 # read the model description model_description = read_model_description(fmu_filename) # collect the value references vrs = {}
def struct_arr_to_df(arr): """Converts a structured array to DataFrame.""" df = pd.DataFrame(arr).set_index("time") return df # Paths fmu_path = f"examples/simple/resources/Simple2R1C_ic_{get_sys_arch()}.fmu" input_path = "examples/simple/resources/inputs.csv" known_path = "examples/simple/resources/known.json" est_path = "examples/simple/resources/est.json" # Print some info about the FMU dump(fmu_path) # Instantiate FMU model_desc = read_model_description(fmu_path) unzipdir = extract(fmu_path) fmu = instantiate_fmu(unzipdir, model_desc) # Input inp_df = pd.read_csv(input_path) inp_struct = df_to_struct_arr(inp_df) # Parameters with open(known_path, "r") as f: start_values = json.load(f) # Declare output names
default='pyfmi') parser.add_argument("-t", "--simulationEndTime", help="simulation ending time", type=float) parser.add_argument("-f", "--modelFile", help="FMU model file path", type=str) parser.add_argument("-r", "--resultFile", help="Simulation result file path", type=str) args = parser.parse_args() if __name__ == "__main__": try: fmufile = args.modelFile fmpy.dump(fmufile) # print model info fmufilename = fmufile.split("/") fmufilename = fmufilename[len(fmufilename) - 1] simulationEndTime = args.simulationEndTime resultFile = args.resultFile pythonLibrary = args.pythonLibrary cont = True except Exception as e: print( "Please use --help to get information regarding necessary command line arguments" ) print(e) cont = False if cont: log = getlog(task='modelica_simulation', dir=logdir,
def simulate(dpi=300, plotDirectory='plots'): # Set the comparison for dymola results dymolaComparisons = ['non-fmu-all', 'fmu-all', 'non-fmu', 'fmu'] # In[3]: # Create plot directory # plotDirectory = 'plots' plotPath = plotDirectory if os.path.exists(plotPath): shutil.rmtree(plotPath) os.makedirs(plotPath) for key in dymolaComparisons: os.makedirs(os.path.join(plotPath, key)) for dymolaComparison in dymolaComparisons: # # FMpy Library # In[4]: fmu_tests = ['Connectors', 'Inputs', 'Parameters'] for fmu_test in fmu_tests: # fmu_test = fmu_tests[0] fmu_path = '../FMUs/' + fmu_test + '/' fmu = fmu_path + 'FMIRaven_Models_LorenzSystem_' + fmu_test + '.fmu' # In[5]: fmpy.dump(fmu) # In[6]: model_description = fmpy.read_model_description(fmu) # In[7]: vrs = [] for variable in model_description.modelVariables: vrs.append(variable.name) # In[8]: vrs # In[9]: outputs = ['x', 'y', 'z', 'sigma', 'beta', 'rho'] start_values = {'sigma': 10, 'rho': 28, 'beta': 8 / 3} inputs = np.genfromtxt('input_test.txt', delimiter=',', names=True) result = fmpy.simulate_fmu( fmu, output=outputs, start_values=start_values ) #,input=inputs) # simulate the FMU # In[10]: from fmpy.util import plot_result # import the plot function # plot_result(result,names=outputs) fig, ax = plt.subplots(len(outputs), 1, figsize=[12, 12]) for i, v in enumerate(outputs): ax[i].plot(result['time'], result[v]) ax[i].set_ylabel(v, rotation=0, labelpad=20) fig.savefig(plotPath + '/{}/{}_fmpy.png'.format(dymolaComparison, fmu_test), dpi=dpi) # # pyFMI Library # In[11]: from pyfmi import load_fmu model = load_fmu(fmu) model.set('sigma', 10) model.set('beta', 8 / 3) model.set('rho', 28) res_pyfmi = model.simulate() # In[12]: fig, ax = plt.subplots(len(outputs), 1, figsize=[12, 12]) for i, v in enumerate(outputs): ax[i].plot(res_pyfmi['time'], res_pyfmi[v]) ax[i].set_ylabel(v, rotation=0, labelpad=20) fig.savefig(plotPath + '/{}/{}_pyfmi.png'.format(dymolaComparison, fmu_test), dpi=dpi) # # Dymola Result File # In[13]: from buildingspy.io.outputfile import Reader # In[14]: if dymolaComparison == 'non-fmu-all': dymResultPath = 'MATFiles/BasicTest.mat' modelName = fmu_test elif dymolaComparison == 'fmu-all': dymResultPath = 'MATFiles/FMU_BasicTest.mat' modelName = fmu_test elif dymolaComparison == 'non-fmu': dymResultPath = 'MATFiles/{}.mat'.format(fmu_test) modelName = 'fmu' elif dymolaComparison == 'fmu': dymResultPath = 'MATFiles/FMU_{}.mat'.format(fmu_test) modelName = 'fmu' else: raise ValueError('Unsported dymolaComparison') res = Reader(dymResultPath, simulator='dymola') # In[15]: res_dym = {} res_dym['time'], res_dym['x'] = res.values( '{}.x'.format(modelName)) _, res_dym['y'] = res.values('{}.y'.format(modelName)) _, res_dym['z'] = res.values('{}.z'.format(modelName)) _, res_dym['sigma'] = res.values('{}.sigma'.format(modelName)) _, res_dym['beta'] = res.values('{}.beta'.format(modelName)) _, res_dym['rho'] = res.values('{}.rho'.format(modelName)) # In[16]: fig, ax = plt.subplots(len(outputs), 1, figsize=[12, 12]) for i, v in enumerate(outputs): try: ax[i].plot(res_dym['time'], res_dym[v]) ax[i].set_ylabel(v, rotation=0, labelpad=20) except: pass fig.savefig(plotPath + '/{}/{}_dymola.png'.format(dymolaComparison, fmu_test), dpi=dpi) # # Result Comparison # In[17]: fig, ax = plt.subplots(len(outputs), 1, figsize=[12, 12]) for i, v in enumerate(outputs): ax[i].plot(result['time'], result[v], 'k-', label='FMpy') ax[i].plot(res_pyfmi['time'], res_pyfmi[v], 'b--', label='pyFMI') try: ax[i].plot(res_dym['time'], res_dym[v], 'r-.', label='Dymola') except: pass ax[i].legend() ax[i].set_ylabel(v, rotation=0, labelpad=20) fig.savefig( plotPath + '/{}/{}_comparison.png'.format(dymolaComparison, fmu_test), dpi=dpi) # # Diff between FMU and Dymola # In[18]: fig, ax = plt.subplots(len(outputs), 1, figsize=[12, 12]) for i, v in enumerate(outputs): try: ax[i].plot(result['time'], result[v] - res_dym[v], 'k-', label='FMpy - Dymola') ax[i].plot(result['time'], res_pyfmi[v] - res_dym[v], 'b--', label='pyFMI - Dymola') except: pass ax[i].legend() ax[i].set_ylabel(v, rotation=0, labelpad=20) fig.savefig(plotPath + '/{}/{}_diff_FMUtoDymola.png'.format( dymolaComparison, fmu_test), dpi=dpi) # # Diff between FMUs # In[19]: fig, ax = plt.subplots(len(outputs), 1, figsize=[12, 12]) for i, v in enumerate(outputs): try: ax[i].plot(result['time'], result[v] - res_pyfmi[v], 'k-', label='FMpy - pyFMI') except: pass ax[i].legend() ax[i].set_ylabel(v, rotation=0, labelpad=20) fig.savefig( plotPath + '/{}/{}_diff_FMUtoFMU.png'.format(dymolaComparison, fmu_test), dpi=dpi) plt.close('all')