-
Notifications
You must be signed in to change notification settings - Fork 1
Add tolerance-driven bilinear approximation config API #122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 16 commits
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
0bf1ff5
Bilinear hydro formulation and IOM/PSY API updates
001b82a
Merge branch 'main' into ac/hydro-bilinear
acostarelli f559b20
Merge remote-tracking branch 'origin/main' into ac/hydro-bilinear
9bc4add
Address review comments on bilinear hydro test
a73d189
Rename HydroTurbineBin2BilinearDispatch to MILP and expose bilinear_a…
57bc7ae
switch HydroTurbineMILPBilinearDispatch from n_segments to tolerance
147ec06
Replace bilinear attribute config with POM config structs
b938cbd
Merge remote-tracking branch 'origin/main' into ac/hydro-milp-rename
8363d0b
Simplify bilinear _iom_config bridge against updated IOM contract
f03f49f
Generalize bilinear configs to x×y and validate tolerance
de5735d
Return to attribute-based bilinear config, deriving epigraph depth fr…
b4e1a6c
Merge remote-tracking branch 'origin/main' into ac/hydro-milp-rename
0414f81
update source branches
14dbbfd
removed excessive comments and tests
ccca499
Make converter loss approximations attribute-driven
475769b
Add relative tolerance to bilinear approximation API
5ebe8f6
Merge NLP+MILP bilinear formulations into single attribute-driven types
3919d47
Address June 8 review: centralize bilinear attrs, tighten tolerance, …
9d930d6
two-layer -> one-layer helper with extra noop for ambiguity
d954775
remove excessive comments and tests
1f3d6f7
copilot review
da98c62
fix target for approximation test
1b1aa08
Fix vacuous HVDC MILP/NLP agreement test
43465c2
remove bad test
40a7cc2
copilot bug fix
d86ae34
apply fixes to hydro models
jd-lara ac483ac
Merge branch 'ac/hydro-milp-rename' of github.com:NREL-Sienna/PowerOp…
jd-lara 5fc3007
fix conflict
jd-lara 153b281
delete untracked files
jd-lara File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
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
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
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,150 @@ | ||
| ############################ Validation helpers ############################################ | ||
|
|
||
| function _validate_tolerance(tolerance::Float64) | ||
| (isfinite(tolerance) && tolerance > 0) || throw( | ||
| ArgumentError( | ||
| "bilinear approximation `tolerance` must be finite and > 0, got $tolerance", | ||
| ), | ||
| ) | ||
| return tolerance | ||
| end | ||
|
|
||
| """ | ||
| Characteristic magnitude of a variable over its per-device `bounds` | ||
| (`max|x|` across all devices). Used to turn a relative tolerance into an | ||
| absolute one — see [`_resolve_tolerance`](@ref). | ||
| """ | ||
| _max_abs(bounds) = maximum(max(abs(b.min), abs(b.max)) for b in bounds) | ||
|
|
||
| """ | ||
| Resolve the absolute bilinear/quadratic approximation tolerance from the | ||
| `absolute` and `relative` attribute values. A relative tolerance is scaled to | ||
| absolute by the characteristic product/term magnitude `scale` | ||
| (`τ_abs = relative · scale`). Each argument is a positive number or `nothing`; | ||
| the discretization must satisfy every tolerance that is set, so the effective | ||
| absolute tolerance is the smallest of those provided. At least one must be set. | ||
| """ | ||
| function _resolve_tolerance(absolute, relative, scale::Float64) | ||
| tols = Float64[] | ||
| isnothing(absolute) || push!(tols, Float64(absolute)) | ||
| isnothing(relative) || push!(tols, Float64(relative) * scale) | ||
| isempty(tols) && throw( | ||
| ArgumentError( | ||
| "at least one of `bilinear_absolute_tolerance` or " * | ||
| "`bilinear_relative_tolerance` must be set (both are unset)", | ||
| ), | ||
| ) | ||
| return _validate_tolerance(minimum(tols)) | ||
| end | ||
|
|
||
| function _quad_config_type(method::String) | ||
| if method == "solver_sos2" | ||
| return IOM.SolverSOS2QuadConfig | ||
| elseif method == "manual_sos2" | ||
| return IOM.ManualSOS2QuadConfig | ||
| elseif method == "sawtooth" | ||
| return IOM.SawtoothQuadConfig | ||
| elseif method == "nmdt" | ||
| return IOM.NMDTQuadConfig | ||
| elseif method == "dnmdt" | ||
| return IOM.DNMDTQuadConfig | ||
| else | ||
| error( | ||
| "Unsupported bilinear quadratic method \"$(method)\". " * | ||
| "Supported: \"solver_sos2\", \"manual_sos2\", \"sawtooth\", " * | ||
| "\"nmdt\", \"dnmdt\".", | ||
| ) | ||
| end | ||
| end | ||
|
|
||
| const _BIN2_QUAD_METHODS = ("solver_sos2", "manual_sos2", "sawtooth", "nmdt", "dnmdt") | ||
| const _HYBS_QUAD_METHODS = ("solver_sos2", "manual_sos2", "sawtooth") | ||
|
|
||
| function _validate_quad_method(method::String, scheme::String, supported) | ||
| method in supported || error( | ||
| "Unsupported bilinear quadratic method \"$(method)\" for bilinear " * | ||
| "approximation \"$(scheme)\". Supported: " * | ||
| join(("\"$(m)\"" for m in supported), ", ") * ".", | ||
| ) | ||
| return method | ||
| end | ||
|
|
||
| ############################ Translation to IOM configs #################################### | ||
|
|
||
| """ | ||
| Build the IOM bilinear config consumed by `IOM._add_bilinear_approx!` from | ||
| string attribute values, sizing the discretization from `tolerance` and the | ||
| per-device domain widths (`delta_x`, `delta_y`). | ||
|
|
||
| `method` selects the bilinear approximation scheme: `"bin2"`, `"hybs"`, | ||
| `"nmdt"`, `"dnmdt"`, or `"none"`. `quad_method` selects the inner quadratic | ||
| PWL method used by the `"bin2"` and `"hybs"` schemes (`"solver_sos2"`, | ||
| `"manual_sos2"`, `"sawtooth"`, and — for `"bin2"` only — `"nmdt"`, `"dnmdt"`); | ||
| it is ignored by the other schemes. | ||
|
|
||
| Each IOM `tolerance_depth` / `tolerance_epigraph_depth` helper inverts its | ||
| method's worst-case-gap bound and allocates the error budget across the inner | ||
| quadratic, so POM never sizes the inner quad by hand — it just builds the inner | ||
| quad at the returned `depth` (with the IOM-default `epigraph_depth`). | ||
|
|
||
| Errors when `method` or `quad_method` is unrecognized, when `quad_method` is | ||
| invalid for the selected scheme, or when `tolerance` is non-finite or ≤ 0. | ||
| """ | ||
| function _build_bilinear_config( | ||
| method::String, | ||
| quad_method::String, | ||
| tolerance::Float64, | ||
| delta_x::Float64, | ||
| delta_y::Float64, | ||
| ) | ||
| method == "none" && return IOM.NoBilinearApproxConfig() | ||
| _validate_tolerance(tolerance) | ||
| if method == "bin2" | ||
| _validate_quad_method(quad_method, method, _BIN2_QUAD_METHODS) | ||
| Q = _quad_config_type(quad_method) | ||
| depth = IOM.tolerance_depth( | ||
| IOM.Bin2Config{Q}; | ||
| tolerance = tolerance, | ||
| max_delta_x = delta_x, | ||
| max_delta_y = delta_y, | ||
| ) | ||
| return IOM.Bin2Config(Q(; depth)) | ||
| elseif method == "hybs" | ||
| _validate_quad_method(quad_method, method, _HYBS_QUAD_METHODS) | ||
| Q = _quad_config_type(quad_method) | ||
| depth = IOM.tolerance_depth( | ||
| IOM.HybSConfig{Q}; | ||
| tolerance = tolerance, | ||
| max_delta_x = delta_x, | ||
| max_delta_y = delta_y, | ||
| ) | ||
| epigraph_depth = IOM.tolerance_epigraph_depth( | ||
| IOM.HybSConfig{Q}; | ||
| tolerance = tolerance, | ||
| max_delta_x = delta_x, | ||
| max_delta_y = delta_y, | ||
| ) | ||
| return IOM.HybSConfig(Q(; depth); epigraph_depth) | ||
| elseif method == "nmdt" | ||
| depth = IOM.tolerance_depth( | ||
| IOM.NMDTBilinearConfig; | ||
| tolerance = tolerance, | ||
| max_delta_x = delta_x, | ||
| max_delta_y = delta_y, | ||
| ) | ||
| return IOM.NMDTBilinearConfig(; depth) | ||
| elseif method == "dnmdt" | ||
| depth = IOM.tolerance_depth( | ||
| IOM.DNMDTBilinearConfig; | ||
| tolerance = tolerance, | ||
| max_delta_x = delta_x, | ||
| max_delta_y = delta_y, | ||
| ) | ||
| return IOM.DNMDTBilinearConfig(; depth) | ||
| else | ||
| error( | ||
| "Unsupported bilinear approximation \"$(method)\". " * | ||
| "Supported: \"bin2\", \"hybs\", \"nmdt\", \"dnmdt\", \"none\".", | ||
| ) | ||
| end | ||
| end | ||
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
Oops, something went wrong.
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.