Add G-1 security-constrained reserve formulations with monitored componets#1617
Add G-1 security-constrained reserve formulations with monitored componets#1617SebastianManriqueM wants to merge 16 commits into
Conversation
There was a problem hiding this comment.
@jd-lara This is still work in progress, but I think I'm going to be stuck a few days in other task
|
Performance Results
|
4328d40 to
1bd7885
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds new security-constrained (G-1) reserve formulations that build post-contingency reserve-deployment variables and monitored-component post-contingency flow constraints using outage supplemental attributes, and introduces a comprehensive new test suite for these models.
Changes:
- Introduces
SecurityConstrainedContingencyReserve/SecurityConstrainedRampReserveformulations plus supporting variables, expressions, constraints, and slack-cost handling. - Adds a
ServiceModel.outagesfield and template-validation logic to populate per-service monitored-component outage maps. - Adds
test_static_injection_security_constrained_models.jlcovering multiple network models, requirement/no-requirement variants, slack on/off, and monitored-component scoping.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
test/test_static_injection_security_constrained_models.jl |
New end-to-end tests for SC reserve formulations across multiple network models and configuration variants. |
src/services_models/static_injection_security_constrained_models.jl |
Core implementation of sparse monitored-component SC reserve expressions/constraints (PTDF + AreaBalance paths) and post-contingency deployment logic. |
src/services_models/reserves.jl |
Ensures SC reserve formulations default to using the requirement time series name. |
src/PowerSimulations.jl |
Exports new formulations/types and includes the new SC reserve service-model implementation file. |
src/operation/template_validation.jl |
Populates ServiceModel.outages during template validation; expands monitored-component admissibility to include AreaInterchange. |
src/devices_models/devices/ac_transmission_security_constrained_models.jl |
Skips monitored-component types absent from PTDF arc maps to avoid resolution errors. |
src/core/variables.jl |
Adds slack-variable type hierarchy for post-contingency flow inequality slacks. |
src/core/service_model.jl |
Adds outages field + constructor kwarg handling and accessor for ServiceModel. |
src/core/formulations.jl |
Adds new SC reserve formulation types. |
src/core/expressions.jl |
Adds new post-contingency expression types and result-writing flags. |
src/core/definitions.jl |
Adds POST_CONTINGENCY_CONSTRAINT_VIOLATION_SLACK_COST. |
src/core/constraints.jl |
Adds new post-contingency constraint types used by the SC formulations. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@ChenHaotianC If you can add a summary of your validations so far here, I think it would be valuable and maybe also let your review/suggestions |
…Reserve formulations
…tored-component pattern Implements SecurityConstrainedContingencyReserve and SecurityConstrainedRampReserve service formulations using the sparse + monitored-component pattern from ac_transmission_security_constrained_models.jl. Covers PTDF, CopperPlate, and AreaBalance network paths with optional post-contingency slacks. Adds supporting core types: AbstractContingencySlackVariableType with PostContingencyFlowActivePowerSlackUpperBound/LowerBound variables, PostContingencyAreaActivePowerDeployment expression, PostContingencyActivePowerGenerationLimitsConstraint and PostContingencyCopperPlateBalanceConstraint constraints, and POST_CONTINGENCY_CONSTRAINT_VIOLATION_SLACK_COST. PTDF only (no MODF); sparse containers keyed by (outage_id, monitored_name, t) scoped via service_model.outages.
…ment, MOI rebaseline - Replace global outage discovery with service-scoped _service_outages(sys, service_model) helper across all 16 attachment sites in static_injection_security_constrained_models.jl; thread sys/service_model through signatures. - Add get_default_time_series_names(::Reserve, ::AbstractSecurityConstrainedReservesFormulation) so the SC reserve formulations pick up the requirement time series like the legacy formulations. - Enable RampConstraint for SecurityConstrainedContingencyReserve (matches the older behavior when requirement_ts is present). - AreaPTDFPowerModel: switch nodal_deployment slicing to positional .data access to match ptdf column positional indices on the area-reduced bus axis. - Tests: normalize meta strings (Reserve1 -lb -> Reserve1_lb etc), attach the UnplannedOutage supplemental attribute to both the contributing component and the reserve service, replace size() on SparseAxisArray with length-based check, and rebaseline MOI count expectations for the new sparse post-contingency containers.
Introduces a new PostContingencyExpressions subtype representing the post-contingency flow on an AreaInterchange, with result-writing and natural-units conversion overloads. Exported from the package alongside PostContingencyBranchFlow.
Extends _monitored_components_by_modeled_type to accept PSY.AreaInterchange in addition to PSY.ACTransmission so AreaBalance-based security-constrained service models can monitor area-tie flows. Adds a haskey guard in the AC transmission resolver so it safely skips AreaInterchange entries that now appear in the shared per-type outage dict.
…der AreaBalancePowerModel
Mirrors the AreaPTDFPowerModel monitored-line handling for AreaInterchange components: adds an add_post_contingency_flow_expressions! dispatch on NetworkModel{<:AreaBalancePowerModel} that builds the PostContingencyAreaInterchangeFlow expression as the baseline FlowActivePowerVariable plus the signed sum of PostContingencyActivePowerReserveDeploymentVariable across the from/to areas minus the outaged generation contribution on the outaged side; adds the matching add_constraints! dispatch enforcing -from_to <= flow <= to_from with optional slack support; wires both into _construct_service_model_areabalance!.
…testsets Adds AreaInterchange to monitored_components in the three AreaBalance G-n testsets, adds PostContingencyFlowRateConstraint keys for Reserve1_1/Reserve1_2 (lb/ub) to each constraint_keys list, and rebaselines moi_tests less-than/greater-than counts to reflect the new flow-rate constraints.
Adds two new testsets to test_static_injection_security_constrained_models.jl that exercise the per-service line-scoping path in _monitored_components_by_modeled_type and the downstream PostContingencyFlowRateConstraint build when the outage monitored_components is a hand-picked subset of the system's AC lines instead of every line. - PTDFPowerModel: c_sys5_uc with SecurityConstrainedRampReserve monitoring lines 1 and 2 only. - AreaPTDFPowerModel: two_area_pjm_DA with two SecurityConstrainedRampReserve services, each monitoring two intra-area lines. MOI counts are lower than the all-lines baselines, as expected; objective values are unchanged.
Fix _assign_outage_to_sc_service_models! so coverage is only marked when an outage is actually assigned to at least one ServiceModel, and restrict auto-discovery to outages whose attached injectors overlap the service's contributing devices. Add regression tests covering both the two-reserve scoping case and the single-reserve coverage case, and rebaseline moi/objective counts and the interarea flow tolerance impacted by the removal of spurious cross-service contingency constraints.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
_service_outages built a typed Vector{PSY.UnplannedOutage}, which would throw a MethodError if a PSY.PlannedOutage UUID landed in service_model.outages via the 'include_planned_outages' opt-in supported by _assign_outage_to_sc_service_models! in template_validation.jl. Widen the return eltype to the PSY.Outage supertype. Downstream call sites filter the attribute_device_map via PSY.get_component_supplemental_attribute_pairs(..., UnplannedOutage, sys), so planned-outage UUIDs in the resolved set are silently skipped via the existing 'outage in associated_outages' membership check rather than crashing the build.
ea8671b to
9e63e0e
Compare
Summary
Adds first-class support for G-1 security-constrained reserve formulations driven by
PSY.Outagesupplemental attributes attached to both contributing components (generators / branches) and to the reserve services that respond to those outages. Brings up thestatic_injection_security_constrained_models.jlconstructor path with a sparse monitored-component pattern and a full test suite.Motivation
The legacy SC reserve implementation built post-contingency containers densely over every (outage × branch × time) cell regardless of the user's intent. With per-component / per-service
UnplannedOutagesupplemental attributes, we can scope post-contingency variables, expressions, and constraints to the actual contingencies a service is expected to cover. This refactor makes that scoping mandatory and the data model the single source of truth.Highlights
SecurityConstrainedContingencyReserveandSecurityConstrainedRampReserveunderAbstractSecurityConstrainedReservesFormulation.ServiceModel.outagesfield (Dict{UUID, Dict{DataType, Set{String}}}) lets users either auto-discover all SC outages or explicitly pin a subset by UUID._build_service_model_outages!validator wiresPSY.get_supplemental_attributes(PSY.Outage, sys)into the service-model outage map at template-validation time, gated byany(t -> t <: PSY.StaticInjection, attached_types)._service_outages(sys, service_model)resolves UUIDs toPSY.UnplannedOutageobjects; threaded through all 16 construction call sites. Each SC service now sees only its own outage set rather than the global system list.(outage_id::String, monitored_name::String, t::Int)with meta strings of the form"<service_name>_<lb|ub>".add_post_contingency_flow_expressions!now usesnodal_deployment[outage_id, :, :].datato align with PTDF column positional indices on the area-reduced bus axis (resolvedKeyError: key 6 not foundforAreaPTDFPowerModel).SecurityConstrainedContingencyReservewhenever the requirement time series is present, matching prior behavior.get_default_time_series_names(::Reserve, ::AbstractSecurityConstrainedReservesFormulation)so the SC formulations pick up therequirementtime series like the legacy formulations.Test Suite
test/test_static_injection_security_constrained_models.jlexercises:SecurityConstrainedRampReserveandSecurityConstrainedContingencyReservewithCopperPlatePowerModel,AreaBalancePowerModel,AreaPTDFPowerModel, andDCPPowerModel-based PTDF.AreaPTDFPowerModel.StaticBranch,StaticBranchUnbounded,StaticBranchBounds).compare_outage_power_and_deployed_reservescross-checks that the solved deployment of each outage equals the lost generation from the outaged component.UnplannedOutagesupplemental attribute to both the contributing component and the reserve service that should respond to it; only those services with the attribute will deploy.Current status on this branch: 1080 / 1080 tests passing in
test_static_injection_security_constrained_models.Notable Decisions
"<service_name>_<bound>"(underscore-delimited) instead of the legacy"<service_name> -<bound>"format.size(::DenseAxisArray)were rewritten to uselength/ key checks.AreaPTDFPowerModeluses positional.dataaccess; PTDF column indexing is positional on the reduced-area axis, while the deployment container is keyed by bus number.Validation