From 3497b17377c73476144140924d628f44e9ef2212 Mon Sep 17 00:00:00 2001 From: Elaine Hale Date: Fri, 6 Dec 2024 15:31:34 -0700 Subject: [PATCH 1/7] Outputting total_der, total_pv_only, and total_pv_stor tracking variables. --- src/agents/customer_group.jl | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/agents/customer_group.jl b/src/agents/customer_group.jl index 5b0d803..725f750 100644 --- a/src/agents/customer_group.jl +++ b/src/agents/customer_group.jl @@ -1684,10 +1684,30 @@ function save_results( ) save_param( customers.rho_DG_my.values, - [:Year, :CustomerType, :DERtech, :Zone, :Day, :Hour], + [:Year, :CustomerType, :DERTech, :Zone, :Day, :Hour], :MW, joinpath(export_file_path, "rho_DG_my.csv"), ) + + # Cumulative DER by Configuration + save_param( + total_der_capacity_my, + [:Year, :Zone, :CustomerType, :DERTech], + :MW, + joinpath(export_file_path, "total_der_capacity_my.csv"), + ) + save_param( + total_pv_only_capacity_my, + [:Year, :Zone, :CustomerType, :DERTech], + :MW, + joinpath(export_file_path, "total_pv_only_capacity_my.csv"), + ) + save_param( + total_pv_stor_capacity_my, + [:Year, :Zone, :CustomerType, :DERTech], + :MW, + joinpath(export_file_path, "total_pv_stor_capacity_my.csv"), + ) end From d1d4b144ede22dc7f9362908240336f0548e1283 Mon Sep 17 00:00:00 2001 From: Elaine Hale Date: Sat, 7 Dec 2024 22:02:03 -0700 Subject: [PATCH 2/7] Adding customer financial, VPP revenue, and emissions outputs. --- script/configs/template.yaml | 1 + src/agents/customer_group.jl | 134 ++++++++++++++++++++++++++++++++--- src/agents/der_aggregator.jl | 9 ++- src/agents/ipp_group.jl | 56 ++++++++++++++- src/agents/utility.jl | 27 +++++++ 5 files changed, 214 insertions(+), 13 deletions(-) diff --git a/script/configs/template.yaml b/script/configs/template.yaml index af2f9a5..b2ba9d6 100644 --- a/script/configs/template.yaml +++ b/script/configs/template.yaml @@ -4,6 +4,7 @@ data_selection: # Specify the path to the inputs for the model. If using HolisticElectricityModelData.jl, it should point to the test case folder under runs/. + # If on Windows, enter paths like "C:\\projects\\HolisticElectricityModelData.jl\\runs\\..." input_path: "../HolisticElectricityModelData.jl/runs/ba_6_base_2020_future_15_ipps_1/" # ------------------------------------------------------------------------------ diff --git a/src/agents/customer_group.jl b/src/agents/customer_group.jl index 725f750..f8aa69e 100644 --- a/src/agents/customer_group.jl +++ b/src/agents/customer_group.jl @@ -220,6 +220,29 @@ mutable struct CustomerGroup <: AbstractCustomerGroup "Cumulative PV plus Storage capacity" total_pv_stor_capacity_my::ParamArray + "Per customer annual utility bill prior to DER" + Payment_before_PVStor_my::ParamArray + "Per customer annual utility bill after adding solar plus storage" + Payment_after_PVStor_my::ParamArray + "Per customer annual VPP aggregation incentive" + PVStor_DERA_incentive_my::ParamArray + "Per customer annual FOM cost if have solar plus storage" + PVStor_FOM_my::ParamArray + "Per customer annual net profit from owning solar plus storage. Does not account for capital costs." + NetProfit_PVStor_my::ParamArray + + "Per customer annual utility bill after adding standalone PV" + Payment_after_PVOnly_my::ParamArray + "Per customer annual FOM cost if have solar" + PVOnly_FOM_my::ParamArray + "Per customer annual net profit from owning standalone PV. Does not account for capital costs." + NetProfit_PVOnly_my::ParamArray + + "Per customer capital costs for solar plus storage. Includes ITC." + FinalCapEx_PVStor_my::ParamArray + "Per customer capital costs for standalone PV. Includes ITC." + FinalCapEx_PVOnly_my::ParamArray + "Cumulative DER capacity, total PV and storage regardless of how they are grouped" total_der_capacity_my_delay_update::ParamArray "Cumulative PV only capacity" @@ -611,6 +634,16 @@ function CustomerGroup(input_filename::AbstractString, model_data::HEMData; id = initialize_param("total_der_capacity_my",model_data.index_y, model_data.index_z, model_data.index_h, index_m), initialize_param("total_pv_only_capacity_my",model_data.index_y, model_data.index_z, model_data.index_h, index_m), initialize_param("total_pv_stor_capacity_my",model_data.index_y, model_data.index_z, model_data.index_h, index_m), + initialize_param("Payment_before_PVStor_my", model_data.index_y, model_data.index_z, model_data.index_h), + initialize_param("Payment_after_PVStor_my", model_data.index_y, model_data.index_z, model_data.index_h), + initialize_param("PVStor_DERA_incentive_my", model_data.index_y, model_data.index_z, model_data.index_h), + initialize_param("PVStor_FOM_my", model_data.index_y, model_data.index_z, model_data.index_h), + initialize_param("NetProfit_PVStor_my", model_data.index_y, model_data.index_z, model_data.index_h), + initialize_param("Payment_after_PVOnly_my", model_data.index_y, model_data.index_z, model_data.index_h), + initialize_param("PVOnly_FOM_my", model_data.index_y, model_data.index_z, model_data.index_h), + initialize_param("NetProfit_PVOnly_my", model_data.index_y, model_data.index_z, model_data.index_h), + initialize_param("FinalCapEx_PVStor_my", model_data.index_y, model_data.index_z, model_data.index_h), + initialize_param("FinalCapEx_PVOnly_my", model_data.index_y, model_data.index_z, model_data.index_h), initialize_param("total_der_capacity_my_delay_update",model_data.index_y, model_data.index_z, model_data.index_h, index_m), initialize_param("total_pv_only_capacity_my_delay_update",model_data.index_y, model_data.index_z, model_data.index_h, index_m), initialize_param("total_pv_stor_capacity_my_delay_update",model_data.index_y, model_data.index_z, model_data.index_h, index_m), @@ -1098,16 +1131,16 @@ function solve_agent_problem!( der_aggregator.incentive_level(reg_year_index_dera, z) * customers.Opti_DG(z, h, :BTMStorage) * der_aggregator.aggregation_level(reg_year_index_dera, z) - # cost of distributed generation sum(customers.FOM_DG(z, h, m) * customers.Opti_DG(z, h, m) for m in customers.index_m) - end - + end # Calculate payback period of DPV-only # The NetProfit represents the energy saving/credit per representative agent per DER technology, # assuming the optimal DER technology size + Payment_after_PVOnly = make_keyed_array(model_data.index_z, model_data.index_h) NetProfit_PV_only = make_keyed_array(model_data.index_z, model_data.index_h) for z in model_data.index_z, h in model_data.index_h - # value of distributed generation (offset load) - NetProfit_PV_only(z, h, :) .= + Payment_after_PVOnly(z, h, :) .= + # value of distributed generation (offset load) sum( model_data.omega(d) * delta_t * regulator.p(z, h, d, t) * @@ -1125,11 +1158,34 @@ function solve_agent_problem!( customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG(z, h, :BTMPV) - customers.d(h, z, d, t) * (1 - utility.loss_dist), ) for d in model_data.index_d, t in model_data.index_t - ) - + ) + NetProfit_PV_only(z, h, :) .= Payment_after_PVOnly(z, h) - # cost of distributed generation customers.FOM_DG(z, h, :BTMPV) * customers.Opti_DG(z, h, :BTMPV) end + # Save financial results + for z in model_data.index_z, h in model_data.index_h + customers.Payment_before_PVStor_my(reg_year_index, z, h, :) .= Payment_before_PVStor(z, h) + customers.Payment_after_PVStor_my(reg_year_index, z, h, :) .= Payment_after_PVStor(z, h) + customers.PVStor_DERA_incentive_my(reg_year_index, z, h, :) .= der_aggregator.incentive_level(reg_year_index_dera, z) * customers.Opti_DG(z, h, :BTMStorage) + customers.PVStor_FOM_my(reg_year_index, z, h, :) .= sum(customers.FOM_DG(z, h, m) * customers.Opti_DG(z, h, m) for m in customers.index_m) + customers.NetProfit_PVStor_my(reg_year_index, z, h, :) .= NetProfit_pv_stor(z, h) + + customers.Payment_after_PVOnly_my(reg_year_index, z, h, :) .= Payment_after_PVOnly(z, h) + customers.PVOnly_FOM_my(reg_year_index, z, h, :) .= customers.FOM_DG(z, h, :BTMPV) * customers.Opti_DG(z, h, :BTMPV) + customers.NetProfit_PVOnly_my(reg_year_index, z, h, :) .= NetProfit_PV_only(z, h) + + customers.FinalCapEx_PVStor_my(reg_year_index, z, h, :) .= sum( + (1.0 - customers.ITC_DER(m)) * customers.CapEx_DG(z, h, m) * customers.Opti_DG(z, h, m) + for m in customers.index_m + ) + customers.FinalCapEx_PVOnly_my(reg_year_index, z, h, :) .= ( + (1.0 - customers.ITC_DER(:BTMPV)) * customers.CapEx_DG(z, h, :BTMPV) * + customers.Opti_DG(z, h, :BTMPV) + ) + end + for z in model_data.index_z, h in model_data.index_h if customer_opts isa CustomerOptions{SolarPlusStorageOnly} if NetProfit_pv_stor(z, h) > 0.0 @@ -1691,23 +1747,85 @@ function save_results( # Cumulative DER by Configuration save_param( - total_der_capacity_my, + customers.total_der_capacity_my.values, [:Year, :Zone, :CustomerType, :DERTech], :MW, joinpath(export_file_path, "total_der_capacity_my.csv"), ) save_param( - total_pv_only_capacity_my, + customers.total_pv_only_capacity_my.values, [:Year, :Zone, :CustomerType, :DERTech], :MW, joinpath(export_file_path, "total_pv_only_capacity_my.csv"), ) save_param( - total_pv_stor_capacity_my, + customers.total_pv_stor_capacity_my.values, [:Year, :Zone, :CustomerType, :DERTech], :MW, joinpath(export_file_path, "total_pv_stor_capacity_my.csv"), ) + + # Financial Metrics + save_param( + customers.Payment_before_PVStor_my.values, + [:Year, :Zone, :CustomerType], + :dollars_per_yr, + joinpath(export_file_path, "Payment_before_PVStor_my"), + ) + save_param( + customers.Payment_after_PVStor_my.values, + [:Year, :Zone, :CustomerType], + :dollars_per_yr, + joinpath(export_file_path, "Payment_after_PVStor_my"), + ) + save_param( + customers.PVStor_DERA_incentive_my.values, + [:Year, :Zone, :CustomerType], + :dollars_per_yr, + joinpath(export_file_path, "PVStor_DERA_incentive_my"), + ) + save_param( + customers.PVStor_FOM_my.values, + [:Year, :Zone, :CustomerType], + :dollars_per_yr, + joinpath(export_file_path, "PVStor_FOM_my"), + ) + save_param( + customers.NetProfit_PVStor_my.values, + [:Year, :Zone, :CustomerType], + :dollars_per_yr, + joinpath(export_file_path, "NetProfit_PVStor_my"), + ) + save_param( + customers.Payment_after_PVOnly_my.values, + [:Year, :Zone, :CustomerType], + :dollars_per_yr, + joinpath(export_file_path, "Payment_after_PVOnly_my"), + ) + save_param( + customers.PVOnly_FOM_my.values, + [:Year, :Zone, :CustomerType], + :dollars_per_yr, + joinpath(export_file_path, "PVOnly_FOM_my"), + ) + save_param( + customers.NetProfit_PVOnly_my.values, + [:Year, :Zone, :CustomerType], + :dollars_per_yr, + joinpath(export_file_path, "NetProfit_PVOnly_my"), + ) + save_param( + customers.FinalCapEx_PVStor_my.values, + [:Year, :Zone, :CustomerType], + :dollars_per_yr, + joinpath(export_file_path, "FinalCapEx_PVStor_my"), + ) + save_param( + customers.FinalCapEx_PVOnly_my.values, + [:Year, :Zone, :CustomerType], + :dollars_per_yr, + joinpath(export_file_path, "FinalCapEx_PVOnly_my"), + ) end diff --git a/src/agents/der_aggregator.jl b/src/agents/der_aggregator.jl index 685edc7..4f04148 100644 --- a/src/agents/der_aggregator.jl +++ b/src/agents/der_aggregator.jl @@ -734,8 +734,7 @@ function solve_agent_problem!( # since we moved some BTM storage to transmission level, need to reduce the BTM net load accordingly (in bulk power system, regulator, customers (maybe?)). - return 0.0 - + return 0.0 end function save_results( @@ -769,4 +768,10 @@ function save_results( :aggregation_pv_mw, joinpath(export_file_path, "dera_aggregation_pv_mw.csv"), ) + save_param( + der_aggregator.revenue.values, + [:Year, :Zone], + :dollars_per_year, + joinpath(export_file_path, "dera_aggregation_revenue.csv"), + ) end diff --git a/src/agents/ipp_group.jl b/src/agents/ipp_group.jl index 9931032..ebbb7c7 100644 --- a/src/agents/ipp_group.jl +++ b/src/agents/ipp_group.jl @@ -213,6 +213,9 @@ mutable struct IPPGroup <: AbstractIPPGroup energy_C_my::ParamArray flow_my::ParamArray + # total emissions + total_emissions_my::ParamArray + Max_Net_Load_my_dict::Dict # McCormic bounds data @@ -814,6 +817,10 @@ function IPPGroup(input_filename::String, model_data::HEMData, id = DEFAULT_ID) model_data.index_d, model_data.index_t, ), + initialize_param( + "total_emissions_my", + model_data.index_y + ), Dict(), [], [], [], [], [], [], [], [], [], [], [], [], initialize_param("lower_level_duality_gap", model_data.index_y, value = 100.0), @@ -5093,7 +5100,7 @@ end function ipp_cap_save_results( WMDER_IPP, ipp, p_star, model_data, delta_t, - customers, der_aggregator, green_developer + customers, der_aggregator, green_developer, regulator ) cust_year = customers.current_year dera_year = der_aggregator.current_year @@ -5198,7 +5205,19 @@ function ipp_cap_save_results( ipp.flow_my(y, l, d, t, :) .= value.(WMDER_IPP[:flow][y, l, d, t]) end - + for y in model_data.index_y + ipp.total_emissions_my(y, :) .= sum( + model_data.omega(d) * delta_t * ( + sum( + ipp.y_E_my(y, p, k, z, d, t) * ipp.emission_rate_E_my(y, p, z, k) for + k in ipp.index_k_existing, p in ipp.index_p + ) + sum( + ipp.y_C_my(y, p, k, z, d, t) * ipp.emission_rate_C_my(y, p, z, k) for + k in ipp.index_k_new, p in ipp.index_p + ) + ) for z in model_data.index_z, d in model_data.index_d, t in model_data.index_t + ) * 0.000453592 + end ###### running MILP only ###### # UCAP_p_star_solution = Dict(y => @@ -5328,6 +5347,31 @@ function ipp_cap_save_results( ipp.ucap_total(y, :) .= UCAP_total(y) end + for y in model_data.index_y, + z in model_data.index_z + + der_aggregator.revenue(y, z, :) .= + # energy + sum( + model_data.omega(d) * delta_t * ipp.LMP_my(y, z, d, t) * ( + ipp.y_E_my(y, p, :dera_pv, z, d, t) + + ipp.discharge_E_my(y, p, :der_aggregator, z, d, t) - + ipp.charge_E_my(y, p, :der_aggregator, z, d, t) + ) for p in ipp.index_p, d in model_data.index_d, t in model_data.index_t + ) + + # capacity + sum( + ipp.capacity_price(y) * ( + ipp.capacity_credit_E_my(y, z, :dera_pv) * ipp.x_E_my(p, z, :dera_pv) + + ipp.capacity_credit_stor_E_my(y, z, :der_aggregator) * ipp.x_stor_E_my(p, z, :der_aggregator) + ) for p in ipp.index_p + ) + + # RECs + sum( + model_data.omega(d) * delta_t * regulator.REC(z, y) * ipp.y_E_my(y, p, :dera_pv, z, d, t) + for p in ipp.index_p, d in model_data.index_d, t in model_data.index_t + ) + end end function solve_agent_problem_ipp_cap( @@ -5478,7 +5522,7 @@ function solve_agent_problem_ipp_cap( ipp_cap_save_results( WMDER_IPP, ipp, p_star, model_data, delta_t, - customers, der_aggregator, green_developer + customers, der_aggregator, green_developer, regulator ) end @@ -5641,6 +5685,12 @@ function save_results( :Flow_MWh, joinpath(export_file_path, "flow.csv"), ) + save_param( + ipp.total_emissions_my.values, + [:Year], + :MetricTon_CO2, # TODO: Check units + joinpath(export_file_path, "total_emissions_my.csv"), + ) end function welfare_calculation!( diff --git a/src/agents/utility.jl b/src/agents/utility.jl index 40971eb..19d962a 100644 --- a/src/agents/utility.jl +++ b/src/agents/utility.jl @@ -212,6 +212,9 @@ mutable struct Utility <: AbstractUtility energy_C_my::ParamArray flow_my::ParamArray + # total emissions + total_emissions_my::ParamArray + Max_Net_Load_my_dict::Dict _obj_value::ParamScalar @@ -1015,6 +1018,10 @@ function Utility( model_data.index_d, model_data.index_t, ), + initialize_param( + "total_emissions_my", + model_data.index_y + ), Dict(), ParamScalar("_obj_value", 0.0, description = "objective value--use with caution") ) @@ -1820,6 +1827,20 @@ function solve_agent_problem!( utility.energy_C_my(y, s, z, d, t, :) .= value.(energy_C[y, s, z, d, t]) end + for y in model_data.index_y + utility.total_emissions_my(y, :) .= sum( + model_data.omega(d) * delta_t * ( + sum( + utility.y_E_my(y, k, z, d, t) * utility.emission_rate_E_my(y, z, k) for + k in utility.index_k_existing + ) + sum( + utility.y_C_my(y, k, z, d, t) * utility.emission_rate_C_my(y, z, k) for + k in utility.index_k_new + ) + ) for z in model_data.index_z, d in model_data.index_d, t in model_data.index_t + ) * 0.000453592 + end + utility.current_year = first(model_data.index_y) end @@ -1927,6 +1948,12 @@ function save_results( :Flow_MWh, joinpath(export_file_path, "flow.csv"), ) + save_param( + utility.total_emissions_my.values, + [:Year], + :MetricTon_CO2, # TODO: Check units + joinpath(export_file_path, "total_emissions_my.csv"), + ) end function welfare_calculation!( From 3d9848fcb71ab40191e51e55452a33bd67a21fd7 Mon Sep 17 00:00:00 2001 From: Elaine Hale Date: Sat, 7 Dec 2024 22:17:46 -0700 Subject: [PATCH 3/7] typo --- src/agents/ipp_group.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/agents/ipp_group.jl b/src/agents/ipp_group.jl index ebbb7c7..2fff4cf 100644 --- a/src/agents/ipp_group.jl +++ b/src/agents/ipp_group.jl @@ -5686,7 +5686,7 @@ function save_results( joinpath(export_file_path, "flow.csv"), ) save_param( - ipp.total_emissions_my.values, + ipps.total_emissions_my.values, [:Year], :MetricTon_CO2, # TODO: Check units joinpath(export_file_path, "total_emissions_my.csv"), From e8072227fccf2f50006983a35f20f6129241210a Mon Sep 17 00:00:00 2001 From: Elaine Hale Date: Sun, 8 Dec 2024 06:45:33 -0700 Subject: [PATCH 4/7] Forgot .csv extensions --- src/agents/customer_group.jl | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/agents/customer_group.jl b/src/agents/customer_group.jl index f8aa69e..e8b8fb1 100644 --- a/src/agents/customer_group.jl +++ b/src/agents/customer_group.jl @@ -1770,61 +1770,61 @@ function save_results( customers.Payment_before_PVStor_my.values, [:Year, :Zone, :CustomerType], :dollars_per_yr, - joinpath(export_file_path, "Payment_before_PVStor_my"), + joinpath(export_file_path, "Payment_before_PVStor_my.csv"), ) save_param( customers.Payment_after_PVStor_my.values, [:Year, :Zone, :CustomerType], :dollars_per_yr, - joinpath(export_file_path, "Payment_after_PVStor_my"), + joinpath(export_file_path, "Payment_after_PVStor_my.csv"), ) save_param( customers.PVStor_DERA_incentive_my.values, [:Year, :Zone, :CustomerType], :dollars_per_yr, - joinpath(export_file_path, "PVStor_DERA_incentive_my"), + joinpath(export_file_path, "PVStor_DERA_incentive_my.csv"), ) save_param( customers.PVStor_FOM_my.values, [:Year, :Zone, :CustomerType], :dollars_per_yr, - joinpath(export_file_path, "PVStor_FOM_my"), + joinpath(export_file_path, "PVStor_FOM_my.csv"), ) save_param( customers.NetProfit_PVStor_my.values, [:Year, :Zone, :CustomerType], :dollars_per_yr, - joinpath(export_file_path, "NetProfit_PVStor_my"), + joinpath(export_file_path, "NetProfit_PVStor_my.csv"), ) save_param( customers.Payment_after_PVOnly_my.values, [:Year, :Zone, :CustomerType], :dollars_per_yr, - joinpath(export_file_path, "Payment_after_PVOnly_my"), + joinpath(export_file_path, "Payment_after_PVOnly_my.csv"), ) save_param( customers.PVOnly_FOM_my.values, [:Year, :Zone, :CustomerType], :dollars_per_yr, - joinpath(export_file_path, "PVOnly_FOM_my"), + joinpath(export_file_path, "PVOnly_FOM_my.csv"), ) save_param( customers.NetProfit_PVOnly_my.values, [:Year, :Zone, :CustomerType], :dollars_per_yr, - joinpath(export_file_path, "NetProfit_PVOnly_my"), + joinpath(export_file_path, "NetProfit_PVOnly_my.csv"), ) save_param( customers.FinalCapEx_PVStor_my.values, [:Year, :Zone, :CustomerType], :dollars_per_yr, - joinpath(export_file_path, "FinalCapEx_PVStor_my"), + joinpath(export_file_path, "FinalCapEx_PVStor_my.csv"), ) save_param( customers.FinalCapEx_PVOnly_my.values, [:Year, :Zone, :CustomerType], :dollars_per_yr, - joinpath(export_file_path, "FinalCapEx_PVOnly_my"), + joinpath(export_file_path, "FinalCapEx_PVOnly_my.csv"), ) end From 189e750d808fd090f269098e32bf041bd8d14792 Mon Sep 17 00:00:00 2001 From: Elaine Hale Date: Thu, 26 Dec 2024 08:55:46 -0700 Subject: [PATCH 5/7] Fix calculation of Payment_after_PVOnly --- src/agents/customer_group.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/agents/customer_group.jl b/src/agents/customer_group.jl index e8b8fb1..a0f29c6 100644 --- a/src/agents/customer_group.jl +++ b/src/agents/customer_group.jl @@ -1139,7 +1139,7 @@ function solve_agent_problem!( Payment_after_PVOnly = make_keyed_array(model_data.index_z, model_data.index_h) NetProfit_PV_only = make_keyed_array(model_data.index_z, model_data.index_h) for z in model_data.index_z, h in model_data.index_h - Payment_after_PVOnly(z, h, :) .= + pvonly_savings = # value of distributed generation (offset load) sum( model_data.omega(d) * delta_t * @@ -1159,7 +1159,8 @@ function solve_agent_problem!( customers.d(h, z, d, t) * (1 - utility.loss_dist), ) for d in model_data.index_d, t in model_data.index_t ) - NetProfit_PV_only(z, h, :) .= Payment_after_PVOnly(z, h) - + Payment_after_PVOnly(z, h, :) .= Payment_before_PVStor(z, h) - pvonly_savings + NetProfit_PV_only(z, h, :) .= pvonly_savings - # cost of distributed generation customers.FOM_DG(z, h, :BTMPV) * customers.Opti_DG(z, h, :BTMPV) end From fea09cdb76744f568015b10ecfca8c15c55ee081 Mon Sep 17 00:00:00 2001 From: Nongchao Guo <43042596+Nongchao@users.noreply.github.com> Date: Thu, 2 Jan 2025 12:42:34 -0700 Subject: [PATCH 6/7] improve consistency of distribution loss treatment --- src/agents/customer_group.jl | 50 ++++---- src/agents/ipp_group.jl | 48 +++---- src/agents/regulator.jl | 238 +++++++++++++++++------------------ src/agents/utility.jl | 8 +- 4 files changed, 172 insertions(+), 172 deletions(-) diff --git a/src/agents/customer_group.jl b/src/agents/customer_group.jl index e8b8fb1..f2e014c 100644 --- a/src/agents/customer_group.jl +++ b/src/agents/customer_group.jl @@ -769,7 +769,7 @@ function solve_agent_problem!( model_data.omega(d) * delta_t * regulator.p(z, h, d, t) * min( - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), customers.rho_DG(h, m, z, d, t) * customers.Opti_DG(z, h, m), ) for d in model_data.index_d, t in model_data.index_t ) + @@ -780,7 +780,7 @@ function solve_agent_problem!( max( 0, customers.rho_DG(h, m, z, d, t) * customers.Opti_DG(z, h, m) - - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) for d in model_data.index_d, t in model_data.index_t ) - # cost of distributed generation @@ -911,7 +911,7 @@ function solve_agent_problem!( sum( model_data.omega(d) * delta_t * regulator.p(z, h, d, t) * - customers.d(h, z, d, t) * (1 - utility.loss_dist) for d in model_data.index_d, t in model_data.index_t + customers.d(h, z, d, t) / (1 + utility.loss_dist) for d in model_data.index_d, t in model_data.index_t ) end @@ -941,10 +941,10 @@ function solve_agent_problem!( end @objective(Customer_PV_Storage_Opti, Min, objective_function_dist) - # for net load balance constraints, need to convert things to kWh, otherwise customers.d(h, z, d, t) * (1 - utility.loss_dist) and + # for net load balance constraints, need to convert things to kWh, otherwise customers.d(h, z, d, t) / (1 + utility.loss_dist) and net_load_balance = (d, t) -> begin - (net_load[d, t] - customers.d(h, z, d, t) * (1 - utility.loss_dist) + (net_load[d, t] - customers.d(h, z, d, t) / (1 + utility.loss_dist) + customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG(z, h, :BTMPV) - stor_charge[d, t] + stor_discharge[d, t]) end @@ -1145,7 +1145,7 @@ function solve_agent_problem!( model_data.omega(d) * delta_t * regulator.p(z, h, d, t) * min( - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG(z, h, :BTMPV), ) for d in model_data.index_d, t in model_data.index_t ) + @@ -1156,7 +1156,7 @@ function solve_agent_problem!( max( 0, customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG(z, h, :BTMPV) - - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) for d in model_data.index_d, t in model_data.index_t ) NetProfit_PV_only(z, h, :) .= Payment_after_PVOnly(z, h) - @@ -1467,7 +1467,7 @@ function solve_agent_problem!( [ sum(GreenSubPerc(h) * ( - customers.d(h, t) * (1 - utility.loss_dist) * model_data.omega(t) * customers.gamma(h) - + customers.d(h, t) / (1 + utility.loss_dist) * model_data.omega(t) * customers.gamma(h) - sum( customers.rho_DG(h, m, t) * customers.x_DG_E_my(reg_year_index, h, m) * model_data.omega(t) for m in customers.index_m @@ -1563,7 +1563,7 @@ function solve_agent_problem!( model_data.omega(t) * regulator.p(h, t) * min( - customers.d(h, t) * (1 - utility.loss_dist), + customers.d(h, t) / (1 + utility.loss_dist), customers.rho_DG(h, m, t) * customers.Opti_DG(h, m), ) for t in model_data.index_t ) + @@ -1574,7 +1574,7 @@ function solve_agent_problem!( max( 0, customers.rho_DG(h, m, t) * customers.Opti_DG(h, m) - - customers.d(h, t) * (1 - utility.loss_dist), + customers.d(h, t) / (1 + utility.loss_dist), ) for t in model_data.index_t ) - # cost of distributed generation @@ -1671,7 +1671,7 @@ function solve_agent_problem!( [ sum(GreenSubPerc(h) * ( - customers.d(h, t) * (1 - utility.loss_dist) * model_data.omega(t) * customers.gamma(h) - + customers.d(h, t) / (1 + utility.loss_dist) * model_data.omega(t) * customers.gamma(h) - sum( customers.rho_DG(h, m, t) * customers.x_DG_E_my(reg_year_index, h, m) * model_data.omega(t) for m in customers.index_m @@ -1912,7 +1912,7 @@ function welfare_calculation!( model_data.omega(t) * regulator.p_my(y, h, t) * min( - customers.d_my(y, h, t) * (1 - utility.loss_dist), + customers.d_my(y, h, t) / (1 + utility.loss_dist), customers.rho_DG(h, m, t) * customers.Opti_DG_my(y, h, m), ) for t in model_data.index_t ) + @@ -1923,7 +1923,7 @@ function welfare_calculation!( max( 0, customers.rho_DG(h, m, t) * customers.Opti_DG_my(y, h, m) - - customers.d_my(y, h, t) * (1 - utility.loss_dist), + customers.d_my(y, h, t) / (1 + utility.loss_dist), ) for t in model_data.index_t ) - # cost of distributed generation @@ -1976,7 +1976,7 @@ function welfare_calculation!( model_data.omega(t) * regulator.p_my(y, h, t) * min( - customers.d_my(y, h, t) * (1 - utility.loss_dist), + customers.d_my(y, h, t) / (1 + utility.loss_dist), customers.rho_DG(h, m, t) * customers.Opti_DG_my(Symbol(Int(y_star)), h, m), ) for t in model_data.index_t @@ -1993,11 +1993,11 @@ function welfare_calculation!( model_data.omega(t) * regulator.p_my(y, h, t) * ( - customers.gamma(h) * customers.d_my(y, h, t) * (1 - utility.loss_dist) - + customers.gamma(h) * customers.d_my(y, h, t) / (1 + utility.loss_dist) - # savings from new DERs sum( min( - customers.d_my(y, h, t) * (1 - utility.loss_dist), + customers.d_my(y, h, t) / (1 + utility.loss_dist), customers.rho_DG(h, m, t) * customers.Opti_DG_my(Symbol(Int(y_star)), h, m), ) * customers.x_DG_new_my(Symbol(Int(y_star)), h, m) / @@ -2065,7 +2065,7 @@ function welfare_calculation!( for y in model_data.index_y_fix, h in model_data.index_h AverageBill_PerCustomer_my(y, h, :) .= AnnualBill_PerCustomer_my(y, h) / sum( - model_data.omega(t) * customers.d_my(y, h, t) * (1 - utility.loss_dist) for + model_data.omega(t) * customers.d_my(y, h, t) / (1 + utility.loss_dist) for t in model_data.index_t ) end @@ -2114,7 +2114,7 @@ function welfare_calculation!( max_sub(y, h, :) .= sum( ( - customers.d_my(y, h, t) * (1 - utility.loss_dist) * model_data.omega(t) * customers.gamma(h) - + customers.d_my(y, h, t) / (1 + utility.loss_dist) * model_data.omega(t) * customers.gamma(h) - sum( customers.rho_DG(h, m, t) * customers.x_DG_E_my(y, h, m) * model_data.omega(t) for m in customers.index_m @@ -2200,7 +2200,7 @@ function welfare_calculation!( model_data.omega(t) * regulator.p_my(y, h, t) * ( - customers.gamma(h) * customers.d_my(y, h, t) * (1 - utility.loss_dist) - + customers.gamma(h) * customers.d_my(y, h, t) / (1 + utility.loss_dist) - # green power subscribers are not paying the retail rates sum( utility.rho_C_my(j, t) * sum(green_developer.green_tech_buildout_my(Symbol(Int(y_symbol)), j, h) for y_symbol in @@ -2266,7 +2266,7 @@ function welfare_calculation!( # AverageBill_PerCustomer_my = Dict( # (y, h) => # AnnualBill_PerCustomer_my(y, h) / sum( - # model_data.omega(t) * customers.d_my(y, h, t) * (1 - utility.loss_dist) + # model_data.omega(t) * customers.d_my(y, h, t) / (1 + utility.loss_dist) # for t in model_data.index_t # ) for y in model_data.index_y_fix, h in model_data.index_h # ) @@ -2320,7 +2320,7 @@ function welfare_calculation!( model_data.omega(t) * regulator.p_my(y, h, t) * min( - customers.d_my(y, h, t) * (1 - utility.loss_dist), + customers.d_my(y, h, t) / (1 + utility.loss_dist), customers.rho_DG(h, m, t) * customers.Opti_DG_my(y, h, m), ) for t in model_data.index_t ) + @@ -2331,7 +2331,7 @@ function welfare_calculation!( max( 0, customers.rho_DG(h, m, t) * customers.Opti_DG_my(y, h, m) - - customers.d_my(y, h, t) * (1 - utility.loss_dist), + customers.d_my(y, h, t) / (1 + utility.loss_dist), ) for t in model_data.index_t ) - # cost of distributed generation @@ -2381,7 +2381,7 @@ function welfare_calculation!( max_sub(y, h, :) .= sum( ( - customers.d_my(y, h, t) * (1 - utility.loss_dist) * model_data.omega(t) * customers.gamma(h) - + customers.d_my(y, h, t) / (1 + utility.loss_dist) * model_data.omega(t) * customers.gamma(h) - sum( customers.rho_DG(h, m, t) * customers.x_DG_E_my(y, h, m) * model_data.omega(t) for m in customers.index_m @@ -2467,7 +2467,7 @@ function welfare_calculation!( model_data.omega(t) * regulator.p_my(y, h, t) * ( - customers.gamma(h) * customers.d_my(y, h, t) * (1 - utility.loss_dist) - + customers.gamma(h) * customers.d_my(y, h, t) / (1 + utility.loss_dist) - # green power subscribers are not paying the retail rates sum( utility.rho_C_my(j, t) * sum(green_developer.green_tech_buildout_my(Symbol(Int(y_symbol)), j, h) for y_symbol in @@ -2534,7 +2534,7 @@ function welfare_calculation!( # AverageBill_PerCustomer_my = Dict( # (y, h) => # AnnualBill_PerCustomer_my(y, h) / sum( - # model_data.omega(t) * customers.d_my(y, h, t) * (1 - utility.loss_dist) + # model_data.omega(t) * customers.d_my(y, h, t) / (1 + utility.loss_dist) # for t in model_data.index_t # ) for y in model_data.index_y_fix, h in model_data.index_h # ) diff --git a/src/agents/ipp_group.jl b/src/agents/ipp_group.jl index 2fff4cf..916be43 100644 --- a/src/agents/ipp_group.jl +++ b/src/agents/ipp_group.jl @@ -857,7 +857,7 @@ Lower level optimization results are used to set variable bounds for McCormick-e """ function ipp_cap_lower( ipp, ipp_opts, model_data, delta_t, window_length, - customers, der_aggregator, green_developer, solver + customers, der_aggregator, green_developer, utility, solver ) MPPDCMER_lower = get_new_jump_model(solver) @@ -950,13 +950,13 @@ function ipp_cap_lower( sum( customers.rho_DG(h, m, z, d, t) * customers.total_der_capacity_my_delay_update(y, z, h, m) for h in model_data.index_h, m in customers.index_m - ) - + ) * (1 + utility.loss_dist) - # remove aggregated behind-the-meter pv/storage generation/consumption since they're front-of-the-meter now sum( customers.rho_DG(h, m, z, d, t) * der_aggregator.aggregation_level(dera_year, z) * customers.total_pv_stor_capacity_my(cust_year, z, h, m) # this actually needs to be a delayed update as well, but all the if-else in customer_group function makes this difficult. However, as long as the initial capacity does not change year over year for the simulation period this is fine (such as in this case). for h in model_data.index_h, m in (:BTMStorage, :BTMPV) - ) + + ) * (1 + utility.loss_dist) + # green technology subscription at time t sum( ipp.rho_C_my(Symbol("ipp1"), j, z, d, t) * sum(green_developer.green_tech_buildout_my(Symbol(Int(y_symbol)), j, z, h) for y_symbol in @@ -1366,7 +1366,7 @@ Lower level dual optimization results are used to set variable bounds for McCorm """ function ipp_cap_lower_dual( ipp, ipp_opts, model_data, delta_t, window_length, - customers, der_aggregator, green_developer, solver + customers, der_aggregator, green_developer, utility, solver ) MPPDCMER_lower_dual = get_new_jump_model(solver) @@ -1473,12 +1473,12 @@ function ipp_cap_lower_dual( sum( customers.rho_DG(h, m, z, d, t) * customers.total_der_capacity_my_delay_update(y, z, h, m) for h in model_data.index_h, m in customers.index_m - ) + + ) * (1 + utility.loss_dist) + # remove aggregated behind-the-meter pv/storage generation/consumption since they're front-of-the-meter now sum( customers.rho_DG(h, m, z, d, t) * der_aggregator.aggregation_level(dera_year, z) * customers.total_pv_stor_capacity_my(cust_year, z, h, m) for h in model_data.index_h, m in (:BTMStorage, :BTMPV) - ) - + ) * (1 + utility.loss_dist) - # green technology subscription at time t sum( ipp.rho_C_my(Symbol("ipp1"), j, z, d, t) * sum(green_developer.green_tech_buildout_my(Symbol(Int(y_symbol)), j, z, h) for y_symbol in @@ -2111,7 +2111,7 @@ end function ipp_cap_upper( mcbnds, ipp, ipp_opts, p_star, model_data, delta_t, - regulator, customers, der_aggregator, green_developer; + regulator, customers, der_aggregator, green_developer, utility; max_build=500.0, constraint_scaling = 1.0 ) reg_year = regulator.current_year @@ -2404,12 +2404,12 @@ function ipp_cap_upper( sum( customers.rho_DG(h, m, z, d, t) * customers.total_der_capacity_my(cust_year, z, h, m) for h in model_data.index_h, m in customers.index_m - ) + + ) * (1 + utility.loss_dist) + # remove aggregated behind-the-meter pv/storage generation/consumption since they're front-of-the-meter now sum( customers.rho_DG(h, m, z, d, t) * der_aggregator.aggregation_level(dera_year, z) * customers.total_pv_stor_capacity_my(cust_year, z, h, m) for h in model_data.index_h, m in (:BTMStorage, :BTMPV) - ) + ) * (1 + utility.loss_dist) end fill!(ipp.Max_Net_Load_my, NaN) Max_Net_Load_my_dict = Dict() @@ -2632,12 +2632,12 @@ function ipp_cap_upper( sum( customers.rho_DG(h, m, z, d, t) * customers.total_der_capacity_my(cust_year, z, h, m) for h in model_data.index_h, m in customers.index_m - ) + + ) * (1 + utility.loss_dist) + # remove aggregated behind-the-meter pv/storage generation/consumption since they're front-of-the-meter now sum( customers.rho_DG(h, m, z, d, t) * der_aggregator.aggregation_level(dera_year, z) * customers.total_pv_stor_capacity_my(cust_year, z, h, m) for h in model_data.index_h, m in (:BTMStorage, :BTMPV) - ) - + ) * (1 + utility.loss_dist) - # green technology subscription at time t sum( ipp.rho_C_my(Symbol("ipp1"), j, z, d, t) * sum(green_developer.green_tech_buildout_my(Symbol(Int(y_symbol)), j, z, h) for y_symbol in @@ -3097,12 +3097,12 @@ function ipp_cap_upper( sum( customers.rho_DG(h, m, z, d, t) * customers.total_der_capacity_my(cust_year, z, h, m) for h in model_data.index_h, m in customers.index_m - ) - + ) * (1 + utility.loss_dist) - # remove aggregated behind-the-meter pv/storage generation/consumption since they're front-of-the-meter now sum( customers.rho_DG(h, m, z, d, t) * der_aggregator.aggregation_level(dera_year, z) * customers.total_pv_stor_capacity_my(cust_year, z, h, m) for h in model_data.index_h, m in (:BTMStorage, :BTMPV) - ) + + ) * (1 + utility.loss_dist) + # green technology subscription at time t sum( ipp.rho_C_my(Symbol("ipp1"), j, z, d, t) * sum(green_developer.green_tech_buildout_my(Symbol(Int(y_symbol)), j, z, h) for y_symbol in @@ -3857,12 +3857,12 @@ function ipp_cap_upper( sum( customers.rho_DG(h, m, z, d, t) * customers.total_der_capacity_my(cust_year, z, h, m) for h in model_data.index_h, m in customers.index_m - ) + + ) * (1 + utility.loss_dist) + # remove aggregated behind-the-meter pv/storage generation/consumption since they're front-of-the-meter now sum( customers.rho_DG(h, m, z, d, t) * der_aggregator.aggregation_level(dera_year, z) * customers.total_pv_stor_capacity_my(cust_year, z, h, m) for h in model_data.index_h, m in (:BTMStorage, :BTMPV) - ) - + ) * (1 + utility.loss_dist) - # green technology subscription at time t sum( ipp.rho_C_my(Symbol("ipp1"), j, z, d, t) * sum(green_developer.green_tech_buildout_my(Symbol(Int(y_symbol)), j, z, h) for y_symbol in @@ -4817,7 +4817,7 @@ end function ipp_calc_duality_gap( WMDER_IPP, ipp, p_star, model_data, delta_t, - customers, der_aggregator, green_developer + customers, der_aggregator, green_developer, utility ) cust_year = customers.current_year @@ -4920,12 +4920,12 @@ function ipp_calc_duality_gap( sum( customers.rho_DG(h, m, z, d, t) * customers.total_der_capacity_my(cust_year, z, h, m) for h in model_data.index_h, m in customers.index_m - ) + + ) * (1 + utility.loss_dist) + # remove aggregated behind-the-meter pv/storage generation/consumption since they're front-of-the-meter now sum( customers.rho_DG(h, m, z, d, t) * der_aggregator.aggregation_level(dera_year, z) * customers.total_pv_stor_capacity_my(cust_year, z, h, m) for h in model_data.index_h, m in (:BTMStorage, :BTMPV) - ) - + ) * (1 + utility.loss_dist) - # green technology subscription at time t sum( ipp.rho_C_my(Symbol("ipp1"), j, z, d, t) * sum(green_developer.green_tech_buildout_my(Symbol(Int(y_symbol)), j, z, h) for y_symbol in @@ -5385,7 +5385,7 @@ function solve_agent_problem_ipp_cap( window_length, jump_model ) - # utility = get_agent(Utility, agent_store) + utility = get_agent(Utility, agent_store) regulator = get_agent(Regulator, agent_store) customers = get_agent(CustomerGroup, agent_store) der_aggregator = get_agent(DERAggregator, agent_store) @@ -5448,7 +5448,7 @@ function solve_agent_problem_ipp_cap( solver = lower_level_solver[1] MPPDCMER_lower = ipp_cap_lower( ipp, ipp_opts, model_data, delta_t, window_length, - customers, der_aggregator, green_developer, solver + customers, der_aggregator, green_developer, utility, solver ) push!(jump_model, MPPDCMER_lower) if termination_status(MPPDCMER_lower) != OPTIMAL @@ -5456,7 +5456,7 @@ function solve_agent_problem_ipp_cap( solver = lower_level_solver[1] MPPDCMER_lower = ipp_cap_lower( ipp, ipp_opts, model_data, delta_t, window_length, - customers, der_aggregator, green_developer, solver + customers, der_aggregator, green_developer, utility, solver ) jump_model[end] = MPPDCMER_lower # if termination_status(MPPDCMER_lower) != OPTIMAL @@ -5473,7 +5473,7 @@ function solve_agent_problem_ipp_cap( solver = lower_level_solver[1] MPPDCMER_lower_dual = ipp_cap_lower_dual( ipp, ipp_opts, model_data, delta_t, window_length, - customers, der_aggregator, green_developer, solver + customers, der_aggregator, green_developer, utility, solver ) # jump_model[end] = MPPDCMER_lower_dual end @@ -5500,7 +5500,7 @@ function solve_agent_problem_ipp_cap( WMDER_IPP = ipp_cap_upper( mcbnds, ipp, ipp_opts, p_star, model_data, delta_t, - regulator, customers, der_aggregator, green_developer + regulator, customers, der_aggregator, green_developer, utility ) push!(jump_model, WMDER_IPP) @@ -5514,7 +5514,7 @@ function solve_agent_problem_ipp_cap( objective_value(WMDER_IPP) lower_level_duality_gap = ipp_calc_duality_gap( WMDER_IPP, ipp, p_star, model_data, delta_t, - customers, der_aggregator, green_developer + customers, der_aggregator, green_developer, utility ) if lower_level_duality_gap < ipp.lower_level_duality_gap(reg_year_index) diff --git a/src/agents/regulator.jl b/src/agents/regulator.jl index 32fb0ea..08cb846 100644 --- a/src/agents/regulator.jl +++ b/src/agents/regulator.jl @@ -785,16 +785,16 @@ function solve_agent_problem!( y in model_data.year(first(model_data.index_y_fix)):reg_year ) ) for h in model_data.index_h, m in customers.index_m, d in model_data.index_d, t in model_data.index_t - ) + + ) * (1 + utility.loss_dist) + # remove aggregated behind-the-meter storage/pv generation/consumption since they're front-of-the-meter now sum( model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) for h in model_data.index_h, d in model_data.index_d, t in model_data.index_t - ) + + ) * (1 + utility.loss_dist) + sum( model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) for h in model_data.index_h, d in model_data.index_d, t in model_data.index_t - ) - + ) * (1 + utility.loss_dist) - # green technology subscription sum( model_data.omega(d) * delta_t * utility.rho_C_my(j, z, d, t) * sum(green_developer.green_tech_buildout_my(Symbol(Int(y_symbol)), j, z, h) for y_symbol in @@ -826,16 +826,16 @@ function solve_agent_problem!( y in model_data.year(first(model_data.index_y_fix)):reg_year ) ) for h in model_data.index_h, m in customers.index_m, d in model_data.index_d, t in model_data.index_t - ) + + ) * (1 + utility.loss_dist) + # remove aggregated behind-the-meter storage/pv generation/consumption since they're front-of-the-meter now sum( model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) for h in model_data.index_h, d in model_data.index_d, t in model_data.index_t - ) + + ) * (1 + utility.loss_dist) + sum( model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) for h in model_data.index_h, d in model_data.index_d, t in model_data.index_t - ) - + ) * (1 + utility.loss_dist) - # green technology subscription sum( model_data.omega(d) * delta_t * utility.rho_C_my(j, z, d, t) * sum(green_developer.green_tech_buildout_my(Symbol(Int(y_symbol)), j, z, h) for y_symbol in @@ -863,14 +863,14 @@ function solve_agent_problem!( max( 0, customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_E(z, h, :BTMPV) - - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) * customers.x_DG_E_my(first(model_data.index_y), h, z, :BTMPV) / customers.Opti_DG_E(z, h, :BTMPV) + sum( max( 0, customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMPV) - - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) * customers.x_DG_new_my(Symbol(Int(y)), h, z, :BTMPV) / customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMPV) for y in model_data.year(first(model_data.index_y_fix)):reg_year @@ -879,7 +879,7 @@ function solve_agent_problem!( max( 0, customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_E(z, h, :BTMPV) - - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) * total_der_pv_capacity(z, h) / customers.Opti_DG_E(z, h, :BTMPV) ) @@ -893,14 +893,14 @@ function solve_agent_problem!( max( 0, sum(customers.rho_DG(h, m, z, d, t) * customers.Opti_DG_E(z, h, m) for m in customers.index_m) - - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) * customers.x_DG_E_my(first(model_data.index_y), h, z, :BTMStorage) / customers.Opti_DG_E(z, h, :BTMStorage) + sum( max( 0, sum(customers.rho_DG(h, m, z, d, t) * customers.Opti_DG_my(Symbol(Int(y)), z, h, m) for m in customers.index_m) - - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) * customers.x_DG_new_my(Symbol(Int(y)), h, z, :BTMStorage) / customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMStorage) for y in model_data.year(first(model_data.index_y_fix)):reg_year @@ -926,10 +926,10 @@ function solve_agent_problem!( y in model_data.year(first(model_data.index_y_fix)):reg_year ) ) for m in customers.index_m, d in model_data.index_d, t in model_data.index_t - ) + + ) * (1 + utility.loss_dist) + # remove aggregated behind-the-meter storage/pv generation/consumption since they're front-of-the-meter now - sum(model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) for d in model_data.index_d, t in model_data.index_t) + - sum(model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) for d in model_data.index_d, t in model_data.index_t) - + sum(model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) for d in model_data.index_d, t in model_data.index_t) * (1 + utility.loss_dist) + + sum(model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) for d in model_data.index_d, t in model_data.index_t) * (1 + utility.loss_dist) - # green technology subscription sum( model_data.omega(d) * delta_t * utility.rho_C_my(j, z, d, t) * sum(green_developer.green_tech_buildout_my(Symbol(Int(y_symbol)), j, z, h) for y_symbol in @@ -943,7 +943,7 @@ function solve_agent_problem!( net_demand_h_wo_loss(z, h, :) .= # Demand without loss sum( - customers.gamma(z, h) * model_data.omega(d) * delta_t * customers.d(h, z, d, t) * (1 - utility.loss_dist) for + customers.gamma(z, h) * model_data.omega(d) * delta_t * customers.d(h, z, d, t) / (1 + utility.loss_dist) for d in model_data.index_d, t in model_data.index_t ) - # DG @@ -958,13 +958,13 @@ function solve_agent_problem!( ( min( customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_E(z, h, :BTMPV), - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) * customers.x_DG_E_my(first(model_data.index_y), h, z, :BTMPV) / customers.Opti_DG_E(z, h, :BTMPV) + sum( min( customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMPV), - customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.d(h, z, d, t) / (1 + utility.loss_dist) ) * customers.x_DG_new_my(Symbol(Int(y)), h, z, :BTMPV) / customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMPV) for y in model_data.year(first(model_data.index_y_fix)):reg_year @@ -972,7 +972,7 @@ function solve_agent_problem!( # minus pv portion of pv_storage tech min( customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_E(z, h, :BTMPV), - customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.d(h, z, d, t) / (1 + utility.loss_dist) ) * total_der_pv_capacity(z, h) / customers.Opti_DG_E(z, h, :BTMPV) ) @@ -984,13 +984,13 @@ function solve_agent_problem!( ( min( sum(customers.rho_DG(h, m, z, d, t) * customers.Opti_DG_E(z, h, m) for m in customers.index_m), - customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.d(h, z, d, t) / (1 + utility.loss_dist) ) * customers.x_DG_E_my(first(model_data.index_y), h, z, :BTMStorage) / customers.Opti_DG_E(z, h, :BTMStorage) + sum( min( sum(customers.rho_DG(h, m, z, d, t) * customers.Opti_DG_my(Symbol(Int(y)), z, h, m) for m in customers.index_m), - customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.d(h, z, d, t) / (1 + utility.loss_dist) ) * customers.x_DG_new_my(Symbol(Int(y)), h, z, :BTMStorage) / customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMStorage) for y in model_data.year(first(model_data.index_y_fix)):reg_year @@ -1011,7 +1011,7 @@ function solve_agent_problem!( net_demand_wo_green_tech_h_wo_loss(z, h, :) .= # Demand with loss sum( - customers.gamma(z, h) * model_data.omega(d) * delta_t * customers.d(h, z, d, t) * (1 - utility.loss_dist) for + customers.gamma(z, h) * model_data.omega(d) * delta_t * customers.d(h, z, d, t) / (1 + utility.loss_dist) for d in model_data.index_d, t in model_data.index_t ) - # DG @@ -1025,13 +1025,13 @@ function solve_agent_problem!( ( min( customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_E(z, h, :BTMPV), - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) * customers.x_DG_E_my(first(model_data.index_y), h, z, :BTMPV) / customers.Opti_DG_E(z, h, :BTMPV) + sum( min( customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMPV), - customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.d(h, z, d, t) / (1 + utility.loss_dist) ) * customers.x_DG_new_my(Symbol(Int(y)), h, z, :BTMPV) / customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMPV) for y in model_data.year(first(model_data.index_y_fix)):reg_year @@ -1039,7 +1039,7 @@ function solve_agent_problem!( # minus pv portion of pv_storage tech min( customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_E(z, h, :BTMPV), - customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.d(h, z, d, t) / (1 + utility.loss_dist) ) * total_der_pv_capacity(z, h) / customers.Opti_DG_E(z, h, :BTMPV) ) @@ -1051,13 +1051,13 @@ function solve_agent_problem!( ( min( sum(customers.rho_DG(h, m, z, d, t) * customers.Opti_DG_E(z, h, m) for m in customers.index_m), - customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.d(h, z, d, t) / (1 + utility.loss_dist) ) * customers.x_DG_E_my(first(model_data.index_y), h, z, :BTMStorage) / customers.Opti_DG_E(z, h, :BTMStorage) + sum( min( sum(customers.rho_DG(h, m, z, d, t) * customers.Opti_DG_my(Symbol(Int(y)), z, h, m) for m in customers.index_m), - customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.d(h, z, d, t) / (1 + utility.loss_dist) ) * customers.x_DG_new_my(Symbol(Int(y)), h, z, :BTMStorage) / customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMStorage) for y in model_data.year(first(model_data.index_y_fix)):reg_year @@ -1148,16 +1148,16 @@ function solve_agent_problem!( y in model_data.year(first(model_data.index_y_fix)):reg_year ) ) for h in model_data.index_h, m in customers.index_m - ) + + ) * (1 + utility.loss_dist) + # remove aggregated behind-the-meter storage/pv generation/consumption since they're front-of-the-meter now sum( model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) for h in model_data.index_h - ) + + ) * (1 + utility.loss_dist) + sum( model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) for h in model_data.index_h - ) - + ) * (1 + utility.loss_dist) - # green technology subscription sum( model_data.omega(d) * delta_t * utility.rho_C_my(j, z, d, t) * sum(green_developer.green_tech_buildout_my(Symbol(Int(y_symbol)), j, z, h) for y_symbol in @@ -1195,16 +1195,16 @@ function solve_agent_problem!( y in model_data.year(first(model_data.index_y_fix)):reg_year ) ) for h in model_data.index_h, m in customers.index_m - ) + + ) * (1 + utility.loss_dist) + # remove aggregated behind-the-meter storage/pv generation/consumption since they're front-of-the-meter now sum( model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) for h in model_data.index_h - ) + + ) * (1 + utility.loss_dist) + sum( model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) for h in model_data.index_h - ) - + ) * (1 + utility.loss_dist) - # green technology subscription sum( model_data.omega(d) * delta_t * utility.rho_C_my(j, z, d, t) * sum(green_developer.green_tech_buildout_my(Symbol(Int(y_symbol)), j, z, h) for y_symbol in @@ -1259,14 +1259,14 @@ function solve_agent_problem!( max( 0, customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_E(z, h, :BTMPV) - - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) * customers.x_DG_E_my(first(model_data.index_y), h, z, :BTMPV) / customers.Opti_DG_E(z, h, :BTMPV) + sum( max( 0, customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMPV) - - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) * customers.x_DG_new_my(Symbol(Int(y)), h, z, :BTMPV) / customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMPV) for y in model_data.year(first(model_data.index_y_fix)):reg_year @@ -1275,7 +1275,7 @@ function solve_agent_problem!( max( 0, customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_E(z, h, :BTMPV) - - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) * total_der_pv_capacity(z, h) / customers.Opti_DG_E(z, h, :BTMPV) ) + @@ -1286,14 +1286,14 @@ function solve_agent_problem!( max( 0, sum(customers.rho_DG(h, m, z, d, t) * customers.Opti_DG_E(z, h, m) for m in customers.index_m) - - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) * customers.x_DG_E_my(first(model_data.index_y), h, z, :BTMStorage) / customers.Opti_DG_E(z, h, :BTMStorage) + sum( max( 0, sum(customers.rho_DG(h, m, z, d, t) * customers.Opti_DG_my(Symbol(Int(y)), z, h, m) for m in customers.index_m) - - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) * customers.x_DG_new_my(Symbol(Int(y)), h, z, :BTMStorage) / customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMStorage) for y in model_data.year(first(model_data.index_y_fix)):reg_year @@ -1322,10 +1322,10 @@ function solve_agent_problem!( y in model_data.year(first(model_data.index_y_fix)):reg_year ) ) for m in customers.index_m - ) + + ) * (1 + utility.loss_dist) + # remove aggregated behind-the-meter storage/pv generation/consumption since they're front-of-the-meter now - model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) + - model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) - + model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) * (1 + utility.loss_dist) + + model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) * (1 + utility.loss_dist) - # green technology subscription sum( model_data.omega(d) * delta_t * utility.rho_C_my(j, z, d, t) * sum(green_developer.green_tech_buildout_my(Symbol(Int(y_symbol)), j, z, h) for y_symbol in @@ -1345,7 +1345,7 @@ function solve_agent_problem!( net_demand_h_t_wo_loss_temp = net_demand_h_t_wo_loss_temp + # Demand without loss sum( - customers.gamma(z, h) * model_data.omega(d) * delta_t * customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.gamma(z, h) * model_data.omega(d) * delta_t * customers.d(h, z, d, t) / (1 + utility.loss_dist) ) - # DG # since this net demand is for rate calculation, we need to consider energy offset at the household level. @@ -1357,13 +1357,13 @@ function solve_agent_problem!( ( min( customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_E(z, h, :BTMPV), - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) * customers.x_DG_E_my(first(model_data.index_y), h, z, :BTMPV) / customers.Opti_DG_E(z, h, :BTMPV) + sum( min( customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMPV), - customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.d(h, z, d, t) / (1 + utility.loss_dist) ) * customers.x_DG_new_my(Symbol(Int(y)), h, z, :BTMPV) / customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMPV) for y in model_data.year(first(model_data.index_y_fix)):reg_year @@ -1371,7 +1371,7 @@ function solve_agent_problem!( # minus pv portion of pv_storage tech min( customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_E(z, h, :BTMPV), - customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.d(h, z, d, t) / (1 + utility.loss_dist) ) * total_der_pv_capacity(z, h) / customers.Opti_DG_E(z, h, :BTMPV) ) - @@ -1380,13 +1380,13 @@ function solve_agent_problem!( ( min( sum(customers.rho_DG(h, m, z, d, t) * customers.Opti_DG_E(z, h, m) for m in customers.index_m), - customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.d(h, z, d, t) / (1 + utility.loss_dist) ) * customers.x_DG_E_my(first(model_data.index_y), h, z, :BTMStorage) / customers.Opti_DG_E(z, h, :BTMStorage) + sum( min( sum(customers.rho_DG(h, m, z, d, t) * customers.Opti_DG_my(Symbol(Int(y)), z, h, m) for m in customers.index_m), - customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.d(h, z, d, t) / (1 + utility.loss_dist) ) * customers.x_DG_new_my(Symbol(Int(y)), h, z, :BTMStorage) / customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMStorage) for y in model_data.year(first(model_data.index_y_fix)):reg_year @@ -1419,10 +1419,10 @@ function solve_agent_problem!( y in model_data.year(first(model_data.index_y_fix)):reg_year ) ) for m in customers.index_m - ) + + ) * (1 + utility.loss_dist) + # remove aggregated behind-the-meter storage/pv generation/consumption since they're front-of-the-meter now - customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) + - customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) - + customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) * (1 + utility.loss_dist) + + customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) * (1 + utility.loss_dist) - # green technology subscription sum( utility.rho_C_my(j, z, d, t) * sum(green_developer.green_tech_buildout_my(Symbol(Int(y_symbol)), j, z, h) for y_symbol in @@ -1447,10 +1447,10 @@ function solve_agent_problem!( y in model_data.year(first(model_data.index_y_fix)):reg_year ) ) for m in customers.index_m - ) + + ) * (1 + utility.loss_dist) + # remove aggregated behind-the-meter storage/pv generation/consumption since they're front-of-the-meter now - customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) + - customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) + customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) * (1 + utility.loss_dist) + + customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) * (1 + utility.loss_dist) end # non-coincident peak load @@ -1716,16 +1716,16 @@ function solve_agent_problem!( y in model_data.year(first(model_data.index_y_fix)):reg_year ) ) for h in model_data.index_h, m in customers.index_m, d in model_data.index_d, t in model_data.index_t - ) + + ) * (1 + utility.loss_dist) + # remove aggregated behind-the-meter storage/pv generation/consumption since they're front-of-the-meter now sum( model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) for h in model_data.index_h, d in model_data.index_d, t in model_data.index_t - ) + + ) * (1 + utility.loss_dist) + sum( model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) for h in model_data.index_h, d in model_data.index_d, t in model_data.index_t - ) - + ) * (1 + utility.loss_dist) - # green technology subscription sum( model_data.omega(d) * delta_t * utility.rho_C_my(j, z, d, t) * sum(green_developer.green_tech_buildout_my(Symbol(Int(y_symbol)), j, z, h) for y_symbol in @@ -1757,16 +1757,16 @@ function solve_agent_problem!( y in model_data.year(first(model_data.index_y_fix)):reg_year ) ) for h in model_data.index_h, m in customers.index_m, d in model_data.index_d, t in model_data.index_t - ) + + ) * (1 + utility.loss_dist) + # remove aggregated behind-the-meter storage generation/consumption since they're front-of-the-meter now sum( model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) for h in model_data.index_h, d in model_data.index_d, t in model_data.index_t - ) + + ) * (1 + utility.loss_dist) + sum( model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) for h in model_data.index_h, d in model_data.index_d, t in model_data.index_t - ) - + ) * (1 + utility.loss_dist) - # green technology subscription sum( model_data.omega(d) * delta_t * utility.rho_C_my(j, z, d, t) * sum(green_developer.green_tech_buildout_my(Symbol(Int(y_symbol)), j, z, h) for y_symbol in @@ -1794,14 +1794,14 @@ function solve_agent_problem!( max( 0, customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_E(z, h, :BTMPV) - - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) * customers.x_DG_E_my(first(model_data.index_y), h, z, :BTMPV) / customers.Opti_DG_E(z, h, :BTMPV) + sum( max( 0, customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMPV) - - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) * customers.x_DG_new_my(Symbol(Int(y)), h, z, :BTMPV) / customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMPV) for y in model_data.year(first(model_data.index_y_fix)):reg_year @@ -1810,7 +1810,7 @@ function solve_agent_problem!( max( 0, customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_E(z, h, :BTMPV) - - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) * total_der_pv_capacity(z, h) / customers.Opti_DG_E(z, h, :BTMPV) ) @@ -1824,14 +1824,14 @@ function solve_agent_problem!( max( 0, sum(customers.rho_DG(h, m, z, d, t) * customers.Opti_DG_E(z, h, m) for m in customers.index_m) - - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) * customers.x_DG_E_my(first(model_data.index_y), h, z, :BTMStorage) / customers.Opti_DG_E(z, h, :BTMStorage) + sum( max( 0, sum(customers.rho_DG(h, m, z, d, t) * customers.Opti_DG_my(Symbol(Int(y)), z, h, m) for m in customers.index_m) - - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) * customers.x_DG_new_my(Symbol(Int(y)), h, z, :BTMStorage) / customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMStorage) for y in model_data.year(first(model_data.index_y_fix)):reg_year @@ -1857,10 +1857,10 @@ function solve_agent_problem!( y in model_data.year(first(model_data.index_y_fix)):reg_year ) ) for m in customers.index_m, d in model_data.index_d, t in model_data.index_t - ) + + ) * (1 + utility.loss_dist) + # remove aggregated behind-the-meter storage/pv generation/consumption since they're front-of-the-meter now - sum(model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) for d in model_data.index_d, t in model_data.index_t) + - sum(model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) for d in model_data.index_d, t in model_data.index_t) - + sum(model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) for d in model_data.index_d, t in model_data.index_t) * (1 + utility.loss_dist) + + sum(model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) for d in model_data.index_d, t in model_data.index_t) * (1 + utility.loss_dist) - # green technology subscription sum( model_data.omega(d) * delta_t * utility.rho_C_my(j, z, d, t) * sum(green_developer.green_tech_buildout_my(Symbol(Int(y_symbol)), j, z, h) for y_symbol in @@ -1874,7 +1874,7 @@ function solve_agent_problem!( net_demand_h_wo_loss(z, h, :) .= # Demand without loss sum( - customers.gamma(z, h) * model_data.omega(d) * delta_t * customers.d(h, z, d, t) * (1 - utility.loss_dist) for + customers.gamma(z, h) * model_data.omega(d) * delta_t * customers.d(h, z, d, t) / (1 + utility.loss_dist) for d in model_data.index_d, t in model_data.index_t ) - # DG @@ -1889,13 +1889,13 @@ function solve_agent_problem!( ( min( customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_E(z, h, :BTMPV), - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) * customers.x_DG_E_my(first(model_data.index_y), h, z, :BTMPV) / customers.Opti_DG_E(z, h, :BTMPV) + sum( min( customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMPV), - customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.d(h, z, d, t) / (1 + utility.loss_dist) ) * customers.x_DG_new_my(Symbol(Int(y)), h, z, :BTMPV) / customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMPV) for y in model_data.year(first(model_data.index_y_fix)):reg_year @@ -1903,7 +1903,7 @@ function solve_agent_problem!( # minus pv portion of pv_storage tech min( customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_E(z, h, :BTMPV), - customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.d(h, z, d, t) / (1 + utility.loss_dist) ) * total_der_pv_capacity(z, h) / customers.Opti_DG_E(z, h, :BTMPV) ) @@ -1915,13 +1915,13 @@ function solve_agent_problem!( ( min( sum(customers.rho_DG(h, m, z, d, t) * customers.Opti_DG_E(z, h, m) for m in customers.index_m), - customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.d(h, z, d, t) / (1 + utility.loss_dist) ) * customers.x_DG_E_my(first(model_data.index_y), h, z, :BTMStorage) / customers.Opti_DG_E(z, h, :BTMStorage) + sum( min( sum(customers.rho_DG(h, m, z, d, t) * customers.Opti_DG_my(Symbol(Int(y)), z, h, m) for m in customers.index_m), - customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.d(h, z, d, t) / (1 + utility.loss_dist) ) * customers.x_DG_new_my(Symbol(Int(y)), h, z, :BTMStorage) / customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMStorage) for y in model_data.year(first(model_data.index_y_fix)):reg_year @@ -1942,7 +1942,7 @@ function solve_agent_problem!( net_demand_wo_green_tech_h_wo_loss(z, h, :) .= # Demand with loss sum( - customers.gamma(z, h) * model_data.omega(d) * delta_t * customers.d(h, z, d, t) * (1 - utility.loss_dist) for + customers.gamma(z, h) * model_data.omega(d) * delta_t * customers.d(h, z, d, t) / (1 + utility.loss_dist) for d in model_data.index_d, t in model_data.index_t ) - # DG @@ -1956,13 +1956,13 @@ function solve_agent_problem!( ( min( customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_E(z, h, :BTMPV), - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) * customers.x_DG_E_my(first(model_data.index_y), h, z, :BTMPV) / customers.Opti_DG_E(z, h, :BTMPV) + sum( min( customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMPV), - customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.d(h, z, d, t) / (1 + utility.loss_dist) ) * customers.x_DG_new_my(Symbol(Int(y)), h, z, :BTMPV) / customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMPV) for y in model_data.year(first(model_data.index_y_fix)):reg_year @@ -1970,7 +1970,7 @@ function solve_agent_problem!( # minus pv portion of pv_storage tech min( customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_E(z, h, :BTMPV), - customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.d(h, z, d, t) / (1 + utility.loss_dist) ) * total_der_pv_capacity(z, h) / customers.Opti_DG_E(z, h, :BTMPV) ) @@ -1982,13 +1982,13 @@ function solve_agent_problem!( ( min( sum(customers.rho_DG(h, m, z, d, t) * customers.Opti_DG_E(z, h, m) for m in customers.index_m), - customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.d(h, z, d, t) / (1 + utility.loss_dist) ) * customers.x_DG_E_my(first(model_data.index_y), h, z, :BTMStorage) / customers.Opti_DG_E(z, h, :BTMStorage) + sum( min( sum(customers.rho_DG(h, m, z, d, t) * customers.Opti_DG_my(Symbol(Int(y)), z, h, m) for m in customers.index_m), - customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.d(h, z, d, t) / (1 + utility.loss_dist) ) * customers.x_DG_new_my(Symbol(Int(y)), h, z, :BTMStorage) / customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMStorage) for y in model_data.year(first(model_data.index_y_fix)):reg_year @@ -2034,16 +2034,16 @@ function solve_agent_problem!( y in model_data.year(first(model_data.index_y_fix)):reg_year ) ) for h in model_data.index_h, m in customers.index_m - ) + + ) * (1 + utility.loss_dist) + # remove aggregated behind-the-meter storage/pv generation/consumption since they're front-of-the-meter now sum( model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) for h in model_data.index_h - ) + + ) * (1 + utility.loss_dist) + sum( model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) for h in model_data.index_h - ) - + ) * (1 + utility.loss_dist) - # green technology subscription sum( model_data.omega(d) * delta_t * utility.rho_C_my(j, z, d, t) * sum(green_developer.green_tech_buildout_my(Symbol(Int(y_symbol)), j, z, h) for y_symbol in @@ -2081,16 +2081,16 @@ function solve_agent_problem!( y in model_data.year(first(model_data.index_y_fix)):reg_year ) ) for h in model_data.index_h, m in customers.index_m - ) + + ) * (1 + utility.loss_dist) + # remove aggregated behind-the-meter storage/pv generation/consumption since they're front-of-the-meter now sum( model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) for h in model_data.index_h - ) + + ) * (1 + utility.loss_dist) + sum( model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) for h in model_data.index_h - ) - + ) * (1 + utility.loss_dist) - # green technology subscription sum( model_data.omega(d) * delta_t * utility.rho_C_my(j, z, d, t) * sum(green_developer.green_tech_buildout_my(Symbol(Int(y_symbol)), j, z, h) for y_symbol in @@ -2145,14 +2145,14 @@ function solve_agent_problem!( max( 0, customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_E(z, h, :BTMPV) - - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) * customers.x_DG_E_my(first(model_data.index_y), h, z, :BTMPV) / customers.Opti_DG_E(z, h, :BTMPV) + sum( max( 0, customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMPV) - - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) * customers.x_DG_new_my(Symbol(Int(y)), h, z, :BTMPV) / customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMPV) for y in model_data.year(first(model_data.index_y_fix)):reg_year @@ -2161,7 +2161,7 @@ function solve_agent_problem!( max( 0, customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_E(z, h, :BTMPV) - - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) * total_der_pv_capacity(z, h) / customers.Opti_DG_E(z, h, :BTMPV) ) + @@ -2172,14 +2172,14 @@ function solve_agent_problem!( max( 0, sum(customers.rho_DG(h, m, z, d, t) * customers.Opti_DG_E(z, h, m) for m in customers.index_m) - - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) * customers.x_DG_E_my(first(model_data.index_y), h, z, :BTMStorage) / customers.Opti_DG_E(z, h, :BTMStorage) + sum( max( 0, sum(customers.rho_DG(h, m, z, d, t) * customers.Opti_DG_my(Symbol(Int(y)), z, h, m) for m in customers.index_m) - - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) * customers.x_DG_new_my(Symbol(Int(y)), h, z, :BTMStorage) / customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMStorage) for y in model_data.year(first(model_data.index_y_fix)):reg_year @@ -2228,10 +2228,10 @@ function solve_agent_problem!( y in model_data.year(first(model_data.index_y_fix)):reg_year ) ) for m in customers.index_m - ) + + ) * (1 + utility.loss_dist) + # remove aggregated behind-the-meter storage/pv generation/consumption since they're front-of-the-meter now - model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) + - model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) - + model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) * (1 + utility.loss_dist) + + model_data.omega(d) * delta_t * customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) * (1 + utility.loss_dist) - # green technology subscription sum( model_data.omega(d) * delta_t * utility.rho_C_my(j, z, d, t) * sum(green_developer.green_tech_buildout_my(Symbol(Int(y_symbol)), j, z, h) for y_symbol in @@ -2251,7 +2251,7 @@ function solve_agent_problem!( net_demand_h_t_wo_loss_temp = net_demand_h_t_wo_loss_temp + # Demand without loss sum( - customers.gamma(z, h) * model_data.omega(d) * delta_t * customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.gamma(z, h) * model_data.omega(d) * delta_t * customers.d(h, z, d, t) / (1 + utility.loss_dist) ) - # DG # since this net demand is for rate calculation, we need to consider energy offset at the household level. @@ -2264,13 +2264,13 @@ function solve_agent_problem!( ( min( customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_E(z, h, :BTMPV), - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) * customers.x_DG_E_my(first(model_data.index_y), h, z, :BTMPV) / customers.Opti_DG_E(z, h, :BTMPV) + sum( min( customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMPV), - customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.d(h, z, d, t) / (1 + utility.loss_dist) ) * customers.x_DG_new_my(Symbol(Int(y)), h, z, :BTMPV) / customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMPV) for y in model_data.year(first(model_data.index_y_fix)):reg_year @@ -2278,7 +2278,7 @@ function solve_agent_problem!( # minus pv portion of pv_storage tech min( customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_E(z, h, :BTMPV), - customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.d(h, z, d, t) / (1 + utility.loss_dist) ) * total_der_pv_capacity(z, h) / customers.Opti_DG_E(z, h, :BTMPV) ) - @@ -2287,13 +2287,13 @@ function solve_agent_problem!( ( min( sum(customers.rho_DG(h, m, z, d, t) * customers.Opti_DG_E(z, h, m) for m in customers.index_m), - customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.d(h, z, d, t) / (1 + utility.loss_dist) ) * customers.x_DG_E_my(first(model_data.index_y), h, z, :BTMStorage) / customers.Opti_DG_E(z, h, :BTMStorage) + sum( min( sum(customers.rho_DG(h, m, z, d, t) * customers.Opti_DG_my(Symbol(Int(y)), z, h, m) for m in customers.index_m), - customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.d(h, z, d, t) / (1 + utility.loss_dist) ) * customers.x_DG_new_my(Symbol(Int(y)), h, z, :BTMStorage) / customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMStorage) for y in model_data.year(first(model_data.index_y_fix)):reg_year @@ -2318,7 +2318,7 @@ function solve_agent_problem!( net_demand_wo_green_tech_h_t_wo_loss_temp = net_demand_wo_green_tech_h_t_wo_loss_temp + # Demand without loss sum( - customers.gamma(z, h) * model_data.omega(d) * delta_t * customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.gamma(z, h) * model_data.omega(d) * delta_t * customers.d(h, z, d, t) / (1 + utility.loss_dist) ) - # DG # since this net demand is for rate calculation, we need to consider energy offset at the household level. @@ -2331,13 +2331,13 @@ function solve_agent_problem!( ( min( customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_E(z, h, :BTMPV), - customers.d(h, z, d, t) * (1 - utility.loss_dist), + customers.d(h, z, d, t) / (1 + utility.loss_dist), ) * customers.x_DG_E_my(first(model_data.index_y), h, z, :BTMPV) / customers.Opti_DG_E(z, h, :BTMPV) + sum( min( customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMPV), - customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.d(h, z, d, t) / (1 + utility.loss_dist) ) * customers.x_DG_new_my(Symbol(Int(y)), h, z, :BTMPV) / customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMPV) for y in model_data.year(first(model_data.index_y_fix)):reg_year @@ -2345,7 +2345,7 @@ function solve_agent_problem!( # minus pv portion of pv_storage tech min( customers.rho_DG(h, :BTMPV, z, d, t) * customers.Opti_DG_E(z, h, :BTMPV), - customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.d(h, z, d, t) / (1 + utility.loss_dist) ) * total_der_pv_capacity(z, h) / customers.Opti_DG_E(z, h, :BTMPV) ) - @@ -2354,13 +2354,13 @@ function solve_agent_problem!( ( min( sum(customers.rho_DG(h, m, z, d, t) * customers.Opti_DG_E(z, h, m) for m in customers.index_m), - customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.d(h, z, d, t) / (1 + utility.loss_dist) ) * customers.x_DG_E_my(first(model_data.index_y), h, z, :BTMStorage) / customers.Opti_DG_E(z, h, :BTMStorage) + sum( min( sum(customers.rho_DG(h, m, z, d, t) * customers.Opti_DG_my(Symbol(Int(y)), z, h, m) for m in customers.index_m), - customers.d(h, z, d, t) * (1 - utility.loss_dist) + customers.d(h, z, d, t) / (1 + utility.loss_dist) ) * customers.x_DG_new_my(Symbol(Int(y)), h, z, :BTMStorage) / customers.Opti_DG_my(Symbol(Int(y)), z, h, :BTMStorage) for y in model_data.year(first(model_data.index_y_fix)):reg_year @@ -2386,10 +2386,10 @@ function solve_agent_problem!( y in model_data.year(first(model_data.index_y_fix)):reg_year ) ) for m in customers.index_m - ) + + ) * (1 + utility.loss_dist) + # remove aggregated behind-the-meter storage/pv generation/consumption since they're front-of-the-meter now - customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) + - customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) - + customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) * (1 + utility.loss_dist) + + customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) * (1 + utility.loss_dist) - # green technology subscription # if customer h in zone z build green tech, that should be able to offest their capacity purchase obligation sum( @@ -2415,10 +2415,10 @@ function solve_agent_problem!( y in model_data.year(first(model_data.index_y_fix)):reg_year ) ) for m in customers.index_m - ) + + ) * (1 + utility.loss_dist) + # remove aggregated behind-the-meter storage/pv generation/consumption since they're front-of-the-meter now - customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) + - customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) + customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) * (1 + utility.loss_dist) + + customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) * (1 + utility.loss_dist) end # non-coincident peak load @@ -2448,10 +2448,10 @@ function solve_agent_problem!( y in model_data.year(first(model_data.index_y_fix)):reg_year ) for m in customers.index_m - ) + + ) * (1 + utility.loss_dist) + # remove aggregated behind-the-meter storage/pv generation/consumption since they're front-of-the-meter now - customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) + - customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) + customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) * (1 + utility.loss_dist) + + customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) * (1 + utility.loss_dist) end energy_purchase_quantity_detailed = make_keyed_array(model_data.index_z, model_data.index_d, model_data.index_t) @@ -2491,10 +2491,10 @@ function solve_agent_problem!( y in model_data.year(first(model_data.index_y_fix)):reg_year ) for m in customers.index_m - ) + + ) * (1 + utility.loss_dist) + # remove aggregated behind-the-meter storage/pv generation/consumption since they're front-of-the-meter now - customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) + - customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) + customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) * (1 + utility.loss_dist) + + customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) * (1 + utility.loss_dist) ) end local_net_load_tou(z, h, tou, :) .= local_net_load_tou_temp @@ -2520,10 +2520,10 @@ function solve_agent_problem!( y in model_data.year(first(model_data.index_y_fix)):reg_year ) for m in customers.index_m - ) + + ) * (1 + utility.loss_dist) + # remove aggregated behind-the-meter storage/pv generation/consumption since they're front-of-the-meter now - customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) + - customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) + customers.rho_DG(h, :BTMStorage, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_stor_capacity(z, h) * (1 + utility.loss_dist) + + customers.rho_DG(h, :BTMPV, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * total_der_pv_capacity(z, h) * (1 + utility.loss_dist) ) for h in model_data.index_h ) ) + diff --git a/src/agents/utility.jl b/src/agents/utility.jl index 69e4313..6a3dc71 100644 --- a/src/agents/utility.jl +++ b/src/agents/utility.jl @@ -1153,12 +1153,12 @@ function solve_agent_problem!( sum( customers.rho_DG(h, m, z, d, t) * customers.total_der_capacity_my(y, z, h, m) for h in model_data.index_h, m in customers.index_m - ) + + ) * (1 + utility.loss_dist) + # remove aggregated behind-the-meter pv/storage generation/consumption since they're front-of-the-meter now sum( customers.rho_DG(h, m, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * customers.total_pv_stor_capacity_my(y, z, h, m) for h in model_data.index_h, m in (:BTMStorage, :BTMPV) - ) + ) * (1 + utility.loss_dist) end fill!(utility.Max_Net_Load_my, NaN) Max_Net_Load_my_dict = Dict() @@ -1270,12 +1270,12 @@ function solve_agent_problem!( sum( customers.rho_DG(h, m, z, d, t) * customers.total_der_capacity_my(y, z, h, m) for h in model_data.index_h, m in customers.index_m - ) - + ) * (1 + utility.loss_dist) - # remove aggregated behind-the-meter pv/storage generation/consumption since they're front-of-the-meter now sum( customers.rho_DG(h, m, z, d, t) * der_aggregator.aggregation_level(reg_year_index_dera, z) * customers.total_pv_stor_capacity_my(y, z, h, m) for h in model_data.index_h, m in (:BTMStorage, :BTMPV) - ) + + ) * (1 + utility.loss_dist) + # green technology subscription at time t sum( utility.rho_C_my(j, z, d, t) * sum(green_developer.green_tech_buildout_my(Symbol(Int(y_symbol)), j, z, h) for y_symbol in From 4667536fcd113a105478d62547237069eaf1220a Mon Sep 17 00:00:00 2001 From: nguo Date: Fri, 3 Jan 2025 12:08:48 -0700 Subject: [PATCH 7/7] output cem results when constructing cem_cost_saving_function --- Project.toml | 1 + src/HolisticElectricityModel.jl | 1 + src/agents/common.jl | 3 +- src/agents/customer_group.jl | 3 +- src/agents/der_aggregator.jl | 29 +++-- src/agents/green_developer.jl | 6 +- src/agents/ipp_group.jl | 6 +- src/agents/regulator.jl | 6 +- src/agents/utility.jl | 195 +++++++++++++++++++++++++++++++- 9 files changed, 231 insertions(+), 19 deletions(-) diff --git a/Project.toml b/Project.toml index 3b3564c..a5811b8 100644 --- a/Project.toml +++ b/Project.toml @@ -10,6 +10,7 @@ CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +DelimitedFiles = "8bb1440f-4735-579b-a4ab-409b98df4dab" Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" Dualization = "191a621a-6537-11e9-281d-650236a99e60" diff --git a/src/HolisticElectricityModel.jl b/src/HolisticElectricityModel.jl index e0be38b..61e118c 100644 --- a/src/HolisticElectricityModel.jl +++ b/src/HolisticElectricityModel.jl @@ -87,6 +87,7 @@ using DataStructures using Logging using JuMP using XLSX +using DelimitedFiles using Lazy: @forward import AxisKeys import AxisKeys: KeyedArray diff --git a/src/agents/common.jl b/src/agents/common.jl index 76a8953..fb84c02 100644 --- a/src/agents/common.jl +++ b/src/agents/common.jl @@ -438,7 +438,8 @@ function solve_equilibrium_problem!( window_length, jump_model, export_file_path, - true + true, + false, ) end @assert !isnothing(diff_one) "Nothing returned by solve_agent_problem!($(typeof(agent))): $(diff_one)" diff --git a/src/agents/customer_group.jl b/src/agents/customer_group.jl index f2e014c..b43d462 100644 --- a/src/agents/customer_group.jl +++ b/src/agents/customer_group.jl @@ -851,7 +851,8 @@ function solve_agent_problem!( window_length, jump_model, export_file_path, - update_results::Bool + update_results::Bool, + output_intermediate_results::Bool ) regulator = get_agent(Regulator, agent_store) utility = get_agent(Utility, agent_store) diff --git a/src/agents/der_aggregator.jl b/src/agents/der_aggregator.jl index 4f04148..3ebea5d 100644 --- a/src/agents/der_aggregator.jl +++ b/src/agents/der_aggregator.jl @@ -83,7 +83,8 @@ function solve_agent_problem!( window_length, jump_model, export_file_path, - update_results::Bool + update_results::Bool, + output_intermediate_results::Bool ) ipp = get_agent(IPPGroup, agent_store) @@ -125,7 +126,8 @@ function solve_agent_problem!( window_length, jump_model, export_file_path, - update_results::Bool + update_results::Bool, + output_intermediate_results::Bool ) utility = get_agent(Utility, agent_store) @@ -166,7 +168,8 @@ function solve_agent_problem!( window_length, jump_model, export_file_path, - update_results::Bool + update_results::Bool, + output_intermediate_results::Bool ) reg_year, reg_year_index = get_reg_year(model_data) @@ -419,7 +422,8 @@ function solve_agent_problem!( window_length, jump_model, export_file_path, - update_results::Bool + update_results::Bool, + output_intermediate_results::Bool ) reg_year, reg_year_index = get_reg_year(model_data) @@ -471,6 +475,9 @@ function solve_agent_problem!( der_aggregator.aggregation_level(reg_year_index_pre, z, :) .= 0.0 end + base_cem_dir = joinpath(export_file_path, "$(reg_year)_viu_dera_base") + mkdir(base_cem_dir) + diff_one_base = solve_agent_problem!( utility, utility_opts, @@ -480,8 +487,9 @@ function solve_agent_problem!( w_iter, window_length, jump_model, - export_file_path, - false + base_cem_dir, + false, + true ) viu_obj_value_base = deepcopy(utility._obj_value) @@ -497,7 +505,9 @@ function solve_agent_problem!( total_der_stor_capacity(z, h) / customers.Opti_DG_E(z, h, :BTMStorage) * customers.Opti_DG_E(z, h, :BTMPV) for h in model_data.index_h ) - + + incentive_function_cem_dir = joinpath(export_file_path, "$(reg_year)_viu_dera_$(z)_agg_level_$(i)") + mkdir(incentive_function_cem_dir) diff_one = solve_agent_problem!( utility, @@ -508,8 +518,9 @@ function solve_agent_problem!( w_iter, window_length, jump_model, - export_file_path, - false + incentive_function_cem_dir, + false, + true, ) viu_obj_value = deepcopy(utility._obj_value) diff --git a/src/agents/green_developer.jl b/src/agents/green_developer.jl index 770406d..2b251f2 100644 --- a/src/agents/green_developer.jl +++ b/src/agents/green_developer.jl @@ -64,7 +64,8 @@ function solve_agent_problem!( window_length, jump_model, export_file_path, - update_results::Bool + update_results::Bool, + output_intermediate_results::Bool ) utility = get_agent(Utility, agent_store) @@ -146,7 +147,8 @@ function solve_agent_problem!( window_length, jump_model, export_file_path, - update_results::Bool + update_results::Bool, + output_intermediate_results::Bool ) reg_year, reg_year_index = get_reg_year(model_data) diff --git a/src/agents/ipp_group.jl b/src/agents/ipp_group.jl index 916be43..6a47dff 100644 --- a/src/agents/ipp_group.jl +++ b/src/agents/ipp_group.jl @@ -839,7 +839,8 @@ function solve_agent_problem!( window_length, jump_model, export_file_path, - update_results::Bool + update_results::Bool, + output_intermediate_results::Bool ) return 0.0 end @@ -5570,7 +5571,8 @@ function solve_agent_problem!( window_length, jump_model, export_file_path, - update_results::Bool + update_results::Bool, + output_intermediate_results::Bool ) diff = 0.0 diff --git a/src/agents/regulator.jl b/src/agents/regulator.jl index 08cb846..9488329 100644 --- a/src/agents/regulator.jl +++ b/src/agents/regulator.jl @@ -368,7 +368,8 @@ function solve_agent_problem!( window_length, jump_model, export_file_path, - update_results::Bool + update_results::Bool, + output_intermediate_results::Bool ) delta_t = get_delta_t(model_data) @@ -1636,7 +1637,8 @@ function solve_agent_problem!( window_length, jump_model, export_file_path, - update_results::Bool + update_results::Bool, + output_intermediate_results::Bool ) for y in model_data.index_y_fix diff --git a/src/agents/utility.jl b/src/agents/utility.jl index 6a3dc71..edb7295 100644 --- a/src/agents/utility.jl +++ b/src/agents/utility.jl @@ -1039,7 +1039,8 @@ function solve_agent_problem!( window_length, jump_model, export_file_path, - update_results::Bool + update_results::Bool, + output_intermediate_results::Bool ) utility.current_year = first(model_data.index_y) return 0.0 @@ -1057,7 +1058,8 @@ function solve_agent_problem!( window_length, jump_model, export_file_path, - update_results::Bool + update_results::Bool, + output_intermediate_results::Bool ) regulator = get_agent(Regulator, agent_store) customers = get_agent(CustomerGroup, agent_store) @@ -1852,6 +1854,195 @@ function solve_agent_problem!( utility.current_year = first(model_data.index_y) end + if output_intermediate_results + y_E_intermediate = initialize_param( + "y_E_intermediate", + model_data.index_y, utility.index_k_existing, model_data.index_z, model_data.index_d, model_data.index_t, + ) + y_C_intermediate = initialize_param( + "y_C_intermediate", + model_data.index_y, utility.index_k_new, model_data.index_z, model_data.index_d, model_data.index_t, + ) + x_R_intermediate = initialize_param( + "x_R_intermediate", + model_data.index_y, utility.index_k_existing, model_data.index_z, + ) + x_C_intermediate = initialize_param( + "x_C_intermediate", + model_data.index_y, utility.index_k_new, model_data.index_z, + ) + x_stor_R_intermediate = initialize_param( + "x_stor_R_intermediate", + model_data.index_y, utility.index_stor_existing, model_data.index_z + ) + x_stor_C_intermediate = initialize_param( + "x_stor_C_intermediate", + model_data.index_y, utility.index_stor_new, model_data.index_z + ) + flow_intermediate = initialize_param( + "flow_intermediate", + model_data.index_y, utility.index_l, model_data.index_d, model_data.index_t, + ) + charge_E_intermediate = initialize_param( + "charge_E_intermediate", + model_data.index_y, utility.index_stor_existing, model_data.index_z, model_data.index_d, model_data.index_t, + ) + discharge_E_intermediate = initialize_param( + "discharge_E_intermediate", + model_data.index_y, utility.index_stor_existing, model_data.index_z, model_data.index_d, model_data.index_t, + ) + energy_E_intermediate = initialize_param( + "energy_E_intermediate", + model_data.index_y, utility.index_stor_existing, model_data.index_z, model_data.index_d, model_data.index_t, + ) + charge_C_intermediate = initialize_param( + "charge_C_intermediate", + model_data.index_y, utility.index_stor_new, model_data.index_z, model_data.index_d, model_data.index_t, + ) + discharge_C_intermediate = initialize_param( + "discharge_C_intermediate", + model_data.index_y, utility.index_stor_new, model_data.index_z, model_data.index_d, model_data.index_t, + ) + energy_C_intermediate = initialize_param( + "energy_C_intermediate", + model_data.index_y, utility.index_stor_new, model_data.index_z, model_data.index_d, model_data.index_t, + ) + obj_intermediate = ParamScalar("obj_intermediate", 0.0) + + for y in model_data.index_y, k in utility.index_k_existing, z in model_data.index_z, d in model_data.index_d, t in model_data.index_t + y_E_intermediate(y, k, z, d, t, :) .= value.(y_E[y, k, z, d, t]) + end + + for y in model_data.index_y, k in utility.index_k_new, z in model_data.index_z, d in model_data.index_d, t in model_data.index_t + y_C_intermediate(y, k, z, d, t, :) .= value.(y_C[y, k, z, d, t]) + end + + for y in model_data.index_y, k in utility.index_k_existing, z in model_data.index_z + x_R_intermediate(y, k, z, :) .= value.(x_R[y, k, z]) + end + + for y in model_data.index_y, k in utility.index_k_new, z in model_data.index_z + x_C_intermediate(y, k, z, :) .= value.(x_C[y, k, z]) + end + + for y in model_data.index_y, k in utility.index_stor_existing, z in model_data.index_z + x_stor_R_intermediate(y, k, z, :) .= value.(x_stor_R[y, k, z]) + end + + for y in model_data.index_y, k in utility.index_stor_new, z in model_data.index_z + x_stor_C_intermediate(y, k, z, :) .= value.(x_stor_C[y, k, z]) + end + + for y in model_data.index_y, l in utility.index_l, d in model_data.index_d, t in model_data.index_t + flow_intermediate(y, l, d, t, :) .= value.(flow[y, l, d, t]) + end + + for y in model_data.index_y, + s in utility.index_stor_existing, + z in model_data.index_z, + d in model_data.index_d, + t in model_data.index_t + + charge_E_intermediate(y, s, z, d, t, :) .= value.(charge_E[y, s, z, d, t]) + discharge_E_intermediate(y, s, z, d, t, :) .= value.(discharge_E[y, s, z, d, t]) + energy_E_intermediate(y, s, z, d, t, :) .= value.(energy_E[y, s, z, d, t]) + end + + for y in model_data.index_y, + s in utility.index_stor_new, + z in model_data.index_z, + d in model_data.index_d, + t in model_data.index_t + + charge_C_intermediate(y, s, z, d, t, :) .= value.(charge_C[y, s, z, d, t]) + discharge_C_intermediate(y, s, z, d, t, :) .= value.(discharge_C[y, s, z, d, t]) + energy_C_intermediate(y, s, z, d, t, :) .= value.(energy_C[y, s, z, d, t]) + end + + obj_intermediate.value = objective_value(VIUDER_Utility) + + save_param( + y_E_intermediate.values, + [:Year, :GenTech, :Zone, :Day, :Time], + :Generation_MWh, + joinpath(export_file_path, "y_E.csv"), + ) + save_param( + y_C_intermediate.values, + [:Year, :GenTech, :Zone, :Day, :Time], + :Generation_MWh, + joinpath(export_file_path, "y_C.csv"), + ) + save_param( + x_R_intermediate.values, + [:Year, :GenTech, :Zone], + :Capacity_MW, + joinpath(export_file_path, "x_R.csv"), + ) + save_param( + x_C_intermediate.values, + [:Year, :GenTech, :Zone], + :Capacity_MW, + joinpath(export_file_path, "x_C.csv"), + ) + save_param( + x_stor_R_intermediate.values, + [:Year, :StorTech, :Zone], + :Capacity_MW, + joinpath(export_file_path, "x_stor_R.csv"), + ) + save_param( + x_stor_C_intermediate.values, + [:Year, :StorTech, :Zone], + :Capacity_MW, + joinpath(export_file_path, "x_stor_C.csv"), + ) + save_param( + charge_E_intermediate.values, + [:Year, :StorTech, :Zone, :Day, :Time], + :Charge_MWh, + joinpath(export_file_path, "charge_E.csv"), + ) + save_param( + discharge_E_intermediate.values, + [:Year, :StorTech, :Zone, :Day, :Time], + :Discharge_MWh, + joinpath(export_file_path, "discharge_E.csv"), + ) + save_param( + charge_C_intermediate.values, + [:Year, :StorTech, :Zone, :Day, :Time], + :Charge_MWh, + joinpath(export_file_path, "charge_C.csv"), + ) + save_param( + discharge_C_intermediate.values, + [:Year, :StorTech, :Zone, :Day, :Time], + :Discharge_MWh, + joinpath(export_file_path, "discharge_C.csv"), + ) + save_param( + energy_E_intermediate.values, + [:Year, :StorTech, :Zone, :Day, :Time], + :Energy_MWh, + joinpath(export_file_path, "energy_E.csv"), + ) + save_param( + energy_C_intermediate.values, + [:Year, :StorTech, :Zone, :Day, :Time], + :Energy_MWh, + joinpath(export_file_path, "energy_C.csv"), + ) + save_param( + flow_intermediate.values, + [:Year, :Line, :Day, :Time], + :Flow_MWh, + joinpath(export_file_path, "flow.csv"), + ) + writedlm(joinpath(export_file_path, "objective_value.csv"), obj_intermediate.value) + + end + utility._obj_value.value = objective_value(VIUDER_Utility) # @info "Original built capacity" x_C_before