-
Notifications
You must be signed in to change notification settings - Fork 2
/
ssolve.py
executable file
·146 lines (127 loc) · 5.3 KB
/
ssolve.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#!/usr/bin/env python3
"""solve.py: Single model template solver for openCEM"""
__version__ = "0.9.2"
__author__ = "José Zapata"
__copyright__ = "Copyright 2018, ITP Renewables, Australia"
__credits__ = ["José Zapata", "Dylan McConnell", "Navid Hagdadi"]
__license__ = "GPLv3"
__maintainer__ = "José Zapata"
__email__ = "[email protected]"
__status__ = "Development"
import argparse
import datetime
import pickle
import sys
import time
from pyomo.opt import SolverFactory, TerminationCondition
import cemo.utils
from cemo.model import create_model
def check_arg(config_file, parameter):
'''Parse .dat file for parameters that enable constraints'''
with open(config_file + '.dat', 'r') as file:
for line in file:
if parameter in line:
return True
return False
# start the clock on the run
START_TIME = time.time()
# create parser object
PARSER = argparse.ArgumentParser(description="openCEM single model solver")
# Single simulation option using a data command file
PARSER.add_argument("name",
help="Specify name of data command file.\n"
+ " Do not include data command file extension `.dat`",
type=str,
metavar='NAME')
# Obtain a solver name from command line, default cbc
PARSER.add_argument("--solver",
help="Specify solver used by model."
+ " For Pyomo supported solvers installed in your system ",
type=str,
metavar='SOLVER',
default="cbc")
# Produce only a printout of the instance and exist
PARSER.add_argument("--printonly",
help="Produce model.STR.pprint() output and exit."
+ " STR=all produces entire model output. Debugging only",
type=str,
metavar='STR')
# Produce a text output of model in Yaml
PARSER.add_argument("--yaml",
help="Produce YAML output for the model named NAME.yaml",
action="store_true")
# Produce pickle output of instance
PARSER.add_argument("--pickle",
help="Produce Pickle of instantiated model object NAME.p",
action="store_true")
# Produce a plot
PARSER.add_argument("-p", "--plot",
help="Produce a simple plot of model results",
action="store_true")
PARSER.add_argument("-u", "--unserved",
help="Enforce USE hard constraints",
action="store_true")
PARSER.add_argument("-r", "--results",
help="Print an abridged model result",
action="store_true")
# Include additional output
PARSER.add_argument("-v", "--verbose",
help="Print additional output, e.g. solver output",
action="store_true")
# parse arguments into args structure
ARGS = PARSER.parse_args()
# Model name comes from command line
MODEL_NAME = ARGS.name
# create cemo model
MODEL = create_model(MODEL_NAME,
unslim=ARGS.unserved,
emitlimit=check_arg(MODEL_NAME, 'nem_year_emit_limit'),
nem_disp_ratio=check_arg(MODEL_NAME, 'nem_disp_ratio'),
nem_ret_ratio=check_arg(MODEL_NAME, 'nem_ret_ratio'),
nem_ret_gwh=check_arg(MODEL_NAME, 'nem_ret_gwh'),
region_ret_ratio=check_arg(MODEL_NAME, 'region_ret_ratio'),
nem_re_disp_ratio=check_arg(MODEL_NAME, 'nem_re_disp_ratio'))
# create a specific instance using file modelName.dat
try:
INSTANCE = MODEL.create_instance(MODEL_NAME + '.dat')
except Exception as ex:
print("openCEM solve.py: ", ex)
sys.exit(1) # exit gracefully if file does not exist
# Produce only a debugging printout of model and then exit
if ARGS.printonly:
cemo.utils.printonly(INSTANCE, ARGS.printonly) # print requested keys
sys.exit(0) # exit with no error
# declare a solver for the model instance
OPT = SolverFactory(ARGS.solver)
# Use multiple threads for CBC solver (if available)
# TODO pass solver options via command line interface
if ARGS.solver == "cbc":
OPT.options['threads'] = 4
OPT.options['ratio'] = 0.0001
# instruct the solver to calculate the solution
print("openCEM solve.py: Runtime %s (pre solver)" %
str(datetime.timedelta(seconds=(time.time() - START_TIME)))
)
RESULTS = OPT.solve(INSTANCE, tee=ARGS.verbose, keepfiles=False)
print("openCEM solve.py: Runtime %s (post solver)" %
str(datetime.timedelta(seconds=(time.time() - START_TIME)))
)
print("openCEM solve.py: Solver status %s" % RESULTS.solver.status)
if RESULTS.solver.termination_condition == TerminationCondition.infeasible:
print("openCEM solve.py: Problem infeasible, no solution found.")
sys.exit(1)
# Produce YAML output of model results
if ARGS.yaml:
# rescue actual results from instance
INSTANCE.solutions.store_to(RESULTS)
# result object to write to json or yaml
RESULTS.write(filename=MODEL_NAME + '.yaml', format='yaml')
# Produce pickle output of entire instance object
if ARGS.pickle:
pickle.dump(INSTANCE, open(MODEL_NAME + '.p', 'wb'))
if ARGS.results:
cemo.utils.printstats(INSTANCE)
# Produce local plot of results
if ARGS.plot:
cemo.utils.plotresults(INSTANCE)
cemo.utils.plotcapacity(INSTANCE)