Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions scripts/coverage/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[deps]
Coverage = "a2441757-f6aa-5fb2-8edb-039e3f45d037"
CoverageTools = "c36e975a-824b-4404-a568-ef97ca766997"

[compat]
Coverage = "1"
CoverageTools = "1"
2 changes: 1 addition & 1 deletion scripts/generate_lcov.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#
# Usage:
# 1. Run tests with coverage: julia --project=. -e 'using TestEnv; TestEnv.activate(); include("test/load_tests.jl"); InfrastructureOptimizationModelsTests.run_tests()'
# 2. Generate lcov: julia --project=. -e 'using TestEnv; TestEnv.activate(); include("scripts/generate_lcov.jl")'
# 2. Generate lcov: julia --project=scripts/coverage -e 'using Pkg; Pkg.instantiate(); include("scripts/generate_lcov.jl")'

using CoverageTools
using Coverage
Expand Down
6 changes: 2 additions & 4 deletions scripts/test_with_coverage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ julia --project=. --code-coverage -e '
'

echo "==> Generating lcov.info..."
julia --project=. -e '
using TestEnv; TestEnv.activate()
include("scripts/generate_lcov.jl")
'
# Coverage.jl caps HTTP at 1.x while the OpenAPI packages need 2.x, so it has its own env.
julia --project=scripts/coverage -e 'using Pkg; Pkg.instantiate(); include("scripts/generate_lcov.jl")'

echo "==> Done. lcov.info written to $(pwd)/lcov.info"
41 changes: 27 additions & 14 deletions src/utils/component_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,22 @@ end
########### Cost Function Utilities ##############
##################################################

"""
_system_base_ratio(unit_system, system_base_power, device_base_power) -> Float64

The x-axis ratio `x_from = ratio * x_su` from `unit_system` to the system base, the
base arithmetic `IS.convert_cost_coefficient` no longer resolves itself.
"""
_system_base_ratio(::IS.SystemBaseUnit, ::Float64, ::Float64) = 1.0
_system_base_ratio(
::IS.ComponentBaseUnit,
system_base_power::Float64,
device_base_power::Float64,
) =
system_base_power / device_base_power
_system_base_ratio(::IS.NaturalUnit, system_base_power::Float64, ::Float64) =
system_base_power

"""
Proportional (slope) cost coefficient normalized to system base.
"""
Expand All @@ -82,8 +98,8 @@ get_proportional_cost_per_system_unit(
system_base_power::Float64,
device_base_power::Float64,
) = IS.convert_cost_coefficient(
cost_term, unit_system, IS.SU,
system_base_power, device_base_power,
cost_term,
_system_base_ratio(unit_system, system_base_power, device_base_power),
)

"""
Expand All @@ -95,8 +111,9 @@ get_quadratic_cost_per_system_unit(
system_base_power::Float64,
device_base_power::Float64,
) = IS.convert_cost_coefficient(
cost_term, unit_system, IS.SU,
system_base_power, device_base_power, 2,
cost_term,
_system_base_ratio(unit_system, system_base_power, device_base_power),
2,
)

"""
Expand All @@ -110,8 +127,9 @@ function get_piecewise_pointcurve_per_system_unit(
device_base_power::Float64,
)
x_ratio = IS.convert_cost_coefficient(
1.0, unit_system, IS.SU,
system_base_power, device_base_power, -1,
1.0,
_system_base_ratio(unit_system, system_base_power, device_base_power),
-1,
)
points = cost_component.points
points_normalized = similar(points)
Expand Down Expand Up @@ -165,14 +183,9 @@ function get_piecewise_curve_per_system_unit(
system_base_power::Float64,
device_base_power::Float64,
)
x_ratio = IS.convert_cost_coefficient(
1.0, unit_system, IS.SU,
system_base_power, device_base_power, -1,
)
y_ratio = IS.convert_cost_coefficient(
1.0, unit_system, IS.SU,
system_base_power, device_base_power, 1,
)
ratio = _system_base_ratio(unit_system, system_base_power, device_base_power)
x_ratio = IS.convert_cost_coefficient(1.0, ratio, -1)
y_ratio = IS.convert_cost_coefficient(1.0, ratio, 1)
return x_coords .* x_ratio, y_coords .* y_ratio
end

Expand Down
1 change: 1 addition & 0 deletions test/InfrastructureOptimizationModelsTests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ function run_tests()
# --- objective_function/ subfolder ---
# import_export.jl: commented out
include(joinpath(TEST_DIR, "test_cost_term_helpers.jl"))
include(joinpath(TEST_DIR, "test_cost_unit_conversion.jl"))
include(joinpath(TEST_DIR, "test_linear_curve.jl"))
# value_curve_cost.jl: needs more work
include(joinpath(TEST_DIR, "test_piecewise_linear.jl"))
Expand Down
2 changes: 0 additions & 2 deletions test/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
ArgParse = "c7e460c6-2fb9-53a9-8c5b-16f535851c63"
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
Coverage = "a2441757-f6aa-5fb2-8edb-039e3f45d037"
CoverageTools = "c36e975a-824b-4404-a568-ef97ca766997"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
DataFramesMeta = "1313f7d8-7da2-5740-9ea0-a2ca25f37964"
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
Expand Down
97 changes: 97 additions & 0 deletions test/test_cost_unit_conversion.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
"""
Unit tests for the cost-coefficient base conversions in src/utils/component_utils.jl.
`IS.convert_cost_coefficient` takes a bare x-axis ratio; the helpers derive it from the
curve's unit system and the two base powers.
"""

@testset "Cost coefficient conversion to system base" begin
system_base = 100.0
device_base = 20.0

@testset "proportional term" begin
@test IOM.get_proportional_cost_per_system_unit(
3.0,
IS.SU,
system_base,
device_base,
) == 3.0
# \$/MW -> \$/(system pu MW): one system pu is 100 MW
@test IOM.get_proportional_cost_per_system_unit(
3.0,
IS.NU,
system_base,
device_base,
) == 300.0
# \$/(device pu MW) -> \$/(system pu MW): one system pu is five device pu
@test IOM.get_proportional_cost_per_system_unit(
3.0,
IS.CU,
system_base,
device_base,
) == 15.0
end

@testset "quadratic term scales with the square of the ratio" begin
@test IOM.get_quadratic_cost_per_system_unit(
2.0,
IS.SU,
system_base,
device_base,
) == 2.0
@test IOM.get_quadratic_cost_per_system_unit(
2.0,
IS.NU,
system_base,
device_base,
) == 2.0e4
@test IOM.get_quadratic_cost_per_system_unit(
2.0,
IS.CU,
system_base,
device_base,
) == 50.0
end

@testset "point curve rescales x only" begin
curve = IS.PiecewiseLinearData([(x = 0.0, y = 0.0), (x = 20.0, y = 100.0)])
natural = IOM.get_piecewise_pointcurve_per_system_unit(
curve,
IS.NU,
system_base,
device_base,
)
@test IS.get_x_coords(natural) == [0.0, 0.2]
@test IS.get_y_coords(natural) == [0.0, 100.0]
device = IOM.get_piecewise_pointcurve_per_system_unit(
curve,
IS.CU,
system_base,
device_base,
)
@test IS.get_x_coords(device) == [0.0, 4.0]
@test IOM.get_piecewise_pointcurve_per_system_unit(
curve,
IS.SU,
system_base,
device_base,
) === curve
end

@testset "step curve rescales x down and y up" begin
curve = IS.PiecewiseStepData([0.0, 20.0], [5.0])
natural =
IOM.get_piecewise_curve_per_system_unit(curve, IS.NU, system_base, device_base)
@test IS.get_x_coords(natural) == [0.0, 0.2]
@test IS.get_y_coords(natural) == [500.0]
device =
IOM.get_piecewise_curve_per_system_unit(curve, IS.CU, system_base, device_base)
@test IS.get_x_coords(device) == [0.0, 4.0]
@test IS.get_y_coords(device) == [25.0]
@test IOM.get_piecewise_curve_per_system_unit(
curve,
IS.SU,
system_base,
device_base,
) === curve
end
end
Loading