Skip to content

G-1 reserves; use IOM.ComponentPairKey; EnumX changes - #321

Open
acostarelli wants to merge 22 commits into
mainfrom
ac/g1-reserves-total
Open

acostarelli wants to merge 22 commits into
mainfrom
ac/g1-reserves-total

Conversation

@acostarelli

Copy link
Copy Markdown
Member

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.

Copilot review overview

🟡 Changes recommended

Unresolved critical dependency, test, reserve-keying, and G-1 monitoring issues block approval.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 6 High severity · 3 Medium severity

Open (9)
What changed in this PR

Ports G-1 security-constrained reserve modeling, migrates reserve indexing to IOM.ComponentPairKey, and updates related models and tests.

Changes:

  • Adds post-contingency reserve deployment, balance, flow, and slack modeling.
  • Updates reserve construction, aggregation, offers, and device integrations.
  • Updates EnumX handling, dependencies, output persistence, and regression coverage.
File Changes Final review findings
test/​test_static_injection_security_constrained_models.jl Adds G-1 regression coverage. Critical (1): No-requirement test checks an absent container incorrectly.
test/​test_services_constructor.jl Updates reserve-container assertions. —
test/​test_model_decision.jl Adapts reserve output discovery. —
test/​test_device_reserve_offers.jl Reads typed reserve awards. —
test/​Project.toml Updates test dependencies and sources. Critical (3): Contributor-specific absolute path. Critical (3): Removed compatible remote source while PowerFlows tests remain enabled.
test/​includes.jl Changes test imports. Critical (3): PFS import is disabled while dependent tests remain enabled.
src/​static_injector_models/​thermal_generation.jl Updates offline reserve lookup. —
src/​static_injector_models/​hydro_generation.jl Updates reserve variable keys. —
src/​services_models/​services_constructor.jl Constructs security-constrained service models. —
src/​services_models/​security_constrained_injectors.jl Implements G-1 reserve modeling. Critical (1): Modeled branch types are skipped due to an inverted condition. Moderate (2): Validation ignores the per-device filter_function.
src/​services_models/​reserves.jl Migrates reserve aggregation and costs. Critical (1): Participation constraints can collide without device-type keys.
src/​services_models/​reserve_offers.jl Supports device-type offer keys. —
src/​services_models/​reserve_group.jl Aggregates pair-keyed reserve variables. —
src/​PowerOperationsModels.jl Registers and exports G-1 APIs. Moderate (3): Removes the existing HVDCDCControlConstraint export.
src/​operation/​template_validation.jl Reorganizes outage validation. —
src/​operation/​decision_model.jl Changes system output persistence. Moderate (3): Comments out the PSY.to_file persistence call.
src/​hybrid_system_models/​hybrid_systems.jl Updates hybrid reserve keys. —
src/​energy_storage_models/​storage_models.jl Updates storage reserve keys. —
src/​core/​variables.jl Adds G-1 variables. —
src/​core/​formulations.jl Adds security-constrained reserve formulations. Nit (1): Documentation inaccurately describes service attachment validation.
src/​core/​expressions.jl Adds post-contingency expressions. —
src/​core/​constraints.jl Adds G-1 constraints. Nit (1): Exported constraint retains an incomplete docstring.
src/​common_models/​converter_control.jl Updates EnumX type signatures. —
src/​common_models/​add_to_expression.jl Updates reserve expression keys. —
Project.toml Updates package sources and dependencies. Critical (3): Contributor-specific absolute path prevents clean checkout and CI instantiation.
ext/​PowerFlowsExt/​pf_headroom.jl Updates EnumX bus typing. —
.claude/​pom_port_plan.md Removes the porting plan. —

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/services_models/reserves.jl Outdated
Comment thread src/services_models/security_constrained_injectors.jl Outdated
Comment thread test/Project.toml Outdated
Comment thread test/Project.toml Outdated
Comment thread test/includes.jl Outdated
Comment thread test/test_static_injection_security_constrained_models.jl Outdated
Comment thread src/PowerOperationsModels.jl Outdated
export RealizedShiftedLoadMinimumBoundConstraint
export NonAnticipativityConstraint
export HVDCDCControlConstraint
export PostContingencyGenerationBalanceConstraint
Comment thread src/operation/decision_model.jl Outdated
Comment thread src/services_models/security_constrained_injectors.jl Outdated
Comment thread src/core/constraints.jl Outdated
Comment thread src/core/variables.jl Outdated
Comment thread src/operation/decision_model.jl Outdated
Comment thread src/operation/template_validation.jl Outdated
Comment thread src/services_models/reserve_group.jl Outdated
Comment thread src/services_models/reserves.jl Outdated
Comment thread test/test_static_injection_security_constrained_models.jl Outdated
Comment thread test/test_static_injection_security_constrained_models.jl Outdated
Comment thread test/test_static_injection_security_constrained_models.jl Outdated
Comment thread test/test_static_injection_security_constrained_models.jl Outdated
flows are built only on modeled components, so monitored components must be a subset of the
modeled ones.
"""
function _check_security_constrained_reserve_monitors(

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This feels like this should be in template validation.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Also I'm not sure if we need a whole check for this. We can either error or warn when building the deviation variables.

end

# Outaged generators whose power the model can remove; the rest are skipped with a warning.
function _outaged_generators(

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Why is this helper per one outage, and the other one is per all the outages?

)
outage::PSY.Outage,
)
outaged = _PER_TYPE()

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I'm considering dropping this const alias.

return monitored_components
end

# Parallel circuits share one reduced entry, so each entry is constrained once.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Unnecessary comment

end

# Every outage gets a balance row per network region. Modeled interchanges carry a deviation
# variable per outage, balanced across areas; monitored interchanges (a subset of the modeled

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think the subset comment is unnecessary.

)
for devices in values(contributing_devices)
# Ramp limits bind spinning reserves only.
_is_ramp_formulation(F) && R <: PSY.Reserve &&

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Make helper

),
)

_valid_component_type(::PSY.ACTransmission, ::NetworkModel{<:AbstractPTDFNetworkModel}) =

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Maybe better name like _valid_monitored_component

::NetworkModel{AreaBalanceNetworkModel},
)
if !has_container_key(container, FlowActivePowerVariable, PSY.AreaInterchange)
@warn "An AreaBalanceNetworkModel with security-constrained reserves needs PSY.AreaInterchange(s) and DeviceModel{PSY.AreaInterchange} for reserve deployment to cross area boundaries. Otherwise, each area must cover its own outages." _group =

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Don't love how this is worded

Comment thread src/core/expressions.jl
struct BThetaBranchFlow <: ExpressionType end
struct PostContingencyNodalActivePowerDeployment <: PostContingencyExpressions end

"""

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think we can combine this with the area one and just do PostContingencyLocationalDeployment

end

_post_contingency_flow_expression(::NetworkModel{<:AbstractPTDFNetworkModel}) =
PostContingencyBranchFlow

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Same thought here, we can combine these and do PostContingencyBranchFlow or some more generic name than Branch. And both PTDF and Area will use the same.

return outaged
end

function _monitored_components(

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Still not checking for filtered?

@jd-lara

jd-lara commented Sep 25, 2026

Copy link
Copy Markdown
Member

@acostarelli we should close this and reopen with just the G-1 code

This branch has not been deployed

No deployments
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