NREL / ssc

SAM Simulation Core (SSC) contains the underlying performance and financial models for SAM
BSD 3-Clause "New" or "Revised" License
79 stars 85 forks source link

Sim fails when only POA data is supplied to `solar_resource_data` #318

Closed caseyzak24 closed 4 years ago

caseyzak24 commented 4 years ago

When providing weather data to an ssc container via the solar_resource_data variable, the simulation will fail if the only irradiance data provided is POA. This is particularly problematic because when trying to model real-system performance, POA may be the only irradiance component available.

Based on the fact that I can successfully use the SAM UI to model a system with POA data, I don't think solar_resource_file experiences the same issue.

To Reproduce Using PySSC we created a data container, wfd, with the following columns:

wfd = ssc.data_create()
ssc.data_set_number(wfd, b'lat', weather_header["Latitude"].iloc[0])
ssc.data_set_number(wfd, b'lon', weather_header["Longitude"].iloc[0])
ssc.data_set_number(wfd, b'tz', weather_header['Time Zone'].iloc[0])
ssc.data_set_number(wfd, b'elev', weather_header["Elevation"].iloc[0])
ssc.data_set_array(wfd, b'year', weather_data["Year"].tolist())
ssc.data_set_array(wfd, b'month', weather_data["Month"].tolist())
ssc.data_set_array(wfd, b'day', weather_data["Day"].tolist())
ssc.data_set_array(wfd, b'hour', weather_data["Hour"].tolist())
ssc.data_set_array(wfd, b'minute', weather_data["Minute"].tolist())
ssc.data_set_array(wfd, b'wspd', weather_data["Wind Speed"].tolist())
ssc.data_set_array(wfd, b'tdry', weather_data["Temperature"].tolist())
ssc.data_set_array(wfd, b'poa', weather_data["POA"].tolist())

We assigned this container to our simulation container along with additional pertinent parameters:

ssc.data_set_table(container, b'solar_resource_data', wfd)
ssc.data_set_number(container, b'irrad_mode', 4)
ssc.data_set_number(container, b'sky_model', 2)

The simulation fails with the following:

pvsamv1: tdry number of entries doesn't match with other fields
pvsamv1: exec fail(pvsamv1): 0 timesteps per hour found. Weather data should be single year.

I've tracked down the issue to a poorly designed conditional in weatherdata in common.cpp (~line 776):

        // make sure two types of irradiance are provided
    size_t nrec = 0;
    int n_irr = 0;
    if (var_data *value = data_table->table.lookup("df"))
    {
        if (value->type == SSC_ARRAY){
            nrec = value->num.length();
            n_irr++;
        }
    }
    if (var_data *value = data_table->table.lookup("dn"))
    {
        if (value->type == SSC_ARRAY){
            nrec = value->num.length();
            n_irr++;
        }
    }
    if (var_data *value = data_table->table.lookup("gh"))
    {
        if (value->type == SSC_ARRAY){
            nrec = value->num.length();
            n_irr++;
        }
    }
    if (nrec == 0 || n_irr < 1)
    {
        if (data_table->table.lookup("poa") == nullptr){
            m_message = "missing irradiance: could not find gh, dn, df, or poa";
            m_ok = false;
            return;
        }
    }

    // check that all vectors are of same length as irradiance vectors
    vec year = get_vector( data_table, "year");
    vec month = get_vector( data_table, "month");
    vec day = get_vector( data_table, "day");
    vec hour = get_vector( data_table, "hour");
    vec minute = get_vector( data_table, "minute");
    vec gh = get_vector( data_table, "gh", &nrec );
    vec dn = get_vector( data_table, "dn", &nrec );
    vec df = get_vector( data_table, "df", &nrec );
    vec poa = get_vector(data_table, "poa", &nrec);
    vec wspd = get_vector( data_table, "wspd", &nrec );
    vec wdir = get_vector( data_table, "wdir", &nrec );
    vec tdry = get_vector( data_table, "tdry", &nrec );
    vec twet = get_vector( data_table, "twet", &nrec ); 
    vec tdew = get_vector( data_table, "tdew", &nrec ); 
    vec rhum = get_vector( data_table, "rhum", &nrec ); 
    vec pres = get_vector( data_table, "pres", &nrec ); 
    vec snow = get_vector( data_table, "snow", &nrec ); 
    vec alb = get_vector( data_table, "alb", &nrec ); 
    vec aod = get_vector( data_table, "aod", &nrec );

If one of the typical irradiance components isn't present (GHI, DNI, DHI), the variable nrec remains zero and causes the error.

I'm happy to submit a PR for this but it will be a while before I get to it and I wanted to bring it up in case someone else can take it on

WORKAROUND PRIOR TO FIX If you need to use POA data, make sure that your weather container has a gh array (it can be an array of zeros) and the simulation will work as expected.

janinefreeman commented 4 years ago

@caseyzak24 thanks for bringing this up. I think I noticed this same issue in some other work I was doing on a branch called "seedldrd" and fixed this already- I can make sure to merge that in for our next release so this can be taken care of. If you get a chance to take a look at this file on that branch and confirm that it fixes the problem, that would be great, if not, no worries.

Thanks!

caseyzak24 commented 4 years ago

@janinefreeman thanks for the quick response. I took a look at that branch and unless I am mistaken nrec would still remain zero if only POA is provided, which is the cause of the error. In the conditional that handles the POA-only scenario there needs to be some sort of statement like the nrec = value->num.length(); that is in the other conditionals because nrec determines the number of rows/records that are pulled from the given data container