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
|