Skip to content

Add G-1 security-constrained reserve formulations with monitored componets#1617

Open
SebastianManriqueM wants to merge 16 commits into
mainfrom
sm/g-1_monitored_c
Open

Add G-1 security-constrained reserve formulations with monitored componets#1617
SebastianManriqueM wants to merge 16 commits into
mainfrom
sm/g-1_monitored_c

Conversation

@SebastianManriqueM

@SebastianManriqueM SebastianManriqueM commented May 26, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds first-class support for G-1 security-constrained reserve formulations driven by PSY.Outage supplemental attributes attached to both contributing components (generators / branches) and to the reserve services that respond to those outages. Brings up the static_injection_security_constrained_models.jl constructor 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 UnplannedOutage supplemental 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

  • New formulations: SecurityConstrainedContingencyReserve and SecurityConstrainedRampReserve under AbstractSecurityConstrainedReservesFormulation.
  • ServiceModel.outages field (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 wires PSY.get_supplemental_attributes(PSY.Outage, sys) into the service-model outage map at template-validation time, gated by any(t -> t <: PSY.StaticInjection, attached_types).
  • Service-side outage threading: _service_outages(sys, service_model) resolves UUIDs to PSY.UnplannedOutage objects; threaded through all 16 construction call sites. Each SC service now sees only its own outage set rather than the global system list.
  • Sparse post-contingency containers keyed by (outage_id::String, monitored_name::String, t::Int) with meta strings of the form "<service_name>_<lb|ub>".
  • AreaPTDF positional fix: add_post_contingency_flow_expressions! now uses nodal_deployment[outage_id, :, :].data to align with PTDF column positional indices on the area-reduced bus axis (resolved KeyError: key 6 not found for AreaPTDFPowerModel).
  • RampConstraint is added for SecurityConstrainedContingencyReserve whenever the requirement time series is present, matching prior behavior.
  • get_default_time_series_names(::Reserve, ::AbstractSecurityConstrainedReservesFormulation) so the SC formulations pick up the requirement time series like the legacy formulations.

Test Suite

test/test_static_injection_security_constrained_models.jl exercises:

  • SecurityConstrainedRampReserve and SecurityConstrainedContingencyReserve with CopperPlatePowerModel, AreaBalancePowerModel, AreaPTDFPowerModel, and DCPPowerModel-based PTDF.
  • Reserve / contingency variants with and without a reserve requirement time series.
  • Reserve-slack on/off variants under AreaPTDFPowerModel.
  • Parallel-circuit reduction interactions for both Ramp and Contingency formulations.
  • Mixed branch formulations (StaticBranch, StaticBranchUnbounded, StaticBranchBounds).
  • A test helper compare_outage_power_and_deployed_reserves cross-checks that the solved deployment of each outage equals the lost generation from the outaged component.
  • Test pattern requires attaching the UnplannedOutage supplemental 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

  • Outages are looked up via the supplemental-attribute graph in PowerSystems rather than per-formulation kwargs, keeping a single source of truth.
  • Post-contingency constraint meta strings use "<service_name>_<bound>" (underscore-delimited) instead of the legacy "<service_name> -<bound>" format.
  • Containers are sparse-only; tests that previously asserted size(::DenseAxisArray) were rewritten to use length / key checks.
  • AreaPTDFPowerModel uses positional .data access; PTDF column indexing is positional on the reduced-area axis, while the deployment container is keyed by bus number.

Validation

julia --project=test test/runtests.jl test_static_injection_security_constrained_models
# Pass: 1080  Total: 1080

@SebastianManriqueM SebastianManriqueM changed the title Add G-1 security-constrained reserve formulations with per-service outage scoping Add G-1 security-constrained reserve formulations with monitored componets May 26, 2026

@SebastianManriqueM SebastianManriqueM left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jd-lara This is still work in progress, but I think I'm going to be stuck a few days in other task

@github-actions

github-actions Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

Performance Results

Version Precompile Time
Main 3.782367878
This Branch 3.828924367
Version Build Time
Main-Build Time Precompile 129.355721979
Main-Build Time Postcompile 1.761029582
This Branch-Build Time Precompile 128.243333599
This Branch-Build Time Postcompile 1.499886722
Version Build Time
Main-Solve Time Precompile 931.442416813
Main-Solve Time Postcompile 890.17256602
This Branch-Solve Time Precompile 438.438148145
This Branch-Solve Time Postcompile 390.726281567

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 / SecurityConstrainedRampReserve formulations plus supporting variables, expressions, constraints, and slack-cost handling.
  • Adds a ServiceModel.outages field and template-validation logic to populate per-service monitored-component outage maps.
  • Adds test_static_injection_security_constrained_models.jl covering 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.

Comment thread src/core/service_model.jl Outdated
Comment thread src/operation/template_validation.jl
Comment thread src/operation/template_validation.jl
Comment thread src/services_models/static_injection_security_constrained_models.jl
@SebastianManriqueM SebastianManriqueM marked this pull request as ready for review May 27, 2026 21:45
@SebastianManriqueM

SebastianManriqueM commented Jun 4, 2026

Copy link
Copy Markdown
Contributor Author

@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

SebastianManriqueM and others added 16 commits June 16, 2026 15:47
…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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants