Multi-scenario sweep#
- sweep(base_case, scenarios, *, solver='dc_opf', paths=(), keep_results=False, max_results=1000, seed=None, n_threads=0, portfolio=None, settlement_net=None, points=None, **solver_kwargs)#
Solve a set of scenarios and aggregate their price distributions.
- Parameters:
base_case -- Case to modify for each scenario.
scenarios -- Iterable of
Scenarioobjects to solve.solver --
"dc_opf","dc_scopf","sced", or a compatible callable.paths --
(source_bus, sink_bus)pairs for path-price distributions.keep_results -- Retain individual solver results for inspection.
max_results -- Maximum number of retained successful results. The sweep still solves and aggregates later scenarios.
seed -- Random seed to record with the result.
n_threads -- Worker count. Zero selects the default.
portfolio -- Optional FTR portfolio to value across every result.
settlement_net -- Prepared DC network for FTR revenue-adequacy checks.
points -- Settlement points keyed by customer name for FTR valuation.
solver_kwargs -- Additional arguments for the selected solver.
- Returns:
A
SweepResult.distributioncontains single-period LMP, congestion, branch-use, and requested path statistics.resultsandresult_labelscontain retained successful results.failedcontains(label, reason)pairs. A SCED sweep returns its retained period results and setsdistributiontoNone.
Examples
>>> import gpf >>> case = gpf.load_case("case.raw") >>> scenarios = [ ... gpf.load_scenario(1.10, label="peak"), ... gpf.outage_scenario((101, 205, "1"), label="line outage"), ... ] >>> result = gpf.sweep(case, scenarios, keep_results=True) >>> result.n_scenarios 2
- class Scenario(label, outages=frozenset({}), demand_scale=1.0, scale_kwargs=(), cost_scale=1.0, gen_cost_scale=(), pg0=(), durations=())#
Declare one operating condition for a distribution sweep.
The scenario constructors provide the simplest interface for one type of change. Construct
Scenariodirectly when one condition combines an outage with load, cost, or SCED changes. Direct construction uses immutable tuples because the object is frozen.- label#
Customer name for the condition.
- Type:
str
- outages#
Branches to remove. Each branch uses the case identity
(from_bus, to_bus, circuit_id).- Type:
frozenset
- demand_scale#
Multiplier for the selected in-service load.
- Type:
float
- scale_kwargs#
Load selection and reactive-power options as
((name, value), ...). Convert list values, such as bus or area selections, to tuples. Seeload_scenariofor the option names.- Type:
tuple
- cost_scale#
Positive multiplier for every generator cost curve.
- Type:
float
- gen_cost_scale#
Additional positive cost multipliers as
(((bus, generator_id), multiplier), ...).- Type:
tuple
- pg0#
Initial generator outputs as
(((bus, generator_id), output_mw), ...). This field applies only to a SCED sweep.- Type:
tuple
- durations#
Positive period lengths in hours. This field applies only to a SCED sweep and must match the dispatch horizon.
- Type:
tuple
Examples
Scale all in-service loads to 110 percent of their base values:
>>> import gpf >>> scenario = gpf.load_scenario(1.10, label="summer peak")
Scale loads in area 2 and remove branch 101-205-1 in separate conditions:
>>> area_peak = gpf.load_scenario(1.08, areas=[2]) >>> line_out = gpf.outage_scenario((101, 205, "1"))
Combine the same load and outage changes in one condition:
>>> combined = gpf.Scenario( ... "area 2 peak with line outage", ... outages=frozenset({(101, 205, "1")}), ... demand_scale=1.08, ... scale_kwargs=(("areas", (2,)),), ... )
- property topology_key#
Return the network identity for this scenario.
- property has_cost_overlay#
Return true when this scenario changes generator costs.
- materialize(base_case)#
Apply this scenario to a copy of
base_caseand return it.
- class SweepResult(distribution, n_scenarios, n_networks, results=<factory>, result_labels=<factory>, results_capped=False, failed=<factory>, seed=None, valuation=None)#
Store aggregate and retained results for a scenario sweep.
distributioncontains the requested price statistics.resultsandresult_labelscontain retained successful results when requested.failedidentifies conditions that did not solve. The result also reports coverage, retained-result limits, the random seed, and optional valuation.- to_json()#
Return a JSON-compatible sweep result.
- class Distribution(paths=())#
Aggregate bus prices, branch use, and path spreads without storing cases.
Congestion is
lmp - lmp_energy. It includes the full non-energy price that settles an FTR, including security for a security-constrained result. Bus numbers and branch keys identify all values.- set_ratings(keys, rates)#
Register per-branch ratings (MW) for binding / utilization; a branch with no positive rating is excluded from branch statistics.
- update(result)#
Fold one solved OPF result (DC-OPF or DC-SCOPF) into the distributions.
- summary()#
Native-keyed distributions (bus ints, branch_key / path tuples).
- to_json()#
Return distributions with stringified tuple keys.
This aggregate is not a queryable point-result surface. Point results use
to_jsonfor a header andas_tablesfor their row data.
- class ScenarioSweepError#
A sweep could not be posed: a mis-declared topology, an unknown solver.
- load_scenario(multiplier, *, label=None, **scale_kwargs)#
Create a scenario that scales selected in-service loads.
- Parameters:
multiplier -- Multiplier for the selected active demand. For example,
1.05adds 5 percent and0.90removes 10 percent.label -- Customer name for reports. The function creates a label when this value is omitted.
scale_kwargs -- Optional load selectors and reactive-power settings.
areas,zones,owners, andbusesaccept sequences of case identifiers.bus_typeacceptsNone,"pq", or"pv_slack".interruptibleaccepts"both","non_interruptible", or"interruptible". All supplied selectors must match a load.q_modeaccepts"scale"(default),"preserve","zero","target","percent","pf", or"increment". The last four modes requireq_target_mvar,q_percent,q_target_pf, orq_increment_mvar, respectively.
- Returns:
A scenario for
sweep.
Examples
Scale active and reactive load at buses 101 and 205 by 5 percent:
>>> scenario = gpf.load_scenario(1.05, buses=[101, 205])
Scale active load in area 2 and preserve its reactive load:
>>> scenario = gpf.load_scenario( ... 1.10, areas=[2], q_mode="preserve", label="area 2 peak" ... )
- outage_scenario(keys, *, label=None)#
Create a scenario that removes one or more branches from service.
- Parameters:
keys -- One
(from_bus, to_bus, circuit_id)identity or an iterable of these identities. Bus numbers are integers. The circuit ID is the case value, such as"1".label -- Customer name for reports. The function creates a label when this value is omitted.
- Returns:
A scenario for
sweep.
- cost_scenario(multiplier=1.0, *, gens=None, label=None, demand_scale=1.0, **scale_kwargs)#
Create a scenario that changes generator costs and optional demand.
- Parameters:
multiplier -- Positive factor for all generator cost curves.
gens -- Optional additional positive factors keyed by
(bus, generator_id). A generator receives both the common and its named factor.label -- Customer name for reports. The function creates a label when this value is omitted.
demand_scale -- Multiplier for selected active demand.
scale_kwargs -- Optional load selectors and reactive-power settings accepted by
load_scenario.
- Returns:
A scenario for
sweep.- Raises:
ValueError -- A common or generator-specific cost factor is not positive.
Examples
Increase all costs by 10 percent and apply an additional 20 percent increase to generator 101-1:
>>> scenario = gpf.cost_scenario( ... 1.10, gens={(101, "1"): 1.20}, label="high fuel cost" ... )
- pg0_scenario(pg0, *, label=None, demand_scale=1.0, **scale_kwargs)#
Create an initial-dispatch condition for a SCED scenario.
- Parameters:
pg0 -- Initial MW values keyed by
(bus, generator_id).label -- Customer name for reports. The function creates a label when this value is omitted.
demand_scale -- Multiplier for selected active demand.
scale_kwargs -- Optional load selectors and reactive-power settings accepted by
load_scenario.
- Returns:
A scenario for
sweep(..., solver="sced").- Raises:
ValueError --
pg0is empty.
Examples
Set the initial output of generator 101-1 to 250 MW:
>>> scenario = gpf.pg0_scenario({(101, "1"): 250.0})
- duration_scenario(durations, *, label=None, demand_scale=1.0, **scale_kwargs)#
Create a period-duration condition for a SCED scenario.
- Parameters:
durations -- Positive period lengths in hours. The number of values must match the dispatch horizon.
label -- Customer name for reports. The function creates a label when this value is omitted.
demand_scale -- Multiplier for selected active demand.
scale_kwargs -- Optional load selectors and reactive-power settings accepted by
load_scenario.
- Returns:
A scenario for
sweep(..., solver="sced").- Raises:
ValueError --
durationsis empty or contains a nonpositive value.
Examples
Use one 30-minute period followed by two one-hour periods:
>>> scenario = gpf.duration_scenario([0.5, 1.0, 1.0])
- monte_carlo_load_scenarios(n, *, seed, sigma=0.1, mean=1.0, label_prefix='mc', **scale_kwargs)#
Create reproducible load scenarios from a normal distribution.
The function clips each sampled multiplier to a minimum of
0.01.- Parameters:
n -- Number of scenarios to create.
seed -- Random seed. The same inputs and seed produce the same scenarios.
sigma -- Standard deviation of the load multiplier.
mean -- Mean load multiplier.
label_prefix -- Prefix for each generated scenario label.
scale_kwargs -- Optional selectors and reactive-power settings accepted by
load_scenario.
- Returns:
A list of
nload scenarios.
Examples
Create 100 load scenarios for area 2 with a 10 percent standard deviation:
>>> scenarios = gpf.monte_carlo_load_scenarios( ... 100, seed=7, sigma=0.10, areas=[2] ... )