Conversation
| print(f"\n[Warning] Case Column: '{c}'") | ||
| print( | ||
| "You are attempting to run a Monte Carlo simulation with " | ||
| "You are attempting to run a Monte Carlo or MGA Random Vector simulation with " |
There was a problem hiding this comment.
This probably doesn't matter since the MGA runs should all have the same inputs, but I left it in for now in case there's a non-deterministic component to the representative day sampling.
There was a problem hiding this comment.
If the inputs are unchanged then the rep days will be unchanged, so I'm pretty sure we can remove the check for RV and only keep it for MCS, which makes it a little easier to use.
patrickbrown4
left a comment
There was a problem hiding this comment.
Looks great! The only critical comment is in d_mga.gms; all the rest are minor cleanups. Approving now but should still confirm zero change before merging.
| inflation.csv,inputs/financials/inflation_{inflation_suffix}.csv,1,ignore,ignore,,,,0,0,,,,,, | ||
| interconnection_queues.csv,inputs/capacity_exogenous/interconnection_queues.csv,1,ignore,ignore,r,"tg,r",,1,0,,,,,, | ||
| jtype.csv,inputs/sets/jtype.csv,1,ignore,ignore,,,,,,,,set,jtype,job types used in model (construction and om), | ||
| jtype.csv,inputs/sets/jtype.csv,1,ignore,ignore,,,,,0,,,set,jtype,job types used in model (construction and om), |
There was a problem hiding this comment.
jtype.csv doesn't have a header so I think the changes to this file should be reverted
| print(f"\n[Warning] Case Column: '{c}'") | ||
| print( | ||
| "You are attempting to run a Monte Carlo simulation with " | ||
| "You are attempting to run a Monte Carlo or MGA Random Vector simulation with " |
There was a problem hiding this comment.
If the inputs are unchanged then the rep days will be unchanged, so I'm pretty sure we can remove the check for RV and only keep it for MCS, which makes it a little easier to use.
| if int(dfcases[c].MCS_runs) > 0: | ||
| mcs_sampler.general_mcs_dist_validation(reeds.io.reeds_path, mcs_dist_path, sw) | ||
| numruns = int(dfcases[c].MCS_runs) | ||
| run_type = 'MC' | ||
| else: | ||
| numruns = int(dfcases[c].GSw_MGA_RV_runs) | ||
| run_type = 'R' |
There was a problem hiding this comment.
MCS and RV are mutually incompatible, right (at least in the current implementation, which is totally ok)? If so, should probably add a check to runreeds.check_compatibility() that raises an exception if MCS_runs and GSw_MGA_RV_runs are both nonzero.
| import pandas as pd | ||
| import scipy.stats | ||
| import sys | ||
| import re |
There was a problem hiding this comment.
(minor cleanup) can remove since unused
| import re |
|
|
||
| # %% |
There was a problem hiding this comment.
| # %% |
|
|
||
| By default the MGA min/max is applied to the sum of the variable across all regions being modeled. | ||
| The MGA approach also supports an option to randomly sample of a vector of weights to apply to the regional values of the variable being optimized. | ||
| This method can be useful to characterizing the uncertainty in the regional distribution of the results. |
There was a problem hiding this comment.
| This method can be useful to characterizing the uncertainty in the regional distribution of the results. | |
| This method can be used to characterize the uncertainty in the regional distribution of the results. |
| By default the MGA min/max is applied to the sum of the variable across all regions being modeled. | ||
| The MGA approach also supports an option to randomly sample of a vector of weights to apply to the regional values of the variable being optimized. | ||
| This method can be useful to characterizing the uncertainty in the regional distribution of the results. | ||
| Weights are sampled as discrete values from a support of {-1,1} to allow for simultaneous minimization and maximization. |
There was a problem hiding this comment.
Just to check, is "support" the right word here? (I'm unfamiliar with this usage but also don't know much stats)
|
|
||
| The MGA random vector capability is controlled by the following switches: | ||
| - `GSw_MGA_RV_runs` (default `0`): Number of random samples of weight vectors to draw; corresponds to the number of runs. | ||
| - `GSw_MGA_RV_region` (default `r`): Regionality level (specified by hierarhcy file) over which to sample the random weights. |
There was a problem hiding this comment.
| - `GSw_MGA_RV_region` (default `r`): Regionality level (specified by hierarhcy file) over which to sample the random weights. | |
| - `GSw_MGA_RV_region` (default `r`): Regionality level (specified by hierarchy file) over which to sample the random weights. |
| *TODO: add different handling for other subobjectives with different dimensions | ||
| * should we also include error checking? | ||
|
|
||
|
|
There was a problem hiding this comment.
Best to move to issue if you still want to address it (or just remove if it's old)
| *TODO: add different handling for other subobjectives with different dimensions | |
| * should we also include error checking? |
| * --------------------------------------------------------------------------- | ||
|
|
||
| $elseif.mgaobj %GSw_MGA_Objective% == 'generation' | ||
| Equation eq_MGA_Objective "--MW-- Defines generation for MGA" ; | ||
| Variable MGA_OBJ "--MWh-- Generation of technology to be minimized/maximied" ; | ||
| eq_MGA_Objective$Sw_MGA.. | ||
| MGA_OBJ | ||
| =e= | ||
| sum{(i,v,r,h,t) | ||
| $[tmodel(t) | ||
| $valgen(i,v,r,t) | ||
| $%GSw_MGA_SubObjective%(i)], | ||
| GEN(i,v,r,h,t) * hours(h) | ||
| * sum{i_subtech$i_subsets(i,i_subtech), mga_weights(r,i_subtech)} |
There was a problem hiding this comment.
Duplicates the next block below; can instead just add * sum{i_subtech$i_subsets(i,i_subtech), mga_weights(r,i_subtech)} to the existing $elseif.mgaobj %GSw_MGA_Objective% == 'generation' block
Summary
This PR adds a new capability to the existing MGA method to support random vector sampling across subcategories of the variables being explored.
Technical details
The current MGA method applies the minimization (or maximization) to the sum of a variable across all modeled regions (e.g., total U.S. solar capacity or fossil generation). The random vector method assigns randomly-sampled weights to the regional quantities applied before the summation. This technique allows for exploring the regional distribution of capacity and generation results in the near-optimal space.
As an illustration, the plot below shows the range of natural gas capacity by region (using the 54-zones) from 100 runs with the MGA random vector method with a 1% cost threshold. The MGA max/min squares indicate the results from the previous, nationwide-method; the original min/max approach is better suited for getting a wider range of total capacity, whereas the new method is better geared toward understanding uncertainty at a regional level.
Implementation notes
main_mga_rvfunction inmcs_sampler.py, with the number of samples (runs) controlled byGSw_MGA_RV_runs.mcs_sampler.pycan support linear sampling from [-1,1] using a uniform distribution. Initial tests suggested this didn't yield as much of a signal so we haven't implemented a switch to control this.GSw_MGA_RV_regionand can be any level in the hierarchy file.GSw_MGA_Objective = (capacity or generation), with weights generated by region and technology group (i_subtech).GSw_MGA_SubObjectiveis an aggregated tech category (e.g.,gentech), unique weights will be sampled for the differenti_subtechgroups within the larger category.b_inputs.gmsand applied to the MGA objective function ind_mga.gms.Additional changes
Added a run using the random vector method to
cases_test.csv.Switches added/removed/changed
GSw_MGA_RV_runs: number of random weight vectors to draw; corresponds to the number of ReEDS runs.Relevant sources or documentation
The random vector method has been used in previous MGA studies (examples here and here
Validation, testing, and comparison report(s)
Will run reference case tests once the HPC is back in service. Will also link a slide deck with some results using this method.
Checklist for author
Details to double-check
d_objective.gms, they are included inobjective_function_params.yamlfor completeness checkinghourlize/resource.pywas rerun to regenerate the existing/prescribed VRE capacity dataGeneral information to guide review
Did you use LLM tools (chatbot or copilot) in the preparation of this PR? If so, describe how
Tag points of contact here if you would like additional review of the relevant parts of the model