From 7cf2e31fc1fcc86fef400b4e517ebada57fac414 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Feb 2026 16:34:21 +0000 Subject: [PATCH 1/8] Initial plan From 5a4cc59ad16240d91bc518b7dcf6932d54e886eb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Feb 2026 17:06:39 +0000 Subject: [PATCH 2/8] Handle zero-demand multipliers in TDR Co-authored-by: gschivley <10373332+gschivley@users.noreply.github.com> --- .../time_domain_reduction.jl | 9 +++++++-- test/test_time_domain_reduction.jl | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/time_domain_reduction/time_domain_reduction.jl b/src/time_domain_reduction/time_domain_reduction.jl index a349f24525..da0061729a 100644 --- a/src/time_domain_reduction/time_domain_reduction.jl +++ b/src/time_domain_reduction/time_domain_reduction.jl @@ -515,8 +515,13 @@ function get_demand_multipliers(ClusterOutputData, weighted_cluster_zone_sums[demandcol] += (W[m] / (TimestepsPerRepPeriod)) * cluster_zone_sums[m][demandcol] end - demand_mults[demandcol] = zone_sums[demandcol] / - weighted_cluster_zone_sums[demandcol] + if iszero(weighted_cluster_zone_sums[demandcol]) && + iszero(zone_sums[demandcol]) + demand_mults[demandcol] = 1.0 + else + demand_mults[demandcol] = zone_sums[demandcol] / + weighted_cluster_zone_sums[demandcol] + end if v println(demandcol, ": ", diff --git a/test/test_time_domain_reduction.jl b/test/test_time_domain_reduction.jl index 7a70df7425..95776556a3 100644 --- a/test/test_time_domain_reduction.jl +++ b/test/test_time_domain_reduction.jl @@ -3,6 +3,7 @@ module TestTDR import GenX import Test import JLD2, Clustering +import DataFrames include(joinpath(@__DIR__, "utilities.jl")) @@ -62,4 +63,19 @@ for file in filter(endswith(".csv"), readdir(TDR_Results_true)) Test.@test cmp_csv(joinpath(TDR_Results_test, file), joinpath(TDR_Results_true, file)) end +Test.@testset "Zero demand multiplier" begin + input_data = DataFrames.DataFrame(Demand_MW_z1 = zeros(2)) + cluster_output = DataFrames.DataFrame(Symbol(1) => zeros(2)) + demand_mults = GenX.get_demand_multipliers(cluster_output, + input_data, + [1], + [2.0], + [:Demand_MW_z1], + 2, + [:Demand_MW_z1, :GrpWeight], + 1, + 1) + Test.@test demand_mults[:Demand_MW_z1] == 1.0 +end + end # module TestTDR From 275beff95797da67f5fa85267e9318bdf963f326 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Feb 2026 17:11:25 +0000 Subject: [PATCH 3/8] Add normal-case TDR multiplier test Co-authored-by: gschivley <10373332+gschivley@users.noreply.github.com> --- test/test_time_domain_reduction.jl | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/test_time_domain_reduction.jl b/test/test_time_domain_reduction.jl index 95776556a3..43552c58ee 100644 --- a/test/test_time_domain_reduction.jl +++ b/test/test_time_domain_reduction.jl @@ -76,6 +76,19 @@ Test.@testset "Zero demand multiplier" begin 1, 1) Test.@test demand_mults[:Demand_MW_z1] == 1.0 + + input_data = DataFrames.DataFrame(Demand_MW_z1 = [1.0, 2.0]) + cluster_output = DataFrames.DataFrame(Symbol(1) => [0.5, 0.5]) + demand_mults = GenX.get_demand_multipliers(cluster_output, + input_data, + [1], + [2.0], + [:Demand_MW_z1], + 2, + [:Demand_MW_z1, :GrpWeight], + 1, + 1) + Test.@test demand_mults[:Demand_MW_z1] == 3.0 end end # module TestTDR From 9db4071fdb6d4b18f04e4b348d2fe897d2c739b1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Feb 2026 17:15:25 +0000 Subject: [PATCH 4/8] Clarify TDR multiplier tests Co-authored-by: gschivley <10373332+gschivley@users.noreply.github.com> --- test/test_time_domain_reduction.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/test_time_domain_reduction.jl b/test/test_time_domain_reduction.jl index 43552c58ee..1f29627af9 100644 --- a/test/test_time_domain_reduction.jl +++ b/test/test_time_domain_reduction.jl @@ -76,6 +76,7 @@ Test.@testset "Zero demand multiplier" begin 1, 1) Test.@test demand_mults[:Demand_MW_z1] == 1.0 + Test.@test !isnan(demand_mults[:Demand_MW_z1]) input_data = DataFrames.DataFrame(Demand_MW_z1 = [1.0, 2.0]) cluster_output = DataFrames.DataFrame(Symbol(1) => [0.5, 0.5]) @@ -88,7 +89,9 @@ Test.@testset "Zero demand multiplier" begin [:Demand_MW_z1, :GrpWeight], 1, 1) - Test.@test demand_mults[:Demand_MW_z1] == 3.0 + expected_multiplier = sum(input_data.Demand_MW_z1) / + ((2.0 / 2) * sum(cluster_output[!, Symbol(1)])) + Test.@test demand_mults[:Demand_MW_z1] == expected_multiplier end end # module TestTDR From fbbc4d5d616cbf4323e704779d067e511df88672 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Feb 2026 17:22:46 +0000 Subject: [PATCH 5/8] Add debug log for zero-demand multiplier Co-authored-by: gschivley <10373332+gschivley@users.noreply.github.com> --- .../time_domain_reduction.jl | 1 + test/test_time_domain_reduction.jl | 15 ++++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/time_domain_reduction/time_domain_reduction.jl b/src/time_domain_reduction/time_domain_reduction.jl index da0061729a..78012bea75 100644 --- a/src/time_domain_reduction/time_domain_reduction.jl +++ b/src/time_domain_reduction/time_domain_reduction.jl @@ -517,6 +517,7 @@ function get_demand_multipliers(ClusterOutputData, end if iszero(weighted_cluster_zone_sums[demandcol]) && iszero(zone_sums[demandcol]) + @debug "Zero demand detected; using neutral demand multiplier." demandcol demand_mults[demandcol] = 1.0 else demand_mults[demandcol] = zone_sums[demandcol] / diff --git a/test/test_time_domain_reduction.jl b/test/test_time_domain_reduction.jl index 1f29627af9..d9897df129 100644 --- a/test/test_time_domain_reduction.jl +++ b/test/test_time_domain_reduction.jl @@ -66,12 +66,14 @@ end Test.@testset "Zero demand multiplier" begin input_data = DataFrames.DataFrame(Demand_MW_z1 = zeros(2)) cluster_output = DataFrames.DataFrame(Symbol(1) => zeros(2)) + weights = [2.0] + timesteps = 2 demand_mults = GenX.get_demand_multipliers(cluster_output, input_data, [1], - [2.0], + weights, [:Demand_MW_z1], - 2, + timesteps, [:Demand_MW_z1, :GrpWeight], 1, 1) @@ -80,17 +82,20 @@ Test.@testset "Zero demand multiplier" begin input_data = DataFrames.DataFrame(Demand_MW_z1 = [1.0, 2.0]) cluster_output = DataFrames.DataFrame(Symbol(1) => [0.5, 0.5]) + weights = [2.0] + timesteps = 2 demand_mults = GenX.get_demand_multipliers(cluster_output, input_data, [1], - [2.0], + weights, [:Demand_MW_z1], - 2, + timesteps, [:Demand_MW_z1, :GrpWeight], 1, 1) expected_multiplier = sum(input_data.Demand_MW_z1) / - ((2.0 / 2) * sum(cluster_output[!, Symbol(1)])) + ((weights[1] / timesteps) * + sum(cluster_output[!, Symbol(1)])) Test.@test demand_mults[:Demand_MW_z1] == expected_multiplier end From 1edeefc1a8fb97406bcf5a8cadd1f60b56849804 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Feb 2026 17:24:35 +0000 Subject: [PATCH 6/8] Remove redundant TDR test assertion Co-authored-by: gschivley <10373332+gschivley@users.noreply.github.com> --- test/test_time_domain_reduction.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/test/test_time_domain_reduction.jl b/test/test_time_domain_reduction.jl index d9897df129..72ad94f505 100644 --- a/test/test_time_domain_reduction.jl +++ b/test/test_time_domain_reduction.jl @@ -78,7 +78,6 @@ Test.@testset "Zero demand multiplier" begin 1, 1) Test.@test demand_mults[:Demand_MW_z1] == 1.0 - Test.@test !isnan(demand_mults[:Demand_MW_z1]) input_data = DataFrames.DataFrame(Demand_MW_z1 = [1.0, 2.0]) cluster_output = DataFrames.DataFrame(Symbol(1) => [0.5, 0.5]) From 27ed86705f8532153b7d34da3ee29c3491f54d6d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Feb 2026 17:25:25 +0000 Subject: [PATCH 7/8] Handle zero clustered demand safely Co-authored-by: gschivley <10373332+gschivley@users.noreply.github.com> --- src/time_domain_reduction/time_domain_reduction.jl | 12 ++++++++---- test/test_time_domain_reduction.jl | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/time_domain_reduction/time_domain_reduction.jl b/src/time_domain_reduction/time_domain_reduction.jl index 78012bea75..ee3c3593c9 100644 --- a/src/time_domain_reduction/time_domain_reduction.jl +++ b/src/time_domain_reduction/time_domain_reduction.jl @@ -515,10 +515,14 @@ function get_demand_multipliers(ClusterOutputData, weighted_cluster_zone_sums[demandcol] += (W[m] / (TimestepsPerRepPeriod)) * cluster_zone_sums[m][demandcol] end - if iszero(weighted_cluster_zone_sums[demandcol]) && - iszero(zone_sums[demandcol]) - @debug "Zero demand detected; using neutral demand multiplier." demandcol - demand_mults[demandcol] = 1.0 + if iszero(weighted_cluster_zone_sums[demandcol]) + if iszero(zone_sums[demandcol]) + @debug "Zero demand detected; using neutral demand multiplier." demandcol + demand_mults[demandcol] = 1.0 + else + @warn "Zero clustered demand with nonzero total; using zero multiplier." demandcol + demand_mults[demandcol] = 0.0 + end else demand_mults[demandcol] = zone_sums[demandcol] / weighted_cluster_zone_sums[demandcol] diff --git a/test/test_time_domain_reduction.jl b/test/test_time_domain_reduction.jl index 72ad94f505..9625f615db 100644 --- a/test/test_time_domain_reduction.jl +++ b/test/test_time_domain_reduction.jl @@ -92,6 +92,7 @@ Test.@testset "Zero demand multiplier" begin [:Demand_MW_z1, :GrpWeight], 1, 1) + # Mirror the demand multiplier formula to validate expected scaling. expected_multiplier = sum(input_data.Demand_MW_z1) / ((weights[1] / timesteps) * sum(cluster_output[!, Symbol(1)])) From d19a5d14a7213041e86336c2508c0eaca440c377 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Feb 2026 17:25:50 +0000 Subject: [PATCH 8/8] Rename demand multiplier test set Co-authored-by: gschivley <10373332+gschivley@users.noreply.github.com> --- test/test_time_domain_reduction.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_time_domain_reduction.jl b/test/test_time_domain_reduction.jl index 9625f615db..eafebbc9f7 100644 --- a/test/test_time_domain_reduction.jl +++ b/test/test_time_domain_reduction.jl @@ -63,7 +63,7 @@ for file in filter(endswith(".csv"), readdir(TDR_Results_true)) Test.@test cmp_csv(joinpath(TDR_Results_test, file), joinpath(TDR_Results_true, file)) end -Test.@testset "Zero demand multiplier" begin +Test.@testset "Demand multiplier edge cases" begin input_data = DataFrames.DataFrame(Demand_MW_z1 = zeros(2)) cluster_output = DataFrames.DataFrame(Symbol(1) => zeros(2)) weights = [2.0]