From 697cc379c34b6e6c436a509a86522aca57e12378 Mon Sep 17 00:00:00 2001 From: Purboday Ghosh Date: Mon, 2 Mar 2026 12:38:39 -0700 Subject: [PATCH] run for 22 years --- .../derating_factor_calculator.jl | 2 +- src/investment_simulation.jl | 2 +- src/investor_functions/annual_updates.jl | 4 +- .../decisions/buildphase_conversion.jl | 2 +- src/resource_adequacy/ra_utils.jl | 139 ++++++++++++++++-- .../simulation_structs/project_creator.jl | 7 +- .../simulation_structs/rts_psy_creator.jl | 52 ++++++- src/structs/market_structs/EnergyMarket.jl | 3 +- src/utils/siip_psy_utils.jl | 15 +- 9 files changed, 194 insertions(+), 32 deletions(-) diff --git a/src/derating_factor_updates/derating_factor_calculator.jl b/src/derating_factor_updates/derating_factor_calculator.jl index 3939e0c..caa8edd 100644 --- a/src/derating_factor_updates/derating_factor_calculator.jl +++ b/src/derating_factor_updates/derating_factor_calculator.jl @@ -334,7 +334,7 @@ function calculate_derating_factors( rt_resolution, simulation) - system_period_of_interest = range(1, length = 8760 * 15) + system_period_of_interest = range(1, length = 8760 * simulation_years) correlated_outage_csv_location = joinpath(outage_dir, "ThermalFOR_2011.csv") # create "Base" PRAS system to be used for calculation of ELCC or EFC. diff --git a/src/investment_simulation.jl b/src/investment_simulation.jl index b933cb7..b82b917 100644 --- a/src/investment_simulation.jl +++ b/src/investment_simulation.jl @@ -234,7 +234,7 @@ function run_agent_simulation(simulation::AgentSimulation, simulation_years::Int end for scenario in keys(sys_PRAS) - ra_metrics, shortfall = calculate_RA_metrics(deepcopy(sys_PRAS[scenario]),false,get_results_dir(simulation), get_outage_dir(case), iteration_year) + ra_metrics, shortfall = calculate_RA_metrics(deepcopy(sys_PRAS[scenario]),false,get_results_dir(simulation), get_outage_dir(case), iteration_year, total_horizon) FileIO.save(joinpath(get_results_dir(simulation), "shortfall_data_$(scenario)_year$(iteration_year).jld2"), "shortfall_data", shortfall) println(ra_metrics) set_metrics!(get_resource_adequacy(simulation)[scenario], iteration_year, ra_metrics) diff --git a/src/investor_functions/annual_updates.jl b/src/investor_functions/annual_updates.jl index fd13b02..fb8e785 100644 --- a/src/investor_functions/annual_updates.jl +++ b/src/investor_functions/annual_updates.jl @@ -124,7 +124,9 @@ function update_annual_cashflow!(project::Union{Project{Retired}, Project{Existi finance_data = get_finance_data(project) annual_revenue = sum(get_realized_profit(finance_data)[:, iteration_year]) - + + @info "length of profit array for $(get_name(project)): $(size(get_realized_profit(finance_data), 2))" + annual_cashflow = annual_revenue - get_fixed_OM_cost(finance_data) set_annual_cashflow!(finance_data, iteration_year, get_annual_cashflow(finance_data)[iteration_year] + annual_cashflow) return diff --git a/src/investor_functions/decisions/buildphase_conversion.jl b/src/investor_functions/decisions/buildphase_conversion.jl index 9adbbca..fd67a62 100644 --- a/src/investor_functions/decisions/buildphase_conversion.jl +++ b/src/investor_functions/decisions/buildphase_conversion.jl @@ -222,7 +222,7 @@ function finish_construction!(projects::Vector{<: Project{<: BuildPhase}}, availability_raw_rt = availability_df_rt[:, Symbol("$(type)_$(zone)")] end - add_device_forecast_PRAS!(sys_PRAS[scenario], PSY.get_component(typeof(PSY_project_PRAS), sys_PRAS[scenario], PSY.get_name(PSY_project_PRAS)), availability_raw_rt, rt_resolution) + add_device_forecast_PRAS!(sys_PRAS[scenario], PSY.get_component(typeof(PSY_project_PRAS), sys_PRAS[scenario], PSY.get_name(PSY_project_PRAS)), availability_raw_rt, rt_resolution, simulation_years) if type == "NU_ST" || type == "RE_CT" || typeof(PSY_project_PRAS) == PSY.RenewableDispatch || typeof(PSY_project_PRAS) == PSY.HydroEnergyReservoir || typeof(PSY_project_PRAS) == PSY.HydroDispatch if type == "RE_CT" diff --git a/src/resource_adequacy/ra_utils.jl b/src/resource_adequacy/ra_utils.jl index afd186f..9850c45 100644 --- a/src/resource_adequacy/ra_utils.jl +++ b/src/resource_adequacy/ra_utils.jl @@ -15,11 +15,12 @@ function calculate_RA_metrics(sys::PSY.System, exportoutage::Bool, base_dir::String, outage_dir::String, - iteration_year::Int64; + iteration_year::Int64, + simulation_years::Int64; samples::Int64 = 100, seed::Int64 = 42) - system_period_of_interest = range(1, length = 8760 * 15); + system_period_of_interest = range(1, length = 8760 * simulation_years); correlated_outage_csv_location = joinpath(outage_dir, "ThermalFOR_scenario_1_new.csv") # pras_system = make_pras_system(sys, # system_model="Single-Node", @@ -30,11 +31,16 @@ function calculate_RA_metrics(sys::PSY.System, # availability_flag=true, # outage_csv_location = correlated_outage_csv_location); - total_load = calculate_total_load(sys, 60) + sys_PRAS = deepcopy(sys) + sys_PRAS = add_outages_to_psy_system!(sys_PRAS, outage_dir, iteration_year, simulation_years) + num_generators = length(PSY.get_components(PSY.Generator, sys_PRAS)) + @info "Number of generators in PRAS system: $num_generators" + + total_load = calculate_total_load(sys_PRAS, 60, simulation_years) ra_metrics = Dict{String, Float64}() # seed = 3 - shortfall, gens_avail= @time PRAS.assess(sys, PSY.Area, PRAS.SequentialMonteCarlo(samples = samples, seed = seed), PRAS.Shortfall(), PRAS.GeneratorAvailability()) + shortfall, gens_avail= @time PRAS.assess(sys_PRAS, PSY.Area, PRAS.SequentialMonteCarlo(samples = samples, seed = seed), PRAS.Shortfall(), PRAS.GeneratorAvailability()) @info "Finished PRAS simulation... " eue_overall = PRAS.EUE(shortfall) lole_overall = PRAS.LOLE(shortfall) @@ -50,7 +56,7 @@ function calculate_RA_metrics(sys::PSY.System, CSV.write(joinpath(outage_csv_location,"1/Generator_year$(iteration_year+1).csv"), df_outage,writeheader = true) end - ra_metrics["LOLE"] = val(lole_overall) / 15 + ra_metrics["LOLE"] = val(lole_overall) / simulation_years ra_metrics["NEUE"] = val(eue_overall) * 1e6 / total_load PSY.set_units_base_system!(sys, PSY.IS.UnitSystem. DEVICE_BASE) @@ -135,7 +141,7 @@ function add_capacity_market_project!(capacity_market_system::PSY.System, availability_raw_rt = availability_df_rt[:, Symbol("$(type)_$(zone)")] end - add_device_forecast_PRAS!(capacity_market_system, PSY_project, availability_raw_rt, rt_resolution) + add_device_forecast_PRAS!(capacity_market_system, PSY_project, availability_raw_rt, rt_resolution, simulation_years) return end @@ -253,7 +259,7 @@ function update_delta_irm!(initial_system::PSY.System, @time begin if !isempty(ra_targets) - ra_metrics, shortfall = calculate_RA_metrics(capacity_market_system, false, results_dir, outage_dir, iteration_year) + ra_metrics, shortfall = calculate_RA_metrics(capacity_market_system, false, results_dir, outage_dir, iteration_year, simulation_years) #println(ra_metrics) adequacy_conditions_met, scarcity_conditions_met = check_ra_conditions(ra_targets, ra_metrics) @@ -280,7 +286,7 @@ function update_delta_irm!(initial_system::PSY.System, count += 1 end - ra_metrics, shortfall = calculate_RA_metrics(capacity_market_system, false, results_dir, outage_dir, iteration_year) + ra_metrics, shortfall = calculate_RA_metrics(capacity_market_system, false, results_dir, outage_dir, iteration_year, simulation_years) #println(ra_metrics) adequacy_conditions_met, scarcity_conditions_met = check_ra_conditions(ra_targets, ra_metrics) end @@ -293,7 +299,7 @@ function update_delta_irm!(initial_system::PSY.System, removed_capacity = get_device_size(removed_project) * PSY.get_base_power(removed_project) total_removed_capacity += removed_capacity PSY.remove_component!(capacity_market_system, removed_project) - ra_metrics, shortfall = calculate_RA_metrics(capacity_market_system, false, results_dir, outage_dir, iteration_year) + ra_metrics, shortfall = calculate_RA_metrics(capacity_market_system, false, results_dir, outage_dir, iteration_year, simulation_years) #println(ra_metrics) adequacy_conditions_met, scarcity_conditions_met = check_ra_conditions(ra_targets, ra_metrics) count += 1 @@ -327,6 +333,7 @@ function create_base_system(initial_system::PSY.System, simulation::Union{AgentSimulation,AgentSimulationData}) capacity_market_year = iteration_year + capacity_forward_years - 1 + simulation_years = get_total_horizon(get_case(simulation)) capacity_market_system = create_capacity_mkt_system(initial_system, active_projects, @@ -335,7 +342,7 @@ function create_base_system(initial_system::PSY.System, iteration_year, simulation_dir, rt_resolution, - get_total_horizon(get_case(simulation))) + simulation_years) ra_targets = get_targets(resource_adequacy) println(ra_targets) @@ -350,7 +357,7 @@ function create_base_system(initial_system::PSY.System, @time begin if !isempty(ra_targets) - ra_metrics, shortfall = calculate_RA_metrics(capacity_market_system, false, get_results_dir(simulation), outage_dir, iteration_year;samples = 100) + ra_metrics, shortfall = calculate_RA_metrics(capacity_market_system, false, get_results_dir(simulation), outage_dir, iteration_year, simulation_years;samples = 100) println(ra_metrics) adequacy_conditions_met, scarcity_conditions_met = check_ra_conditions(ra_targets, ra_metrics) @@ -377,7 +384,7 @@ function create_base_system(initial_system::PSY.System, count += 1 end - ra_metrics, shortfall = calculate_RA_metrics(capacity_market_system, false,get_results_dir(simulation), outage_dir, iteration_year;samples = 100) + ra_metrics, shortfall = calculate_RA_metrics(capacity_market_system, false,get_results_dir(simulation), outage_dir, iteration_year, simulation_years;samples = 100) println("Added Capacity") println(ra_metrics) adequacy_conditions_met, scarcity_conditions_met = check_ra_conditions(ra_targets, ra_metrics) @@ -392,7 +399,7 @@ function create_base_system(initial_system::PSY.System, removed_capacity = get_device_size(removed_project) * PSY.get_base_power(removed_project) total_removed_capacity += removed_capacity PSY.remove_component!(capacity_market_system, removed_project) - ra_metrics, shortfall = calculate_RA_metrics(capacity_market_system, false,get_results_dir(simulation), outage_dir, iteration_year;samples = 100) + ra_metrics, shortfall = calculate_RA_metrics(capacity_market_system, false,get_results_dir(simulation), outage_dir, iteration_year, simulation_years;samples = 100) println("Removed Capacity") println(ra_metrics) adequacy_conditions_met, scarcity_conditions_met = check_ra_conditions(ra_targets, ra_metrics) @@ -406,3 +413,109 @@ function create_base_system(initial_system::PSY.System, return capacity_market_system end + + +function add_outages_to_psy_system!(sys_PRAS::PSY.System, + outage_dir::String, + iteration_year::Int64, + simulation_years::Int64) + + lambda_ts = CSV.read(joinpath(outage_dir, "gen_lambdas.csv"), DataFrames.DataFrame) + mu_ts = CSV.read(joinpath(outage_dir, "gen_mus.csv"), DataFrames.DataFrame) + + first_ts_temp_PRAS = first(PSY.get_time_series_multiple(sys_PRAS)) + start_datetime_PRAS = PSY.IS.get_initial_timestamp(first_ts_temp_PRAS) + sys_PRAS_res = PSY.get_time_series_resolutions(sys_PRAS)[1] + finish_datetime_PRAS = start_datetime_PRAS + Dates.Hour(((simulation_years * 8760) - 1) * sys_PRAS_res) + timestep = StepRange(start_datetime_PRAS, sys_PRAS_res, finish_datetime_PRAS); + + # Default values for λ and µ + # Outage probability (λ) and recovery probability (µ) + λ = 0.04 + µ = 1.0 + + num_generators = length(PSY.get_components(PSY.Generator, sys_PRAS)) + @info "Adding outage information to $(num_generators) generators in the system..." + + for gen in PSY.get_components(PSY.Generator, sys_PRAS) + gen_name = PSY.get_name(gen) + + # remove fuel cost time series + remove_time_series!(sys_PRAS, SingleTimeSeries, gen, "fuel_cost") + + outage = PSY.GeometricDistributionForcedOutage(; + mean_time_to_recovery = 1 - µ, + outage_transition_probability = λ, + ) + + outage_probability_values = Float64[] + recovery_probability_values = Float64[] + + PSY.add_supplemental_attribute!(sys_PRAS, gen, outage) + + if gen_name in names(lambda_ts) + outage_probability_values = lambda_ts[!, Symbol(gen_name)] + outage_probability_values = outage_probability_values[1:length(timestep)] + end + if gen_name in names(mu_ts) + recovery_probability_values = mu_ts[!, Symbol(gen_name)] + recovery_probability_values = recovery_probability_values[1:length(timestep)] + end + + if length(outage_probability_values) > 0 + outage_probability_ts = TS.TimeArray(timestep, outage_probability_values) + ts = SingleTimeSeries(; name = "outage_probability", data = outage_probability_ts) + PSY.add_time_series!(sys_PRAS, outage, ts) + end + if length(recovery_probability_values) > 0 + recovery_probability_ts = TS.TimeArray(timestep, recovery_probability_values) + ts = SingleTimeSeries(; name = "recovery_probability", data = recovery_probability_ts) + PSY.add_time_series!(sys_PRAS, outage, ts) + end + + end + + load_df = DataFrame() + base_year = 1998 + for load_year in base_year:base_year + simulation_years - 1 + zone_load_profile = CSV.read("/projects/gmlcmarkets/Phase2_EMIS_Analysis/Jul2025_NY_IMPACT_Test_PGHOSH/RTS-GMLC_NY/nygrid2sienna/load_profile_zonal/Baseload/Baseload_$(load_year).csv", DataFrame) + load_df = vcat(load_df, zone_load_profile) + # load_year = 2019 + end + + for load in PSY.get_components(PSY.StandardLoad, sys_PRAS) + name = PSY.get_name(load) + bus_name = PSY.get_name(PSY.get_bus(load)) + remove_time_series!(sys_PRAS, SingleTimeSeries, load, "max_active_power") + if bus_name in names(load_df) + load_profile = load_df[!, bus_name] + load_profile = load_profile[1:length(timestep)] + if maximum(load_profile) == 0.0 + PSY.add_time_series!( + sys_PRAS, + load, + PSY.SingleTimeSeries( + "max_active_power", + TS.TimeArray(timestep, load_profile / minimum(load_profile)), + scaling_factor_multiplier=PSY.get_max_active_power, + ) + ) + else + PSY.add_time_series!( + sys_PRAS, + load, + PSY.SingleTimeSeries( + "max_active_power", + TS.TimeArray(timestep, load_profile / maximum(load_profile)), + scaling_factor_multiplier=PSY.get_max_active_power, + ) + ) + end + else + @warn "Load profile for $(bus_name) not found in outage directory." + end + end + + + return sys_PRAS +end diff --git a/src/struct_creators/simulation_structs/project_creator.jl b/src/struct_creators/simulation_structs/project_creator.jl index 6f5561e..08d4be1 100644 --- a/src/struct_creators/simulation_structs/project_creator.jl +++ b/src/struct_creators/simulation_structs/project_creator.jl @@ -81,8 +81,8 @@ function add_investor_project_availability!(test_system_dir::String, projects::Vector{Project}, sys_UC::Union{Nothing, PSY.System}) - pv_availability_file = CSV.read(joinpath(test_system_dir, "RTS_Data", "upv_availability.csv"), DataFrame) - wind_availability_file = CSV.read(joinpath(test_system_dir, "RTS_Data", "wind_availability.csv"), DataFrame) + pv_availability_file = CSV.read(joinpath(test_system_dir, "RTS_Data", scenario, "year_$(sim_year)", "upv_availability.csv"), DataFrame) + wind_availability_file = CSV.read(joinpath(test_system_dir, "RTS_Data", scenario, "year_$(sim_year)", "wind_availability.csv"), DataFrame) system_availability_data = DataFrames.DataFrame(CSV.File(joinpath(simulation_dir, "timeseries_data_files", scenario, "sim_year_$(sim_year)", "Availability", "DAY_AHEAD_availability.csv"))) system_availability_data_rt = DataFrames.DataFrame(CSV.File(joinpath(simulation_dir, "timeseries_data_files", scenario, "sim_year_$(sim_year)", "Availability", "REAL_TIME_availability.csv"))) @@ -327,6 +327,8 @@ function create_investment_data(size::Float64, annual_cashflow = zeros(num_profit_years) + @info("num_profit_years: $num_profit_years") + finance_data = Finance(investment_cost, effective_investment_cost, preference_multiplier, @@ -798,6 +800,7 @@ function create_project(projectdata::DataFrames.DataFrameRow, lag_bool::Bool) name = String(projectdata["GEN_UID"]) + @info "Creating project: $name" unit_type = String(projectdata["Unit Type"]) size_raw = projectdata["Size"] diff --git a/src/struct_creators/simulation_structs/rts_psy_creator.jl b/src/struct_creators/simulation_structs/rts_psy_creator.jl index 052ea42..cca0447 100644 --- a/src/struct_creators/simulation_structs/rts_psy_creator.jl +++ b/src/struct_creators/simulation_structs/rts_psy_creator.jl @@ -85,7 +85,8 @@ function create_rts_sys(rts_dir::String, # prune_system_devices!(sys_UC, pruned_unit) # prune_system_devices!(sys_ED, pruned_unit) - ntp_ts_data_dir = joinpath(rts_dir, "..", "..", "Feb2024_ERCOT_2011_MARKET_Test_CAVRAAM", "NTP_TimeSeries_Data", "input_processing") + # ntp_ts_data_dir = joinpath(rts_dir, "..", "..", "Feb2024_ERCOT_2011_MARKET_Test_CAVRAAM", "NTP_TimeSeries_Data", "input_processing") + ntp_ts_data_dir = joinpath(rts_dir, "nys_psy") sys_MDs = Vector{PSY.System}() sys_UCs = Vector{PSY.System}() @@ -107,13 +108,14 @@ function create_rts_sys(rts_dir::String, MD_sys_filename = joinpath(rts_dir, "constructed_systems", pcm_scenario, "sim_year_$(sim_year)", "MD_sys_EMIS_$(MD_horizon)hor_$(MD_interval)int.json") MD_num_forecast_filename = joinpath(rts_dir, "constructed_systems", pcm_scenario, "sim_year_$(sim_year)", "MD_num_forecast_$(MD_horizon)hor_$(MD_interval)int.txt") - loadyear = 2020+sim_year + # NY - 22 year load data starts from 1998 + loadyear = 1997+sim_year weatheryear = loadyear if !(isfile(MD_sys_filename) && isfile(MD_num_forecast_filename)) println("MD json file doesn't exist. Creating required data.") dir_exists(dirname(MD_sys_filename)) - sys_MD_initial = PSY.System(joinpath(rts_dir,"nys2019_zonal.json"), time_series_directory = scratch_dir); + sys_MD_initial = PSY.System(joinpath(rts_dir, "nys_psy", "nys2019_zonal.json"), time_series_directory = scratch_dir); # create MD system create_sys_w_updated_ts_ny( ntp_ts_data_dir, @@ -139,7 +141,7 @@ function create_rts_sys(rts_dir::String, if !(isfile(UC_filename)) println("UC json file doesn't exist. Creating required json file.") dir_exists(dirname(UC_filename)) - sys_UC_initial = PSY.System(joinpath(rts_dir, "nys2019_zonal.json"), time_series_directory = scratch_dir); + sys_UC_initial = PSY.System(joinpath(rts_dir, "nys_psy", "nys2019_zonal.json"), time_series_directory = scratch_dir); create_sys_w_updated_ts_ny( ntp_ts_data_dir, sys_UC_initial, @@ -175,7 +177,7 @@ function create_rts_sys(rts_dir::String, if !isfile(ED_filename) println("ED json file doesn't exist. Creating required json file.") dir_exists(dirname(ED_filename)) - sys_ED_initial = PSY.System(joinpath(rts_dir,"nys2019_zonal.json"), time_series_directory = scratch_dir); + sys_ED_initial = PSY.System(joinpath(rts_dir, "nys_psy", "nys2019_zonal.json"), time_series_directory = scratch_dir); create_sys_w_updated_ts_ny( ntp_ts_data_dir, sys_ED_initial, @@ -658,6 +660,46 @@ function create_sys_w_updated_ts_ny( sys_MD = initial_sys PSY.set_units_base_system!(sys_MD, PSY.IS.UnitSystem.SYSTEM_BASE) + ###### update load time series ###### + #-------------------------------------------- + + zonal_load_profile = CSV.read(joinpath(data_dir, "..", "nygrid2sienna", "load_profile_zonal", "Baseload", "Baseload_$(loadyear).csv"), DataFrame) + + for d in get_components(StandardLoad, sys_MD) + bus_name = PSY.get_name(PSY.get_bus(d)) + newtsdata = zonal_load_profile[!, bus_name] + first_ts_temp_MD = first(PSY.get_time_series_multiple(sys_MD)) + start_timestamp = PSY.IS.get_initial_timestamp(first_ts_temp_MD) + end_timestamp = start_timestamp + Dates.Hour(8760 - 1) + timestamps = start_timestamp:Hour(1):end_timestamp + + # remove old time series + remove_time_series!(sys_MD, SingleTimeSeries, d, "max_active_power") + + if maximum(newtsdata) == 0.0 + PSY.add_time_series!( + sys_MD, + d, + PSY.SingleTimeSeries( + "max_active_power", + TS.TimeArray(timestamps, newtsdata / minimum(newtsdata)), + scaling_factor_multiplier=PSY.get_max_active_power, + ) + ) + else + PSY.add_time_series!( + sys_MD, + d, + PSY.SingleTimeSeries( + "max_active_power", + TS.TimeArray(timestamps, newtsdata / maximum(newtsdata)), + scaling_factor_multiplier=PSY.get_max_active_power, + ) + ) + end + + end + to_json(sys_MD, output_file, force=true) # number_of_forecast = sys_MD.data.time_series_params.forecast_params.count diff --git a/src/structs/market_structs/EnergyMarket.jl b/src/structs/market_structs/EnergyMarket.jl index 73f4787..8e0d997 100644 --- a/src/structs/market_structs/EnergyMarket.jl +++ b/src/structs/market_structs/EnergyMarket.jl @@ -10,7 +10,8 @@ struct EnergyMarket{Z, T} price_cap::AxisArrays.AxisArray{Float64, 1} # $/MWh function EnergyMarket{}(demand::AxisArrays.AxisArray{Float64, 2}, price_cap::AxisArrays.AxisArray{Float64, 1}) - @assert all(demand .>= 0) + ## NY Change to accommodate negative loads + # @assert all(demand .>= 0) @assert all(price_cap .>= 0) Z = size(demand, 1) T = size(demand, 2) diff --git a/src/utils/siip_psy_utils.jl b/src/utils/siip_psy_utils.jl index 2a6bfc4..3c0664b 100644 --- a/src/utils/siip_psy_utils.jl +++ b/src/utils/siip_psy_utils.jl @@ -232,7 +232,8 @@ This function does nothing if Device is not of RenewableGen type. function add_device_forecast_PRAS!(sys::PSY.System, device::D, availability_raw_rt::Vector{Float64}, - rt_resolution::Int64) where D <: Union{PSY.ThermalGen, PSY.HydroGen, PSY.Storage} + rt_resolution::Int64, + simulation_years::Int64) where D <: Union{PSY.ThermalGen, PSY.HydroGen, PSY.Storage} return end @@ -244,12 +245,12 @@ This function adds forecast timeseries to PRAS System if Device is of RenewableG function add_device_forecast_PRAS!(sys::PSY.System, device::D, availability_raw_rt::Vector{Float64}, - rt_resolution::Int64 + rt_resolution::Int64, + simulation_years::Int64 ) where D <: PSY.RenewableGen - - start_datetime = Dates.DateTime("2019-01-01T00:00:00") - timestamp = range(start_datetime, step = Hour(1), length = 8760 * 15) + start_datetime = Dates.DateTime("2019-01-01T00:00:00") + timestamp = range(start_datetime, step = Hour(1), length = 8760 * simulation_years) value_ts = availability_raw_rt data = TS.TimeArray(timestamp, value_ts) single_time_series = PSY.SingleTimeSeries("max_active_power", data, scaling_factor_multiplier=get_max_active_power) @@ -673,7 +674,7 @@ function add_psy_clean_energy_constraint!(sys::PSY.System, end -function calculate_total_load(sys::PSY.System, time_resolution::Int64) +function calculate_total_load(sys::PSY.System, time_resolution::Int64, simulation_years::Int64) total_load = 0.0 # sys_interval = sys.data.time_series_params.forecast_params.interval @@ -696,7 +697,7 @@ function calculate_total_load(sys::PSY.System, time_resolution::Int64) # for timestep in keys(loadts_raw) # ts_data=[ts_data;loadts_raw[timestep][1:Int(sys_interval/sys_resolution)]] # end - total_load += sum(TS.values(ts_data[1:8760*15]) * PSY.get_max_active_power(load)) * time_resolution / 60 + total_load += sum(TS.values(ts_data[1:8760*simulation_years]) * PSY.get_max_active_power(load)) * time_resolution / 60 end return total_load