Skip to content

Commit 9e7bc32

Browse files
committed
Various cleaning
1 parent 879348b commit 9e7bc32

File tree

9 files changed

+118
-114
lines changed

9 files changed

+118
-114
lines changed

parsing/parser.py

Lines changed: 92 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
# -*- coding: utf-8 -*-
22
"""
3-
Implements the .mo file parsing and generates wrapped.fmu. The supported
4-
tools are OpenModelica, Dymola, and OCT. In order to parse with a supported tool,
5-
it must be installed on the system.
6-
Choose as tool for compilation using variable "tool".
3+
Implements the .mo file parsing and generates teh test case wrapped.fmu.
4+
The supported tools are OpenModelica, Dymola, and OCT.
5+
In order to parse with a supported tool, it must be installed on the system.
6+
The primary function to use here is export_fmu() and its arguments for
7+
tool and solver options.
78
8-
The steps are:
9+
The general steps are:
910
1) Compile Modelica code into fmu
1011
2) Use signal exchange block id parameters to find block instance paths and
1112
read any associated signals for KPIs, units, min/max, and descriptions.
@@ -32,22 +33,84 @@
3233
else:
3334
modelicapath=os.path.abspath('.')
3435

36+
def compile_fmu_OM(model_path, file_name, algorithm='cvode', tolerance=1e-6):
37+
'''Use OpenModelica via OMPython to compile FMU.
38+
39+
Parameters
40+
----------
41+
model_path : str
42+
Path to modelica model
43+
file_name : list
44+
Path(s) to modelica file and required libraries not on MODELICAPATH.
45+
algorithm : str, optional
46+
Specify the solver algorithm. Only 'cvode' available for OpenModelica.
47+
Default is 'cvode'.
48+
tolerance : numeric, optional
49+
Specify the solver tolerance.
50+
Default is 1e-6.
51+
52+
Returns
53+
-------
54+
fmu_path : str
55+
Generated FMU path.
56+
57+
'''
58+
59+
from OMPython import OMCSessionZMQ
60+
omc = OMCSessionZMQ()
61+
# Load libraries from MODELICAPATH
62+
libs = []
63+
for d in os.environ['MODELICAPATH'].split(':'):
64+
if ('Buildings' in d):
65+
path = d+'/package.mo'
66+
elif ('IDEAS' in d):
67+
path = d+'/package.mo'
68+
elif ('IBPSA' in d):
69+
path = d+'/package.mo'
70+
else:
71+
continue
72+
libs.append(path)
73+
for f in file_name:
74+
res = omc.sendExpression('loadFile("{0}")'.format(f))
75+
print('Loaded file: {0}, {1}'.format(f, res))
76+
# Load Modelica library
77+
res = omc.sendExpression('loadModel(Modelica)')
78+
print('Loaded library: Modelica, {0}'.format(res))
79+
# Load packages from libraries
80+
for lib in libs:
81+
res = omc.sendExpression('loadFile("{0}")'.format(lib))
82+
print('Loaded library: {0}, {1}'.format(lib, res))
83+
# Set Compilation Flags as annotations
84+
res = omc.sendExpression('setCommandLineOptions("--matchingAlgorithm=PFPlusExt \
85+
--indexReductionMethod=dynamicStateSelection -d=initialization")')
86+
87+
# Set simulation flags via fmiFlags
88+
res = omc.sendExpression('setCommandLineOptions("--fmiFlags=s:{0},lv:LOG_STDOUT \
89+
LOG_ASSERT LOG_STATS,tolerance:{1}")'.format(algorithm,tolerance))
90+
91+
# Compile FMU
92+
fmu_path = omc.sendExpression('buildModelFMU({0}, fmuType="cs")'.format(model_path))
93+
94+
return fmu_path
95+
3596
def compile_fmu_dymola(model_path, algorithm='Cvode', tolerance=1e-6):
36-
'''Execute dymola process to compile FMU.
97+
'''Use Dymola to compile FMU.
3798
99+
Parameters
100+
----------
38101
model_path : str
39102
Path to modelica model
40103
algorithm : str, optional
41104
Specify the solver algorithm. Options are 'Cvode', 'Dassl', 'Radau', 'Lsodar'.
42105
Default is 'Cvode'.
43106
tolerance : numeric, optional
44-
Specify the solver tolerance.
107+
Specify the solver tolerance.
45108
Default is 1e-6.
46-
109+
47110
Returns
48111
-------
49112
fmu_path : str
50-
generated FMU path.
113+
Generated FMU path.
51114
52115
'''
53116

@@ -176,8 +239,8 @@ def parse_instances(model_path, file_name, tool='openmodelica', algorithm='cvode
176239
tool : str, optional
177240
FMU compilation tool. "OCT" or "dymola" or "openmodelica" supported.
178241
Default is "openmodelica".
179-
algorithm : str, optional
180-
Specify the solver algorithm. Check _solver_check function for options
242+
algorithm : str, optional
243+
Specify the solver algorithm. Check _solver_check function for options.
181244
Default is 'cvode'.
182245
tolerance : numeric, optional
183246
Specify the solver tolerance.
@@ -198,7 +261,7 @@ def parse_instances(model_path, file_name, tool='openmodelica', algorithm='cvode
198261
# Compile fmu
199262
if tool == 'OCT':
200263
from pymodelica import compile_fmu
201-
fmu_path = compile_fmu(model_path, file_name, modelicapath=modelicapath, jvm_args="-Xmx8g", target='cs',
264+
fmu_path = compile_fmu(model_path, file_name, modelicapath=modelicapath, jvm_args="-Xmx8g", target='cs',
202265
compiler_options = {'cs_rel_tol': tolerance,'cs_solver': algorithm})
203266
elif tool == 'openmodelica':
204267
fmu_path = compile_fmu_OM(model_path, file_name)
@@ -313,7 +376,7 @@ def parse_instances(model_path, file_name, tool='openmodelica', algorithm='cvode
313376
signals[signal_type].append(_make_var_name(instance,style='output'))
314377
else:
315378
signals[signal_type] = [_make_var_name(instance,style='output')]
316-
379+
317380
return instances, signals
318381

319382
def write_wrapper(model_path, file_name, instances, tool='openmodelica', algorithm='cvode', tolerance=1e-6):
@@ -336,7 +399,7 @@ def write_wrapper(model_path, file_name, instances, tool='openmodelica', algorit
336399
Specify the solver algorithm. Check _solver_check function for options.
337400
Default is 'cvode'.
338401
tolerance : numeric, optional
339-
Specify the solver tolerance.
402+
Specify the solver tolerance.
340403
Default is 1e-6.
341404
342405
Returns
@@ -404,7 +467,7 @@ def write_wrapper(model_path, file_name, instances, tool='openmodelica', algorit
404467
# Export as fmu
405468
if tool == 'OCT':
406469
from pymodelica import compile_fmu
407-
fmu_path = compile_fmu('wrapped', [wrapped_path]+file_name, modelicapath=modelicapath, jvm_args="-Xmx8g", target='cs',
470+
fmu_path = compile_fmu('wrapped', [wrapped_path]+file_name, modelicapath=modelicapath, jvm_args="-Xmx8g", target='cs',
408471
compiler_options = {'cs_rel_tol': tolerance,'cs_solver': algorithm})
409472
elif tool == 'openmodelica':
410473
fmu_path = compile_fmu_OM('wrapped', [wrapped_path]+file_name)
@@ -420,7 +483,7 @@ def write_wrapper(model_path, file_name, instances, tool='openmodelica', algorit
420483
# Compile fmu
421484
if tool == 'OCT':
422485
from pymodelica import compile_fmu
423-
fmu_path = compile_fmu(model_path, file_name, modelicapath=modelicapath, jvm_args="-Xmx8g", target='cs',
486+
fmu_path = compile_fmu(model_path, file_name, modelicapath=modelicapath, jvm_args="-Xmx8g", target='cs',
424487
compiler_options = {'cs_rel_tol': tolerance,'cs_solver': algorithm})
425488
elif tool == 'openmodelica':
426489
fmu_path = compile_fmu_OM(model_path, file_name)
@@ -449,7 +512,7 @@ def export_fmu(model_path, file_name, tool='openmodelica', algorithm='cvode', to
449512
Specify the solver algorithm. Check _solver_check function for options.
450513
Default is 'cvode'.
451514
tolerance : numeric, optional
452-
Specify the solver tolerance.
515+
Specify the solver tolerance.
453516
Default is 1e-6.
454517
455518
Returns
@@ -463,7 +526,7 @@ def export_fmu(model_path, file_name, tool='openmodelica', algorithm='cvode', to
463526

464527
# Take folder snapshot for cleanup
465528
folder_content = set(os.listdir())
466-
# Check if solver option is valid
529+
# Check if solver option is valid
467530
_solver_check(algorithm,tool)
468531
# Get signal exchange instances and kpi signals
469532
instances, signals = parse_instances(model_path, file_name, tool, algorithm=algorithm, tolerance=tolerance)
@@ -476,7 +539,7 @@ def export_fmu(model_path, file_name, tool='openmodelica', algorithm='cvode', to
476539
# Generate test case data
477540
man = Data_Manager()
478541
man.save_data_and_jsons(fmu_path=fmu_path)
479-
542+
480543
# Clean up
481544
folder_content_remove = set(os.listdir())
482545
keep = {"wrapped.fmu", "wrapped.mo","kpis.json"}
@@ -532,92 +595,33 @@ def _make_var_name(block, style, description='', attribute=''):
532595

533596
return var_name
534597

535-
def _solver_check(algorithm,tool):
536-
'''Checks if solver option is correct for the chosen tool.
598+
def _solver_check(algorithm, tool):
599+
'''Checks if solver option is valid for the chosen tool.
600+
601+
Parameters
602+
----------
537603
algorithm : str
538604
Specify the solver algorithm.
539-
Default is "cvode"
540605
tool : str, optional
541606
FMU compilation tool. "OCT" or "dymola" or "openmodelica" supported.
542-
Default is "openmodelica".
543607
544608
'''
609+
545610
# Check solver option is valid
546611
if tool == 'dymola':
547612
valid_algorithms = ['Cvode', 'Dassl', 'Radau', 'Lsodar']
548613
if (algorithm not in valid_algorithms):
549-
raise ValueError('Invalid algorithm "{0}" for tool Dymola. Choose from {1}.'.format(algorithm, valid_algorithms))
550-
551-
elif tool == 'openmodelica':
614+
raise ValueError('Invalid algorithm "{0}" for tool {1}. Choose from {2}.'.format(algorithm, tool, valid_algorithms))
615+
elif tool == 'openmodelica':
552616
valid_algorithms = ['cvode']
553617
if (algorithm not in valid_algorithms):
554-
raise ValueError('Invalid algorithm "{0}" for tool OpenModelica. Choose from {1}.'.format(algorithm, valid_algorithms))
555-
618+
raise ValueError('Invalid algorithm "{0}" for tool {1}. Choose from {2}.'.format(algorithm, tool, valid_algorithms))
556619
elif tool == 'OCT':
557620
valid_algorithms = ['CVode', 'Radau5ODE', 'RungeKutta34', 'ExplicitEuler']
558621
if (algorithm not in valid_algorithms):
559-
raise ValueError('Invalid algorithm "{0}" for tool OCT. Choose from {1}.'.format(algorithm, valid_algorithms))
560-
622+
raise ValueError('Invalid algorithm "{0}" for tool {1}. Choose from {2}.'.format(algorithm, tool, valid_algorithms))
561623
else:
562624
raise ValueError('Tool {0} unknown.'.format(tool))
563-
564-
565-
def compile_fmu_OM(model_path, file_name, algorithm='cvode', tolerance=1e-6):
566-
'''Utilize OMPython to compile OpenModelica FMU.
567-
568-
model_path : str
569-
Path to modelica model
570-
file_name : list
571-
Path(s) to modelica file and required libraries not on MODELICAPATH.
572-
algorithm : str, optional
573-
Specify the solver algorithm. Only 'cvode' available for OpenModelica.
574-
Default is 'cvode'.
575-
tolerance : numeric, optional
576-
Specify the solver tolerance.
577-
Default is 1e-6.
578-
579-
Returns
580-
-------
581-
fmu_path : str
582-
generated FMU path.
583-
584-
'''
585-
from OMPython import OMCSessionZMQ
586-
omc = OMCSessionZMQ()
587-
# Load libraries from MODELICAPATH
588-
libs = []
589-
for d in os.environ['MODELICAPATH'].split(':'):
590-
if ('Buildings' in d):
591-
path = d+'/package.mo'
592-
elif ('IDEAS' in d):
593-
path = d+'/package.mo'
594-
elif ('IBPSA' in d):
595-
path = d+'/package.mo'
596-
else:
597-
continue
598-
libs.append(path)
599-
for f in file_name:
600-
res = omc.sendExpression('loadFile("{0}")'.format(f))
601-
print('Loaded file: {0}, {1}'.format(f, res))
602-
# Load Modelica library
603-
res = omc.sendExpression('loadModel(Modelica)')
604-
print('Loaded library: Modelica, {0}'.format(res))
605-
# Load packages from libraries
606-
for lib in libs:
607-
res = omc.sendExpression('loadFile("{0}")'.format(lib))
608-
print('Loaded library: {0}, {1}'.format(lib, res))
609-
# Set Compilation Flags as annotations
610-
res = omc.sendExpression('setCommandLineOptions("--matchingAlgorithm=PFPlusExt \
611-
--indexReductionMethod=dynamicStateSelection -d=initialization")')
612-
613-
# Set simulation flags via fmiFlags
614-
res = omc.sendExpression('setCommandLineOptions("--fmiFlags=s:{0},lv:LOG_STDOUT \
615-
LOG_ASSERT LOG_STATS,tolerance:{1}")'.format(algorithm,tolerance))
616-
617-
# Compile FMU
618-
fmu_path = omc.sendExpression('buildModelFMU({0}, fmuType="cs")'.format(model_path))
619-
620-
return fmu_path
621625

622626
if __name__ == '__main__':
623627
# Define model

testcases/bestest_hydronic_heat_pump/models/compile_fmu.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def compile_fmu():
2727

2828
# DEFINE MODEL
2929
# ------------
30-
mopath = 'BESTESTHydronicHeatPump'
30+
mopath = 'BESTESTHydronicHeatPump/package.mo'
3131
modelpath = 'BESTESTHydronicHeatPump.TestCase'
3232
# ------------
3333

testcases/multizone_residential_hydronic/models/compile_fmu.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def compile_fmu():
2828

2929
# DEFINE MODEL
3030
# ------------
31-
mopath = 'MultiZoneResidentialHydronic'
31+
mopath = 'MultiZoneResidentialHydronic/package.mo'
3232
modelpath = 'MultiZoneResidentialHydronic.TestCase'
3333
# ------------
3434

testcases/singlezone_commercial_hydronic/models/compile_fmu.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,26 +17,26 @@
1717

1818
def compile_fmu():
1919
'''Compile the fmu.
20-
20+
2121
Returns
2222
-------
2323
fmupath : str
2424
Path to compiled fmu.
25-
25+
2626
'''
27-
27+
2828
# DEFINE MODEL
2929
# ------------
30-
mopath = 'OU44Emulator'
30+
mopath = 'OU44Emulator/package.mo'
3131
modelpath = 'OU44Emulator.Models.Validation.RealOccupancy'
3232
# ------------
33-
33+
3434
# COMPILE FMU
3535
# -----------
3636
fmupath = parser.export_fmu(modelpath, [mopath], tool = sys.argv[1], algorithm='Cvode', tolerance=1e-6)
3737
# -----------
3838

3939
return fmupath
40-
40+
4141
if __name__ == "__main__":
4242
fmupath = compile_fmu()

testcases/testcase1/models/compile_fmu.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def compile_fmu():
2727

2828
# DEFINE MODEL
2929
# ------------
30-
mopath = 'SimpleRC.mo';
30+
mopath = 'SimpleRC.mo'
3131
modelpath = 'SimpleRC'
3232
# ------------
3333

testcases/testcase2/models/compile_fmu.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"""
1414

1515
from parsing import parser
16-
import sys
16+
import sys
1717

1818
def compile_fmu():
1919
'''Compile the fmu.
@@ -27,7 +27,7 @@ def compile_fmu():
2727

2828
# DEFINE MODEL
2929
# ------------
30-
mopath = 'SingleZoneVAV.mo';
30+
mopath = 'SingleZoneVAV.mo'
3131
modelpath = 'SingleZoneVAV.TestCaseSupervisory'
3232
# ------------
3333

testcases/testcase3/models/compile_fmu.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# -*- coding: utf-8 -*-
22
"""
33
This module compiles the defined test case model into an FMU using the
4-
BOPTEST parser.
4+
BOPTEST parser.
55
66
The tool cli argument is the FMU compilation tool. "OCT" or "dymola" or "openmodelica" supported.
77
i.e. python compile_fmu openmodelica
@@ -13,7 +13,7 @@
1313
"""
1414

1515
from parsing import parser
16-
import sys
16+
import sys
1717

1818
def compile_fmu():
1919
'''Compile the fmu.
@@ -27,7 +27,7 @@ def compile_fmu():
2727

2828
# DEFINE MODEL
2929
# ------------
30-
mopath = 'TwoZones.mo';
30+
mopath = 'TwoZones.mo'
3131
modelpath = 'TwoZones'
3232
# ------------
3333

0 commit comments

Comments
 (0)