LCOV - code coverage report
Current view: top level - EnergyPlus - PVWatts.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 81.9 % 216 177
Test Date: 2025-05-22 16:09:37 Functions: 85.0 % 20 17

            Line data    Source code
       1              : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
       2              : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3              : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4              : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5              : // contributors. All rights reserved.
       6              : //
       7              : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8              : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9              : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10              : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11              : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12              : //
      13              : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14              : // provided that the following conditions are met:
      15              : //
      16              : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17              : //     conditions and the following disclaimer.
      18              : //
      19              : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20              : //     conditions and the following disclaimer in the documentation and/or other materials
      21              : //     provided with the distribution.
      22              : //
      23              : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24              : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25              : //     used to endorse or promote products derived from this software without specific prior
      26              : //     written permission.
      27              : //
      28              : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29              : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30              : //     reference solely to the software portion of its product, Licensee must refer to the
      31              : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32              : //     obtained under this License and may not use a different name for the software. Except as
      33              : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34              : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35              : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36              : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37              : //
      38              : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39              : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40              : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41              : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42              : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43              : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44              : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45              : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46              : // POSSIBILITY OF SUCH DAMAGE.
      47              : 
      48              : // C++ Headers
      49              : #include <math.h>
      50              : #include <stdexcept>
      51              : 
      52              : // ObjexxFCL Headers
      53              : 
      54              : // EnergyPlus Headers
      55              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      56              : #include <EnergyPlus/DataEnvironment.hh>
      57              : #include <EnergyPlus/DataHVACGlobals.hh>
      58              : #include <EnergyPlus/DataHeatBalance.hh>
      59              : #include <EnergyPlus/DataIPShortCuts.hh>
      60              : #include <EnergyPlus/ElectricPowerServiceManager.hh>
      61              : #include <EnergyPlus/General.hh>
      62              : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      63              : #include <EnergyPlus/OutputProcessor.hh>
      64              : #include <EnergyPlus/PVWatts.hh>
      65              : #include <EnergyPlus/UtilityRoutines.hh>
      66              : #include <EnergyPlus/WeatherManager.hh>
      67              : 
      68              : // SAM Headers
      69              : // #include <../third_party/ssc/shared/lib_irradproc.h>
      70              : // #include <../third_party/ssc/shared/lib_pvwatts.h>
      71              : // #include <../third_party/ssc/shared/lib_pvshade.h>
      72              : // #include <../third_party/ssc/shared/lib_pv_incidence_modifier.h>
      73              : #include <../third_party/ssc/ssc/sscapi.h>
      74              : 
      75              : namespace EnergyPlus {
      76              : 
      77              : namespace PVWatts {
      78              : 
      79           14 :     PVWattsGenerator::PVWattsGenerator(EnergyPlusData &state,
      80              :                                        const std::string &name,
      81              :                                        const Real64 dcSystemCapacity,
      82              :                                        ModuleType moduleType,
      83              :                                        ArrayType arrayType,
      84              :                                        Real64 systemLosses,
      85              :                                        GeometryType geometryType,
      86              :                                        Real64 tilt,
      87              :                                        Real64 azimuth,
      88              :                                        size_t surfaceNum,
      89           14 :                                        Real64 groundCoverageRatio)
      90           14 :         : moduleType_(moduleType), arrayType_(arrayType), geometryType_(geometryType), DCtoACRatio_(1.1), inverterEfficiency_(0.96),
      91           14 :           outputDCPower_(1000.0), outputDCEnergy_(0.0), outputACPower_(0.0), outputACEnergy_(0.0), cellTemperature_(-9999),
      92           14 :           planeOfArrayIrradiance_(-9999), shadedPercent_(0.0), pvwattsModule_(ssc_module_create("pvwattsv5_1ts")), pvwattsData_(ssc_data_create()),
      93           14 :           NumTimeStepsToday_(0.0)
      94              : 
      95              :     {
      96              : 
      97           14 :         assert(pvwattsModule_ != nullptr);
      98              : 
      99           14 :         bool errorsFound(false);
     100              : 
     101           14 :         if (name.empty()) {
     102            2 :             ShowSevereError(state, "PVWatts: name cannot be blank.");
     103            1 :             errorsFound = true;
     104              :         }
     105           14 :         name_ = name;
     106              : 
     107           14 :         if (dcSystemCapacity <= 0) {
     108            2 :             ShowSevereError(state, "PVWatts: DC system capacity must be greater than zero.");
     109            1 :             errorsFound = true;
     110              :         }
     111           14 :         dcSystemCapacity_ = dcSystemCapacity;
     112              : 
     113           14 :         if (systemLosses > 1.0 || systemLosses < 0.0) {
     114            1 :             ShowSevereError(state, format("PVWatts: Invalid system loss value {:.2R}", systemLosses));
     115            1 :             errorsFound = true;
     116              :         }
     117           14 :         systemLosses_ = systemLosses;
     118              : 
     119           14 :         if (geometryType_ == GeometryType::TILT_AZIMUTH) {
     120           14 :             if (tilt < 0 || tilt > 90) {
     121            1 :                 ShowSevereError(state, format("PVWatts: Invalid tilt: {:.2R}", tilt));
     122            1 :                 errorsFound = true;
     123              :             }
     124           14 :             tilt_ = tilt;
     125           14 :             if (azimuth < 0 || azimuth >= 360) {
     126            1 :                 ShowSevereError(state, format("PVWatts: Invalid azimuth: {:.2R}", azimuth));
     127              :             }
     128           14 :             azimuth_ = azimuth;
     129            0 :         } else if (geometryType_ == GeometryType::SURFACE) {
     130            0 :             if (surfaceNum == 0 || surfaceNum > state.dataSurface->Surface.size()) {
     131            0 :                 ShowSevereError(state, format("PVWatts: SurfaceNum not in Surfaces: {}", surfaceNum));
     132            0 :                 errorsFound = true;
     133              :             } else {
     134            0 :                 surfaceNum_ = surfaceNum;
     135            0 :                 tilt_ = getSurface(state).Tilt;
     136            0 :                 azimuth_ = getSurface(state).Azimuth;
     137              :                 // TODO: Do some bounds checking on Tilt and Azimuth.
     138              :             }
     139              :         } else {
     140            0 :             assert(false);
     141              :         }
     142              : 
     143           14 :         if (groundCoverageRatio > 1.0 || groundCoverageRatio < 0.0) {
     144            1 :             ShowSevereError(state, format("PVWatts: Invalid ground coverage ratio: {:.2R}", groundCoverageRatio));
     145            1 :             errorsFound = true;
     146              :         }
     147           14 :         groundCoverageRatio_ = groundCoverageRatio;
     148              : 
     149           14 :         if (errorsFound) {
     150            3 :             ShowFatalError(state, "Errors found in getting PVWatts input");
     151              :         }
     152              : 
     153              :         // Initialize m_pvwattsData
     154              :         // Location
     155           13 :         ssc_data_set_number(pvwattsData_, "lat", state.dataWeather->WeatherFileLatitude);
     156           13 :         ssc_data_set_number(pvwattsData_, "lon", state.dataWeather->WeatherFileLongitude);
     157           13 :         ssc_data_set_number(pvwattsData_, "tz", state.dataWeather->WeatherFileTimeZone);
     158              :         // System Properties
     159           13 :         ssc_data_set_number(pvwattsData_, "time_step", state.dataGlobal->TimeStepZone);
     160           13 :         ssc_data_set_number(pvwattsData_, "system_capacity", dcSystemCapacity_ * 0.001);
     161           13 :         ssc_data_set_number(pvwattsData_, "module_type", static_cast<int>(moduleType_));
     162           13 :         ssc_data_set_number(pvwattsData_, "dc_ac_ratio", DCtoACRatio_);
     163           13 :         ssc_data_set_number(pvwattsData_, "inv_eff", inverterEfficiency_ * 100.0);
     164           13 :         ssc_data_set_number(pvwattsData_, "losses", systemLosses_ * 100.0);
     165           13 :         ssc_data_set_number(pvwattsData_, "array_type", static_cast<int>(arrayType_));
     166           13 :         ssc_data_set_number(pvwattsData_, "tilt", tilt_);
     167           13 :         ssc_data_set_number(pvwattsData_, "azimuth", azimuth_);
     168           13 :         ssc_data_set_number(pvwattsData_, "gcr", groundCoverageRatio_);
     169              :         // Initialize shaded percent
     170           13 :         ssc_data_set_number(pvwattsData_, "shaded_percent", shadedPercent_);
     171           14 :     }
     172              : 
     173            4 :     void PVWattsGenerator::setupOutputVariables(EnergyPlusData &state)
     174              :     {
     175              :         // Set up output variables
     176            8 :         SetupOutputVariable(state,
     177              :                             "Generator Produced DC Electricity Rate",
     178              :                             Constant::Units::W,
     179            4 :                             outputDCPower_,
     180              :                             OutputProcessor::TimeStepType::System,
     181              :                             OutputProcessor::StoreType::Average,
     182            4 :                             name_);
     183            8 :         SetupOutputVariable(state,
     184              :                             "Generator Produced DC Electricity Energy",
     185              :                             Constant::Units::J,
     186            4 :                             outputDCEnergy_,
     187              :                             OutputProcessor::TimeStepType::System,
     188              :                             OutputProcessor::StoreType::Sum,
     189            4 :                             name_,
     190              :                             Constant::eResource::ElectricityProduced,
     191              :                             OutputProcessor::Group::Plant,
     192              :                             OutputProcessor::EndUseCat::Photovoltaic);
     193            8 :         SetupOutputVariable(state,
     194              :                             "Generator PV Cell Temperature",
     195              :                             Constant::Units::C,
     196            4 :                             cellTemperature_,
     197              :                             OutputProcessor::TimeStepType::System,
     198              :                             OutputProcessor::StoreType::Average,
     199            4 :                             name_);
     200            8 :         SetupOutputVariable(state,
     201              :                             "Plane of Array Irradiance",
     202              :                             Constant::Units::W_m2,
     203            4 :                             planeOfArrayIrradiance_,
     204              :                             OutputProcessor::TimeStepType::System,
     205              :                             OutputProcessor::StoreType::Average,
     206            4 :                             name_);
     207            8 :         SetupOutputVariable(state,
     208              :                             "Shaded Percent",
     209              :                             Constant::Units::Perc,
     210            4 :                             shadedPercent_,
     211              :                             OutputProcessor::TimeStepType::System,
     212              :                             OutputProcessor::StoreType::Average,
     213            4 :                             name_);
     214            4 :     }
     215              : 
     216            8 :     std::unique_ptr<PVWattsGenerator> PVWattsGenerator::createFromIdfObj(EnergyPlusData &state, int objNum)
     217              :     {
     218            8 :         Array1D_string cAlphaFieldNames;
     219            8 :         Array1D_string cNumericFieldNames;
     220            8 :         Array1D_bool lNumericFieldBlanks;
     221            8 :         Array1D_bool lAlphaFieldBlanks;
     222            8 :         Array1D_string cAlphaArgs;
     223            8 :         Array1D<Real64> rNumericArgs;
     224            8 :         constexpr int maxAlphas = 6;  // from idd
     225            8 :         constexpr int maxNumeric = 5; // from idd
     226            8 :         cAlphaFieldNames.allocate(maxAlphas);
     227            8 :         cNumericFieldNames.allocate(maxNumeric);
     228            8 :         lNumericFieldBlanks.allocate(maxNumeric);
     229            8 :         lAlphaFieldBlanks.allocate(maxAlphas);
     230            8 :         cAlphaArgs.allocate(maxAlphas);
     231            8 :         rNumericArgs.allocate(maxNumeric);
     232              :         int NumAlphas;
     233              :         int NumNums;
     234              :         int IOStat;
     235            8 :         bool errorsFound = false;
     236              : 
     237            8 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     238              :                                                                  "Generator:PVWatts",
     239              :                                                                  objNum,
     240              :                                                                  cAlphaArgs,
     241              :                                                                  NumAlphas,
     242              :                                                                  rNumericArgs,
     243              :                                                                  NumNums,
     244              :                                                                  IOStat,
     245              :                                                                  lNumericFieldBlanks,
     246              :                                                                  lAlphaFieldBlanks,
     247              :                                                                  cAlphaFieldNames,
     248              :                                                                  cNumericFieldNames);
     249              : 
     250            8 :         const std::string name(cAlphaArgs(AlphaFields::NAME));
     251            8 :         const Real64 dcSystemCapacity(rNumericArgs(NumFields::DC_SYSTEM_CAPACITY));
     252              :         const std::map<std::string, ModuleType> moduleTypeMap = {
     253           40 :             {"STANDARD", ModuleType::STANDARD}, {"PREMIUM", ModuleType::PREMIUM}, {"THINFILM", ModuleType::THIN_FILM}};
     254              :         ModuleType moduleType;
     255            8 :         auto moduleTypeIt = moduleTypeMap.find(cAlphaArgs(AlphaFields::MODULE_TYPE));
     256            8 :         if (moduleTypeIt == moduleTypeMap.end()) {
     257            1 :             ShowSevereError(state, format("PVWatts: Invalid Module Type: {}", cAlphaArgs(AlphaFields::MODULE_TYPE)));
     258            1 :             errorsFound = true;
     259              :         } else {
     260            7 :             moduleType = moduleTypeIt->second;
     261              :         }
     262              : 
     263            0 :         const std::map<std::string, ArrayType> arrayTypeMap = {{"FIXEDOPENRACK", ArrayType::FIXED_OPEN_RACK},
     264            0 :                                                                {"FIXEDROOFMOUNTED", ArrayType::FIXED_ROOF_MOUNTED},
     265            0 :                                                                {"ONEAXIS", ArrayType::ONE_AXIS},
     266            0 :                                                                {"ONEAXISBACKTRACKING", ArrayType::ONE_AXIS_BACKTRACKING},
     267           56 :                                                                {"TWOAXIS", ArrayType::TWO_AXIS}};
     268              :         ArrayType arrayType;
     269            8 :         auto arrayTypeIt = arrayTypeMap.find(cAlphaArgs(AlphaFields::ARRAY_TYPE));
     270            8 :         if (arrayTypeIt == arrayTypeMap.end()) {
     271            1 :             ShowSevereError(state, format("PVWatts: Invalid Array Type: {}", cAlphaArgs(AlphaFields::ARRAY_TYPE)));
     272            1 :             errorsFound = true;
     273              :         } else {
     274            7 :             arrayType = arrayTypeIt->second;
     275              :         }
     276              : 
     277            8 :         const Real64 systemLosses(rNumericArgs(NumFields::SYSTEM_LOSSES));
     278           32 :         const std::map<std::string, GeometryType> geometryTypeMap{{"TILTAZIMUTH", GeometryType::TILT_AZIMUTH}, {"SURFACE", GeometryType::SURFACE}};
     279              :         GeometryType geometryType;
     280            8 :         auto geometryTypeIt = geometryTypeMap.find(cAlphaArgs(AlphaFields::GEOMETRY_TYPE));
     281            8 :         if (geometryTypeIt == geometryTypeMap.end()) {
     282            1 :             ShowSevereError(state, format("PVWatts: Invalid Geometry Type: {}", cAlphaArgs(AlphaFields::GEOMETRY_TYPE)));
     283            1 :             errorsFound = true;
     284              :         } else {
     285            7 :             geometryType = geometryTypeIt->second;
     286              :         }
     287              : 
     288            8 :         const Real64 tilt(rNumericArgs(NumFields::TILT_ANGLE));
     289            8 :         const Real64 azimuth(rNumericArgs(NumFields::AZIMUTH_ANGLE));
     290              :         int surfaceNum;
     291            8 :         if (lAlphaFieldBlanks(AlphaFields::SURFACE_NAME)) {
     292            8 :             surfaceNum = 0;
     293              :         } else {
     294            0 :             surfaceNum = Util::FindItemInList(cAlphaArgs(AlphaFields::SURFACE_NAME), state.dataSurface->Surface);
     295              :         }
     296              : 
     297            8 :         if (errorsFound) {
     298            3 :             ShowFatalError(state, "Errors found in getting PVWatts input");
     299              :         }
     300              : 
     301            7 :         if (NumNums < NumFields::GROUND_COVERAGE_RATIO) {
     302              :             return std::make_unique<PVWattsGenerator>(
     303            8 :                 state, name, dcSystemCapacity, moduleType, arrayType, systemLosses, geometryType, tilt, azimuth, surfaceNum, 0.4);
     304              :         }
     305            3 :         const Real64 groundCoverageRatio(rNumericArgs(NumFields::GROUND_COVERAGE_RATIO));
     306              : 
     307              :         return std::make_unique<PVWattsGenerator>(
     308            3 :             state, name, dcSystemCapacity, moduleType, arrayType, systemLosses, geometryType, tilt, azimuth, surfaceNum, groundCoverageRatio);
     309           41 :     }
     310              : 
     311            5 :     Real64 PVWattsGenerator::getDCSystemCapacity()
     312              :     {
     313            5 :         return dcSystemCapacity_;
     314              :     }
     315              : 
     316            2 :     ModuleType PVWattsGenerator::getModuleType()
     317              :     {
     318            2 :         return moduleType_;
     319              :     }
     320              : 
     321            2 :     ArrayType PVWattsGenerator::getArrayType()
     322              :     {
     323            2 :         return arrayType_;
     324              :     }
     325              : 
     326            1 :     Real64 PVWattsGenerator::getSystemLosses()
     327              :     {
     328            1 :         return systemLosses_;
     329              :     }
     330              : 
     331            1 :     GeometryType PVWattsGenerator::getGeometryType()
     332              :     {
     333            1 :         return geometryType_;
     334              :     }
     335              : 
     336            2 :     Real64 PVWattsGenerator::getTilt()
     337              :     {
     338            2 :         return tilt_;
     339              :     }
     340              : 
     341            2 :     Real64 PVWattsGenerator::getAzimuth()
     342              :     {
     343            2 :         return azimuth_;
     344              :     }
     345              : 
     346            0 :     DataSurfaces::SurfaceData &PVWattsGenerator::getSurface(EnergyPlusData &state)
     347              :     {
     348            0 :         return state.dataSurface->Surface(surfaceNum_);
     349              :     }
     350              : 
     351            4 :     Real64 PVWattsGenerator::getGroundCoverageRatio()
     352              :     {
     353            4 :         return groundCoverageRatio_;
     354              :     }
     355              : 
     356            0 :     Real64 PVWattsGenerator::getCellTemperature()
     357              :     {
     358            0 :         return cellTemperature_;
     359              :     }
     360              : 
     361            5 :     void PVWattsGenerator::setCellTemperature(Real64 cellTemp)
     362              :     {
     363            5 :         cellTemperature_ = cellTemp;
     364            5 :     }
     365              : 
     366            0 :     Real64 PVWattsGenerator::getPlaneOfArrayIrradiance()
     367              :     {
     368            0 :         return planeOfArrayIrradiance_;
     369              :     }
     370              : 
     371            5 :     void PVWattsGenerator::setPlaneOfArrayIrradiance(Real64 poa)
     372              :     {
     373            5 :         planeOfArrayIrradiance_ = poa;
     374            5 :     }
     375              : 
     376            4 :     void PVWattsGenerator::setDCtoACRatio(Real64 const dc2ac)
     377              :     {
     378            4 :         DCtoACRatio_ = dc2ac;
     379            4 :     }
     380              : 
     381            4 :     void PVWattsGenerator::setInverterEfficiency(Real64 const inverterEfficiency)
     382              :     {
     383            4 :         inverterEfficiency_ = inverterEfficiency;
     384            4 :     }
     385              : 
     386            5 :     void PVWattsGenerator::calc(EnergyPlusData &state)
     387              :     {
     388            5 :         Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
     389              : 
     390              :         // We only run this once for each zone time step.
     391            5 :         const int NumTimeStepsToday_loc = state.dataGlobal->HourOfDay * state.dataGlobal->TimeStepsInHour + state.dataGlobal->TimeStep;
     392            5 :         if (NumTimeStepsToday_ != NumTimeStepsToday_loc) {
     393            5 :             NumTimeStepsToday_ = NumTimeStepsToday_loc;
     394              :         } else {
     395            0 :             outputDCEnergy_ = outputDCPower_ * TimeStepSysSec;
     396            0 :             outputACEnergy_ = outputACPower_ * TimeStepSysSec;
     397            0 :             return;
     398              :         }
     399              :         // SSC Inputs
     400              :         // Time
     401            5 :         ssc_data_set_number(pvwattsData_, "year", state.dataEnvrn->Year);
     402            5 :         ssc_data_set_number(pvwattsData_, "month", state.dataEnvrn->Month);
     403            5 :         ssc_data_set_number(pvwattsData_, "day", state.dataEnvrn->DayOfMonth);
     404            5 :         ssc_data_set_number(pvwattsData_, "hour", state.dataGlobal->HourOfDay - 1);
     405            5 :         ssc_data_set_number(pvwattsData_, "minute", (state.dataGlobal->TimeStep - 0.5) * state.dataGlobal->MinutesInTimeStep);
     406              : 
     407              :         // Weather Conditions
     408            5 :         ssc_data_set_number(pvwattsData_, "beam", state.dataEnvrn->BeamSolarRad);
     409            5 :         ssc_data_set_number(pvwattsData_, "diffuse", state.dataEnvrn->DifSolarRad);
     410            5 :         ssc_data_set_number(pvwattsData_, "tamb", state.dataEnvrn->OutDryBulbTemp);
     411            5 :         ssc_data_set_number(pvwattsData_, "wspd", state.dataEnvrn->WindSpeed);
     412            5 :         Real64 albedo = state.dataWeather->wvarsHrTsToday(state.dataGlobal->TimeStep, state.dataGlobal->HourOfDay).Albedo;
     413            5 :         if (!(std::isfinite(albedo) && albedo > 0.0 && albedo < 1)) {
     414            5 :             albedo = 0.2;
     415              :         }
     416            5 :         ssc_data_set_number(pvwattsData_, "alb", albedo);
     417              : 
     418              :         // In/Out Properties
     419            5 :         ssc_data_set_number(pvwattsData_, "tcell", cellTemperature_);
     420            5 :         ssc_data_set_number(pvwattsData_, "poa", planeOfArrayIrradiance_);
     421              : 
     422              :         // Get the shading from the geometry, if applicable
     423            5 :         if (geometryType_ == GeometryType::SURFACE) {
     424            0 :             shadedPercent_ = (1.0 - state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, surfaceNum_)) * 100.0;
     425            0 :             ssc_data_set_number(pvwattsData_, "shaded_percent", shadedPercent_);
     426              :         }
     427              : 
     428            5 :         if (ssc_module_exec(pvwattsModule_, pvwattsData_) == 0) {
     429              :             // Error
     430              :             const char *errtext;
     431              :             int sscErrType;
     432              :             float time;
     433            0 :             int i = 0;
     434            0 :             while ((errtext = ssc_module_log(pvwattsModule_, i++, &sscErrType, &time))) {
     435            0 :                 std::string err("PVWatts: ");
     436            0 :                 switch (sscErrType) {
     437            0 :                 case SSC_WARNING:
     438            0 :                     err.append(errtext);
     439            0 :                     ShowWarningMessage(state, err);
     440            0 :                     break;
     441            0 :                 case SSC_ERROR:
     442            0 :                     err.append(errtext);
     443            0 :                     ShowErrorMessage(state, err);
     444            0 :                     break;
     445            0 :                 default:
     446            0 :                     break;
     447              :                 }
     448            0 :             }
     449              :         } else {
     450              :             // Report Out
     451            5 :             ssc_data_get_number(pvwattsData_, "dc", &outputDCPower_);
     452            5 :             outputDCEnergy_ = outputDCPower_ * TimeStepSysSec;
     453            5 :             ssc_data_get_number(pvwattsData_, "ac", &outputACPower_);
     454            5 :             outputACEnergy_ = outputACPower_ * TimeStepSysSec;
     455            5 :             ssc_data_get_number(pvwattsData_, "tcell", &cellTemperature_);
     456            5 :             ssc_data_get_number(pvwattsData_, "poa", &planeOfArrayIrradiance_);
     457              :         }
     458              :     }
     459              : 
     460            5 :     void PVWattsGenerator::getResults(Real64 &GeneratorPower, Real64 &GeneratorEnergy, Real64 &ThermalPower, Real64 &ThermalEnergy)
     461              :     {
     462            5 :         GeneratorPower = outputDCPower_;
     463            5 :         GeneratorEnergy = outputDCEnergy_;
     464            5 :         ThermalPower = 0.0;
     465            5 :         ThermalEnergy = 0.0;
     466            5 :     }
     467              : 
     468              : } // namespace PVWatts
     469              : 
     470              : } // namespace EnergyPlus
        

Generated by: LCOV version 2.0-1