Skip to content

Commit 14aa764

Browse files
committed
Merge remote-tracking branch 'rael/wecc' into improv_hydro
2 parents a0d67c4 + cbb6276 commit 14aa764

File tree

6 files changed

+40
-42
lines changed

6 files changed

+40
-42
lines changed

switch_model/solve.py

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ def define_arguments(argparser):
529529
# whether that does the same thing as --solver-options-string so we don't reuse the same name.
530530
argparser.add_argument(
531531
"--solver-options-string",
532-
default=None,
532+
default="",
533533
help="A quoted string of options to pass to the model solver. Each option must be of the form option=value. "
534534
"(e.g., --solver-options-string \"mipgap=0.001 primalopt='' advance=2 threads=1\")",
535535
)
@@ -717,6 +717,14 @@ def define_arguments(argparser):
717717
" that all variables must be the same between the previous and current scenario.",
718718
)
719719

720+
argparser.add_argument(
721+
"--gurobi-make-mps",
722+
default=False,
723+
action="store_true",
724+
help="Instead of solving just output a Gurobi .mps file that can be used for debugging numerical properties."
725+
" See https://github.com/staadecker/lp-analyzer/ for details.",
726+
)
727+
720728

721729
def add_recommended_args(argparser):
722730
"""
@@ -900,27 +908,25 @@ def solve(model):
900908
# Note previously solver was saved in model however this is very memory inefficient.
901909
solver = SolverFactory(model.options.solver, solver_io=model.options.solver_io)
902910

903-
# If this option is enabled, gurobi will output an IIS to outputs\iis.ilp.
904-
if model.options.gurobi_find_iis:
905-
# Enable symbolic labels since otherwise we can't debug the .ilp file.
906-
model.options.symbolic_solver_labels = True
911+
if model.options.gurobi_find_iis and model.options.gurobi_make_mps:
912+
raise Exception("Can't use --gurobi-find-iis with --gurobi-make-mps.")
907913

908-
# If no string is passed make the string empty so we can add to it
909-
if model.options.solver_options_string is None:
910-
model.options.solver_options_string = ""
914+
if model.options.gurobi_find_iis or model.options.gurobi_make_mps:
915+
# If we are outputting a file we want to enable symbolic labels to help debugging
916+
model.options.symbolic_solver_labels = True
911917

918+
# If this option is enabled, gurobi will output an IIS to outputs\iis.ilp.
919+
if model.options.gurobi_find_iis:
912920
# Add to the solver options 'ResultFile=iis.ilp'
913921
# https://stackoverflow.com/a/51994135/5864903
914-
iis_file_path = os.path.join(model.options.outputs_dir, "iis.ilp")
915-
model.options.solver_options_string += " ResultFile={}".format(
916-
iis_file_path
922+
model.options.solver_options_string += " ResultFile=iis.ilp"
923+
if model.options.gurobi_make_mps:
924+
# Output the input file and set time limit to zero to ensure it doesn't actually solve
925+
model.options.solver_options_string += (
926+
f" ResultFile=problem.mps TimeLimit=0"
917927
)
918928

919929
if model.options.threads:
920-
# If no string is passed make the string empty so we can add to it
921-
if model.options.solver_options_string is None:
922-
model.options.solver_options_string = ""
923-
924930
model.options.solver_options_string += f" Threads={model.options.threads}"
925931

926932
if model.options.solver_method is not None:

switch_model/tools/graph/main.py

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,33 +21,18 @@
2121
import plotnine
2222

2323
# Local imports
24-
from switch_model.utilities import StepTimer, get_module_list, query_yes_no
24+
from switch_model.utilities import (
25+
StepTimer,
26+
get_module_list,
27+
query_yes_no,
28+
catch_exceptions,
29+
)
2530

2631
# When True exceptions that are thrown while graphing will be caught
2732
# and outputted to console as a warning instead of an error
2833
CATCH_EXCEPTIONS = True
2934

3035

31-
def catch_exceptions(func):
32-
"""
33-
Decorator that wraps a function such that exceptions are caught and outputted as warnings instead.
34-
"""
35-
36-
@functools.wraps(func)
37-
def wrapper(*args, **kwargs):
38-
if not CATCH_EXCEPTIONS:
39-
return func(*args, **kwargs)
40-
try:
41-
return func(*args, **kwargs)
42-
except:
43-
warnings.warn(
44-
f"The following error was caught and we are moving on."
45-
f"{traceback.format_exc()}"
46-
)
47-
48-
return wrapper
49-
50-
5136
# List of graphing functions. Every time a function uses the @graph() decorator,
5237
# the function gets registered here.
5338
registered_graphs = {}
@@ -77,7 +62,9 @@ def graph(
7762

7863
def decorator(func):
7964
@functools.wraps(func)
80-
@catch_exceptions
65+
@catch_exceptions(
66+
"Failed to run a graphing function.", should_catch=CATCH_EXCEPTIONS
67+
)
8168
def wrapper(tools: GraphTools):
8269
if tools.skip_long and is_long:
8370
return

switch_model/utilities/__init__.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,9 @@ def query_yes_no(question, default="yes"):
801801
sys.stdout.write("Please respond with 'yes' or 'no' " "(or 'y' or 'n').\n")
802802

803803

804-
def catch_exceptions(warning_msg=None, should_catch=True):
804+
def catch_exceptions(
805+
warning_msg="An exception was caught and ignored.", should_catch=True
806+
):
805807
"""Decorator that catches exceptions."""
806808

807809
def decorator(func):
@@ -813,8 +815,9 @@ def wrapper(*args, **kwargs):
813815
try:
814816
return func(*args, **kwargs)
815817
except:
816-
if warning_msg is not None:
817-
warnings.warn(warning_msg)
818+
warnings.warn(
819+
warning_msg + "\nDetailed error log: " + traceback.format_exc()
820+
)
818821

819822
return wrapper
820823

switch_model/utilities/gurobi_aug.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from pyomo.solvers.plugins.solvers.gurobi_direct import GurobiDirect
2323
from pyomo.environ import *
2424

25-
from switch_model.utilities import StepTimer
25+
from switch_model.utilities import StepTimer, catch_exceptions
2626

2727

2828
class PicklableData:
@@ -222,6 +222,7 @@ def _postsolve(self):
222222
print(f"Created warm start pickle file in {timer.step_time_as_str()}")
223223
return results
224224

225+
@catch_exceptions(warning_msg="Failed to save warm start information.")
225226
def _save_warm_start(self, save_c_v_basis):
226227
"""Create a pickle file containing the CBasis/VBasis information."""
227228
# Setup our data objects

switch_model/wecc/get_inputs/get_inputs.py

100755100644
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ def write_csv(data: Iterable[List], fname, headers: List[str], log=True):
6868
"switch_model.transmission.transport.build",
6969
"switch_model.transmission.transport.dispatch",
7070
"switch_model.policies.carbon_policies",
71-
"switch_model.policies.rps_unbundled",
7271
"switch_model.policies.min_per_tech", # Always include since it provides useful outputs even when unused
7372
# "switch_model.reporting.basic_exports_wecc",
7473
# Always include since by default it does nothing except output useful data
@@ -747,6 +746,7 @@ def query_db(full_config, skip_cf):
747746
order by 1, 2;
748747
"""
749748
)
749+
modules.append("switch_model.policies.rps_unbundled")
750750

751751
########################################################
752752
# BIO_SOLID SUPPLY CURVE

switch_model/wecc/get_inputs/post_process_steps/add_storage.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ def main(config):
123123

124124
# Get the plant costs from GSheets and append to costs
125125
storage_costs = fetch_df("costs", "costs_scenario", config)
126+
storage_costs = storage_costs[storage_costs["GENERATION_PROJECT"].isin(gen_projects["GENERATION_PROJECT"])]
126127
add_to_csv("gen_build_costs.csv", storage_costs, primary_key=["GENERATION_PROJECT", "build_year"])
127128

128129
# Create add_storage_info.csv

0 commit comments

Comments
 (0)