From 04c42cc5f31b9501bc74ab16af499ce361a1feba Mon Sep 17 00:00:00 2001 From: Matt Prilliman <54449384+mjprilliman@users.noreply.github.com> Date: Fri, 15 Aug 2025 09:40:15 -0500 Subject: [PATCH 1/8] Update cost curves --- ssc/cmod_mhk_costs.cpp | 82 +++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/ssc/cmod_mhk_costs.cpp b/ssc/cmod_mhk_costs.cpp index 2a30524d8..5b2658911 100644 --- a/ssc/cmod_mhk_costs.cpp +++ b/ssc/cmod_mhk_costs.cpp @@ -181,21 +181,21 @@ class cm_mhk_costs : public compute_module if (technology == TIDAL) { // device = RM1 if (device_type == RM1) { - structural_assembly = 338981 * system_capacity_MW + 936326; - power_takeoff = 1821066.0 * system_capacity_MW + 602898.0; - mooring_found_substruc = 443055.0 * system_capacity_MW + 384877.0; + structural_assembly = 437807 * system_capacity_MW + 1136551; + power_takeoff = 1911085.0 * system_capacity_MW + 641328.0; + mooring_found_substruc = 441591.0 * system_capacity_MW + 769351.0; //BOS costs SAM Cost Model v8.xlsx - development = 2957847 * pow(system_capacity_MW, 0.51); - eng_and_mgmt = 78127 * system_capacity_MW + 2325517; + development = 2882733 * pow(system_capacity_MW, 0.51); + eng_and_mgmt = 1049336 * pow(system_capacity_MW, 0.56); } else if (device_type == RM2) { //REPLACE WITH ACTUAL RM2 COST CURVES - structural_assembly = 1573876 * system_capacity_MW + 161960; - power_takeoff = 3397389 * system_capacity_MW; - mooring_found_substruc = 551697 * system_capacity_MW; + structural_assembly = 2650166 * system_capacity_MW + 352232; + power_takeoff = 5207150 * pow(system_capacity_MW, 0.64); + mooring_found_substruc = 330163 * system_capacity_MW; //BOS costs SAM Cost Model v8.xlsx - development = 2957847 * pow(system_capacity_MW, 0.51); - eng_and_mgmt = 78127 * system_capacity_MW + 2325517; + development = 2882733 * pow(system_capacity_MW, 0.51); + eng_and_mgmt = 1049336 * pow(system_capacity_MW, 0.56); } else { //Generic Tidal structural_assembly = 1573876 * system_capacity_MW + 161960; @@ -210,47 +210,47 @@ class cm_mhk_costs : public compute_module { if (device_type == RM3) { - structural_assembly = 8174919.0 * system_capacity_MW + 3135478.0; - power_takeoff = 2481879.0 * pow(system_capacity_MW, 0.91); - mooring_found_substruc = 2189982.0 * system_capacity_MW + 35386.0; + structural_assembly = 8435164.0 * system_capacity_MW + 3235294.0; + power_takeoff = 2643426.0 * pow(system_capacity_MW, 0.91); + mooring_found_substruc = 2247873.0 * system_capacity_MW; //BOS costs SAM Cost Model v8.xlsx - development = 2957847.0 * pow(system_capacity_MW, 0.51); - eng_and_mgmt = 78127 * system_capacity_MW + 2325517; + development = 2882733 * pow(system_capacity_MW, 0.51); + eng_and_mgmt = 1049336 * pow(system_capacity_MW, 0.56); } else if (device_type == RM5) { - structural_assembly = 8167155.0 * system_capacity_MW + 3953752.0; - power_takeoff = 1909207.0 * pow(system_capacity_MW, 0.91); - mooring_found_substruc = 2574104.0 * system_capacity_MW + 1250918.0; + structural_assembly = 8437834.0 * system_capacity_MW + 4084789.0; + power_takeoff = 1972483.0 * pow(system_capacity_MW, 0.91); + mooring_found_substruc = 2689321.0 * system_capacity_MW + 439357.0; //BOS costs SAM Cost Model v8.xlsx - development = 2957847.0 * pow(system_capacity_MW, 0.51); - eng_and_mgmt = 78127 * system_capacity_MW + 2325517; + development = 2882733 * pow(system_capacity_MW, 0.51); + eng_and_mgmt = 1049336 * pow(system_capacity_MW, 0.56); } else if (device_type == RM6) { - structural_assembly = 15885057.0 * system_capacity_MW + 7967714.0; - power_takeoff = 4527629.0 * pow(system_capacity_MW, 0.78); - mooring_found_substruc = 2421878.0 * system_capacity_MW + 570523.0; + structural_assembly = 17442939.0 * system_capacity_MW + 8221362.0; + power_takeoff = 4903325.0 * pow(system_capacity_MW, 0.78); + mooring_found_substruc = 2659397.0 * system_capacity_MW + 588685.0; //BOS costs SAM Cost Model v8.xlsx - development = 2957847.0 * pow(system_capacity_MW, 0.51); - eng_and_mgmt = 78127 * system_capacity_MW + 2325517; + development = 2882733 * pow(system_capacity_MW, 0.51); + eng_and_mgmt = 1049336 * pow(system_capacity_MW, 0.56); } else //generic model applies to everything else { - structural_assembly = 7708042.0 * system_capacity_MW + 7092078; - power_takeoff = 1550104.0 * system_capacity_MW + 5331628.0; - mooring_found_substruc = 1619167.0 * system_capacity_MW; + structural_assembly = 7994094.0 * system_capacity_MW + 2502878; + power_takeoff = 1970813.0 * system_capacity_MW + 2456226.0; + mooring_found_substruc = 430255.0 * system_capacity_MW; //BOS costs SAM Cost Model v8.xlsx - development = 2957847 * pow(system_capacity_MW, 0.51); - eng_and_mgmt = 78127 * system_capacity_MW + 2325517; + development = 2882733.0 * pow(system_capacity_MW, 0.51); + eng_and_mgmt = 1049336 * pow(system_capacity_MW, 0.56); } } // REmaining BOS costs that are not CapEx dependent and not technology dependent - assembly_and_install = 2564748 * pow(system_capacity_MW, 0.67); + assembly_and_install = 2973817 * pow(system_capacity_MW, 0.67); other_infrastructure = 0; //electrical infrastructure costs @@ -262,10 +262,10 @@ class cm_mhk_costs : public compute_module other_elec_infra = 47966.16 * system_capacity_MW + 665841.0; // operations cost - operations_cost = 31250.0 * system_capacity_MW + 879282.0; + operations_cost = 46157.0 * system_capacity_MW + 1078155.0; // maintenance cost - maintenance_cost = 116803.0 * system_capacity_MW + 317719.0; + maintenance_cost = 79926.0 * system_capacity_MW + 2206357.0; //at this point, we need to assign the "independent" modeled outputs- //i.e., we want the modeled value to be reported prior to overwriting with a user input @@ -362,8 +362,8 @@ class cm_mhk_costs : public compute_module other_elec_infra = as_double("other_elec_infra_cost_input"); - plant_commissioning = 56103 * system_capacity_MW; - site_access_port_staging = 75462 * system_capacity_MW; + /*plant_commissioning = 56103 * system_capacity_MW; + site_access_port_staging = 75462 * system_capacity_MW;*/ // Now, we calculated the CapEx using whatever combination of modeled values and user-entered values @@ -371,15 +371,15 @@ class cm_mhk_costs : public compute_module // CapEx is defined to include all device costs and BOS costs that are not CapEx dependent double capex = structural_assembly + power_takeoff + mooring_found_substruc + development + eng_and_mgmt + assembly_and_install + other_infrastructure - + array_cable_system + export_cable_system + onshore_substation + offshore_substation + other_elec_infra - + plant_commissioning + site_access_port_staging; + + array_cable_system + export_cable_system + onshore_substation + offshore_substation + other_elec_infra; - + plant_commissioning = 0.016 * capex; + site_access_port_staging = 0.011 * capex; // Calculate the CapEx-dependent financial costs - project_contingency = 0.08 * capex; - insurance_during_construction = 0.01 * capex; - reserve_accounts = 0.03 * capex; + project_contingency = 0.081 * capex; + insurance_during_construction = 0.013 * capex; + reserve_accounts = 0.031 * capex; From 9c25ac6e617d9ed263813119ffa838e92cc2d391 Mon Sep 17 00:00:00 2001 From: Matt Prilliman <54449384+mjprilliman@users.noreply.github.com> Date: Fri, 19 Sep 2025 08:50:10 -0500 Subject: [PATCH 2/8] Add check that resource and power matrix have same binning --- ssc/cmod_mhk_wave.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/ssc/cmod_mhk_wave.cpp b/ssc/cmod_mhk_wave.cpp index b4d2a81f5..2bddbc397 100644 --- a/ssc/cmod_mhk_wave.cpp +++ b/ssc/cmod_mhk_wave.cpp @@ -444,9 +444,13 @@ class cm_mhk_wave : public compute_module for (size_t j = 0; j < (size_t)wave_power_matrix.ncols(); j++) { //Calculate and allocate annual_energy_distribution: - if (j == 0 || i == 0) //Where (i = 0) is the row header, and (j = 0) is the column header. - p_annual_energy_dist[k] = (ssc_number_t) wave_resource_matrix.at(i, j); //Don't do anything with top left corner of matrix as this value is always 0 and not part of the grid - else { + if (j == 0 || i == 0) { //Where (i = 0) is the row header, and (j = 0) is the column header. + if (wave_resource_matrix.at(i, j) != wave_power_matrix.at(i, j)) { + throw exec_error("mhk_wave", "Resource matrix and Power matrix bins do not match."); + } + p_annual_energy_dist[k] = (ssc_number_t)wave_resource_matrix.at(i, j); //Don't do anything with top left corner of matrix as this value is always 0 and not part of the grid + } + else { //Find annual probability (as a %) of wave at height i and period j, multiply by 8760/100 to find fractional hours per year that wave(i,j) is achieved; //Mult. by number of devices and total loss multiplier to find energy for certain wave type in grid p_annual_energy_dist[k] = (ssc_number_t)(wave_resource_matrix.at(i,j) * wave_power_matrix.at(i,j) * 8760.0 / 100.0) * (1-total_loss/100) * number_devices; From 6d7bf97c746a44582416304a2a099925c5d1f456 Mon Sep 17 00:00:00 2001 From: Matt Prilliman <54449384+mjprilliman@users.noreply.github.com> Date: Thu, 2 Oct 2025 16:30:45 -0500 Subject: [PATCH 3/8] Refactor cost models to run mostly from cmod --- ssc/cmod_mhk_costs.cpp | 285 +++++++++++++++++++++++++++++++++-------- 1 file changed, 229 insertions(+), 56 deletions(-) diff --git a/ssc/cmod_mhk_costs.cpp b/ssc/cmod_mhk_costs.cpp index 5b2658911..a5dc0dd36 100644 --- a/ssc/cmod_mhk_costs.cpp +++ b/ssc/cmod_mhk_costs.cpp @@ -56,26 +56,84 @@ static var_info _cm_vtab_mhk_costs[] = { // 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=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=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=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", "*", "", "" }, + { SSC_INPUT, SSC_NUMBER, "structural_assembly_cost_input", "Structural assembly cost", "$", "", "MHKCosts", "structural_assembly_cost_method<2", "", "" }, + { SSC_INPUT, SSC_NUMBER, "structural_assembly_cost_total", "Structural assembly itemized cost total", "$", "", "MHKCosts", "structural_assembly_cost_method=3", "", "" }, + { SSC_INPUT, SSC_NUMBER, "structural_assembly_cost_rvalue", "Structural assembly R-value", "", "", "MHKCosts", "structural_assembly_cost_method=4", "MIN=0,MAX=1", "" }, + + + { 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", "power_takeoff_system_cost_method<2", "", "" }, + { SSC_INPUT, SSC_NUMBER, "power_takeoff_system_cost_total", "Power take-off system cost itemized cost total", "$", "", "MHKCosts", "power_takeoff_system_cost_method=3", "", "" }, + { SSC_INPUT, SSC_NUMBER, "structural_assembly_cost_rvalue", "Power take-off system R-value", "", "", "MHKCosts", "power_takeoff_system_cost_method=4", "MIN=0,MAX=1", "" }, + + + { 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", "mooring_found_substruc_cost_method<2", "", "" }, + { SSC_INPUT, SSC_NUMBER, "mooring_found_substruc_cost_total", "Mooring, foundation, and substructure itemized cost total", "$", "", "MHKCosts", "mooring_found_substruc_cost_method=3", "", "" }, + { SSC_INPUT, SSC_NUMBER, "mooring_found_substruc_cost_rvalue", "Mooring, foundation, and substructure R-value", "", "", "MHKCosts", "mooring_found_substruc_cost_method=4", "MIN=0,MAX=1", "" }, // 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=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=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=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=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=4", "" }, + { SSC_INPUT, SSC_NUMBER, "development_cost_input", "Development cost", "$", "", "MHKCosts", "development_cost_method<2", "", "" }, + { SSC_INPUT, SSC_NUMBER, "development_cost_total", "Development itemized cost total", "$", "", "MHKCosts", "development_cost_method=3", "", "" }, + { SSC_INPUT, SSC_NUMBER, "development_cost_rvalue", "Development R-value", "", "", "MHKCosts", "development_cost_method=4", "MIN=0,MAX=1", "" }, + + { 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", "eng_and_mgmt_cost_method<2", "", "" }, + { SSC_INPUT, SSC_NUMBER, "eng_and_mgmt_cost_total", "Engineering and management itemized cost total", "$", "", "MHKCosts", "eng_and_mgmt_cost_method=3", "", "" }, + { SSC_INPUT, SSC_NUMBER, "eng_and_mgmt_cost_rvalue", "Engineering and management R-value", "", "", "MHKCosts", "eng_and_mgmt_cost_method=4", "MIN=0,MAX=1", "" }, + + { 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", "assembly_and_install_cost_method<2", "", "" }, + { SSC_INPUT, SSC_NUMBER, "assembly_and_install_cost_total", "Assembly and installation itemized cost total", "$", "", "MHKCosts", "assembly_and_install_cost_method=3", "", "" }, + { SSC_INPUT, SSC_NUMBER, "assembly_and_install_cost_rvalue", "Assembly and installation R-value", "", "", "MHKCosts", "assembly_and_install_cost_method=4", "MIN=0,MAX=1", "" }, + + { 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", "other_infrastructure_cost_method<2", "", "" }, + { SSC_INPUT, SSC_NUMBER, "other_infrastructure_cost_total", "Other infrastructure itemized cost total", "$", "", "MHKCosts", "other_infrastructure_cost_method=3", "", "" }, + { SSC_INPUT, SSC_NUMBER, "other_infrastructure_cost_rvalue", "Other infrastructure R-value", "", "", "MHKCosts", "other_infrastructure_cost_method=4", "MIN=0,MAX=1", "" }, + + { SSC_INPUT, SSC_NUMBER, "elec_infras_cost_method", "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, "elec_infras_cost_input", "Electrical infrastructure cost", "$", "", "MHKCosts", "elec_infras_cost_method<2", "", "" }, + { SSC_INPUT, SSC_NUMBER, "elec_infras_cost_modeled", "Electrical infrastructure cost modeled", "$", "", "MHKCosts", "elec_infras_cost_method=2", "", "" }, + { SSC_INPUT, SSC_NUMBER, "elec_infras_cost_total", "Electrical infrastructure itemized cost total", "$", "", "MHKCosts", "elec_infras_cost_method=3", "", "" }, + { SSC_INPUT, SSC_NUMBER, "elec_infras_cost_rvalue", "Electrical infrastructure R-value", "", "", "MHKCosts", "elec_infras_cost_method=4", "MIN=0,MAX=1", "" }, + + //Plant Commissioning + { SSC_INPUT, SSC_NUMBER, "plant_commissioning_cost_method", "Plant commissioning 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, "plant_commissioning_cost_input", "Plant commissioning cost", "$", "", "MHKCosts", "plant_commissioning_cost_method<2", "", "" }, + { SSC_INPUT, SSC_NUMBER, "plant_commissioning_cost_total", "Plant commissioning itemized cost total", "$", "", "MHKCosts", "plant_commissioning_cost_method=3", "", "" }, + { SSC_INPUT, SSC_NUMBER, "plant_commissioning_cost_rvalue", "Plant commissioning R-value", "", "", "MHKCosts", "plant_commissioning_cost_method=4", "MIN=0,MAX=1", "" }, + + //Site Access + { SSC_INPUT, SSC_NUMBER, "site_access_port_staging_cost_method", "Site access and port staging 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, "site_access_port_staging_cost_input", "Site access and port staging cost", "$", "", "MHKCosts", "site_access_port_staging_cost_method<2", "", "" }, + { SSC_INPUT, SSC_NUMBER, "site_access_port_staging_cost_total", "Site access and port staging itemized cost total", "$", "", "MHKCosts", "site_access_port_staging_cost_method=3", "", "" }, + { SSC_INPUT, SSC_NUMBER, "site_access_port_staging_cost_rvalue", "Site access and port staging R-value", "", "", "MHKCosts", "site_access_port_staging_cost_method=4", "MIN=0,MAX=1", "" }, + + + //Project Contingency + { SSC_INPUT, SSC_NUMBER, "project_contingency_cost_method", "Project contingency 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, "project_contingency_cost_input", "Project contingency cost", "$", "", "MHKCosts", "project_contingency_cost_method<2", "", "" }, + { SSC_INPUT, SSC_NUMBER, "project_contingency_cost_rvalue", "Project contingency R-value", "", "", "MHKCosts", "project_contingency_cost_method=3", "MIN=0,MAX=1", "" }, + + //Insurance during construction + { SSC_INPUT, SSC_NUMBER, "insurance_during_construction_cost_method", "Insurance during construction 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, "insurance_during_construction_cost_input", "Insurance during construction cost", "$", "", "MHKCosts", "insurance_during_construction_cost_method<2", "", "" }, + { SSC_INPUT, SSC_NUMBER, "insurance_during_construction_cost_rvalue", "Insurance during construction R-value", "", "", "MHKCosts", "insurance_during_construction_cost_method=3", "MIN=0,MAX=1", "" }, + + //Reserve Accounts + { SSC_INPUT, SSC_NUMBER, "reserve_accounts_cost_method", "Reserve accounts 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, "reserve_accounts_cost_input", "Reserve accounts cost", "$", "", "MHKCosts", "reserve_accounts_cost_method<2", "", "" }, + { SSC_INPUT, SSC_NUMBER, "reserve_accounts_cost_total", "Reserve accounts itemized cost total", "$", "", "MHKCosts", "reserve_accounts_cost_method=3", "", "" }, + { SSC_INPUT, SSC_NUMBER, "reserve_accounts_cost_rvalue", "Reserve accounts R-value", "", "", "MHKCosts", "reserve_accounts_cost_method=4", "MIN=0,MAX=1", "" }, + + //Other financial costs + { SSC_INPUT, SSC_NUMBER, "other_financial_cost_method", "Other financial 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_financial_cost_input", "Other financial cost", "$,$/kW", "", "MHKCosts", "other_financial_cost_method<2", "", "" }, + { SSC_INPUT, SSC_NUMBER, "other_financial_cost_rvalue", "Other financial R-value", "", "", "MHKCosts", "other_financial_cost_method=3", "MIN=0,MAX=1", "" }, + + /*{ 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=4", "" }, { SSC_INPUT, SSC_NUMBER, "export_cable_system_cost_input", "Export cable system cost", "$", "", "MHKCosts", "*", "", "" }, @@ -84,27 +142,43 @@ static var_info _cm_vtab_mhk_costs[] = { { 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=4", "" }, - { SSC_INPUT, SSC_NUMBER, "other_elec_infra_cost_input", "Other electrical infrastructure cost", "$", "", "MHKCosts", "*", "", "" }, + { SSC_INPUT, SSC_NUMBER, "other_elec_infra_cost_input", "Other electrical infrastructure cost", "$", "", "MHKCosts", "*", "", "" },*/ //CapEx costs { SSC_OUTPUT, SSC_NUMBER, "structural_assembly_cost_modeled", "Modeled structural assembly cost", "$", "", "MHKCosts", "", "", "" }, - { SSC_OUTPUT, SSC_NUMBER, "power_takeoff_system_cost_modeled", "Modeled power take-off cost", "$", "", "MHKCosts", "", "", "" }, - { SSC_OUTPUT, SSC_NUMBER, "mooring_found_substruc_cost_modeled", "Modeled mooring, foundation, and substructure cost", "$", "", "MHKCosts", "", "", "" }, - + { SSC_OUTPUT, SSC_NUMBER, "structural_assembly_cost", "Structural assembly cost", "$", "", "MHKCosts", "", "", "" }, + + { SSC_OUTPUT, SSC_NUMBER, "power_takeoff_system_cost_modeled", "Modeled power take-off cost", "$", "", "MHKCosts", "", "", "" }, + { SSC_OUTPUT, SSC_NUMBER, "power_takeoff_system_cost", "Power take-off cost", "$", "", "MHKCosts", "", "", "" }, + + { SSC_OUTPUT, SSC_NUMBER, "mooring_found_substruc_cost_modeled", "Modeled mooring, foundation, and substructure cost", "$", "", "MHKCosts", "", "", "" }, + { SSC_OUTPUT, SSC_NUMBER, "mooring_found_substruc_cost", "Mooring, foundation, and substructure cost", "$", "", "MHKCosts", "", "", "" }, + //Balance of system costs { SSC_OUTPUT, SSC_NUMBER, "development_cost_modeled", "Modeled development cost", "$", "", "MHKCosts", "", "", "" }, - { SSC_OUTPUT, SSC_NUMBER, "eng_and_mgmt_cost_modeled", "Modeled engineering and management cost", "$", "", "MHKCosts", "", "", "" }, - { SSC_OUTPUT, SSC_NUMBER, "plant_commissioning_cost_modeled", "Modeled plant commissioning cost", "$", "", "MHKCosts", "", "", "" }, - { SSC_OUTPUT, SSC_NUMBER, "site_access_port_staging_cost_modeled", "Modeled site access, port, and staging cost", "$", "", "MHKCosts", "", "", "" }, - { SSC_OUTPUT, SSC_NUMBER, "assembly_and_install_cost_modeled", "Modeled assembly and installation cost", "$", "", "MHKCosts", "", "", "" }, - { SSC_OUTPUT, SSC_NUMBER, "other_infrastructure_cost_modeled", "Modeled other infrastructure cost", "$", "", "MHKCosts", "", "", "" }, - + { SSC_OUTPUT, SSC_NUMBER, "development_cost", "Development cost", "$", "", "MHKCosts", "", "", "" }, + + { SSC_OUTPUT, SSC_NUMBER, "eng_and_mgmt_cost_modeled", "Modeled engineering and management cost", "$", "", "MHKCosts", "", "", "" }, + { SSC_OUTPUT, SSC_NUMBER, "eng_and_mgmt_cost", "Engineering and management cost", "$", "", "MHKCosts", "", "", "" }, + + { SSC_OUTPUT, SSC_NUMBER, "plant_commissioning_cost_modeled", "Modeled plant commissioning cost", "$", "", "MHKCosts", "", "", "" }, + { SSC_OUTPUT, SSC_NUMBER, "plant_commissioning_cost", "Plant commissioning cost", "$", "", "MHKCosts", "", "", "" }, + + { SSC_OUTPUT, SSC_NUMBER, "site_access_port_staging_cost_modeled", "Modeled site access, port, and staging cost", "$", "", "MHKCosts", "", "", "" }, + { SSC_OUTPUT, SSC_NUMBER, "site_access_port_staging_cost", "Site access, port, and staging cost", "$", "", "MHKCosts", "", "", "" }, + + { SSC_OUTPUT, SSC_NUMBER, "assembly_and_install_cost_modeled", "Modeled assembly and installation cost", "$", "", "MHKCosts", "", "", "" }, + { SSC_OUTPUT, SSC_NUMBER, "assembly_and_install_cost", "Assembly and installation cost", "$", "", "MHKCosts", "", "", "" }, + + { SSC_OUTPUT, SSC_NUMBER, "other_infrastructure_cost_modeled", "Modeled other infrastructure cost", "$", "", "MHKCosts", "", "", "" }, + { SSC_OUTPUT, SSC_NUMBER, "other_infrastructure_cost", "Other infrastructure cost", "$", "", "MHKCosts", "", "", "" }, + //Electrical infrastructure costs - { SSC_OUTPUT, SSC_NUMBER, "array_cable_system_cost_modeled", "Modeled array cable system cost", "$", "", "MHKCosts", "", "", "" }, + /*{ SSC_OUTPUT, SSC_NUMBER, "array_cable_system_cost_modeled", "Modeled array cable system cost", "$", "", "MHKCosts", "", "", "" }, { SSC_OUTPUT, SSC_NUMBER, "export_cable_system_cost_modeled", "Modeled export cable system cost", "$", "", "MHKCosts", "", "", "" }, { SSC_OUTPUT, SSC_NUMBER, "onshore_substation_cost_modeled", "Modeled onshore substation cost", "$", "", "MHKCosts", "", "", "" }, { SSC_OUTPUT, SSC_NUMBER, "offshore_substation_cost_modeled", "Modeled offshore substation cost", "$", "", "MHKCosts", "", "", "" }, - { SSC_OUTPUT, SSC_NUMBER, "other_elec_infra_cost_modeled", "Modeled other electrical infrastructure cost", "$", "", "MHKCosts", "", "", "" }, + { SSC_OUTPUT, SSC_NUMBER, "other_elec_infra_cost_modeled", "Modeled other electrical infrastructure cost", "$", "", "MHKCosts", "", "", "" },*/ //Financial costs { SSC_OUTPUT, SSC_NUMBER, "project_contingency", "Modeled project contingency cost", "$", "", "MHKCosts", "", "", "" }, @@ -254,12 +328,13 @@ class cm_mhk_costs : public compute_module other_infrastructure = 0; //electrical infrastructure costs - array_cable_system = (4.40 * (device_rating * devices_per_row / 1000.0) + 162.81) * interarray_length + /*array_cable_system = (4.40 * (device_rating * devices_per_row / 1000.0) + 162.81) * interarray_length + (4.40 * (device_rating / 1000.0) + 162.81) * riser_length; export_cable_system = (4.40 * system_capacity_MW + 162.81) * export_length; onshore_substation = 75000.0 * system_capacity_MW; offshore_substation = 100000.0 * system_capacity_MW; - other_elec_infra = 47966.16 * system_capacity_MW + 665841.0; + other_elec_infra = 47966.16 * system_capacity_MW + 665841.0;*/ + double elec_infras = as_double("elec_infras_cost_modeled"); // operations cost operations_cost = 46157.0 * system_capacity_MW + 1078155.0; @@ -277,11 +352,11 @@ class cm_mhk_costs : public compute_module assign("eng_and_mgmt_cost_modeled", var_data(static_cast(eng_and_mgmt))); assign("assembly_and_install_cost_modeled", var_data(static_cast(assembly_and_install))); assign("other_infrastructure_cost_modeled", var_data(static_cast(other_infrastructure))); - assign("array_cable_system_cost_modeled", var_data(static_cast(array_cable_system))); + /*assign("array_cable_system_cost_modeled", var_data(static_cast(array_cable_system))); assign("export_cable_system_cost_modeled", var_data(static_cast(export_cable_system))); assign("onshore_substation_cost_modeled", var_data(static_cast(onshore_substation))); assign("offshore_substation_cost_modeled", var_data(static_cast(offshore_substation))); - assign("other_elec_infra_cost_modeled", var_data(static_cast(other_elec_infra))); + assign("other_elec_infra_cost_modeled", var_data(static_cast(other_elec_infra)));*/ assign("operations_cost", var_data(static_cast(operations_cost))); assign("maintenance_cost", var_data(static_cast(maintenance_cost))); @@ -296,51 +371,107 @@ class cm_mhk_costs : public compute_module int eng_and_mgmt_cost_method = as_integer("eng_and_mgmt_cost_method"); int assembly_and_install_cost_method = as_integer("assembly_and_install_cost_method"); int other_infrastructure_cost_method = as_integer("other_infrastructure_cost_method"); + int elec_infras_cost_method = as_integer("elec_infras_cost_method"); + int plant_commissioning_cost_method = as_integer("plant_commissioning_cost_method"); + int site_access_port_staging_cost_method = as_integer("site_access_port_staging_cost_method"); - int array_cable_system_cost_method = as_integer("array_cable_system_cost_method"); + int project_contingency_cost_method = as_integer("project_contingency_cost_method"); + int insurance_during_construction_cost_method = as_integer("insurance_during_construction_cost_method"); + int reserve_accounts_cost_method = as_integer("reserve_accounts_cost_method"); + int other_financial_cost_method = as_integer("other_financial_cost_method"); + + /*int array_cable_system_cost_method = as_integer("array_cable_system_cost_method"); int export_cable_system_cost_method = as_integer("export_cable_system_cost_method"); int onshore_substation_cost_method = as_integer("onshore_substation_cost_method"); int offshore_substation_cost_method = as_integer("offshore_substation_cost_method"); - int other_elec_infra_cost_method = as_integer("other_elec_infra_cost_method"); + int other_elec_infra_cost_method = as_integer("other_elec_infra_cost_method");*/ // check for user entered values if (structural_assembly_cost_method == 0) structural_assembly = as_double("structural_assembly_cost_input") * system_capacity_kW; else if (structural_assembly_cost_method == 1) structural_assembly = as_double("structural_assembly_cost_input"); - //else if (structural_assembly_cost_method == 3) - //structural_assembly = as_double("structural_assembly_cost_total"); - if (power_takeoff_system_cost_method == 0) + else if (structural_assembly_cost_method == 3) + structural_assembly = as_double("structural_assembly_cost_total"); + else if (structural_assembly_cost_method == 4) + structural_assembly = as_double("structural_assembly_cost_input") * -1 * std::log(1.0 - as_double("structural_assembly_cost_rvalue")) / std::log(2.0); + assign("structural_assembly_cost", var_data(static_cast(structural_assembly))); + + if (power_takeoff_system_cost_method == 0) power_takeoff = as_double("power_takeoff_system_cost_input") * system_capacity_kW; else if (power_takeoff_system_cost_method == 1) power_takeoff = as_double("power_takeoff_system_cost_input"); - //else if (power_takeoff_system_cost_method == 3) - //power_takeoff = as_double("power_takeoff_system_cost_total"); + else if (power_takeoff_system_cost_method == 3) + power_takeoff = as_double("power_takeoff_system_cost_total"); + else if (power_takeoff_system_cost_method == 4) + power_takeoff = as_double("power_takeoff_system_cost_input") * -1 * std::log(1.0 - as_double("power_takeoff_system_cost_rvalue")) / std::log(2.0); + assign("power_takeoff_system_cost", var_data(static_cast(power_takeoff))); + + if (mooring_found_substruc_cost_method == 0) mooring_found_substruc = as_double("mooring_found_substruc_cost_input") * system_capacity_kW; else if (mooring_found_substruc_cost_method == 1) mooring_found_substruc = as_double("mooring_found_substruc_cost_input"); - //else if (mooring_found_substruc_cost_method == 3) - //mooring_found_substruc = as_double("mooring_found_substruc_cost_total"); + else if (mooring_found_substruc_cost_method == 3) + mooring_found_substruc = as_double("mooring_found_substruc_cost_total"); + else if (mooring_found_substruc_cost_method == 4) + mooring_found_substruc = as_double("mooring_found_substruc_cost_input") * -1 * std::log(1.0 - as_double("mooring_found_substruc_cost_rvalue")) / std::log(2.0); + assign("mooring_found_substruc_cost", var_data(static_cast(mooring_found_substruc))); if (development_cost_method == 0) development = as_double("development_cost_input") * system_capacity_kW; else if (development_cost_method == 1) development = as_double("development_cost_input"); + else if (development_cost_method == 3) + development = as_double("development_cost_total"); + else if (development_cost_method == 4) + development = as_double("development_cost_input") * -1 * std::log(1.0 - as_double("development_cost_rvalue")) / std::log(2.0); + assign("development_cost", var_data(static_cast(development))); + + if (eng_and_mgmt_cost_method == 0) eng_and_mgmt = as_double("eng_and_mgmt_cost_input") * system_capacity_kW; else if (eng_and_mgmt_cost_method == 1) eng_and_mgmt = as_double("eng_and_mgmt_cost_input"); + else if (eng_and_mgmt_cost_method == 3) + eng_and_mgmt = as_double("eng_and_mgmt_cost_total"); + else if (eng_and_mgmt_cost_method == 4) + eng_and_mgmt = as_double("eng_and_mgmt_cost_input") * -1 * std::log(1.0 - as_double("eng_and_mgmt_cost_rvalue")) / std::log(2.0); + assign("eng_and_mgmt_cost", var_data(static_cast(eng_and_mgmt))); + + if (assembly_and_install_cost_method == 0) assembly_and_install = as_double("assembly_and_install_cost_input") * system_capacity_kW; else if (assembly_and_install_cost_method == 1) assembly_and_install = as_double("assembly_and_install_cost_input"); + else if (assembly_and_install_cost_method == 3) + assembly_and_install = as_double("assembly_and_install_cost_total"); + else if (assembly_and_install_cost_method == 4) + assembly_and_install = as_double("assembly_and_install_cost_input") * -1 * std::log(1.0 - as_double("assembly_and_install_cost_rvalue")) / std::log(2.0); + assign("assembly_and_install_cost", var_data(static_cast(assembly_and_install))); + if (other_infrastructure_cost_method == 0) other_infrastructure = as_double("other_infrastructure_cost_input") * system_capacity_kW; else if (other_infrastructure_cost_method == 1) other_infrastructure = as_double("other_infrastructure_cost_input"); - - if (array_cable_system_cost_method == 0) + else if (other_infrastructure_cost_method == 3) + other_infrastructure = as_double("other_infrastructure_cost_total"); + else if (other_infrastructure_cost_method == 4) + other_infrastructure = as_double("other_infrastructure_cost_input") * -1 * std::log(1.0 - as_double("other_infrastructure_cost_rvalue")) / std::log(2.0); + assign("other_infrastructure_cost", var_data(static_cast(other_infrastructure))); + + if (elec_infras_cost_method == 0) + elec_infras = as_double("elec_infras_cost_input") * system_capacity_kW; + else if (elec_infras_cost_method == 1) + elec_infras = as_double("elec_infras_cost_input"); + else if (elec_infras_cost_method == 3) + elec_infras = as_double("elec_infras_cost_total"); + else if (other_infrastructure_cost_method == 4) + elec_infras = as_double("elec_infras_cost_input") * -1 * std::log(1.0 - as_double("elec_infras_cost_rvalue")) / std::log(2.0); + assign("elec_infras_cost", var_data(static_cast(elec_infras))); + + + /*if (array_cable_system_cost_method == 0) array_cable_system = as_double("array_cable_system_cost_input") * system_capacity_kW; else if (array_cable_system_cost_method == 1) array_cable_system = as_double("array_cable_system_cost_input"); @@ -359,7 +490,7 @@ class cm_mhk_costs : public compute_module if (other_elec_infra_cost_method == 0) other_elec_infra = as_double("other_elec_infra_cost_input") * system_capacity_kW; else if (other_elec_infra_cost_method == 1) - other_elec_infra = as_double("other_elec_infra_cost_input"); + other_elec_infra = as_double("other_elec_infra_cost_input");*/ /*plant_commissioning = 56103 * system_capacity_MW; @@ -371,24 +502,66 @@ class cm_mhk_costs : public compute_module // CapEx is defined to include all device costs and BOS costs that are not CapEx dependent double capex = structural_assembly + power_takeoff + mooring_found_substruc + development + eng_and_mgmt + assembly_and_install + other_infrastructure - + array_cable_system + export_cable_system + onshore_substation + offshore_substation + other_elec_infra; + + elec_infras; plant_commissioning = 0.016 * capex; - site_access_port_staging = 0.011 * capex; + assign("plant_commissioning_cost_modeled", var_data(static_cast(plant_commissioning))); + if (plant_commissioning_cost_method == 0) + plant_commissioning = as_double("plant_commissioning_cost_input") * system_capacity_kW; + else if (plant_commissioning_cost_method == 1) + plant_commissioning = as_double("plant_commissioning_cost_input"); + else if (plant_commissioning_cost_method == 3) + plant_commissioning = as_double("plant_commissioning_cost_input") * -1 * std::log(1.0 - as_double("plant_commissioning_cost_rvalue")) / std::log(2.0); - // Calculate the CapEx-dependent financial costs + site_access_port_staging = 0.011 * capex; + assign("site_access_port_staging_cost_modeled", var_data(static_cast(site_access_port_staging))); + if (site_access_port_staging_cost_method == 0) + site_access_port_staging = as_double("site_access_port_staging_cost_input") * system_capacity_kW; + else if (site_access_port_staging_cost_method == 1) + site_access_port_staging = as_double("site_access_port_staging_cost_input"); + else if (site_access_port_staging_cost_method == 3) + site_access_port_staging = as_double("site_access_port_staging_cost_total"); + else if (site_access_port_staging_cost_method == 4) + site_access_port_staging = as_double("site_access_port_staging_cost_input") * -1 * std::log(1.0 - as_double("site_access_port_staging_cost_rvalue")) / std::log(2.0); + + // Calculate the CapEx-dependent financial costs project_contingency = 0.081 * capex; - insurance_during_construction = 0.013 * capex; - reserve_accounts = 0.031 * capex; - + assign("project_contingency_cost_modeled", var_data(static_cast(project_contingency))); + if (project_contingency_cost_method == 0) + project_contingency = as_double("project_contingency_cost_input") * system_capacity_kW; + else if (project_contingency_cost_method == 1) + project_contingency = as_double("project_contingency_cost_input"); + else if (project_contingency_cost_method == 3) + project_contingency = as_double("project_contingency_cost_input") * -1 * std::log(1.0 - as_double("project_contingency_cost_rvalue")) / std::log(2.0); + + insurance_during_construction = 0.013 * capex; + assign("insurance_during_construction_cost_modeled", var_data(static_cast(insurance_during_construction))); + if (insurance_during_construction_cost_method == 0) + insurance_during_construction = as_double("insurance_during_construction_cost_input") * system_capacity_kW; + else if (insurance_during_construction_cost_method == 1) + insurance_during_construction = as_double("insurance_during_construction_cost_input"); + else if (insurance_during_construction_cost_method == 3) + insurance_during_construction = as_double("insurance_during_construction_cost_input") * -1 * std::log(1.0 - as_double("insurance_during_construction_cost_rvalue")) / std::log(2.0); + + + reserve_accounts = 0.031 * capex; + assign("reserve_accounts_cost_modeled", var_data(static_cast(reserve_accounts))); + if (reserve_accounts_cost_method == 0) + reserve_accounts = as_double("reserve_accounts_cost_input") * system_capacity_kW; + else if (reserve_accounts_cost_method == 1) + reserve_accounts = as_double("reserve_accounts_cost_input"); + else if (reserve_accounts_cost_method == 3) + reserve_accounts = as_double("reserve_accounts_cost_total"); + else if (reserve_accounts_cost_method == 4) + reserve_accounts = as_double("reserve_accounts_cost_input") * -1 * std::log(1.0 - as_double("reserve_accounts_cost_rvalue")) / std::log(2.0); // Assign the CapEx-dependent outputs - assign("plant_commissioning_cost_modeled", var_data(static_cast(plant_commissioning))); - assign("site_access_port_staging_cost_modeled", var_data(static_cast(site_access_port_staging))); - assign("project_contingency", var_data(static_cast(project_contingency))); - assign("insurance_during_construction", var_data(static_cast(insurance_during_construction))); - assign("reserve_accounts", var_data(static_cast(reserve_accounts))); + assign("plant_commissioning_cost", var_data(static_cast(plant_commissioning))); + assign("site_access_port_staging_cost", var_data(static_cast(site_access_port_staging))); + assign("project_contingency_cost", var_data(static_cast(project_contingency))); + assign("insurance_during_construction_cost", var_data(static_cast(insurance_during_construction))); + assign("reserve_accounts_cost", var_data(static_cast(reserve_accounts))); From a45112983f418a3ed30d6381e457c4f68879c43c Mon Sep 17 00:00:00 2001 From: Matt Prilliman <54449384+mjprilliman@users.noreply.github.com> Date: Thu, 16 Oct 2025 10:58:00 -0500 Subject: [PATCH 4/8] Update tile file reader, cost equations --- ssc/cmod_mhk_costs.cpp | 74 ++++++++++++++++--- ssc/cmod_tidalfile.cpp | 157 ++++++++++++++++++++++++++++++----------- 2 files changed, 181 insertions(+), 50 deletions(-) diff --git a/ssc/cmod_mhk_costs.cpp b/ssc/cmod_mhk_costs.cpp index a5dc0dd36..49ae359aa 100644 --- a/ssc/cmod_mhk_costs.cpp +++ b/ssc/cmod_mhk_costs.cpp @@ -102,7 +102,6 @@ static var_info _cm_vtab_mhk_costs[] = { //Plant Commissioning { SSC_INPUT, SSC_NUMBER, "plant_commissioning_cost_method", "Plant commissioning 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, "plant_commissioning_cost_input", "Plant commissioning cost", "$", "", "MHKCosts", "plant_commissioning_cost_method<2", "", "" }, - { SSC_INPUT, SSC_NUMBER, "plant_commissioning_cost_total", "Plant commissioning itemized cost total", "$", "", "MHKCosts", "plant_commissioning_cost_method=3", "", "" }, { SSC_INPUT, SSC_NUMBER, "plant_commissioning_cost_rvalue", "Plant commissioning R-value", "", "", "MHKCosts", "plant_commissioning_cost_method=4", "MIN=0,MAX=1", "" }, //Site Access @@ -133,6 +132,20 @@ static var_info _cm_vtab_mhk_costs[] = { { SSC_INPUT, SSC_NUMBER, "other_financial_cost_input", "Other financial cost", "$,$/kW", "", "MHKCosts", "other_financial_cost_method<2", "", "" }, { SSC_INPUT, SSC_NUMBER, "other_financial_cost_rvalue", "Other financial R-value", "", "", "MHKCosts", "other_financial_cost_method=3", "MIN=0,MAX=1", "" }, + //Operations + { SSC_INPUT, SSC_NUMBER, "operations_cost_method", "Operations 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, "operations_cost_input", "Operations cost", "$", "", "MHKCosts", "operations_cost_method<2", "", "" }, + { SSC_INPUT, SSC_NUMBER, "operations_cost_total", "Operations itemized cost total", "$", "", "MHKCosts", "operations_cost_method=3", "", "" }, + { SSC_INPUT, SSC_NUMBER, "operations_cost_rvalue", "Operations R-value", "", "", "MHKCosts", "operations_cost_method=4", "MIN=0,MAX=1", "" }, + + //Maintenance + { SSC_INPUT, SSC_NUMBER, "maintenance_cost_method", "Maintenance 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, "maintenance_cost_input", "Maintenance cost", "$", "", "MHKCosts", "maintenance_cost_method<2", "", "" }, + { SSC_INPUT, SSC_NUMBER, "maintenance_cost_total", "Maintenance itemized cost total", "$", "", "MHKCosts", "maintenance_cost_method=3", "", "" }, + { SSC_INPUT, SSC_NUMBER, "maintenance_cost_rvalue", "Maintenance R-value", "", "", "MHKCosts", "maintenance_cost_method=4", "MIN=0,MAX=1", "" }, + + + /*{ 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=4", "" }, @@ -181,13 +194,24 @@ static var_info _cm_vtab_mhk_costs[] = { { SSC_OUTPUT, SSC_NUMBER, "other_elec_infra_cost_modeled", "Modeled other electrical infrastructure cost", "$", "", "MHKCosts", "", "", "" },*/ //Financial costs - { SSC_OUTPUT, SSC_NUMBER, "project_contingency", "Modeled project contingency cost", "$", "", "MHKCosts", "", "", "" }, - { SSC_OUTPUT, SSC_NUMBER, "insurance_during_construction", "Modeled cost of insurance during construction", "$", "", "MHKCosts", "", "", "" }, - { SSC_OUTPUT, SSC_NUMBER, "reserve_accounts", "Modeled reserve account costs", "$", "", "MHKCosts", "", "", "" }, + { SSC_OUTPUT, SSC_NUMBER, "project_contingency_cost", "Project contingency cost", "$", "", "MHKCosts", "", "", "" }, + { SSC_OUTPUT, SSC_NUMBER, "project_contingency_cost_modeled", "Modeled project contingency cost", "$", "", "MHKCosts", "", "", "" }, + + { SSC_OUTPUT, SSC_NUMBER, "insurance_during_construction_cost", "Cost of insurance during construction", "$", "", "MHKCosts", "", "", "" }, + { SSC_OUTPUT, SSC_NUMBER, "insurance_during_construction_cost_modeled", "Modeled cost of insurance during construction", "$", "", "MHKCosts", "", "", "" }, + + { SSC_OUTPUT, SSC_NUMBER, "other_financial_cost", "Cost of other financial considerations", "$", "", "MHKCosts", "", "", "" }, + { SSC_OUTPUT, SSC_NUMBER, "other_financial_cost_modeled", "Modeled cost of other financial considerations", "$", "", "MHKCosts", "", "", "" }, + + { SSC_OUTPUT, SSC_NUMBER, "reserve_accounts_cost", "Reserve account costs", "$", "", "MHKCosts", "", "", "" }, + { SSC_OUTPUT, SSC_NUMBER, "reserve_accounts_cost_modeled", "Modeled reserve account costs", "$", "", "MHKCosts", "", "", "" }, //O and M costs { SSC_OUTPUT, SSC_NUMBER, "operations_cost", "Operations cost", "$", "", "MHKCosts", "", "", "" }, - { SSC_OUTPUT, SSC_NUMBER, "maintenance_cost", "Maintenance cost", "$", "", "MHKCosts", "", "", "" }, + { SSC_OUTPUT, SSC_NUMBER, "operations_cost_modeled", "Modeled operations cost", "$", "", "MHKCosts", "", "", "" }, + + { SSC_OUTPUT, SSC_NUMBER, "maintenance_cost", "Maintenance cost", "$", "", "MHKCosts", "", "", "" }, + { SSC_OUTPUT, SSC_NUMBER, "maintenance_cost_modeled", "Modeled maintenance cost", "$", "", "MHKCosts", "", "", "" }, var_info_invalid }; @@ -338,9 +362,10 @@ class cm_mhk_costs : public compute_module // operations cost operations_cost = 46157.0 * system_capacity_MW + 1078155.0; - + assign("operations_cost_modeled", var_data(static_cast(operations_cost))); // maintenance cost maintenance_cost = 79926.0 * system_capacity_MW + 2206357.0; + assign("maintenance_cost_modeled", var_data(static_cast(maintenance_cost))); //at this point, we need to assign the "independent" modeled outputs- //i.e., we want the modeled value to be reported prior to overwriting with a user input @@ -357,8 +382,7 @@ class cm_mhk_costs : public compute_module assign("onshore_substation_cost_modeled", var_data(static_cast(onshore_substation))); assign("offshore_substation_cost_modeled", var_data(static_cast(offshore_substation))); assign("other_elec_infra_cost_modeled", var_data(static_cast(other_elec_infra)));*/ - assign("operations_cost", var_data(static_cast(operations_cost))); - assign("maintenance_cost", var_data(static_cast(maintenance_cost))); + // there are five cost values that are a percentage of total CapEx // we want those modeled values to reflect user-input values that are overwriting the modeled values @@ -380,6 +404,9 @@ class cm_mhk_costs : public compute_module int reserve_accounts_cost_method = as_integer("reserve_accounts_cost_method"); int other_financial_cost_method = as_integer("other_financial_cost_method"); + int operations_cost_method = as_integer("operations_cost_method"); + int maintenance_cost_method = as_integer("maintenance_cost_method"); + /*int array_cable_system_cost_method = as_integer("array_cable_system_cost_method"); int export_cable_system_cost_method = as_integer("export_cable_system_cost_method"); int onshore_substation_cost_method = as_integer("onshore_substation_cost_method"); @@ -555,6 +582,14 @@ class cm_mhk_costs : public compute_module else if (reserve_accounts_cost_method == 4) reserve_accounts = as_double("reserve_accounts_cost_input") * -1 * std::log(1.0 - as_double("reserve_accounts_cost_rvalue")) / std::log(2.0); + double other_financial = 0.0; + assign("other_financial_cost_modeled", var_data(static_cast(other_financial))); + if (other_financial_cost_method == 0) + other_financial = as_double("other_financial_cost_input") * system_capacity_kW; + else if (other_financial_cost_method == 1) + other_financial = as_double("other_financial_cost_input"); + else if (other_financial_cost_method == 3) + other_financial = as_double("other_financial_cost_input") * -1 * std::log(1.0 - as_double("other_financial_cost_rvalue")) / std::log(2.0); // Assign the CapEx-dependent outputs assign("plant_commissioning_cost", var_data(static_cast(plant_commissioning))); @@ -562,7 +597,30 @@ class cm_mhk_costs : public compute_module assign("project_contingency_cost", var_data(static_cast(project_contingency))); assign("insurance_during_construction_cost", var_data(static_cast(insurance_during_construction))); assign("reserve_accounts_cost", var_data(static_cast(reserve_accounts))); + assign("other_financial_cost", var_data(static_cast(other_financial))); + + + + if (operations_cost_method == 0) + operations_cost = as_double("operations_cost_input") * system_capacity_kW; + else if (operations_cost_method == 1) + operations_cost = as_double("operations_cost_input"); + else if (operations_cost_method == 3) + operations_cost = as_double("operations_cost_total"); + else if (operations_cost_method == 4) + operations_cost = as_double("operations_cost_input") * -1 * std::log(1.0 - as_double("operations_cost_rvalue")) / std::log(2.0); + assign("operations_cost", var_data(static_cast(operations_cost))); + + if (maintenance_cost_method == 0) + maintenance_cost = as_double("maintenance_cost_input") * system_capacity_kW; + else if (maintenance_cost_method == 1) + maintenance_cost = as_double("maintenance_cost_input"); + else if (maintenance_cost_method == 3) + maintenance_cost = as_double("maintenance_cost_total"); + else if (maintenance_cost_method == 4) + maintenance_cost = as_double("maintenance_cost_input") * -1 * std::log(1.0 - as_double("maintenance_cost_rvalue")) / std::log(2.0); + assign("maintenance_cost", var_data(static_cast(maintenance_cost))); diff --git a/ssc/cmod_tidalfile.cpp b/ssc/cmod_tidalfile.cpp index e6c23523f..f5fb12f23 100644 --- a/ssc/cmod_tidalfile.cpp +++ b/ssc/cmod_tidalfile.cpp @@ -125,17 +125,22 @@ class cm_tidal_file_reader : public compute_module void exec() { - if (as_integer("tidal_resource_model_choice") == 0) return; + //if (as_integer("tidal_resource_model_choice") == 0) return; std::string file; if (is_assigned("tidal_resource_filename") && as_integer("tidal_resource_model_choice")==1) { file = as_string("tidal_resource_filename"); } + else if (is_assigned("tidal_resource_filename_dist") && as_integer("tidal_resource_model_choice") == 0) + { + file = as_string("tidal_resource_filename_dist"); + } else { throw exec_error("tidal_file_reader", "Model choice and tidal resource file do not match"); } + if (file.empty()) { throw exec_error("tidal_file_reader", "File name missing."); @@ -168,41 +173,98 @@ class cm_tidal_file_reader : public compute_module throw exec_error("tidal_file_reader", "Number of header column labels does not match number of values. There are " + std::to_string(ncols) + "keys and " + std::to_string(ncols1) + "values."); } if (as_integer("tidal_resource_model_choice") == 0) { - assign("name", var_data(values[0])); - assign("city", var_data(values[1])); - assign("state", var_data(values[2])); - assign("country", var_data(values[3])); - // lat with S is negative - ssc_number_t dlat = std::numeric_limits::quiet_NaN(); - std::vector slat = split(values[4], ' '); - if (slat.size() > 0) + //assign("name", var_data(values[0])); + //assign("city", var_data(values[1])); + //assign("state", var_data(values[2])); + //assign("country", var_data(values[3])); + //// lat with S is negative + //ssc_number_t dlat = std::numeric_limits::quiet_NaN(); + //std::vector slat = split(values[4], ' '); + //if (slat.size() > 0) + //{ + // dlat = std::stod(slat[0]); + // if (slat.size() > 1) + // { + // if (slat[1] == "S") dlat = 0.0 - dlat; + // } + //} + //assign("lat", var_data(dlat)); + //// lon with W is negative + //ssc_number_t dlon = std::numeric_limits::quiet_NaN(); + //std::vector slon = split(values[5], ' '); + //if (slon.size() > 0) + //{ + // dlon = std::stod(slon[0]); + // if (slon.size() > 1) + // { + // if (slon[1] == "W") dlon = 0.0 - dlon; + // } + //} + //assign("lon", var_data(dlon)); + //assign("nearby_buoy_number", var_data(values[6])); + //assign("average_power_flux", var_data(std::stod(values[7]))); + //assign("bathymetry", var_data(values[8])); + //assign("sea_bed", var_data(values[9])); + //assign("tz", var_data(std::stod(values[10]))); + //assign("data_source", var_data(values[11])); + //assign("notes", var_data(values[12])); + + // allow metadata rows to have different lengths as long as required data is included + ncols = std::min(ncols, ncols1); + + std::string name, value; + + for (size_t i = 0; (int)i < ncols; i++) { - dlat = std::stod(slat[0]); - if (slat.size() > 1) + + name = ""; + if (!keys[i].empty()) + name = util::lower_case(trimboth(keys[i])); + + value = ""; + if (!values[i].empty()) + value = trimboth(values[i]); + + // required metadata (see checks below) + if (name == "lat" || name == "latitude") { - if (slat[1] == "S") dlat = 0.0 - dlat; + assign("lat", var_data(std::stod(value))); } - } - assign("lat", var_data(dlat)); - // lon with W is negative - ssc_number_t dlon = std::numeric_limits::quiet_NaN(); - std::vector slon = split(values[5], ' '); - if (slon.size() > 0) - { - dlon = std::stod(slon[0]); - if (slon.size() > 1) + else if (name == "lon" || name == "long" || name == "longitude" || name == "lng") + { + assign("lon", var_data(std::stod(value))); + } + else if (name == "tz" || name == "timezone" || name == "time zone") // require "time zone" and "local time zone" columns in NSRDB files are the same { - if (slon[1] == "W") dlon = 0.0 - dlon; + assign("tz", var_data(std::stod(value))); + } + else if (name == "distance to shore" || name == "shore distance" || name == "distance") // require "time zone" and "local time zone" columns in NSRDB files are the same + { + assign("distance_to_shore_file", var_data(std::stod(value))); + } + else if (name == "water depth" || name == "depth") // require "time zone" and "local time zone" columns in NSRDB files are the same + { + assign("water_depth_file", var_data(std::stod(value))); + } + else if (name == "id" || name == "jurisdiction" || name == "station id" || name == "wban" || name == "wban#" || name == "site") + { + assign("location", var_data(value)); + } + else if (name == "location" || name == "location id") + { + assign("location_id", var_data(value)); + } + + + else if (name == "source" || name == "src" || name == "data source") + { + assign("data_source", var_data(value)); + } + else if (name == "notes" || name == "source notes") + { + assign("notes", var_data(value)); } } - assign("lon", var_data(dlon)); - assign("nearby_buoy_number", var_data(values[6])); - assign("average_power_flux", var_data(std::stod(values[7]))); - assign("bathymetry", var_data(values[8])); - assign("sea_bed", var_data(values[9])); - assign("tz", var_data(std::stod(values[10]))); - assign("data_source", var_data(values[11])); - assign("notes", var_data(values[12])); } else { /* @@ -416,28 +478,39 @@ class cm_tidal_file_reader : public compute_module assign("number_hours", int(numberRecords * hourdiff)); } else if (as_integer("tidal_resource_model_choice") == 0) { - ssc_number_t* mat = allocate("wave_resource_matrix", 21, 22); - for (size_t r = 0; r < 21; r++) + getline(ifs, buf); //Skip past column labels for record counting + size_t numberRecords = 0; + while (getline(ifs, buf)) { + numberRecords++; + + } + + ifs.clear(); + ifs.seekg(0); + for (size_t i = 0; i < 3; i++) + getline(ifs, buf); + if (ifs.eof()) + { + throw exec_error("tidal_file_reader", "Could not read column names"); + } + ssc_number_t* mat = allocate("tidal_resource", numberRecords, 2); + for (size_t r = 0; r < numberRecords; r++) { getline(ifs, buf); values.clear(); values = split(buf); - if (values.size() != 22) - { - throw exec_error("tidal_file_reader", "Wave period columns must span 0.5s to 20.5s with increments of 1s. Incorrect number of wave period (s) columns: " + std::to_string(values.size())); - } - for (size_t c = 0; c < 22; c++) + if (values.size() != 2) { - if (r == 0 && c == 0) - mat[r * 22 + c] = 0.0; - else - mat[r * 22 + c] = std::stod(values[c]); + throw exec_error("tidal_file_reader", "Tidal resource probability must contain 2 columns: tidal velocity and probability of occurence"); } + mat[r * 2] = std::stod(values[0]); + mat[r * 2 + 1] = std::stod(values[1]); + } } else { - throw exec_error("tidal_file_reader", "Resource data type needs to be defined "); + throw exec_error("tidal_file_reader", "Resource data type needs to be defined. "); } return; From 6293d930d7d5df37f3bc9648f8ad003e2d08a262 Mon Sep 17 00:00:00 2001 From: Matt Prilliman <54449384+mjprilliman@users.noreply.github.com> Date: Thu, 23 Oct 2025 11:11:40 -0500 Subject: [PATCH 5/8] Update capex basis for costs, skip distribution files in tidal file reader --- ssc/cmod_mhk_costs.cpp | 3 +++ ssc/cmod_tidalfile.cpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ssc/cmod_mhk_costs.cpp b/ssc/cmod_mhk_costs.cpp index 49ae359aa..568507d73 100644 --- a/ssc/cmod_mhk_costs.cpp +++ b/ssc/cmod_mhk_costs.cpp @@ -540,6 +540,7 @@ class cm_mhk_costs : public compute_module else if (plant_commissioning_cost_method == 3) plant_commissioning = as_double("plant_commissioning_cost_input") * -1 * std::log(1.0 - as_double("plant_commissioning_cost_rvalue")) / std::log(2.0); + site_access_port_staging = 0.011 * capex; assign("site_access_port_staging_cost_modeled", var_data(static_cast(site_access_port_staging))); if (site_access_port_staging_cost_method == 0) @@ -551,6 +552,8 @@ class cm_mhk_costs : public compute_module else if (site_access_port_staging_cost_method == 4) site_access_port_staging = as_double("site_access_port_staging_cost_input") * -1 * std::log(1.0 - as_double("site_access_port_staging_cost_rvalue")) / std::log(2.0); + + //capex += plant_commissioning + site_access_port_staging; // Calculate the CapEx-dependent financial costs project_contingency = 0.081 * capex; assign("project_contingency_cost_modeled", var_data(static_cast(project_contingency))); diff --git a/ssc/cmod_tidalfile.cpp b/ssc/cmod_tidalfile.cpp index f5fb12f23..47362c469 100644 --- a/ssc/cmod_tidalfile.cpp +++ b/ssc/cmod_tidalfile.cpp @@ -125,7 +125,7 @@ class cm_tidal_file_reader : public compute_module void exec() { - //if (as_integer("tidal_resource_model_choice") == 0) return; + if (as_integer("tidal_resource_model_choice") == 0) return; //Nothing to do std::string file; if (is_assigned("tidal_resource_filename") && as_integer("tidal_resource_model_choice")==1) From b0fa6b6c877118bb43e9ccfb2d12e0c8c38b0b07 Mon Sep 17 00:00:00 2001 From: Matt Prilliman <54449384+mjprilliman@users.noreply.github.com> Date: Thu, 23 Oct 2025 17:22:49 -0500 Subject: [PATCH 6/8] Check for empty value in col headings --- ssc/cmod_wavefile.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/ssc/cmod_wavefile.cpp b/ssc/cmod_wavefile.cpp index 802b5a7ed..f09c2f023 100644 --- a/ssc/cmod_wavefile.cpp +++ b/ssc/cmod_wavefile.cpp @@ -206,6 +206,7 @@ class cm_wave_file_reader : public compute_module value = ""; if (!values[i].empty()) value = trimboth(values[i]); + if (value == "") continue; // required metadata (see checks below) if (name == "lat" || name == "latitude") From be8aba06f91d8c30bb897e99603cf684cad714cf Mon Sep 17 00:00:00 2001 From: Steven Janzou Date: Fri, 24 Oct 2025 01:54:54 -0600 Subject: [PATCH 7/8] Remove macos-latest runner with suspect stable_sort issue for failing GitHub Actions --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b74b91d96..60371962e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -102,7 +102,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [macos-14-large, macos-latest] + os: [macos-14-large] steps: - name: Setup cmake From aa92d0b4c1a90120d07d06c0fc25149cee8bdd9d Mon Sep 17 00:00:00 2001 From: Matt Prilliman <54449384+mjprilliman@users.noreply.github.com> Date: Fri, 24 Oct 2025 14:11:20 -0500 Subject: [PATCH 8/8] Add mhk_cost unit tests, cost model checks for future debugging --- ssc/cmod_mhk_costs.cpp | 40 +++---- test/input_cases/mhk/mhk_cost_inputs.h | 117 ++++++++++++++++++ test/ssc_test/cmod_mhk_costs_test.cpp | 158 +++++++++++++++++++++++++ test/ssc_test/cmod_mhk_costs_test.h | 82 +++++++++++++ 4 files changed, 375 insertions(+), 22 deletions(-) create mode 100644 test/input_cases/mhk/mhk_cost_inputs.h create mode 100644 test/ssc_test/cmod_mhk_costs_test.cpp create mode 100644 test/ssc_test/cmod_mhk_costs_test.h diff --git a/ssc/cmod_mhk_costs.cpp b/ssc/cmod_mhk_costs.cpp index 568507d73..4f45b0da4 100644 --- a/ssc/cmod_mhk_costs.cpp +++ b/ssc/cmod_mhk_costs.cpp @@ -50,96 +50,92 @@ static var_info _cm_vtab_mhk_costs[] = { { SSC_INPUT, SSC_STRING, "lib_wave_device", "Wave library name", "", "", "MHKCosts", "marine_energy_tech=0", "", "" }, { SSC_INPUT, SSC_STRING, "lib_tidal_device", "Tidal library name", "", "", "MHKCosts", "marine_energy_tech=1", "", "" }, - { SSC_INPUT, SSC_NUMBER, "inter_array_cable_length", "Inter-array cable length", "m", "", "MHKCosts", "*", "MIN=0", "" }, - { SSC_INPUT, SSC_NUMBER, "riser_cable_length", "Riser cable length", "m", "", "MHKCosts", "*", "MIN=0", "" }, - { 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=4", "" }, + { SSC_INPUT, SSC_NUMBER, "structural_assembly_cost_method", "Structural assembly cost method", "0-4", "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", "structural_assembly_cost_method<2", "", "" }, { SSC_INPUT, SSC_NUMBER, "structural_assembly_cost_total", "Structural assembly itemized cost total", "$", "", "MHKCosts", "structural_assembly_cost_method=3", "", "" }, { SSC_INPUT, SSC_NUMBER, "structural_assembly_cost_rvalue", "Structural assembly R-value", "", "", "MHKCosts", "structural_assembly_cost_method=4", "MIN=0,MAX=1", "" }, - { 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_method", "Power take-off system cost method", "0-4", "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", "power_takeoff_system_cost_method<2", "", "" }, { SSC_INPUT, SSC_NUMBER, "power_takeoff_system_cost_total", "Power take-off system cost itemized cost total", "$", "", "MHKCosts", "power_takeoff_system_cost_method=3", "", "" }, { SSC_INPUT, SSC_NUMBER, "structural_assembly_cost_rvalue", "Power take-off system R-value", "", "", "MHKCosts", "power_takeoff_system_cost_method=4", "MIN=0,MAX=1", "" }, - { 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_method", "Mooring, foundation, and substructure cost method", "0-4", "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", "mooring_found_substruc_cost_method<2", "", "" }, { SSC_INPUT, SSC_NUMBER, "mooring_found_substruc_cost_total", "Mooring, foundation, and substructure itemized cost total", "$", "", "MHKCosts", "mooring_found_substruc_cost_method=3", "", "" }, { SSC_INPUT, SSC_NUMBER, "mooring_found_substruc_cost_rvalue", "Mooring, foundation, and substructure R-value", "", "", "MHKCosts", "mooring_found_substruc_cost_method=4", "MIN=0,MAX=1", "" }, // 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=4", "" }, + { SSC_INPUT, SSC_NUMBER, "development_cost_method", "Development cost method", "0-4", "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", "development_cost_method<2", "", "" }, { SSC_INPUT, SSC_NUMBER, "development_cost_total", "Development itemized cost total", "$", "", "MHKCosts", "development_cost_method=3", "", "" }, { SSC_INPUT, SSC_NUMBER, "development_cost_rvalue", "Development R-value", "", "", "MHKCosts", "development_cost_method=4", "MIN=0,MAX=1", "" }, - { 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_method", "Engineering and management cost method", "0-4", "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", "eng_and_mgmt_cost_method<2", "", "" }, { SSC_INPUT, SSC_NUMBER, "eng_and_mgmt_cost_total", "Engineering and management itemized cost total", "$", "", "MHKCosts", "eng_and_mgmt_cost_method=3", "", "" }, { SSC_INPUT, SSC_NUMBER, "eng_and_mgmt_cost_rvalue", "Engineering and management R-value", "", "", "MHKCosts", "eng_and_mgmt_cost_method=4", "MIN=0,MAX=1", "" }, - { 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_method", "Assembly and installation cost method", "0-4", "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", "assembly_and_install_cost_method<2", "", "" }, { SSC_INPUT, SSC_NUMBER, "assembly_and_install_cost_total", "Assembly and installation itemized cost total", "$", "", "MHKCosts", "assembly_and_install_cost_method=3", "", "" }, { SSC_INPUT, SSC_NUMBER, "assembly_and_install_cost_rvalue", "Assembly and installation R-value", "", "", "MHKCosts", "assembly_and_install_cost_method=4", "MIN=0,MAX=1", "" }, - { 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_method", "Other infrastructure cost method", "0-4", "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", "other_infrastructure_cost_method<2", "", "" }, { SSC_INPUT, SSC_NUMBER, "other_infrastructure_cost_total", "Other infrastructure itemized cost total", "$", "", "MHKCosts", "other_infrastructure_cost_method=3", "", "" }, { SSC_INPUT, SSC_NUMBER, "other_infrastructure_cost_rvalue", "Other infrastructure R-value", "", "", "MHKCosts", "other_infrastructure_cost_method=4", "MIN=0,MAX=1", "" }, - { SSC_INPUT, SSC_NUMBER, "elec_infras_cost_method", "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, "elec_infras_cost_method", "Electrical infrastructure cost method", "0-4", "0=Enter in $/kW,1=Enter in $,2=Use modeled value", "MHKCosts", "*", "MIN=0,MAX=4", "" }, { SSC_INPUT, SSC_NUMBER, "elec_infras_cost_input", "Electrical infrastructure cost", "$", "", "MHKCosts", "elec_infras_cost_method<2", "", "" }, { SSC_INPUT, SSC_NUMBER, "elec_infras_cost_modeled", "Electrical infrastructure cost modeled", "$", "", "MHKCosts", "elec_infras_cost_method=2", "", "" }, { SSC_INPUT, SSC_NUMBER, "elec_infras_cost_total", "Electrical infrastructure itemized cost total", "$", "", "MHKCosts", "elec_infras_cost_method=3", "", "" }, { SSC_INPUT, SSC_NUMBER, "elec_infras_cost_rvalue", "Electrical infrastructure R-value", "", "", "MHKCosts", "elec_infras_cost_method=4", "MIN=0,MAX=1", "" }, //Plant Commissioning - { SSC_INPUT, SSC_NUMBER, "plant_commissioning_cost_method", "Plant commissioning 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, "plant_commissioning_cost_method", "Plant commissioning cost method", "0-3", "0=Enter in $/kW,1=Enter in $,2=Use modeled value", "MHKCosts", "*", "MIN=0,MAX=4", "" }, { SSC_INPUT, SSC_NUMBER, "plant_commissioning_cost_input", "Plant commissioning cost", "$", "", "MHKCosts", "plant_commissioning_cost_method<2", "", "" }, { SSC_INPUT, SSC_NUMBER, "plant_commissioning_cost_rvalue", "Plant commissioning R-value", "", "", "MHKCosts", "plant_commissioning_cost_method=4", "MIN=0,MAX=1", "" }, //Site Access - { SSC_INPUT, SSC_NUMBER, "site_access_port_staging_cost_method", "Site access and port staging 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, "site_access_port_staging_cost_method", "Site access and port staging cost method", "0-4", "0=Enter in $/kW,1=Enter in $,2=Use modeled value", "MHKCosts", "*", "MIN=0,MAX=4", "" }, { SSC_INPUT, SSC_NUMBER, "site_access_port_staging_cost_input", "Site access and port staging cost", "$", "", "MHKCosts", "site_access_port_staging_cost_method<2", "", "" }, { SSC_INPUT, SSC_NUMBER, "site_access_port_staging_cost_total", "Site access and port staging itemized cost total", "$", "", "MHKCosts", "site_access_port_staging_cost_method=3", "", "" }, { SSC_INPUT, SSC_NUMBER, "site_access_port_staging_cost_rvalue", "Site access and port staging R-value", "", "", "MHKCosts", "site_access_port_staging_cost_method=4", "MIN=0,MAX=1", "" }, //Project Contingency - { SSC_INPUT, SSC_NUMBER, "project_contingency_cost_method", "Project contingency 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, "project_contingency_cost_method", "Project contingency cost method", "0-3", "0=Enter in $/kW,1=Enter in $,2=Use modeled value", "MHKCosts", "*", "MIN=0,MAX=4", "" }, { SSC_INPUT, SSC_NUMBER, "project_contingency_cost_input", "Project contingency cost", "$", "", "MHKCosts", "project_contingency_cost_method<2", "", "" }, { SSC_INPUT, SSC_NUMBER, "project_contingency_cost_rvalue", "Project contingency R-value", "", "", "MHKCosts", "project_contingency_cost_method=3", "MIN=0,MAX=1", "" }, //Insurance during construction - { SSC_INPUT, SSC_NUMBER, "insurance_during_construction_cost_method", "Insurance during construction 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, "insurance_during_construction_cost_method", "Insurance during construction cost method", "0-3", "0=Enter in $/kW,1=Enter in $,2=Use modeled value", "MHKCosts", "*", "MIN=0,MAX=4", "" }, { SSC_INPUT, SSC_NUMBER, "insurance_during_construction_cost_input", "Insurance during construction cost", "$", "", "MHKCosts", "insurance_during_construction_cost_method<2", "", "" }, { SSC_INPUT, SSC_NUMBER, "insurance_during_construction_cost_rvalue", "Insurance during construction R-value", "", "", "MHKCosts", "insurance_during_construction_cost_method=3", "MIN=0,MAX=1", "" }, //Reserve Accounts - { SSC_INPUT, SSC_NUMBER, "reserve_accounts_cost_method", "Reserve accounts 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, "reserve_accounts_cost_method", "Reserve accounts cost method", "0-4", "0=Enter in $/kW,1=Enter in $,2=Use modeled value", "MHKCosts", "*", "MIN=0,MAX=4", "" }, { SSC_INPUT, SSC_NUMBER, "reserve_accounts_cost_input", "Reserve accounts cost", "$", "", "MHKCosts", "reserve_accounts_cost_method<2", "", "" }, { SSC_INPUT, SSC_NUMBER, "reserve_accounts_cost_total", "Reserve accounts itemized cost total", "$", "", "MHKCosts", "reserve_accounts_cost_method=3", "", "" }, { SSC_INPUT, SSC_NUMBER, "reserve_accounts_cost_rvalue", "Reserve accounts R-value", "", "", "MHKCosts", "reserve_accounts_cost_method=4", "MIN=0,MAX=1", "" }, //Other financial costs - { SSC_INPUT, SSC_NUMBER, "other_financial_cost_method", "Other financial 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_financial_cost_method", "Other financial cost method", "0-3", "0=Enter in $/kW,1=Enter in $,2=Use modeled value", "MHKCosts", "*", "MIN=0,MAX=4", "" }, { SSC_INPUT, SSC_NUMBER, "other_financial_cost_input", "Other financial cost", "$,$/kW", "", "MHKCosts", "other_financial_cost_method<2", "", "" }, { SSC_INPUT, SSC_NUMBER, "other_financial_cost_rvalue", "Other financial R-value", "", "", "MHKCosts", "other_financial_cost_method=3", "MIN=0,MAX=1", "" }, //Operations - { SSC_INPUT, SSC_NUMBER, "operations_cost_method", "Operations 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, "operations_cost_method", "Operations cost method", "0-4", "0=Enter in $/kW,1=Enter in $,2=Use modeled value", "MHKCosts", "*", "MIN=0,MAX=4", "" }, { SSC_INPUT, SSC_NUMBER, "operations_cost_input", "Operations cost", "$", "", "MHKCosts", "operations_cost_method<2", "", "" }, { SSC_INPUT, SSC_NUMBER, "operations_cost_total", "Operations itemized cost total", "$", "", "MHKCosts", "operations_cost_method=3", "", "" }, { SSC_INPUT, SSC_NUMBER, "operations_cost_rvalue", "Operations R-value", "", "", "MHKCosts", "operations_cost_method=4", "MIN=0,MAX=1", "" }, //Maintenance - { SSC_INPUT, SSC_NUMBER, "maintenance_cost_method", "Maintenance 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, "maintenance_cost_method", "Maintenance cost method", "0-4", "0=Enter in $/kW,1=Enter in $,2=Use modeled value", "MHKCosts", "*", "MIN=0,MAX=4", "" }, { SSC_INPUT, SSC_NUMBER, "maintenance_cost_input", "Maintenance cost", "$", "", "MHKCosts", "maintenance_cost_method<2", "", "" }, { SSC_INPUT, SSC_NUMBER, "maintenance_cost_total", "Maintenance itemized cost total", "$", "", "MHKCosts", "maintenance_cost_method=3", "", "" }, { SSC_INPUT, SSC_NUMBER, "maintenance_cost_rvalue", "Maintenance R-value", "", "", "MHKCosts", "maintenance_cost_method=4", "MIN=0,MAX=1", "" }, @@ -233,9 +229,9 @@ class cm_mhk_costs : public compute_module // int device_type = as_integer("device_type"); int technology = as_integer("marine_energy_tech"); int devices_per_row = as_integer("devices_per_row"); - double interarray_length = as_double("inter_array_cable_length"); + /*double interarray_length = as_double("inter_array_cable_length"); double riser_length = as_double("riser_cable_length"); - double export_length = as_double("export_cable_length"); + double export_length = as_double("export_cable_length");*/ int device_type = 4; diff --git a/test/input_cases/mhk/mhk_cost_inputs.h b/test/input_cases/mhk/mhk_cost_inputs.h new file mode 100644 index 000000000..06a7f25e2 --- /dev/null +++ b/test/input_cases/mhk/mhk_cost_inputs.h @@ -0,0 +1,117 @@ +/* +BSD 3-Clause License + +Copyright (c) Alliance for Sustainable Energy, LLC. See also https://github.com/NREL/ssc/blob/develop/LICENSE +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef MHK_COST_INPUTS_H_ +#define MHK_COST_INPUTS_H_ + +#include +#include "../test/input_cases/code_generator_utilities.h" + +void mhk_cost_inputs(ssc_data_t &data) { + + ssc_data_set_number(data, "device_rated_power", 286); + ssc_data_set_number(data, "system_capacity", 28600); + ssc_data_set_number(data, "devices_per_row", 10); + ssc_data_set_number(data, "marine_energy_tech", 0); + ssc_data_set_number(data, "library_or_input_wec", 0); + ssc_data_set_string(data, "lib_wave_device", "RM3"); + ssc_data_set_string(data, "lib_tidal_device", "RM1"); + ssc_data_set_number(data, "structural_assembly_cost_method", 2); + ssc_data_set_number(data, "structural_assembly_cost_input", 100); //$ or $/kW + ssc_data_set_number(data, "structural_assembly_cost_total", 1000000); + ssc_data_set_number(data, "structural_assembly_cost_rvalue", 0.1); + ssc_data_set_number(data, "power_takeoff_system_cost_method", 2); + ssc_data_set_number(data, "power_takeoff_system_cost_input", 100); //$ or $/kW + ssc_data_set_number(data, "power_takeoff_system_cost_total", 1000000); + ssc_data_set_number(data, "power_takeoff_system_cost_rvalue", 0.1); + ssc_data_set_number(data, "mooring_found_substruc_cost_method", 2); + ssc_data_set_number(data, "mooring_found_substruc_cost_input", 100); //$ or $/kW + ssc_data_set_number(data, "mooring_found_substruc_cost_total", 1000000); + ssc_data_set_number(data, "mooring_found_substruc_cost_rvalue", 0.1); + ssc_data_set_number(data, "development_cost_method", 2); + ssc_data_set_number(data, "development_cost_input", 100); //$ or $/kW + ssc_data_set_number(data, "development_cost_total", 1000000); + ssc_data_set_number(data, "development_cost_rvalue", 0.1); + ssc_data_set_number(data, "eng_and_mgmt_cost_method", 2); + ssc_data_set_number(data, "eng_and_mgmt_cost_input", 100); //$ or $/kW + ssc_data_set_number(data, "eng_and_mgmt_cost_total", 1000000); + ssc_data_set_number(data, "eng_and_mgmt_cost_rvalue", 0.1); + ssc_data_set_number(data, "assembly_and_install_cost_method", 2); + ssc_data_set_number(data, "assembly_and_install_cost_input", 100); //$ or $/kW + ssc_data_set_number(data, "assembly_and_install_cost_total", 1000000); + ssc_data_set_number(data, "assembly_and_install_cost_rvalue", 0.1); + ssc_data_set_number(data, "other_infrastructure_cost_method", 2); + ssc_data_set_number(data, "other_infrastructure_cost_input", 100); //$ or $/kW + ssc_data_set_number(data, "other_infrastructure_cost_total", 1000000); + ssc_data_set_number(data, "other_infrastructure_cost_rvalue", 0.1); + ssc_data_set_number(data, "elec_infras_cost_method", 2); + ssc_data_set_number(data, "elec_infras_cost_modeled", 0); + ssc_data_set_number(data, "elec_infras_cost_input", 100); //$ or $/kW + ssc_data_set_number(data, "elec_infras_cost_total", 1000000); + ssc_data_set_number(data, "elec_infras_cost_rvalue", 0.1); + ssc_data_set_number(data, "plant_commissioning_cost_method", 2); + ssc_data_set_number(data, "plant_commissioning_cost_input", 100); //$ or $/kW + ssc_data_set_number(data, "plant_commissioning_cost_total", 1000000); + ssc_data_set_number(data, "plant_commissioning_cost_rvalue", 0.1); + ssc_data_set_number(data, "site_access_port_staging_cost_method", 2); + ssc_data_set_number(data, "site_access_port_staging_cost_input", 100); //$ or $/kW + ssc_data_set_number(data, "site_access_port_staging_cost_total", 1000000); + ssc_data_set_number(data, "site_access_port_staging_cost_rvalue", 0.1); + ssc_data_set_number(data, "project_contingency_cost_method", 2); + ssc_data_set_number(data, "project_contingency_cost_input", 100); //$ or $/kW + ssc_data_set_number(data, "project_contingency_cost_total", 1000000); + ssc_data_set_number(data, "project_contingency_cost_rvalue", 0.1); + ssc_data_set_number(data, "insurance_during_construction_cost_method", 2); + ssc_data_set_number(data, "insurance_during_construction_cost_input", 100); //$ or $/kW + ssc_data_set_number(data, "insurance_during_construction_cost_total", 1000000); + ssc_data_set_number(data, "insurance_during_construction_cost_rvalue", 0.1); + ssc_data_set_number(data, "reserve_accounts_cost_method", 2); + ssc_data_set_number(data, "reserve_accounts_cost_input", 100); //$ or $/kW + ssc_data_set_number(data, "reserve_accounts_cost_total", 1000000); + ssc_data_set_number(data, "reserve_accounts_cost_rvalue", 0.1); + ssc_data_set_number(data, "other_financial_cost_method", 2); + ssc_data_set_number(data, "other_financial_cost_input", 100); //$ or $/kW + ssc_data_set_number(data, "other_financial_cost_total", 1000000); + ssc_data_set_number(data, "other_financial_cost_rvalue", 0.1); + ssc_data_set_number(data, "operations_cost_method", 2); + ssc_data_set_number(data, "operations_cost_input", 100); //$ or $/kW + ssc_data_set_number(data, "operations_cost_total", 1000000); + ssc_data_set_number(data, "operations_cost_rvalue", 0.1); + ssc_data_set_number(data, "maintenance_cost_method", 2); + ssc_data_set_number(data, "maintenance_cost_input", 100); //$ or $/kW + ssc_data_set_number(data, "maintenance_cost_total", 1000000); + ssc_data_set_number(data, "maintenance_cost_rvalue", 0.1); + + +} + +#endif diff --git a/test/ssc_test/cmod_mhk_costs_test.cpp b/test/ssc_test/cmod_mhk_costs_test.cpp new file mode 100644 index 000000000..97f4e5ad7 --- /dev/null +++ b/test/ssc_test/cmod_mhk_costs_test.cpp @@ -0,0 +1,158 @@ +/* +BSD 3-Clause License + +Copyright Alliance for Sustainable Energy, LLC. See also https://github.com/NREL/ssc/blob/develop/LICENSE + + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include "cmod_mhk_costs_test.h" +#include "core.h" + +TEST_F(CM_MHKCost, ComputeModuleTest_cmod_mhk_costs) { + + int mhk_wave_errors = run_module(data, "mhk_costs"); + ASSERT_EQ(mhk_wave_errors, 0); + + ssc_number_t structural, pto, moor; + + ssc_data_get_number(data, "structural_assembly_cost", &structural); + EXPECT_NEAR(structural, 244480984, 1.0); //$ + + ssc_data_get_number(data, "power_takeoff_system_cost", &pto); + EXPECT_NEAR(pto, 55906235, 1.0); //$ + + ssc_data_get_number(data, "mooring_found_substruc_cost", &moor); + EXPECT_NEAR(moor, 64289168, 1.0); //$ + +} + +TEST_F(CM_MHKCost, ModeledValuesTest) { + + + + std::string devices[3] = { "RM1", "RM3", "RM5" }; + ssc_number_t device_rated_power[3] = { 1115, 286, 360 }; + ssc_number_t system_capacity[3] = { 111500, 28600, 36000 }; + ssc_number_t elec_infras_cost[3] = { 17322061, 7451369, 8594027 }; + ssc_number_t struc_cost[3] = { 49952032, 244480984, 307846813 }; + ssc_number_t pto_cost[3] = { 213727306, 55906235, 51433792 }; + ssc_number_t moor_cost[3] = { 50006748, 64289168, 97254913 }; + ssc_number_t dev_cost[3] = { 31909103, 15942304, 17927457 }; + ssc_number_t eng_cost[3] = { 14702409, 6862456, 7806277 }; + ssc_number_t assem_cost[3] = { 69982331, 28124155, 32812318 }; + ssc_number_t elec_cost[3] = { 17322061, 7451369, 8594027 }; + ssc_number_t site_cost[3] = { 4923622, 4653623, 5760432 }; + ssc_number_t plant_cost[3] = { 7161632, 6768907, 8378810 }; + ssc_number_t ins_cost[3] = { 5818826, 5499737, 6807783 }; + ssc_number_t cont_cost[3] = { 36255761, 34267590, 42417723 }; + ssc_number_t res_cost[3] = { 13875662, 13114757, 16233944 }; + ssc_number_t oper_cost[3] = { 6224661, 2398245, 2739807 }; + ssc_number_t maint_cost[3] = { 11118106, 4492241, 5083693 }; + ssc_number_t struc, pto, moor, dev, eng, assem, elec, site, plant, ins, cont, res, oper, maint; + for (int i = 0; i < 3; i++) { + ssc_data_set_string(data, "lib_wave_device", devices[i].c_str()); + if (devices[i] == "RM1") + ssc_data_set_number(data, "marine_energy_tech", 1); + else + ssc_data_set_number(data, "marine_energy_tech", 0); + ssc_data_set_number(data, "device_rated_power", device_rated_power[i]); + ssc_data_set_number(data, "system_capacity", system_capacity[i]); + ssc_data_set_number(data, "elec_infras_cost_modeled", elec_infras_cost[i]); + int mhk_wave_errors = run_module(data, "mhk_costs"); + ASSERT_EQ(mhk_wave_errors, 0); + ssc_data_get_number(data, "structural_assembly_cost", &struc); + EXPECT_NEAR(struc, struc_cost[i], 1.0); //$ + ssc_data_get_number(data, "power_takeoff_system_cost", &pto); + EXPECT_NEAR(pto, pto_cost[i], 1.0); //$ + ssc_data_get_number(data, "mooring_found_substruc_cost", &moor); + EXPECT_NEAR(moor, moor_cost[i], 1.0); //$ + ssc_data_get_number(data, "development_cost", &dev); + EXPECT_NEAR(dev, dev_cost[i], 1.0); //$ + ssc_data_get_number(data, "eng_and_mgmt_cost", &eng); + EXPECT_NEAR(eng, eng_cost[i], 1.0); //$ + ssc_data_get_number(data, "assembly_and_install_cost", &assem); + EXPECT_NEAR(assem, assem_cost[i], 1.0); //$ + ssc_data_get_number(data, "elec_infras_cost", &elec); + EXPECT_NEAR(elec, elec_cost[i], 1.0); //$ + ssc_data_get_number(data, "site_access_port_staging_cost", &site); + EXPECT_NEAR(site, site_cost[i], 1.0); //$ + ssc_data_get_number(data, "plant_commissioning_cost", &plant); + EXPECT_NEAR(plant, plant_cost[i], 1.0); //$ + ssc_data_get_number(data, "insurance_during_construction_cost", &ins); + EXPECT_NEAR(ins, ins_cost[i], 1.0); //$ + ssc_data_get_number(data, "project_contingency_cost", &cont); + EXPECT_NEAR(cont, cont_cost[i], 1.0); //$ + ssc_data_get_number(data, "reserve_accounts_cost", &res); + EXPECT_NEAR(res, res_cost[i], 1.0); //$ + ssc_data_get_number(data, "operations_cost", &oper); + EXPECT_NEAR(oper, oper_cost[i], 1000.0); //$ + ssc_data_get_number(data, "maintenance_cost", &maint); + EXPECT_NEAR(maint, maint_cost[i], 1000.0); //$ + + } +} + +TEST_F(CM_MHKCost, CostModelOptionsTest) { + ssc_data_set_number(data, "structural_assembly_cost_input", 100); //$ or $/kW + ssc_data_set_number(data, "structural_assembly_cost_total", 1000000); + ssc_data_set_number(data, "structural_assembly_cost_rvalue", 0.1); + + ssc_number_t struc_cost[5] = { 2860000, 100, 244480984, 1000000, 15.20 }; + + ssc_number_t struc, pto, moor, dev, eng, assem, elec, site, plant, ins, cont, res, oper, maint; + for (int i = 0; i < 5; i++) { + ssc_data_set_number(data, "structural_assembly_cost_method", i); + ssc_data_set_number(data, "power_takeoff_system_cost_method", i); + ssc_data_set_number(data, "mooring_found_substruct_cost_method", i); + ssc_data_set_number(data, "development_cost_method", i); + ssc_data_set_number(data, "eng_and_mgmt_cost_method", i); + ssc_data_set_number(data, "assembly_and_install_cost_method", i); + ssc_data_set_number(data, "other_infrastructure_cost_method", i); + ssc_data_set_number(data, "elec_infras_cost_method", i); + ssc_data_set_number(data, "plant_commissioning_cost_method", i); + ssc_data_set_number(data, "site_access_port_staging_cost_method", i); + ssc_data_set_number(data, "project_conteingency_cost_method", i); + ssc_data_set_number(data, "insurance_during_construction_cost_method", i); + ssc_data_set_number(data, "reserve_accounts_cost_method", i); + ssc_data_set_number(data, "other_financial_cost_method", i); + ssc_data_set_number(data, "operations_cost_method", i); + ssc_data_set_number(data, "maintenance_cost_method", i); + int mhk_wave_errors = run_module(data, "mhk_costs"); + ASSERT_EQ(mhk_wave_errors, 0); + ssc_data_get_number(data, "structural_assembly_cost", &struc); + EXPECT_NEAR(struc, struc_cost[i], 1.0); //$ + + + } +} + + + + + diff --git a/test/ssc_test/cmod_mhk_costs_test.h b/test/ssc_test/cmod_mhk_costs_test.h new file mode 100644 index 000000000..775d10b83 --- /dev/null +++ b/test/ssc_test/cmod_mhk_costs_test.h @@ -0,0 +1,82 @@ +/* +BSD 3-Clause License + +Copyright Alliance for Sustainable Energy, LLC. See also https://github.com/NREL/ssc/blob/develop/LICENSE + + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#ifndef CMOD_MHK_COST_TEST_H_ +#define CMOD_MHK_COST_TEST_H_ + +#include +#include "../test/input_cases/mhk/mhk_cost_inputs.h" + +#include "core.h" +#include "sscapi.h" + +#include "vartab.h" +#include "../ssc/common.h" +#include "../test/input_cases/code_generator_utilities.h" + +class CM_MHKCost : public ::testing::Test { +private: +public: + ssc_data_t data; + ssc_number_t calculated_value; + ssc_number_t * calculated_array; + + void SetUp() { + data = ssc_data_create(); + mhk_cost_inputs(data); + } + + void TearDown() { +// if (data) +// ssc_data_clear(data); + ssc_data_free(data); + } + + void SetCalculated(std::string name) + { + ssc_data_get_number(data, const_cast(name.c_str()), &calculated_value); + } + // apparently memory of the array is managed internally to the sscapi. + void SetCalculatedArray(std::string name) + { + int n; + calculated_array = ssc_data_get_array(data, const_cast(name.c_str()), &n); + } + + + +}; + +#endif // !CMOD_MHK_COST_TEST_H_ +