def test_ExtFuncShared(self): """ Test compiling a model with external functions in a shared library. Real, Integer, and Boolean arrays. """ fmu_name = compile_fmu(self.cpath, self.fpath, compiler_options={'variability_propagation':True}) model = load_fmu(fmu_name) s_ceval = model.get('s') res = model.simulate() s_sim1 = res.final('s') fmu_name = compile_fmu(self.cpath, self.fpath, compiler_options={'variability_propagation':False}) model = load_fmu(fmu_name) res = model.simulate() s_sim2 = res.final('s') nose.tools.assert_equals(s_sim1, s_sim2)
def run_demo(with_plots=True): """ This example shows how to simulate a system that contains switches. The example model is simple in the sense that no reinitialization of the variables is needed at the event points. """ curr_dir = os.path.dirname(os.path.abspath(__file__)); class_name = 'IfExpExamples.IfExpExample2' mofile = curr_dir+'/files/IfExpExamples.mo' fmu_name = compile_fmu(class_name, mofile) # Load the dynamic library and XML data model = load_fmu(fmu_name) # Simulate res = model.simulate(final_time=5.0) # Get results x = res['x'] u = res['u'] t = res['time'] assert N.abs(res.final('x') - 3.5297217) < 1e-3 assert N.abs(res.final('u') - (-0.2836621)) < 1e-3 if with_plots: fig = p.figure() p.plot(t, x, t, u) p.legend(('x','u')) p.show()
def run_demo(with_plots=True): """ Distillation2 model """ curr_dir = os.path.dirname(os.path.abspath(__file__)); fmu_name = compile_fmu("JMExamples.Distillation.Distillation2", curr_dir+"/files/JMExamples.mo") dist2 = load_fmu(fmu_name) res = dist2.simulate(final_time=7200) # Extract variable profiles x16 = res['x[16]'] x32 = res['x[32]'] t = res['time'] print "t = ", repr(N.array(t)) print "x16 = ", repr(N.array(x16)) print "x32 = ", repr(N.array(x32)) if with_plots: # Plot plt.figure(1) plt.plot(t,x16,t,x32) plt.grid() plt.ylabel('x') plt.xlabel('time') plt.show()
def run_demo(with_plots=True): """ An example on how to simulate a model using the DAE simulator. The result can be compared with that of sim_rlc.py which has solved the same problem using dymola. Also writes information to a file. """ curr_dir = os.path.dirname(os.path.abspath(__file__)); class_name = 'RLC_Circuit' mofile = curr_dir+'/files/RLC_Circuit.mo' fmu_name = compile_fmu(class_name, mofile) rlc = load_fmu(fmu_name) res = rlc.simulate(final_time=30) sine_y = res['sine.y'] resistor_v = res['resistor.v'] inductor1_i = res['inductor1.i'] t = res['time'] assert N.abs(res.final('resistor.v') - 0.159255008028) < 1e-3 if with_plots: fig = p.figure() p.plot(t, sine_y, t, resistor_v, t, inductor1_i) p.legend(('sine.y','resistor.v','inductor1.i')) p.show()
def simulate(self): ''' TODO: LOG all command omc ''' # tic= timeit.default_timer() # Simulation process with JModelica fullMoFile= self.moPath+ '/'+ self.moFile fullMoLib= self.libPath+ '/'+ self.libFile '''build the fmu block from the modelica model ''' # fmu_name= compile_fmu(self.moModel, absolutePath, # compiler_options = {'extra_lib_dirs':self.libPath}) fmu_name= compile_fmu(self.moModel, [fullMoFile, fullMoLib]) ''' Load the model ''' model_fmu= load_fmu(fmu_name) ''' Load the list of options for the JModelica compiler ''' opts = model_fmu.simulate_options() opts['solver']= self.config.getSolver() opts['ncp']= self.config.getNcp() # for key,value in simOpt.getOptions().items(): # print key,value # opts[key] = value print opts result = model_fmu.simulate(start_time= self.config.getStartTime(), final_time= self.config.getStopTime(), options=opts) # toc= timeit.default_timer() # print 'Simulation time ', toc- tic return result
def run_demo(with_plots=True): curr_dir = os.path.dirname(os.path.abspath(__file__)); class_name = 'ExtFunctions.transposeSquareMatrix' mofile = os.path.join(curr_dir, 'files', 'ExtFunctions.mo') # Compile and load model fmu_name = compile_fmu(class_name, mofile) model = load_fmu(fmu_name) # Simulate res = model.simulate() # Get result data b1_1 = res['b_out[1,1]'] b1_2 = res['b_out[1,2]'] b2_1 = res['b_out[2,1]'] b2_2 = res['b_out[2,2]'] t = res['time'] assert N.abs(res.final('b_out[1,1]') - 1) < 1e-6 assert N.abs(res.final('b_out[1,2]') - 3) < 1e-6 assert N.abs(res.final('b_out[2,1]') - 2) < 1e-6 assert N.abs(res.final('b_out[2,2]') - 4) < 1e-6 if with_plots: fig = p.figure() p.clf() p.plot(t, b1_1, label='b1_1') p.plot(t, b1_2, label='b1_2') p.plot(t, b2_1, label='b2_1') p.plot(t, b2_2, label='b2_2') p.legend() p.grid() p.show()
def test_ExtFuncStatic(self): """ Test compiling a model with external functions in a static library. """ cpath = "ExtFunctionTests.ExtFunctionTest1" fmu_name = compile_fmu(cpath, TestExternalStatic.fpath) model = load_fmu(fmu_name)
def run_demo(with_plots=True): """ An example on how to simulate a model using the ODE simulator. """ curr_dir = os.path.dirname(os.path.abspath(__file__)); file_name = os.path.join(curr_dir,'files','VDP.mop') fmu_name = compile_fmu("JMExamples.VDP.VDP", curr_dir+"/files/JMExamples.mo") model = load_fmu(fmu_name) opts = model.simulate_options() opts["CVode_options"]["rtol"] = 1e-6 res = model.simulate(final_time=10, options=opts) assert N.abs(res.final('x1') - 7.34186386e-01) < 1e-3 assert N.abs(res.final('x2') + 1.58202722) < 1e-3 x1 = res['x1'] x2 = res['x2'] if with_plots: plt.figure() plt.plot(x2, x1) plt.legend(('x1(x2)')) plt.show()
def run_demo(with_plots=True, version="2.0"): # Compile model fmu_name = compile_fmu("IBPSA.Fluid.FixedResistances.Examples.PlugFlowPipe","C:\My_Libs\modelica-ibpsa\IBPSA") fmu_name=("IBPSA_Fluid_FixedResistances_Examples_PlugFlowPipe.fmu") #print("FMU compiled",fmu_name) print(fmu_name) # Load model pipe = load_fmu(fmu_name) print("FMU loaded", pipe) res = pipe.simulate(final_time=100) x1 = res['Tin.offset'] x2 = res['sou.m_flow'] t = res['time'] plt.figure(1) plt.plot(t, x1, t, x2) plt.legend(('Tin (K)','mdot (kg/s)')) plt.title('Pipe') plt.ylabel('y axis') plt.xlabel('Time (s)') plt.show()
def run_demo(with_plots=True): """ Demonstrates how to use an JMODELICA generated FMU for sensitivity calculations. """ curr_dir = os.path.dirname(os.path.abspath(__file__)); fmu_name = compile_fmu("Robertson", curr_dir+"/files/Robertson.mo") model = load_fmu(fmu_name) # Get and set the options opts = model.simulate_options() opts['sensitivities'] = ["p1","p2","p3"] opts['ncp'] = 400 #Simulate res = model.simulate(final_time=4, options=opts) dy1dp1 = res['dy1/dp1'] dy2dp1 = res['dy2/dp1'] time = res['time'] nose.tools.assert_almost_equal(dy1dp1[40], -0.35590, 3) nose.tools.assert_almost_equal(dy2dp1[40], 3.9026e-04, 6) if with_plots: plt.plot(time, dy1dp1, time, dy2dp1) plt.legend(('dy1/dp1', 'dy2/dp1')) plt.show()
def run_demo(with_plots=True): curr_dir = os.path.dirname(os.path.abspath(__file__)); class_name = 'ExtFunctions.addTwo' mofile = os.path.join(curr_dir, 'files', 'ExtFunctions.mo') # Compile and load model fmu_name = compile_fmu(class_name, mofile) model = load_fmu(fmu_name) # Simulate res = model.simulate() # Load result data sim_a = res['a'] sim_b = res['b'] sim_c = res['c'] t = res['time'] assert N.abs(res.final('a') - 1) < 1e-6 assert N.abs(res.final('b') - 2) < 1e-6 assert N.abs(res.final('c') - 3) < 1e-6 if with_plots: fig = p.figure() p.clf() p.subplot(3,1,1) p.plot(t, sim_a) p.subplot(3,1,2) p.plot(t, sim_b) p.subplot(3,1,3) p.plot(t, sim_c) p.show()
def run_demo(with_plots=True): """ An example on how to simulate a model using a DAE simulator with Assimulo. The model used is made by Maja Djačić. """ curr_dir = os.path.dirname(os.path.abspath(__file__)); m_name = 'SolAngles' mofile = curr_dir+'/files/SolAngles.mo' fmu_name = compile_fmu(m_name, mofile) model = load_fmu(fmu_name) res = model.simulate(final_time=86400.0, options={'ncp':86400}) theta = res['theta'] azim = res['azim'] N_day = res['N_day'] time = res['time'] assert N.abs(res.final('theta') - 90.28737353) < 1e-3 # Plot results if with_plots: p.figure(1) p.plot(time, theta) p.xlabel('time [s]') p.ylabel('theta [deg]') p.title('Angle of Incidence on Surface') p.grid() p.show()
def run_demo(with_plots=True): """ Simulation of a model that predicts the blood glucose levels of a type-I diabetic. The objective is to predict the relationship between insulin injection and blood glucose levels. Reference: S. M. Lynch and B. W. Bequette, Estimation based Model Predictive Control of Blood Glucose in Type I Diabetes: A Simulation Study, Proc. 27th IEEE Northeast Bioengineering Conference, IEEE, 2001. S. M. Lynch and B. W. Bequette, Model Predictive Control of Blood Glucose in type I Diabetics using Subcutaneous Glucose Measurements, Proc. ACC, Anchorage, AK, 2002. """ curr_dir = os.path.dirname(os.path.abspath(__file__)) fmu_name1 = compile_fmu("JMExamples.BloodGlucose.BloodGlucose1", os.path.join(curr_dir, "files", "JMExamples.mo")) bg = load_fmu(fmu_name1) opts = bg.simulate_options() opts["CVode_options"]["rtol"] = 1e-6 res = bg.simulate(final_time=400, options=opts) # Extract variable profiles G = res["G"] X = res["X"] I = res["I"] t = res["time"] assert N.abs(res.final("G") - 19.77650) < 1e-4 assert N.abs(res.final("X") - 14.97815) < 1e-4 assert N.abs(res.final("I") - 2.7) < 1e-4 if with_plots: plt.figure(1) plt.subplot(2, 2, 1) plt.plot(t, G) plt.title("Plasma Glucose Conc") plt.grid(True) plt.ylabel("Plasma Glucose Conc. (mmol/L)") plt.xlabel("time") plt.subplot(2, 2, 2) plt.plot(t, X) plt.title("Plasma Insulin Conc.") plt.grid(True) plt.ylabel("Plasma Insulin Conc. (mu/L)") plt.xlabel("time") plt.subplot(2, 2, 3) plt.plot(t, I) plt.title("Plasma Insulin Conc.") plt.grid(True) plt.ylabel("Plasma Insulin Conc. (mu/L)") plt.xlabel("time") plt.show()
def run_demo(with_plots=True): """ Example demonstrating how to use index reduction. """ curr_dir = os.path.dirname(os.path.abspath(__file__)); # Compile model fmu_name = compile_fmu("Pendulum_pack.PlanarPendulum", curr_dir+"/files/Pendulum_pack.mop",compiler='optimica') # Load model model = load_fmu(fmu_name) # Options opts = model.simulate_options() opts["CVode_options"]["rtol"] = 1e-6 # Load result file res = model.simulate(final_time=10., options=opts) x = res['x'] st = res['st'] ct = res['ct'] err = res['err'] y = res['y'] vx = res['vx'] vy = res['vy'] t = res['time'] maxerr = N.max(err) if maxerr > 1e-6: print "Maximum error: ", maxerr assert maxerr < 1e-4 assert N.abs(res.final('x') - 0.38735171) < 1e-3 assert N.abs(res.final('st') - 0.38733358) < 1e-3 assert N.abs(res.final('ct') + 0.92193964) < 1e-3 assert N.abs(res.final('err') - 1.96716163e-05) < 1e-3 assert N.abs(res.final('y') + 0.92193202) < 1e-3 assert N.abs(res.final('vx') - 6.04839823e-01) < 1e-3 assert N.abs(res.final('vy') - 2.54124747e-01) < 1e-3 if with_plots: plt.figure(1) plt.subplot(3,1,1) plt.plot(t,x,t,y) plt.grid(True) plt.legend(['x','y']) plt.subplot(3,1,2) plt.plot(t,vx,t,vy) plt.grid(True) plt.legend(['vx','vy']) plt.subplot(3,1,3) plt.plot(t,err) plt.grid(True) plt.legend(['err']) plt.xlabel('time [s]') plt.show()
def test_ModelicaUtilities(self): """ Test compiling a model with external functions using the functions in ModelicaUtilities. """ fpath = path(get_files_path(), 'Modelica', "ExtFunctionTests.mo") cpath = "ExtFunctionTests.ExtFunctionTest3" jmu_name = compile_fmu(cpath, fpath) model = load_fmu(jmu_name)
def test_ExtFuncSharedCeval(self): """ Test compiling a model with external functions in a shared library. Constant evaluation during compilation. """ cpath = "ExtFunctionTests.ExtFunctionTest1" fmu_name = compile_fmu(cpath, TestExternalShared.fpath, compiler_options={'variability_propagation':True}) model = load_fmu(fmu_name) nose.tools.assert_equals(model.get('c'), 3)
def run_demo(with_plots=True,with_blocking_factors = False): """ FMU simulation of a distillation column. The distillation column model is documented in the paper: @Article{hahn+02, title={An improved method for nonlinear model reduction using balancing of empirical gramians}, author={Hahn, J. and Edgar, T.F.}, journal={Computers and Chemical Engineering}, volume={26}, number={10}, pages={1379-1397}, year={2002} } """ curr_dir = os.path.dirname(os.path.abspath(__file__)); # Compile the stationary initialization model into a JMU fmu_name = compile_fmu('DISTLib.Examples.Simulation', os.path.join(curr_dir, 'files', 'DISTLib.mo')) # Load a model instance into Python model = load_fmu(fmu_name) # Simulate res = model.simulate(final_time=200) x_16 = res['binary_dist_initial.x[16]'] y_16 = res['binary_dist_initial.y[16]'] x_32 = res['binary_dist_initial.x[32]'] y_32 = res['binary_dist_initial.y[32]'] t = res['time'] assert N.abs(res.final('binary_dist_initial.x[16]') - 0.49931368) < 1e-3 assert N.abs(res.final('binary_dist_initial.y[16]') - 0.61473464) < 1e-3 assert N.abs(res.final('binary_dist_initial.x[32]') - 0.18984724) < 1e-3 assert N.abs(res.final('binary_dist_initial.y[32]') - 0.27269352) < 1e-3 # Plot the results if with_plots: plt.figure(1) plt.clf() plt.subplot(2,1,1) plt.plot(t,x_16,'b') plt.hold(True) plt.plot(t,x_32,'b') plt.title('Liquid composition') plt.grid(True) plt.subplot(2,1,2) plt.plot(t,y_16,'b') plt.hold(True) plt.plot(t,y_32,'b') plt.title('Vapor composition') plt.grid(True) plt.show()
def test_simulate(self): cpath = 'Asserts.ModelicaError' fmu_name = compile_fmu(cpath, TestModelicaError.fpath) model = load_fmu(fmu_name) try: model.simulate(final_time = 3) assert False, 'Simulation not stopped by calls to ModelicaError()' except CVodeError, e: assert abs(e.t - 2.0) < 0.01, 'Simulation stopped at wrong time'
def test_ExtFuncShared(self): """ Test compiling a model with external functions in a shared library. Simple. """ cpath = "ExtFunctionTests.ExtFunctionTest1" fmu_name = compile_fmu(cpath, TestExternalShared.fpath, compiler_options={'variability_propagation':False}) model = load_fmu(fmu_name) res = model.simulate() nose.tools.assert_equals(res.final('c'), 3)
def test_ExtFuncBool(self): """ Test compiling a model with external functions in a shared library. Boolean arrays. """ fmu_name = compile_fmu(self.cpath, self.fpath, compiler_options={'variability_propagation':False}) model = load_fmu(fmu_name) model.simulate() fmu_name = compile_fmu(self.cpath, self.fpath, compiler_options={'variability_propagation':True}) model2 = load_fmu(fmu_name) model2.simulate() trueInd = {1,2,3,5,8} falseInd = {4,6,7} for i in trueInd: assert(model.get('res[' + str(i) + ']')) assert(model2.get('res[' + str(i) + ']')) for i in falseInd: assert(not model.get('res[' + str(i) + ']')) assert(not model2.get('res[' + str(i) + ']'))
def test_compile_fmu_mop(self): """ Test that it is possible to compile an FMU from a .mop file with pymodelica.compile_fmu. """ fmuname = compile_fmu(Test_Compiler.cpath_mc, Test_Compiler.fpath_oc) assert os.access(fmuname, os.F_OK) == True, \ fmuname+" was not created." os.remove(fmuname)
def __init__(self): self.TimeZero = 0 # in TimeStep steps self.t = 0 # current time in TimeStep steps self.statekeys = ['env.avg0', 'env.adm0', 'env.n0', 'env.depth0', 'monitor.y0', 'sys.x0'] self.inputkeys = ['noise0', 'failures0'] self.getdict = {} self.getdict['env.avg0'] = 'env.x.avg' self.getdict['env.adm0'] = 'env.x.adm' self.getdict['env.n0'] = 'env.x.n' self.getdict['env.depth0'] = 'env.x.depth' self.getdict['env.noise0'] = 'env.d.noise' self.getdict['env.failures0'] = 'env.d.failures' self.getdict['monitor.y0'] = 'monitor.y' self.getdict['sys.x0'] = 'sys.x' # self.state = {} #for k in self.statekeys : # self.state[k] = self.model.get(self.getdict[k]) self.time = {} self.time['start'] = self.t #self.act = {} # self.act['time'] = self.StartTime #for k in self.inputkeys : # self.act[k] = self.model.get(self.getdict[k]) self.actlist = [-1, 0.0, 1] self.fmu = compile_fmu('ClosedSystem', ['closed-system.mo', 'system.mo', 'monitor.mo', 'environment.mo', 'dictionary.mo', 'state.mo']) self.create_model() #self.model = load_fmu(self.fmu) #self.opts = self.model.simulate_options() #self.opts['CVode_options']['verbosity'] = 50 # No output #self.opts['initialize'] = False #self.model.time = self.start_time(self.t) #self.model.initialize() #for k in self.statekeys : # self.state[k] = self.model.get(self.getdict[k]) #for k in self.inputkeys : # self.state[k] = self.model.get(self.getdict[k]) # get time step from disturbance model self.TimeStep = self.model.get('env.T') # in seconds
def test_IntegerArraysCeval(self): """ Test a model with external functions containing integer array and literal inputs. Constant evaluation during compilation. """ cpath = "ExtFunctionTests.ExtFunctionTest4" fmu_name = compile_fmu(cpath, TestExternalStatic.fpath, compiler_options={'variability_propagation':True}) model = load_fmu(fmu_name) nose.tools.assert_equals(model.get('myResult[1]'), 2) nose.tools.assert_equals(model.get('myResult[2]'), 4) nose.tools.assert_equals(model.get('myResult[3]'), 6)
def run_demo(with_plots=True): """ Demonstrate how to do batch simulations """ curr_dir = os.path.dirname(os.path.abspath(__file__)); # Define model file name and class name model_name = 'VDP_pack.VDP' mofile = curr_dir+'/files/VDP.mop' # Compile model fmu_name = compile_fmu(model_name,mofile) # Define initial conditions N_points = 11 x1_0 = N.linspace(-3.,3.,N_points) x2_0 = N.zeros(N_points) # Open phase plane plot if with_plots: fig = p.figure() p.clf() p.hold(True) p.xlabel('x1') p.ylabel('x2') # Loop over initial conditions for i in range(N_points): # Load model model = load_fmu(fmu_name) # Set initial conditions in model model.set('x1_0',x1_0[i]) model.set('x2_0',x2_0[i]) # Simulate res = model.simulate(final_time=20) # Get simulation result x1=res['x1'] x2=res['x2'] # Plot simulation result in phase plane plot if with_plots: p.plot(x1, x2,'b') assert N.abs(res.final('x1') - 1.75293937) < 1e-3 assert N.abs(res.final('x2') + 3.98830742e-01) < 1e-3 if with_plots: p.grid() p.show()
def test_get_nominal(self): from pymodelica import compile_fmu from pyfmi import load_fmu fmu = load_fmu(compile_fmu("NominalTests.NominalTest3", TestNominal.mo_path)) n = fmu._get_nominal_continuous_states() nose.tools.assert_almost_equal(n[0], 1.0) nose.tools.assert_almost_equal(n[1], 1.0) nose.tools.assert_almost_equal(n[2], 2.0) nose.tools.assert_almost_equal(n[3], 6.0) nose.tools.assert_almost_equal(n[4], 5.0)
def test_division(self): cname = "JacGenTests.JacTestDiv" fn = compile_fmu( cname, self.fname, compiler_options={"generate_ode_jacobian": True, "eliminate_alias_variables": False}, version="2.0alpha", ) m = FMUModel2(fn) m.set_debug_logging(True) Afd, Bfd, Cfd, Dfd, n_errs = m.check_jacobians(delta_rel=1e-6, delta_abs=1e-3, tol=1e-5) assert n_errs == 0
def test_IntegerArrays(self): """ Test a model with external functions containing integer array and literal inputs. """ cpath = "ExtFunctionTests.ExtFunctionTest4" fmu_name = compile_fmu(cpath, TestExternalStatic.fpath, compiler_options={'variability_propagation':False}) model = load_fmu(fmu_name) res = model.simulate() nose.tools.assert_equals(res.final('myResult[1]'), 2) nose.tools.assert_equals(res.final('myResult[2]'), 4) nose.tools.assert_equals(res.final('myResult[3]'), 6)
def test_Unsolved_blocks6(self): cname = "JacGenTests.Unsolved_blocks6" fn = compile_fmu( cname, self.fname, compiler_options={"generate_ode_jacobian": True, "eliminate_alias_variables": False}, version="2.0alpha", ) m = FMUModel2(fn) m.set_debug_logging(True) m.initialize(relativeTolerance=1e-11) Afd, Bfd, Cfd, Dfd, n_errs = m.check_jacobians(delta_rel=1e-6, delta_abs=1e-3, tol=1e-5) assert n_errs == 0
def test_ExtObjectDestructor(self): """ Test compiling a model with external object functions in a static library. """ cpath = 'ExtFunctionTests.ExternalObjectTests1' fmu_name = compile_fmu(cpath, TestExternalObject.fpath) model = load_fmu(fmu_name) model.simulate() model.terminate() if (os.path.exists('test_ext_object.marker')): os.remove('test_ext_object.marker') else: assert False, 'External object destructor not called.'
def run_demo(with_plots=True): """ Distillation1 model """ curr_dir = os.path.dirname(os.path.abspath(__file__)); fmu_name1 = compile_fmu("JMExamples.Distillation.Distillation1Inputstep", curr_dir+"/files/JMExamples.mo") dist1 = load_fmu(fmu_name1) res = dist1.simulate(final_time=7200) # Extract variable profiles x1 = res['x[1]'] x8 = res['x[8]'] x16 = res['x[16]'] x24 = res['x[24]'] x32 = res['x[32]'] y1 = res['y[1]'] y8 = res['y[8]'] y16 = res['y[16]'] y24 = res['y[24]'] y32 = res['y[32]'] t = res['time'] print "t = ", repr(N.array(t)) print "x16 = ", repr(N.array(x16)) print "x32 = ", repr(N.array(x32)) print "y16 = ", repr(N.array(y16)) print "y32 = ", repr(N.array(y32)) if with_plots: # Plot plt.figure() plt.subplot(1,2,1) plt.plot(t,x16,t,x32,t,x1,t,x8,t,x24) plt.title('Liquid composition') plt.grid(True) plt.ylabel('x') plt.subplot(1,2,2) plt.plot(t,y16,t,y32,t,y1,t,y8,t,y24) plt.title('Vapor composition') plt.grid(True) plt.ylabel('y') plt.xlabel('time') plt.show()
# If the argument is a file, then parse it to a model name if os.path.isfile(sys.argv[1]): model = sys.argv[1].replace(os.path.sep, '.')[:-3] else: model = sys.argv[1] print("*** Compiling {}".format(model)) # Increase memory pymodelica.environ['JVM_ARGS'] = '-Xmx4096m' sys.stdout.flush() ###################################################################### # Compile fmu fmu_name = compile_fmu(model, version="2.0", compiler_log_level='warning', compiler_options={"generate_html_diagnostics": False}) ###################################################################### # Load model mod = load_fmu(fmu_name, log_level=3) ###################################################################### # Retrieve and set solver options x_nominal = mod.nominal_continuous_states opts = mod.simulate_options() #Retrieve the default options opts['solver'] = 'CVode' opts['ncp'] = 5000 if opts['solver'].lower() == 'cvode':
def __init__(self, file_path, model_name, K, dt, t_final, start_values, ctrl_point, output_names, input_names, input_ranges, par_values={}, obs_var_names=None, par_changes=ParameterChanges(), sim_options={}, noise=0): """ Creates an LQR object containing a simulated process to run it on. Parameters:: file_path -- The path of the .mop file containing the model to be used for simulating the process. model_name -- The name of the model in the file specified by file_path to be used for the simulated process. K -- The linear gain feedback matrix used to calculate the control signal from the state vector. dt -- The time to wait in between each sample. t_final -- The total time to run the real time LQR. start_values -- A dictionary containing the initial state values for the process. ctrl_point -- A dictionary containing the initial control point, with the keys being state names and values their values. output_names -- A list of the names of all of the output variables used in the model. input_names -- A list of the names of all of the input variables used in the model. input_ranges -- A list of the ranges to clamp the input control signals to, in the same order as in input_names. Each range should be a pair with the first element being the lower bound and the second being the upper. par_changes -- A ParameterChanges object containing parameter changes and the times they should be applied. Default: An empty ParameterChanges object obs_var_names -- A list of the names of all state variables that should be observable. If set to None, all state variables are assumed to be observable. Default: None sim_options -- A dictionary of options to be used for the simulation. noise -- Standard deviation of the noise to add to the input signals. Default: 0 """ super(LQRSimBase, self).__init__(K, dt, t_final, start_values, ctrl_point, output_names, input_names, input_ranges, par_changes, noise) if obs_var_names is not None: self.obs_var_names = obs_var_names else: self.obs_var_names = output_names self.sim_options = { 'initialize': False, 'CVode_options': { 'verbosity': 50 } } if 'CVode_options' in sim_options: self.sim_options['CVode_options'].update( sim_options['CVode_options']) for k in sim_options: if k != 'CVode_options': self.sim_options[k] = sim_options[k] sim_fmu = compile_fmu( model_name, file_path, compiler_options={'state_initial_equations': True}) self.model = load_fmu(sim_fmu) self.model.set(start_values.keys(), start_values.values()) self.model.set(par_values.keys(), par_values.values()) self.model.initialize() self.t = 0 self._realtime = False
def __init__(self, file_path, opt_name, model_name, dt, t_hor, t_final, start_values, par_values, output_names, input_names, obs_var_names=None, par_changes=ParameterChanges(), mpc_options={}, sim_options={}, constr_viol_costs={}, noise=0): """ Creates an MPC object containing a simulated process to run it on. Parameters:: file_path -- The path of the .mop file containing the model to be used for the MPC solver. opt_name -- The name of the optimization in the file specified by file_path to be used by the MPC solver. model_name -- The name of the model in the file specified by file_path to be used for the simulated process. dt -- The time to wait in between each sample. t_hor -- The horizon time for the MPC solver. Must be an even multiple of dt. t_final -- The total time to run the real time MPC. start_values -- A dictionary containing the initial state values for the process. par_values -- A dictionary containing parameter values to be set in the model. output_names -- A list of the names of all of the output variables used in the model. input_names -- A list of the names of all of the input variables used in the model. obs_var_names -- A list of the names of all state variables that should be observable. If set to None, all state variables are assumed to be observable. Default: None par_changes -- A ParameterChanges object containing parameter changes and the times they should be applied. Default: An empty ParameterChanges object mpc_options -- A dictionary of options to be used for the MPC solver. sim_options -- A dictionary of options to be used for the simulation. constr_viol_costs -- Constraint violation costs used by the MPC solver. See the documentation of the MPC class for more information. noise -- Standard deviation of the noise to add to the input signals. Default: 0 """ super(MPCSimBase, self).__init__(file_path, opt_name, dt, t_hor, t_final, start_values, par_values, output_names, input_names, par_changes, mpc_options, constr_viol_costs, noise) if obs_var_names is not None: self.obs_var_names = obs_var_names else: self.obs_var_names = output_names self.sim_options = { 'initialize': False, 'CVode_options': { 'verbosity': 50 } } if 'CVode_options' in sim_options: self.sim_options['CVode_options'].update( sim_options['CVode_options']) for k in sim_options: if k != 'CVode_options': self.sim_options[k] = sim_options[k] sim_fmu = compile_fmu( model_name, file_path, compiler_options={'state_initial_equations': True}) self.model = load_fmu(sim_fmu) self.model.set(start_values.keys(), start_values.values()) self.model.set(par_values.keys(), par_values.values()) self.model.initialize() self.t = 0 self._realtime = False
from pymodelica import compile_fmu from pyfmi import load_fmu import matplotlib.pyplot as plt from pyjmi.common.plotting import plot_gui # or pyfmi.common.plotting import plot_gui ## model_name = 'Buildings.Fluid.Boilers.Examples.BoilerPolynomial' mo_file = 'C:\Users\James\Desktop\Buildings 4.0.0' fmu = compile_fmu(model_name, mo_file) model = load_fmu(fmu) res = model.simulate(final_time=10.) t = res['time'] T = res['boi1.temSen.T'] plt.figure(1) plt.plot(t, T) plt.grid(True) plt.legend(['T']) plt.xlabel('time [s]') plt.ylabel('T') plt.show() plot_gui.startGUI()
def run_demo(with_plots=True): """ This example is based on a combined cycle power plant (CCPP). The model has 9 states, 128 algebraic variables and 1 control variable. The task is to minimize the time required to perform a warm start-up of the power plant. This problem has become highly industrially relevant during the last few years, due to an increasing need to improve power generation flexibility. The example consists of the following steps: 1. Simulating the system using a simple input trajectory. 2. Solving the optimal control problem using the result from the first step to initialize the non-linear program. 3. Verifying the result from the second step by simulating the system once more usng the optimized input trajectory. The model was developed by Francesco Casella and was published in @InProceedings{CFA2011, author = "Casella, Francesco and Donida, Filippo and {\AA}kesson, Johan", title = "Object-Oriented Modeling and Optimal Control: A Case Study in Power Plant Start-Up", booktitle = "18th IFAC World Congress", address = "Milano, Italy", year = 2011, month = aug } """ ### 1. Compute initial guess trajectories by means of simulation # Locate the Modelica and Optimica code file_paths = (os.path.join(get_files_path(), "CombinedCycle.mo"), os.path.join(get_files_path(), "CombinedCycleStartup.mop")) # Compile the optimization initialization model init_sim_fmu = compile_fmu("CombinedCycleStartup.Startup6Reference", file_paths) # Load the model init_sim_model = load_fmu(init_sim_fmu) # Simulate init_res = init_sim_model.simulate(start_time=0., final_time=10000.) # Extract variable profiles init_sim_plant_p = init_res['plant.p'] init_sim_plant_sigma = init_res['plant.sigma'] init_sim_plant_load = init_res['plant.load'] init_sim_time = init_res['time'] # Plot the initial guess trajectories if with_plots: plt.close(1) plt.figure(1) plt.subplot(3, 1, 1) plt.plot(init_sim_time, init_sim_plant_p * 1e-6) plt.ylabel('evaporator pressure [MPa]') plt.grid(True) plt.title('Initial guess obtained by simulation') plt.subplot(3, 1, 2) plt.plot(init_sim_time, init_sim_plant_sigma * 1e-6) plt.grid(True) plt.ylabel('turbine thermal stress [MPa]') plt.subplot(3, 1, 3) plt.plot(init_sim_time, init_sim_plant_load) plt.grid(True) plt.ylabel('input load [1]') plt.xlabel('time [s]') ### 2. Solve the optimal control problem # Compile model fmux = compile_fmux("CombinedCycleStartup.Startup6", file_paths) # Load model opt_model = CasadiModel(fmux) # Set options opt_opts = opt_model.optimize_options() opt_opts['n_e'] = 50 # Number of elements opt_opts['init_traj'] = init_res.result_data # Simulation result opt_opts['nominal_traj'] = init_res.result_data # Solve the optimal control problem opt_res = opt_model.optimize(options=opt_opts) # Extract variable profiles opt_plant_p = opt_res['plant.p'] opt_plant_sigma = opt_res['plant.sigma'] opt_plant_load = opt_res['plant.load'] opt_time = opt_res['time'] opt_input = N.vstack([opt_time, opt_plant_load]).T # Plot the optimized trajectories if with_plots: plt.close(2) plt.figure(2) plt.subplot(3, 1, 1) plt.plot(opt_time, opt_plant_p * 1e-6) plt.ylabel('evaporator pressure [MPa]') plt.grid(True) plt.title('Optimized trajectories') plt.subplot(3, 1, 2) plt.plot(opt_time, opt_plant_sigma * 1e-6) plt.grid(True) plt.ylabel('turbine thermal stress [MPa]') plt.subplot(3, 1, 3) plt.plot(opt_time, opt_plant_load) plt.grid(True) plt.ylabel('input load [1]') plt.xlabel('time [s]') # Verify solution for testing purposes try: import casadi except: pass else: cost = float(opt_res.solver.solver_object.output(casadi.NLP_SOLVER_F)) N.testing.assert_allclose(cost, 17492.465548193624, rtol=1e-5) ### 3. Simulate to verify the optimal solution # Compile model sim_fmu = compile_fmu("CombinedCycle.Optimization.Plants.CC0D_WarmStartUp", file_paths) # Load model sim_model = load_fmu(sim_fmu) # Simulate using optimized input sim_res = sim_model.simulate(start_time=0., final_time=4000., input=('load', opt_input)) # Extract variable profiles sim_plant_p = sim_res['p'] sim_plant_sigma = sim_res['sigma'] sim_plant_load = sim_res['load'] sim_time = sim_res['time'] # Plot the simulated trajectories if with_plots: plt.close(3) plt.figure(3) plt.subplot(3, 1, 1) plt.plot(opt_time, opt_plant_p * 1e-6, '--', lw=5) plt.hold(True) plt.plot(sim_time, sim_plant_p * 1e-6, lw=2) plt.ylabel('evaporator pressure [MPa]') plt.grid(True) plt.legend(('optimized', 'simulated'), loc='lower right') plt.title('Verification') plt.subplot(3, 1, 2) plt.plot(opt_time, opt_plant_sigma * 1e-6, '--', lw=5) plt.hold(True) plt.plot(sim_time, sim_plant_sigma * 1e-6, lw=2) plt.ylabel('turbine thermal stress [MPa]') plt.grid(True) plt.subplot(3, 1, 3) plt.plot(opt_time, opt_plant_load, '--', lw=5) plt.hold(True) plt.plot(sim_time, sim_plant_load, lw=2) plt.ylabel('input load [1]') plt.xlabel('time [s]') plt.grid(True) plt.show() # Verify solution for testing purposes N.testing.assert_allclose(opt_res.final('plant.p'), sim_res.final('p'), rtol=5e-3)
DATARAW.index)) # change 'str' to datetime obj DATARAW['time'] = H_date2simtime(DATARAW.index, '2018') DATA = DATARAW.reindex(simtimedate, method='nearest') # resample or reindex QBL = DATA[['QBL', 'time']].fillna(method='ffill') QCHL = DATA[['QCHLsum', 'time']].fillna(value=0) Twb = DATA[['Twb', 'time']].fillna(method='ffill') Pow = DATA[['PCHsum', 'PCTtot', 'time']].sum(axis=1) del DATARAW, DATA os.chdir(currentdir) #%% modelica model test modelname = 'Merced.CoolingPlantNew.Dummytest' modelicafile = '/home/adun6414/Work/CERC_UCM/Merced/CoolingPlantNew/Dummytest.mo' import pymodelica import pyfmi myfmu = pymodelica.compile_fmu(modelname, modelicafile) fmuinpy = pyfmi.load_fmu(myfmu) UW = fmuinpy.get_model_variables(causality=0) Y = fmuinpy.get_model_variables(causality=1) C = fmuinpy.get_model_variables(variability=1) key_uw = UW.keys() key_y = Y.keys() key_c = [k for k in C.keys() if '_' not in k] IN = (obj.key_uw[0], QBL[['time', 'QBL']].to_numpy()) opts = fmuinpy.simulate_options() opts["ncp"] = IN[1].shape[ 0] - 1 #Specify a number of output points that should be returned
def parse_instances(model_path, file_name): '''Parse the signal exchange block class instances using fmu xml. Parameters ---------- model_path : str Path to modelica model file_name : list Path(s) to modelica file and required libraries not on MODELICAPATH. Passed to file_name parameter of pymodelica.compile_fmu() in JModelica. Returns ------- instances : dict Dictionary of overwrite and read block class instance lists. {'Overwrite': {input_name : {Unit : unit_name, Description : description, Minimum : min, Maximum : max}}, 'Read': {output_name : {Unit : unit_name, Description : description, Minimum : min, Maximum : max}}} signals : dict {'signal_type' : [output_name]} ''' # Compile fmu fmu_path = compile_fmu(model_path, file_name) # Load fmu fmu = load_fmu(fmu_path) # Check version if fmu.get_version() != '2.0': raise ValueError('FMU version must be 2.0') # Get all parameters allvars = fmu.get_model_variables(variability = 0).keys() + \ fmu.get_model_variables(variability = 1).keys() # Initialize dictionaries instances = {'Overwrite': dict(), 'Read': dict()} signals = {} # Find instances of 'Overwrite' or 'Read' for var in allvars: # Get instance name instance = '.'.join(var.split('.')[:-1]) # Overwrite if 'boptestOverwrite' in var: label = 'Overwrite' unit = fmu.get_variable_unit(instance + '.u') description = fmu.get(instance + '.description')[0] mini = fmu.get_variable_min(instance + '.u') maxi = fmu.get_variable_max(instance + '.u') # Read elif 'boptestRead' in var: label = 'Read' unit = fmu.get_variable_unit(instance + '.y') description = fmu.get(instance + '.description')[0] mini = None maxi = None # KPI elif 'KPIs' in var: label = 'kpi' else: continue # Save instance if label is not 'kpi': instances[label][instance] = {'Unit': unit} instances[label][instance]['Description'] = description instances[label][instance]['Minimum'] = mini instances[label][instance]['Maximum'] = maxi else: signal_type = fmu.get_variable_declared_type(var).items[fmu.get( var)[0]][0] if signal_type is 'None': continue elif signal_type in signals: signals[signal_type].append( _make_var_name(instance, style='output')) else: signals[signal_type] = [ _make_var_name(instance, style='output') ] # Clean up os.remove(fmu_path) os.remove(fmu_path.replace('.fmu', '_log.txt')) return instances, signals
def run_demo(with_plots=True): """ This example is based on the Hicks-Ray Continuously Stirred Tank Reactors (CSTR) system. The system has two states, the concentration and the temperature. The control input to the system is the temperature of the cooling flow in the reactor jacket. The chemical reaction in the reactor is exothermic, and also temperature dependent; high temperature results in high reaction rate. The problem is solved using the CasADi-based collocation algorithm. The steps performed correspond to those demonstrated in example pyjmi.examples.cstr, where the same problem is solved using the default JMI algorithm. FMI is used for initialization and simulation purposes. The following steps are demonstrated in this example: 1. How to solve the initialization problem. The initialization model has equations specifying that all derivatives should be identically zero, which implies that a stationary solution is obtained. Two stationary points, corresponding to different inputs, are computed. We call the stationary points A and B respectively. Point A corresponds to operating conditions where the reactor is cold and the reaction rate is low, whereas point B corresponds to a higher temperature where the reaction rate is high. 2. How to generate an initial guess for a direct collocation method by means of simulation with a constant input. The trajectories resulting from the simulation are used to initialize the variables in the transcribed NLP. 3. An optimal control problem is solved where the objective is to transfer the state of the system from stationary point A to point B. The challenge is to ignite the reactor while avoiding uncontrolled temperature increase. 4. Finally the system is simulated using the optimal control profile. This step is important in order to verify that the approximation in the transcription step is sufficiently accurate. """ ### 1. Solve the initialization problem # Locate the Modelica and Optimica code file_path = os.path.join(get_files_path(), "CSTR.mop") # Compile the stationary initialization model into a FMU init_fmu = compile_fmu("CSTR.CSTR_Init", file_path) # Load the FMU init_model = load_fmu(init_fmu) # Set input for Stationary point A Tc_0_A = 250 init_model.set('Tc', Tc_0_A) # Solve the initialization problem using FMI init_model.initialize() # Store stationary point A [c_0_A, T_0_A] = init_model.get(['c', 'T']) # Print some data for stationary point A print(' *** Stationary point A ***') print('Tc = %f' % Tc_0_A) print('c = %f' % c_0_A) print('T = %f' % T_0_A) # Set inputs for Stationary point B init_model = load_fmu(init_fmu) Tc_0_B = 280 init_model.set('Tc', Tc_0_B) # Solve the initialization problem using FMI init_model.initialize() # Store stationary point B [c_0_B, T_0_B] = init_model.get(['c', 'T']) # Print some data for stationary point B print(' *** Stationary point B ***') print('Tc = %f' % Tc_0_B) print('c = %f' % c_0_B) print('T = %f' % T_0_B) ### 2. Compute initial guess trajectories by means of simulation # Compile the optimization initialization model init_sim_fmu = compile_fmu("CSTR.CSTR_Init_Optimization", file_path) # Load the model init_sim_model = load_fmu(init_sim_fmu) # Set initial and reference values init_sim_model.set('cstr.c_init', c_0_A) init_sim_model.set('cstr.T_init', T_0_A) init_sim_model.set('c_ref', c_0_B) init_sim_model.set('T_ref', T_0_B) init_sim_model.set('Tc_ref', Tc_0_B) # Simulate with constant input Tc init_res = init_sim_model.simulate(start_time=0., final_time=150.) # Extract variable profiles c_init_sim = init_res['cstr.c'] T_init_sim = init_res['cstr.T'] Tc_init_sim = init_res['cstr.Tc'] t_init_sim = init_res['time'] # Plot the initial guess trajectories if with_plots: plt.close(1) plt.figure(1) plt.hold(True) plt.subplot(3, 1, 1) plt.plot(t_init_sim, c_init_sim) plt.grid() plt.ylabel('Concentration') plt.title('Initial guess obtained by simulation') plt.subplot(3, 1, 2) plt.plot(t_init_sim, T_init_sim) plt.grid() plt.ylabel('Temperature') plt.subplot(3, 1, 3) plt.plot(t_init_sim, Tc_init_sim) plt.grid() plt.ylabel('Cooling temperature') plt.xlabel('time') plt.show() ### 3. Solve the optimal control problem # Compile model fmux = compile_fmux("CSTR.CSTR_Opt2", file_path) # Load model cstr = CasadiModel(fmux) # Set reference values cstr.set('Tc_ref', Tc_0_B) cstr.set('c_ref', c_0_B) cstr.set('T_ref', T_0_B) # Set initial values cstr.set('cstr.c_init', c_0_A) cstr.set('cstr.T_init', T_0_A) # Set options opt_opts = cstr.optimize_options() opt_opts['n_e'] = 100 # Number of elements opt_opts['init_traj'] = init_res.result_data opt_opts['nominal_traj'] = init_res.result_data opt_opts['IPOPT_options']['tol'] = 1e-10 # Solve the optimal control problem res = cstr.optimize(options=opt_opts) # Extract variable profiles c_res = res['cstr.c'] T_res = res['cstr.T'] Tc_res = res['cstr.Tc'] time_res = res['time'] c_ref = res['c_ref'] T_ref = res['T_ref'] Tc_ref = res['Tc_ref'] # Verify solution for testing purposes try: import casadi except: pass else: cost = float(res.solver.solver.output(casadi.NLP_SOLVER_F)) assert(N.abs(cost/1.e3 - 1.8585429) < 1e-3) # Plot the results if with_plots: plt.close(2) plt.figure(2) plt.hold(True) plt.subplot(3, 1, 1) plt.plot(time_res, c_res) plt.plot([time_res[0], time_res[-1]], [c_ref, c_ref], '--') plt.grid() plt.ylabel('Concentration') plt.title('Optimized trajectories') plt.subplot(312) plt.plot(time_res,T_res) plt.plot([time_res[0],time_res[-1]],[T_ref,T_ref],'--') plt.grid() plt.ylabel('Temperature') plt.subplot(313) plt.plot(time_res,Tc_res) plt.plot([time_res[0],time_res[-1]],[Tc_ref,Tc_ref],'--') plt.grid() plt.ylabel('Cooling temperature') plt.xlabel('time') plt.show() ### 4. Simulate to verify the optimal solution # Compile model sim_fmu = compile_fmu("CSTR.CSTR", file_path) # Load model sim_model = load_fmu(sim_fmu) # Get optimized input (_, opt_input) = res.solver.get_opt_input() # Set initial values sim_model.set('c_init',c_0_A) sim_model.set('T_init',T_0_A) # Simulate using optimized input sim_opts = sim_model.simulate_options() sim_opts['CVode_options']['rtol'] = 1e-6 sim_opts['CVode_options']['atol'] = 1e-8 res = sim_model.simulate(start_time=0., final_time=150., input=('Tc', opt_input), options=sim_opts) # Extract variable profiles c_sim=res['c'] T_sim=res['T'] Tc_sim=res['Tc'] time_sim = res['time'] # Verify results N.testing.assert_array_less(abs(c_res[-1] - c_sim[-1])/c_res[-1], 5e-2) # Plot the results if with_plots: plt.close(3) plt.figure(3) plt.hold(True) plt.subplot(3, 1, 1) plt.plot(time_res, c_res, '--', lw=5) plt.plot(time_sim, c_sim, lw=2) plt.legend(('optimized', 'simulated')) plt.grid(True) plt.ylabel('Concentration') plt.title('Verification') plt.subplot(3, 1, 2) plt.plot(time_res, T_res, '--', lw=5) plt.plot(time_sim, T_sim, lw=2) plt.grid(True) plt.ylabel('Temperature') plt.subplot(3, 1, 3) plt.plot(time_res, Tc_res, '--', lw=5) plt.plot(time_sim, Tc_sim, lw=2) plt.grid(True) plt.ylabel('Cooling temperature') plt.xlabel('time') plt.show()
], axis=1) emissions_boptest.to_csv(os.path.join(gen.resources_dir, 'emissions.csv'), index=True) #===================================================================== # Generate variables from model #===================================================================== # Initialize data frame df = gen.create_df() file_name = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'BESTESTHydronicHeatPump') class_name = 'BESTESTHydronicHeatPump.TestCase' # Compile the model to generate the data fmu_path = compile_fmu(file_name=file_name, class_name=class_name) # Load FMU model = load_fmu(fmu_path) # Set number of communication points options = model.simulate_options() options['ncp'] = len(gen.time) - 1 # Simulate res = model.simulate(start_time=gen.time[0], final_time=gen.time[-1], options=options) keysMap = {}
# give the path to directory where package.mo is stored moLibs = [ os.path.join(jmodDir, "ThirdParty\MSL\Modelica"), os.path.join(moLiDir, "BuildingSystems"), ] print(sys.version) print( all(os.path.isfile(os.path.join(moLib, "package.mo")) for moLib in moLibs)) print(os.getcwd()) # <codecell> compile model to fmu from pymodelica import compile_fmu model_name = 'BuildingSystems.Applications.BuildingTypes.Germany.Rowhouse1918' my_fmu = compile_fmu(model_name, moLibs) # <codecell> simulate the fmu and store results from pyfmi import load_fmu myModel = load_fmu(my_fmu) opts = myModel.simulate_options() opts['solver'] = "CVode" opts['ncp'] = 8760 opts['result_handling'] = "file" opts["CVode_options"]['discr'] = 'BDF' opts['CVode_options']['iter'] = 'Newton' opts['CVode_options']['maxord'] = 5 opts['CVode_options']['atol'] = 1e-5 opts['CVode_options']['rtol'] = 1e-5
def generate_weather( self, model_class='IBPSA.BoundaryConditions.WeatherData.ReaderTMY3', model_library=None): '''Generate the weather data and store into a csv file. This method reads the data from a .mos or .TMY file and applies a transformation carried out by the ReaderTMY3 model of the IBPSA library. The user could provide any other reader model but should then make sure that the naming convention is accomplished. Parameters ---------- model_class: string, default is IBPSA TMY3 Reader Name of the model class that is going to be used to pre-process the weather data. This is most likely to be the ReaderTMY3 of IBPSA but other classes could be created. model_library: string, default is None String to library path. If empty it will look for IBPSA library in MODELICAPATH ''' # Initialize data frame df = self.create_df() if not model_library: # Try to find the IBPSA library for p in os.environ['MODELICAPATH'].split(self.sep): if os.path.isdir(os.path.join(p, 'IBPSA')): model_library = os.path.join(p, 'IBPSA') # Raise an error if ibpsa cannot be found if not model_library: raise ValueError('Provide a valid model_library or point '\ 'to the IBPSA library in your MODELICAPATH') # Path to modelica reader model file model_file = model_library for f in model_class.split('.')[1:]: model_file = os.path.join(model_file, f) model_file = model_file + '.mo' # Edit the class to load the weather_file_name before compilation str_old = 'filNam=""' str_new = 'filNam=Modelica.Utilities.Files.loadResource("{0}")'\ .format(self.weather_file_name) with open(model_file) as f: newText = f.read().replace(str_old, str_new) with open(model_file, "w") as f: f.write(newText) # Change to Resources directory currdir = os.curdir os.chdir(self.weather_dir) # Compile the ReaderTMY3 from IBPSA using JModelica fmu_path = compile_fmu(model_class, model_library) # Revert changes in directory and model file os.chdir(currdir) with open(model_file) as f: newText = f.read().replace(str_new, str_old) with open(model_file, "w") as f: f.write(newText) # Load FMU model = load_fmu(fmu_path) # Set number of communication points options = model.simulate_options() options['ncp'] = len(self.time) - 1 # Simulate res = model.simulate(start_time=self.time[0], final_time=self.time[-1], options=options) # Get model outputs output_names = [] for key in res.keys(): if 'weaBus.' in key: output_names.append(key) # Write every output in the data for out in output_names: # Interpolate to avoid problems with events from Modelica g = interpolate.interp1d(res['time'], res[out], kind='linear') df.loc[:, out.replace('weaBus.', '')] = g(self.time) # Store in csv self.store_df(df, 'weather') return df
else: model = sys.argv[1] print("*** Compiling {}".format(model)) # Increase memory pymodelica.environ['JVM_ARGS'] = '-Xmx4096m' sys.stdout.flush() ###################################################################### # Compile fmu fmu_name = compile_fmu( model, version="2.0", compiler_log_level='warning', #'info', 'warning', compiler_options={ "generate_html_diagnostics": True, "event_output_vars": True, "nle_solver_tol_factor": 1e-2 }) # 1e-2 is the default ###################################################################### # Copy style sheets. # This is a hack to get the css and js files to render the html diagnostics. htm_dir = os.path.splitext(os.path.basename(fmu_name))[0] + "_html_diagnostics" if os.path.exists(htm_dir): for fil in ["scripts.js", "style.css", "zepto.min.js"]: src = os.path.join(".jmodelica_html", fil) if os.path.exists(src): des = os.path.join(htm_dir, fil) shutil.copyfile(src, des)
from pymodelica import compile_fmu print("Export Modelica models as FMU Model Exchange Version 2.0") model_name = raw_input( "What is the name of the Modelica model you would like to export? \n") mo_file = raw_input( "What is the name of the Modelica file? (ex. RLC_Circuit.mo). Multiple dependent files can be added as RLC_Circuit.mo, RLC_Dependent.mo" ) # model_name = 'RLC_Circuit' # mo_file = 'RLC_Circuit.mo' my_fmu = compile_fmu(model_name, mo_file, version=2.0)
def write_wrapper(model_path, file_name, instances): '''Write the wrapper modelica model and export as fmu Parameters ---------- model_path : str Path to orginal modelica model file_name : list Path(s) to modelica file and required libraries not on MODELICAPATH. Passed to file_name parameter of pymodelica.compile_fmu() in JModelica. instances : dict Dictionary of overwrite and read block class instance lists. {'Overwrite': [str], 'Read': [str]} Returns ------- fmu_path : str Path to the wrapped modelica model fmu wrapped_path : str or None Path to the wrapped modelica model if instances of signale exchange. Otherwise, None ''' # Check for instances of Overwrite and/or Read blocks len_write_blocks = len(instances['Overwrite']) len_read_blocks = len(instances['Read']) # If there are, write and export wrapper model if (len_write_blocks + len_read_blocks): # Define wrapper modelica file path wrapped_path = 'wrapped.mo' # Open file with open(wrapped_path, 'w') as f: # Start file f.write('model wrapped "Wrapped model"\n') # Add inputs for every overwrite block f.write('\t// Input overwrite\n') input_signals_w_info = dict() input_signals_wo_info = dict() input_activate_w_info = dict() input_activate_wo_info = dict() for block in instances['Overwrite'].keys(): # Add to signal input list with and without units input_signals_w_info[block] = _make_var_name( block, style='input_signal', description=instances['Overwrite'][block]['Description'], attribute='(unit="{0}", min={1}, max={2})'.format( instances['Overwrite'][block]['Unit'], instances['Overwrite'][block]['Minimum'], instances['Overwrite'][block]['Maximum'])) input_signals_wo_info[block] = _make_var_name( block, style='input_signal') # Add to signal activate list input_activate_w_info[block] = _make_var_name( block, style='input_activate', description='Activation for {0}'.format( instances['Overwrite'][block]['Description'])) input_activate_wo_info[block] = _make_var_name( block, style='input_activate') # Instantiate input signal f.write('\tModelica.Blocks.Interfaces.RealInput {0};\n'.format( input_signals_w_info[block], block)) # Instantiate input activation f.write( '\tModelica.Blocks.Interfaces.BooleanInput {0};\n'.format( input_activate_w_info[block], block)) # Add outputs for every read block f.write('\t// Out read\n') for block in instances['Read'].keys(): # Instantiate input signal f.write( '\tModelica.Blocks.Interfaces.RealOutput {0} = mod.{1}.y "{2}";\n' .format( _make_var_name(block, style='output', attribute='(unit="{0}")'.format( instances['Read'][block]['Unit'])), block, instances['Read'][block]['Description'])) # Add original model f.write('\t// Original model\n') f.write('\t{0} mod(\n'.format(model_path)) # Connect inputs to original model overwrite and activate signals if len_write_blocks: for i, block in enumerate(instances['Overwrite']): f.write('\t\t{0}(uExt(y={1}),activate(y={2}))'.format( block, input_signals_wo_info[block], input_activate_wo_info[block])) if i == len(instances['Overwrite']) - 1: f.write(') "Original model with overwrites";\n') else: f.write(',\n') else: f.write(') "Original model without overwrites";\n') # End file f.write('end wrapped;') # Export as fmu fmu_path = compile_fmu('wrapped', [wrapped_path] + file_name) # If there are not, write and export wrapper model else: # Warn user warnings.warn( 'No signal exchange block instances found in model. Exporting model as is.' ) # Compile fmu fmu_path = compile_fmu(model_path, file_name) wrapped_path = None return fmu_path, wrapped_path
def run_demo(with_plots=True): """ This example is based on a combined cycle power plant (CCPP). The model has 9 states, 128 algebraic variables and 1 control variable. The task is to minimize the time required to perform a warm start-up of the power plant. This problem has become highly industrially relevant during the last few years, due to an increasing need to improve power generation flexibility. The example consists of the following steps: 1. Simulating the system using a simple input trajectory. 2. Solving the optimal control problem using the result from the first step to initialize the non-linear program. In addition, a set of algebraic variables is eliminated by means of BLt information 3. Verifying the result from the second step by simulating the system once more usng the optimized input trajectory. The model was developed by Francesco Casella and is published in @InProceedings{CFA2011, author = "Casella, Francesco and Donida, Filippo and {\AA}kesson, Johan", title = "Object-Oriented Modeling and Optimal Control: A Case Study in Power Plant Start-Up", booktitle = "18th IFAC World Congress", address = "Milano, Italy", year = 2011, month = aug } """ ### 1. Compute initial guess trajectories by means of simulation # Locate the Modelica and Optimica code file_paths = (os.path.join(get_files_path(), "CombinedCycle.mo"), os.path.join(get_files_path(), "CombinedCycleStartup.mop")) # Compile the optimization initialization model init_sim_fmu = compile_fmu("CombinedCycleStartup.Startup6Reference", file_paths, separate_process=True) # Load the model init_sim_model = load_fmu(init_sim_fmu) # Simulate init_res = init_sim_model.simulate(start_time=0., final_time=10000.) # Extract variable profiles init_sim_plant_p = init_res['plant.p'] init_sim_plant_sigma = init_res['plant.sigma'] init_sim_plant_load = init_res['plant.load'] init_sim_time = init_res['time'] # Plot the initial guess trajectories if with_plots: plt.close(1) plt.figure(1) plt.subplot(3, 1, 1) plt.plot(init_sim_time, init_sim_plant_p * 1e-6) plt.ylabel('evaporator pressure [MPa]') plt.grid(True) plt.title('Initial guess obtained by simulation') plt.subplot(3, 1, 2) plt.plot(init_sim_time, init_sim_plant_sigma * 1e-6) plt.grid(True) plt.ylabel('turbine thermal stress [MPa]') plt.subplot(3, 1, 3) plt.plot(init_sim_time, init_sim_plant_load) plt.grid(True) plt.ylabel('input load [1]') plt.xlabel('time [s]') ### 2. Solve the optimal control problem # Compile model from pyjmi import transfer_to_casadi_interface compiler_options={'equation_sorting':True, "common_subexp_elim":False} op = transfer_to_casadi_interface("CombinedCycleStartup.Startup6", file_paths, compiler_options) # Set options opt_opts = op.optimize_options() opt_opts['n_e'] = 50 # Number of elements opt_opts['init_traj'] = init_res # Simulation result opt_opts['nominal_traj'] = init_res # variable elimination eliminables = op.getEliminableVariables() algebraics = op.getVariables(op.REAL_ALGEBRAIC) print("Number of algebraics: ",len(algebraics)) print("Eliminating variables!") eliminable_algebraics = [a for a in algebraics if a in eliminables] variables_to_eliminate = list() variables_with_bounds = list() for v in eliminable_algebraics: if not v.hasAttributeSet("min") and not v.hasAttributeSet("max"): variables_to_eliminate.append(v) else: variables_with_bounds.append(v) # Elimination of unbounded variables op.markVariablesForElimination(variables_to_eliminate) # Elimination of bounded variables (skip elimination of plant.sigma) bounded_eliminations = [v for v in variables_with_bounds if not v.getName()=="plant.sigma"] op.markVariablesForElimination(bounded_eliminations) op.eliminateVariables() # Alternative way of eliminating variables however this method do not eliminate any bounded variables #op.eliminateAlgebraics() print("Done with elimination") eliminated_vars = op.getEliminatedVariables() print("Number of variables that were eliminated: ", len(eliminated_vars)) # Solve the optimal control problem opt_res = op.optimize(options=opt_opts) # get output of one eliminated variable elim_var_name = eliminable_algebraics[5].getName() # Extract variable profiles opt_plant_p = opt_res['plant.p'] opt_plant_sigma = opt_res['plant.sigma'] opt_plant_load = opt_res['plant.load'] opt_eliminated = opt_res[elim_var_name] opt_time = opt_res['time'] opt_input = N.vstack([opt_time, opt_plant_load]).T # Plot the optimized trajectories if with_plots: plt.close(2) plt.figure(2) plt.subplot(4, 1, 1) plt.plot(opt_time, opt_plant_p * 1e-6) plt.ylabel('evaporator pressure [MPa]') plt.grid(True) plt.title('Optimized trajectories') plt.subplot(4, 1, 2) plt.plot(opt_time, opt_plant_sigma * 1e-6) plt.grid(True) plt.ylabel('turbine thermal stress [MPa]') plt.subplot(4, 1, 3) plt.plot(opt_time, opt_plant_load) plt.grid(True) plt.ylabel('input load [1]') plt.xlabel('time [s]') plt.subplot(4, 1, 4) plt.plot(opt_time, opt_eliminated) plt.grid(True) plt.ylabel(elim_var_name) plt.xlabel('time [s]') # Verify solution for testing purposes try: import casadi except: pass else: cost = float(opt_res.solver.solver_object.output(casadi.NLP_SOLVER_F)) N.testing.assert_allclose(cost, 17492.465548193624, rtol=1e-5) ### 3. Simulate to verify the optimal solution # Compile model sim_fmu = compile_fmu("CombinedCycle.Optimization.Plants.CC0D_WarmStartUp", file_paths) # Load model sim_model = load_fmu(sim_fmu) # Simulate using optimized input sim_res = sim_model.simulate(start_time=0., final_time=4000., input=('load', opt_input)) # Extract variable profiles sim_plant_p = sim_res['p'] sim_plant_sigma = sim_res['sigma'] sim_plant_load = sim_res['load'] sim_time = sim_res['time'] # Plot the simulated trajectories if with_plots: plt.close(3) plt.figure(3) plt.subplot(3, 1, 1) plt.plot(opt_time, opt_plant_p * 1e-6, '--', lw=5) plt.hold(True) plt.plot(sim_time, sim_plant_p * 1e-6, lw=2) plt.ylabel('evaporator pressure [MPa]') plt.grid(True) plt.legend(('optimized', 'simulated'), loc='lower right') plt.title('Verification') plt.subplot(3, 1, 2) plt.plot(opt_time, opt_plant_sigma * 1e-6, '--', lw=5) plt.hold(True) plt.plot(sim_time, sim_plant_sigma * 1e-6, lw=2) plt.ylabel('turbine thermal stress [MPa]') plt.grid(True) plt.subplot(3, 1, 3) plt.plot(opt_time, opt_plant_load, '--', lw=5) plt.hold(True) plt.plot(sim_time, sim_plant_load, lw=2) plt.ylabel('input load [1]') plt.xlabel('time [s]') plt.grid(True) plt.show() # Verify solution for testing purposes N.testing.assert_allclose(opt_res.final('plant.p'), sim_res.final('p'), rtol=5e-3)
from pymodelica import compile_fmu from pyfmi import load_fmu libPath = r'C:\Users\vmg\Documents\Modelica\TRANSFORM-Library/TRANSFORM' modelName = 'TRANSFORM.Examples.LightWaterSmallModularReactor.Examples.IRIS_Default_Teststandalone' fmu = compile_fmu(modelName, libPath, target='cs') model = load_fmu(fmu) opts = model.simulate_options() opts['time_limit'] = 60 results = model.simulate(options=opts)
from pymodelica import compile_fmu fmu_name = compile_fmu("{{model_name}}", "{{model_name}}.mo", version="{{fmi_version}}", target="{{fmi_api}}", compiler_options={'extra_lib_dirs':["{{sim_lib_path}}"]})
# -*- coding: utf-8 -*- """ This module compiles the defined test case model into an FMU using the overwrite block parser. The following libraries must be on the MODELICAPATH: - Modelica IBPSA - Modelica Buildings """ from pymodelica import compile_fmu # DEFINE MODEL # ------------ # library path mopath = 'RCNetworks' # model path modelpath = 'RCNetworks.Examples.HighThermalMassWall' # ------------ # COMPILE FMU: set JVM maximum leap to 1G to avoid memory issues # ----------- #fmupath = parser.export_fmu(modelpath, [mopath]) fmupath = compile_fmu(modelpath, [mopath], jvm_args='-Xmx1g') # -----------
def run_demo(): """ Demonstrate how to parse a log file from a JModelica FMU. """ curr_dir = os.path.dirname(os.path.abspath(__file__)) file_name = os.path.join(curr_dir, 'files', 'LoggerTest.mo') fmu_name = compile_fmu( 'LoggerTest', file_name, compiler_log_level='i', compiler_options={'generate_only_initial_system': True}) log_file_name = 'LoggerTest_log.txt' m = load_fmu(fmu_name, log_file_name=log_file_name) m.set_debug_logging(True) m.set('_log_level', 6) m.set_fmil_log_level(5) # Play around with the model m.set('u1', 3) print 'u1' + str(m.get('u1')) print 'x1' + str(m.get('x1')) print 'y1' + str(m.get('y1')) print 'z1' + str(m.get('z1')) m.set('y1', 0.) m.initialize() print "model initialized" print 'u1' + str(m.get('u1')) print 'x1' + str(m.get('x1')) print 'y1' + str(m.get('y1')) print 'z1' + str(m.get('z1')) m.set('u1', 4) print "Input set" print 'u1' + str(m.get('u1')) print 'x1' + str(m.get('x1')) print 'y1' + str(m.get('y1')) print 'z1' + str(m.get('z1')) m.get_derivatives() m.set('y1', 0.5) print "Set initial value of y1" print 'x1' + str(m.get('x1')) print 'y1' + str(m.get('y1')) print 'z1' + str(m.get('z1')) m.set('p', 0.5) print "Set initial value of p" print 'x1' + str(m.get('x1')) print 'y1' + str(m.get('y1')) print 'z1' + str(m.get('z1')) # Parse the log file and print some of its contents # Extract the log file XML contents into a pure XML file dest_xml_file_name = 'LoggerTest_log.xml' extract_jmi_log(dest_xml_file_name, log_file_name) # Parse the entire XML log log = parse_jmi_log(log_file_name) print print 'Top log node: log =', log print 'Unnamed sub nodes: log.nodes = [' for node in log.nodes: print ' ', node, ',' print ']' # Gather information pertaining to equation solves solves = gather_solves(log) print print 'Number of solver invocations:', len(solves) print 'Time of first solve:', solves[0].t print 'Number of block solves in first solver invocation:', len( solves[0].block_solves) print 'Names of iteration variables in first block solve:', solves[ 0].block_solves[0].variables print 'Min bounds in first block solve:', solves[0].block_solves[0].min print 'Max bounds in first block solve:', solves[0].block_solves[0].max print 'Initial residual scaling in first block solve:', solves[ 0].block_solves[0].initial_residual_scaling print 'Number of iterations in first block solve:', len( solves[0].block_solves[0].iterations) print print 'First iteration in first block solve: ' print ' Iteration variables:', solves[0].block_solves[0].iterations[0].ivs print ' Scaled residuals:', solves[0].block_solves[0].iterations[ 0].scaled_residuals print ' Jacobian:\n', solves[0].block_solves[0].iterations[0].jacobian print ' Jacobian updated in iteration:', solves[0].block_solves[ 0].iterations[0].jacobian_updated print ' Residual scaling factors:', solves[0].block_solves[0].iterations[ 0].residual_scaling print ' Residual scaling factors_updated:', solves[0].block_solves[ 0].iterations[0].residual_scaling_updated print ' Scaled residual norm:', solves[0].block_solves[0].iterations[ 0].scaled_residual_norm
def run_demo(with_plots=True): """ This example is based on the multibody mechanics double pendulum example from the Modelica Standard Library (MSL). The MSL example has been modified by adding a torque on the first revolute joint of the pendulum as a top-level input. The considered optimization problem is to invert both pendulum bodies with bounded torque. This example needs linear solver MA27 to work. """ # Simulate system with linear state feedback to generate initial guess file_paths = (os.path.join(get_files_path(), "DoublePendulum.mo"), os.path.join(get_files_path(), "DoublePendulum.mop")) comp_opts = {'inline_functions': 'all', 'dynamic_states': False, 'expose_temp_vars_in_fmu': True, 'equation_sorting': True, 'automatic_tearing': True} init_fmu = load_fmu(compile_fmu("DoublePendulum.Feedback", file_paths, compiler_options=comp_opts)) init_res = init_fmu.simulate(final_time=3., options={'CVode_options': {'rtol': 1e-10}}) # Set up optimization op = transfer_optimization_problem('Opt', file_paths, compiler_options=comp_opts) opts = op.optimize_options() opts['IPOPT_options']['linear_solver'] = "ma27" opts['n_e'] = 100 opts['init_traj'] = init_res opts['nominal_traj'] = init_res # Symbolic elimination op = BLTOptimizationProblem(op) # Solve optimization problem res = op.optimize(options=opts) # Extract solution time = res['time'] phi1 = res['pendulum.revolute1.phi'] phi2 = res['pendulum.revolute2.phi'] u = res['u'] # Verify solution for testing purposes try: import casadi except: pass else: cost = float(res.solver.solver_object.output(casadi.NLP_SOLVER_F)) N.testing.assert_allclose(cost, 9.632883808252522, rtol=5e-3) # Plot solution if with_plots: plt.close(1) plt.figure(1) plt.subplot(2, 1, 1) plt.plot(time, phi1, 'b') plt.plot(time, phi2, 'r') plt.legend(['$\phi_1$', '$\phi_2$']) plt.ylabel('$\phi$') plt.xlabel('$t$') plt.grid() plt.subplot(2, 1, 2) plt.plot(time, u) plt.ylabel('$u$') plt.xlabel('$t$') plt.grid() plt.show()