Skip to content

Commit efd6c0b

Browse files
authored
Merge pull request #1358 from NREL/me-ui-updates-fy25
Me UI updates fy25
2 parents 0276c6c + aa92d0b commit efd6c0b

File tree

7 files changed

+820
-155
lines changed

7 files changed

+820
-155
lines changed

ssc/cmod_mhk_costs.cpp

Lines changed: 340 additions & 110 deletions
Large diffs are not rendered by default.

ssc/cmod_mhk_wave.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -444,9 +444,13 @@ class cm_mhk_wave : public compute_module
444444
for (size_t j = 0; j < (size_t)wave_power_matrix.ncols(); j++) {
445445

446446
//Calculate and allocate annual_energy_distribution:
447-
if (j == 0 || i == 0) //Where (i = 0) is the row header, and (j = 0) is the column header.
448-
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
449-
else {
447+
if (j == 0 || i == 0) { //Where (i = 0) is the row header, and (j = 0) is the column header.
448+
if (wave_resource_matrix.at(i, j) != wave_power_matrix.at(i, j)) {
449+
throw exec_error("mhk_wave", "Resource matrix and Power matrix bins do not match.");
450+
}
451+
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
452+
}
453+
else {
450454
//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;
451455
//Mult. by number of devices and total loss multiplier to find energy for certain wave type in grid
452456
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;

ssc/cmod_tidalfile.cpp

Lines changed: 115 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -125,17 +125,22 @@ class cm_tidal_file_reader : public compute_module
125125
void exec()
126126
{
127127

128-
if (as_integer("tidal_resource_model_choice") == 0) return;
128+
if (as_integer("tidal_resource_model_choice") == 0) return; //Nothing to do
129129

130130
std::string file;
131131
if (is_assigned("tidal_resource_filename") && as_integer("tidal_resource_model_choice")==1)
132132
{
133133
file = as_string("tidal_resource_filename");
134134
}
135+
else if (is_assigned("tidal_resource_filename_dist") && as_integer("tidal_resource_model_choice") == 0)
136+
{
137+
file = as_string("tidal_resource_filename_dist");
138+
}
135139
else
136140
{
137141
throw exec_error("tidal_file_reader", "Model choice and tidal resource file do not match");
138142
}
143+
139144
if (file.empty())
140145
{
141146
throw exec_error("tidal_file_reader", "File name missing.");
@@ -168,41 +173,98 @@ class cm_tidal_file_reader : public compute_module
168173
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.");
169174
}
170175
if (as_integer("tidal_resource_model_choice") == 0) {
171-
assign("name", var_data(values[0]));
172-
assign("city", var_data(values[1]));
173-
assign("state", var_data(values[2]));
174-
assign("country", var_data(values[3]));
175-
// lat with S is negative
176-
ssc_number_t dlat = std::numeric_limits<double>::quiet_NaN();
177-
std::vector<std::string> slat = split(values[4], ' ');
178-
if (slat.size() > 0)
176+
//assign("name", var_data(values[0]));
177+
//assign("city", var_data(values[1]));
178+
//assign("state", var_data(values[2]));
179+
//assign("country", var_data(values[3]));
180+
//// lat with S is negative
181+
//ssc_number_t dlat = std::numeric_limits<double>::quiet_NaN();
182+
//std::vector<std::string> slat = split(values[4], ' ');
183+
//if (slat.size() > 0)
184+
//{
185+
// dlat = std::stod(slat[0]);
186+
// if (slat.size() > 1)
187+
// {
188+
// if (slat[1] == "S") dlat = 0.0 - dlat;
189+
// }
190+
//}
191+
//assign("lat", var_data(dlat));
192+
//// lon with W is negative
193+
//ssc_number_t dlon = std::numeric_limits<double>::quiet_NaN();
194+
//std::vector<std::string> slon = split(values[5], ' ');
195+
//if (slon.size() > 0)
196+
//{
197+
// dlon = std::stod(slon[0]);
198+
// if (slon.size() > 1)
199+
// {
200+
// if (slon[1] == "W") dlon = 0.0 - dlon;
201+
// }
202+
//}
203+
//assign("lon", var_data(dlon));
204+
//assign("nearby_buoy_number", var_data(values[6]));
205+
//assign("average_power_flux", var_data(std::stod(values[7])));
206+
//assign("bathymetry", var_data(values[8]));
207+
//assign("sea_bed", var_data(values[9]));
208+
//assign("tz", var_data(std::stod(values[10])));
209+
//assign("data_source", var_data(values[11]));
210+
//assign("notes", var_data(values[12]));
211+
212+
// allow metadata rows to have different lengths as long as required data is included
213+
ncols = std::min(ncols, ncols1);
214+
215+
std::string name, value;
216+
217+
for (size_t i = 0; (int)i < ncols; i++)
179218
{
180-
dlat = std::stod(slat[0]);
181-
if (slat.size() > 1)
219+
220+
name = "";
221+
if (!keys[i].empty())
222+
name = util::lower_case(trimboth(keys[i]));
223+
224+
value = "";
225+
if (!values[i].empty())
226+
value = trimboth(values[i]);
227+
228+
// required metadata (see checks below)
229+
if (name == "lat" || name == "latitude")
182230
{
183-
if (slat[1] == "S") dlat = 0.0 - dlat;
231+
assign("lat", var_data(std::stod(value)));
184232
}
185-
}
186-
assign("lat", var_data(dlat));
187-
// lon with W is negative
188-
ssc_number_t dlon = std::numeric_limits<double>::quiet_NaN();
189-
std::vector<std::string> slon = split(values[5], ' ');
190-
if (slon.size() > 0)
191-
{
192-
dlon = std::stod(slon[0]);
193-
if (slon.size() > 1)
233+
else if (name == "lon" || name == "long" || name == "longitude" || name == "lng")
234+
{
235+
assign("lon", var_data(std::stod(value)));
236+
}
237+
else if (name == "tz" || name == "timezone" || name == "time zone") // require "time zone" and "local time zone" columns in NSRDB files are the same
194238
{
195-
if (slon[1] == "W") dlon = 0.0 - dlon;
239+
assign("tz", var_data(std::stod(value)));
240+
}
241+
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
242+
{
243+
assign("distance_to_shore_file", var_data(std::stod(value)));
244+
}
245+
else if (name == "water depth" || name == "depth") // require "time zone" and "local time zone" columns in NSRDB files are the same
246+
{
247+
assign("water_depth_file", var_data(std::stod(value)));
248+
}
249+
else if (name == "id" || name == "jurisdiction" || name == "station id" || name == "wban" || name == "wban#" || name == "site")
250+
{
251+
assign("location", var_data(value));
252+
}
253+
else if (name == "location" || name == "location id")
254+
{
255+
assign("location_id", var_data(value));
256+
}
257+
258+
259+
else if (name == "source" || name == "src" || name == "data source")
260+
{
261+
assign("data_source", var_data(value));
262+
}
263+
else if (name == "notes" || name == "source notes")
264+
{
265+
assign("notes", var_data(value));
196266
}
197267
}
198-
assign("lon", var_data(dlon));
199-
assign("nearby_buoy_number", var_data(values[6]));
200-
assign("average_power_flux", var_data(std::stod(values[7])));
201-
assign("bathymetry", var_data(values[8]));
202-
assign("sea_bed", var_data(values[9]));
203-
assign("tz", var_data(std::stod(values[10])));
204-
assign("data_source", var_data(values[11]));
205-
assign("notes", var_data(values[12]));
206268
}
207269
else {
208270
/*
@@ -416,28 +478,39 @@ class cm_tidal_file_reader : public compute_module
416478
assign("number_hours", int(numberRecords * hourdiff));
417479
}
418480
else if (as_integer("tidal_resource_model_choice") == 0) {
419-
ssc_number_t* mat = allocate("wave_resource_matrix", 21, 22);
420-
for (size_t r = 0; r < 21; r++)
481+
getline(ifs, buf); //Skip past column labels for record counting
482+
size_t numberRecords = 0;
483+
while (getline(ifs, buf)) {
484+
numberRecords++;
485+
486+
}
487+
488+
ifs.clear();
489+
ifs.seekg(0);
490+
for (size_t i = 0; i < 3; i++)
491+
getline(ifs, buf);
492+
if (ifs.eof())
493+
{
494+
throw exec_error("tidal_file_reader", "Could not read column names");
495+
}
496+
ssc_number_t* mat = allocate("tidal_resource", numberRecords, 2);
497+
for (size_t r = 0; r < numberRecords; r++)
421498
{
422499
getline(ifs, buf);
423500
values.clear();
424501
values = split(buf);
425-
if (values.size() != 22)
426-
{
427-
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()));
428-
}
429-
for (size_t c = 0; c < 22; c++)
502+
if (values.size() != 2)
430503
{
431-
if (r == 0 && c == 0)
432-
mat[r * 22 + c] = 0.0;
433-
else
434-
mat[r * 22 + c] = std::stod(values[c]);
504+
throw exec_error("tidal_file_reader", "Tidal resource probability must contain 2 columns: tidal velocity and probability of occurence");
435505
}
506+
mat[r * 2] = std::stod(values[0]);
507+
mat[r * 2 + 1] = std::stod(values[1]);
508+
436509
}
437510

438511
}
439512
else {
440-
throw exec_error("tidal_file_reader", "Resource data type needs to be defined ");
513+
throw exec_error("tidal_file_reader", "Resource data type needs to be defined. ");
441514
}
442515

443516
return;

ssc/cmod_wavefile.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ class cm_wave_file_reader : public compute_module
206206
value = "";
207207
if (!values[i].empty())
208208
value = trimboth(values[i]);
209+
if (value == "") continue;
209210

210211
// required metadata (see checks below)
211212
if (name == "lat" || name == "latitude")
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/*
2+
BSD 3-Clause License
3+
4+
Copyright (c) Alliance for Sustainable Energy, LLC. See also https://github.com/NREL/ssc/blob/develop/LICENSE
5+
All rights reserved.
6+
7+
Redistribution and use in source and binary forms, with or without
8+
modification, are permitted provided that the following conditions are met:
9+
10+
1. Redistributions of source code must retain the above copyright notice, this
11+
list of conditions and the following disclaimer.
12+
13+
2. Redistributions in binary form must reproduce the above copyright notice,
14+
this list of conditions and the following disclaimer in the documentation
15+
and/or other materials provided with the distribution.
16+
17+
3. Neither the name of the copyright holder nor the names of its
18+
contributors may be used to endorse or promote products derived from
19+
this software without specific prior written permission.
20+
21+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31+
*/
32+
33+
#ifndef MHK_COST_INPUTS_H_
34+
#define MHK_COST_INPUTS_H_
35+
36+
#include <stdio.h>
37+
#include "../test/input_cases/code_generator_utilities.h"
38+
39+
void mhk_cost_inputs(ssc_data_t &data) {
40+
41+
ssc_data_set_number(data, "device_rated_power", 286);
42+
ssc_data_set_number(data, "system_capacity", 28600);
43+
ssc_data_set_number(data, "devices_per_row", 10);
44+
ssc_data_set_number(data, "marine_energy_tech", 0);
45+
ssc_data_set_number(data, "library_or_input_wec", 0);
46+
ssc_data_set_string(data, "lib_wave_device", "RM3");
47+
ssc_data_set_string(data, "lib_tidal_device", "RM1");
48+
ssc_data_set_number(data, "structural_assembly_cost_method", 2);
49+
ssc_data_set_number(data, "structural_assembly_cost_input", 100); //$ or $/kW
50+
ssc_data_set_number(data, "structural_assembly_cost_total", 1000000);
51+
ssc_data_set_number(data, "structural_assembly_cost_rvalue", 0.1);
52+
ssc_data_set_number(data, "power_takeoff_system_cost_method", 2);
53+
ssc_data_set_number(data, "power_takeoff_system_cost_input", 100); //$ or $/kW
54+
ssc_data_set_number(data, "power_takeoff_system_cost_total", 1000000);
55+
ssc_data_set_number(data, "power_takeoff_system_cost_rvalue", 0.1);
56+
ssc_data_set_number(data, "mooring_found_substruc_cost_method", 2);
57+
ssc_data_set_number(data, "mooring_found_substruc_cost_input", 100); //$ or $/kW
58+
ssc_data_set_number(data, "mooring_found_substruc_cost_total", 1000000);
59+
ssc_data_set_number(data, "mooring_found_substruc_cost_rvalue", 0.1);
60+
ssc_data_set_number(data, "development_cost_method", 2);
61+
ssc_data_set_number(data, "development_cost_input", 100); //$ or $/kW
62+
ssc_data_set_number(data, "development_cost_total", 1000000);
63+
ssc_data_set_number(data, "development_cost_rvalue", 0.1);
64+
ssc_data_set_number(data, "eng_and_mgmt_cost_method", 2);
65+
ssc_data_set_number(data, "eng_and_mgmt_cost_input", 100); //$ or $/kW
66+
ssc_data_set_number(data, "eng_and_mgmt_cost_total", 1000000);
67+
ssc_data_set_number(data, "eng_and_mgmt_cost_rvalue", 0.1);
68+
ssc_data_set_number(data, "assembly_and_install_cost_method", 2);
69+
ssc_data_set_number(data, "assembly_and_install_cost_input", 100); //$ or $/kW
70+
ssc_data_set_number(data, "assembly_and_install_cost_total", 1000000);
71+
ssc_data_set_number(data, "assembly_and_install_cost_rvalue", 0.1);
72+
ssc_data_set_number(data, "other_infrastructure_cost_method", 2);
73+
ssc_data_set_number(data, "other_infrastructure_cost_input", 100); //$ or $/kW
74+
ssc_data_set_number(data, "other_infrastructure_cost_total", 1000000);
75+
ssc_data_set_number(data, "other_infrastructure_cost_rvalue", 0.1);
76+
ssc_data_set_number(data, "elec_infras_cost_method", 2);
77+
ssc_data_set_number(data, "elec_infras_cost_modeled", 0);
78+
ssc_data_set_number(data, "elec_infras_cost_input", 100); //$ or $/kW
79+
ssc_data_set_number(data, "elec_infras_cost_total", 1000000);
80+
ssc_data_set_number(data, "elec_infras_cost_rvalue", 0.1);
81+
ssc_data_set_number(data, "plant_commissioning_cost_method", 2);
82+
ssc_data_set_number(data, "plant_commissioning_cost_input", 100); //$ or $/kW
83+
ssc_data_set_number(data, "plant_commissioning_cost_total", 1000000);
84+
ssc_data_set_number(data, "plant_commissioning_cost_rvalue", 0.1);
85+
ssc_data_set_number(data, "site_access_port_staging_cost_method", 2);
86+
ssc_data_set_number(data, "site_access_port_staging_cost_input", 100); //$ or $/kW
87+
ssc_data_set_number(data, "site_access_port_staging_cost_total", 1000000);
88+
ssc_data_set_number(data, "site_access_port_staging_cost_rvalue", 0.1);
89+
ssc_data_set_number(data, "project_contingency_cost_method", 2);
90+
ssc_data_set_number(data, "project_contingency_cost_input", 100); //$ or $/kW
91+
ssc_data_set_number(data, "project_contingency_cost_total", 1000000);
92+
ssc_data_set_number(data, "project_contingency_cost_rvalue", 0.1);
93+
ssc_data_set_number(data, "insurance_during_construction_cost_method", 2);
94+
ssc_data_set_number(data, "insurance_during_construction_cost_input", 100); //$ or $/kW
95+
ssc_data_set_number(data, "insurance_during_construction_cost_total", 1000000);
96+
ssc_data_set_number(data, "insurance_during_construction_cost_rvalue", 0.1);
97+
ssc_data_set_number(data, "reserve_accounts_cost_method", 2);
98+
ssc_data_set_number(data, "reserve_accounts_cost_input", 100); //$ or $/kW
99+
ssc_data_set_number(data, "reserve_accounts_cost_total", 1000000);
100+
ssc_data_set_number(data, "reserve_accounts_cost_rvalue", 0.1);
101+
ssc_data_set_number(data, "other_financial_cost_method", 2);
102+
ssc_data_set_number(data, "other_financial_cost_input", 100); //$ or $/kW
103+
ssc_data_set_number(data, "other_financial_cost_total", 1000000);
104+
ssc_data_set_number(data, "other_financial_cost_rvalue", 0.1);
105+
ssc_data_set_number(data, "operations_cost_method", 2);
106+
ssc_data_set_number(data, "operations_cost_input", 100); //$ or $/kW
107+
ssc_data_set_number(data, "operations_cost_total", 1000000);
108+
ssc_data_set_number(data, "operations_cost_rvalue", 0.1);
109+
ssc_data_set_number(data, "maintenance_cost_method", 2);
110+
ssc_data_set_number(data, "maintenance_cost_input", 100); //$ or $/kW
111+
ssc_data_set_number(data, "maintenance_cost_total", 1000000);
112+
ssc_data_set_number(data, "maintenance_cost_rvalue", 0.1);
113+
114+
115+
}
116+
117+
#endif

0 commit comments

Comments
 (0)