Skip to content

Add HVDCTwoTerminalVSC two-terminal HVDC formulation#119

Merged
jd-lara merged 7 commits into
ac/hvdcfrom
ac/hvdc-vsc
May 18, 2026
Merged

Add HVDCTwoTerminalVSC two-terminal HVDC formulation#119
jd-lara merged 7 commits into
ac/hvdcfrom
ac/hvdc-vsc

Conversation

@acostarelli
Copy link
Copy Markdown
Member

No description provided.

Add two new formulations for PSY.TwoTerminalVSCLine: HVDCTwoTerminalVSC (NLP)
and HVDCTwoTerminalVSCBin2 (SOS2 MILP). Both model independent active/reactive
power control per terminal under a PQ capability circle, quadratic+linear
converter losses, and explicit cable resistance via v_f - v_t = (1/g)*I.
Reactive variables/constraints are added only on full AC networks.

Refactor shared converter-loss helpers (loss expression builder, abs-value
decomposition, linear-loss detection) out of mt_hvdc_models into
src/common_models/quadratic_converter_loss.jl so the multi-terminal and
two-terminal VSC paths reuse the same primitives. Rename the
ConverterPositiveCurrent / NegativeCurrent / CurrentDirection variable types
to generic PositiveCurrent / NegativeCurrent / CurrentDirection.

Point Project.toml at the InfrastructureOptimizationModels ac/hvdc-vsc
branch (which carries the per-device-bounds API used by these formulations)
and restore runtests.jl to run the full test list.
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 12, 2026

Performance Results

Version Precompile Time
Main 2.934761524
This Branch 2.982287969
Version Build Time
Main-Build Time Precompile 99.306053424
Main-Build Time Postcompile 13.474029951
This Branch-Build Time Precompile 79.700279507
This Branch-Build Time Postcompile 1.673959811
Version Solve Time
Main-Solve Time Precompile 408.847446944
Main-Solve Time Postcompile 377.325105639
This Branch-Solve Time Precompile 130.441635819
This Branch-Solve Time Postcompile 101.145207151

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 introduces a new two-terminal VSC HVDC formulation (HVDCTwoTerminalVSC NLP and HVDCTwoTerminalVSCBin2 MILP approximation) and associated modeling infrastructure, plus a refactor to share quadratic-loss and absolute-value current decomposition utilities across HVDC components.

Changes:

  • Add two-terminal VSC HVDC device formulation (variables, constraints, constructor integration) including Bin2 approximations.
  • Factor shared quadratic converter-loss + |I| decomposition helpers into a common module and reuse them in MT HVDC converter code.
  • Add/extend tests to build/solve the new VSC formulations and update a logger-dependent warning test.

Reviewed changes

Copilot reviewed 13 out of 14 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/core/formulations.jl Adds AbstractTwoTerminalVSCFormulation, HVDCTwoTerminalVSC, HVDCTwoTerminalVSCBin2.
src/core/variables.jl Introduces new VSC-related variables and renames current decomposition variable types.
src/core/constraints.jl Adds constraint types/docs for VSC power balance, cable Ohm’s law, and PQ capability.
src/common_models/quadratic_converter_loss.jl New shared helpers for quadratic/two-term loss expressions and abs-value decomposition.
src/twoterminal_hvdc_models/TwoTerminalDC_branches.jl Implements VSC variable traits, core constraints (Ohm’s law, power balance), and PQ capability constraints.
src/ac_transmission_models/branch_constructor.jl Wires TwoTerminalVSCLine into the build pipeline (variables, expressions, constraints, approximations).
src/network_models/pm_translator.jl Skips PM translation for LCC/VSC two-terminal HVDC branches via a trait.
src/mt_hvdc_models/HVDCsystems.jl Updates MT HVDC converter code to use shared loss/decomposition helpers and renamed variables.
src/mt_hvdc_models/hvdcsystems_constructor.jl Updates MT HVDC converter constructor to use renamed decomposition variables and formatting tweaks.
src/PowerOperationsModels.jl Includes the new common helper file and exports new formulations/variables (and renamed variables).
test/test_device_hvdc.jl Adds VSC formulation tests and adjusts a warning assertion to read the build log file.
test/runtests.jl Updates commented-out entries in the disabled test file list.
test/Project.toml Pins InfrastructureOptimizationModels to a feature branch for tests.
Project.toml Pins InfrastructureOptimizationModels to a feature branch and removes its [compat] entry.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread test/test_device_hvdc.jl Outdated
Comment on lines +1734 to +1752
_maybe_add_reactive_power_variables!(container, devices, device_model, network_model)

if _use_linear_loss(F, device_model)
ll_devices = _devices_with_linear_loss(devices)
if isempty(ll_devices)
@warn "use_linear_loss is enabled but every TwoTerminalVSCLine has zero proportional loss terms; no linear-loss variables/constraints will be added."
else
_add_abs_value_decomposition_variables!(container, ll_devices, device_model)
end
end

add_to_expression!(
container, ActivePowerBalance, FlowActivePowerFromToVariable,
devices, device_model, network_model,
)
add_to_expression!(
container, ActivePowerBalance, FlowActivePowerToFromVariable,
devices, device_model, network_model,
)
Copy link
Copy Markdown
Contributor

@rodrigomha rodrigomha May 13, 2026

Choose a reason for hiding this comment

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

@acostarelli Copilot is trolling here. the _maybe_add method also adds them to the expression. However, I would make the method in common files so it can be used with generic formulations like ThermalStandard or others. We do not need to refactor the old code to this, but future methods should try to use this.

Comment on lines +1564 to +1574
g = PSY.get_g(d)
# If g == 0 we treat the cable as lossless (v_f == v_t).
# Otherwise R = 1/g.
for t in time_steps
cons[name, t] = if iszero(g)
JuMP.@constraint(jump_model, v_f[name, t] == v_t[name, t])
else
JuMP.@constraint(
jump_model,
v_f[name, t] - v_t[name, t] == (1.0 / g) * i_var[name, t],
)
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.

@rodrigomha Does this look right now?

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.

This is correct. If g = 0, then there is an infinite impedance and hence cannot be current flowing through the cable. Good catch here.

Comment on lines +1715 to +1767
# Bin2 variant: inscribed octagon in the rating circle (s/sqrt(2) half-diagonal).
# Eight linear constraints per terminal: ±p ± q ≤ s and ±p ≤ s, ±q ≤ s.
function add_constraints!(
container::OptimizationContainer,
::Type{HVDCVSCReactiveCapabilityConstraint},
devices::Union{
Vector{PSY.TwoTerminalVSCLine},
IS.FlattenIteratorWrapper{PSY.TwoTerminalVSCLine},
},
::DeviceModel{PSY.TwoTerminalVSCLine, HVDCTwoTerminalVSCBin2},
::NetworkModel{<:AbstractPowerModel},
)
time_steps = get_time_steps(container)
names = [PSY.get_name(d) for d in devices]
jump_model = get_jump_model(container)

p_ft = get_variable(container, FlowActivePowerFromToVariable, PSY.TwoTerminalVSCLine)
p_tf = get_variable(container, FlowActivePowerToFromVariable, PSY.TwoTerminalVSCLine)
q_f = get_variable(container, HVDCReactivePowerFromVariable, PSY.TwoTerminalVSCLine)
q_t = get_variable(container, HVDCReactivePowerToVariable, PSY.TwoTerminalVSCLine)

cons = Dict{String, Any}()
for tag in ("from_pp", "from_pn", "from_np", "from_nn",
"to_pp", "to_pn", "to_np", "to_nn")
cons[tag] = add_constraints_container!(
container, HVDCVSCReactiveCapabilityConstraint, PSY.TwoTerminalVSCLine,
names, time_steps; meta = tag,
)
end

inv_sqrt2 = 1.0 / sqrt(2.0)
for d in devices
name = PSY.get_name(d)
s_f = PSY.get_rating_from(d) * inv_sqrt2
s_t = PSY.get_rating_to(d) * inv_sqrt2
for t in time_steps
# Octagon at the from terminal: project (p, q) onto 4 diagonal lines.
cons["from_pp"][name, t] =
JuMP.@constraint(jump_model, p_ft[name, t] + q_f[name, t] <= 2.0 * s_f)
cons["from_pn"][name, t] =
JuMP.@constraint(jump_model, p_ft[name, t] - q_f[name, t] <= 2.0 * s_f)
cons["from_np"][name, t] =
JuMP.@constraint(jump_model, -p_ft[name, t] + q_f[name, t] <= 2.0 * s_f)
cons["from_nn"][name, t] =
JuMP.@constraint(jump_model, -p_ft[name, t] - q_f[name, t] <= 2.0 * s_f)
cons["to_pp"][name, t] =
JuMP.@constraint(jump_model, p_tf[name, t] + q_t[name, t] <= 2.0 * s_t)
cons["to_pn"][name, t] =
JuMP.@constraint(jump_model, p_tf[name, t] - q_t[name, t] <= 2.0 * s_t)
cons["to_np"][name, t] =
JuMP.@constraint(jump_model, -p_tf[name, t] + q_t[name, t] <= 2.0 * s_t)
cons["to_nn"][name, t] =
JuMP.@constraint(jump_model, -p_tf[name, t] - q_t[name, t] <= 2.0 * s_t)
Comment thread src/core/constraints.jl Outdated
Comment thread src/PowerOperationsModels.jl
Comment thread src/ac_transmission_models/branch_constructor.jl Outdated
Comment thread src/ac_transmission_models/branch_constructor.jl Outdated
Comment thread src/common_models/quadratic_converter_loss.jl Outdated
Comment thread src/common_models/quadratic_converter_loss.jl Outdated
Comment thread src/common_models/quadratic_converter_loss.jl Outdated
Comment thread src/network_models/pm_translator.jl
Comment thread src/twoterminal_hvdc_models/TwoTerminalDC_branches.jl
Comment thread test/test_device_hvdc.jl
Comment thread src/twoterminal_hvdc_models/TwoTerminalDC_branches.jl Outdated
Comment thread src/twoterminal_hvdc_models/TwoTerminalDC_branches.jl Outdated
- Rename Bin2 → MIP for VSC + IPC formulations and update tests
- Make HVDCReactivePowerVariable parametric on From/To with const aliases
- Wire HVDCReactivePower{From,To}Variable into ReactivePowerBalance on AC
- Fix g==0 cable Ohm's law to force I==0 (open circuit, not v_f == v_t)
- Add axis-aligned half-spaces to the MIP PQ-capability octagon
- Default use_linear_loss=true for MIP and false for NLP via
  get_default_attributes; warn when NLP runs with use_linear_loss=true
- Collapse abs-value decomposition into a single ModelConstructStage helper
- Skip zero-coefficient terms in the quadratic converter loss expression
- Fix docstring sign convention on HVDCVSCConverterPowerConstraint
- Drop brittle log-file-regex linear-loss warning test

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copy link
Copy Markdown
Member Author

@acostarelli acostarelli left a comment

Choose a reason for hiding this comment

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

Review 2

Comment thread src/ac_transmission_models/branch_constructor.jl Outdated
Comment thread src/common_models/add_to_expression.jl Outdated
Comment thread src/common_models/quadratic_converter_loss.jl Outdated
Comment thread src/mt_hvdc_models/HVDCsystems.jl
Comment thread src/mt_hvdc_models/hvdcsystems_constructor.jl Outdated
Comment thread src/twoterminal_hvdc_models/TwoTerminalDC_branches.jl
- Add HVDCTwoTerminalVSCLP formulation that owns the octagonal linear
  outer-approximation of the per-terminal PQ disk; document the octagon
  geometry and its tightness tradeoffs vs the PWL path.
- Refactor HVDCTwoTerminalVSC (NLP) and HVDCTwoTerminalVSCMIP (PWL) to
  share a single PQ-capability add_constraints! method that writes
  `p_sq + q_sq <= s^2` over IOM._add_quadratic_approx! expressions.
- Collapse the HVDCReactivePowerVariable{From}/{To} add_to_expression
  methods into one parametric method via a new `_vsc_arc_bus` helper;
  collapse `_vsc_v_from_bounds`/`_vsc_v_to_bounds` similarly.
- Dispatch `_quadratic_converter_loss_expr` on i_sq_t (QuadExpr vs
  AffExpr) and accumulate via JuMP.add_to_expression!; degrade to
  AffExpr when a == 0 even on the QuadExpr branch.
- Drop the explicit-type-check MINLP warnings on both VSC and MT HVDC
  paths; leave brief comments in their place.
- Document the use_linear_loss defaults on all four
  get_default_attributes methods.
- Reorder construct_device! to add the abs-value decomposition variables
  before the constraints that consume them (PositiveCurrent /
  NegativeCurrent were previously requested before they were added).
- Replace `filter(_has_linear_loss, devices)` with a comprehension so
  it works on FlattenIteratorWrapper as well as Vector.
- Omit the VSCMIP/VSCLP on ACPPowerModel build tests: HiGHS cannot
  handle the ACP network's trigonometric branch constraints.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Comment thread src/core/variables.jl Outdated
"""
struct HVDCToDCVoltage <: VariableType end

abstract type From end
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.

This looks wierd. Probably an hallucination

Comment thread src/core/constraints.jl Outdated

For `HVDCTwoTerminalVSCMIP` it is replaced by an inscribed polygon to stay MILP.
"""
struct HVDCVSCReactiveCapabilityConstraint <: ConstraintType end
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.

This name is off. If this is a constraint for p^2+q^2, then this is constraint on ApparentPower, so it should be HVDCVSCApparentPowerLimitConstraint.

However a more important comment is that I don't understand why Claude is talking here about MIP or LP. This a circle constraint on apparent power, but we could skip this and only model the box constraints separately Pmin <= P <= Pmax and Qmin <= Q <= Qmax.

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 instructed it to make three formulations:

  • NLP that uses the exact p^2+q^2
  • MIP that approximates p^2 and q^2
  • LP that builds an octagon (instead of a box)

Comment thread src/core/variables.jl Outdated
Comment thread src/mt_hvdc_models/hvdcsystems_constructor.jl
# solver in that case.
use_ll = get_attribute(model, "use_linear_loss")
if use_ll
_add_abs_value_decomposition!(
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.

Is this creating the variables in the ModelConstructor? I think we should try to create the variables in the ArgumentConstructor. Is fine if we have two auxiliary methods for constraints and variables separately.

Comment thread src/network_models/pm_translator.jl
Comment thread src/common_models/quadratic_converter_loss.jl Outdated
Comment thread src/twoterminal_hvdc_models/TwoTerminalDC_branches.jl Outdated
Copy link
Copy Markdown
Contributor

@rodrigomha rodrigomha left a comment

Choose a reason for hiding this comment

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

@acostarelli I think these comments are good starting point. Let me know when you address them and I will re-review.

Overall, is in a good shape. I have not reviewed the tests yet.

I think we should not use parametric types for now for variables or others, so let's revert that to multiple From/To structs specifically.

- Drop parametric From/To types in favor of two concrete reactive-power
  variable structs (HVDCReactivePowerFromVariable / ToVariable); unroll the
  side-parametric _vsc_* accessors into two named methods each.
- Rename HVDCTwoTerminalVSCMIP -> HVDCTwoTerminalVSCMILP (forward-looking
  for future MINLP support) and HVDCVSCReactiveCapabilityConstraint ->
  HVDCVSCApparentPowerLimitConstraint with a docstring covering NLP/MILP/LP
  paths accurately.
- Split _add_abs_value_decomposition! into separate variables (ArgumentStage)
  and constraints (ModelStage) helpers; move the variable-creation call to
  ArgumentConstructStage in both the VSC and MT converter constructors.
- Move _maybe_add_reactive_power_variables! / _constraints! to a new
  common_models/network_conditional.jl as generic helpers parameterized by
  variable types and constraint type, addressing issue #120.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copy link
Copy Markdown
Member Author

@acostarelli acostarelli left a comment

Choose a reason for hiding this comment

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

Review 3

Comment thread src/twoterminal_hvdc_models/TwoTerminalDC_branches.jl Outdated
Comment thread src/ac_transmission_models/branch_constructor.jl Outdated
Comment thread src/common_models/add_to_expression.jl Outdated
Two-terminal VSC: add `HVDCReactivePowerFromVariable` to `ReactivePowerBalance`
at the from-terminal AC bus.
"""
function add_to_expression!(
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.

We can still combine these two add_to_expression!s and dispatch on the variable type.

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.

I think is fine having two methods. However, since the methods are super close I think you could reuse a single method with Union for both From and To, and having a helper method that retrieves the from or to bus depending on the variable. Proposed approach:

function add_to_expression!(
    container::OptimizationContainer,
    ::Type{T},
    ::Type{U},
    devices::IS.FlattenIteratorWrapper{V},
    ::DeviceModel{V, W},
    network_model::NetworkModel{X},
) where {
    T <: ReactivePowerBalance,
    U <: Union{HVDCReactivePowerFromVariable, HVDCReactivePowerToVariable}
    V <: PSY.TwoTerminalVSCLine,
    W <: AbstractTwoTerminalVSCFormulation,
    X <: ACPPowerModel,
}
    var = get_variable(container, HVDCReactivePowerToVariable, V)
    nodal_expr = get_expression(container, T, PSY.ACBus)
    network_reduction = get_network_reduction(network_model)
    time_steps = get_time_steps(container)
    for d in devices
        name = PSY.get_name(d)
        bus = _get_bus_for_expression(d, U) # TODO: implement this helper method
        bus_no = PNM.get_mapped_bus_number(network_reduction, bus)
        for t in time_steps
            add_proportional_to_jump_expression!(
                nodal_expr[bus_no, t],
                var[name, t],
                -1.0,
            )
        end
    end
    return
end

Also, I think we should just add the ReactivePowerVariable positive to the expression. This is mostly a convention for VSC endings, that they can inject/consume reactive power freely, so it's fine to have them positive (contrary to the LCC model that has to consume reactive power).

Comment thread src/common_models/network_conditional.jl Outdated
Comment thread src/common_models/network_conditional.jl Outdated
Comment thread src/twoterminal_hvdc_models/TwoTerminalDC_branches.jl Outdated
Comment thread src/twoterminal_hvdc_models/TwoTerminalDC_branches.jl Outdated
(prefix = "from", p_var = p_ft, q_var = q_f, rating_getter = _vsc_rating_from),
(prefix = "to", p_var = p_tf, q_var = q_t, rating_getter = _vsc_rating_to),
)
for d in devices
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.

Can we reorganize this loop and use JuMP vectorized jump.@constraint macros to build this faster?

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.

You can ask Claude to try this, but this is okay as it is. Note that we are adding a container for each tag, so it can be a pain to implement that.

Comment thread src/twoterminal_hvdc_models/TwoTerminalDC_branches.jl Outdated
# Their intersection is a regular octagon. Eight linear constraints per
# terminal per timestep (four diagonal + four axis-aligned).
#
# Tightness: the octagon is loose by at most ≈8.2% in area (octagon-to-disk
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.

Are you sure it's an outer approximation?

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.

I asked Claude to make a nice figure of this, but yeah, pretty much, since the diagonal is rating * sqrt(2.0).

image

@rodrigomha
Copy link
Copy Markdown
Contributor

Still some work to be done here, but is getting there.

Anthony Costarelli and others added 2 commits May 14, 2026 12:50
Drop the HVDCTwoTerminalVSCMILP formulation: the PWL surrogate for the
loss model is already MILP-grade, so a separate MILP-on-disk path didn't
buy anything we can solve. The LP path now carries a `use_octagon`
attribute (default `true`) that toggles the four diagonal half-planes on
top of the always-on axis-aligned box, so users can pick either the
octagon (≤8.2% loose linear outer-approximation of the disk) or just the
box without adding new formulations.

Refactors driven by the review feedback:
- Rename MIPQuadraticLossConverter -> MILPQuadraticLossConverter
  (forward-looking for potential MINLP variants).
- Delete _maybe_add_pq_sq_approx! and the per-formulation
  _uses_pq_sq_approx trait; the p_sq/q_sq IOM expressions are now
  registered by _register_pq_sq_expressions!, resolved by dispatch on
  (formulation, network) so only HVDCTwoTerminalVSC on an AC network
  registers them.
- Drop the VSC PSY wrappers (_vsc_v_limits_*, _vsc_rating_*,
  _vsc_v_bounds_*, _vsc_i_bounds) and call PSY.get_voltage_limits_* /
  get_rating_* directly via broadcast.
- Consolidate _vsc_shared_i_max into _linear_loss_i_max with method
  overloads for TwoTerminalVSCLine and InterconnectingConverter.
- Collapse the From/To HVDCReactivePower* add_to_expression! pair into
  one method dispatching on the variable type via _vsc_q_terminal_bus,
  and flip the coefficient from -1.0 to +1.0 (VSC injects/consumes Q
  freely, unlike LCC which is strictly a consumer).
- Replace the runtime `if N <: AbstractActivePowerModel` guards in
  network_conditional.jl with explicit no-op methods dispatched on
  NetworkModel{<:AbstractActivePowerModel}.
- Combine the two _quadratic_converter_loss_expr methods via a
  JuMP-type-dispatched _loss_seed helper.
- Drop the i_max_getter::Function argument from
  _add_abs_value_decomposition_constraints!; the getter is now picked
  by dispatch on the device type.
- Switch the four VSC add_constraints! signatures to the parameterized
  Union{Vector{U}, IS.FlattenIteratorWrapper{U}} where {U <: ...} form
  used elsewhere in the file.

Tests:
- Delete the HVDCTwoTerminalVSCMILP testsets and rename the
  MILPQuadraticLossConverter testset accordingly.
- Switch the MIP-vs-NLP agreement test to LP-vs-NLP isapprox at 5%
  tolerance (on DCP the PQ disk is inactive, so the LP and NLP differ
  only by the i² loss surrogate; the SOS2 PWL can be slightly above the
  exact i², so a strict ordering doesn't hold).
- Add a new testset that asserts use_octagon=true on the LP path gives
  an objective ≥ the box-only case, pinning the new attribute's
  semantics.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copy link
Copy Markdown
Member Author

@acostarelli acostarelli left a comment

Choose a reason for hiding this comment

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

Review 4

Comment thread src/ac_transmission_models/branch_constructor.jl Outdated
return expr
end

function _quadratic_converter_loss_expr(
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.

What do you think of this setup with the helper? @rodrigomha

Comment thread src/mt_hvdc_models/hvdcsystems_constructor.jl Outdated
Comment thread src/twoterminal_hvdc_models/TwoTerminalDC_branches.jl Outdated
Comment thread src/twoterminal_hvdc_models/TwoTerminalDC_branches.jl Outdated
prefix = spec.prefix
p_var, q_var = spec.p_var, spec.q_var
for t in time_steps
cons[prefix * "_p_ub"][name, t] =
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.

If we didn't this prefix system, could we simplify this using the vectorized constraints?

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.

This is good for future testing but not really needed for this PR, so we can keep it as it is for now, but an issue could be open if you want to explore the idea

Comment thread src/core/formulations.jl
``I^2`` terms exact. Requires an NLP-capable solver (e.g. Ipopt).
"""
struct HVDCTwoTerminalVSC <: AbstractTwoTerminalVSCFormulation end
struct HVDCTwoTerminalVSCNLP <: AbstractTwoTerminalVSCFormulation 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.

@rodrigomha What do you think of this naming?

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.

It's okay I think. I'm thinking that maybe NLPHVDCTwoTerminalVSC and LPHVDCTwoTerminalVSC is better, but I don't know lol. This approach is more consistent with the Converter convention using MILPQuadraticLossConverter.

Any ideas @jd-lara

# converter formulations.
_quad_config(::Type{HVDCTwoTerminalVSCNLP}) = IOM.NoQuadApproxConfig()
_quad_config(::Type{HVDCTwoTerminalVSCLP}) =
IOM.SolverSOS2QuadConfig(DEFAULT_INTERPOLATION_LENGTH)
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.

@acostarelli Can you open an issue to figure out how the user can configure the interpolation and model option (BIN2 or other) for the approximation for the future? We don't need to solve this in this PR, but we need to be aware of that.

Copy link
Copy Markdown
Contributor

@rodrigomha rodrigomha left a comment

Choose a reason for hiding this comment

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

Okay. I'm happy with this. We can merge this @jd-lara after we decide if we are okay with the naming convention

@jd-lara jd-lara merged commit baa0288 into ac/hvdc May 18, 2026
2 of 6 checks passed
@jd-lara
Copy link
Copy Markdown
Member

jd-lara commented May 18, 2026

Okay. I'm happy with this. We can merge this @jd-lara after we decide if we are okay with the naming convention

we can open an issue to review that

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.

4 participants