Add enable_ront: regulated transformer (rONT) as an LV voltage measure (#377) - #729
Open
nader-00 wants to merge 6 commits into
Open
Add enable_ront: regulated transformer (rONT) as an LV voltage measure (#377)#729nader-00 wants to merge 6 commits into
enable_ront: regulated transformer (rONT) as an LV voltage measure (#377)#729nader-00 wants to merge 6 commits into
Conversation
Adds an enable_ront flag to reinforce_grid() that resolves LV-internal voltage issues by relabelling the existing station transformer as a RONT (regelbarer Ortsnetztransformator) instead of disconnecting or reinforcing lines, for grids where lv_grid_ront_feasible() confirms that a RONT with a bounded control range (ront_voltage_range config, default +/-6%, placeholder pending a citable source) can resolve all voltage issues at every time step - respecting both that control range and the hard +/-10% system voltage limit. lv_grid_ront_feasible() is the single source of truth used by both the enable_ront guard and the RONT-aware final absolute check, so a grid for which RONT is set is guaranteed to also pass that check. The RONT is electrically identical to the standard transformer it replaces (s_nom/r_pu/x_pu unchanged, only type_info changes) - its regulating effect is modelled as an idealised, bounded reference-voltage shift in the voltage limit checks, not as an actual tap-changing transformer in the power flow. Also fixes two pre-existing gaps surfaced while validating this feature: - _reinforce_station_overloading()'s "second transformer of the same kind" clone branch could clone a RONT-tagged transformer's type_info onto the new transformer, mislabelling a plain overload-driven unit as a second RONT. Fixed via a new standard_type_name() helper (inverse of ront_type_name()). - grid_expansion_costs() only costed transformers with change=="added", silently never costing "changed" transformers (RONT conversions use change=="changed", analogous to how line type upgrades are logged). Extended to cost "changed" transformers too, excluding ones later removed. Validated against 33 known voltage-driven LV grids across 7 real networks: 33/33 resolved via RONT, 0 residual violations, 0 stations with more than one RONT-tagged transformer, real Grenzfall 32182/1118050007 confirmed solved. enable_ront=False remains bit-identical to dev.
ront_voltage_range: 0.06 (unsourced placeholder) -> 0.10, per FNN-Hinweis "Regelbarer Ortsnetztransformator (rONT) -- Einsatz in Netzplanung und Netzbetrieb" (2016), sections 5.9.1/5.9.2 -- the network planning criterion uses +/-10% (9 taps, 2.5% step); market products and all five practical examples in annex B confirm +/-4 x 2.5%. Comment now also notes that real rONTs are stepped with a ~4% control deadband (section 5.5.2), whereas our ref(t) model is continuous and deadband-free -- an optimistic idealisation, to be called out explicitly in the PR description. ront_surcharge: kept at 20 kEUR, comment replaced to point at the actual FNN 2016 cost-component discussion (section 5.8.1) instead of the earlier, less specific literature pointers -- FNN names cost components but no absolute figures, so the value itself remains a placeholder to be adapted per operator/product. Re-validated with the new default: full test suite green, enable_ront=False still bit-identical to dev, integration re-run against the 33 known cases unchanged (33/33 resolved, 0 residual violations, 7/7 networks without ValueError, 0 stations with more than one RONT-tagged transformer).
- remove lv_grid_voltage_spread() (dead since lv_grid_ront_feasible() became the shared guard/check criterion) and its tests - remove the 7 unused "<size> RONT" catalogue rows; rONT type_info is a marker (impedance comes from the existing transformer row), documented in ront_type_name() - move ront_voltage_range to [grid_expansion_allowed_voltage_deviations] next to lv_max_v_rise/lv_max_v_drop
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds an opt-in LV voltage-issue reinforcement measure: converting an LV
station's standard transformer to a regelbarer Ortsnetztransformator (rONT,
regulated distribution transformer) instead of reinforcing/disconnecting LV
lines, for grids where a bounded voltage-control range at the station is
sufficient to resolve all LV voltage issues.
Part of the broader effort in #377 (add/improve grid reinforcement methods).
Problem
Today, LV voltage issues are always solved by splitting/reinforcing LV
feeders (
reinforce_lines_voltage_issues), even in cases where the actualspread of LV voltage deviations across the grid is small enough that a
regulated transformer at the station — a real, commonly used piece of
equipment in German LV grids — would resolve the issue without touching a
single line.
Solution
enable_ront: bool = Falseparameter onreinforce_grid(). Whenenabled, for every LV grid with voltage issues, before falling back to line
reinforcement, checks whether a regulated transformer with a bounded
control range (
lv_grid_ront_feasible()) can resolve all voltage issues atthat grid — if so, converts the station's transformer to its rONT
equivalent (
reinforce_lv_grid_ront_voltage_issues()) instead of touchinglines.
transformer it replaces (same
s_nom/r_pu/x_pu) — the voltage-regulating behaviour is modelled as a widened, bounded allowed-voltage
window around the transformer's own unregulated secondary voltage
(
v_unreg(t)), evaluated in_lv_allowed_voltage_limits(), rather than bysimulating an actual tap-changer in the power flow. This is a deliberate
simplification (Option A from the design discussion) — see Caveats below.
lv_grid_ront_feasible()): the single source oftruth used both by the reinforcement guard and by the RONT-aware final
check, so "a RONT was installed" and "the final +/-10% band check passes"
are structurally guaranteed to agree, not just empirically.
(
allowed_voltage_limits(split_voltage_band=False)) excludes (does notsilently pass) buses belonging to a feasible-RONT grid, using the same
lv_grid_ront_feasible()function — everything else keeps the untouched,hard +/-10% band as a backstop.
transformer size in
equipment-parameters_LV_transformers.csv, impedance-identical to its base type (
is_ront()/ront_type_name()/standard_type_name()helpers intools.py).[grid_expansion_ront].ront_voltage_range = 0.10and[costs_transformers].ront_surcharge = 20(both sourced, see Configvalues below).
Two additional, incidental fixes found during integration testing
_reinforce_station_overloading()'s"second transformer of the same kind" clone branch copied the RONT-tagged
type_infoverbatim onto a new transformer meant to resolve anindependent overload — meaning a RONT station could end up with two
RONT-tagged transformers instead of one RONT (voltage) plus one correctly
typed standard transformer (overload). Fixed via an
is_ront()check +standard_type_name()reassignment before the clone is renamed. Theinvariant is "no station has more than one RONT-tagged transformer", not
"no station has more than one transformer" — a RONT station legitimately
can gain a second, standard transformer for an independent overload.
validation):
grid_expansion_costs()only ever costed transformers withequipment_changes["change"] == "added", never"changed". RONTconversions are logged as
"changed"(the transformer itself is notreplaced, only its
type_info), so RONT'sront_surchargewas silentlynever costed (always 0 kEUR). Fixed by extending the costable-transformer
filter to include
"changed"entries (excluding any later"removed"),mirroring how "changed" lines are already costed unconditionally.
Config values (sourced)
ront_voltage_range = 0.10: FNN-Hinweis "Regelbarer Ortsnetztransformator(rONT) — Einsatz in Netzplanung und Netzbetrieb" (2016), sections
5.9.1/5.9.2 — the network-planning criterion uses +/-10% (9 taps, 2.5%
step); market products and all five practical examples in annex B confirm
+/-4 x 2.5%.
ront_surcharge = 20kEUR: same source, section 5.8.1 — names the costcomponents (procurement, installation incl. sensors/control electronics,
documentation) but no absolute figures; the value itself is a placeholder,
operator- and product-specific, and should be adapted per use case.
Caveats (idealisation, called out explicitly)
typically ~4% (1.6x the tap step, FNN section 5.5.2) before the regulator
switches. This PR's
ref(t)model is continuous and dead-band-free — anoptimistic idealisation relative to any real device, in addition to the
general limitation that no actual tap-changer is simulated in the power
flow.
this PR only ever uses it for voltage issues; an independent overload at
the same station is still resolved by adding a correctly-typed standard
transformer (see the duplicate-transformer fix above).
ratios of 1:2.5 to 1:6-7 versus conventional expansion in real projects
(~28% savings). Our own validation sample (33 known voltage-driven LV
grids across 7 real networks) shows a comparable order of magnitude
(status-quo 2573.0 kEUR -> RONT 1297.36 kEUR total, ~50%), though our flat,
size- and cross-section-independent line cost model likely understates the
conventional alternative rather than overstating it.
Validation
enable_ront=Falseconfirmed bit-identical todev(pickledtransformers_df,topology_lines_df,equipment_changes,grid_expansion_costs, compared viapandas.testing.assert_frame_equal),re-checked after every code change.
(excluding one grid with a known, unrelated non-convergence issue): 33/33
resolved via RONT, 0/33 residual violations against the final +/-10% check,
7/7 networks without a
ValueError, 0 stations with more than oneRONT-tagged transformer, 33/33 grids with equal-or-fewer reinforcement
measures than the status quo.
Related, but independent work
from [FEATURE] Add grid reinforcement methods #377 — does not touch RONT,
reinforce_grid.py,check_tech_constraints.pyortools.pyat all (verified against its ownmerge-base). No overlap.
type_infocost fix forseparate_lv_grid()) is unrelated: it fixes atype_info=Nonedata bug on transformers added byseparate_lv_grid()(an opt-in, whole-station-separation path unrelated to RONT), while this PR
fixes a separate bug —
change=="changed"transformers never being costedat all. Independent bugs, independent code paths, no dependency either way
(
is_ront(None)returnsFalserather than raising, andenable_rontisa
reinforce_grid()-only parameter, never reachingseparate_lv_grid()).Type of change
fixes described above
Checklist:
pre-commithooks