From 0609a92c91a179d7956d5060cb7b9357830da501 Mon Sep 17 00:00:00 2001 From: Matt Prilliman Date: Thu, 1 Dec 2022 09:17:08 -0700 Subject: [PATCH 01/22] ME array cable voltage, cable cost ssc eqn setup --- ssc/cmod_mhk_eqns.cpp | 147 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) diff --git a/ssc/cmod_mhk_eqns.cpp b/ssc/cmod_mhk_eqns.cpp index d34b74ea7..00f392670 100644 --- a/ssc/cmod_mhk_eqns.cpp +++ b/ssc/cmod_mhk_eqns.cpp @@ -89,5 +89,152 @@ bool me_array_cable_length(ssc_data_t data) return true; } +bool me_array_cable_voltage(ssc_data_t data) +{ + auto vt = static_cast(data); + if (!vt) { + return false; + } + + double devices_per_row, device_spacing_in_row, number_rows, row_spacing, cable_system_overbuild, floating_array, export_cable_redundancy, water_depth, number_devices, distance_to_shore; + double device_rated_power, system_capacity; + vt_get_number(vt, "devices_per_row", &devices_per_row); + vt_get_number(vt, "device_rated_power", &device_rated_power); + vt_get_number(vt, "system_capacity", &system_capacity); + vt_get_number(vt, "device_spacing_in_row", &device_spacing_in_row); + vt_get_number(vt, "number_rows", &number_rows); + vt_get_number(vt, "row_spacing", &row_spacing); + vt_get_number(vt, "cable_system_overbuild", &cable_system_overbuild); + vt_get_number(vt, "floating_array", &floating_array); + vt_get_number(vt, "export_cable_redundancy", &export_cable_redundancy); + vt_get_number(vt, "water_depth", &water_depth); + vt_get_number(vt, "number_devices", &number_devices); + vt_get_number(vt, "distance_to_shore", &distance_to_shore); + + + double PF = 0.95; //Power Factor + double angle = acos(PF); + double reactive_power = sqrt(3.0); //Where is this used + double riser_cable_rated_power_per_device = device_rated_power / (sqrt(3.0) * PF * 1000.0); + double array_cable_rated_power_per_row = (device_rated_power * devices_per_row) / (sqrt(3.0) * PF * 1000.0); + double export_cable_rated_power_array_ac = (system_capacity) / (sqrt(3.0) * PF * 1000.0); + double export_cable_rated_power_array_hvdc = (system_capacity) / 1000.0; + + //Cable Electrical Specifications + double export_cable_type = 0; //0 - AC, 1 - HVDC Appendix A Electrical Instracture Model spreadsheet + if (system_capacity >= 200000 && distance_to_shore >= 150000 || + (system_capacity >= 300000 && distance_to_shore >= 100000) || + (system_capacity >= 500000 && distance_to_shore >= 90000) || + (system_capacity >=600000 && distance_to_shore >= 80000) || + (system_capacity >= 1100000 && distance_to_shore >= 70000)) { + export_cable_type = 1; + } + vt->assign("export_cable_type", export_cable_type); + //Riser Cable + double riser_cable_voltage = 0; + double riser_cable_cost = 0; //$/m + if ( array_cable_rated_power_per_row < 4) { + riser_cable_voltage = 7.2; + riser_cable_cost = 57.955 * array_cable_rated_power_per_row; + } + else if (riser_cable_rated_power_per_device >= 5 && riser_cable_rated_power_per_device < 9) { + riser_cable_voltage = 12; + riser_cable_cost = 47.214 * riser_cable_rated_power_per_device - 91.05; + } + else if (riser_cable_rated_power_per_device >= 9 && riser_cable_rated_power_per_device < 14) { + riser_cable_voltage = 24; + riser_cable_cost = 22.748 * riser_cable_rated_power_per_device - 68.376; + } + else if (riser_cable_rated_power_per_device >= 14) { + riser_cable_voltage = 36; + riser_cable_cost = 20.82 * riser_cable_rated_power_per_device - 163.14; + } + vt->assign("riser_cable_voltage", riser_cable_voltage); + vt->assign("riser_cable_cost", riser_cable_cost); + + //Array Cable + double array_cable_voltage = 0; + double array_cable_cost = 0; + if ( array_cable_rated_power_per_row < 4) { + array_cable_voltage = 7.2; + array_cable_cost = 44.245 * array_cable_rated_power_per_row; + } + else if ( array_cable_rated_power_per_row >= 4 && array_cable_rated_power_per_row < 9) { + array_cable_voltage = 12; + array_cable_cost = 31.029 * array_cable_rated_power_per_row - 40.744; + } + else if ( array_cable_rated_power_per_row >= 9 && array_cable_rated_power_per_row < 14) { + array_cable_voltage = 24; + array_cable_cost = 17.348 * array_cable_rated_power_per_row - 61.467; + } + else if ( array_cable_rated_power_per_row >= 14 && array_cable_rated_power_per_row < 30) { + array_cable_voltage = 36; + array_cable_cost = 13.791 * array_cable_rated_power_per_row - 93.272; + } + else if (array_cable_rated_power_per_row >= 30) { + array_cable_voltage = 66; + array_cable_cost = 11.984 * array_cable_rated_power_per_row - 155.97; + } + vt->assign("array_cable_voltage", array_cable_voltage); + vt->assign("array_cable_cost", array_cable_cost); + + //Export Cable + double export_cable_voltage = 0; + double export_cable_cost = 0; + if (export_cable_type == 0) { + if (export_cable_rated_power_array_ac < 4) { + export_cable_voltage = 7.2; + export_cable_cost = 44.245 * export_cable_rated_power_array_ac; + } + else if (export_cable_rated_power_array_ac >= 4 && export_cable_rated_power_array_ac < 9) { + export_cable_voltage = 12; + export_cable_cost = 31.029 * export_cable_rated_power_array_ac - 40.744; + } + else if (export_cable_rated_power_array_ac >= 9 && export_cable_rated_power_array_ac < 14) { + export_cable_voltage = 24; + export_cable_cost = 17.348 * export_cable_rated_power_array_ac - 61.467; + } + else if (export_cable_rated_power_array_ac >= 14 && export_cable_rated_power_array_ac < 30) { + export_cable_voltage = 36; + export_cable_cost = 13.791 * export_cable_rated_power_array_ac - 93.272; + } + else if (export_cable_rated_power_array_ac >= 30 && export_cable_rated_power_array_ac < 40) { + export_cable_voltage = 66; + array_cable_cost = 11.984 * export_cable_rated_power_array_ac - 155.97; + } + else if (export_cable_rated_power_array_ac >= 40 && export_cable_rated_power_array_ac < 121) { + export_cable_voltage = 72.5; + array_cable_cost = 9.8977 * export_cable_rated_power_array_ac - 195.75; + } + else if (export_cable_rated_power_array_ac >= 121 && export_cable_rated_power_array_ac < 250) { + export_cable_voltage = 145; + array_cable_cost = 10.046 * export_cable_rated_power_array_ac - 886.49; + } + else if (export_cable_rated_power_array_ac >= 250 && export_cable_rated_power_array_ac < 550) { + export_cable_voltage = 220; + array_cable_cost = 5.2937 * export_cable_rated_power_array_ac - 318.15; + } + else if (export_cable_rated_power_array_ac >= 550) { + export_cable_voltage = 400; + array_cable_cost = 7.7566 * export_cable_rated_power_array_ac - 2704.6; + } + } + else { + if (export_cable_rated_power_array_hvdc < 500) { + export_cable_voltage = 150; + export_cable_cost = 2.5026 * export_cable_rated_power_array_hvdc; + } + else { + export_cable_voltage = 300; + export_cable_cost = 2.0375 * export_cable_rated_power_array_hvdc - 516.02; + } + } + vt->assign("export_cable_voltage", export_cable_voltage); + vt->assign("export_cable_cost", export_cable_cost); + + + +} + From 94863de6d37dc63961f70bd283f196df1294bda5 Mon Sep 17 00:00:00 2001 From: Matt Prilliman Date: Fri, 2 Dec 2022 12:46:51 -0700 Subject: [PATCH 02/22] Onshore, offshore substation cost calcs added to ssc eqn (may need to move to mhk_costs) --- ssc/cmod_mhk_eqns.cpp | 69 ++++++++++++++++++++++++++++++++++++++++--- ssc/cmod_mhk_eqns.h | 13 ++++++++ 2 files changed, 78 insertions(+), 4 deletions(-) diff --git a/ssc/cmod_mhk_eqns.cpp b/ssc/cmod_mhk_eqns.cpp index 00f392670..9e803f57e 100644 --- a/ssc/cmod_mhk_eqns.cpp +++ b/ssc/cmod_mhk_eqns.cpp @@ -97,11 +97,15 @@ bool me_array_cable_voltage(ssc_data_t data) } double devices_per_row, device_spacing_in_row, number_rows, row_spacing, cable_system_overbuild, floating_array, export_cable_redundancy, water_depth, number_devices, distance_to_shore; - double device_rated_power, system_capacity; + double device_rated_power, system_capacity, inter_array_cable_length, riser_cable_length, export_cable_length; + double use_onshore_substation, load_grid_voltage; vt_get_number(vt, "devices_per_row", &devices_per_row); vt_get_number(vt, "device_rated_power", &device_rated_power); vt_get_number(vt, "system_capacity", &system_capacity); vt_get_number(vt, "device_spacing_in_row", &device_spacing_in_row); + vt_get_number(vt, "inter_array_cable_length", &inter_array_cable_length); + vt_get_number(vt, "riser_cable_length", &riser_cable_length); + vt_get_number(vt, "export_cable_length", &export_cable_length); vt_get_number(vt, "number_rows", &number_rows); vt_get_number(vt, "row_spacing", &row_spacing); vt_get_number(vt, "cable_system_overbuild", &cable_system_overbuild); @@ -110,16 +114,18 @@ bool me_array_cable_voltage(ssc_data_t data) vt_get_number(vt, "water_depth", &water_depth); vt_get_number(vt, "number_devices", &number_devices); vt_get_number(vt, "distance_to_shore", &distance_to_shore); + vt_get_number(vt, "use_onshore_substation", &use_onshore_substation); + vt_get_number(vt, "load_grid_voltage", &load_grid_voltage); double PF = 0.95; //Power Factor double angle = acos(PF); - double reactive_power = sqrt(3.0); //Where is this used + double riser_cable_rated_power_per_device = device_rated_power / (sqrt(3.0) * PF * 1000.0); double array_cable_rated_power_per_row = (device_rated_power * devices_per_row) / (sqrt(3.0) * PF * 1000.0); double export_cable_rated_power_array_ac = (system_capacity) / (sqrt(3.0) * PF * 1000.0); double export_cable_rated_power_array_hvdc = (system_capacity) / 1000.0; - + double reactive_power = sqrt(3.0) * array_cable_rated_power_per_row * sin(angle); //Where is this used //Cable Electrical Specifications double export_cable_type = 0; //0 - AC, 1 - HVDC Appendix A Electrical Instracture Model spreadsheet if (system_capacity >= 200000 && distance_to_shore >= 150000 || @@ -151,6 +157,8 @@ bool me_array_cable_voltage(ssc_data_t data) } vt->assign("riser_cable_voltage", riser_cable_voltage); vt->assign("riser_cable_cost", riser_cable_cost); + double riser_cable_cost_total = riser_cable_cost * riser_cable_length; + vt->assign("riser_cable_cost_total", riser_cable_cost_total); //Array Cable double array_cable_voltage = 0; @@ -177,63 +185,116 @@ bool me_array_cable_voltage(ssc_data_t data) } vt->assign("array_cable_voltage", array_cable_voltage); vt->assign("array_cable_cost", array_cable_cost); + double array_cable_cost_total = array_cable_cost * inter_array_cable_length; + vt->assign("array_cable_cost_total", array_cable_cost_total); //Export Cable double export_cable_voltage = 0; double export_cable_cost = 0; + double offshore_substation_voltage = 0; if (export_cable_type == 0) { if (export_cable_rated_power_array_ac < 4) { export_cable_voltage = 7.2; export_cable_cost = 44.245 * export_cable_rated_power_array_ac; + offshore_substation_voltage = 8; //kVAC } else if (export_cable_rated_power_array_ac >= 4 && export_cable_rated_power_array_ac < 9) { export_cable_voltage = 12; export_cable_cost = 31.029 * export_cable_rated_power_array_ac - 40.744; + offshore_substation_voltage = 15; //kVAC } else if (export_cable_rated_power_array_ac >= 9 && export_cable_rated_power_array_ac < 14) { export_cable_voltage = 24; export_cable_cost = 17.348 * export_cable_rated_power_array_ac - 61.467; + offshore_substation_voltage = 25; //kVAC } else if (export_cable_rated_power_array_ac >= 14 && export_cable_rated_power_array_ac < 30) { export_cable_voltage = 36; export_cable_cost = 13.791 * export_cable_rated_power_array_ac - 93.272; + offshore_substation_voltage = 46; //kVAC } else if (export_cable_rated_power_array_ac >= 30 && export_cable_rated_power_array_ac < 40) { export_cable_voltage = 66; array_cable_cost = 11.984 * export_cable_rated_power_array_ac - 155.97; + offshore_substation_voltage = 69; //kVAC } else if (export_cable_rated_power_array_ac >= 40 && export_cable_rated_power_array_ac < 121) { export_cable_voltage = 72.5; array_cable_cost = 9.8977 * export_cable_rated_power_array_ac - 195.75; + offshore_substation_voltage = 115; //kVAC } else if (export_cable_rated_power_array_ac >= 121 && export_cable_rated_power_array_ac < 250) { export_cable_voltage = 145; array_cable_cost = 10.046 * export_cable_rated_power_array_ac - 886.49; + offshore_substation_voltage = 161; //kVAC } else if (export_cable_rated_power_array_ac >= 250 && export_cable_rated_power_array_ac < 550) { export_cable_voltage = 220; array_cable_cost = 5.2937 * export_cable_rated_power_array_ac - 318.15; + offshore_substation_voltage = 230; //kVAC } else if (export_cable_rated_power_array_ac >= 550) { export_cable_voltage = 400; array_cable_cost = 7.7566 * export_cable_rated_power_array_ac - 2704.6; + offshore_substation_voltage = 415; //kVAC } } else { if (export_cable_rated_power_array_hvdc < 500) { export_cable_voltage = 150; export_cable_cost = 2.5026 * export_cable_rated_power_array_hvdc; + offshore_substation_voltage = 161; //kV HVDC } else { export_cable_voltage = 300; export_cable_cost = 2.0375 * export_cable_rated_power_array_hvdc - 516.02; + offshore_substation_voltage = 345; //kVAC } } vt->assign("export_cable_voltage", export_cable_voltage); vt->assign("export_cable_cost", export_cable_cost); - + double export_cable_cost_total = export_cable_cost * export_cable_length; + vt->assign("export_cable_cost_total", export_cable_cost_total); + //Offshore substation costs + double offshore_foundation_cost = 303.09 * system_capacity; + //AC Electrical equipment + double circuit_breaker_cost = 818.42 * offshore_substation_voltage; + double ac_switchgear_cost = 14018 * offshore_substation_voltage; + double transformer_cost = 11879 * export_cable_rated_power_array_ac; + double shunt_reactor_cost = 35226 * reactive_power; + double series_capacitor_cost = 22047 * reactive_power; + double static_var_compensator_cost = 105060 * reactive_power; + //HVDC Electrical equipment + double hvdc_converter_station_cost = 142.61 * system_capacity; + double offshore_substation_cost_total = 0; + if (array_cable_voltage == export_cable_voltage && export_cable_type == 0) { + offshore_substation_cost_total = offshore_foundation_cost + circuit_breaker_cost + ac_switchgear_cost + transformer_cost + + shunt_reactor_cost + series_capacitor_cost + static_var_compensator_cost; + } + else if (array_cable_voltage == export_cable_voltage && export_cable_type == 1) { + offshore_substation_cost_total = offshore_foundation_cost + hvdc_converter_station_cost; + } + //Onshore substation + double onshore_substation_voltage = load_grid_voltage; + double onshore_foundation_cost = 3590.4 * onshore_substation_voltage + 1000000; + double onshore_circuit_breaker_cost = 818.42 * onshore_substation_voltage; + double onshore_ac_switchgear_cost = 14018 * onshore_substation_voltage; + double onshore_transformer_cost = 11346 * export_cable_rated_power_array_ac; + double onshore_shunt_reactor_cost = 35226 * reactive_power; + double onshore_series_capacitor_cost = 22047 * reactive_power; + double onshore_static_var_compensator_cost = 105060 * reactive_power; + //HVDC Electrical equipment + double onshore_hvdc_converter_station_cost = 142.61 * system_capacity; + double onshore_substation_cost_total; + if (use_onshore_substation==1 && export_cable_type == 0) { + onshore_substation_cost_total = onshore_foundation_cost + onshore_circuit_breaker_cost + onshore_ac_switchgear_cost + onshore_transformer_cost + + onshore_shunt_reactor_cost + onshore_series_capacitor_cost + onshore_static_var_compensator_cost; + } + else if (use_onshore_substation==1 && export_cable_type == 1) { + onshore_substation_cost_total = onshore_foundation_cost + onshore_hvdc_converter_station_cost; + } } diff --git a/ssc/cmod_mhk_eqns.h b/ssc/cmod_mhk_eqns.h index 112e7d193..8cfdd9fab 100644 --- a/ssc/cmod_mhk_eqns.h +++ b/ssc/cmod_mhk_eqns.h @@ -53,6 +53,19 @@ static const char* me_array_cable_length_doc = SSCEXPORT bool me_array_cable_length(ssc_data_t data); +static const char* me_array_cable_voltage_doc = +"Calculates the cable voltages in an ME array\\n" +"Input: var_table with key-value pairs\\n" +" 'devices_per_row' - double [-]\\n" +" 'device_spacing_in_row' - double [m]\\n" +" 'number_rows' - double [-]\\n" +" 'row_spacing' - double [m]\\n" +" 'cable_system_overbuild' - double [%]\\n" +"Output: key-value pairs added to var_table\\n" +" 'inter_array_cable_voltage' - double [m]\\n"; + +SSCEXPORT bool me_array_cable_voltage(ssc_data_t data); + #ifdef __cplusplus } From 29dc5ddf49f7949053f1ebd1a20c6b19b5985006 Mon Sep 17 00:00:00 2001 From: Matt Prilliman Date: Fri, 2 Dec 2022 12:56:10 -0700 Subject: [PATCH 03/22] Onshore substation cost assignment --- ssc/cmod_mhk_eqns.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/ssc/cmod_mhk_eqns.cpp b/ssc/cmod_mhk_eqns.cpp index 9e803f57e..efd2e7142 100644 --- a/ssc/cmod_mhk_eqns.cpp +++ b/ssc/cmod_mhk_eqns.cpp @@ -106,14 +106,6 @@ bool me_array_cable_voltage(ssc_data_t data) vt_get_number(vt, "inter_array_cable_length", &inter_array_cable_length); vt_get_number(vt, "riser_cable_length", &riser_cable_length); vt_get_number(vt, "export_cable_length", &export_cable_length); - vt_get_number(vt, "number_rows", &number_rows); - vt_get_number(vt, "row_spacing", &row_spacing); - vt_get_number(vt, "cable_system_overbuild", &cable_system_overbuild); - vt_get_number(vt, "floating_array", &floating_array); - vt_get_number(vt, "export_cable_redundancy", &export_cable_redundancy); - vt_get_number(vt, "water_depth", &water_depth); - vt_get_number(vt, "number_devices", &number_devices); - vt_get_number(vt, "distance_to_shore", &distance_to_shore); vt_get_number(vt, "use_onshore_substation", &use_onshore_substation); vt_get_number(vt, "load_grid_voltage", &load_grid_voltage); @@ -253,6 +245,7 @@ bool me_array_cable_voltage(ssc_data_t data) } vt->assign("export_cable_voltage", export_cable_voltage); vt->assign("export_cable_cost", export_cable_cost); + vt->assign("export_cable_type", export_cable_type); double export_cable_cost_total = export_cable_cost * export_cable_length; vt->assign("export_cable_cost_total", export_cable_cost_total); @@ -275,6 +268,7 @@ bool me_array_cable_voltage(ssc_data_t data) else if (array_cable_voltage == export_cable_voltage && export_cable_type == 1) { offshore_substation_cost_total = offshore_foundation_cost + hvdc_converter_station_cost; } + vt->assign("offshore_substation_cost_total", offshore_substation_cost_total); //Onshore substation double onshore_substation_voltage = load_grid_voltage; @@ -295,6 +289,7 @@ bool me_array_cable_voltage(ssc_data_t data) else if (use_onshore_substation==1 && export_cable_type == 1) { onshore_substation_cost_total = onshore_foundation_cost + onshore_hvdc_converter_station_cost; } + vt->assign("onshore_substation_cost_total", onshore_substation_cost_total); } From e32afe50dcf7e5a023ef7481843d1e7723d59c5e Mon Sep 17 00:00:00 2001 From: Matt Prilliman Date: Wed, 7 Dec 2022 13:00:30 -0700 Subject: [PATCH 04/22] Added equation definition to list --- ssc/ssc_equations.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ssc/ssc_equations.h b/ssc/ssc_equations.h index d88ac3eab..51ebc6316 100644 --- a/ssc/ssc_equations.h +++ b/ssc/ssc_equations.h @@ -84,6 +84,9 @@ static ssc_equation_entry ssc_equation_table [] = { // Marine energy {"me_array_cable_length", me_array_cable_length, "Marine energy", me_array_cable_length_doc, + false, true}, + {"me_array_cable_voltage", me_array_cable_voltage, + "Marine energy", me_array_cable_voltage_doc, false, true}, {"mp_ancillary_services", mp_ancillary_services, "Merchant plant", mp_ancillary_services_doc, From 40c791899b57fb7df3105f5e03bf770a17ea8a22 Mon Sep 17 00:00:00 2001 From: Matt Prilliman Date: Thu, 29 Dec 2022 12:08:19 -0700 Subject: [PATCH 05/22] Fixed riser cable cost calc --- ssc/cmod_mhk_eqns.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ssc/cmod_mhk_eqns.cpp b/ssc/cmod_mhk_eqns.cpp index efd2e7142..da6c8b746 100644 --- a/ssc/cmod_mhk_eqns.cpp +++ b/ssc/cmod_mhk_eqns.cpp @@ -133,7 +133,7 @@ bool me_array_cable_voltage(ssc_data_t data) double riser_cable_cost = 0; //$/m if ( array_cable_rated_power_per_row < 4) { riser_cable_voltage = 7.2; - riser_cable_cost = 57.955 * array_cable_rated_power_per_row; + riser_cable_cost = 57.955 * riser_cable_rated_power_per_device; } else if (riser_cable_rated_power_per_device >= 5 && riser_cable_rated_power_per_device < 9) { riser_cable_voltage = 12; @@ -261,11 +261,11 @@ bool me_array_cable_voltage(ssc_data_t data) //HVDC Electrical equipment double hvdc_converter_station_cost = 142.61 * system_capacity; double offshore_substation_cost_total = 0; - if (array_cable_voltage == export_cable_voltage && export_cable_type == 0) { + if (array_cable_voltage != export_cable_voltage && export_cable_type == 0) { offshore_substation_cost_total = offshore_foundation_cost + circuit_breaker_cost + ac_switchgear_cost + transformer_cost + shunt_reactor_cost + series_capacitor_cost + static_var_compensator_cost; } - else if (array_cable_voltage == export_cable_voltage && export_cable_type == 1) { + else if (array_cable_voltage != export_cable_voltage && export_cable_type == 1) { offshore_substation_cost_total = offshore_foundation_cost + hvdc_converter_station_cost; } vt->assign("offshore_substation_cost_total", offshore_substation_cost_total); @@ -281,12 +281,12 @@ bool me_array_cable_voltage(ssc_data_t data) double onshore_static_var_compensator_cost = 105060 * reactive_power; //HVDC Electrical equipment double onshore_hvdc_converter_station_cost = 142.61 * system_capacity; - double onshore_substation_cost_total; - if (use_onshore_substation==1 && export_cable_type == 0) { + double onshore_substation_cost_total = 0; + if (use_onshore_substation==0 && export_cable_type == 0) { onshore_substation_cost_total = onshore_foundation_cost + onshore_circuit_breaker_cost + onshore_ac_switchgear_cost + onshore_transformer_cost + onshore_shunt_reactor_cost + onshore_series_capacitor_cost + onshore_static_var_compensator_cost; } - else if (use_onshore_substation==1 && export_cable_type == 1) { + else if (use_onshore_substation==0 && export_cable_type == 1) { onshore_substation_cost_total = onshore_foundation_cost + onshore_hvdc_converter_station_cost; } vt->assign("onshore_substation_cost_total", onshore_substation_cost_total); From dcf8eae3e679bdf97f8bc965901e593e3d44dac3 Mon Sep 17 00:00:00 2001 From: Matt Prilliman Date: Tue, 7 Feb 2023 11:34:18 -0700 Subject: [PATCH 06/22] Fix constraint for structural assembly number of modeling options --- ssc/cmod_mhk_costs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ssc/cmod_mhk_costs.cpp b/ssc/cmod_mhk_costs.cpp index 59832fcf9..3954ab8bb 100644 --- a/ssc/cmod_mhk_costs.cpp +++ b/ssc/cmod_mhk_costs.cpp @@ -53,7 +53,7 @@ static var_info _cm_vtab_mhk_costs[] = { { SSC_INPUT, SSC_NUMBER, "export_cable_length", "Export cable length", "m", "", "MHKCosts", "*", "MIN=0", "" }, // User input for CapEx dependent costs - { SSC_INPUT, SSC_NUMBER, "structural_assembly_cost_method", "Structural assembly cost method", "0/1/2", "0=Enter in $/kW,1=Enter in $,2=Use modeled value,3=Use itemized costs in $", "MHKCosts", "*", "MIN=0,MAX=3", "" }, + { SSC_INPUT, SSC_NUMBER, "structural_assembly_cost_method", "Structural assembly cost method", "0/1/2", "0=Enter in $/kW,1=Enter in $,2=Use modeled value,3=Use itemized costs in $", "MHKCosts", "*", "MIN=0,MAX=4", "" }, { SSC_INPUT, SSC_NUMBER, "structural_assembly_cost_input", "Structural assembly cost", "$", "", "MHKCosts", "*", "", "" }, //{ SSC_INPUT, SSC_NUMBER, "structural_assembly_cost_total", "Structural assembly itemized cost total", "$", "", "MHKCosts", "*", "", "" }, { SSC_INPUT, SSC_NUMBER, "power_takeoff_system_cost_method", "Power take-off system cost method", "0/1/2", "0=Enter in $/kW,1=Enter in $,2=Use modeled value,3=Use itemized costs in $", "MHKCosts", "*", "MIN=0,MAX=3", "" }, From 370595669f6cf17cc2b6a73be35c75c03cc459df Mon Sep 17 00:00:00 2001 From: Matt Prilliman Date: Wed, 15 Feb 2023 10:30:54 -0700 Subject: [PATCH 07/22] ssc equation for tidal turbine design --- ssc/cmod_mhk_eqns.cpp | 70 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/ssc/cmod_mhk_eqns.cpp b/ssc/cmod_mhk_eqns.cpp index d34b74ea7..98689f399 100644 --- a/ssc/cmod_mhk_eqns.cpp +++ b/ssc/cmod_mhk_eqns.cpp @@ -89,5 +89,75 @@ bool me_array_cable_length(ssc_data_t data) return true; } +bool tidal_turbine_calculate_powercurve(ssc_data_t data) +{ + auto vt = static_cast(data); + if (!vt) { + return false; + } + + double turbine_size, rotor_diameter, elevation, max_cp, max_tip_speed, max_tip_sp_ratio, cut_in, + cut_out, rotor_area, generator_rated_capacity, water_depth, velocity_power_law_fit, number_rotors; + int drive_train; + util::matrix_t tidal_resource; + double pto_efficiency, min_vel; + + try { + vt_get_number(vt, "turbine_size", &turbine_size); + vt_get_number(vt, "tidal_turbine_rotor_diameter", &rotor_diameter); // ssc input + vt_get_number(vt, "number_rotors", &number_rotors); + vt_get_number(vt, "elevation", &elevation); + vt_get_number(vt, "tidal_turbine_max_cp", &max_cp); // ssc input + vt_get_number(vt, "cut_in", &cut_in); + vt_get_number(vt, "cut_out", &cut_out); + vt_get_matrix(vt, "tidal_resource", tidal_resource); + vt_get_number(vt, "generator_rated_capacity", &generator_rated_capacity); + vt_get_number(vt, "water_depth", &water_depth); + vt_get_number(vt, "velocity_power_law_fit", &velocity_power_law_fit); + vt_get_number(vt, "pto_efficiency", &pto_efficiency); + vt_get_number(vt, "min_tidal_velocity", &min_vel); + + } + catch (std::runtime_error& e) { + vt->assign("error", var_data(e.what())); + return false; + } + + util::matrix_t powercurve_tidespeeds; + util::matrix_t powercurve_powerout; + util::matrix_t powercurve_hub_efficiency; + + char errmsg[250]; + + + size_t array_size = tidal_resource.nrows(); + + powercurve_tidespeeds.resize(array_size); + powercurve_powerout.resize(array_size); + rotor_area = pow((rotor_diameter / 2), 2) * M_PI * number_rotors; + double tidal_vel, p_fluid, p_rotor, eff, p_electric; + for (size_t i = 0; i < array_size; i += 1) { + tidal_vel = tidal_resource[i]; + p_fluid = 0.5 * pow(tidal_vel, 3) * 1.025 * rotor_area; + p_rotor = p_fluid * max_cp; + eff = pto_efficiency; + if (tidal_vel < cut_in) eff = 0; + if (tidal_vel > cut_out) eff = 0; + p_electric = std::min(eff * p_rotor, generator_rated_capacity); + powercurve_powerout[i] = p_electric; + powercurve_tidespeeds[i] = tidal_vel; + + } + + var_data windspeeds = var_data(powercurve_tidespeeds.data(), powercurve_tidespeeds.ncols()); + var_data powerout = var_data(powercurve_powerout.data(), powercurve_powerout.ncols()); + + vt->assign("tidal_turbine_powercurve_tidespeeds", windspeeds); + vt->assign("tidal_turbine_powercurve_powerout", powerout); + sprintf(errmsg, "None"); + vt->assign("error", std::string(errmsg)); + return true; +} + From 64620279f5670810f2e5775eaa3f3c4e1d2a5e50 Mon Sep 17 00:00:00 2001 From: Matt Prilliman Date: Thu, 16 Feb 2023 08:41:40 -0700 Subject: [PATCH 08/22] Fixed inputs list for ssc eqn --- ssc/cmod_mhk_eqns.cpp | 6 ++---- ssc/cmod_mhk_eqns.h | 2 ++ ssc/ssc_equations.h | 3 +++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ssc/cmod_mhk_eqns.cpp b/ssc/cmod_mhk_eqns.cpp index 98689f399..0c366cedf 100644 --- a/ssc/cmod_mhk_eqns.cpp +++ b/ssc/cmod_mhk_eqns.cpp @@ -106,7 +106,6 @@ bool tidal_turbine_calculate_powercurve(ssc_data_t data) vt_get_number(vt, "turbine_size", &turbine_size); vt_get_number(vt, "tidal_turbine_rotor_diameter", &rotor_diameter); // ssc input vt_get_number(vt, "number_rotors", &number_rotors); - vt_get_number(vt, "elevation", &elevation); vt_get_number(vt, "tidal_turbine_max_cp", &max_cp); // ssc input vt_get_number(vt, "cut_in", &cut_in); vt_get_number(vt, "cut_out", &cut_out); @@ -115,7 +114,6 @@ bool tidal_turbine_calculate_powercurve(ssc_data_t data) vt_get_number(vt, "water_depth", &water_depth); vt_get_number(vt, "velocity_power_law_fit", &velocity_power_law_fit); vt_get_number(vt, "pto_efficiency", &pto_efficiency); - vt_get_number(vt, "min_tidal_velocity", &min_vel); } catch (std::runtime_error& e) { @@ -137,10 +135,10 @@ bool tidal_turbine_calculate_powercurve(ssc_data_t data) rotor_area = pow((rotor_diameter / 2), 2) * M_PI * number_rotors; double tidal_vel, p_fluid, p_rotor, eff, p_electric; for (size_t i = 0; i < array_size; i += 1) { - tidal_vel = tidal_resource[i]; + tidal_vel = tidal_resource.at(i,0); p_fluid = 0.5 * pow(tidal_vel, 3) * 1.025 * rotor_area; p_rotor = p_fluid * max_cp; - eff = pto_efficiency; + eff = pto_efficiency/100.0; if (tidal_vel < cut_in) eff = 0; if (tidal_vel > cut_out) eff = 0; p_electric = std::min(eff * p_rotor, generator_rated_capacity); diff --git a/ssc/cmod_mhk_eqns.h b/ssc/cmod_mhk_eqns.h index 112e7d193..e0b8e5f7a 100644 --- a/ssc/cmod_mhk_eqns.h +++ b/ssc/cmod_mhk_eqns.h @@ -53,6 +53,8 @@ static const char* me_array_cable_length_doc = SSCEXPORT bool me_array_cable_length(ssc_data_t data); +SSCEXPORT bool tidal_turbine_calculate_powercurve(ssc_data_t data); + #ifdef __cplusplus } diff --git a/ssc/ssc_equations.h b/ssc/ssc_equations.h index d88ac3eab..febf799f5 100644 --- a/ssc/ssc_equations.h +++ b/ssc/ssc_equations.h @@ -84,6 +84,9 @@ static ssc_equation_entry ssc_equation_table [] = { // Marine energy {"me_array_cable_length", me_array_cable_length, "Marine energy", me_array_cable_length_doc, + false, true}, + {"tidal_turbine_calculate_powercurve", tidal_turbine_calculate_powercurve, + "Marine energy", me_array_cable_length_doc, false, true}, {"mp_ancillary_services", mp_ancillary_services, "Merchant plant", mp_ancillary_services_doc, From f1c2f34640d26c69bd8f3b0f4580612b79e4b22a Mon Sep 17 00:00:00 2001 From: Matt Prilliman Date: Fri, 17 Feb 2023 12:08:32 -0700 Subject: [PATCH 09/22] Remove unused inputs --- ssc/cmod_mhk_eqns.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/ssc/cmod_mhk_eqns.cpp b/ssc/cmod_mhk_eqns.cpp index 0c366cedf..88d6d4349 100644 --- a/ssc/cmod_mhk_eqns.cpp +++ b/ssc/cmod_mhk_eqns.cpp @@ -103,7 +103,6 @@ bool tidal_turbine_calculate_powercurve(ssc_data_t data) double pto_efficiency, min_vel; try { - vt_get_number(vt, "turbine_size", &turbine_size); vt_get_number(vt, "tidal_turbine_rotor_diameter", &rotor_diameter); // ssc input vt_get_number(vt, "number_rotors", &number_rotors); vt_get_number(vt, "tidal_turbine_max_cp", &max_cp); // ssc input @@ -111,8 +110,6 @@ bool tidal_turbine_calculate_powercurve(ssc_data_t data) vt_get_number(vt, "cut_out", &cut_out); vt_get_matrix(vt, "tidal_resource", tidal_resource); vt_get_number(vt, "generator_rated_capacity", &generator_rated_capacity); - vt_get_number(vt, "water_depth", &water_depth); - vt_get_number(vt, "velocity_power_law_fit", &velocity_power_law_fit); vt_get_number(vt, "pto_efficiency", &pto_efficiency); } From 25435c6db236ebb918c09b9d3f03d0651424f158 Mon Sep 17 00:00:00 2001 From: Matt Prilliman Date: Thu, 23 Feb 2023 10:17:05 -0700 Subject: [PATCH 10/22] numericsched inputs for pto eff, max cp inputs --- ssc/cmod_mhk_eqns.cpp | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/ssc/cmod_mhk_eqns.cpp b/ssc/cmod_mhk_eqns.cpp index 88d6d4349..3c5b0192b 100644 --- a/ssc/cmod_mhk_eqns.cpp +++ b/ssc/cmod_mhk_eqns.cpp @@ -96,21 +96,24 @@ bool tidal_turbine_calculate_powercurve(ssc_data_t data) return false; } - double turbine_size, rotor_diameter, elevation, max_cp, max_tip_speed, max_tip_sp_ratio, cut_in, + double turbine_size, rotor_diameter, elevation, max_tip_speed, max_tip_sp_ratio, cut_in, cut_out, rotor_area, generator_rated_capacity, water_depth, velocity_power_law_fit, number_rotors; int drive_train; util::matrix_t tidal_resource; - double pto_efficiency, min_vel; + double min_vel; + int max_cp_length, pto_efficiency_length; + std::vector pto_efficiency; + std::vector max_cp; try { vt_get_number(vt, "tidal_turbine_rotor_diameter", &rotor_diameter); // ssc input vt_get_number(vt, "number_rotors", &number_rotors); - vt_get_number(vt, "tidal_turbine_max_cp", &max_cp); // ssc input + vt_get_array_vec(vt, "tidal_turbine_max_cp", max_cp); // ssc input + vt_get_array_vec(vt, "pto_efficiency", pto_efficiency); vt_get_number(vt, "cut_in", &cut_in); vt_get_number(vt, "cut_out", &cut_out); vt_get_matrix(vt, "tidal_resource", tidal_resource); vt_get_number(vt, "generator_rated_capacity", &generator_rated_capacity); - vt_get_number(vt, "pto_efficiency", &pto_efficiency); } catch (std::runtime_error& e) { @@ -131,11 +134,25 @@ bool tidal_turbine_calculate_powercurve(ssc_data_t data) powercurve_powerout.resize(array_size); rotor_area = pow((rotor_diameter / 2), 2) * M_PI * number_rotors; double tidal_vel, p_fluid, p_rotor, eff, p_electric; + double max_cp_value, pto_eff_value; for (size_t i = 0; i < array_size; i += 1) { tidal_vel = tidal_resource.at(i,0); p_fluid = 0.5 * pow(tidal_vel, 3) * 1.025 * rotor_area; - p_rotor = p_fluid * max_cp; - eff = pto_efficiency/100.0; + + if (max_cp.size() == 1) { + max_cp_value = max_cp[0]; + } + else { + max_cp_value = max_cp[i]; + } + p_rotor = p_fluid * max_cp_value; + if (pto_efficiency.size() == 1) { + pto_eff_value = pto_efficiency[0]; + } + else { + pto_eff_value = pto_efficiency[i]; + } + eff = pto_eff_value/100.0; if (tidal_vel < cut_in) eff = 0; if (tidal_vel > cut_out) eff = 0; p_electric = std::min(eff * p_rotor, generator_rated_capacity); From b28f443d0213cb51c49a413c7773dad91b94687c Mon Sep 17 00:00:00 2001 From: Steven Janzou Date: Sat, 4 Mar 2023 03:25:43 -0700 Subject: [PATCH 11/22] Address loss diagram issue for POA reference cell in SAM issue 1366 --- ssc/cmod_pvsamv1.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ssc/cmod_pvsamv1.cpp b/ssc/cmod_pvsamv1.cpp index 9369d6b1a..17a85b0ad 100644 --- a/ssc/cmod_pvsamv1.cpp +++ b/ssc/cmod_pvsamv1.cpp @@ -1789,7 +1789,11 @@ void cm_pvsamv1::exec() } // Calculate total front irradiation after soiling added to shading - ipoa_front[nn] = ibeam + iskydiff + ignddiff; + if (radmode == irrad::POA_R || radmode == irrad::POA_P) + ipoa_front[nn] = ipoa[nn]; + else + ipoa_front[nn] = ibeam + iskydiff + ignddiff; + ts_accum_poa_front_shaded_soiled += ipoa_front[nn] * ref_area_m2 * Subarrays[nn]->nModulesPerString * Subarrays[nn]->nStrings; // Calculate rear-side irradiance From 75c059d365d3a641d14ccd893c144b2c51948820 Mon Sep 17 00:00:00 2001 From: Steven Janzou Date: Mon, 6 Mar 2023 04:18:40 -0700 Subject: [PATCH 12/22] Working without pressure column Need to remove some modifications in cmod_pvsamv1 - set to SAM_1366 branch --- shared/lib_irradproc.cpp | 11 +++++++---- ssc/cmod_pvsamv1.cpp | 23 ++++++++++++----------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/shared/lib_irradproc.cpp b/shared/lib_irradproc.cpp index ce792d594..11e844e69 100644 --- a/shared/lib_irradproc.cpp +++ b/shared/lib_irradproc.cpp @@ -1233,6 +1233,8 @@ calculate_spa(double jd, double lat, double lng, double alt, double pressure, do double atmos_refract = 0.5667; // atmospheric refraction for check if sun is below horizon double del_e = atmospheric_refraction_correction(pressure, temp, atmos_refract, e0); // atmospheric refraction correction in degrees, returns 0 if sun is below horizon + if (std::isnan(del_e)) del_e = 0; + double e = topocentric_elevation_angle_corrected(e0, del_e); // Topocentric elevation angle corrected for refraction (degrees) needed_values[6] = e; // Pass topocentric elevation angle as an output of solarpos_spa (degrees) @@ -1824,8 +1826,10 @@ int poaDecomp(double, double angle[], double sun[], double alb, poaDecompReq *pA dnTmp, dfTmp, ghTmp, poaTmp); } } - - avgKtp /= count; + // fails when count = 0; + //avgKtp /= count; + if (count > 0) + avgKtp /= count; //Calculate Kt double am = Min(15.25, 1.0 / (cos(sun[1]) + 0.15 * (pow(93.9 - sun[1] * 180 / M_PI, -1.253)))); // air mass @@ -1855,8 +1859,7 @@ int poaDecomp(double, double angle[], double sun[], double alb, poaDecompReq *pA gh = 0; errorcode = 42; } - if (df < - 0) //check for df before gh because gh is only calculated using dn and df, so is least likely to be the actual culprit + if (df < 0) //check for df before gh because gh is only calculated using dn and df, so is least likely to be the actual culprit { df = 0; errorcode = 41; diff --git a/ssc/cmod_pvsamv1.cpp b/ssc/cmod_pvsamv1.cpp index 17a85b0ad..b66a1aa0b 100644 --- a/ssc/cmod_pvsamv1.cpp +++ b/ssc/cmod_pvsamv1.cpp @@ -1480,6 +1480,7 @@ void cm_pvsamv1::exec() } else if (radmode == irrad::POA_P) { ipoa[nn] = wf.poa; + Subarrays[nn]->poa.usePOAFromWF = true; } if (Subarrays[nn]->Module->simpleEfficiencyForceNoPOA && (radmode == irrad::POA_R || radmode == irrad::POA_P)) { // only will be true if using a poa model AND spe module model AND spe_fp is < 1 @@ -1557,18 +1558,18 @@ void cm_pvsamv1::exec() // record sub-array plane of array output before computing shading and soiling if (iyear == 0 || save_full_lifetime_variables == 1) { - if (radmode != irrad::POA_R) - PVSystem->p_poaNominalFront[nn][idx] = (ssc_number_t)((ibeam + iskydiff + ignddiff)); - else + if ((radmode == irrad::POA_R) || (radmode == irrad::POA_P)) PVSystem->p_poaNominalFront[nn][idx] = (ssc_number_t)((ipoa[nn])); + else + PVSystem->p_poaNominalFront[nn][idx] = (ssc_number_t)((ibeam + iskydiff + ignddiff)); } // record sub-array contribution to total POA power for this time step (W) - if (radmode != irrad::POA_R) - ts_accum_poa_front_nom += (ibeam + iskydiff + ignddiff) * ref_area_m2 * Subarrays[nn]->nModulesPerString * Subarrays[nn]->nStrings; - else + if ((radmode == irrad::POA_R) || (radmode == irrad::POA_P)) ts_accum_poa_front_nom += (ipoa[nn]) * ref_area_m2 * Subarrays[nn]->nModulesPerString * Subarrays[nn]->nStrings; + else + ts_accum_poa_front_nom += (ibeam + iskydiff + ignddiff) * ref_area_m2 * Subarrays[nn]->nModulesPerString * Subarrays[nn]->nStrings; // record sub-array contribution to total POA beam power for this time step (W) ts_accum_poa_front_beam_nom += ibeam * ref_area_m2 * Subarrays[nn]->nModulesPerString * Subarrays[nn]->nStrings; @@ -1766,7 +1767,7 @@ void cm_pvsamv1::exec() throw exec_error("pvsamv1", util::format("Self-shading calculation failed at %d", (int)idx)); } - double poashad = (radmode == irrad::POA_R) ? ipoa[nn] : (ibeam + iskydiff + ignddiff); + double poashad = ((radmode == irrad::POA_R) || ((radmode == irrad::POA_P))) ? ipoa[nn] : (ibeam + iskydiff + ignddiff); // determine sub-array contribution to total shaded plane of array for this hour ts_accum_poa_front_shaded += poashad * ref_area_m2 * Subarrays[nn]->nModulesPerString * Subarrays[nn]->nStrings; @@ -1923,7 +1924,7 @@ void cm_pvsamv1::exec() Subarrays[nn]->poa.poaDiffuseFront = iskydiff; Subarrays[nn]->poa.poaGroundFront = ignddiff; Subarrays[nn]->poa.poaRear = Subarrays[nn]->Module->isBifacial ? ipoa_rear_after_losses[nn] : 0.; // TODO: why is setting to 0 necessary for some tests to pass? - Subarrays[nn]->poa.poaTotal = (radmode == irrad::POA_R) ? ipoa[nn] : (ipoa_front[nn] + ipoa_rear_after_losses[nn] * bifaciality); + Subarrays[nn]->poa.poaTotal = ((radmode == irrad::POA_R) || (radmode == irrad::POA_P)) ? ipoa[nn] : (ipoa_front[nn] + ipoa_rear_after_losses[nn] * bifaciality); Subarrays[nn]->poa.angleOfIncidenceDegrees = aoi; Subarrays[nn]->poa.sunUp = sunup; Subarrays[nn]->poa.surfaceTiltDegrees = stilt; @@ -2209,11 +2210,11 @@ void cm_pvsamv1::exec() if (iyear == 0 || save_full_lifetime_variables == 1) { ipoa_front[nn] *= out[nn].AOIModifier; - PVSystem->p_poaFront[nn][idx] = (radmode == irrad::POA_R) ? (ssc_number_t)ipoa[nn] : (ssc_number_t)(ipoa_front[nn]); - PVSystem->p_poaTotal[nn][idx] = (radmode == irrad::POA_R) ? (ssc_number_t)ipoa[nn] : (ssc_number_t)(ipoa_front[nn] + ipoa_rear_after_losses[nn] * bifaciality); + PVSystem->p_poaFront[nn][idx] = ((radmode == irrad::POA_R) || (radmode == irrad::POA_P)) ? (ssc_number_t)ipoa[nn] : (ssc_number_t)(ipoa_front[nn]); + PVSystem->p_poaTotal[nn][idx] = ((radmode == irrad::POA_R) || (radmode == irrad::POA_P)) ? (ssc_number_t)ipoa[nn] : (ssc_number_t)(ipoa_front[nn] + ipoa_rear_after_losses[nn] * bifaciality); ts_accum_poa_front_total += ipoa_front[nn] * ref_area_m2 * Subarrays[nn]->nModulesPerString * Subarrays[nn]->nStrings; - ts_accum_poa_total_eff += ((radmode == irrad::POA_R) ? ipoa[nn] : (ipoa_front[nn] + ipoa_rear_after_losses[nn] * bifaciality)) * ref_area_m2 * Subarrays[nn]->nModulesPerString * Subarrays[nn]->nStrings; + ts_accum_poa_total_eff += (((radmode == irrad::POA_R) || (radmode == irrad::POA_P))? ipoa[nn] : (ipoa_front[nn] + ipoa_rear_after_losses[nn] * bifaciality)) * ref_area_m2 * Subarrays[nn]->nModulesPerString * Subarrays[nn]->nStrings; //assign final string voltage output PVSystem->p_dcStringVoltage[nn][idx] = (ssc_number_t)Subarrays[nn]->Module->dcVoltage * Subarrays[nn]->nModulesPerString; From d050a8de3ee8be6e07fa52324a40f11e83ba156d Mon Sep 17 00:00:00 2001 From: Steven Janzou Date: Tue, 7 Mar 2023 02:53:15 -0700 Subject: [PATCH 13/22] Reset POA_P mode - uses decomposition with and without pressure column --- ssc/cmod_pvsamv1.cpp | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/ssc/cmod_pvsamv1.cpp b/ssc/cmod_pvsamv1.cpp index b66a1aa0b..17a85b0ad 100644 --- a/ssc/cmod_pvsamv1.cpp +++ b/ssc/cmod_pvsamv1.cpp @@ -1480,7 +1480,6 @@ void cm_pvsamv1::exec() } else if (radmode == irrad::POA_P) { ipoa[nn] = wf.poa; - Subarrays[nn]->poa.usePOAFromWF = true; } if (Subarrays[nn]->Module->simpleEfficiencyForceNoPOA && (radmode == irrad::POA_R || radmode == irrad::POA_P)) { // only will be true if using a poa model AND spe module model AND spe_fp is < 1 @@ -1558,18 +1557,18 @@ void cm_pvsamv1::exec() // record sub-array plane of array output before computing shading and soiling if (iyear == 0 || save_full_lifetime_variables == 1) { - if ((radmode == irrad::POA_R) || (radmode == irrad::POA_P)) - PVSystem->p_poaNominalFront[nn][idx] = (ssc_number_t)((ipoa[nn])); - else + if (radmode != irrad::POA_R) PVSystem->p_poaNominalFront[nn][idx] = (ssc_number_t)((ibeam + iskydiff + ignddiff)); + else + PVSystem->p_poaNominalFront[nn][idx] = (ssc_number_t)((ipoa[nn])); } // record sub-array contribution to total POA power for this time step (W) - if ((radmode == irrad::POA_R) || (radmode == irrad::POA_P)) - ts_accum_poa_front_nom += (ipoa[nn]) * ref_area_m2 * Subarrays[nn]->nModulesPerString * Subarrays[nn]->nStrings; - else + if (radmode != irrad::POA_R) ts_accum_poa_front_nom += (ibeam + iskydiff + ignddiff) * ref_area_m2 * Subarrays[nn]->nModulesPerString * Subarrays[nn]->nStrings; + else + ts_accum_poa_front_nom += (ipoa[nn]) * ref_area_m2 * Subarrays[nn]->nModulesPerString * Subarrays[nn]->nStrings; // record sub-array contribution to total POA beam power for this time step (W) ts_accum_poa_front_beam_nom += ibeam * ref_area_m2 * Subarrays[nn]->nModulesPerString * Subarrays[nn]->nStrings; @@ -1767,7 +1766,7 @@ void cm_pvsamv1::exec() throw exec_error("pvsamv1", util::format("Self-shading calculation failed at %d", (int)idx)); } - double poashad = ((radmode == irrad::POA_R) || ((radmode == irrad::POA_P))) ? ipoa[nn] : (ibeam + iskydiff + ignddiff); + double poashad = (radmode == irrad::POA_R) ? ipoa[nn] : (ibeam + iskydiff + ignddiff); // determine sub-array contribution to total shaded plane of array for this hour ts_accum_poa_front_shaded += poashad * ref_area_m2 * Subarrays[nn]->nModulesPerString * Subarrays[nn]->nStrings; @@ -1924,7 +1923,7 @@ void cm_pvsamv1::exec() Subarrays[nn]->poa.poaDiffuseFront = iskydiff; Subarrays[nn]->poa.poaGroundFront = ignddiff; Subarrays[nn]->poa.poaRear = Subarrays[nn]->Module->isBifacial ? ipoa_rear_after_losses[nn] : 0.; // TODO: why is setting to 0 necessary for some tests to pass? - Subarrays[nn]->poa.poaTotal = ((radmode == irrad::POA_R) || (radmode == irrad::POA_P)) ? ipoa[nn] : (ipoa_front[nn] + ipoa_rear_after_losses[nn] * bifaciality); + Subarrays[nn]->poa.poaTotal = (radmode == irrad::POA_R) ? ipoa[nn] : (ipoa_front[nn] + ipoa_rear_after_losses[nn] * bifaciality); Subarrays[nn]->poa.angleOfIncidenceDegrees = aoi; Subarrays[nn]->poa.sunUp = sunup; Subarrays[nn]->poa.surfaceTiltDegrees = stilt; @@ -2210,11 +2209,11 @@ void cm_pvsamv1::exec() if (iyear == 0 || save_full_lifetime_variables == 1) { ipoa_front[nn] *= out[nn].AOIModifier; - PVSystem->p_poaFront[nn][idx] = ((radmode == irrad::POA_R) || (radmode == irrad::POA_P)) ? (ssc_number_t)ipoa[nn] : (ssc_number_t)(ipoa_front[nn]); - PVSystem->p_poaTotal[nn][idx] = ((radmode == irrad::POA_R) || (radmode == irrad::POA_P)) ? (ssc_number_t)ipoa[nn] : (ssc_number_t)(ipoa_front[nn] + ipoa_rear_after_losses[nn] * bifaciality); + PVSystem->p_poaFront[nn][idx] = (radmode == irrad::POA_R) ? (ssc_number_t)ipoa[nn] : (ssc_number_t)(ipoa_front[nn]); + PVSystem->p_poaTotal[nn][idx] = (radmode == irrad::POA_R) ? (ssc_number_t)ipoa[nn] : (ssc_number_t)(ipoa_front[nn] + ipoa_rear_after_losses[nn] * bifaciality); ts_accum_poa_front_total += ipoa_front[nn] * ref_area_m2 * Subarrays[nn]->nModulesPerString * Subarrays[nn]->nStrings; - ts_accum_poa_total_eff += (((radmode == irrad::POA_R) || (radmode == irrad::POA_P))? ipoa[nn] : (ipoa_front[nn] + ipoa_rear_after_losses[nn] * bifaciality)) * ref_area_m2 * Subarrays[nn]->nModulesPerString * Subarrays[nn]->nStrings; + ts_accum_poa_total_eff += ((radmode == irrad::POA_R) ? ipoa[nn] : (ipoa_front[nn] + ipoa_rear_after_losses[nn] * bifaciality)) * ref_area_m2 * Subarrays[nn]->nModulesPerString * Subarrays[nn]->nStrings; //assign final string voltage output PVSystem->p_dcStringVoltage[nn][idx] = (ssc_number_t)Subarrays[nn]->Module->dcVoltage * Subarrays[nn]->nModulesPerString; From 803f6bb8deef8a522762fba148877b115998a748 Mon Sep 17 00:00:00 2001 From: Paul Gilman Date: Tue, 7 Mar 2023 09:27:46 -0800 Subject: [PATCH 14/22] Add wfpoa to reported outputs to facilitate troubleshooting --- shared/lib_pv_io_manager.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/shared/lib_pv_io_manager.cpp b/shared/lib_pv_io_manager.cpp index 979731b7f..5ab85a694 100644 --- a/shared/lib_pv_io_manager.cpp +++ b/shared/lib_pv_io_manager.cpp @@ -295,6 +295,8 @@ void Irradiance_IO::AllocateOutputs(compute_module* cm) p_weatherFileGHI = cm->allocate("gh", numberOfWeatherFileRecords); p_weatherFileDNI = cm->allocate("dn", numberOfWeatherFileRecords); p_weatherFileDHI = cm->allocate("df", numberOfWeatherFileRecords); + p_weatherFilePOA.push_back(cm->allocate("wfpoa", numberOfWeatherFileRecords)); + p_sunPositionTime = cm->allocate("sunpos_hour", numberOfWeatherFileRecords); p_weatherFileWindSpeed = cm->allocate("wspd", numberOfWeatherFileRecords); p_weatherFileAmbientTemp = cm->allocate("tdry", numberOfWeatherFileRecords); From 9c319bb615dabe4b136abe734ea6ee54c43f0863 Mon Sep 17 00:00:00 2001 From: Matthew Boyd <30417543+Matthew-Boyd@users.noreply.github.com> Date: Thu, 9 Mar 2023 11:41:40 -0700 Subject: [PATCH 15/22] Size the collector loop mass flow based on n_collectors (#1004) --- ssc/cmod_swh.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ssc/cmod_swh.cpp b/ssc/cmod_swh.cpp index 81a25783f..8b302272a 100644 --- a/ssc/cmod_swh.cpp +++ b/ssc/cmod_swh.cpp @@ -277,7 +277,7 @@ class cm_swh : public compute_module double test_flow = as_double("test_flow"); // collector test flow rate (kg/s) /* collector properties */ - double mdot_total = as_double("mdot"); // total system mass flow rate (kg/s) + double mdot_total = as_double("test_flow") * as_integer("ncoll"); // total system mass flow rate (kg/s) double area_total = as_double("area_coll") * as_integer("ncoll"); // total solar collector area (m2) double area_coll = as_double("area_coll"); From b400059d52790c348868fe04f9fb04509b20fa65 Mon Sep 17 00:00:00 2001 From: Matt Prilliman Date: Wed, 15 Mar 2023 13:40:18 -0600 Subject: [PATCH 16/22] Reset max options for cost method variables --- ssc/cmod_mhk_costs.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/ssc/cmod_mhk_costs.cpp b/ssc/cmod_mhk_costs.cpp index 3954ab8bb..f8c94e744 100644 --- a/ssc/cmod_mhk_costs.cpp +++ b/ssc/cmod_mhk_costs.cpp @@ -56,32 +56,32 @@ static var_info _cm_vtab_mhk_costs[] = { { SSC_INPUT, SSC_NUMBER, "structural_assembly_cost_method", "Structural assembly cost method", "0/1/2", "0=Enter in $/kW,1=Enter in $,2=Use modeled value,3=Use itemized costs in $", "MHKCosts", "*", "MIN=0,MAX=4", "" }, { SSC_INPUT, SSC_NUMBER, "structural_assembly_cost_input", "Structural assembly cost", "$", "", "MHKCosts", "*", "", "" }, //{ SSC_INPUT, SSC_NUMBER, "structural_assembly_cost_total", "Structural assembly itemized cost total", "$", "", "MHKCosts", "*", "", "" }, - { SSC_INPUT, SSC_NUMBER, "power_takeoff_system_cost_method", "Power take-off system cost method", "0/1/2", "0=Enter in $/kW,1=Enter in $,2=Use modeled value,3=Use itemized costs in $", "MHKCosts", "*", "MIN=0,MAX=3", "" }, + { SSC_INPUT, SSC_NUMBER, "power_takeoff_system_cost_method", "Power take-off system cost method", "0/1/2", "0=Enter in $/kW,1=Enter in $,2=Use modeled value,3=Use itemized costs in $", "MHKCosts", "*", "MIN=0,MAX=4", "" }, { SSC_INPUT, SSC_NUMBER, "power_takeoff_system_cost_input", "Power take-off system cost", "$", "", "MHKCosts", "*", "", "" }, //{ SSC_INPUT, SSC_NUMBER, "power_takeoff_system_cost_total", "Power take-off system cost itemized cost total", "$", "", "MHKCosts", "*", "", "" }, - { SSC_INPUT, SSC_NUMBER, "mooring_found_substruc_cost_method", "Mooring, foundation, and substructure cost method", "0/1/2", "0=Enter in $/kW,1=Enter in $,2=Use modeled value,3=Use itemized costs in $", "MHKCosts", "*", "MIN=0,MAX=3", "" }, + { SSC_INPUT, SSC_NUMBER, "mooring_found_substruc_cost_method", "Mooring, foundation, and substructure cost method", "0/1/2", "0=Enter in $/kW,1=Enter in $,2=Use modeled value,3=Use itemized costs in $", "MHKCosts", "*", "MIN=0,MAX=4", "" }, { SSC_INPUT, SSC_NUMBER, "mooring_found_substruc_cost_input", "Mooring, foundation, and substructure cost", "$", "", "MHKCosts", "*", "", "" }, //{ SSC_INPUT, SSC_NUMBER, "mooring_found_substruc_cost_total", "Mooring, foundation, and substructure itemized cost total", "$", "", "MHKCosts", "*", "", "" }, // User input BOS values - { SSC_INPUT, SSC_NUMBER, "development_cost_method", "Development cost method", "0/1/2", "0=Enter in $/kW,1=Enter in $,2=Use modeled value,3=Enter in itemized costs", "MHKCosts", "*", "MIN=0,MAX=3", "" }, + { SSC_INPUT, SSC_NUMBER, "development_cost_method", "Development cost method", "0/1/2", "0=Enter in $/kW,1=Enter in $,2=Use modeled value,3=Enter in itemized costs", "MHKCosts", "*", "MIN=0,MAX=4", "" }, { SSC_INPUT, SSC_NUMBER, "development_cost_input", "Development cost", "$", "", "MHKCosts", "*", "", "" }, - { SSC_INPUT, SSC_NUMBER, "eng_and_mgmt_cost_method", "Engineering and management cost method", "0/1/2", "0=Enter in $/kW,1=Enter in $,2=Use modeled value,3=Enter in itemized costs", "MHKCosts", "*", "MIN=0,MAX=3", "" }, + { SSC_INPUT, SSC_NUMBER, "eng_and_mgmt_cost_method", "Engineering and management cost method", "0/1/2", "0=Enter in $/kW,1=Enter in $,2=Use modeled value,3=Enter in itemized costs", "MHKCosts", "*", "MIN=0,MAX=4", "" }, { SSC_INPUT, SSC_NUMBER, "eng_and_mgmt_cost_input", "Engineering and management cost", "$", "", "MHKCosts", "*", "", "" }, - { SSC_INPUT, SSC_NUMBER, "assembly_and_install_cost_method", "Assembly and installation cost method", "0/1/2", "0=Enter in $/kW,1=Enter in $,2=Use modeled value", "MHKCosts", "*", "MIN=0,MAX=3", "" }, + { SSC_INPUT, SSC_NUMBER, "assembly_and_install_cost_method", "Assembly and installation cost method", "0/1/2", "0=Enter in $/kW,1=Enter in $,2=Use modeled value", "MHKCosts", "*", "MIN=0,MAX=4", "" }, { SSC_INPUT, SSC_NUMBER, "assembly_and_install_cost_input", "Assembly and installation cost", "$", "", "MHKCosts", "*", "", "" }, - { SSC_INPUT, SSC_NUMBER, "other_infrastructure_cost_method", "Other infrastructure cost method", "0/1/2", "0=Enter in $/kW,1=Enter in $,2=Use modeled value", "MHKCosts", "*", "MIN=0,MAX=3", "" }, + { SSC_INPUT, SSC_NUMBER, "other_infrastructure_cost_method", "Other infrastructure cost method", "0/1/2", "0=Enter in $/kW,1=Enter in $,2=Use modeled value", "MHKCosts", "*", "MIN=0,MAX=4", "" }, { SSC_INPUT, SSC_NUMBER, "other_infrastructure_cost_input", "Other infrastructure cost", "$", "", "MHKCosts", "*", "", "" }, - { SSC_INPUT, SSC_NUMBER, "array_cable_system_cost_method", "Array cable system cost method", "0/1/2", "0=Enter in $/kW,1=Enter in $,2=Use modeled value", "MHKCosts", "*", "MIN=0,MAX=3", "" }, + { SSC_INPUT, SSC_NUMBER, "array_cable_system_cost_method", "Array cable system cost method", "0/1/2", "0=Enter in $/kW,1=Enter in $,2=Use modeled value", "MHKCosts", "*", "MIN=0,MAX=4", "" }, { SSC_INPUT, SSC_NUMBER, "array_cable_system_cost_input", "Array cable system cost", "$", "", "MHKCosts", "*", "", "" }, - { SSC_INPUT, SSC_NUMBER, "export_cable_system_cost_method", "Export cable system cost method", "0/1/2", "0=Enter in $/kW,1=Enter in $,2=Use modeled value", "MHKCosts", "*", "MIN=0,MAX=3", "" }, + { SSC_INPUT, SSC_NUMBER, "export_cable_system_cost_method", "Export cable system cost method", "0/1/2", "0=Enter in $/kW,1=Enter in $,2=Use modeled value", "MHKCosts", "*", "MIN=0,MAX=4", "" }, { SSC_INPUT, SSC_NUMBER, "export_cable_system_cost_input", "Export cable system cost", "$", "", "MHKCosts", "*", "", "" }, - { SSC_INPUT, SSC_NUMBER, "onshore_substation_cost_method", "Onshore substation cost method", "0/1/2", "0=Enter in $/kW,1=Enter in $,2=Use modeled value", "MHKCosts", "*", "MIN=0,MAX=3", "" }, + { SSC_INPUT, SSC_NUMBER, "onshore_substation_cost_method", "Onshore substation cost method", "0/1/2", "0=Enter in $/kW,1=Enter in $,2=Use modeled value", "MHKCosts", "*", "MIN=0,MAX=4", "" }, { SSC_INPUT, SSC_NUMBER, "onshore_substation_cost_input", "Onshore substation cost", "$", "", "MHKCosts", "*", "", "" }, - { SSC_INPUT, SSC_NUMBER, "offshore_substation_cost_method", "Offshore substation cost method", "0/1/2", "0=Enter in $/kW,1=Enter in $,2=Use modeled value", "MHKCosts", "*", "MIN=0,MAX=3", "" }, + { SSC_INPUT, SSC_NUMBER, "offshore_substation_cost_method", "Offshore substation cost method", "0/1/2", "0=Enter in $/kW,1=Enter in $,2=Use modeled value", "MHKCosts", "*", "MIN=0,MAX=4", "" }, { SSC_INPUT, SSC_NUMBER, "offshore_substation_cost_input", "Offshore substation cost", "$", "", "MHKCosts", "*", "", "" }, - { SSC_INPUT, SSC_NUMBER, "other_elec_infra_cost_method", "Other electrical infrastructure cost method", "0/1/2", "0=Enter in $/kW,1=Enter in $,2=Use modeled value", "MHKCosts", "*", "MIN=0,MAX=3", "" }, + { SSC_INPUT, SSC_NUMBER, "other_elec_infra_cost_method", "Other electrical infrastructure cost method", "0/1/2", "0=Enter in $/kW,1=Enter in $,2=Use modeled value", "MHKCosts", "*", "MIN=0,MAX=4", "" }, { SSC_INPUT, SSC_NUMBER, "other_elec_infra_cost_input", "Other electrical infrastructure cost", "$", "", "MHKCosts", "*", "", "" }, //CapEx costs From 60c6eb3c533d44cb8f655e5075a2f7f47709fe60 Mon Sep 17 00:00:00 2001 From: Steven Janzou Date: Tue, 25 Jul 2023 00:58:32 -0600 Subject: [PATCH 17/22] 2023.7.25.ssc.282 beta for ME --- ssc/sscapi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ssc/sscapi.cpp b/ssc/sscapi.cpp index d6f4a1987..eecc08512 100644 --- a/ssc/sscapi.cpp +++ b/ssc/sscapi.cpp @@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SSCEXPORT int ssc_version() { - return 280; + return 282; } SSCEXPORT const char *ssc_build_info() From 54da8f09bff13f6347e8d7f18e349c98d10cba40 Mon Sep 17 00:00:00 2001 From: Matt Prilliman Date: Mon, 16 Oct 2023 11:14:16 -0500 Subject: [PATCH 18/22] Fix ssc equation docs for mhk equations --- ssc/cmod_mhk_eqns.h | 38 +++++++++++++++++++++++++++++++++++--- ssc/ssc_equations.h | 2 +- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/ssc/cmod_mhk_eqns.h b/ssc/cmod_mhk_eqns.h index 77c511047..d2756cbc5 100644 --- a/ssc/cmod_mhk_eqns.h +++ b/ssc/cmod_mhk_eqns.h @@ -53,18 +53,50 @@ static const char* me_array_cable_length_doc = SSCEXPORT bool me_array_cable_length(ssc_data_t data); +static const char* tidal_turbine_calculate_powercurve_doc = +"Calculates the tidal energy converter power output for tidal velocity bins in an ME array\\n" +"Input: var_table with key-value pairs\\n" +" 'tidal_turbine_rotor_diameter' - double [m]\\n" +" 'number_rotors' - integer [-]\\n" +" 'tidal_turbine_max_cp' - double [-]\\n" +" 'pto_efficiency' - double [%]\\n" +" 'cut_in' - double [m/s]\\n" +" 'cut_out' - double [m/s]\\n" +" 'tidal_resource' - matrix [-]\\n" +" 'generator_rated_capacity' - matrix [-]\\n" +"Output: key-value pairs added to var_table\\n" +" 'tidal_turbine_powercurve_tidespeeds' - array [m/s]\\n" +" 'tidal_turbine_powercurve_powerout' - array [kW]\\n" +" 'error - string [-]\\n"; + + SSCEXPORT bool tidal_turbine_calculate_powercurve(ssc_data_t data); static const char* me_array_cable_voltage_doc = "Calculates the cable voltages in an ME array\\n" "Input: var_table with key-value pairs\\n" " 'devices_per_row' - double [-]\\n" +" 'device_rated_power' - double [kW]\\n" +" 'system_capacity' - double [kW]\\n" " 'device_spacing_in_row' - double [m]\\n" -" 'number_rows' - double [-]\\n" " 'row_spacing' - double [m]\\n" -" 'cable_system_overbuild' - double [%]\\n" +" 'inter_array_cable_length' - double [m]\\n" +" 'riser_cable_length' - double [m]\\n" +" 'export_cable_length' - double [m]\\n" +" 'use_onshore_substation' - double [-]\\n" +" 'load_grid_voltage' - double [-]\\n" "Output: key-value pairs added to var_table\\n" -" 'inter_array_cable_voltage' - double [m]\\n"; +" 'array_cable_voltage' - double [V]\\n" +" 'array_cable_cost' - double [$]\\n" +" 'array_cable_cost_total' - double [$]\\n" +" 'export_cable_voltage' - double [V]\\n" +" 'export_cable_cost' - double [$]\\n" +" 'export_cable_cost_total' - double [$]\\n" +" 'riser_cable_voltage' - double [V]\\n" +" 'riser_cable_cost' - double [$]\\n" +" 'riser_cable_cost_total' - double [$]\\n" +" 'onshore_substation_cost_total' - double [$]\\n" +" 'offshore_substation_cost_total' - double [$]\\n"; SSCEXPORT bool me_array_cable_voltage(ssc_data_t data); diff --git a/ssc/ssc_equations.h b/ssc/ssc_equations.h index 3c3574fbf..a415ff107 100644 --- a/ssc/ssc_equations.h +++ b/ssc/ssc_equations.h @@ -86,7 +86,7 @@ static ssc_equation_entry ssc_equation_table [] = { "Marine energy", me_array_cable_length_doc, false, true}, {"tidal_turbine_calculate_powercurve", tidal_turbine_calculate_powercurve, - "Marine energy", me_array_cable_length_doc, + "Marine energy", tidal_turbine_calculate_powercurve_doc, false, true}, {"me_array_cable_voltage", me_array_cable_voltage, "Marine energy", me_array_cable_voltage_doc, From 1763c4d870325d4735fb853324eee5cb568c3625 Mon Sep 17 00:00:00 2001 From: Matt Prilliman Date: Mon, 16 Oct 2023 13:13:44 -0500 Subject: [PATCH 19/22] Add missing initialization of distance_to_shore --- ssc/cmod_mhk_eqns.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ssc/cmod_mhk_eqns.cpp b/ssc/cmod_mhk_eqns.cpp index d9d2001a8..50db50120 100644 --- a/ssc/cmod_mhk_eqns.cpp +++ b/ssc/cmod_mhk_eqns.cpp @@ -178,7 +178,7 @@ bool me_array_cable_voltage(ssc_data_t data) { return false; } - double devices_per_row, device_spacing_in_row, number_rows, row_spacing, cable_system_overbuild, floating_array, export_cable_redundancy, water_depth, number_devices, distance_to_shore; + double devices_per_row, device_spacing_in_row, distance_to_shore; double device_rated_power, system_capacity, inter_array_cable_length, riser_cable_length, export_cable_length; double use_onshore_substation, load_grid_voltage; vt_get_number(vt, "devices_per_row", &devices_per_row); @@ -190,7 +190,7 @@ bool me_array_cable_voltage(ssc_data_t data) { vt_get_number(vt, "export_cable_length", &export_cable_length); vt_get_number(vt, "use_onshore_substation", &use_onshore_substation); vt_get_number(vt, "load_grid_voltage", &load_grid_voltage); - + vt_get_number(vt, "distance_to_shore", &distance_to_shore); double PF = 0.95; //Power Factor double angle = acos(PF); From daaf3920c5dde48156614d897edf9b97f477f826 Mon Sep 17 00:00:00 2001 From: Matt Prilliman Date: Mon, 16 Oct 2023 15:48:17 -0500 Subject: [PATCH 20/22] Initialize variables --- ssc/cmod_mhk_eqns.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/ssc/cmod_mhk_eqns.cpp b/ssc/cmod_mhk_eqns.cpp index 50db50120..f6f72280f 100644 --- a/ssc/cmod_mhk_eqns.cpp +++ b/ssc/cmod_mhk_eqns.cpp @@ -45,7 +45,7 @@ bool me_array_cable_length(ssc_data_t data) return false; } - double devices_per_row, device_spacing_in_row, number_rows, row_spacing, cable_system_overbuild, floating_array, export_cable_redundancy, water_depth, number_devices, distance_to_shore; + double devices_per_row, device_spacing_in_row, number_rows, row_spacing, cable_system_overbuild, floating_array, export_cable_redundancy, water_depth, number_devices, distance_to_shore = 0; vt_get_number(vt, "devices_per_row", &devices_per_row); vt_get_number(vt, "device_spacing_in_row", &device_spacing_in_row); @@ -96,12 +96,9 @@ bool tidal_turbine_calculate_powercurve(ssc_data_t data) return false; } - double turbine_size, rotor_diameter, elevation, max_tip_speed, max_tip_sp_ratio, cut_in, - cut_out, rotor_area, generator_rated_capacity, water_depth, velocity_power_law_fit, number_rotors; - int drive_train; + double rotor_diameter, cut_in, + cut_out, rotor_area, generator_rated_capacity, number_rotors = 0; util::matrix_t tidal_resource; - double min_vel; - int max_cp_length, pto_efficiency_length; std::vector pto_efficiency; std::vector max_cp; @@ -178,9 +175,9 @@ bool me_array_cable_voltage(ssc_data_t data) { return false; } - double devices_per_row, device_spacing_in_row, distance_to_shore; - double device_rated_power, system_capacity, inter_array_cable_length, riser_cable_length, export_cable_length; - double use_onshore_substation, load_grid_voltage; + double devices_per_row, device_spacing_in_row, distance_to_shore = 0; + double device_rated_power, system_capacity, inter_array_cable_length, riser_cable_length, export_cable_length = 0; + double use_onshore_substation, load_grid_voltage = 0; vt_get_number(vt, "devices_per_row", &devices_per_row); vt_get_number(vt, "device_rated_power", &device_rated_power); vt_get_number(vt, "system_capacity", &system_capacity); From 6da17cea9276227456cd925c386419301f875a40 Mon Sep 17 00:00:00 2001 From: Matt Prilliman Date: Mon, 16 Oct 2023 15:57:28 -0500 Subject: [PATCH 21/22] Add else statements to fix control path not returning value error --- ssc/cmod_mhk_eqns.cpp | 94 +++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 44 deletions(-) diff --git a/ssc/cmod_mhk_eqns.cpp b/ssc/cmod_mhk_eqns.cpp index f6f72280f..de8b8950b 100644 --- a/ssc/cmod_mhk_eqns.cpp +++ b/ssc/cmod_mhk_eqns.cpp @@ -208,22 +208,22 @@ bool me_array_cable_voltage(ssc_data_t data) { } vt->assign("export_cable_type", export_cable_type); //Riser Cable - double riser_cable_voltage = 0; - double riser_cable_cost = 0; //$/m - if ( array_cable_rated_power_per_row < 4) { + double riser_cable_voltage = 0.0; + double riser_cable_cost = 0.0; //$/m + if ( array_cable_rated_power_per_row < 4.0) { riser_cable_voltage = 7.2; riser_cable_cost = 57.955 * riser_cable_rated_power_per_device; } - else if (riser_cable_rated_power_per_device >= 5 && riser_cable_rated_power_per_device < 9) { - riser_cable_voltage = 12; + else if (riser_cable_rated_power_per_device >= 5.0 && riser_cable_rated_power_per_device < 9.0) { + riser_cable_voltage = 12.0; riser_cable_cost = 47.214 * riser_cable_rated_power_per_device - 91.05; } - else if (riser_cable_rated_power_per_device >= 9 && riser_cable_rated_power_per_device < 14) { - riser_cable_voltage = 24; + else if (riser_cable_rated_power_per_device >= 9.0 && riser_cable_rated_power_per_device < 14.0) { + riser_cable_voltage = 24.0; riser_cable_cost = 22.748 * riser_cable_rated_power_per_device - 68.376; } - else if (riser_cable_rated_power_per_device >= 14) { - riser_cable_voltage = 36; + else { + riser_cable_voltage = 36.0; riser_cable_cost = 20.82 * riser_cable_rated_power_per_device - 163.14; } vt->assign("riser_cable_voltage", riser_cable_voltage); @@ -232,26 +232,26 @@ bool me_array_cable_voltage(ssc_data_t data) { vt->assign("riser_cable_cost_total", riser_cable_cost_total); //Array Cable - double array_cable_voltage = 0; - double array_cable_cost = 0; - if ( array_cable_rated_power_per_row < 4) { + double array_cable_voltage = 0.0; + double array_cable_cost = 0.0; + if ( array_cable_rated_power_per_row < 4.0) { array_cable_voltage = 7.2; array_cable_cost = 44.245 * array_cable_rated_power_per_row; } - else if ( array_cable_rated_power_per_row >= 4 && array_cable_rated_power_per_row < 9) { - array_cable_voltage = 12; + else if ( array_cable_rated_power_per_row >= 4.0 && array_cable_rated_power_per_row < 9.0) { + array_cable_voltage = 12.0; array_cable_cost = 31.029 * array_cable_rated_power_per_row - 40.744; } - else if ( array_cable_rated_power_per_row >= 9 && array_cable_rated_power_per_row < 14) { - array_cable_voltage = 24; + else if ( array_cable_rated_power_per_row >= 9.0 && array_cable_rated_power_per_row < 14.0) { + array_cable_voltage = 24.0; array_cable_cost = 17.348 * array_cable_rated_power_per_row - 61.467; } - else if ( array_cable_rated_power_per_row >= 14 && array_cable_rated_power_per_row < 30) { - array_cable_voltage = 36; + else if ( array_cable_rated_power_per_row >= 14.0 && array_cable_rated_power_per_row < 30.0) { + array_cable_voltage = 36.0; array_cable_cost = 13.791 * array_cable_rated_power_per_row - 93.272; } - else if (array_cable_rated_power_per_row >= 30) { - array_cable_voltage = 66; + else { + array_cable_voltage = 66.0; array_cable_cost = 11.984 * array_cable_rated_power_per_row - 155.97; } vt->assign("array_cable_voltage", array_cable_voltage); @@ -264,62 +264,62 @@ bool me_array_cable_voltage(ssc_data_t data) { double export_cable_cost = 0; double offshore_substation_voltage = 0; if (export_cable_type == 0) { - if (export_cable_rated_power_array_ac < 4) { + if (export_cable_rated_power_array_ac < 4.0) { export_cable_voltage = 7.2; export_cable_cost = 44.245 * export_cable_rated_power_array_ac; offshore_substation_voltage = 8; //kVAC } - else if (export_cable_rated_power_array_ac >= 4 && export_cable_rated_power_array_ac < 9) { + else if (export_cable_rated_power_array_ac >= 4.0 && export_cable_rated_power_array_ac < 9.0) { export_cable_voltage = 12; export_cable_cost = 31.029 * export_cable_rated_power_array_ac - 40.744; offshore_substation_voltage = 15; //kVAC } - else if (export_cable_rated_power_array_ac >= 9 && export_cable_rated_power_array_ac < 14) { + else if (export_cable_rated_power_array_ac >= 9.0 && export_cable_rated_power_array_ac < 14.0) { export_cable_voltage = 24; export_cable_cost = 17.348 * export_cable_rated_power_array_ac - 61.467; offshore_substation_voltage = 25; //kVAC } - else if (export_cable_rated_power_array_ac >= 14 && export_cable_rated_power_array_ac < 30) { + else if (export_cable_rated_power_array_ac >= 14.0 && export_cable_rated_power_array_ac < 30.0) { export_cable_voltage = 36; export_cable_cost = 13.791 * export_cable_rated_power_array_ac - 93.272; offshore_substation_voltage = 46; //kVAC } - else if (export_cable_rated_power_array_ac >= 30 && export_cable_rated_power_array_ac < 40) { + else if (export_cable_rated_power_array_ac >= 30.0 && export_cable_rated_power_array_ac < 40.0) { export_cable_voltage = 66; array_cable_cost = 11.984 * export_cable_rated_power_array_ac - 155.97; offshore_substation_voltage = 69; //kVAC } - else if (export_cable_rated_power_array_ac >= 40 && export_cable_rated_power_array_ac < 121) { + else if (export_cable_rated_power_array_ac >= 40.0 && export_cable_rated_power_array_ac < 121.0) { export_cable_voltage = 72.5; array_cable_cost = 9.8977 * export_cable_rated_power_array_ac - 195.75; offshore_substation_voltage = 115; //kVAC } - else if (export_cable_rated_power_array_ac >= 121 && export_cable_rated_power_array_ac < 250) { + else if (export_cable_rated_power_array_ac >= 121.0 && export_cable_rated_power_array_ac < 250.0) { export_cable_voltage = 145; array_cable_cost = 10.046 * export_cable_rated_power_array_ac - 886.49; offshore_substation_voltage = 161; //kVAC } - else if (export_cable_rated_power_array_ac >= 250 && export_cable_rated_power_array_ac < 550) { - export_cable_voltage = 220; + else if (export_cable_rated_power_array_ac >= 250.0 && export_cable_rated_power_array_ac < 550.0) { + export_cable_voltage = 220.0; array_cable_cost = 5.2937 * export_cable_rated_power_array_ac - 318.15; - offshore_substation_voltage = 230; //kVAC + offshore_substation_voltage = 230.0; //kVAC } - else if (export_cable_rated_power_array_ac >= 550) { - export_cable_voltage = 400; + else { + export_cable_voltage = 400.0; array_cable_cost = 7.7566 * export_cable_rated_power_array_ac - 2704.6; - offshore_substation_voltage = 415; //kVAC + offshore_substation_voltage = 415.0; //kVAC } } else { - if (export_cable_rated_power_array_hvdc < 500) { - export_cable_voltage = 150; + if (export_cable_rated_power_array_hvdc < 500.0) { + export_cable_voltage = 150.0; export_cable_cost = 2.5026 * export_cable_rated_power_array_hvdc; - offshore_substation_voltage = 161; //kV HVDC + offshore_substation_voltage = 161.0; //kV HVDC } else { - export_cable_voltage = 300; + export_cable_voltage = 300.0; export_cable_cost = 2.0375 * export_cable_rated_power_array_hvdc - 516.02; - offshore_substation_voltage = 345; //kVAC + offshore_substation_voltage = 345.0; //kVAC } } vt->assign("export_cable_voltage", export_cable_voltage); @@ -339,14 +339,17 @@ bool me_array_cable_voltage(ssc_data_t data) { double static_var_compensator_cost = 105060 * reactive_power; //HVDC Electrical equipment double hvdc_converter_station_cost = 142.61 * system_capacity; - double offshore_substation_cost_total = 0; - if (array_cable_voltage != export_cable_voltage && export_cable_type == 0) { + double offshore_substation_cost_total = 0.0; + if (array_cable_voltage != export_cable_voltage && export_cable_type == 0.0) { offshore_substation_cost_total = offshore_foundation_cost + circuit_breaker_cost + ac_switchgear_cost + transformer_cost + shunt_reactor_cost + series_capacitor_cost + static_var_compensator_cost; } - else if (array_cable_voltage != export_cable_voltage && export_cable_type == 1) { + else if (array_cable_voltage != export_cable_voltage && export_cable_type == 1.0) { offshore_substation_cost_total = offshore_foundation_cost + hvdc_converter_station_cost; } + else { + //do nothing + } vt->assign("offshore_substation_cost_total", offshore_substation_cost_total); //Onshore substation @@ -360,14 +363,17 @@ bool me_array_cable_voltage(ssc_data_t data) { double onshore_static_var_compensator_cost = 105060 * reactive_power; //HVDC Electrical equipment double onshore_hvdc_converter_station_cost = 142.61 * system_capacity; - double onshore_substation_cost_total = 0; - if (use_onshore_substation==0 && export_cable_type == 0) { + double onshore_substation_cost_total = 0.0; + if (use_onshore_substation== 0.0 && export_cable_type == 0.0) { onshore_substation_cost_total = onshore_foundation_cost + onshore_circuit_breaker_cost + onshore_ac_switchgear_cost + onshore_transformer_cost + onshore_shunt_reactor_cost + onshore_series_capacitor_cost + onshore_static_var_compensator_cost; } - else if (use_onshore_substation==0 && export_cable_type == 1) { + else if (use_onshore_substation== 0.0 && export_cable_type == 1.0) { onshore_substation_cost_total = onshore_foundation_cost + onshore_hvdc_converter_station_cost; } + else { + //do nothing + } vt->assign("onshore_substation_cost_total", onshore_substation_cost_total); } From a84f45e41f887624a4d029cad18db501e0146ed2 Mon Sep 17 00:00:00 2001 From: Matt Prilliman Date: Mon, 16 Oct 2023 16:03:11 -0500 Subject: [PATCH 22/22] Return status variable for array cable voltage ssc equation --- ssc/cmod_mhk_eqns.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ssc/cmod_mhk_eqns.cpp b/ssc/cmod_mhk_eqns.cpp index de8b8950b..5f20a71e1 100644 --- a/ssc/cmod_mhk_eqns.cpp +++ b/ssc/cmod_mhk_eqns.cpp @@ -349,6 +349,7 @@ bool me_array_cable_voltage(ssc_data_t data) { } else { //do nothing + offshore_substation_cost_total = 0.0; } vt->assign("offshore_substation_cost_total", offshore_substation_cost_total); @@ -375,6 +376,7 @@ bool me_array_cable_voltage(ssc_data_t data) { //do nothing } vt->assign("onshore_substation_cost_total", onshore_substation_cost_total); + return true; }