diff --git a/src/EnergyPlus/DataGenerators.cc b/src/EnergyPlus/DataGenerators.cc index ab64e13bc0d..56c5bbca687 100644 --- a/src/EnergyPlus/DataGenerators.cc +++ b/src/EnergyPlus/DataGenerators.cc @@ -64,6 +64,15 @@ namespace DataGenerators { // to the Fuel cell and Micro CHP modeling in EnergyPlus // the data for the older BLAST generators are in those component's modules + // METHODOLOGY EMPLOYED: + + // REFERENCES: + // na + + // OTHER NOTES: + // na + + // Using/Aliasing using namespace DataPrecisionGlobals; // Data @@ -135,17 +144,11 @@ namespace DataGenerators { Real64 const ImBalanceTol(0.00001); // used as fraction of electrical power at power module - // DERIVED TYPE DEFINITIONS - - // MODULE VARIABLE DECLARATIONS: - int NumFuelConstit(0); int NumGeneratorFuelSups(0); - int NumFuelCellGenerators(0); // number of SOFC Generators specified in input int NumGensWDynamics(0); // number of dynamics controls for generators // Object Data - Array1D FuelCell; // dimension to number of machines Array1D GasPhaseThermoChemistryData; Array1D FuelSupply; // fuel supply (reused across various) Array1D GeneratorDynamics; @@ -154,11 +157,10 @@ namespace DataGenerators { { NumFuelConstit = 0; NumGeneratorFuelSups = 0; - NumFuelCellGenerators = 0; NumGensWDynamics = 0; - FuelCell.deallocate(); GasPhaseThermoChemistryData.deallocate(); FuelSupply.deallocate(); + GeneratorDynamics.deallocate(); } } // namespace DataGenerators diff --git a/src/EnergyPlus/DataGenerators.hh b/src/EnergyPlus/DataGenerators.hh index e4c849ba941..7b757af1925 100644 --- a/src/EnergyPlus/DataGenerators.hh +++ b/src/EnergyPlus/DataGenerators.hh @@ -132,501 +132,8 @@ namespace DataGenerators { extern int NumFuelConstit; extern int NumGeneratorFuelSups; - extern int NumFuelCellGenerators; // number of SOFC Generators specified in input extern int NumGensWDynamics; // number of dynamics controls for generators - struct FCPowerModuleStruct - { - // Members - // user input data - std::string Name; // name of this PowerModule data - int EffMode; // mode for efficiency curves - int EffCurveID; // pointer to curve for efficiency - Real64 NomEff; // nominal efficiency - Real64 NomPel; // nominal power rate at rating point - int NumCycles; // number of start stop cycles - Real64 CyclingDegradRat; // rate of degradation from cycles - Real64 NumRunHours; // number of hours of operation - Real64 OperateDegradRat; // rate of degradation from run time (per hour) - Real64 ThreshRunHours; // number of hours before degradation starts - Real64 UpTranLimit; // power up transient limit - Real64 DownTranLimit; // power down tran limit - Real64 StartUpTime; // time for start up [hours] - Real64 StartUpFuel; // fuel use during start up - Real64 StartUpElectConsum; // electricity used during start up - Real64 StartUpElectProd; // electricity produced during start up - Real64 ShutDownTime; // time to shut down [hours] - Real64 ShutDownFuel; // fuel consumed during shut down - Real64 ShutDownElectConsum; // Elect consumed during shut down - Real64 ANC0; // Ancilliary Loads constant term - Real64 ANC1; // Ancilliary Loads linear term - int SkinLossMode; // how are skin losses determined - std::string ZoneName; - int ZoneID; // "pointer" to zone with component in it - Real64 RadiativeFract; - Real64 QdotSkin; - Real64 UAskin; - int SkinLossCurveID; - int WaterSupplyCurveID; // pointer to curve for water use in reforming - Real64 NdotDilutionAir; // user defined constant flow of dilution air (kmol/sec) - Real64 StackHeatLossToDilution; // (watts) - std::string DilutionInletNodeName; // dilution -> AirHR ?? added air heat recovery path - int DilutionInletNode; // pointer to node for inlet - std::string DilutionExhaustNodeName; - int DilutionExhaustNode; // pointer to node getting exhaust - Real64 PelMin; // minimum operating point for FCPM electrical power Pel - Real64 PelMax; // maximum operating point for FCPM electrical power Pel - // Calculated values and input from elsewhere - Real64 Pel; // current DC electrical power produced - Real64 PelLastTimeStep; - Real64 Eel; // power module efficiency - Real64 QdotStackCool; // Heat removed by stack cooler - Real64 FractionalDayofLastStartUp; // fractional days into simulation - Real64 FractionalDayofLastShutDown; // fractional Days into simulations - bool HasBeenOn; - bool DuringShutDown; - bool DuringStartUp; - Real64 NdotFuel; // molar fuel use rate. (kmol/sec) - Real64 TotFuelInEnthalphy; // Enthalpy of fuel coming into FCPM (watts) - Real64 NdotProdGas; // (kmol/sec) - Array1D ConstitMolalFract; - Array1D_int GasLibID; // lookup ID in Gas Phase ThermoChemistry Structure Array - Real64 TprodGasLeavingFCPM; - Real64 NdotAir; // molar air use rate (kmol/sec) - Real64 TotAirInEnthalphy; // Enthalpy of air coming nto FCPM energy balance (watts) - Real64 NdotLiqwater; // molar water use rate (kmol/sec) - Real64 TwaterInlet; - Real64 WaterInEnthalpy; // Enthalpy of liquid water used for reforming (watts) - Real64 DilutionAirInEnthalpy; // Enthalpy of Dilution air coming into FCPM (watts) - Real64 DilutionAirOutEnthalpy; - Real64 PelancillariesAC; // ancillary power (watts) - Real64 TotProdGasEnthalphy; // Enthalphy of product gases leaving FCPM (watts) - Real64 WaterOutEnthalpy; // enthalpy of vapor from water used for reforming - int SeqSubstitIter; - int RegulaFalsiIter; - - // Default Constructor - FCPowerModuleStruct() - : EffMode(0), EffCurveID(0), NomEff(0.0), NomPel(0.0), NumCycles(0), CyclingDegradRat(0.0), NumRunHours(0.0), OperateDegradRat(0.0), - ThreshRunHours(0.0), UpTranLimit(0.0), DownTranLimit(0.0), StartUpTime(0.0), StartUpFuel(0.0), StartUpElectConsum(0.0), - StartUpElectProd(0.0), ShutDownTime(0.0), ShutDownFuel(0.0), ShutDownElectConsum(0.0), ANC0(0.0), ANC1(0.0), SkinLossMode(0), ZoneID(0), - RadiativeFract(0.0), QdotSkin(0.0), UAskin(0.0), SkinLossCurveID(0), WaterSupplyCurveID(0), NdotDilutionAir(0.0), - StackHeatLossToDilution(0.0), DilutionInletNode(0), DilutionExhaustNode(0), PelMin(0.0), PelMax(0.0), Pel(0.0), PelLastTimeStep(0.0), - Eel(0.0), QdotStackCool(0.0), FractionalDayofLastStartUp(0.0), FractionalDayofLastShutDown(0.0), HasBeenOn(true), DuringShutDown(false), - DuringStartUp(false), NdotFuel(0.0), TotFuelInEnthalphy(0.0), NdotProdGas(0.0), ConstitMolalFract(14, 0.0), GasLibID(14, 0), - TprodGasLeavingFCPM(0.0), NdotAir(0.0), TotAirInEnthalphy(0.0), NdotLiqwater(0.0), TwaterInlet(0.0), WaterInEnthalpy(0.0), - DilutionAirInEnthalpy(0.0), DilutionAirOutEnthalpy(0.0), PelancillariesAC(0.0), TotProdGasEnthalphy(0.0), WaterOutEnthalpy(0.0), - SeqSubstitIter(0), RegulaFalsiIter(0) - { - } - }; - - struct FCAirSupplyDataStruct - { - // Members - // user input data - std::string Name; // name of this - std::string NodeName; // Air supply node name - int SupNodeNum; // Air supply node ID - int BlowerPowerCurveID; // "pointer" to blower power quadratic - Real64 BlowerHeatLossFactor; // alpha for blower heat loss fraction - int AirSupRateMode; // control for modeling method used to deterime supply air flow rate - Real64 Stoics; // excess air ratio - int AirFuncPelCurveID; // "pointer" to curve for air as function of power - Real64 AirTempCoeff; // coeff a3 in equ 16. - int AirFuncNdotCurveID; // "pointer" to curve for air as function of fuel flow rate - int IntakeRecoveryMode; - int ConstituentMode; // how are air data input - int NumConstituents; - Array1D_string ConstitName; - Array1D ConstitMolalFract; - // Calculated values and input from elsewhere - Array1D_int GasLibID; // lookup ID in Gas Phase ThermoChemistry Structure Array - Real64 O2fraction; - Real64 TairIntoBlower; // temperature entering blower - Real64 TairIntoFCPM; // temperature leaving blower and entering FCPM - Real64 PairCompEl; // power drawn by compressor - Real64 QskinLoss; // pumping losses for zone - Real64 QintakeRecovery; // heat recovered on intake air by accessories - - // Default Constructor - FCAirSupplyDataStruct() - : SupNodeNum(0), BlowerPowerCurveID(0), BlowerHeatLossFactor(0.0), AirSupRateMode(0), Stoics(0.0), AirFuncPelCurveID(0), - AirTempCoeff(0.0), AirFuncNdotCurveID(0), IntakeRecoveryMode(0), ConstituentMode(0), NumConstituents(0), ConstitName(14), - ConstitMolalFract(14, 0.0), GasLibID(14, 0), O2fraction(0.0), TairIntoBlower(0.0), TairIntoFCPM(0.0), PairCompEl(0.0), QskinLoss(0.0), - QintakeRecovery(0.0) - { - } - }; - - struct FCStackCoolerDataStruct - { - // Members - // user input data - std::string Name; // name of this stack cooler module - std::string WaterInNodeName; // HR Water Inlet Node - int WaterInNode; // HR Water Outlet Node ID - std::string WaterOutNodeName; // HR water outlet Node name - int WaterOutNode; // HR Water outlet Node ID - Real64 TstackNom; // nominal fuel cell stack temperature - Real64 TstackActual; // actual fuel cell stack temperature - Real64 r0; // stack cooling power coefficient r0 - Real64 r1; // stack cooling power coefficient r1 - Real64 r2; // stack cooling power coefficient r2 - Real64 r3; // stack cooling power coefficient r3 - Real64 MdotStackCoolant; // stack coolant flow rate kg/s - Real64 UAs_cool; // stack heat transfer coef - Real64 Fs_cogen; - Real64 As_cogen; - Real64 MdotCogenNom; - Real64 hCogenNom; - Real64 ns; - Real64 PstackPumpEl; - Real64 PmpPowerLossFactor; - Real64 f0; - Real64 f1; - Real64 f2; - // calculated and from elsewhere - bool StackCoolerPresent; // control modeling - Real64 qs_cool; - Real64 qs_air; - - // Default Constructor - FCStackCoolerDataStruct() - : WaterInNode(0), WaterOutNode(0), TstackNom(0.0), TstackActual(0.0), r0(0.0), r1(0.0), r2(0.0), r3(0.0), MdotStackCoolant(0.0), - UAs_cool(0.0), Fs_cogen(0.0), As_cogen(0.0), MdotCogenNom(0.0), hCogenNom(0.0), ns(0.0), PstackPumpEl(0.0), PmpPowerLossFactor(0.0), - f0(0.0), f1(0.0), f2(0.0), StackCoolerPresent(false), qs_cool(0.0), qs_air(0.0) - { - } - }; - - struct FCWaterSupplyDataStruct - { - // Members - std::string Name; // name of this water supply module - int WaterTempMode; // temperature of water inlet determination - std::string NodeName; // node name for temperature at input - int NodeNum; // node number for temperature at input - int SchedNum; // water temperature at input - int WaterSupRateCurveID; // "pointer" to water flow rate curve as a function of fuel rate - int PmpPowerCurveID; // "pointer to Pump power curve as a function of water flow Rate - Real64 PmpPowerLossFactor; // Pump heat loss factor - // calculated data - bool IsModeled; - Real64 TwaterIntoCompress; // inlet Water Temperature - Real64 TwaterIntoFCPM; // pumped water temp - Real64 PwaterCompEl; // water pump power - Real64 QskinLoss; // pumping losses for zone - - // Default Constructor - FCWaterSupplyDataStruct() - : WaterTempMode(0), NodeNum(0), SchedNum(0), WaterSupRateCurveID(0), PmpPowerCurveID(0), PmpPowerLossFactor(0.0), IsModeled(true), - TwaterIntoCompress(0.0), TwaterIntoFCPM(0.0), PwaterCompEl(0.0), QskinLoss(0.0) - { - } - }; - - struct FCAuxilHeatDataStruct - { - // Members - std::string Name; // name of this auxiliary heating module - std::string ZoneName; - int ZoneID; - Real64 UASkin; // for skin losses to zone - Real64 ExcessAirRAT; - Real64 ANC0; - Real64 ANC1; - int SkinLossDestination; // control mode for where lost heat goes - Real64 MaxPowerW; - Real64 MinPowerW; - Real64 MaxPowerkmolperSec; - Real64 MinPowerkmolperSec; - // calculated and from elsewhere - int NumConstituents; - Real64 TauxMix; - Real64 NdotAuxMix; - Array1D ConstitMolalFract; - Array1D_int GasLibID; // lookup ID in Gas Phase ThermoChemistry Structure Array - Real64 QskinLoss; // Heat lost to room - Real64 QairIntake; // heat into intake air - - // Default Constructor - FCAuxilHeatDataStruct() - : ZoneID(0), UASkin(0.0), ExcessAirRAT(0.0), ANC0(0.0), ANC1(0.0), SkinLossDestination(0), MaxPowerW(0.0), MinPowerW(0.0), - MaxPowerkmolperSec(0.0), MinPowerkmolperSec(0.0), NumConstituents(0), TauxMix(0.0), NdotAuxMix(0.0), ConstitMolalFract(14, 0.0), - GasLibID(14, 0), QskinLoss(0.0), QairIntake(0.0) - { - } - }; - - struct FCExhaustHXDataStruct - { - // Members - // user defined variables - std::string Name; // name of this exhaust gas heat recovery - std::string WaterInNodeName; // HR Water Inlet Node - int WaterInNode; // HR Water Outlet Node ID - std::string WaterOutNodeName; // HR water outlet Node name - int WaterOutNode; // HR Water outlet Node ID - Real64 WaterVolumeFlowMax; // HR water flow rate max avail - std::string ExhaustOutNodeName; // air node for exhaust flow - int ExhaustOutNode; // Exhaust Air node ID - int HXmodelMode; // Heat Exchanger Calculation Method - Real64 HXEffect; // Heat Exchanger Effectiveness (method 1) - Real64 hxs0; // (method 2) - Real64 hxs1; // (method 2) - Real64 hxs2; // (method 2) - Real64 hxs3; // (method 2) - Real64 hxs4; // (method 2) - Real64 h0gas; // (method 3) - Real64 NdotGasRef; // (method 3) - Real64 nCoeff; // (method 3) - Real64 AreaGas; // (method 3) - Real64 h0Water; // (method 3) - Real64 NdotWaterRef; // (method 3) - Real64 mCoeff; // (method 3) - Real64 AreaWater; // (method 3) - Real64 Fadjust; // (method 3) - Real64 l1Coeff; // (method 4) - Real64 l2Coeff; // (method 4) - Real64 CondensationThresholdTemp; // (method 4) [degrees C] - // calculated - Real64 qHX; // heat flow from gas stream to water - Real64 THXexh; // temperature of exhaust gases leaving heat exchanger. - Real64 WaterMassFlowRateDesign; // Design level of water flow rate - Real64 WaterMassFlowRate; // water flow rate in plant loop - Real64 WaterInletTemp; - Real64 WaterVaporFractExh; // water vapor fraction in exhaust gas stream. - Real64 CondensateRate; // water condensation rate. - Array1D ConstitMolalFract; - Array1D_int GasLibID; // lookup ID in Gas Phase ThermoChemistry Structure Array - Real64 NdotHXleaving; - Real64 WaterOutletTemp; - Real64 WaterOutletEnthalpy; - - // Default Constructor - FCExhaustHXDataStruct() - : WaterInNode(0), WaterOutNode(0), WaterVolumeFlowMax(0.0), ExhaustOutNode(0), HXmodelMode(0), HXEffect(0.0), hxs0(0.0), hxs1(0.0), - hxs2(0.0), hxs3(0.0), hxs4(0.0), h0gas(0.0), NdotGasRef(0.0), nCoeff(0.0), AreaGas(0.0), h0Water(0.0), NdotWaterRef(0.0), mCoeff(0.0), - AreaWater(0.0), Fadjust(0.0), l1Coeff(0.0), l2Coeff(0.0), CondensationThresholdTemp(0.0), qHX(0.0), THXexh(0.0), - WaterMassFlowRateDesign(0.0), WaterMassFlowRate(0.0), WaterInletTemp(0.0), WaterVaporFractExh(0.0), CondensateRate(0.0), - ConstitMolalFract(14, 0.0), GasLibID(14, 0), NdotHXleaving(0.0), WaterOutletTemp(0.0), WaterOutletEnthalpy(0.0) - { - } - }; - - struct BatteryDichargeDataStruct - { - // Members - // user defined variables - std::string Name; // name of this battery data set - Real64 NumInSeries; - Real64 NumInParallel; - Real64 NominalVoltage; - Real64 LowVoltsDischarged; // not used - int NumTablePairs; - Array1D DischargeCurrent; // amps - Array1D DischargeTime; // hours - // calculated variables - Real64 k; // parameter in Manwell McGowan model - Real64 c; // parameter in Manwell McGowan model - Real64 qmax; // parameter in Manwell McGowan model - - // Default Constructor - BatteryDichargeDataStruct() - : NumInSeries(0.0), NumInParallel(0.0), NominalVoltage(0.0), LowVoltsDischarged(0.0), NumTablePairs(0), k(0.0), c(0.0), qmax(0.0) - { - } - }; - - struct FCElecStorageDataStruct - { - // Members - // user defined variables - std::string Name; // name of this electrical storage module - int StorageModelMode; - Real64 StartingEnergyStored; // joules inside - Real64 EnergeticEfficCharge; // for - Real64 EnergeticEfficDischarge; - Real64 MaxPowerDraw; // for simple bucket method 0 - Real64 MaxPowerStore; // for simple bucket method 0 - Real64 NominalVoltage; - Real64 NominalEnergyCapacity; // [J] - // calculated and from elsewhere vars - Real64 ThisTimeStepStateOfCharge; // [J] - Real64 LastTimeStepStateOfCharge; // [J] - Real64 PelNeedFromStorage; - Real64 IdesiredDischargeCurrent; - Real64 PelFromStorage; // power - Real64 IfromStorage; // current this timestepm - Real64 PelIntoStorage; - Real64 QairIntake; // heat into intake air - // nested structures - BatteryDichargeDataStruct Battery; - - // Default Constructor - FCElecStorageDataStruct() - : StorageModelMode(0), StartingEnergyStored(0.0), EnergeticEfficCharge(0.0), EnergeticEfficDischarge(0.0), MaxPowerDraw(0.0), - MaxPowerStore(0.0), NominalVoltage(0.0), NominalEnergyCapacity(0.0), ThisTimeStepStateOfCharge(0.0), LastTimeStepStateOfCharge(0.0), - PelNeedFromStorage(0.0), IdesiredDischargeCurrent(0.0), PelFromStorage(0.0), IfromStorage(0.0), PelIntoStorage(0.0), QairIntake(0.0) - { - } - }; - - struct FCInverterDataStruct - { - // Members - // user-defined data - std::string Name; // name of this inverter - int EffMode; // efficiency calculation mode - Real64 ConstEff; - int EffQuadraticCurveID; - // calculated and from elsewhere - Real64 PCUlosses; - Real64 QairIntake; - - // Default Constructor - FCInverterDataStruct() : EffMode(0), ConstEff(0.0), EffQuadraticCurveID(0), PCUlosses(0.0), QairIntake(0.0) - { - } - }; - - struct FCReportDataStruct // these are all for reporting only! - { - // Members - Real64 ACPowerGen; // reporting: power (W) - Real64 ACEnergyGen; // reporting: energy (J) - Real64 QdotExhaust; // reporting: exhaust gas heat recovered (W) - Real64 TotalHeatEnergyRec; // reporting: total heat recovered (J) - Real64 ExhaustEnergyRec; // reporting: exhaust gas heat recovered (J) - Real64 FuelEnergyLHV; // reporting: Fuel Energy used in Lower Heating Value(J) - Real64 FuelEnergyUseRateLHV; // reporting: Fuel Energy used in Lower Heating Value(W) - Real64 FuelEnergyHHV; // reporting: Fuel Energy used in Lower Heating Value(J) - Real64 FuelEnergyUseRateHHV; // reporting: Fuel Energy used in Lower Heating Value(W) - Real64 FuelRateMdot; // (Kg/s) - Real64 HeatRecInletTemp; // reporting: Heat Recovery Loop Inlet Temperature (C) - Real64 HeatRecOutletTemp; // reporting: Heat Recovery Loop Outlet Temperature (C) - Real64 HeatRecMdot; // reporting: Heat Recovery Loop Mass flow rate (kg/s) - // air supply and blower - Real64 TairInlet; // State point 1 - Real64 TairIntoFCPM; // Temperature at State point 4 - Real64 NdotAir; // air flow in kmol/sec - Real64 TotAirInEnthalphy; // Enthalpy at State point 4 - Real64 BlowerPower; // electrical power used by air supply blower - Real64 BlowerEnergy; // electrical energy used by air supply blower - Real64 BlowerSkinLoss; // heat rate of losses by blower - // fuel supply and compressor - Real64 TfuelInlet; // State point 2 [C] - Real64 TfuelIntoFCPM; // state point 5 [C] - Real64 NdotFuel; // fuel flow in [kmol/sec] - Real64 TotFuelInEnthalpy; // state point 5 [W] - Real64 FuelCompressPower; // electrical power used by fuel supply compressor [W] - Real64 FuelCompressEnergy; // electrical energy used by fuel supply compressor [J] - Real64 FuelCompressSkinLoss; // heat rate of losses.by fuel supply compressor [W] - // reformer water supply - Real64 TwaterInlet; // State point 3 - Real64 TwaterIntoFCPM; // State point 6 - Real64 NdotWater; // water flow in kmol/sec (reformer water) - Real64 WaterPumpPower; // electrical power used by water pump [W] - Real64 WaterPumpEnergy; // electrical energy used by water pump [J] - Real64 WaterIntoFCPMEnthalpy; // state point 6 - // product (exhaust) gas leaving power module - Real64 TprodGas; // State point 7 Product Gas temperature - Real64 EnthalProdGas; // state point 7 product gas enthalpy - Real64 NdotProdGas; // point 7 flow rate [kmol/sec] - Real64 NdotProdAr; // argon flow rate at point 7 - Real64 NdotProdCO2; // carbon dioxide flow rate at point 7 - Real64 NdotProdH2O; // water vapor flow rate at point 7 - Real64 NdotProdN2; // nitrogen flow rate at point 7 - Real64 NdotProdO2; // oxygen flow rate at point 7 - // heat exchanger for water to exhaust heat recovery - Real64 qHX; // heat flow from gas stream to water [W] - Real64 HXenergy; // energy from gas stream to water [J] - Real64 THXexh; // temperature of exhaust gases leaving heat exchanger. - Real64 WaterVaporFractExh; // water vapor fraction in exhaust gas stream - // relative to water vapor entering HX (NdotH20/Ndoaux-mix) - Real64 CondensateRate; // water condensation rate [kmol/s] - int SeqSubstIterations; // number of iterations in SOFC loop - int RegulaFalsiIterations; // number of iterations in Tproduct gas solving - Real64 ACancillariesPower; - Real64 ACancillariesEnergy; - Real64 PCUlosses; // power conditioning Unit losses - Real64 DCPowerGen; // Pel, Power module power level [W] - Real64 DCPowerEff; // Eel, power module efficiency [] - Real64 ElectEnergyinStorage; // State of charge in Electrical Storage [J] - Real64 StoredPower; // Power added to Electrical Storage [W] - Real64 StoredEnergy; // energy added to Electrical STorage [J] - Real64 DrawnPower; // Power drawn from Electrical STorage [W] - Real64 DrawnEnergy; // Energy drawn from Electrical STorage [J] - Real64 SkinLossPower; // heat loss to surrounding zone [W] - Real64 SkinLossEnergy; // heat loss to surround zone [J] - Real64 SkinLossConvect; // convective heat loss to zone [W] - Real64 SkinLossRadiat; // radiative heat loss to zone [W} - Real64 ElectEfficiency; - Real64 ThermalEfficiency; - Real64 OverallEfficiency; - Real64 ExergyEfficiency; - - // Default Constructor - FCReportDataStruct() - : ACPowerGen(0.0), ACEnergyGen(0.0), QdotExhaust(0.0), TotalHeatEnergyRec(0.0), ExhaustEnergyRec(0.0), FuelEnergyLHV(0.0), - FuelEnergyUseRateLHV(0.0), FuelEnergyHHV(0.0), FuelEnergyUseRateHHV(0.0), FuelRateMdot(0.0), HeatRecInletTemp(0.0), - HeatRecOutletTemp(0.0), HeatRecMdot(0.0), TairInlet(0.0), TairIntoFCPM(0.0), NdotAir(0.0), TotAirInEnthalphy(0.0), BlowerPower(0.0), - BlowerEnergy(0.0), BlowerSkinLoss(0.0), TfuelInlet(0.0), TfuelIntoFCPM(0.0), NdotFuel(0.0), TotFuelInEnthalpy(0.0), - FuelCompressPower(0.0), FuelCompressEnergy(0.0), FuelCompressSkinLoss(0.0), TwaterInlet(0.0), TwaterIntoFCPM(0.0), NdotWater(0.0), - WaterPumpPower(0.0), WaterPumpEnergy(0.0), WaterIntoFCPMEnthalpy(0.0), TprodGas(0.0), EnthalProdGas(0.0), NdotProdGas(0.0), - NdotProdAr(0.0), NdotProdCO2(0.0), NdotProdH2O(0.0), NdotProdN2(0.0), NdotProdO2(0.0), qHX(0.0), HXenergy(0.0), THXexh(0.0), - WaterVaporFractExh(0.0), CondensateRate(0.0), SeqSubstIterations(0), RegulaFalsiIterations(0), ACancillariesPower(0.0), - ACancillariesEnergy(0.0), PCUlosses(0.0), DCPowerGen(0.0), DCPowerEff(0.0), ElectEnergyinStorage(0.0), StoredPower(0.0), - StoredEnergy(0.0), DrawnPower(0.0), DrawnEnergy(0.0), SkinLossPower(0.0), SkinLossEnergy(0.0), SkinLossConvect(0.0), - SkinLossRadiat(0.0), ElectEfficiency(0.0), ThermalEfficiency(0.0), OverallEfficiency(0.0), ExergyEfficiency(0.0) - { - } - }; - - struct FCDataStruct - { - // Members - // from input data and nested types for subsystems - std::string Name; // user identifier - std::string NameFCPM; // name of FC Power Module - FCPowerModuleStruct FCPM; // data for Power Module - std::string NameFCAirSup; // name of air supply module for fuel cell - FCAirSupplyDataStruct AirSup; // data for air supply module - std::string NameFCFuelSup; // name of fuel supply module - int FuelSupNum; // indes for fuel supply module structure - std::string NameFCWaterSup; // name of water supply module - FCWaterSupplyDataStruct WaterSup; // data for water supply module - std::string NameFCAuxilHeat; // name of auxiliary heating module - FCAuxilHeatDataStruct AuxilHeat; // data for auxiliary heating module - std::string NameExhaustHX; // name of Exhaust HX module - FCExhaustHXDataStruct ExhaustHX; // data for Exhaust heat exchanger module - std::string NameElecStorage; // name of Battery module - FCElecStorageDataStruct ElecStorage; // data for Battery module - std::string NameInverter; // name of Inverter Module - FCInverterDataStruct Inverter; // data for INverter module - std::string NameStackCooler; // name of Inverter Module - FCStackCoolerDataStruct StackCooler; // data for INverter module - int CWLoopNum; // cooling water plant loop index number - int CWLoopSideNum; // cooling water plant loop side index - int CWBranchNum; // cooling water plant loop branch index - int CWCompNum; // cooling water plant loop component index - FCReportDataStruct Report; // data for reporting as E+ output variables - // calculated whole-system level variables - Real64 ACPowerGen; // Net output from SOFC unit - Real64 QconvZone; // convective heat lost to surrounding zone - Real64 QradZone; // radiative heat lost to surrounding zone - int DynamicsControlID; - Real64 TimeElapsed; // used to track when timestep has changed - - // Default Constructor - FCDataStruct() - : FuelSupNum(0), CWLoopNum(0), CWLoopSideNum(0), CWBranchNum(0), CWCompNum(0), ACPowerGen(0.0), QconvZone(0.0), QradZone(0.0), - DynamicsControlID(0), TimeElapsed(0.0) - { - } - }; - struct GeneratorFuelSupplyDataStruct { // Members @@ -705,7 +212,6 @@ namespace DataGenerators { } }; - struct GeneratorDynamicsManagerStruct { // Members @@ -760,20 +266,19 @@ namespace DataGenerators { // Default Constructor GeneratorDynamicsManagerStruct() - : PelMin(0.0), PelMax(0.0), UpTranLimit(0.0), DownTranLimit(0.0), UpTranLimitFuel(0.0), DownTranLimitFuel(0.0), WarmUpByTimeDelay(false), - WarmUpByEngineTemp(true), StartUpTimeDelay(0.0), WarmUpDelay(0.0), StartUpFuel(0.0), StartUpElectConsum(0.0), StartUpElectProd(0.0), - ShutDownFuel(0.0), ShutDownElectConsum(0.0), PcoolDown(0.0), CoolDownDelay(0.0), NumCyclesInit(0), NumRunHoursInit(0.0), Pstandby(0.0), - MCeng(0.0), MCcw(0.0), kf(0.0), TnomEngOp(0.0), kp(0.0), MandatoryFullCoolDown(false), WarmRestartOkay(true), AvailabilitySchedID(0), - CurrentOpMode(OpModeOff), LastOpMode(OpModeOff), FractionalDayofLastShutDown(0.0), FractionalDayofLastStartUp(0.0), HasBeenOn(false), - DuringStartUp(false), DuringShutDown(false), FuelMdotLastTimestep(0.0), PelLastTimeStep(0.0), NumCycles(0), - PLRforSubtimestepStartUp(0.0), PLRforSubtimestepShutDown(0.0), ElectEffNom(0.0), ThermEffNom(0.0), QdotHXMax(0.0), QdotHXMin(0.0), - QdotHXOpt(0.0) + : PelMin(0.0), PelMax(0.0), UpTranLimit(0.0), DownTranLimit(0.0), UpTranLimitFuel(0.0), DownTranLimitFuel(0.0), WarmUpByTimeDelay(false), + WarmUpByEngineTemp(true), StartUpTimeDelay(0.0), WarmUpDelay(0.0), StartUpFuel(0.0), StartUpElectConsum(0.0), StartUpElectProd(0.0), + ShutDownFuel(0.0), ShutDownElectConsum(0.0), PcoolDown(0.0), CoolDownDelay(0.0), NumCyclesInit(0), NumRunHoursInit(0.0), Pstandby(0.0), + MCeng(0.0), MCcw(0.0), kf(0.0), TnomEngOp(0.0), kp(0.0), MandatoryFullCoolDown(false), WarmRestartOkay(true), AvailabilitySchedID(0), + CurrentOpMode(OpModeOff), LastOpMode(OpModeOff), FractionalDayofLastShutDown(0.0), FractionalDayofLastStartUp(0.0), HasBeenOn(false), + DuringStartUp(false), DuringShutDown(false), FuelMdotLastTimestep(0.0), PelLastTimeStep(0.0), NumCycles(0), + PLRforSubtimestepStartUp(0.0), PLRforSubtimestepShutDown(0.0), ElectEffNom(0.0), ThermEffNom(0.0), QdotHXMax(0.0), QdotHXMin(0.0), + QdotHXOpt(0.0) { } }; // Object Data - extern Array1D FuelCell; // dimension to number of machines extern Array1D GasPhaseThermoChemistryData; extern Array1D FuelSupply; // fuel supply (reused across various) extern Array1D GeneratorDynamics; diff --git a/src/EnergyPlus/ElectricPowerServiceManager.cc b/src/EnergyPlus/ElectricPowerServiceManager.cc index e180d35fcc5..0910a5f51cc 100644 --- a/src/EnergyPlus/ElectricPowerServiceManager.cc +++ b/src/EnergyPlus/ElectricPowerServiceManager.cc @@ -1977,7 +1977,6 @@ GeneratorController::GeneratorController(std::string const &objectName, { std::string const routineName = "GeneratorController constructor "; - bool errorsFound = false; name = objectName; typeOfName = objectType; @@ -2012,7 +2011,8 @@ GeneratorController::GeneratorController(std::string const &objectName, // exhaust gas HX is required and it assumed that it has more thermal capacity and is used for control compPlantTypeOf_Num = DataPlant::TypeOf_Generator_FCExhaust; // and the name of plant component is not the same as the generator because of child object references, so fetch that name - FuelCellElectricGenerator::getFuelCellGeneratorHeatRecoveryInfo(name, compPlantName); + auto thisFC = FuelCellElectricGenerator::FCDataStruct::factory(name); + compPlantName = dynamic_cast (thisFC)->ExhaustHX.Name; } else if (UtilityRoutines::SameString(objectType, "Generator:MicroCHP")) { generatorType = GeneratorType::microCHP; compGenTypeOf_Num = DataGlobalConstants::iGeneratorMicroCHP; @@ -2025,7 +2025,6 @@ GeneratorController::GeneratorController(std::string const &objectName, } else { ShowSevereError(routineName + DataIPShortCuts::cCurrentModuleObject + " invalid entry."); ShowContinueError("Invalid " + objectType + " associated with generator = " + objectName); - errorsFound = true; } availSched = availSchedName; @@ -2037,7 +2036,6 @@ GeneratorController::GeneratorController(std::string const &objectName, ShowSevereError(routineName + DataIPShortCuts::cCurrentModuleObject + ", invalid entry."); ShowContinueError("Invalid availability schedule = " + availSchedName); ShowContinueError("Schedule was not found "); - errorsFound = true; } else { if (generatorType == GeneratorType::pvWatts) { ShowWarningError(routineName + DataIPShortCuts::cCurrentModuleObject + ", Availability Schedule for Generator:PVWatts '" + objectName + "' will be be ignored (runs all the time)."); @@ -2109,8 +2107,12 @@ void GeneratorController::simGeneratorGetPowerOutput(bool const runFlag, dynamic_cast (thisICE)->InitICEngineGenerators(runFlag, FirstHVACIteration); dynamic_cast (thisICE)->CalcICEngineGeneratorModel(runFlag, tempLoad); dynamic_cast (thisICE)->update(); - electricPowerOutput = dynamic_cast (thisICE)->ElecPowerGenerated; - thermalPowerOutput = dynamic_cast (thisICE)->QTotalHeatRecovered; + electProdRate = dynamic_cast (thisICE)->ElecPowerGenerated; + electricityProd = dynamic_cast (thisICE)->ElecEnergyGenerated; + thermProdRate = dynamic_cast (thisICE)->QTotalHeatRecovered; + thermalProd = dynamic_cast (thisICE)->TotalHeatEnergyRec; + electricPowerOutput = electProdRate; + thermalPowerOutput = thermProdRate; break; } case GeneratorType::combTurbine: { @@ -2124,8 +2126,12 @@ void GeneratorController::simGeneratorGetPowerOutput(bool const runFlag, thisCTE->simulate(L, FirstHVACIteration, tempLoad, runFlag); dynamic_cast (thisCTE)->InitCTGenerators(runFlag, FirstHVACIteration); dynamic_cast (thisCTE)->CalcCTGeneratorModel(runFlag, tempLoad, FirstHVACIteration); - electricPowerOutput = dynamic_cast (thisCTE)->ElecPowerGenerated; - thermalPowerOutput = dynamic_cast (thisCTE)->QTotalHeatRecovered; + electProdRate = dynamic_cast (thisCTE)->ElecPowerGenerated; + electricityProd = dynamic_cast (thisCTE)->ElecEnergyGenerated; + thermProdRate = dynamic_cast (thisCTE)->QTotalHeatRecovered; + thermalProd = dynamic_cast (thisCTE)->TotalHeatEnergyRec; + electricPowerOutput = electProdRate; + thermalPowerOutput = thermProdRate; break; } case GeneratorType::pV: { @@ -2145,10 +2151,12 @@ void GeneratorController::simGeneratorGetPowerOutput(bool const runFlag, break; } case GeneratorType::fuelCell: { - FuelCellElectricGenerator::SimFuelCellGenerator( - DataGlobalConstants::iGeneratorFuelCell, name, generatorIndex, runFlag, myElecLoadRequest, FirstHVACIteration); - FuelCellElectricGenerator::GetFuelCellGeneratorResults( - DataGlobalConstants::iGeneratorFuelCell, generatorIndex, electProdRate, electricityProd, thermProdRate, thermalProd); + auto thisFC = FuelCellElectricGenerator::FCDataStruct::factory(name); + dynamic_cast (thisFC)->SimFuelCellGenerator(runFlag, myElecLoadRequest, FirstHVACIteration); + electProdRate = dynamic_cast (thisFC)->Report.ACPowerGen; + electricityProd = dynamic_cast (thisFC)->Report.ACEnergyGen; + thermProdRate = dynamic_cast (thisFC)->Report.qHX; + thermalProd = dynamic_cast (thisFC)->Report.HXenergy; electricPowerOutput = electProdRate; thermalPowerOutput = thermProdRate; break; @@ -2169,8 +2177,12 @@ void GeneratorController::simGeneratorGetPowerOutput(bool const runFlag, dynamic_cast (thisMCHP)->CalcUpdateHeatRecovery(); dynamic_cast (thisMCHP)->UpdateMicroCHPGeneratorRecords(); - thermalPowerOutput = dynamic_cast (thisMCHP)->A42Model.ACPowerGen; - thermalPowerOutput = dynamic_cast (thisMCHP)->A42Model.QdotHR; + electProdRate = dynamic_cast (thisMCHP)->A42Model.ACPowerGen; + electricityProd = dynamic_cast (thisMCHP)->A42Model.ACEnergyGen; + thermProdRate = dynamic_cast (thisMCHP)->A42Model.QdotHR; + thermalProd = dynamic_cast (thisMCHP)->A42Model.TotalHeatEnergyRec; + electricPowerOutput = electProdRate; + thermalPowerOutput = thermProdRate; break; } case GeneratorType::microturbine: { @@ -2184,8 +2196,12 @@ void GeneratorController::simGeneratorGetPowerOutput(bool const runFlag, dynamic_cast (thisMTG)->InitMTGenerators(runFlag, tempLoad, FirstHVACIteration); dynamic_cast (thisMTG)->CalcMTGeneratorModel(runFlag, tempLoad); dynamic_cast (thisMTG)->UpdateMTGeneratorRecords(); - electricPowerOutput = dynamic_cast (thisMTG)->ElecPowerGenerated; - thermalPowerOutput = dynamic_cast (thisMTG)->QHeatRecovered; + electProdRate = dynamic_cast (thisMTG)->ElecPowerGenerated; + electricityProd = dynamic_cast (thisMTG)->EnergyGen; + thermProdRate = dynamic_cast (thisMTG)->QHeatRecovered; + thermalProd = dynamic_cast (thisMTG)->ExhaustEnergyRec; + electricPowerOutput = electProdRate; + thermalPowerOutput = thermProdRate; break; } case GeneratorType::windTurbine: { diff --git a/src/EnergyPlus/FuelCellElectricGenerator.cc b/src/EnergyPlus/FuelCellElectricGenerator.cc index 02cb2be22d7..0e44e7eb2a9 100644 --- a/src/EnergyPlus/FuelCellElectricGenerator.cc +++ b/src/EnergyPlus/FuelCellElectricGenerator.cc @@ -58,7 +58,6 @@ #include #include #include -#include #include #include #include @@ -69,7 +68,6 @@ #include #include #include -#include #include #include #include @@ -83,14 +81,8 @@ namespace EnergyPlus { namespace FuelCellElectricGenerator { - //_______________________________________________________________________ - // IEA Annex 42 generators: - // FuelCellElectricGenerator (Solid Oxide Fuel Cell (SOFC)) - // (Proton Exchange Membrane FC (PEMFC)) - // IEA/ECBCS Annex 42 model) - // MODULE INFORMATION: - // AUTHOR Brent Griffth + // AUTHOR Brent Griffith // DATE WRITTEN August. 2005 // MODIFIED na // RE-ENGINEERED na @@ -107,89 +99,79 @@ namespace FuelCellElectricGenerator { // REFERENCES: // IEA/ECBCS Annex 42 model specification for Solid oxide and proton exchange membrane fuel cells - // Using/Aliasing - using namespace DataGenerators; - using namespace DataLoopNode; - using DataGlobalConstants::iGeneratorFuelCell; - using DataGlobals::BeginEnvrnFlag; - using DataGlobals::CurrentTime; - using DataGlobals::DayOfSim; - using DataGlobals::HoursInDay; - using DataGlobals::KelvinConv; - using DataGlobals::NumOfTimeStepInHour; - using DataGlobals::NumOfZones; - using DataGlobals::SecInHour; - using DataGlobals::WarmupFlag; - using namespace GeneratorFuelSupply; - using namespace GeneratorDynamicsManager; - - // MODULE VARIABLE DECLARATIONS: - bool GetFuelCellInput(true); // When TRUE, calls subroutine to read input file. + int NumFuelCellGenerators(0); + bool getFuelCellInputFlag(true); Array1D_bool CheckEquipName; + Array1D FuelCell; // dimension to number of machines - void SimFuelCellGenerator(int const EP_UNUSED(GeneratorType), // type of Generator - std::string const &GeneratorName, // user specified name of Generator - int &GeneratorIndex, - bool const RunFlag, // simulate Generator when TRUE - Real64 const MyLoad, // demand on electric generator - bool const FirstHVACIteration) + void clear_state() { - // SUBROUTINE INFORMATION: - // AUTHOR Brent Griffith - // DATE WRITTEN MArch 2005 - // RE-ENGINEERED na - - // PURPOSE OF THIS SUBROUTINE: This is the Solid oxide fuel cell Generator model driver. It - // gets the input for the models, initializes simulation variables, call - // the appropriate model and sets up reporting variables. + NumFuelCellGenerators = 0; + getFuelCellInputFlag = true; + CheckEquipName.deallocate(); + FuelCell.deallocate(); + } - // Using/Aliasing - using General::TrimSigDigits; + PlantComponent *FCDataStruct::factory(std::string const &objectName) + { + // Process the input data + if (getFuelCellInputFlag) { + getFuelCellInput(); + getFuelCellInputFlag = false; + } - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int GenNum; // Generator number counter + // Now look for this object + for (auto &thisFC : FuelCell) { + if (thisFC.Name == objectName) { + return &thisFC; + } + } + // If we didn't find it, fatal + ShowFatalError("LocalFuelCellGenFactory: Error getting inputs for object named: " + objectName); // LCOV_EXCL_LINE + // Shut up the compiler + return nullptr; // LCOV_EXCL_LINE + } - // Get Generator data from input file - if (GetFuelCellInput) { - GetFuelCellGeneratorInput(); - GetFuelCellInput = false; + PlantComponent *FCDataStruct::factory_exhaust(std::string const &objectName) + { + // Process the input data + if (getFuelCellInputFlag) { + getFuelCellInput(); + getFuelCellInputFlag = false; } - if (GeneratorIndex == 0) { - GenNum = UtilityRoutines::FindItemInList(GeneratorName, FuelCell); - if (GenNum == 0) ShowFatalError("SimFuelCellGenerator: Specified Generator not one of Valid FuelCell Generators " + GeneratorName); - GeneratorIndex = GenNum; - } else { - GenNum = GeneratorIndex; - if (GenNum > NumFuelCellGenerators || GenNum < 1) { - ShowFatalError("SimFuelCellGenerator: Invalid GeneratorIndex passed=" + TrimSigDigits(GenNum) + - ", Number of FuelCell Generators=" + TrimSigDigits(NumFuelCellGenerators) + ", Generator name=" + GeneratorName); - } - if (CheckEquipName(GenNum)) { - if (GeneratorName != FuelCell(GenNum).Name) { - ShowFatalError("SimFuelCellGenerator: Invalid GeneratorIndex passed=" + TrimSigDigits(GenNum) + - ", Generator name=" + GeneratorName + ", stored Generator Name for that index=" + FuelCell(GenNum).Name); - } - CheckEquipName(GenNum) = false; + // Now look for this object + for (auto &thisFC : FuelCell) { + if (UtilityRoutines::MakeUPPERCase(thisFC.NameExhaustHX) == UtilityRoutines::MakeUPPERCase(objectName)) { + return &thisFC; } } + // If we didn't find it, fatal + ShowFatalError("LocalFuelCellGenFactory: Error getting inputs for object named: " + objectName); // LCOV_EXCL_LINE + // Shut up the compiler + return nullptr; // LCOV_EXCL_LINE + } - InitFuelCellGenerators(GenNum); - - CalcFuelCellGeneratorModel(GenNum, RunFlag, MyLoad, FirstHVACIteration); + void FCDataStruct::SimFuelCellGenerator(bool const RunFlag, // simulate Generator when TRUE + Real64 const MyLoad, // demand on electric generator + bool const FirstHVACIteration) + { + // SUBROUTINE INFORMATION: + // AUTHOR Brent Griffith + // DATE WRITTEN March 2005 + // RE-ENGINEERED na - CalcUpdateHeatRecovery(GenNum, FirstHVACIteration); + // PURPOSE OF THIS SUBROUTINE: This is the Solid oxide fuel cell Generator model driver. It + // gets the input for the models, initializes simulation variables, call + // the appropriate model and sets up reporting variables. - UpdateFuelCellGeneratorRecords(RunFlag, GenNum); + this->initialize(); + this->CalcFuelCellGeneratorModel(RunFlag, MyLoad, FirstHVACIteration); + this->CalcUpdateHeatRecovery(FirstHVACIteration); + this->UpdateFuelCellGeneratorRecords(); } - // End FuelCell Generator Module Driver Subroutines - //****************************************************************************** - - // Beginning of FuelCell Generator Module Get Input subroutines - //****************************************************************************** - - void GetFuelCellGeneratorInput() + void getFuelCellInput() { // SUBROUTINE INFORMATION: // AUTHOR: Brent Griffith @@ -202,1202 +184,1157 @@ namespace FuelCellElectricGenerator { // METHODOLOGY EMPLOYED: // EnergyPlus input processor - // Using/Aliasing - using namespace DataGenerators; - using namespace DataIPShortCuts; // Data for field names, blank numerics - using BranchNodeConnections::TestCompSet; - using CurveManager::GetCurveIndex; - using DataGlobals::DisplayAdvancedReportVariables; - using DataHeatBalance::IntGainTypeOf_GeneratorFuelCell; - using DataHeatBalance::Zone; - using General::RoundSigDigits; - using NodeInputManager::GetOnlySingleNode; - using PlantUtilities::RegisterPlantCompDesignFlow; - using ScheduleManager::GetScheduleIndex; - - // LOCAL VARIABLES - int GeneratorNum; // Generator counter int NumAlphas; // Number of elements in the alpha array int NumNums; // Number of elements in the numeric array int IOStat; // IO Status when calling get input subroutine Array1D_string AlphArray(25); // character string data Array1D NumArray(200); // numeric data TODO deal with allocatable for extensible Array1D_bool lAlphaBlanks(25); - static bool ErrorsFound(false); // error flag - int NumFuelCellPMs; // number of power subsystems in input file - int NumFuelCellAirSups; // number of air supply subsystems in input file - // INTEGER :: NumFuelCellFuelSups ! number of fuel supply subsystems in input file - int NumFCWaterSups; // number of water supply subsystems in input file - int NumFuelCellAuxilHeaters; - int NumFCExhaustGasHXs; - int NumFCElecStorageUnits; // number of electrical storage objects in input file - // INTEGER :: NumBatteries !number of Manwell and McGowan battery data objects - int NumFCPowerCondUnits; // number of power conditioning units (inverter) - int NumFCStackCoolers; // number of stack coolers. - int NumAirConstit; // number of gas constituents in air - int FCPMNum; // loop counter over power subsystems - int FCAirSupNum; // loop counter over air supply subsystems - // INTEGER :: FCFuelSupNum !loop counter over fuel supply subsystems - int ConstitNum; // loop counter for consituents - int FCWaterSupNum; // loop counter over water supply subsystems - int FCHXNum; // loop counter for heat exchangers - int FCAuxHeatNum; // loop counter over auxiliar heater - int FCPCUNum; // loop counter over inverters - int StorageNum; // loop counter over electrical storage subsystems - int FCScoolNum; // loop counter over stack coolers - int thisFuelCell; // temporary index - int otherFuelCell; // loop counter and temporary indexer - int i; // loop counter - static bool MyOneTimeFlag(true); - std::string thisName; - int NumHardCodedConstituents; - int thisConstituent; - int thisGasID; - int FuelSupNum; - - // Autodesk:Uninit Initialize variables used uninitialized - thisFuelCell = 0; // Autodesk:Uninit Force default initialization: Will cause intentional failure if used as a FuelCell array index: Issue may - // be fixed by changes in EP 8.2 but that wasn't documented here (initialization is harmless so left in for now) - - // execution - if (MyOneTimeFlag) { - - cCurrentModuleObject = "Generator:FuelCell"; - NumFuelCellGenerators = inputProcessor->getNumObjectsFound(cCurrentModuleObject); - - if (NumFuelCellGenerators <= 0) { - ShowSevereError("No " + cCurrentModuleObject + " equipment specified in input file"); - ErrorsFound = true; - } + bool ErrorsFound(false); // error flag - // ALLOCATE ARRAYS - FuelCell.allocate(NumFuelCellGenerators); // inits handeled in derived type definitions - CheckEquipName.dimension(NumFuelCellGenerators, true); - - // first load in FuelCell names - for (GeneratorNum = 1; GeneratorNum <= NumFuelCellGenerators; ++GeneratorNum) { - inputProcessor->getObjectItem( - cCurrentModuleObject, GeneratorNum, AlphArray, NumAlphas, NumArray, NumNums, IOStat, _, _, cAlphaFieldNames, cNumericFieldNames); - UtilityRoutines::IsNameEmpty(AlphArray(1), cCurrentModuleObject, ErrorsFound); - - FuelCell(GeneratorNum).Name = AlphArray(1); - FuelCell(GeneratorNum).NameFCPM = AlphArray(2); - FuelCell(GeneratorNum).NameFCAirSup = AlphArray(3); - FuelCell(GeneratorNum).NameFCFuelSup = AlphArray(4); - FuelCell(GeneratorNum).NameFCWaterSup = AlphArray(5); - FuelCell(GeneratorNum).NameFCAuxilHeat = AlphArray(6); - FuelCell(GeneratorNum).NameExhaustHX = AlphArray(7); - FuelCell(GeneratorNum).NameElecStorage = AlphArray(8); - FuelCell(GeneratorNum).NameInverter = AlphArray(9); - if (NumAlphas == 10) { - FuelCell(GeneratorNum).NameStackCooler = AlphArray(10); - } - } + DataIPShortCuts::cCurrentModuleObject = "Generator:FuelCell"; + NumFuelCellGenerators = inputProcessor->getNumObjectsFound(DataIPShortCuts::cCurrentModuleObject); - cCurrentModuleObject = "Generator:FuelCell:PowerModule"; - NumFuelCellPMs = inputProcessor->getNumObjectsFound(cCurrentModuleObject); + if (NumFuelCellGenerators <= 0) { + ShowSevereError("No " + DataIPShortCuts::cCurrentModuleObject + " equipment specified in input file"); + ErrorsFound = true; + } - if (NumFuelCellPMs <= 0) { // Autodesk:Uninit Allowing code to continue past this condition used thisFuelCell uninitialized in EP 8.0 - ShowSevereError("No " + cCurrentModuleObject + " equipment specified in input file"); - ErrorsFound = true; + // ALLOCATE ARRAYS + FuelCell.allocate(NumFuelCellGenerators); // inits handled in derived type definitions + CheckEquipName.dimension(NumFuelCellGenerators, true); + + // first load in FuelCell names + for (int GeneratorNum = 1; GeneratorNum <= NumFuelCellGenerators; ++GeneratorNum) { + inputProcessor->getObjectItem(DataIPShortCuts::cCurrentModuleObject, + GeneratorNum, + AlphArray, + NumAlphas, + NumArray, + NumNums, + IOStat, + _, + _, + DataIPShortCuts::cAlphaFieldNames, + DataIPShortCuts::cNumericFieldNames); + UtilityRoutines::IsNameEmpty(AlphArray(1), DataIPShortCuts::cCurrentModuleObject, ErrorsFound); + + FuelCell(GeneratorNum).Name = AlphArray(1); + FuelCell(GeneratorNum).NameFCPM = AlphArray(2); + FuelCell(GeneratorNum).NameFCAirSup = AlphArray(3); + FuelCell(GeneratorNum).NameFCFuelSup = AlphArray(4); + FuelCell(GeneratorNum).NameFCWaterSup = AlphArray(5); + FuelCell(GeneratorNum).NameFCAuxilHeat = AlphArray(6); + FuelCell(GeneratorNum).NameExhaustHX = AlphArray(7); + FuelCell(GeneratorNum).NameElecStorage = AlphArray(8); + FuelCell(GeneratorNum).NameInverter = AlphArray(9); + if (NumAlphas == 10) { + FuelCell(GeneratorNum).NameStackCooler = AlphArray(10); } + } - for (FCPMNum = 1; FCPMNum <= NumFuelCellPMs; ++FCPMNum) { - inputProcessor->getObjectItem(cCurrentModuleObject, - FCPMNum, - AlphArray, - NumAlphas, - NumArray, - NumNums, - IOStat, - _, - lAlphaBlanks, - cAlphaFieldNames, - cNumericFieldNames); - UtilityRoutines::IsNameEmpty(AlphArray(1), cCurrentModuleObject, ErrorsFound); - - thisFuelCell = UtilityRoutines::FindItemInList(AlphArray(1), FuelCell, &FCDataStruct::NameFCPM); - if (thisFuelCell > 0) { // cr9323 - - FuelCell(thisFuelCell).FCPM.Name = AlphArray(1); - if (UtilityRoutines::SameString(AlphArray(2), "ANNEX42")) FuelCell(thisFuelCell).FCPM.EffMode = DirectCurveMode; - if (UtilityRoutines::SameString(AlphArray(2), "NORMALIZED")) FuelCell(thisFuelCell).FCPM.EffMode = NormalizedCurveMode; - if (FuelCell(thisFuelCell).FCPM.EffMode == 0) { - ShowSevereError("Invalid, " + cAlphaFieldNames(2) + " = " + AlphArray(2)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); - ErrorsFound = true; - } - FuelCell(thisFuelCell).FCPM.EffCurveID = GetCurveIndex(AlphArray(3)); - if (FuelCell(thisFuelCell).FCPM.EffCurveID == 0) { - ShowSevereError("Invalid, " + cAlphaFieldNames(3) + " = " + AlphArray(3)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); - ErrorsFound = true; - } - - FuelCell(thisFuelCell).FCPM.NomEff = NumArray(1); - FuelCell(thisFuelCell).FCPM.NomPel = NumArray(2); - FuelCell(thisFuelCell).FCPM.NumCycles = NumArray(3); - FuelCell(thisFuelCell).FCPM.CyclingDegradRat = NumArray(4); - FuelCell(thisFuelCell).FCPM.NumRunHours = NumArray(5); - FuelCell(thisFuelCell).FCPM.OperateDegradRat = NumArray(6); - FuelCell(thisFuelCell).FCPM.ThreshRunHours = NumArray(7); - FuelCell(thisFuelCell).FCPM.UpTranLimit = NumArray(8); - FuelCell(thisFuelCell).FCPM.DownTranLimit = NumArray(9); - FuelCell(thisFuelCell).FCPM.StartUpTime = NumArray(10) / SecInHour; // convert to hours from seconds - FuelCell(thisFuelCell).FCPM.StartUpFuel = NumArray(11); - FuelCell(thisFuelCell).FCPM.StartUpElectConsum = NumArray(12); - FuelCell(thisFuelCell).FCPM.StartUpElectProd = NumArray(13); - FuelCell(thisFuelCell).FCPM.ShutDownTime = NumArray(14) / SecInHour; // convert to hours from seconds - FuelCell(thisFuelCell).FCPM.ShutDownFuel = NumArray(15); - FuelCell(thisFuelCell).FCPM.ShutDownElectConsum = NumArray(16); - FuelCell(thisFuelCell).FCPM.ANC0 = NumArray(17); - FuelCell(thisFuelCell).FCPM.ANC1 = NumArray(18); - if (UtilityRoutines::SameString(AlphArray(4), "ConstantRate")) FuelCell(thisFuelCell).FCPM.SkinLossMode = ConstantRateSkinLoss; - if (UtilityRoutines::SameString(AlphArray(4), "UAForProcessGasTemperature")) - FuelCell(thisFuelCell).FCPM.SkinLossMode = UADTSkinLoss; - if (UtilityRoutines::SameString(AlphArray(4), "QUADRATIC FUNCTION OF FUEL RATE")) - FuelCell(thisFuelCell).FCPM.SkinLossMode = QuadraticFuelNdotSkin; - if (FuelCell(thisFuelCell).FCPM.SkinLossMode == 0) { - // throw error - ShowSevereError("Invalid, " + cAlphaFieldNames(4) + " = " + AlphArray(4)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); - ErrorsFound = true; - } - FuelCell(thisFuelCell).FCPM.ZoneName = AlphArray(5); - FuelCell(thisFuelCell).FCPM.ZoneID = UtilityRoutines::FindItemInList(FuelCell(thisFuelCell).FCPM.ZoneName, Zone); - if (FuelCell(thisFuelCell).FCPM.ZoneID == 0 && !lAlphaBlanks(5)) { - ShowSevereError("Invalid, " + cAlphaFieldNames(5) + " = " + AlphArray(5)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); - ShowContinueError("Zone Name was not found "); - ErrorsFound = true; - } + DataIPShortCuts::cCurrentModuleObject = "Generator:FuelCell:PowerModule"; + int NumFuelCellPMs = inputProcessor->getNumObjectsFound(DataIPShortCuts::cCurrentModuleObject); - FuelCell(thisFuelCell).FCPM.RadiativeFract = NumArray(19); - FuelCell(thisFuelCell).FCPM.QdotSkin = NumArray(20); - FuelCell(thisFuelCell).FCPM.UAskin = NumArray(21); + if (NumFuelCellPMs <= 0) { + ShowSevereError("No " + DataIPShortCuts::cCurrentModuleObject + " equipment specified in input file"); + ErrorsFound = true; + } - FuelCell(thisFuelCell).FCPM.SkinLossCurveID = GetCurveIndex(AlphArray(6)); - if (FuelCell(thisFuelCell).FCPM.SkinLossCurveID == 0) { - if (FuelCell(thisFuelCell).FCPM.SkinLossMode == QuadraticFuelNdotSkin) { - ShowSevereError("Invalid, " + cAlphaFieldNames(6) + " = " + AlphArray(6)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); - ErrorsFound = true; - } - } + for (int FCPMNum = 1; FCPMNum <= NumFuelCellPMs; ++FCPMNum) { + inputProcessor->getObjectItem(DataIPShortCuts::cCurrentModuleObject, + FCPMNum, + AlphArray, + NumAlphas, + NumArray, + NumNums, + IOStat, + _, + lAlphaBlanks, + DataIPShortCuts::cAlphaFieldNames, + DataIPShortCuts::cNumericFieldNames); + UtilityRoutines::IsNameEmpty(AlphArray(1), DataIPShortCuts::cCurrentModuleObject, ErrorsFound); + + int thisFuelCell = UtilityRoutines::FindItemInList(AlphArray(1), FuelCell, &FCDataStruct::NameFCPM); + if (thisFuelCell > 0) { + + FuelCell(thisFuelCell).FCPM.Name = AlphArray(1); + if (UtilityRoutines::SameString(AlphArray(2), "ANNEX42")) FuelCell(thisFuelCell).FCPM.EffMode = DataGenerators::DirectCurveMode; + if (UtilityRoutines::SameString(AlphArray(2), "NORMALIZED")) + FuelCell(thisFuelCell).FCPM.EffMode = DataGenerators::NormalizedCurveMode; + if (FuelCell(thisFuelCell).FCPM.EffMode == 0) { + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(2) + " = " + AlphArray(2)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); + ErrorsFound = true; + } + FuelCell(thisFuelCell).FCPM.EffCurveID = CurveManager::GetCurveIndex(AlphArray(3)); + if (FuelCell(thisFuelCell).FCPM.EffCurveID == 0) { + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(3) + " = " + AlphArray(3)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); + ErrorsFound = true; + } - FuelCell(thisFuelCell).FCPM.NdotDilutionAir = NumArray(22); - FuelCell(thisFuelCell).FCPM.StackHeatLossToDilution = NumArray(23); - FuelCell(thisFuelCell).FCPM.DilutionInletNodeName = AlphArray(7); - FuelCell(thisFuelCell).FCPM.DilutionInletNode = GetOnlySingleNode( - AlphArray(7), ErrorsFound, cCurrentModuleObject, AlphArray(1), NodeType_Air, NodeConnectionType_Inlet, 1, ObjectIsNotParent); - FuelCell(thisFuelCell).FCPM.DilutionExhaustNodeName = AlphArray(8); - FuelCell(thisFuelCell).FCPM.DilutionExhaustNode = GetOnlySingleNode( - AlphArray(8), ErrorsFound, cCurrentModuleObject, AlphArray(1), NodeType_Air, NodeConnectionType_Outlet, 1, ObjectIsNotParent); - - FuelCell(thisFuelCell).FCPM.PelMin = NumArray(24); - FuelCell(thisFuelCell).FCPM.PelMax = NumArray(25); - - // check for other FuelCell using the same power module and fill - for (otherFuelCell = thisFuelCell + 1; otherFuelCell <= NumFuelCellGenerators; ++otherFuelCell) { - if (UtilityRoutines::SameString(FuelCell(otherFuelCell).FCPM.Name, FuelCell(thisFuelCell).FCPM.Name)) { - FuelCell(otherFuelCell).FCPM = FuelCell(thisFuelCell).FCPM; - } - } - } else { // throw warning, did not find power module input - ShowSevereError("Invalid, " + cAlphaFieldNames(1) + " = " + AlphArray(1)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); + FuelCell(thisFuelCell).FCPM.NomEff = NumArray(1); + FuelCell(thisFuelCell).FCPM.NomPel = NumArray(2); + FuelCell(thisFuelCell).FCPM.NumCycles = NumArray(3); + FuelCell(thisFuelCell).FCPM.CyclingDegradRat = NumArray(4); + FuelCell(thisFuelCell).FCPM.NumRunHours = NumArray(5); + FuelCell(thisFuelCell).FCPM.OperateDegradRat = NumArray(6); + FuelCell(thisFuelCell).FCPM.ThreshRunHours = NumArray(7); + FuelCell(thisFuelCell).FCPM.UpTranLimit = NumArray(8); + FuelCell(thisFuelCell).FCPM.DownTranLimit = NumArray(9); + FuelCell(thisFuelCell).FCPM.StartUpTime = NumArray(10) / DataGlobals::SecInHour; // convert to hours from seconds + FuelCell(thisFuelCell).FCPM.StartUpFuel = NumArray(11); + FuelCell(thisFuelCell).FCPM.StartUpElectConsum = NumArray(12); + FuelCell(thisFuelCell).FCPM.StartUpElectProd = NumArray(13); + FuelCell(thisFuelCell).FCPM.ShutDownTime = NumArray(14) / DataGlobals::SecInHour; // convert to hours from seconds + FuelCell(thisFuelCell).FCPM.ShutDownFuel = NumArray(15); + FuelCell(thisFuelCell).FCPM.ShutDownElectConsum = NumArray(16); + FuelCell(thisFuelCell).FCPM.ANC0 = NumArray(17); + FuelCell(thisFuelCell).FCPM.ANC1 = NumArray(18); + if (UtilityRoutines::SameString(AlphArray(4), "ConstantRate")) + FuelCell(thisFuelCell).FCPM.SkinLossMode = DataGenerators::ConstantRateSkinLoss; + if (UtilityRoutines::SameString(AlphArray(4), "UAForProcessGasTemperature")) + FuelCell(thisFuelCell).FCPM.SkinLossMode = DataGenerators::UADTSkinLoss; + if (UtilityRoutines::SameString(AlphArray(4), "QUADRATIC FUNCTION OF FUEL RATE")) + FuelCell(thisFuelCell).FCPM.SkinLossMode = DataGenerators::QuadraticFuelNdotSkin; + if (FuelCell(thisFuelCell).FCPM.SkinLossMode == 0) { + // throw error + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(4) + " = " + AlphArray(4)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); + ErrorsFound = true; + } + FuelCell(thisFuelCell).FCPM.ZoneName = AlphArray(5); + FuelCell(thisFuelCell).FCPM.ZoneID = UtilityRoutines::FindItemInList(FuelCell(thisFuelCell).FCPM.ZoneName, DataHeatBalance::Zone); + if (FuelCell(thisFuelCell).FCPM.ZoneID == 0 && !lAlphaBlanks(5)) { + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(5) + " = " + AlphArray(5)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); + ShowContinueError("Zone Name was not found "); ErrorsFound = true; } - } // loop over NumFuelCellPMs - GetGeneratorFuelSupplyInput(); + FuelCell(thisFuelCell).FCPM.RadiativeFract = NumArray(19); + FuelCell(thisFuelCell).FCPM.QdotSkin = NumArray(20); + FuelCell(thisFuelCell).FCPM.UAskin = NumArray(21); - for (FuelSupNum = 1; FuelSupNum <= NumGeneratorFuelSups; ++FuelSupNum) { - SetupFuelConstituentData(FuelSupNum, ErrorsFound); - } + FuelCell(thisFuelCell).FCPM.SkinLossCurveID = CurveManager::GetCurveIndex(AlphArray(6)); + if (FuelCell(thisFuelCell).FCPM.SkinLossCurveID == 0) { + if (FuelCell(thisFuelCell).FCPM.SkinLossMode == DataGenerators::QuadraticFuelNdotSkin) { + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(6) + " = " + AlphArray(6)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); + ErrorsFound = true; + } + } - // set fuel supply ID in Fuel cell structure - for (GeneratorNum = 1; GeneratorNum <= NumFuelCellGenerators; ++GeneratorNum) { - FuelCell(GeneratorNum).FuelSupNum = - UtilityRoutines::FindItemInList(FuelCell(GeneratorNum).NameFCFuelSup, FuelSupply); // Fuel Supply ID - if (FuelCell(GeneratorNum).FuelSupNum == 0) { - ShowSevereError("Fuel Supply Name: " + FuelCell(GeneratorNum).NameFCFuelSup + " not found in " + FuelCell(GeneratorNum).Name); - ErrorsFound = true; + FuelCell(thisFuelCell).FCPM.NdotDilutionAir = NumArray(22); + FuelCell(thisFuelCell).FCPM.StackHeatLossToDilution = NumArray(23); + FuelCell(thisFuelCell).FCPM.DilutionInletNodeName = AlphArray(7); + FuelCell(thisFuelCell).FCPM.DilutionInletNode = NodeInputManager::GetOnlySingleNode(AlphArray(7), + ErrorsFound, + DataIPShortCuts::cCurrentModuleObject, + AlphArray(1), + DataLoopNode::NodeType_Air, + DataLoopNode::NodeConnectionType_Inlet, + 1, + DataLoopNode::ObjectIsNotParent); + FuelCell(thisFuelCell).FCPM.DilutionExhaustNodeName = AlphArray(8); + FuelCell(thisFuelCell).FCPM.DilutionExhaustNode = NodeInputManager::GetOnlySingleNode(AlphArray(8), + ErrorsFound, + DataIPShortCuts::cCurrentModuleObject, + AlphArray(1), + DataLoopNode::NodeType_Air, + DataLoopNode::NodeConnectionType_Outlet, + 1, + DataLoopNode::ObjectIsNotParent); + + FuelCell(thisFuelCell).FCPM.PelMin = NumArray(24); + FuelCell(thisFuelCell).FCPM.PelMax = NumArray(25); + + // check for other FuelCell using the same power module and fill + for (int otherFuelCell = thisFuelCell + 1; otherFuelCell <= NumFuelCellGenerators; ++otherFuelCell) { + if (UtilityRoutines::SameString(FuelCell(otherFuelCell).FCPM.Name, FuelCell(thisFuelCell).FCPM.Name)) { + FuelCell(otherFuelCell).FCPM = FuelCell(thisFuelCell).FCPM; + } } + } else { // throw warning, did not find power module input + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(1) + " = " + AlphArray(1)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); + ErrorsFound = true; } + } // loop over NumFuelCellPMs - cCurrentModuleObject = "Generator:FuelCell:AirSupply"; - NumFuelCellAirSups = inputProcessor->getNumObjectsFound(cCurrentModuleObject); + GeneratorFuelSupply::GetGeneratorFuelSupplyInput(); - if (NumFuelCellAirSups <= 0) { // Autodesk:Uninit thisFuelCell was possibly uninitialized past this condition - ShowSevereError("No " + cCurrentModuleObject + " equipment specified in input file"); + for (int FuelSupNum = 1; FuelSupNum <= DataGenerators::NumGeneratorFuelSups; ++FuelSupNum) { + GeneratorFuelSupply::SetupFuelConstituentData(FuelSupNum, ErrorsFound); + } + + // set fuel supply ID in Fuel cell structure + for (int GeneratorNum = 1; GeneratorNum <= NumFuelCellGenerators; ++GeneratorNum) { + FuelCell(GeneratorNum).FuelSupNum = + UtilityRoutines::FindItemInList(FuelCell(GeneratorNum).NameFCFuelSup, DataGenerators::FuelSupply); // Fuel Supply ID + if (FuelCell(GeneratorNum).FuelSupNum == 0) { + ShowSevereError("Fuel Supply Name: " + FuelCell(GeneratorNum).NameFCFuelSup + " not found in " + FuelCell(GeneratorNum).Name); ErrorsFound = true; } + } - for (FCAirSupNum = 1; FCAirSupNum <= NumFuelCellAirSups; ++FCAirSupNum) { - inputProcessor->getObjectItem( - cCurrentModuleObject, FCAirSupNum, AlphArray, NumAlphas, NumArray, NumNums, IOStat, _, _, cAlphaFieldNames, cNumericFieldNames); - UtilityRoutines::IsNameEmpty(AlphArray(1), cCurrentModuleObject, ErrorsFound); + DataIPShortCuts::cCurrentModuleObject = "Generator:FuelCell:AirSupply"; + int NumFuelCellAirSups = inputProcessor->getNumObjectsFound(DataIPShortCuts::cCurrentModuleObject); - thisFuelCell = UtilityRoutines::FindItemInList(AlphArray(1), FuelCell, &FCDataStruct::NameFCAirSup); - if (thisFuelCell > 0) { + if (NumFuelCellAirSups <= 0) { // Autodesk:Uninit thisFuelCell was possibly uninitialized past this condition + ShowSevereError("No " + DataIPShortCuts::cCurrentModuleObject + " equipment specified in input file"); + ErrorsFound = true; + } + + for (int FCAirSupNum = 1; FCAirSupNum <= NumFuelCellAirSups; ++FCAirSupNum) { + inputProcessor->getObjectItem(DataIPShortCuts::cCurrentModuleObject, + FCAirSupNum, + AlphArray, + NumAlphas, + NumArray, + NumNums, + IOStat, + _, + _, + DataIPShortCuts::cAlphaFieldNames, + DataIPShortCuts::cNumericFieldNames); + UtilityRoutines::IsNameEmpty(AlphArray(1), DataIPShortCuts::cCurrentModuleObject, ErrorsFound); + + int thisFuelCell = UtilityRoutines::FindItemInList(AlphArray(1), FuelCell, &FCDataStruct::NameFCAirSup); + + if (thisFuelCell > 0) { + + FuelCell(thisFuelCell).AirSup.Name = AlphArray(1); + FuelCell(thisFuelCell).AirSup.NodeName = AlphArray(2); + + // check the node connections + FuelCell(thisFuelCell).AirSup.SupNodeNum = NodeInputManager::GetOnlySingleNode(AlphArray(2), + ErrorsFound, + DataIPShortCuts::cCurrentModuleObject, + AlphArray(1), + DataLoopNode::NodeType_Air, + DataLoopNode::NodeConnectionType_Inlet, + 1, + DataLoopNode::ObjectIsNotParent); + + FuelCell(thisFuelCell).AirSup.BlowerPowerCurveID = CurveManager::GetCurveIndex(AlphArray(3)); + if (FuelCell(thisFuelCell).AirSup.BlowerPowerCurveID == 0) { + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(3) + " = " + AlphArray(3)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); + ShowContinueError("Curve name was not found "); + ErrorsFound = true; + } + FuelCell(thisFuelCell).AirSup.BlowerHeatLossFactor = NumArray(1); + + if (UtilityRoutines::SameString(AlphArray(4), "AirRatiobyStoics")) { + FuelCell(thisFuelCell).AirSup.AirSupRateMode = DataGenerators::ConstantStoicsAirRat; + } else if (UtilityRoutines::SameString(AlphArray(4), "QuadraticFunctionofElectricPower")) { + FuelCell(thisFuelCell).AirSup.AirSupRateMode = DataGenerators::QuadraticFuncofPel; + } else if (UtilityRoutines::SameString(AlphArray(4), "QUADRATIC FUNCTION OF FUEL RATE")) { + FuelCell(thisFuelCell).AirSup.AirSupRateMode = DataGenerators::QuadraticFuncofNdot; + } else { + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(4) + " = " + AlphArray(4)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); + ErrorsFound = true; + } - FuelCell(thisFuelCell).AirSup.Name = AlphArray(1); - FuelCell(thisFuelCell).AirSup.NodeName = AlphArray(2); + FuelCell(thisFuelCell).AirSup.Stoics = NumArray(2) + 1.0; - // check the node connections - FuelCell(thisFuelCell).AirSup.SupNodeNum = GetOnlySingleNode( - AlphArray(2), ErrorsFound, cCurrentModuleObject, AlphArray(1), NodeType_Air, NodeConnectionType_Inlet, 1, ObjectIsNotParent); + FuelCell(thisFuelCell).AirSup.AirFuncPelCurveID = CurveManager::GetCurveIndex(AlphArray(5)); + if ((FuelCell(thisFuelCell).AirSup.AirFuncPelCurveID == 0) && + (FuelCell(thisFuelCell).AirSup.AirSupRateMode == DataGenerators::QuadraticFuncofPel)) { + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(5) + " = " + AlphArray(5)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); + ShowSevereError("Curve name was not found"); + ErrorsFound = true; + } - FuelCell(thisFuelCell).AirSup.BlowerPowerCurveID = GetCurveIndex(AlphArray(3)); - if (FuelCell(thisFuelCell).AirSup.BlowerPowerCurveID == 0) { - ShowSevereError("Invalid, " + cAlphaFieldNames(3) + " = " + AlphArray(3)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); - ShowContinueError("Curve name was not found "); - ErrorsFound = true; - } - FuelCell(thisFuelCell).AirSup.BlowerHeatLossFactor = NumArray(1); - - if (UtilityRoutines::SameString(AlphArray(4), "AirRatiobyStoics")) { - FuelCell(thisFuelCell).AirSup.AirSupRateMode = ConstantStoicsAirRat; - } else if (UtilityRoutines::SameString(AlphArray(4), "QuadraticFunctionofElectricPower")) { - FuelCell(thisFuelCell).AirSup.AirSupRateMode = QuadraticFuncofPel; - } else if (UtilityRoutines::SameString(AlphArray(4), "QUADRATIC FUNCTION OF FUEL RATE")) { - FuelCell(thisFuelCell).AirSup.AirSupRateMode = QuadraticFuncofNdot; - } else { - ShowSevereError("Invalid, " + cAlphaFieldNames(4) + " = " + AlphArray(4)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); - ErrorsFound = true; - } + FuelCell(thisFuelCell).AirSup.AirTempCoeff = NumArray(3); - FuelCell(thisFuelCell).AirSup.Stoics = NumArray(2) + 1.0; + FuelCell(thisFuelCell).AirSup.AirFuncNdotCurveID = CurveManager::GetCurveIndex(AlphArray(6)); + if ((FuelCell(thisFuelCell).AirSup.AirFuncNdotCurveID == 0) && + (FuelCell(thisFuelCell).AirSup.AirSupRateMode == DataGenerators::QuadraticFuncofNdot)) { + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(6) + " = " + AlphArray(6)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); + ShowSevereError("Curve name was not found"); + ErrorsFound = true; + } - FuelCell(thisFuelCell).AirSup.AirFuncPelCurveID = GetCurveIndex(AlphArray(5)); - if ((FuelCell(thisFuelCell).AirSup.AirFuncPelCurveID == 0) && - (FuelCell(thisFuelCell).AirSup.AirSupRateMode == QuadraticFuncofPel)) { - ShowSevereError("Invalid, " + cAlphaFieldNames(5) + " = " + AlphArray(5)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); - ShowSevereError("Curve name was not found"); - ErrorsFound = true; - } + if (UtilityRoutines::SameString("RecoverBurnerInverterStorage", AlphArray(7))) { + FuelCell(thisFuelCell).AirSup.IntakeRecoveryMode = DataGenerators::RecoverBurnInvertBatt; + } else if (UtilityRoutines::SameString("RecoverAuxiliaryBurner", AlphArray(7))) { + FuelCell(thisFuelCell).AirSup.IntakeRecoveryMode = DataGenerators::RecoverAuxiliaryBurner; + } else if (UtilityRoutines::SameString("RecoverInverterandStorage", AlphArray(7))) { + FuelCell(thisFuelCell).AirSup.IntakeRecoveryMode = DataGenerators::RecoverInverterBatt; + } else if (UtilityRoutines::SameString("RecoverInverter", AlphArray(7))) { + FuelCell(thisFuelCell).AirSup.IntakeRecoveryMode = DataGenerators::RecoverInverter; + } else if (UtilityRoutines::SameString("RecoverElectricalStorage", AlphArray(7))) { + FuelCell(thisFuelCell).AirSup.IntakeRecoveryMode = DataGenerators::RecoverBattery; + } else if (UtilityRoutines::SameString("NoRecovery", AlphArray(7))) { + FuelCell(thisFuelCell).AirSup.IntakeRecoveryMode = DataGenerators::NoRecoveryOnAirIntake; + } else { + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(7) + " = " + AlphArray(7)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); + ErrorsFound = true; + } - FuelCell(thisFuelCell).AirSup.AirTempCoeff = NumArray(3); + if (UtilityRoutines::SameString("AmbientAir", AlphArray(8))) { + FuelCell(thisFuelCell).AirSup.ConstituentMode = DataGenerators::RegularAir; + } else if (UtilityRoutines::SameString("UserDefinedConstituents", AlphArray(8))) { + FuelCell(thisFuelCell).AirSup.ConstituentMode = DataGenerators::UserDefinedConstituents; + } else { + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(8) + " = " + AlphArray(8)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); + ErrorsFound = true; + } - FuelCell(thisFuelCell).AirSup.AirFuncNdotCurveID = GetCurveIndex(AlphArray(6)); - if ((FuelCell(thisFuelCell).AirSup.AirFuncNdotCurveID == 0) && - (FuelCell(thisFuelCell).AirSup.AirSupRateMode == QuadraticFuncofNdot)) { - ShowSevereError("Invalid, " + cAlphaFieldNames(6) + " = " + AlphArray(6)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); - ShowSevereError("Curve name was not found"); - ErrorsFound = true; - } + int NumAirConstit; - if (UtilityRoutines::SameString("RecoverBurnerInverterStorage", AlphArray(7))) { - FuelCell(thisFuelCell).AirSup.IntakeRecoveryMode = RecoverBurnInvertBatt; - } else if (UtilityRoutines::SameString("RecoverAuxiliaryBurner", AlphArray(7))) { - FuelCell(thisFuelCell).AirSup.IntakeRecoveryMode = RecoverAuxiliaryBurner; - } else if (UtilityRoutines::SameString("RecoverInverterandStorage", AlphArray(7))) { - FuelCell(thisFuelCell).AirSup.IntakeRecoveryMode = RecoverInverterBatt; - } else if (UtilityRoutines::SameString("RecoverInverter", AlphArray(7))) { - FuelCell(thisFuelCell).AirSup.IntakeRecoveryMode = RecoverInverter; - } else if (UtilityRoutines::SameString("RecoverElectricalStorage", AlphArray(7))) { - FuelCell(thisFuelCell).AirSup.IntakeRecoveryMode = RecoverBattery; - } else if (UtilityRoutines::SameString("NoRecovery", AlphArray(7))) { - FuelCell(thisFuelCell).AirSup.IntakeRecoveryMode = NoRecoveryOnAirIntake; - } else { - ShowSevereError("Invalid, " + cAlphaFieldNames(7) + " = " + AlphArray(7)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); - ErrorsFound = true; - } + if (FuelCell(thisFuelCell).AirSup.ConstituentMode == DataGenerators::UserDefinedConstituents) { + NumAirConstit = NumArray(4); + FuelCell(thisFuelCell).AirSup.NumConstituents = NumAirConstit; - if (UtilityRoutines::SameString("AmbientAir", AlphArray(8))) { - FuelCell(thisFuelCell).AirSup.ConstituentMode = RegularAir; - } else if (UtilityRoutines::SameString("UserDefinedConstituents", AlphArray(8))) { - FuelCell(thisFuelCell).AirSup.ConstituentMode = UserDefinedConstituents; - } else { - ShowSevereError("Invalid, " + cAlphaFieldNames(8) + " = " + AlphArray(8)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); + if (NumAirConstit > 5) { + ShowSevereError("Invalid " + DataIPShortCuts::cNumericFieldNames(4) + '=' + General::RoundSigDigits(NumArray(4), 2)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); + ShowContinueError("Fuel Cell model not set up for more than 5 air constituents"); ErrorsFound = true; } - if (FuelCell(thisFuelCell).AirSup.ConstituentMode == UserDefinedConstituents) { - NumAirConstit = NumArray(4); - FuelCell(thisFuelCell).AirSup.NumConstituents = NumAirConstit; - - if (NumAirConstit > 5) { - ShowSevereError("Invalid " + cNumericFieldNames(4) + '=' + RoundSigDigits(NumArray(4), 2)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); - ShowContinueError("Fuel Cell model not set up for more than 5 air constituents"); - ErrorsFound = true; - } - - for (ConstitNum = 1; ConstitNum <= NumAirConstit; ++ConstitNum) { - FuelCell(thisFuelCell).AirSup.ConstitName(ConstitNum) = AlphArray(ConstitNum + 8); - FuelCell(thisFuelCell).AirSup.ConstitMolalFract(ConstitNum) = NumArray(ConstitNum + 4); - } + for (int ConstitNum = 1; ConstitNum <= NumAirConstit; ++ConstitNum) { + FuelCell(thisFuelCell).AirSup.ConstitName(ConstitNum) = AlphArray(ConstitNum + 8); + FuelCell(thisFuelCell).AirSup.ConstitMolalFract(ConstitNum) = NumArray(ConstitNum + 4); + } - } else { // regular air - NumAirConstit = 5; + } else { // regular air + NumAirConstit = 5; - FuelCell(thisFuelCell).AirSup.NumConstituents = NumAirConstit; + FuelCell(thisFuelCell).AirSup.NumConstituents = NumAirConstit; - FuelCell(thisFuelCell).AirSup.ConstitName(1) = "Nitrogen"; - FuelCell(thisFuelCell).AirSup.ConstitMolalFract(1) = 0.7728; + FuelCell(thisFuelCell).AirSup.ConstitName(1) = "Nitrogen"; + FuelCell(thisFuelCell).AirSup.ConstitMolalFract(1) = 0.7728; - FuelCell(thisFuelCell).AirSup.ConstitName(2) = "Oxygen"; - FuelCell(thisFuelCell).AirSup.ConstitMolalFract(2) = 0.2073; + FuelCell(thisFuelCell).AirSup.ConstitName(2) = "Oxygen"; + FuelCell(thisFuelCell).AirSup.ConstitMolalFract(2) = 0.2073; - FuelCell(thisFuelCell).AirSup.ConstitName(3) = "Water"; - FuelCell(thisFuelCell).AirSup.ConstitMolalFract(3) = 0.0104; + FuelCell(thisFuelCell).AirSup.ConstitName(3) = "Water"; + FuelCell(thisFuelCell).AirSup.ConstitMolalFract(3) = 0.0104; - FuelCell(thisFuelCell).AirSup.ConstitName(4) = "Argon"; - FuelCell(thisFuelCell).AirSup.ConstitMolalFract(4) = 0.0092; + FuelCell(thisFuelCell).AirSup.ConstitName(4) = "Argon"; + FuelCell(thisFuelCell).AirSup.ConstitMolalFract(4) = 0.0092; - FuelCell(thisFuelCell).AirSup.ConstitName(5) = "CarbonDioxide"; - FuelCell(thisFuelCell).AirSup.ConstitMolalFract(5) = 0.0003; - } + FuelCell(thisFuelCell).AirSup.ConstitName(5) = "CarbonDioxide"; + FuelCell(thisFuelCell).AirSup.ConstitMolalFract(5) = 0.0003; + } - // check for molar fractions summing to 1.0. - if (std::abs(sum(FuelCell(thisFuelCell).AirSup.ConstitMolalFract) - 1.0) > 0.0001) { + // check for molar fractions summing to 1.0. + if (std::abs(sum(FuelCell(thisFuelCell).AirSup.ConstitMolalFract) - 1.0) > 0.0001) { - ShowSevereError(cCurrentModuleObject + " molar fractions do not sum to 1.0"); - ShowContinueError("..Sum was=" + RoundSigDigits(sum(FuelCell(thisFuelCell).AirSup.ConstitMolalFract), 1)); - ShowContinueError("Entered in " + cCurrentModuleObject + " = " + AlphArray(1)); - ErrorsFound = true; - } + ShowSevereError(DataIPShortCuts::cCurrentModuleObject + " molar fractions do not sum to 1.0"); + ShowContinueError("..Sum was=" + General::RoundSigDigits(sum(FuelCell(thisFuelCell).AirSup.ConstitMolalFract), 1)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + " = " + AlphArray(1)); + ErrorsFound = true; + } - // check for other FuelCell using the same Air Supply module and fill - for (otherFuelCell = thisFuelCell + 1; otherFuelCell <= NumFuelCellGenerators; ++otherFuelCell) { - if (UtilityRoutines::SameString(FuelCell(otherFuelCell).AirSup.Name, FuelCell(thisFuelCell).AirSup.Name)) { - FuelCell(otherFuelCell).AirSup = FuelCell(thisFuelCell).AirSup; - } + // check for other FuelCell using the same Air Supply module and fill + for (int otherFuelCell = thisFuelCell + 1; otherFuelCell <= NumFuelCellGenerators; ++otherFuelCell) { + if (UtilityRoutines::SameString(FuelCell(otherFuelCell).AirSup.Name, FuelCell(thisFuelCell).AirSup.Name)) { + FuelCell(otherFuelCell).AirSup = FuelCell(thisFuelCell).AirSup; } - } else { - ShowSevereError("Invalid, " + cAlphaFieldNames(1) + " = " + AlphArray(1)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); - ErrorsFound = true; } + } else { + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(1) + " = " + AlphArray(1)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); + ErrorsFound = true; } + } - for (GeneratorNum = 1; GeneratorNum <= NumFuelCellGenerators; ++GeneratorNum) { - // find molal fraction of oxygen in air supply - thisConstituent = - UtilityRoutines::FindItem("Oxygen", FuelCell(GeneratorNum).AirSup.ConstitName, FuelCell(GeneratorNum).AirSup.NumConstituents); - if (thisConstituent > 0) FuelCell(GeneratorNum).AirSup.O2fraction = FuelCell(GeneratorNum).AirSup.ConstitMolalFract(thisConstituent); - - NumHardCodedConstituents = 14; - - // Loop over air constituents and do one-time setup - for (i = 1; i <= FuelCell(GeneratorNum).AirSup.NumConstituents; ++i) { - - thisName = FuelCell(GeneratorNum).AirSup.ConstitName(i); - - thisGasID = UtilityRoutines::FindItem(thisName, GasPhaseThermoChemistryData, &GasPropertyDataStruct::ConstituentName); + for (int GeneratorNum = 1; GeneratorNum <= NumFuelCellGenerators; ++GeneratorNum) { + // find molar fraction of oxygen in air supply + int thisConstituent = + UtilityRoutines::FindItem("Oxygen", FuelCell(GeneratorNum).AirSup.ConstitName, FuelCell(GeneratorNum).AirSup.NumConstituents); + if (thisConstituent > 0) FuelCell(GeneratorNum).AirSup.O2fraction = FuelCell(GeneratorNum).AirSup.ConstitMolalFract(thisConstituent); - FuelCell(GeneratorNum).AirSup.GasLibID(i) = thisGasID; - } + // Loop over air constituents and do one-time setup + for (int i = 1; i <= FuelCell(GeneratorNum).AirSup.NumConstituents; ++i) { - // set up gas constiuents for product gases - FuelCell(GeneratorNum).FCPM.GasLibID(1) = 1; // Carbon Dioxide - FuelCell(GeneratorNum).FCPM.GasLibID(2) = 2; // Nitrogen - FuelCell(GeneratorNum).FCPM.GasLibID(3) = 3; // Oxygen - FuelCell(GeneratorNum).FCPM.GasLibID(4) = 4; // Water - FuelCell(GeneratorNum).FCPM.GasLibID(5) = 5; // Argon - } + std::string thisName = FuelCell(GeneratorNum).AirSup.ConstitName(i); - cCurrentModuleObject = "Generator:FuelCell:WaterSupply"; - NumFCWaterSups = inputProcessor->getNumObjectsFound(cCurrentModuleObject); + int thisGasID = UtilityRoutines::FindItem( + thisName, DataGenerators::GasPhaseThermoChemistryData, &DataGenerators::GasPropertyDataStruct::ConstituentName); - if (NumFCWaterSups <= 0) { - ShowSevereError("No " + cCurrentModuleObject + " equipment specified in input file"); - ErrorsFound = true; + FuelCell(GeneratorNum).AirSup.GasLibID(i) = thisGasID; } - for (FCWaterSupNum = 1; FCWaterSupNum <= NumFCWaterSups; ++FCWaterSupNum) { - inputProcessor->getObjectItem( - cCurrentModuleObject, FCWaterSupNum, AlphArray, NumAlphas, NumArray, NumNums, IOStat, _, _, cAlphaFieldNames, cNumericFieldNames); - UtilityRoutines::IsNameEmpty(AlphArray(1), cCurrentModuleObject, ErrorsFound); + // set up gas constituents for product gases + FuelCell(GeneratorNum).FCPM.GasLibID(1) = 1; // Carbon Dioxide + FuelCell(GeneratorNum).FCPM.GasLibID(2) = 2; // Nitrogen + FuelCell(GeneratorNum).FCPM.GasLibID(3) = 3; // Oxygen + FuelCell(GeneratorNum).FCPM.GasLibID(4) = 4; // Water + FuelCell(GeneratorNum).FCPM.GasLibID(5) = 5; // Argon + } - thisFuelCell = UtilityRoutines::FindItemInList(AlphArray(1), FuelCell, &FCDataStruct::NameFCWaterSup); - if (thisFuelCell > 0) { - // this is only the first instance of a FuelCell generator using this type of Water supply module - FuelCell(thisFuelCell).WaterSup.Name = AlphArray(1); - FuelCell(thisFuelCell).WaterSup.WaterSupRateCurveID = GetCurveIndex(AlphArray(2)); - if (FuelCell(thisFuelCell).WaterSup.WaterSupRateCurveID == 0) { - ShowSevereError("Invalid, " + cAlphaFieldNames(2) + " = " + AlphArray(2)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); - ShowContinueError("Curve name was not found "); - ErrorsFound = true; - } - FuelCell(thisFuelCell).WaterSup.PmpPowerCurveID = GetCurveIndex(AlphArray(3)); - if (FuelCell(thisFuelCell).WaterSup.PmpPowerCurveID == 0) { - ShowSevereError("Invalid, " + cAlphaFieldNames(3) + " = " + AlphArray(3)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); - ShowContinueError("Curve name was not found "); - ErrorsFound = true; - } - FuelCell(thisFuelCell).WaterSup.PmpPowerLossFactor = NumArray(1); - - //! CR9240? - if (UtilityRoutines::SameString("TemperatureFromAirNode", AlphArray(4))) { - FuelCell(thisFuelCell).WaterSup.WaterTempMode = WaterInReformAirNode; - - FuelCell(thisFuelCell).WaterSup.NodeName = AlphArray(5); - FuelCell(thisFuelCell).WaterSup.NodeNum = GetOnlySingleNode(AlphArray(5), - ErrorsFound, - cCurrentModuleObject, - AlphArray(1), - NodeType_Air, - NodeConnectionType_Sensor, - 1, - ObjectIsNotParent); - - } else if (UtilityRoutines::SameString("TemperatureFromWaterNode", AlphArray(4))) { - FuelCell(thisFuelCell).WaterSup.WaterTempMode = WaterInReformWaterNode; - - FuelCell(thisFuelCell).WaterSup.NodeName = AlphArray(5); - FuelCell(thisFuelCell).WaterSup.NodeNum = GetOnlySingleNode(AlphArray(5), - ErrorsFound, - cCurrentModuleObject, - AlphArray(1), - NodeType_Water, - NodeConnectionType_Sensor, - 1, - ObjectIsNotParent); - - } else if (UtilityRoutines::SameString("MainsWaterTemperature", AlphArray(4))) { - FuelCell(thisFuelCell).WaterSup.WaterTempMode = WaterInReformMains; - - } else if (UtilityRoutines::SameString("TemperatureFromSchedule", AlphArray(4))) { - FuelCell(thisFuelCell).WaterSup.WaterTempMode = WaterInReformSchedule; - } else { - ShowSevereError("Invalid, " + cAlphaFieldNames(4) + " = " + AlphArray(4)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); - ErrorsFound = true; - } + DataIPShortCuts::cCurrentModuleObject = "Generator:FuelCell:WaterSupply"; + int NumFCWaterSups = inputProcessor->getNumObjectsFound(DataIPShortCuts::cCurrentModuleObject); - FuelCell(thisFuelCell).WaterSup.SchedNum = GetScheduleIndex(AlphArray(6)); - if ((FuelCell(thisFuelCell).WaterSup.SchedNum == 0) && (FuelCell(thisFuelCell).WaterSup.WaterTempMode == WaterInReformSchedule)) { - ShowSevereError("Invalid, " + cAlphaFieldNames(6) + " = " + AlphArray(6)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); - ShowContinueError("Schedule was not found"); - ErrorsFound = true; - } + if (NumFCWaterSups <= 0) { + ShowSevereError("No " + DataIPShortCuts::cCurrentModuleObject + " equipment specified in input file"); + ErrorsFound = true; + } - // check for other FuelCell using the same Water Supply module and fill - for (otherFuelCell = thisFuelCell + 1; otherFuelCell <= NumFuelCellGenerators; ++otherFuelCell) { - if (UtilityRoutines::SameString(FuelCell(otherFuelCell).WaterSup.Name, FuelCell(thisFuelCell).WaterSup.Name)) { - FuelCell(otherFuelCell).WaterSup = FuelCell(thisFuelCell).WaterSup; - } - } + for (int FCWaterSupNum = 1; FCWaterSupNum <= NumFCWaterSups; ++FCWaterSupNum) { + inputProcessor->getObjectItem(DataIPShortCuts::cCurrentModuleObject, + FCWaterSupNum, + AlphArray, + NumAlphas, + NumArray, + NumNums, + IOStat, + _, + _, + DataIPShortCuts::cAlphaFieldNames, + DataIPShortCuts::cNumericFieldNames); + UtilityRoutines::IsNameEmpty(AlphArray(1), DataIPShortCuts::cCurrentModuleObject, ErrorsFound); + + int thisFuelCell = UtilityRoutines::FindItemInList(AlphArray(1), FuelCell, &FCDataStruct::NameFCWaterSup); + + if (thisFuelCell > 0) { + // this is only the first instance of a FuelCell generator using this type of Water supply module + FuelCell(thisFuelCell).WaterSup.Name = AlphArray(1); + FuelCell(thisFuelCell).WaterSup.WaterSupRateCurveID = CurveManager::GetCurveIndex(AlphArray(2)); + if (FuelCell(thisFuelCell).WaterSup.WaterSupRateCurveID == 0) { + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(2) + " = " + AlphArray(2)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); + ShowContinueError("Curve name was not found "); + ErrorsFound = true; + } + FuelCell(thisFuelCell).WaterSup.PmpPowerCurveID = CurveManager::GetCurveIndex(AlphArray(3)); + if (FuelCell(thisFuelCell).WaterSup.PmpPowerCurveID == 0) { + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(3) + " = " + AlphArray(3)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); + ShowContinueError("Curve name was not found "); + ErrorsFound = true; + } + FuelCell(thisFuelCell).WaterSup.PmpPowerLossFactor = NumArray(1); + + if (UtilityRoutines::SameString("TemperatureFromAirNode", AlphArray(4))) { + FuelCell(thisFuelCell).WaterSup.WaterTempMode = DataGenerators::WaterInReformAirNode; + + FuelCell(thisFuelCell).WaterSup.NodeName = AlphArray(5); + FuelCell(thisFuelCell).WaterSup.NodeNum = NodeInputManager::GetOnlySingleNode(AlphArray(5), + ErrorsFound, + DataIPShortCuts::cCurrentModuleObject, + AlphArray(1), + DataLoopNode::NodeType_Air, + DataLoopNode::NodeConnectionType_Sensor, + 1, + DataLoopNode::ObjectIsNotParent); + + } else if (UtilityRoutines::SameString("TemperatureFromWaterNode", AlphArray(4))) { + FuelCell(thisFuelCell).WaterSup.WaterTempMode = DataGenerators::WaterInReformWaterNode; + + FuelCell(thisFuelCell).WaterSup.NodeName = AlphArray(5); + FuelCell(thisFuelCell).WaterSup.NodeNum = NodeInputManager::GetOnlySingleNode(AlphArray(5), + ErrorsFound, + DataIPShortCuts::cCurrentModuleObject, + AlphArray(1), + DataLoopNode::NodeType_Water, + DataLoopNode::NodeConnectionType_Sensor, + 1, + DataLoopNode::ObjectIsNotParent); + + } else if (UtilityRoutines::SameString("MainsWaterTemperature", AlphArray(4))) { + FuelCell(thisFuelCell).WaterSup.WaterTempMode = DataGenerators::WaterInReformMains; + + } else if (UtilityRoutines::SameString("TemperatureFromSchedule", AlphArray(4))) { + FuelCell(thisFuelCell).WaterSup.WaterTempMode = DataGenerators::WaterInReformSchedule; } else { - ShowSevereError("Invalid, " + cAlphaFieldNames(1) + " = " + AlphArray(1)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(4) + " = " + AlphArray(4)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); ErrorsFound = true; } - } - cCurrentModuleObject = "Generator:FuelCell:AuxiliaryHeater"; - NumFuelCellAuxilHeaters = inputProcessor->getNumObjectsFound(cCurrentModuleObject); + FuelCell(thisFuelCell).WaterSup.SchedNum = ScheduleManager::GetScheduleIndex(AlphArray(6)); + if ((FuelCell(thisFuelCell).WaterSup.SchedNum == 0) && + (FuelCell(thisFuelCell).WaterSup.WaterTempMode == DataGenerators::WaterInReformSchedule)) { + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(6) + " = " + AlphArray(6)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); + ShowContinueError("Schedule was not found"); + ErrorsFound = true; + } - if (NumFuelCellAuxilHeaters <= 0) { - ShowSevereError("No " + cCurrentModuleObject + " equipment specified in input file"); + // check for other FuelCell using the same Water Supply module and fill + for (int otherFuelCell = thisFuelCell + 1; otherFuelCell <= NumFuelCellGenerators; ++otherFuelCell) { + if (UtilityRoutines::SameString(FuelCell(otherFuelCell).WaterSup.Name, FuelCell(thisFuelCell).WaterSup.Name)) { + FuelCell(otherFuelCell).WaterSup = FuelCell(thisFuelCell).WaterSup; + } + } + } else { + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(1) + " = " + AlphArray(1)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); ErrorsFound = true; } + } - for (FCAuxHeatNum = 1; FCAuxHeatNum <= NumFuelCellAuxilHeaters; ++FCAuxHeatNum) { - inputProcessor->getObjectItem( - cCurrentModuleObject, FCAuxHeatNum, AlphArray, NumAlphas, NumArray, NumNums, IOStat, _, _, cAlphaFieldNames, cNumericFieldNames); - UtilityRoutines::IsNameEmpty(AlphArray(1), cCurrentModuleObject, ErrorsFound); + DataIPShortCuts::cCurrentModuleObject = "Generator:FuelCell:AuxiliaryHeater"; + int NumFuelCellAuxilHeaters = inputProcessor->getNumObjectsFound(DataIPShortCuts::cCurrentModuleObject); - thisFuelCell = UtilityRoutines::FindItemInList(AlphArray(1), FuelCell, &FCDataStruct::NameFCAuxilHeat); - if (thisFuelCell > 0) { - FuelCell(thisFuelCell).AuxilHeat.Name = AlphArray(1); + if (NumFuelCellAuxilHeaters <= 0) { + ShowSevereError("No " + DataIPShortCuts::cCurrentModuleObject + " equipment specified in input file"); + ErrorsFound = true; + } - FuelCell(thisFuelCell).AuxilHeat.ExcessAirRAT = NumArray(1); - FuelCell(thisFuelCell).AuxilHeat.ANC0 = NumArray(2); - FuelCell(thisFuelCell).AuxilHeat.ANC1 = NumArray(3); - FuelCell(thisFuelCell).AuxilHeat.UASkin = NumArray(4); + for (int FCAuxHeatNum = 1; FCAuxHeatNum <= NumFuelCellAuxilHeaters; ++FCAuxHeatNum) { + inputProcessor->getObjectItem(DataIPShortCuts::cCurrentModuleObject, + FCAuxHeatNum, + AlphArray, + NumAlphas, + NumArray, + NumNums, + IOStat, + _, + _, + DataIPShortCuts::cAlphaFieldNames, + DataIPShortCuts::cNumericFieldNames); + UtilityRoutines::IsNameEmpty(AlphArray(1), DataIPShortCuts::cCurrentModuleObject, ErrorsFound); - if (UtilityRoutines::SameString("SurroundingZone", AlphArray(2))) { - FuelCell(thisFuelCell).AuxilHeat.SkinLossDestination = SurroundingZone; - } else if (UtilityRoutines::SameString("AirInletForFuelCell", AlphArray(2))) { - FuelCell(thisFuelCell).AuxilHeat.SkinLossDestination = AirInletForFC; - } else { - ShowSevereError("Invalid, " + cAlphaFieldNames(2) + " = " + AlphArray(2)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); - ErrorsFound = true; - } + int thisFuelCell = UtilityRoutines::FindItemInList(AlphArray(1), FuelCell, &FCDataStruct::NameFCAuxilHeat); - FuelCell(thisFuelCell).AuxilHeat.ZoneName = AlphArray(3); - FuelCell(thisFuelCell).AuxilHeat.ZoneID = UtilityRoutines::FindItemInList(AlphArray(3), Zone); - if ((FuelCell(thisFuelCell).AuxilHeat.ZoneID == 0) && (FuelCell(thisFuelCell).AuxilHeat.SkinLossDestination == SurroundingZone)) { - ShowSevereError("Invalid, " + cAlphaFieldNames(3) + " = " + AlphArray(3)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); - ShowContinueError("Zone name was not found "); - ErrorsFound = true; - } - FuelCell(thisFuelCell).AuxilHeat.MaxPowerW = NumArray(5); - FuelCell(thisFuelCell).AuxilHeat.MinPowerW = NumArray(6); - FuelCell(thisFuelCell).AuxilHeat.MaxPowerkmolperSec = NumArray(7); - FuelCell(thisFuelCell).AuxilHeat.MinPowerkmolperSec = NumArray(8); + if (thisFuelCell > 0) { + FuelCell(thisFuelCell).AuxilHeat.Name = AlphArray(1); - // TODO finish Auxiliary heater + FuelCell(thisFuelCell).AuxilHeat.ExcessAirRAT = NumArray(1); + FuelCell(thisFuelCell).AuxilHeat.ANC0 = NumArray(2); + FuelCell(thisFuelCell).AuxilHeat.ANC1 = NumArray(3); + FuelCell(thisFuelCell).AuxilHeat.UASkin = NumArray(4); - // check for other FuelCell using the same Auxiliary Heating module and fill - for (otherFuelCell = thisFuelCell + 1; otherFuelCell <= NumFuelCellGenerators; ++otherFuelCell) { - if (UtilityRoutines::SameString(FuelCell(otherFuelCell).AuxilHeat.Name, FuelCell(thisFuelCell).AuxilHeat.Name)) { - FuelCell(otherFuelCell).AuxilHeat = FuelCell(thisFuelCell).AuxilHeat; - } - } + if (UtilityRoutines::SameString("SurroundingZone", AlphArray(2))) { + FuelCell(thisFuelCell).AuxilHeat.SkinLossDestination = DataGenerators::SurroundingZone; + } else if (UtilityRoutines::SameString("AirInletForFuelCell", AlphArray(2))) { + FuelCell(thisFuelCell).AuxilHeat.SkinLossDestination = DataGenerators::AirInletForFC; } else { - ShowSevereError("Invalid, " + cAlphaFieldNames(1) + " = " + AlphArray(1)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(2) + " = " + AlphArray(2)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); ErrorsFound = true; } - } - // exhaust gas heat exchanger - cCurrentModuleObject = "Generator:FuelCell:ExhaustGasToWaterHeatExchanger"; - NumFCExhaustGasHXs = inputProcessor->getNumObjectsFound(cCurrentModuleObject); - if (NumFCExhaustGasHXs <= 0) { - ShowWarningError("No " + cCurrentModuleObject + " equipment specified in input file"); - ShowContinueError("Fuel Cell model requires an " + cCurrentModuleObject + " object"); + FuelCell(thisFuelCell).AuxilHeat.ZoneName = AlphArray(3); + FuelCell(thisFuelCell).AuxilHeat.ZoneID = UtilityRoutines::FindItemInList(AlphArray(3), DataHeatBalance::Zone); + if ((FuelCell(thisFuelCell).AuxilHeat.ZoneID == 0) && + (FuelCell(thisFuelCell).AuxilHeat.SkinLossDestination == DataGenerators::SurroundingZone)) { + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(3) + " = " + AlphArray(3)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); + ShowContinueError("Zone name was not found "); + ErrorsFound = true; + } + FuelCell(thisFuelCell).AuxilHeat.MaxPowerW = NumArray(5); + FuelCell(thisFuelCell).AuxilHeat.MinPowerW = NumArray(6); + FuelCell(thisFuelCell).AuxilHeat.MaxPowerkmolperSec = NumArray(7); + FuelCell(thisFuelCell).AuxilHeat.MinPowerkmolperSec = NumArray(8); + + // TODO finish Auxiliary heater + + // check for other FuelCell using the same Auxiliary Heating module and fill + for (int otherFuelCell = thisFuelCell + 1; otherFuelCell <= NumFuelCellGenerators; ++otherFuelCell) { + if (UtilityRoutines::SameString(FuelCell(otherFuelCell).AuxilHeat.Name, FuelCell(thisFuelCell).AuxilHeat.Name)) { + FuelCell(otherFuelCell).AuxilHeat = FuelCell(thisFuelCell).AuxilHeat; + } + } + } else { + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(1) + " = " + AlphArray(1)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); ErrorsFound = true; } + } - for (FCHXNum = 1; FCHXNum <= NumFCExhaustGasHXs; ++FCHXNum) { - inputProcessor->getObjectItem( - cCurrentModuleObject, FCHXNum, AlphArray, NumAlphas, NumArray, NumNums, IOStat, _, _, cAlphaFieldNames, cNumericFieldNames); - UtilityRoutines::IsNameEmpty(AlphArray(1), cCurrentModuleObject, ErrorsFound); + // exhaust gas heat exchanger + DataIPShortCuts::cCurrentModuleObject = "Generator:FuelCell:ExhaustGasToWaterHeatExchanger"; + int NumFCExhaustGasHXs = inputProcessor->getNumObjectsFound(DataIPShortCuts::cCurrentModuleObject); + if (NumFCExhaustGasHXs <= 0) { + ShowWarningError("No " + DataIPShortCuts::cCurrentModuleObject + " equipment specified in input file"); + ShowContinueError("Fuel Cell model requires an " + DataIPShortCuts::cCurrentModuleObject + " object"); + ErrorsFound = true; + } - thisFuelCell = UtilityRoutines::FindItemInList(AlphArray(1), FuelCell, &FCDataStruct::NameExhaustHX); - if (thisFuelCell > 0) { - FuelCell(thisFuelCell).ExhaustHX.Name = AlphArray(1); - FuelCell(thisFuelCell).ExhaustHX.WaterInNodeName = AlphArray(2); - FuelCell(thisFuelCell).ExhaustHX.WaterOutNodeName = AlphArray(3); - // find node ids for water path - FuelCell(thisFuelCell).ExhaustHX.WaterInNode = GetOnlySingleNode(AlphArray(2), - ErrorsFound, - cCurrentModuleObject, - AlphArray(1), - NodeType_Water, - NodeConnectionType_Inlet, - 1, - ObjectIsNotParent); - FuelCell(thisFuelCell).ExhaustHX.WaterOutNode = GetOnlySingleNode(AlphArray(3), - ErrorsFound, - cCurrentModuleObject, - AlphArray(1), - NodeType_Water, - NodeConnectionType_Outlet, - 1, - ObjectIsNotParent); - TestCompSet(cCurrentModuleObject, AlphArray(1), AlphArray(2), AlphArray(3), "Heat Recovery Nodes"); - - // CR9240 - FuelCell(thisFuelCell).ExhaustHX.ExhaustOutNodeName = AlphArray(4); - FuelCell(thisFuelCell).ExhaustHX.ExhaustOutNode = GetOnlySingleNode( - AlphArray(4), ErrorsFound, cCurrentModuleObject, AlphArray(1), NodeType_Air, NodeConnectionType_Outlet, 2, ObjectIsNotParent); - - if (UtilityRoutines::SameString("FixedEffectiveness", AlphArray(5))) { - FuelCell(thisFuelCell).ExhaustHX.HXmodelMode = FixedEffectiveness; - } else if (UtilityRoutines::SameString("EmpiricalUAeff", AlphArray(5))) { - FuelCell(thisFuelCell).ExhaustHX.HXmodelMode = LMTDempiricalUAeff; - } else if (UtilityRoutines::SameString("FundementalUAeff", AlphArray(5))) { - FuelCell(thisFuelCell).ExhaustHX.HXmodelMode = LMTDfundementalUAeff; - } else if (UtilityRoutines::SameString("CONDENSING", AlphArray(5))) { - FuelCell(thisFuelCell).ExhaustHX.HXmodelMode = Condensing; - } else { - ShowSevereError("Invalid, " + cAlphaFieldNames(5) + " = " + AlphArray(5)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); - ErrorsFound = true; - } - FuelCell(thisFuelCell).ExhaustHX.WaterVolumeFlowMax = NumArray(1); - FuelCell(thisFuelCell).ExhaustHX.HXEffect = NumArray(2); - FuelCell(thisFuelCell).ExhaustHX.hxs0 = NumArray(3); - FuelCell(thisFuelCell).ExhaustHX.hxs1 = NumArray(4); - FuelCell(thisFuelCell).ExhaustHX.hxs2 = NumArray(5); - FuelCell(thisFuelCell).ExhaustHX.hxs3 = NumArray(6); - FuelCell(thisFuelCell).ExhaustHX.hxs4 = NumArray(7); - FuelCell(thisFuelCell).ExhaustHX.h0gas = NumArray(8); - FuelCell(thisFuelCell).ExhaustHX.NdotGasRef = NumArray(9); - FuelCell(thisFuelCell).ExhaustHX.nCoeff = NumArray(10); - FuelCell(thisFuelCell).ExhaustHX.AreaGas = NumArray(11); - FuelCell(thisFuelCell).ExhaustHX.h0Water = NumArray(12); - FuelCell(thisFuelCell).ExhaustHX.NdotWaterRef = NumArray(13); - FuelCell(thisFuelCell).ExhaustHX.mCoeff = NumArray(14); - FuelCell(thisFuelCell).ExhaustHX.AreaWater = NumArray(15); - FuelCell(thisFuelCell).ExhaustHX.Fadjust = NumArray(16); - FuelCell(thisFuelCell).ExhaustHX.l1Coeff = NumArray(17); - FuelCell(thisFuelCell).ExhaustHX.l2Coeff = NumArray(18); - FuelCell(thisFuelCell).ExhaustHX.CondensationThresholdTemp = NumArray(19); - - // store cooling water volume flow rate for autosizing system - RegisterPlantCompDesignFlow(FuelCell(thisFuelCell).ExhaustHX.WaterInNode, FuelCell(thisFuelCell).ExhaustHX.WaterVolumeFlowMax); + for (int FCHXNum = 1; FCHXNum <= NumFCExhaustGasHXs; ++FCHXNum) { + inputProcessor->getObjectItem(DataIPShortCuts::cCurrentModuleObject, + FCHXNum, + AlphArray, + NumAlphas, + NumArray, + NumNums, + IOStat, + _, + _, + DataIPShortCuts::cAlphaFieldNames, + DataIPShortCuts::cNumericFieldNames); + UtilityRoutines::IsNameEmpty(AlphArray(1), DataIPShortCuts::cCurrentModuleObject, ErrorsFound); + + int thisFuelCell = UtilityRoutines::FindItemInList(AlphArray(1), FuelCell, &FCDataStruct::NameExhaustHX); + + if (thisFuelCell > 0) { + FuelCell(thisFuelCell).ExhaustHX.Name = AlphArray(1); + FuelCell(thisFuelCell).ExhaustHX.WaterInNodeName = AlphArray(2); + FuelCell(thisFuelCell).ExhaustHX.WaterOutNodeName = AlphArray(3); + // find node ids for water path + FuelCell(thisFuelCell).ExhaustHX.WaterInNode = NodeInputManager::GetOnlySingleNode(AlphArray(2), + ErrorsFound, + DataIPShortCuts::cCurrentModuleObject, + AlphArray(1), + DataLoopNode::NodeType_Water, + DataLoopNode::NodeConnectionType_Inlet, + 1, + DataLoopNode::ObjectIsNotParent); + FuelCell(thisFuelCell).ExhaustHX.WaterOutNode = NodeInputManager::GetOnlySingleNode(AlphArray(3), + ErrorsFound, + DataIPShortCuts::cCurrentModuleObject, + AlphArray(1), + DataLoopNode::NodeType_Water, + DataLoopNode::NodeConnectionType_Outlet, + 1, + DataLoopNode::ObjectIsNotParent); + BranchNodeConnections::TestCompSet( + DataIPShortCuts::cCurrentModuleObject, AlphArray(1), AlphArray(2), AlphArray(3), "Heat Recovery Nodes"); + + FuelCell(thisFuelCell).ExhaustHX.ExhaustOutNodeName = AlphArray(4); + FuelCell(thisFuelCell).ExhaustHX.ExhaustOutNode = NodeInputManager::GetOnlySingleNode(AlphArray(4), + ErrorsFound, + DataIPShortCuts::cCurrentModuleObject, + AlphArray(1), + DataLoopNode::NodeType_Air, + DataLoopNode::NodeConnectionType_Outlet, + 2, + DataLoopNode::ObjectIsNotParent); + + if (UtilityRoutines::SameString("FixedEffectiveness", AlphArray(5))) { + FuelCell(thisFuelCell).ExhaustHX.HXmodelMode = DataGenerators::FixedEffectiveness; + } else if (UtilityRoutines::SameString("EmpiricalUAeff", AlphArray(5))) { + FuelCell(thisFuelCell).ExhaustHX.HXmodelMode = DataGenerators::LMTDempiricalUAeff; + } else if (UtilityRoutines::SameString("FundementalUAeff", AlphArray(5))) { + FuelCell(thisFuelCell).ExhaustHX.HXmodelMode = DataGenerators::LMTDfundementalUAeff; + } else if (UtilityRoutines::SameString("CONDENSING", AlphArray(5))) { + FuelCell(thisFuelCell).ExhaustHX.HXmodelMode = DataGenerators::Condensing; } else { - ShowSevereError("Invalid, " + cAlphaFieldNames(1) + " = " + AlphArray(1)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(5) + " = " + AlphArray(5)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); ErrorsFound = true; } + FuelCell(thisFuelCell).ExhaustHX.WaterVolumeFlowMax = NumArray(1); + FuelCell(thisFuelCell).ExhaustHX.HXEffect = NumArray(2); + FuelCell(thisFuelCell).ExhaustHX.hxs0 = NumArray(3); + FuelCell(thisFuelCell).ExhaustHX.hxs1 = NumArray(4); + FuelCell(thisFuelCell).ExhaustHX.hxs2 = NumArray(5); + FuelCell(thisFuelCell).ExhaustHX.hxs3 = NumArray(6); + FuelCell(thisFuelCell).ExhaustHX.hxs4 = NumArray(7); + FuelCell(thisFuelCell).ExhaustHX.h0gas = NumArray(8); + FuelCell(thisFuelCell).ExhaustHX.NdotGasRef = NumArray(9); + FuelCell(thisFuelCell).ExhaustHX.nCoeff = NumArray(10); + FuelCell(thisFuelCell).ExhaustHX.AreaGas = NumArray(11); + FuelCell(thisFuelCell).ExhaustHX.h0Water = NumArray(12); + FuelCell(thisFuelCell).ExhaustHX.NdotWaterRef = NumArray(13); + FuelCell(thisFuelCell).ExhaustHX.mCoeff = NumArray(14); + FuelCell(thisFuelCell).ExhaustHX.AreaWater = NumArray(15); + FuelCell(thisFuelCell).ExhaustHX.Fadjust = NumArray(16); + FuelCell(thisFuelCell).ExhaustHX.l1Coeff = NumArray(17); + FuelCell(thisFuelCell).ExhaustHX.l2Coeff = NumArray(18); + FuelCell(thisFuelCell).ExhaustHX.CondensationThresholdTemp = NumArray(19); + + // store cooling water volume flow rate for autosizing system + PlantUtilities::RegisterPlantCompDesignFlow(FuelCell(thisFuelCell).ExhaustHX.WaterInNode, + FuelCell(thisFuelCell).ExhaustHX.WaterVolumeFlowMax); + } else { + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(1) + " = " + AlphArray(1)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); + ErrorsFound = true; } + } - cCurrentModuleObject = "Generator:FuelCell:ElectricalStorage"; - NumFCElecStorageUnits = inputProcessor->getNumObjectsFound(cCurrentModuleObject); + DataIPShortCuts::cCurrentModuleObject = "Generator:FuelCell:ElectricalStorage"; + int NumFCElecStorageUnits = inputProcessor->getNumObjectsFound(DataIPShortCuts::cCurrentModuleObject); - if (NumFCElecStorageUnits <= 0) { - ShowWarningError("No " + cCurrentModuleObject + " equipment specified in input file"); - ShowContinueError("Fuel Cell model requires an " + cCurrentModuleObject + " object"); - ErrorsFound = true; - } + if (NumFCElecStorageUnits <= 0) { + ShowWarningError("No " + DataIPShortCuts::cCurrentModuleObject + " equipment specified in input file"); + ShowContinueError("Fuel Cell model requires an " + DataIPShortCuts::cCurrentModuleObject + " object"); + ErrorsFound = true; + } - for (StorageNum = 1; StorageNum <= NumFCElecStorageUnits; ++StorageNum) { - inputProcessor->getObjectItem( - cCurrentModuleObject, StorageNum, AlphArray, NumAlphas, NumArray, NumNums, IOStat, _, _, cAlphaFieldNames, cNumericFieldNames); - UtilityRoutines::IsNameEmpty(AlphArray(1), cCurrentModuleObject, ErrorsFound); + for (int StorageNum = 1; StorageNum <= NumFCElecStorageUnits; ++StorageNum) { + inputProcessor->getObjectItem(DataIPShortCuts::cCurrentModuleObject, + StorageNum, + AlphArray, + NumAlphas, + NumArray, + NumNums, + IOStat, + _, + _, + DataIPShortCuts::cAlphaFieldNames, + DataIPShortCuts::cNumericFieldNames); + UtilityRoutines::IsNameEmpty(AlphArray(1), DataIPShortCuts::cCurrentModuleObject, ErrorsFound); - thisFuelCell = UtilityRoutines::FindItemInList(AlphArray(1), FuelCell, &FCDataStruct::NameElecStorage); - if (thisFuelCell > 0) { - FuelCell(thisFuelCell).ElecStorage.Name = AlphArray(1); + int thisFuelCell = UtilityRoutines::FindItemInList(AlphArray(1), FuelCell, &FCDataStruct::NameElecStorage); - if (UtilityRoutines::SameString(AlphArray(2), "SimpleEfficiencyWithConstraints")) { - FuelCell(thisFuelCell).ElecStorage.StorageModelMode = SimpleEffConstraints; - } else { - ShowSevereError("Invalid, " + cAlphaFieldNames(2) + " = " + AlphArray(2)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); - ErrorsFound = true; - } - FuelCell(thisFuelCell).ElecStorage.EnergeticEfficCharge = NumArray(1); - FuelCell(thisFuelCell).ElecStorage.EnergeticEfficDischarge = NumArray(2); - FuelCell(thisFuelCell).ElecStorage.NominalEnergyCapacity = NumArray(3); - FuelCell(thisFuelCell).ElecStorage.MaxPowerDraw = NumArray(4); - FuelCell(thisFuelCell).ElecStorage.MaxPowerStore = NumArray(5); - FuelCell(thisFuelCell).ElecStorage.StartingEnergyStored = NumArray(6); - - // check for other FuelCell using the same Electrical Storage and fill - for (otherFuelCell = thisFuelCell + 1; otherFuelCell <= NumFuelCellGenerators; ++otherFuelCell) { - if (UtilityRoutines::SameString(FuelCell(otherFuelCell).ElecStorage.Name, FuelCell(thisFuelCell).ElecStorage.Name)) { - FuelCell(otherFuelCell).ElecStorage = FuelCell(thisFuelCell).ElecStorage; - } - } + if (thisFuelCell > 0) { + FuelCell(thisFuelCell).ElecStorage.Name = AlphArray(1); + + if (UtilityRoutines::SameString(AlphArray(2), "SimpleEfficiencyWithConstraints")) { + FuelCell(thisFuelCell).ElecStorage.StorageModelMode = DataGenerators::SimpleEffConstraints; } else { - ShowSevereError("Invalid, " + cAlphaFieldNames(1) + " = " + AlphArray(1)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(2) + " = " + AlphArray(2)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); ErrorsFound = true; } - } - - cCurrentModuleObject = "Generator:FuelCell:Inverter"; - NumFCPowerCondUnits = inputProcessor->getNumObjectsFound(cCurrentModuleObject); - - if (NumFCPowerCondUnits <= 0) { - ShowWarningError("No " + cCurrentModuleObject + " equipment specified in input file"); - ShowContinueError("Fuel Cell model requires a " + cCurrentModuleObject + " object"); - + FuelCell(thisFuelCell).ElecStorage.EnergeticEfficCharge = NumArray(1); + FuelCell(thisFuelCell).ElecStorage.EnergeticEfficDischarge = NumArray(2); + FuelCell(thisFuelCell).ElecStorage.NominalEnergyCapacity = NumArray(3); + FuelCell(thisFuelCell).ElecStorage.MaxPowerDraw = NumArray(4); + FuelCell(thisFuelCell).ElecStorage.MaxPowerStore = NumArray(5); + FuelCell(thisFuelCell).ElecStorage.StartingEnergyStored = NumArray(6); + + // check for other FuelCell using the same Electrical Storage and fill + for (int otherFuelCell = thisFuelCell + 1; otherFuelCell <= NumFuelCellGenerators; ++otherFuelCell) { + if (UtilityRoutines::SameString(FuelCell(otherFuelCell).ElecStorage.Name, FuelCell(thisFuelCell).ElecStorage.Name)) { + FuelCell(otherFuelCell).ElecStorage = FuelCell(thisFuelCell).ElecStorage; + } + } + } else { + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(1) + " = " + AlphArray(1)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); ErrorsFound = true; } + } - for (FCPCUNum = 1; FCPCUNum <= NumFCPowerCondUnits; ++FCPCUNum) { - inputProcessor->getObjectItem( - cCurrentModuleObject, FCPCUNum, AlphArray, NumAlphas, NumArray, NumNums, IOStat, _, _, cAlphaFieldNames, cNumericFieldNames); - UtilityRoutines::IsNameEmpty(AlphArray(1), cCurrentModuleObject, ErrorsFound); + DataIPShortCuts::cCurrentModuleObject = "Generator:FuelCell:Inverter"; + int NumFCPowerCondUnits = inputProcessor->getNumObjectsFound(DataIPShortCuts::cCurrentModuleObject); - thisFuelCell = UtilityRoutines::FindItemInList(AlphArray(1), FuelCell, &FCDataStruct::NameInverter); - if (thisFuelCell > 0) { - FuelCell(thisFuelCell).Inverter.Name = AlphArray(1); + if (NumFCPowerCondUnits <= 0) { + ShowWarningError("No " + DataIPShortCuts::cCurrentModuleObject + " equipment specified in input file"); + ShowContinueError("Fuel Cell model requires a " + DataIPShortCuts::cCurrentModuleObject + " object"); - if (UtilityRoutines::SameString(AlphArray(2), "QUADRATIC")) FuelCell(thisFuelCell).Inverter.EffMode = InverterEffQuadratic; - if (UtilityRoutines::SameString(AlphArray(2), "Constant")) FuelCell(thisFuelCell).Inverter.EffMode = InverterEffConstant; - if (FuelCell(thisFuelCell).Inverter.EffMode == 0) { - ShowSevereError("Invalid, " + cAlphaFieldNames(2) + " = " + AlphArray(2)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); - ErrorsFound = true; - } + ErrorsFound = true; + } - FuelCell(thisFuelCell).Inverter.ConstEff = NumArray(1); + for (int FCPCUNum = 1; FCPCUNum <= NumFCPowerCondUnits; ++FCPCUNum) { + inputProcessor->getObjectItem(DataIPShortCuts::cCurrentModuleObject, + FCPCUNum, + AlphArray, + NumAlphas, + NumArray, + NumNums, + IOStat, + _, + _, + DataIPShortCuts::cAlphaFieldNames, + DataIPShortCuts::cNumericFieldNames); + UtilityRoutines::IsNameEmpty(AlphArray(1), DataIPShortCuts::cCurrentModuleObject, ErrorsFound); + + int thisFuelCell = UtilityRoutines::FindItemInList(AlphArray(1), FuelCell, &FCDataStruct::NameInverter); + + if (thisFuelCell > 0) { + FuelCell(thisFuelCell).Inverter.Name = AlphArray(1); + + if (UtilityRoutines::SameString(AlphArray(2), "QUADRATIC")) + FuelCell(thisFuelCell).Inverter.EffMode = DataGenerators::InverterEffQuadratic; + if (UtilityRoutines::SameString(AlphArray(2), "Constant")) + FuelCell(thisFuelCell).Inverter.EffMode = DataGenerators::InverterEffConstant; + if (FuelCell(thisFuelCell).Inverter.EffMode == 0) { + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(2) + " = " + AlphArray(2)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); + ErrorsFound = true; + } - FuelCell(thisFuelCell).Inverter.EffQuadraticCurveID = GetCurveIndex(AlphArray(3)); - if ((FuelCell(thisFuelCell).Inverter.EffQuadraticCurveID == 0) && - (FuelCell(thisFuelCell).Inverter.EffMode == InverterEffQuadratic)) { - ShowSevereError("Invalid, " + cAlphaFieldNames(3) + " = " + AlphArray(3)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); - ShowContinueError("Curve was not found "); - ErrorsFound = true; - } + FuelCell(thisFuelCell).Inverter.ConstEff = NumArray(1); - // check for other FuelCell using the same Inverter and fill - for (otherFuelCell = thisFuelCell + 1; otherFuelCell <= NumFuelCellGenerators; ++otherFuelCell) { - if (UtilityRoutines::SameString(FuelCell(otherFuelCell).Inverter.Name, FuelCell(thisFuelCell).Inverter.Name)) { - FuelCell(otherFuelCell).Inverter = FuelCell(thisFuelCell).Inverter; - } - } - } else { - ShowSevereError("Invalid, " + cAlphaFieldNames(1) + " = " + AlphArray(1)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); + FuelCell(thisFuelCell).Inverter.EffQuadraticCurveID = CurveManager::GetCurveIndex(AlphArray(3)); + if ((FuelCell(thisFuelCell).Inverter.EffQuadraticCurveID == 0) && + (FuelCell(thisFuelCell).Inverter.EffMode == DataGenerators::InverterEffQuadratic)) { + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(3) + " = " + AlphArray(3)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); + ShowContinueError("Curve was not found "); ErrorsFound = true; } - } - - cCurrentModuleObject = "Generator:FuelCell:StackCooler"; - NumFCStackCoolers = inputProcessor->getNumObjectsFound(cCurrentModuleObject); - - if (NumFCStackCoolers > 0) { // get stack cooler input data - for (FCScoolNum = 1; FCScoolNum <= NumFCStackCoolers; ++FCScoolNum) { - inputProcessor->getObjectItem(cCurrentModuleObject, - FCScoolNum, - AlphArray, - NumAlphas, - NumArray, - NumNums, - IOStat, - _, - _, - cAlphaFieldNames, - cNumericFieldNames); - UtilityRoutines::IsNameEmpty(AlphArray(1), cCurrentModuleObject, ErrorsFound); - - thisFuelCell = UtilityRoutines::FindItemInList(AlphArray(1), FuelCell, &FCDataStruct::NameStackCooler); - if (thisFuelCell > 0) { - FuelCell(thisFuelCell).StackCooler.Name = AlphArray(1); - FuelCell(thisFuelCell).StackCooler.WaterInNodeName = AlphArray(2); - - FuelCell(thisFuelCell).StackCooler.WaterOutNodeName = AlphArray(3); - - FuelCell(thisFuelCell).StackCooler.WaterInNode = GetOnlySingleNode(AlphArray(2), - ErrorsFound, - cCurrentModuleObject, - AlphArray(1), - NodeType_Water, - NodeConnectionType_Inlet, - 1, - ObjectIsNotParent); - FuelCell(thisFuelCell).StackCooler.WaterOutNode = GetOnlySingleNode(AlphArray(3), - ErrorsFound, - cCurrentModuleObject, - AlphArray(1), - NodeType_Water, - NodeConnectionType_Outlet, - 1, - ObjectIsNotParent); - TestCompSet(cCurrentModuleObject, AlphArray(1), AlphArray(2), AlphArray(3), "Heat Recovery Nodes"); - - FuelCell(thisFuelCell).StackCooler.TstackNom = NumArray(1); - FuelCell(thisFuelCell).StackCooler.TstackActual = NumArray(2); - FuelCell(thisFuelCell).StackCooler.r0 = NumArray(3); - FuelCell(thisFuelCell).StackCooler.r1 = NumArray(4); - FuelCell(thisFuelCell).StackCooler.r2 = NumArray(5); - FuelCell(thisFuelCell).StackCooler.r3 = NumArray(6); - FuelCell(thisFuelCell).StackCooler.MdotStackCoolant = NumArray(7); - FuelCell(thisFuelCell).StackCooler.UAs_cool = NumArray(8); - FuelCell(thisFuelCell).StackCooler.Fs_cogen = NumArray(9); - FuelCell(thisFuelCell).StackCooler.As_cogen = NumArray(10); - FuelCell(thisFuelCell).StackCooler.MdotCogenNom = NumArray(11); - FuelCell(thisFuelCell).StackCooler.hCogenNom = NumArray(12); - FuelCell(thisFuelCell).StackCooler.ns = NumArray(13); - FuelCell(thisFuelCell).StackCooler.PstackPumpEl = NumArray(14); - FuelCell(thisFuelCell).StackCooler.PmpPowerLossFactor = NumArray(15); - FuelCell(thisFuelCell).StackCooler.f0 = NumArray(16); - FuelCell(thisFuelCell).StackCooler.f1 = NumArray(17); - FuelCell(thisFuelCell).StackCooler.f1 = NumArray(18); - - FuelCell(thisFuelCell).StackCooler.StackCoolerPresent = true; - } else { - ShowSevereError("Invalid, " + cAlphaFieldNames(1) + " = " + AlphArray(1)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + AlphArray(1)); - ErrorsFound = true; + // check for other FuelCell using the same Inverter and fill + for (int otherFuelCell = thisFuelCell + 1; otherFuelCell <= NumFuelCellGenerators; ++otherFuelCell) { + if (UtilityRoutines::SameString(FuelCell(otherFuelCell).Inverter.Name, FuelCell(thisFuelCell).Inverter.Name)) { + FuelCell(otherFuelCell).Inverter = FuelCell(thisFuelCell).Inverter; } } + } else { + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(1) + " = " + AlphArray(1)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); + ErrorsFound = true; } + } - if (ErrorsFound) { - ShowFatalError("Errors found in getting input for fuel cell model "); - } + DataIPShortCuts::cCurrentModuleObject = "Generator:FuelCell:StackCooler"; + int NumFCStackCoolers = inputProcessor->getNumObjectsFound(DataIPShortCuts::cCurrentModuleObject); - for (GeneratorNum = 1; GeneratorNum <= NumFuelCellGenerators; ++GeneratorNum) { - SetupOutputVariable("Generator Produced Electric Power", - OutputProcessor::Unit::W, - FuelCell(GeneratorNum).Report.ACPowerGen, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Produced Electric Energy", - OutputProcessor::Unit::J, - FuelCell(GeneratorNum).Report.ACEnergyGen, - "System", - "Sum", - FuelCell(GeneratorNum).Name, - _, - "ElectricityProduced", - "COGENERATION", - _, - "Plant"); - SetupOutputVariable("Generator Produced Thermal Rate", - OutputProcessor::Unit::W, - FuelCell(GeneratorNum).Report.qHX, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Produced Thermal Energy", - OutputProcessor::Unit::J, - FuelCell(GeneratorNum).Report.HXenergy, - "System", - "Sum", - FuelCell(GeneratorNum).Name, - _, - "ENERGYTRANSFER", - "COGENERATION", - _, - "Plant"); - - SetupOutputVariable("Generator Fuel HHV Basis Energy", - OutputProcessor::Unit::J, - FuelCell(GeneratorNum).Report.FuelEnergyHHV, - "System", - "Sum", - FuelCell(GeneratorNum).Name, - _, - "Gas", - "COGENERATION", - _, - "Plant"); - SetupOutputVariable("Generator Fuel HHV Basis Rate", - OutputProcessor::Unit::W, - FuelCell(GeneratorNum).Report.FuelEnergyUseRateHHV, - "System", - "Average", - FuelCell(GeneratorNum).Name); - - SetupOutputVariable("Generator Zone Sensible Heat Transfer Rate", - OutputProcessor::Unit::W, - FuelCell(GeneratorNum).Report.SkinLossPower, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Zone Sensible Heat Transfer Energy", - OutputProcessor::Unit::J, - FuelCell(GeneratorNum).Report.SkinLossEnergy, - "System", - "Sum", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Zone Convection Heat Transfer Rate", - OutputProcessor::Unit::W, - FuelCell(GeneratorNum).Report.SkinLossConvect, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Zone Radiation Heat Transfer Rate", - OutputProcessor::Unit::W, - FuelCell(GeneratorNum).Report.SkinLossRadiat, - "System", - "Average", - FuelCell(GeneratorNum).Name); - if (FuelCell(GeneratorNum).FCPM.ZoneID > 0) { - SetupZoneInternalGain(FuelCell(GeneratorNum).FCPM.ZoneID, - "Generator:FuelCell", - FuelCell(GeneratorNum).Name, - IntGainTypeOf_GeneratorFuelCell, - FuelCell(GeneratorNum).Report.SkinLossConvect, - _, - FuelCell(GeneratorNum).Report.SkinLossRadiat); - } + if (NumFCStackCoolers > 0) { // get stack cooler input data + for (int FCScoolNum = 1; FCScoolNum <= NumFCStackCoolers; ++FCScoolNum) { + inputProcessor->getObjectItem(DataIPShortCuts::cCurrentModuleObject, + FCScoolNum, + AlphArray, + NumAlphas, + NumArray, + NumNums, + IOStat, + _, + _, + DataIPShortCuts::cAlphaFieldNames, + DataIPShortCuts::cNumericFieldNames); + UtilityRoutines::IsNameEmpty(AlphArray(1), DataIPShortCuts::cCurrentModuleObject, ErrorsFound); + + int thisFuelCell = UtilityRoutines::FindItemInList(AlphArray(1), FuelCell, &FCDataStruct::NameStackCooler); - if (DisplayAdvancedReportVariables) { // show extra data originally needed for detailed comparative testing - SetupOutputVariable("Generator Air Inlet Temperature", - OutputProcessor::Unit::C, - FuelCell(GeneratorNum).Report.TairInlet, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Power Module Entering Air Temperature", - OutputProcessor::Unit::C, - FuelCell(GeneratorNum).Report.TairIntoFCPM, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Air Molar Flow Rate", - OutputProcessor::Unit::kmol_s, - FuelCell(GeneratorNum).Report.NdotAir, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Power Module Entering Air Enthalpy", - OutputProcessor::Unit::W, - FuelCell(GeneratorNum).Report.TotAirInEnthalphy, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Blower Electric Power", - OutputProcessor::Unit::W, - FuelCell(GeneratorNum).Report.BlowerPower, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Blower Electric Energy", - OutputProcessor::Unit::J, - FuelCell(GeneratorNum).Report.BlowerEnergy, - "System", - "Sum", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Blower Skin Heat Loss Rate", - OutputProcessor::Unit::W, - FuelCell(GeneratorNum).Report.BlowerSkinLoss, - "System", - "Average", - FuelCell(GeneratorNum).Name); - - SetupOutputVariable("Generator Fuel Inlet Temperature", - OutputProcessor::Unit::C, - FuelCell(GeneratorNum).Report.TfuelInlet, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Power Module Entering Fuel Temperature", - OutputProcessor::Unit::C, - FuelCell(GeneratorNum).Report.TfuelIntoFCPM, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Fuel Molar Flow Rate", - OutputProcessor::Unit::kmol_s, - FuelCell(GeneratorNum).Report.NdotFuel, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Fuel Consumption LHV Basis Energy", - OutputProcessor::Unit::J, - FuelCell(GeneratorNum).Report.FuelEnergyLHV, - "System", - "Sum", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Fuel Consumption Rate LHV Basis", - OutputProcessor::Unit::W, - FuelCell(GeneratorNum).Report.FuelEnergyUseRateLHV, - "System", - "Average", - FuelCell(GeneratorNum).Name); - - SetupOutputVariable("Generator Power Module Entering Fuel Enthalpy", - OutputProcessor::Unit::W, - FuelCell(GeneratorNum).Report.TotFuelInEnthalpy, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Fuel Compressor Electric Power", - OutputProcessor::Unit::W, - FuelCell(GeneratorNum).Report.FuelCompressPower, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Fuel Compressor Electric Energy", - OutputProcessor::Unit::J, - FuelCell(GeneratorNum).Report.FuelCompressEnergy, - "System", - "Sum", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Fuel Compressor Skin Heat Loss Rate", - OutputProcessor::Unit::W, - FuelCell(GeneratorNum).Report.FuelCompressSkinLoss, - "System", - "Average", - FuelCell(GeneratorNum).Name); - - SetupOutputVariable("Generator Fuel Reformer Water Inlet Temperature", - OutputProcessor::Unit::C, - FuelCell(GeneratorNum).Report.TwaterInlet, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Power Module Entering Reforming Water Temperature", - OutputProcessor::Unit::C, - FuelCell(GeneratorNum).Report.TwaterIntoFCPM, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Fuel Reformer Water Molar Flow Rate", - OutputProcessor::Unit::kmol_s, - FuelCell(GeneratorNum).Report.NdotWater, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Fuel Reformer Water Pump Electric Power", - OutputProcessor::Unit::W, - FuelCell(GeneratorNum).Report.WaterPumpPower, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Fuel Reformer Water Pump Electric Energy", - OutputProcessor::Unit::J, - FuelCell(GeneratorNum).Report.WaterPumpEnergy, - "System", - "Sum", - FuelCell(GeneratorNum).Name); - - SetupOutputVariable("Generator Power Module Entering Reforming Water Enthalpy", - OutputProcessor::Unit::W, - FuelCell(GeneratorNum).Report.WaterIntoFCPMEnthalpy, - "System", - "Average", - FuelCell(GeneratorNum).Name); - - SetupOutputVariable("Generator Product Gas Temperature", - OutputProcessor::Unit::C, - FuelCell(GeneratorNum).Report.TprodGas, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Product Gas Enthalpy", - OutputProcessor::Unit::W, - FuelCell(GeneratorNum).Report.EnthalProdGas, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Product Gas Molar Flow Rate", - OutputProcessor::Unit::kmol_s, - FuelCell(GeneratorNum).Report.NdotProdGas, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Product Gas Ar Molar Flow Rate", - OutputProcessor::Unit::kmol_s, - FuelCell(GeneratorNum).Report.NdotProdAr, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Product Gas CO2 Molar Flow Rate", - OutputProcessor::Unit::kmol_s, - FuelCell(GeneratorNum).Report.NdotProdCO2, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Product Gas H2O Vapor Molar Flow Rate", - OutputProcessor::Unit::kmol_s, - FuelCell(GeneratorNum).Report.NdotProdH2O, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Product Gas N2 Molar Flow Rate", - OutputProcessor::Unit::kmol_s, - FuelCell(GeneratorNum).Report.NdotProdN2, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Product Gas O2 Molar Flow Rate", - OutputProcessor::Unit::kmol_s, - FuelCell(GeneratorNum).Report.NdotProdO2, - "System", - "Average", - FuelCell(GeneratorNum).Name); - - SetupOutputVariable("Generator Heat Recovery Exit Gas Temperature", - OutputProcessor::Unit::C, - FuelCell(GeneratorNum).Report.THXexh, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Heat Recovery Exit Gas H2O Vapor Fraction", - OutputProcessor::Unit::None, - FuelCell(GeneratorNum).Report.WaterVaporFractExh, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Heat Recovery Water Condensate Molar Flow Rate", - OutputProcessor::Unit::kmol_s, - FuelCell(GeneratorNum).Report.CondensateRate, - "System", - "Average", - FuelCell(GeneratorNum).Name); - - SetupOutputVariable("Generator Inverter Loss Power", - OutputProcessor::Unit::W, - FuelCell(GeneratorNum).Report.PCUlosses, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Produced DC Electric Power", - OutputProcessor::Unit::W, - FuelCell(GeneratorNum).Report.DCPowerGen, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator DC Power Efficiency", - OutputProcessor::Unit::None, - FuelCell(GeneratorNum).Report.DCPowerEff, - "System", - "Average", - FuelCell(GeneratorNum).Name); - - SetupOutputVariable("Generator Electric Storage Charge State", - OutputProcessor::Unit::J, - FuelCell(GeneratorNum).Report.ElectEnergyinStorage, - "System", - "Average", - FuelCell(GeneratorNum).Name); //? 'Sum' - SetupOutputVariable("Generator DC Storage Charging Power", - OutputProcessor::Unit::W, - FuelCell(GeneratorNum).Report.StoredPower, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator DC Storage Charging Energy", - OutputProcessor::Unit::J, - FuelCell(GeneratorNum).Report.StoredEnergy, - "System", - "Sum", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator DC Storage Discharging Power", - OutputProcessor::Unit::W, - FuelCell(GeneratorNum).Report.DrawnPower, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator DC Storage Discharging Energy", - OutputProcessor::Unit::J, - FuelCell(GeneratorNum).Report.DrawnEnergy, - "System", - "Sum", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Ancillary AC Electric Power", - OutputProcessor::Unit::W, - FuelCell(GeneratorNum).Report.ACancillariesPower, - "System", - "Average", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Ancillary AC Electric Energy", - OutputProcessor::Unit::J, - FuelCell(GeneratorNum).Report.ACancillariesEnergy, - "System", - "Sum", - FuelCell(GeneratorNum).Name); - - SetupOutputVariable("Generator Fuel Cell Model Iteration Count", - OutputProcessor::Unit::None, - FuelCell(GeneratorNum).Report.SeqSubstIterations, - "System", - "Sum", - FuelCell(GeneratorNum).Name); - SetupOutputVariable("Generator Root Solver Iteration Count", - OutputProcessor::Unit::None, - FuelCell(GeneratorNum).Report.RegulaFalsiIterations, - "System", - "Sum", - FuelCell(GeneratorNum).Name); + if (thisFuelCell > 0) { + FuelCell(thisFuelCell).StackCooler.Name = AlphArray(1); + FuelCell(thisFuelCell).StackCooler.WaterInNodeName = AlphArray(2); + + FuelCell(thisFuelCell).StackCooler.WaterOutNodeName = AlphArray(3); + + FuelCell(thisFuelCell).StackCooler.WaterInNode = NodeInputManager::GetOnlySingleNode(AlphArray(2), + ErrorsFound, + DataIPShortCuts::cCurrentModuleObject, + AlphArray(1), + DataLoopNode::NodeType_Water, + DataLoopNode::NodeConnectionType_Inlet, + 1, + DataLoopNode::ObjectIsNotParent); + FuelCell(thisFuelCell).StackCooler.WaterOutNode = NodeInputManager::GetOnlySingleNode(AlphArray(3), + ErrorsFound, + DataIPShortCuts::cCurrentModuleObject, + AlphArray(1), + DataLoopNode::NodeType_Water, + DataLoopNode::NodeConnectionType_Outlet, + 1, + DataLoopNode::ObjectIsNotParent); + BranchNodeConnections::TestCompSet( + DataIPShortCuts::cCurrentModuleObject, AlphArray(1), AlphArray(2), AlphArray(3), "Heat Recovery Nodes"); + + FuelCell(thisFuelCell).StackCooler.TstackNom = NumArray(1); + FuelCell(thisFuelCell).StackCooler.TstackActual = NumArray(2); + FuelCell(thisFuelCell).StackCooler.r0 = NumArray(3); + FuelCell(thisFuelCell).StackCooler.r1 = NumArray(4); + FuelCell(thisFuelCell).StackCooler.r2 = NumArray(5); + FuelCell(thisFuelCell).StackCooler.r3 = NumArray(6); + FuelCell(thisFuelCell).StackCooler.MdotStackCoolant = NumArray(7); + FuelCell(thisFuelCell).StackCooler.UAs_cool = NumArray(8); + FuelCell(thisFuelCell).StackCooler.Fs_cogen = NumArray(9); + FuelCell(thisFuelCell).StackCooler.As_cogen = NumArray(10); + FuelCell(thisFuelCell).StackCooler.MdotCogenNom = NumArray(11); + FuelCell(thisFuelCell).StackCooler.hCogenNom = NumArray(12); + FuelCell(thisFuelCell).StackCooler.ns = NumArray(13); + FuelCell(thisFuelCell).StackCooler.PstackPumpEl = NumArray(14); + FuelCell(thisFuelCell).StackCooler.PmpPowerLossFactor = NumArray(15); + FuelCell(thisFuelCell).StackCooler.f0 = NumArray(16); + FuelCell(thisFuelCell).StackCooler.f1 = NumArray(17); + FuelCell(thisFuelCell).StackCooler.f1 = NumArray(18); + + FuelCell(thisFuelCell).StackCooler.StackCoolerPresent = true; + + } else { + ShowSevereError("Invalid, " + DataIPShortCuts::cAlphaFieldNames(1) + " = " + AlphArray(1)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + AlphArray(1)); + ErrorsFound = true; } } + } + + if (ErrorsFound) { + ShowFatalError("Errors found in getting input for fuel cell model "); + } - MyOneTimeFlag = false; + for (int genNum = 1; genNum <= NumFuelCellGenerators; ++genNum) { + auto &thisGen = FuelCell(genNum); + thisGen.setupOutputVars(); } } - // End of Get Input subroutines for the FuelCell Generator Module + void FCDataStruct::setupOutputVars() + { + SetupOutputVariable("Generator Produced Electric Power", OutputProcessor::Unit::W, this->Report.ACPowerGen, "System", "Average", this->Name); + + SetupOutputVariable("Generator Produced Electric Energy", + OutputProcessor::Unit::J, + this->Report.ACEnergyGen, + "System", + "Sum", + this->Name, + _, + "ElectricityProduced", + "COGENERATION", + _, + "Plant"); + + SetupOutputVariable("Generator Produced Thermal Rate", OutputProcessor::Unit::W, this->Report.qHX, "System", "Average", this->Name); + + SetupOutputVariable("Generator Produced Thermal Energy", + OutputProcessor::Unit::J, + this->Report.HXenergy, + "System", + "Sum", + this->Name, + _, + "ENERGYTRANSFER", + "COGENERATION", + _, + "Plant"); + + SetupOutputVariable("Generator Fuel HHV Basis Energy", + OutputProcessor::Unit::J, + this->Report.FuelEnergyHHV, + "System", + "Sum", + this->Name, + _, + "Gas", + "COGENERATION", + _, + "Plant"); + + SetupOutputVariable( + "Generator Fuel HHV Basis Rate", OutputProcessor::Unit::W, this->Report.FuelEnergyUseRateHHV, "System", "Average", this->Name); + + SetupOutputVariable( + "Generator Zone Sensible Heat Transfer Rate", OutputProcessor::Unit::W, this->Report.SkinLossPower, "System", "Average", this->Name); + + SetupOutputVariable( + "Generator Zone Sensible Heat Transfer Energy", OutputProcessor::Unit::J, this->Report.SkinLossEnergy, "System", "Sum", this->Name); + + SetupOutputVariable( + "Generator Zone Convection Heat Transfer Rate", OutputProcessor::Unit::W, this->Report.SkinLossConvect, "System", "Average", this->Name); + + SetupOutputVariable( + "Generator Zone Radiation Heat Transfer Rate", OutputProcessor::Unit::W, this->Report.SkinLossRadiat, "System", "Average", this->Name); + + if (this->FCPM.ZoneID > 0) { + SetupZoneInternalGain(this->FCPM.ZoneID, + "Generator:FuelCell", + this->Name, + DataHeatBalance::IntGainTypeOf_GeneratorFuelCell, + this->Report.SkinLossConvect, + _, + this->Report.SkinLossRadiat); + } - // Beginning of Generator model Subroutines - // ***************************************************************************** + if (DataGlobals::DisplayAdvancedReportVariables) { // show extra data originally needed for detailed comparative testing + SetupOutputVariable("Generator Air Inlet Temperature", OutputProcessor::Unit::C, this->Report.TairInlet, "System", "Average", this->Name); + + SetupOutputVariable("Generator Power Module Entering Air Temperature", + OutputProcessor::Unit::C, + this->Report.TairIntoFCPM, + "System", + "Average", + this->Name); + + SetupOutputVariable( + "Generator Air Molar Flow Rate", OutputProcessor::Unit::kmol_s, this->Report.NdotAir, "System", "Average", this->Name); + + SetupOutputVariable("Generator Power Module Entering Air Enthalpy", + OutputProcessor::Unit::W, + this->Report.TotAirInEnthalphy, + "System", + "Average", + this->Name); + + SetupOutputVariable( + "Generator Blower Electric Power", OutputProcessor::Unit::W, this->Report.BlowerPower, "System", "Average", this->Name); + + SetupOutputVariable("Generator Blower Electric Energy", OutputProcessor::Unit::J, this->Report.BlowerEnergy, "System", "Sum", this->Name); + + SetupOutputVariable( + "Generator Blower Skin Heat Loss Rate", OutputProcessor::Unit::W, this->Report.BlowerSkinLoss, "System", "Average", this->Name); + + SetupOutputVariable( + "Generator Fuel Inlet Temperature", OutputProcessor::Unit::C, this->Report.TfuelInlet, "System", "Average", this->Name); + + SetupOutputVariable("Generator Power Module Entering Fuel Temperature", + OutputProcessor::Unit::C, + this->Report.TfuelIntoFCPM, + "System", + "Average", + this->Name); + + SetupOutputVariable( + "Generator Fuel Molar Flow Rate", OutputProcessor::Unit::kmol_s, this->Report.NdotFuel, "System", "Average", this->Name); + + SetupOutputVariable( + "Generator Fuel Consumption LHV Basis Energy", OutputProcessor::Unit::J, this->Report.FuelEnergyLHV, "System", "Sum", this->Name); + + SetupOutputVariable("Generator Fuel Consumption Rate LHV Basis", + OutputProcessor::Unit::W, + this->Report.FuelEnergyUseRateLHV, + "System", + "Average", + this->Name); + + SetupOutputVariable("Generator Power Module Entering Fuel Enthalpy", + OutputProcessor::Unit::W, + this->Report.TotFuelInEnthalpy, + "System", + "Average", + this->Name); + + SetupOutputVariable("Generator Fuel Compressor Electric Power", + OutputProcessor::Unit::W, + this->Report.FuelCompressPower, + "System", + "Average", + this->Name); + + SetupOutputVariable( + "Generator Fuel Compressor Electric Energy", OutputProcessor::Unit::J, this->Report.FuelCompressEnergy, "System", "Sum", this->Name); + + SetupOutputVariable("Generator Fuel Compressor Skin Heat Loss Rate", + OutputProcessor::Unit::W, + this->Report.FuelCompressSkinLoss, + "System", + "Average", + this->Name); + + SetupOutputVariable("Generator Fuel Reformer Water Inlet Temperature", + OutputProcessor::Unit::C, + this->Report.TwaterInlet, + "System", + "Average", + this->Name); + + SetupOutputVariable("Generator Power Module Entering Reforming Water Temperature", + OutputProcessor::Unit::C, + this->Report.TwaterIntoFCPM, + "System", + "Average", + this->Name); + + SetupOutputVariable("Generator Fuel Reformer Water Molar Flow Rate", + OutputProcessor::Unit::kmol_s, + this->Report.NdotWater, + "System", + "Average", + this->Name); + + SetupOutputVariable("Generator Fuel Reformer Water Pump Electric Power", + OutputProcessor::Unit::W, + this->Report.WaterPumpPower, + "System", + "Average", + this->Name); + + SetupOutputVariable("Generator Fuel Reformer Water Pump Electric Energy", + OutputProcessor::Unit::J, + this->Report.WaterPumpEnergy, + "System", + "Sum", + this->Name); + + SetupOutputVariable("Generator Power Module Entering Reforming Water Enthalpy", + OutputProcessor::Unit::W, + this->Report.WaterIntoFCPMEnthalpy, + "System", + "Average", + this->Name); + + SetupOutputVariable( + "Generator Product Gas Temperature", OutputProcessor::Unit::C, this->Report.TprodGas, "System", "Average", this->Name); + + SetupOutputVariable( + "Generator Product Gas Enthalpy", OutputProcessor::Unit::W, this->Report.EnthalProdGas, "System", "Average", this->Name); + + SetupOutputVariable( + "Generator Product Gas Molar Flow Rate", OutputProcessor::Unit::kmol_s, this->Report.NdotProdGas, "System", "Average", this->Name); + + SetupOutputVariable( + "Generator Product Gas Ar Molar Flow Rate", OutputProcessor::Unit::kmol_s, this->Report.NdotProdAr, "System", "Average", this->Name); + + SetupOutputVariable("Generator Product Gas CO2 Molar Flow Rate", + OutputProcessor::Unit::kmol_s, + this->Report.NdotProdCO2, + "System", + "Average", + this->Name); + + SetupOutputVariable("Generator Product Gas H2O Vapor Molar Flow Rate", + OutputProcessor::Unit::kmol_s, + this->Report.NdotProdH2O, + "System", + "Average", + this->Name); + + SetupOutputVariable( + "Generator Product Gas N2 Molar Flow Rate", OutputProcessor::Unit::kmol_s, this->Report.NdotProdN2, "System", "Average", this->Name); + + SetupOutputVariable( + "Generator Product Gas O2 Molar Flow Rate", OutputProcessor::Unit::kmol_s, this->Report.NdotProdO2, "System", "Average", this->Name); + + SetupOutputVariable( + "Generator Heat Recovery Exit Gas Temperature", OutputProcessor::Unit::C, this->Report.THXexh, "System", "Average", this->Name); + + SetupOutputVariable("Generator Heat Recovery Exit Gas H2O Vapor Fraction", + OutputProcessor::Unit::None, + this->Report.WaterVaporFractExh, + "System", + "Average", + this->Name); + + SetupOutputVariable("Generator Heat Recovery Water Condensate Molar Flow Rate", + OutputProcessor::Unit::kmol_s, + this->Report.CondensateRate, + "System", + "Average", + this->Name); + + SetupOutputVariable("Generator Inverter Loss Power", OutputProcessor::Unit::W, this->Report.PCUlosses, "System", "Average", this->Name); + + SetupOutputVariable( + "Generator Produced DC Electric Power", OutputProcessor::Unit::W, this->Report.DCPowerGen, "System", "Average", this->Name); + + SetupOutputVariable( + "Generator DC Power Efficiency", OutputProcessor::Unit::None, this->Report.DCPowerEff, "System", "Average", this->Name); + + SetupOutputVariable("Generator Electric Storage Charge State", + OutputProcessor::Unit::J, + this->Report.ElectEnergyinStorage, + "System", + "Average", + this->Name); + + SetupOutputVariable( + "Generator DC Storage Charging Power", OutputProcessor::Unit::W, this->Report.StoredPower, "System", "Average", this->Name); + + SetupOutputVariable( + "Generator DC Storage Charging Energy", OutputProcessor::Unit::J, this->Report.StoredEnergy, "System", "Sum", this->Name); + + SetupOutputVariable( + "Generator DC Storage Discharging Power", OutputProcessor::Unit::W, this->Report.DrawnPower, "System", "Average", this->Name); + + SetupOutputVariable( + "Generator DC Storage Discharging Energy", OutputProcessor::Unit::J, this->Report.DrawnEnergy, "System", "Sum", this->Name); + + SetupOutputVariable( + "Generator Ancillary AC Electric Power", OutputProcessor::Unit::W, this->Report.ACancillariesPower, "System", "Average", this->Name); + + SetupOutputVariable( + "Generator Ancillary AC Electric Energy", OutputProcessor::Unit::J, this->Report.ACancillariesEnergy, "System", "Sum", this->Name); + + SetupOutputVariable("Generator Fuel Cell Model Iteration Count", + OutputProcessor::Unit::None, + this->Report.SeqSubstIterations, + "System", + "Sum", + this->Name); + + SetupOutputVariable("Generator Root Solver Iteration Count", + OutputProcessor::Unit::None, + this->Report.RegulaFalsiIterations, + "System", + "Sum", + this->Name); + } + } - void CalcFuelCellGeneratorModel(int const GeneratorNum, // Generator number - bool const RunFlag, // TRUE when Generator operating - Real64 const MyLoad, // Generator demand - bool const EP_UNUSED(FirstHVACIteration)) + void FCDataStruct::CalcFuelCellGeneratorModel(bool const RunFlag, Real64 const MyLoad, bool const EP_UNUSED(FirstHVACIteration)) { // SUBROUTINE INFORMATION: // AUTHOR Brent Griffith @@ -1414,106 +1351,45 @@ namespace FuelCellElectricGenerator { // REFERENCES: IEA/ECBCS Annex 42.... - // Using/Aliasing - using CurveManager::CurveValue; - using DataEnvironment::WaterMainsTemp; - using DataHeatBalFanSys::ZT; - using DataHVACGlobals::SysTimeElapsed; - using General::RoundSigDigits; - using General::SolveRoot; - using ScheduleManager::GetCurrentScheduleValue; - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE PARAMETER DEFINITIONS: - - // DERIVED TYPE DEFINITIONS - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - static Real64 PpcuLosses; // losses in inverter [W] - Real64 Pel; // DC power generated in Fuel Cell Power Module - Real64 Pdemand; - Real64 Eel; - Real64 Tavg; // working average temperature - static bool ConstrainedFCPM(false); // true if power prod is constrained for some reason - static bool ConstrainedFCPMTrans(false); - Real64 PelDiff; - int iter; // loop index over repeating set of inter dependent calculaitons - Real64 NdotO2; // molar rate coeff working varible - Real64 CpWater; // heat capacity of water in molar units - Real64 WaterEnthOfForm; // Standard molar enthalpy of formation - Real64 NdotFuel; // fuel flow rate - Real64 NdotStoicAir; // Air to match fuel molar rate coeff, working variable - Real64 NdotExcessAir; // Air in excess of match for fuel - Real64 NdotCO2ProdGas; // CO2 from reaction - Real64 NdotH20ProdGas; // Water from reaction - Real64 NdotCO2; // temp CO2 molar rate coef product gas stream - Real64 NdotN2; // temp Nitrogen rate coef product gas stream - Real64 Ndot02; // temp Oxygen rate coef product gas stream - Real64 NdotH20; // temp Water rate coef product gas stream - Real64 NdotAr; // tmep Argon rate coef product gas stream - Real64 Cp; // temp Heat Capacity, used in thermochemistry units of (J/mol K) - Real64 Hmolfuel; // temp enthalpy of fuel mixture in KJ/mol - Real64 Hmolair; // temp enthalpy of air mixture in KJ/mol - Real64 HmolProdGases; // enthalpy of product gas mixture in KJ/mol - Real64 HLiqWater; // temp enthalpy of liquid water in KJ/mol No Formation - Real64 HGasWater; // temp enthalpy of gaseous water in KJ/mol No Formation - int thisGas; // loop index - Real64 MagofImbalance; // error signal to control exiting loop and targeting product enthalpy - Real64 tmpTotProdGasEnthalphy; - Real64 Acc; // accuracy control for SolveRoot - int MaxIter; // iteration control for SolveRoot - int SolverFlag; // feed back flag from SolveRoot - Array1D Par(3); // parameters passed in to SolveRoot - // Par(1) = generator number index in structure - // Par(2) = targeted enthalpy (W) - // Par(3) = molar flow rate of product gases (kmol/s) - Real64 tmpTprodGas; - // unused REAL(r64) :: LHV !Lower Heating Value - bool ConstrainedStorage; // contrained overall elect because of storage - Real64 PgridExtra; // extra electric power that should go into storage but can't - Real64 Pstorage; // power into storage (+), power from storage (-) - Real64 PintoInverter; // power into inverter after storage interactions - Real64 PoutofInverter; // power out of inverter after losses and including storage - Real64 PacAncillariesTotal; // total AC ancillaries - - //! begin controls block to be moved out to GeneratorDynamics module + // begin controls block to be moved out to GeneratorDynamics module // If no loop demand or Generator OFF, return if (!RunFlag) { // TODO zero out terms as appropriate - if (FuelCell(GeneratorNum).FCPM.HasBeenOn) { + if (this->FCPM.HasBeenOn) { // FuelCell just now beginning to shut down, // set Day and Time of Last Shut Down - FuelCell(GeneratorNum).FCPM.FractionalDayofLastShutDown = - double(DayOfSim) + (int(CurrentTime) + (SysTimeElapsed + (CurrentTime - int(CurrentTime)))) / HoursInDay; - FuelCell(GeneratorNum).FCPM.HasBeenOn = false; + this->FCPM.FractionalDayofLastShutDown = + double(DataGlobals::DayOfSim) + + (int(DataGlobals::CurrentTime) + (DataHVACGlobals::SysTimeElapsed + (DataGlobals::CurrentTime - int(DataGlobals::CurrentTime)))) / + DataGlobals::HoursInDay; + this->FCPM.HasBeenOn = false; - if (FuelCell(GeneratorNum).FCPM.ShutDownTime > 0.0) FuelCell(GeneratorNum).FCPM.DuringShutDown = true; + if (this->FCPM.ShutDownTime > 0.0) this->FCPM.DuringShutDown = true; } // TODO check to see if still in shut down mode and using fuel. - if (FuelCell(GeneratorNum).FCPM.DuringShutDown) { + if (this->FCPM.DuringShutDown) { } return; } - if (!FuelCell(GeneratorNum).FCPM.HasBeenOn) { + if (!this->FCPM.HasBeenOn) { // fuel cell just turned on // set Day and Time of Last STart Up - FuelCell(GeneratorNum).FCPM.FractionalDayofLastStartUp = - double(DayOfSim) + (int(CurrentTime) + (SysTimeElapsed + (CurrentTime - int(CurrentTime)))) / HoursInDay; + this->FCPM.FractionalDayofLastStartUp = + double(DataGlobals::DayOfSim) + + (int(DataGlobals::CurrentTime) + (DataHVACGlobals::SysTimeElapsed + (DataGlobals::CurrentTime - int(DataGlobals::CurrentTime)))) / + DataGlobals::HoursInDay; - FuelCell(GeneratorNum).FCPM.HasBeenOn = true; - ++FuelCell(GeneratorNum).FCPM.NumCycles; // increment cycling counter + this->FCPM.HasBeenOn = true; + ++this->FCPM.NumCycles; // increment cycling counter - if (FuelCell(GeneratorNum).FCPM.StartUpTime > 0.0) FuelCell(GeneratorNum).FCPM.DuringStartUp = true; + if (this->FCPM.StartUpTime > 0.0) this->FCPM.DuringStartUp = true; } // TODO deal with things when jump out if not running? @@ -1521,438 +1397,432 @@ namespace FuelCellElectricGenerator { return; } - // Note: MyLoad (input) is Pdemand (electical Power requested) - Pdemand = MyLoad; - PacAncillariesTotal = 0.0; - PpcuLosses = 0.0; - Pstorage = 0.0; - PgridExtra = 0.0; - PoutofInverter = 0.0; - ConstrainedFCPM = false; + // Note: MyLoad (input) is Pdemand (electrical Power requested) + Real64 Pdemand = MyLoad; + Real64 PacAncillariesTotal = 0.0; + Real64 PpcuLosses = 0.0; + Real64 Pstorage = 0.0; + Real64 PgridExtra = 0.0; + Real64 PoutofInverter = 0.0; + bool ConstrainedFCPM = false; + int SolverFlag; + int iter; + Real64 Pel; - //! BEGIN SEQUENTIAL SUBSTITUTION to handle a lot of inter-related calcs + // BEGIN SEQUENTIAL SUBSTITUTION to handle a lot of inter-related calcs for (iter = 1; iter <= 20; ++iter) { if (iter > 1) { - FigurePowerConditioningLosses(GeneratorNum, PoutofInverter, PpcuLosses); - FigureACAncillaries(GeneratorNum, PacAncillariesTotal); + this->FigurePowerConditioningLosses(PoutofInverter, PpcuLosses); + this->FigureACAncillaries(PacAncillariesTotal); Pdemand = MyLoad + PacAncillariesTotal + PpcuLosses; } else { // control Step 1a: Figure ancillary AC power draws - FigureACAncillaries(GeneratorNum, PacAncillariesTotal); + this->FigureACAncillaries(PacAncillariesTotal); Pdemand = MyLoad + PacAncillariesTotal; // Control Step 1b: Calculate losses associated with Power conditioning - FigurePowerConditioningLosses(GeneratorNum, Pdemand, PpcuLosses); + this->FigurePowerConditioningLosses(Pdemand, PpcuLosses); Pdemand += PpcuLosses; Pel = Pdemand; } - FuelCell(GeneratorNum).Inverter.PCUlosses = PpcuLosses; + this->Inverter.PCUlosses = PpcuLosses; // Control step 2: adjust for transient and startup/shut down constraints - FigureTransientConstraints(GeneratorNum, Pel, ConstrainedFCPMTrans, PelDiff); + Real64 PelDiff; + bool ConstrainedFCPMTrans = false; + this->FigureTransientConstraints(Pel, ConstrainedFCPMTrans, PelDiff); // Control step 3: adjust for max and min limits on Pel - if (Pel < FuelCell(GeneratorNum).FCPM.PelMin) { - PelDiff += (FuelCell(GeneratorNum).FCPM.PelMin - Pel); - Pel = FuelCell(GeneratorNum).FCPM.PelMin; + if (Pel < this->FCPM.PelMin) { + PelDiff += (this->FCPM.PelMin - Pel); + Pel = this->FCPM.PelMin; ConstrainedFCPM = true; } - if (Pel > FuelCell(GeneratorNum).FCPM.PelMax) { - PelDiff += (FuelCell(GeneratorNum).FCPM.PelMax - Pel); - Pel = FuelCell(GeneratorNum).FCPM.PelMax; + if (Pel > this->FCPM.PelMax) { + PelDiff += (this->FCPM.PelMax - Pel); + Pel = this->FCPM.PelMax; ConstrainedFCPM = true; } if (ConstrainedFCPM) { } - FuelCell(GeneratorNum).FCPM.Pel = Pel; + this->FCPM.Pel = Pel; // Now calculate FC models. return to controls and batter after // Calculation Step 1. Determine electrical Efficiency Eel - if (FuelCell(GeneratorNum).FCPM.EffMode == NormalizedCurveMode) { + Real64 Eel = 0.0; + if (this->FCPM.EffMode == DataGenerators::NormalizedCurveMode) { // Equation (8) in FuelCell Spec modified for normalized curve - Eel = CurveValue(FuelCell(GeneratorNum).FCPM.EffCurveID, Pel / FuelCell(GeneratorNum).FCPM.NomPel) * - FuelCell(GeneratorNum).FCPM.NomEff * - (1.0 - FuelCell(GeneratorNum).FCPM.NumCycles * FuelCell(GeneratorNum).FCPM.CyclingDegradRat) * - (1.0 - max((FuelCell(GeneratorNum).FCPM.NumRunHours - FuelCell(GeneratorNum).FCPM.ThreshRunHours), 0.0) * - FuelCell(GeneratorNum).FCPM.OperateDegradRat); + Eel = CurveManager::CurveValue(this->FCPM.EffCurveID, Pel / this->FCPM.NomPel) * this->FCPM.NomEff * + (1.0 - this->FCPM.NumCycles * this->FCPM.CyclingDegradRat) * + (1.0 - max((this->FCPM.NumRunHours - this->FCPM.ThreshRunHours), 0.0) * this->FCPM.OperateDegradRat); - } else if (FuelCell(GeneratorNum).FCPM.EffMode == DirectCurveMode) { + } else if (this->FCPM.EffMode == DataGenerators::DirectCurveMode) { // Equation (8) in FuelCell Spec - Eel = CurveValue(FuelCell(GeneratorNum).FCPM.EffCurveID, Pel) * - (1.0 - FuelCell(GeneratorNum).FCPM.NumCycles * FuelCell(GeneratorNum).FCPM.CyclingDegradRat) * - (1.0 - max((FuelCell(GeneratorNum).FCPM.NumRunHours - FuelCell(GeneratorNum).FCPM.ThreshRunHours), 0.0) * - FuelCell(GeneratorNum).FCPM.OperateDegradRat); + Eel = CurveManager::CurveValue(this->FCPM.EffCurveID, Pel) * (1.0 - this->FCPM.NumCycles * this->FCPM.CyclingDegradRat) * + (1.0 - max((this->FCPM.NumRunHours - this->FCPM.ThreshRunHours), 0.0) * this->FCPM.OperateDegradRat); } - FuelCell(GeneratorNum).FCPM.Eel = Eel; + this->FCPM.Eel = Eel; // Calculation Step 2. Determine fuel rate - NdotFuel = Pel / (Eel * FuelSupply(FuelCell(GeneratorNum).FuelSupNum).LHV * 1000000.0); // Eq. 10 solved for Ndot + // fuel flow rate + Real64 NdotFuel = Pel / (Eel * DataGenerators::FuelSupply(this->FuelSupNum).LHV * 1000000.0); // Eq. 10 solved for Ndot - FuelCell(GeneratorNum).FCPM.NdotFuel = NdotFuel; + this->FCPM.NdotFuel = NdotFuel; if (Pel <= 0.0) { // TODO zero stuff before leaving Pel = 0.0; - FuelCell(GeneratorNum).FCPM.Pel = 0.0; + this->FCPM.Pel = 0.0; return; } else { - FuelCell(GeneratorNum).FCPM.Pel = Pel; + this->FCPM.Pel = Pel; } // Calculation Step 3. Determine Air rate - if (FuelCell(GeneratorNum).AirSup.AirSupRateMode == ConstantStoicsAirRat) { // MEthod 1 - NdotO2 = FuelSupply(FuelCell(GeneratorNum).FuelSupNum).StoicOxygenRate * FuelCell(GeneratorNum).FCPM.NdotFuel * - FuelCell(GeneratorNum).AirSup.Stoics; + if (this->AirSup.AirSupRateMode == DataGenerators::ConstantStoicsAirRat) { // MEthod 1 + // molar rate coeff working variable + Real64 NdotO2 = DataGenerators::FuelSupply(this->FuelSupNum).StoicOxygenRate * this->FCPM.NdotFuel * this->AirSup.Stoics; - FuelCell(GeneratorNum).FCPM.NdotAir = NdotO2 / FuelCell(GeneratorNum).AirSup.O2fraction; + this->FCPM.NdotAir = NdotO2 / this->AirSup.O2fraction; - } else if (FuelCell(GeneratorNum).AirSup.AirSupRateMode == QuadraticFuncofPel) { // MEthod 2 + } else if (this->AirSup.AirSupRateMode == DataGenerators::QuadraticFuncofPel) { // MEthod 2 - FuelCell(GeneratorNum).FCPM.NdotAir = CurveValue(FuelCell(GeneratorNum).AirSup.AirFuncPelCurveID, Pel) * - (1 + FuelCell(GeneratorNum).AirSup.AirTempCoeff * FuelCell(GeneratorNum).AirSup.TairIntoFCPM); + this->FCPM.NdotAir = + CurveManager::CurveValue(this->AirSup.AirFuncPelCurveID, Pel) * (1 + this->AirSup.AirTempCoeff * this->AirSup.TairIntoFCPM); - } else if (FuelCell(GeneratorNum).AirSup.AirSupRateMode == QuadraticFuncofNdot) { // method 3 - FuelCell(GeneratorNum).FCPM.NdotAir = - CurveValue(FuelCell(GeneratorNum).AirSup.AirFuncNdotCurveID, FuelCell(GeneratorNum).FCPM.NdotFuel) * - (1 + FuelCell(GeneratorNum).AirSup.AirTempCoeff * FuelCell(GeneratorNum).AirSup.TairIntoFCPM); + } else if (this->AirSup.AirSupRateMode == DataGenerators::QuadraticFuncofNdot) { // method 3 + this->FCPM.NdotAir = CurveManager::CurveValue(this->AirSup.AirFuncNdotCurveID, this->FCPM.NdotFuel) * + (1 + this->AirSup.AirTempCoeff * this->AirSup.TairIntoFCPM); } // Calculation Step 4. fuel compressor power - FuelSupply(FuelCell(GeneratorNum).FuelSupNum).PfuelCompEl = - CurveValue(FuelSupply(FuelCell(GeneratorNum).FuelSupNum).CompPowerCurveID, FuelCell(GeneratorNum).FCPM.NdotFuel); + DataGenerators::FuelSupply(this->FuelSupNum).PfuelCompEl = + CurveManager::CurveValue(DataGenerators::FuelSupply(this->FuelSupNum).CompPowerCurveID, this->FCPM.NdotFuel); // calculation Step 5, Fuel Compressor (need outlet temperature) - if (FuelSupply(FuelCell(GeneratorNum).FuelSupNum).FuelTempMode == FuelInTempFromNode) { + if (DataGenerators::FuelSupply(this->FuelSupNum).FuelTempMode == DataGenerators::FuelInTempFromNode) { - FuelSupply(FuelCell(GeneratorNum).FuelSupNum).TfuelIntoCompress = Node(FuelSupply(FuelCell(GeneratorNum).FuelSupNum).NodeNum).Temp; + DataGenerators::FuelSupply(this->FuelSupNum).TfuelIntoCompress = + DataLoopNode::Node(DataGenerators::FuelSupply(this->FuelSupNum).NodeNum).Temp; - } else if (FuelSupply(FuelCell(GeneratorNum).FuelSupNum).FuelTempMode == FuelInTempSchedule) { + } else if (DataGenerators::FuelSupply(this->FuelSupNum).FuelTempMode == DataGenerators::FuelInTempSchedule) { - FuelSupply(FuelCell(GeneratorNum).FuelSupNum).TfuelIntoCompress = - GetCurrentScheduleValue(FuelSupply(FuelCell(GeneratorNum).FuelSupNum).SchedNum); + DataGenerators::FuelSupply(this->FuelSupNum).TfuelIntoCompress = + ScheduleManager::GetCurrentScheduleValue(DataGenerators::FuelSupply(this->FuelSupNum).SchedNum); } - // evaluate heat capacity at average temperature usign shomate - Tavg = - (FuelSupply(FuelCell(GeneratorNum).FuelSupNum).TfuelIntoCompress + FuelSupply(FuelCell(GeneratorNum).FuelSupNum).TfuelIntoFCPM) / 2.0; - FigureFuelHeatCap(GeneratorNum, Tavg, Cp); // Cp in (J/mol K) + // evaluate heat capacity at average temperature using shomate + Real64 Cp; // temp Heat Capacity, used in thermochemistry units of (J/mol K) + Real64 Tavg = + (DataGenerators::FuelSupply(this->FuelSupNum).TfuelIntoCompress + DataGenerators::FuelSupply(this->FuelSupNum).TfuelIntoFCPM) / 2.0; + this->FigureFuelHeatCap(Tavg, Cp); // Cp in (J/mol K) // calculate a Temp of fuel out of compressor and into power module - if (FuelCell(GeneratorNum).FCPM.NdotFuel <= 0.0) { // just pass through, domain probably collapased in modeling - FuelSupply(FuelCell(GeneratorNum).FuelSupNum).TfuelIntoFCPM = FuelSupply(FuelCell(GeneratorNum).FuelSupNum).TfuelIntoCompress; + if (this->FCPM.NdotFuel <= 0.0) { // just pass through, domain probably collapsed in modeling + DataGenerators::FuelSupply(this->FuelSupNum).TfuelIntoFCPM = DataGenerators::FuelSupply(this->FuelSupNum).TfuelIntoCompress; } else { - FuelSupply(FuelCell(GeneratorNum).FuelSupNum).TfuelIntoFCPM = - ((1.0 - FuelSupply(FuelCell(GeneratorNum).FuelSupNum).CompPowerLossFactor) * - FuelSupply(FuelCell(GeneratorNum).FuelSupNum).PfuelCompEl / (FuelCell(GeneratorNum).FCPM.NdotFuel * Cp * 1000.0)) + - FuelSupply(FuelCell(GeneratorNum).FuelSupNum).TfuelIntoCompress; // 1000 Cp units mol-> kmol + DataGenerators::FuelSupply(this->FuelSupNum).TfuelIntoFCPM = + ((1.0 - DataGenerators::FuelSupply(this->FuelSupNum).CompPowerLossFactor) * + DataGenerators::FuelSupply(this->FuelSupNum).PfuelCompEl / (this->FCPM.NdotFuel * Cp * 1000.0)) + + DataGenerators::FuelSupply(this->FuelSupNum).TfuelIntoCompress; // 1000 Cp units mol-> kmol } // calc skin losses from fuel compressor - FuelSupply(FuelCell(GeneratorNum).FuelSupNum).QskinLoss = - FuelSupply(FuelCell(GeneratorNum).FuelSupNum).CompPowerLossFactor * FuelSupply(FuelCell(GeneratorNum).FuelSupNum).PfuelCompEl; + DataGenerators::FuelSupply(this->FuelSupNum).QskinLoss = + DataGenerators::FuelSupply(this->FuelSupNum).CompPowerLossFactor * DataGenerators::FuelSupply(this->FuelSupNum).PfuelCompEl; - if (FuelSupply(FuelCell(GeneratorNum).FuelSupNum).QskinLoss < 0.0) { - // write(*,*) 'problem in FuelSupply%QskinLoss ', FuelSupply(FuelCell(GeneratorNum)%FuelSupNum)%QskinLoss - ShowWarningError("problem in FuelSupply%QskinLoss " + RoundSigDigits(FuelSupply(FuelCell(GeneratorNum).FuelSupNum).QskinLoss, 3)); - FuelSupply(FuelCell(GeneratorNum).FuelSupNum).QskinLoss = 0.0; + if (DataGenerators::FuelSupply(this->FuelSupNum).QskinLoss < 0.0) { + ShowWarningError("problem in FuelSupply.QskinLoss " + + General::RoundSigDigits(DataGenerators::FuelSupply(this->FuelSupNum).QskinLoss, 3)); + DataGenerators::FuelSupply(this->FuelSupNum).QskinLoss = 0.0; } - // calculate tatal fuel enthalpy coming into power module + // calculate total fuel enthalpy coming into power module // (Hmolfuel in KJ/mol) - FigureFuelEnthalpy(GeneratorNum, FuelSupply(FuelCell(GeneratorNum).FuelSupNum).TfuelIntoFCPM, Hmolfuel); + Real64 Hmolfuel; // temp enthalpy of fuel mixture in KJ/mol + this->FigureFuelEnthalpy(DataGenerators::FuelSupply(this->FuelSupNum).TfuelIntoFCPM, Hmolfuel); // units, NdotFuel in kmol/sec. Hmolfule in KJ/mol , // factor of 1000's to get to J/s or watts - FuelCell(GeneratorNum).FCPM.TotFuelInEnthalphy = Hmolfuel * 1000.0 * FuelCell(GeneratorNum).FCPM.NdotFuel * 1000.0; + this->FCPM.TotFuelInEnthalphy = Hmolfuel * 1000.0 * this->FCPM.NdotFuel * 1000.0; // Calculation Step 6, water compressor calculations // calculate water consumption - FuelCell(GeneratorNum).FCPM.NdotLiqwater = - CurveValue(FuelCell(GeneratorNum).WaterSup.WaterSupRateCurveID, FuelCell(GeneratorNum).FCPM.NdotFuel); + this->FCPM.NdotLiqwater = CurveManager::CurveValue(this->WaterSup.WaterSupRateCurveID, this->FCPM.NdotFuel); // set inlet temp. (could move to init) { - auto const SELECT_CASE_var(FuelCell(GeneratorNum).WaterSup.WaterTempMode); + auto const SELECT_CASE_var(this->WaterSup.WaterTempMode); - if (SELECT_CASE_var == WaterInReformMains) { + if (SELECT_CASE_var == DataGenerators::WaterInReformMains) { - FuelCell(GeneratorNum).WaterSup.TwaterIntoCompress = WaterMainsTemp; + this->WaterSup.TwaterIntoCompress = DataEnvironment::WaterMainsTemp; - } else if ((SELECT_CASE_var == WaterInReformAirNode) || (SELECT_CASE_var == WaterInReformWaterNode)) { + } else if ((SELECT_CASE_var == DataGenerators::WaterInReformAirNode) || (SELECT_CASE_var == DataGenerators::WaterInReformWaterNode)) { - FuelCell(GeneratorNum).WaterSup.TwaterIntoCompress = Node(FuelCell(GeneratorNum).WaterSup.NodeNum).Temp; + this->WaterSup.TwaterIntoCompress = DataLoopNode::Node(this->WaterSup.NodeNum).Temp; - } else if (SELECT_CASE_var == WaterInReformSchedule) { + } else if (SELECT_CASE_var == DataGenerators::WaterInReformSchedule) { - FuelCell(GeneratorNum).WaterSup.TwaterIntoCompress = GetCurrentScheduleValue(FuelCell(GeneratorNum).WaterSup.SchedNum); + this->WaterSup.TwaterIntoCompress = ScheduleManager::GetCurrentScheduleValue(this->WaterSup.SchedNum); } } - FuelCell(GeneratorNum).WaterSup.PwaterCompEl = - CurveValue(FuelCell(GeneratorNum).WaterSup.PmpPowerCurveID, FuelCell(GeneratorNum).FCPM.NdotLiqwater); + this->WaterSup.PwaterCompEl = CurveManager::CurveValue(this->WaterSup.PmpPowerCurveID, this->FCPM.NdotLiqwater); // 75.325 J/mol K Water at 0.1 MPa and 298 K, reference NIST WEBBOOK - FigureLiquidWaterHeatCap(FuelCell(GeneratorNum).WaterSup.TwaterIntoCompress, CpWater); - - WaterEnthOfForm = -241.8264; // KJ/mol + Real64 CpWater; // heat capacity of water in molar units + FigureLiquidWaterHeatCap(this->WaterSup.TwaterIntoCompress, CpWater); - if (FuelCell(GeneratorNum).FCPM.NdotLiqwater <= 0.0) { // just pass through, domain probably collapased in modeling - FuelCell(GeneratorNum).WaterSup.TwaterIntoFCPM = FuelCell(GeneratorNum).WaterSup.TwaterIntoCompress; + if (this->FCPM.NdotLiqwater <= 0.0) { // just pass through, domain probably collapsed in modeling + this->WaterSup.TwaterIntoFCPM = this->WaterSup.TwaterIntoCompress; } else { - FuelCell(GeneratorNum).WaterSup.TwaterIntoFCPM = - ((1 - FuelCell(GeneratorNum).WaterSup.PmpPowerLossFactor) * FuelCell(GeneratorNum).WaterSup.PwaterCompEl / - (FuelCell(GeneratorNum).FCPM.NdotLiqwater * CpWater * 1000.0)) + - FuelCell(GeneratorNum).WaterSup.TwaterIntoCompress; + this->WaterSup.TwaterIntoFCPM = + ((1 - this->WaterSup.PmpPowerLossFactor) * this->WaterSup.PwaterCompEl / (this->FCPM.NdotLiqwater * CpWater * 1000.0)) + + this->WaterSup.TwaterIntoCompress; } - FuelCell(GeneratorNum).WaterSup.QskinLoss = - FuelCell(GeneratorNum).WaterSup.PmpPowerLossFactor * FuelCell(GeneratorNum).WaterSup.PwaterCompEl; + this->WaterSup.QskinLoss = this->WaterSup.PmpPowerLossFactor * this->WaterSup.PwaterCompEl; - if (FuelCell(GeneratorNum).WaterSup.QskinLoss < 0.0) { - // write(*,*) 'problem in WaterSup%QskinLoss ',FuelCell(GeneratorNum)%WaterSup%QskinLoss - FuelCell(GeneratorNum).WaterSup.QskinLoss = 0.0; + if (this->WaterSup.QskinLoss < 0.0) { + this->WaterSup.QskinLoss = 0.0; } - FigureLiquidWaterEnthalpy(FuelCell(GeneratorNum).WaterSup.TwaterIntoFCPM, HLiqWater); // HLiqWater in KJ/mol + Real64 HLiqWater; // temp enthalpy of liquid water in KJ/mol No Formation + FigureLiquidWaterEnthalpy(this->WaterSup.TwaterIntoFCPM, HLiqWater); // HLiqWater in KJ/mol - FuelCell(GeneratorNum).FCPM.WaterInEnthalpy = FuelCell(GeneratorNum).FCPM.NdotLiqwater * HLiqWater * 1000.0 * 1000.0; + this->FCPM.WaterInEnthalpy = this->FCPM.NdotLiqwater * HLiqWater * 1000.0 * 1000.0; // Calculation Step 7, Air compressor - FuelCell(GeneratorNum).AirSup.TairIntoBlower = Node(FuelCell(GeneratorNum).AirSup.SupNodeNum).Temp; + this->AirSup.TairIntoBlower = DataLoopNode::Node(this->AirSup.SupNodeNum).Temp; - FuelCell(GeneratorNum).AirSup.PairCompEl = - CurveValue(FuelCell(GeneratorNum).AirSup.BlowerPowerCurveID, FuelCell(GeneratorNum).FCPM.NdotAir); + this->AirSup.PairCompEl = CurveManager::CurveValue(this->AirSup.BlowerPowerCurveID, this->FCPM.NdotAir); - Tavg = (FuelCell(GeneratorNum).AirSup.TairIntoBlower + FuelCell(GeneratorNum).AirSup.TairIntoFCPM) / 2.0; + Tavg = (this->AirSup.TairIntoBlower + this->AirSup.TairIntoFCPM) / 2.0; - FigureAirHeatCap(GeneratorNum, Tavg, Cp); // Cp in (J/mol K) + this->FigureAirHeatCap(Tavg, Cp); // Cp in (J/mol K) // if PEMFC with stack cooler, then calculate stack cooler impacts - if (FuelCell(GeneratorNum).StackCooler.StackCoolerPresent) { + if (this->StackCooler.StackCoolerPresent) { - FuelCell(GeneratorNum).StackCooler.qs_cool = - (FuelCell(GeneratorNum).StackCooler.r0 + - FuelCell(GeneratorNum).StackCooler.r1 * - (FuelCell(GeneratorNum).StackCooler.TstackActual - FuelCell(GeneratorNum).StackCooler.TstackNom)) * - (1 + FuelCell(GeneratorNum).StackCooler.r2 * Pel + FuelCell(GeneratorNum).StackCooler.r3 * Pel * Pel) * Pel; + this->StackCooler.qs_cool = + (this->StackCooler.r0 + this->StackCooler.r1 * (this->StackCooler.TstackActual - this->StackCooler.TstackNom)) * + (1 + this->StackCooler.r2 * Pel + this->StackCooler.r3 * Pel * Pel) * Pel; - FuelCell(GeneratorNum).FCPM.QdotStackCool = FuelCell(GeneratorNum).StackCooler.qs_cool; + this->FCPM.QdotStackCool = this->StackCooler.qs_cool; } // Figure heat recovery from Electrical Storage, power conditioning, and auxiliary burner { - auto const SELECT_CASE_var(FuelCell(GeneratorNum).AirSup.IntakeRecoveryMode); - - if (SELECT_CASE_var == RecoverBurnInvertBatt) { - FuelCell(GeneratorNum).AirSup.QintakeRecovery = FuelCell(GeneratorNum).AuxilHeat.QairIntake + - FuelCell(GeneratorNum).ElecStorage.QairIntake + - FuelCell(GeneratorNum).Inverter.QairIntake; - } else if (SELECT_CASE_var == RecoverAuxiliaryBurner) { - FuelCell(GeneratorNum).AirSup.QintakeRecovery = FuelCell(GeneratorNum).AuxilHeat.QairIntake; - } else if (SELECT_CASE_var == RecoverInverterBatt) { - FuelCell(GeneratorNum).AirSup.QintakeRecovery = - FuelCell(GeneratorNum).ElecStorage.QairIntake + FuelCell(GeneratorNum).Inverter.QairIntake; - } else if (SELECT_CASE_var == RecoverInverter) { - FuelCell(GeneratorNum).AirSup.QintakeRecovery = FuelCell(GeneratorNum).Inverter.QairIntake; - } else if (SELECT_CASE_var == RecoverBattery) { - FuelCell(GeneratorNum).AirSup.QintakeRecovery = FuelCell(GeneratorNum).ElecStorage.QairIntake; - } else if (SELECT_CASE_var == NoRecoveryOnAirIntake) { - FuelCell(GeneratorNum).AirSup.QintakeRecovery = 0.0; + auto const SELECT_CASE_var(this->AirSup.IntakeRecoveryMode); + + if (SELECT_CASE_var == DataGenerators::RecoverBurnInvertBatt) { + this->AirSup.QintakeRecovery = this->AuxilHeat.QairIntake + this->ElecStorage.QairIntake + this->Inverter.QairIntake; + } else if (SELECT_CASE_var == DataGenerators::RecoverAuxiliaryBurner) { + this->AirSup.QintakeRecovery = this->AuxilHeat.QairIntake; + } else if (SELECT_CASE_var == DataGenerators::RecoverInverterBatt) { + this->AirSup.QintakeRecovery = this->ElecStorage.QairIntake + this->Inverter.QairIntake; + } else if (SELECT_CASE_var == DataGenerators::RecoverInverter) { + this->AirSup.QintakeRecovery = this->Inverter.QairIntake; + } else if (SELECT_CASE_var == DataGenerators::RecoverBattery) { + this->AirSup.QintakeRecovery = this->ElecStorage.QairIntake; + } else if (SELECT_CASE_var == DataGenerators::NoRecoveryOnAirIntake) { + this->AirSup.QintakeRecovery = 0.0; } } - if (FuelCell(GeneratorNum).FCPM.NdotAir <= 0.0) { // just pass through, domain probably collapased in modeling - FuelCell(GeneratorNum).AirSup.TairIntoFCPM = FuelCell(GeneratorNum).AirSup.TairIntoBlower; + if (this->FCPM.NdotAir <= 0.0) { // just pass through, domain probably collapsed in modeling + this->AirSup.TairIntoFCPM = this->AirSup.TairIntoBlower; } else { - FuelCell(GeneratorNum).AirSup.TairIntoFCPM = - (((1 - FuelCell(GeneratorNum).AirSup.BlowerHeatLossFactor) * FuelCell(GeneratorNum).AirSup.PairCompEl + - FuelCell(GeneratorNum).AirSup.QintakeRecovery) / - (FuelCell(GeneratorNum).FCPM.NdotAir * Cp * 1000.0)) + - FuelCell(GeneratorNum).AirSup.TairIntoBlower; // 1000 Cp units mol-> kmol + this->AirSup.TairIntoFCPM = (((1 - this->AirSup.BlowerHeatLossFactor) * this->AirSup.PairCompEl + this->AirSup.QintakeRecovery) / + (this->FCPM.NdotAir * Cp * 1000.0)) + + this->AirSup.TairIntoBlower; // 1000 Cp units mol-> kmol } - FuelCell(GeneratorNum).AirSup.QskinLoss = FuelCell(GeneratorNum).AirSup.BlowerHeatLossFactor * FuelCell(GeneratorNum).AirSup.PairCompEl; + this->AirSup.QskinLoss = this->AirSup.BlowerHeatLossFactor * this->AirSup.PairCompEl; - if (FuelCell(GeneratorNum).AirSup.QskinLoss < 0.0) { - // write(*,*) 'problem in AirSup%QskinLoss ', FuelCell(GeneratorNum)%AirSup%QskinLoss - ShowWarningError("problem in AirSup%QskinLoss " + RoundSigDigits(FuelCell(GeneratorNum).AirSup.QskinLoss, 3)); - FuelCell(GeneratorNum).AirSup.QskinLoss = 0.0; + if (this->AirSup.QskinLoss < 0.0) { + ShowWarningError("problem in AirSup.QskinLoss " + General::RoundSigDigits(this->AirSup.QskinLoss, 3)); + this->AirSup.QskinLoss = 0.0; } - FigureAirEnthalpy(GeneratorNum, FuelCell(GeneratorNum).AirSup.TairIntoFCPM, Hmolair); // (Hmolair in KJ/mol) + Real64 Hmolair; // temp enthalpy of air mixture in KJ/mol + this->FigureAirEnthalpy(this->AirSup.TairIntoFCPM, Hmolair); // (Hmolair in KJ/mol) // units, NdotAir in kmol/sec.; Hmolfuel in KJ/mol , // factor of 1000's to get to J/s or watts - FuelCell(GeneratorNum).FCPM.TotAirInEnthalphy = Hmolair * 1000.0 * FuelCell(GeneratorNum).FCPM.NdotAir * 1000.0; + this->FCPM.TotAirInEnthalphy = Hmolair * 1000.0 * this->FCPM.NdotAir * 1000.0; // calculation Step 8, Figure Product Gases // figure stoic N dot for air - NdotO2 = FuelSupply(FuelCell(GeneratorNum).FuelSupNum).StoicOxygenRate * FuelCell(GeneratorNum).FCPM.NdotFuel; + Real64 NdotO2 = DataGenerators::FuelSupply(this->FuelSupNum).StoicOxygenRate * this->FCPM.NdotFuel; - NdotStoicAir = NdotO2 / FuelCell(GeneratorNum).AirSup.O2fraction; + // Air in excess of match for fuel + Real64 NdotStoicAir = NdotO2 / this->AirSup.O2fraction; // figure excess air rate - NdotExcessAir = FuelCell(GeneratorNum).FCPM.NdotAir - NdotStoicAir; + // Air in excess of match for fuel + Real64 NdotExcessAir = this->FCPM.NdotAir - NdotStoicAir; if (NdotExcessAir < 0) { // can't meet stoichiometric fuel reaction ShowWarningError("Air flow rate into fuel cell is too low for stoichiometric fuel reaction"); - ShowContinueError("Increase air flow in GENERATOR:FC:AIR SUPPLY object:" + FuelCell(GeneratorNum).AirSup.Name); + ShowContinueError("Increase air flow in GENERATOR:FC:AIR SUPPLY object:" + this->AirSup.Name); } // figure CO2 and Water rate from products (coefs setup during one-time processing in gas phase library ) - NdotCO2ProdGas = FuelCell(GeneratorNum).FCPM.NdotFuel * FuelSupply(FuelCell(GeneratorNum).FuelSupNum).CO2ProductGasCoef; + // CO2 from reaction + Real64 NdotCO2ProdGas = this->FCPM.NdotFuel * DataGenerators::FuelSupply(this->FuelSupNum).CO2ProductGasCoef; - NdotH20ProdGas = FuelCell(GeneratorNum).FCPM.NdotFuel * FuelSupply(FuelCell(GeneratorNum).FuelSupNum).H20ProductGasCoef; + // Water from reaction + Real64 NdotH20ProdGas = this->FCPM.NdotFuel * DataGenerators::FuelSupply(this->FuelSupNum).H20ProductGasCoef; // set product gas constituent fractions (assume five usual components) - NdotCO2 = 0.0; - NdotN2 = 0.0; - Ndot02 = 0.0; - NdotH20 = 0.0; - NdotAr = 0.0; + Real64 NdotCO2 = 0.0; // temp CO2 molar rate coef product gas stream + Real64 NdotN2 = 0.0; // temp Nitrogen rate coef product gas stream + Real64 Ndot02 = 0.0; // temp Oxygen rate coef product gas stream + Real64 NdotH20 = 0.0; // temp Water rate coef product gas stream + Real64 NdotAr = 0.0; // temp Argon rate coef product gas stream - // Product gas constiuents are fixed (not a user defined thing) + // Product gas constituents are fixed (not a user defined thing) - for (thisGas = 1; thisGas <= FuelCell(GeneratorNum).AirSup.NumConstituents; ++thisGas) { + for (int thisGas = 1; thisGas <= this->AirSup.NumConstituents; ++thisGas) { { - auto const SELECT_CASE_var(FuelCell(GeneratorNum).AirSup.GasLibID(thisGas)); + auto const SELECT_CASE_var(this->AirSup.GasLibID(thisGas)); if (SELECT_CASE_var == 1) { // all the CO2 coming in plus the new CO2 from reactions - NdotCO2 = NdotCO2ProdGas + FuelCell(GeneratorNum).AirSup.ConstitMolalFract(thisGas) * FuelCell(GeneratorNum).FCPM.NdotAir; + NdotCO2 = NdotCO2ProdGas + this->AirSup.ConstitMolalFract(thisGas) * this->FCPM.NdotAir; } else if (SELECT_CASE_var == 2) { - // all the nitrogen comming in - NdotN2 = FuelCell(GeneratorNum).FCPM.NdotAir * FuelCell(GeneratorNum).AirSup.ConstitMolalFract(thisGas); + // all the nitrogen coming in + NdotN2 = this->FCPM.NdotAir * this->AirSup.ConstitMolalFract(thisGas); } else if (SELECT_CASE_var == 3) { // all the oxygen in the excess air stream - Ndot02 = NdotExcessAir * FuelCell(GeneratorNum).AirSup.ConstitMolalFract(thisGas); + Ndot02 = NdotExcessAir * this->AirSup.ConstitMolalFract(thisGas); } else if (SELECT_CASE_var == 4) { - // all the H20 comming in plus the new H20 from reactions and the H20 from water used in reforming - NdotH20 = NdotH20ProdGas + FuelCell(GeneratorNum).AirSup.ConstitMolalFract(thisGas) * FuelCell(GeneratorNum).FCPM.NdotAir; - //+ FuelCell(GeneratorNum)%FCPM%NdotLiqwater + // all the H20 coming in plus the new H20 from reactions and the H20 from water used in reforming + NdotH20 = NdotH20ProdGas + this->AirSup.ConstitMolalFract(thisGas) * this->FCPM.NdotAir; } else if (SELECT_CASE_var == 5) { // all the argon coming in. - NdotAr = FuelCell(GeneratorNum).FCPM.NdotAir * FuelCell(GeneratorNum).AirSup.ConstitMolalFract(thisGas); + NdotAr = this->FCPM.NdotAir * this->AirSup.ConstitMolalFract(thisGas); } else { } } } - FuelCell(GeneratorNum).FCPM.NdotProdGas = NdotCO2 + NdotN2 + Ndot02 + NdotH20 + NdotAr; + this->FCPM.NdotProdGas = NdotCO2 + NdotN2 + Ndot02 + NdotH20 + NdotAr; // now that we have the total, figure molar fractions - FuelCell(GeneratorNum).FCPM.ConstitMolalFract(1) = NdotCO2 / FuelCell(GeneratorNum).FCPM.NdotProdGas; + this->FCPM.ConstitMolalFract(1) = NdotCO2 / this->FCPM.NdotProdGas; - // all the nitrogen comming in - FuelCell(GeneratorNum).FCPM.ConstitMolalFract(2) = NdotN2 / FuelCell(GeneratorNum).FCPM.NdotProdGas; + // all the nitrogen coming in + this->FCPM.ConstitMolalFract(2) = NdotN2 / this->FCPM.NdotProdGas; // all the oxygen in the excess air stream - FuelCell(GeneratorNum).FCPM.ConstitMolalFract(3) = Ndot02 / FuelCell(GeneratorNum).FCPM.NdotProdGas; + this->FCPM.ConstitMolalFract(3) = Ndot02 / this->FCPM.NdotProdGas; // all the H20 comming in plus the new H20 from reactions and the H20 from water used in reforming - FuelCell(GeneratorNum).FCPM.ConstitMolalFract(4) = NdotH20 / FuelCell(GeneratorNum).FCPM.NdotProdGas; + this->FCPM.ConstitMolalFract(4) = NdotH20 / this->FCPM.NdotProdGas; // all the argon coming in. - FuelCell(GeneratorNum).FCPM.ConstitMolalFract(5) = NdotAr / FuelCell(GeneratorNum).FCPM.NdotProdGas; + this->FCPM.ConstitMolalFract(5) = NdotAr / this->FCPM.NdotProdGas; // HmolProdGases KJ/mol) - FigureProductGasesEnthalpy(GeneratorNum, FuelCell(GeneratorNum).FCPM.TprodGasLeavingFCPM, HmolProdGases); + Real64 HmolProdGases; // enthalpy of product gas mixture in KJ/mol + this->FigureProductGasesEnthalpy(this->FCPM.TprodGasLeavingFCPM, HmolProdGases); // units, NdotProdGas in kmol/sec.; HmolProdGases in KJ/mol , // factor of 1000's to get to J/s or watts - FuelCell(GeneratorNum).FCPM.TotProdGasEnthalphy = HmolProdGases * 1000.0 * FuelCell(GeneratorNum).FCPM.NdotProdGas * 1000.0; + this->FCPM.TotProdGasEnthalphy = HmolProdGases * 1000.0 * this->FCPM.NdotProdGas * 1000.0; // calculation Step 9, Figure Skin lossess - if (FuelCell(GeneratorNum).FCPM.SkinLossMode == ConstantRateSkinLoss) { + if (this->FCPM.SkinLossMode == DataGenerators::ConstantRateSkinLoss) { // do nothing just use QdotSkin - } else if (FuelCell(GeneratorNum).FCPM.SkinLossMode == UADTSkinLoss) { + } else if (this->FCPM.SkinLossMode == DataGenerators::UADTSkinLoss) { // get zone air temp - if (FuelCell(GeneratorNum).FCPM.ZoneID > 0) { - FuelCell(GeneratorNum).FCPM.QdotSkin = FuelCell(GeneratorNum).FCPM.UAskin * - (FuelCell(GeneratorNum).FCPM.TprodGasLeavingFCPM - ZT(FuelCell(GeneratorNum).FCPM.ZoneID)); + if (this->FCPM.ZoneID > 0) { + this->FCPM.QdotSkin = this->FCPM.UAskin * (this->FCPM.TprodGasLeavingFCPM - DataHeatBalFanSys::ZT(this->FCPM.ZoneID)); } - } else if (FuelCell(GeneratorNum).FCPM.SkinLossMode == QuadraticFuelNdotSkin) { + } else if (this->FCPM.SkinLossMode == DataGenerators::QuadraticFuelNdotSkin) { - FuelCell(GeneratorNum).FCPM.QdotSkin = CurveValue(FuelCell(GeneratorNum).FCPM.SkinLossCurveID, FuelCell(GeneratorNum).FCPM.NdotFuel); + this->FCPM.QdotSkin = CurveManager::CurveValue(this->FCPM.SkinLossCurveID, this->FCPM.NdotFuel); } // calculation Step 10, AC FCPM power ancillaries - FuelCell(GeneratorNum).FCPM.PelancillariesAC = - FuelCell(GeneratorNum).FCPM.ANC0 + FuelCell(GeneratorNum).FCPM.ANC1 * FuelCell(GeneratorNum).FCPM.NdotFuel; + this->FCPM.PelancillariesAC = this->FCPM.ANC0 + this->FCPM.ANC1 * this->FCPM.NdotFuel; // calculation Step 11, Dilution air - FigureAirEnthalpy(GeneratorNum, FuelCell(GeneratorNum).AirSup.TairIntoBlower, Hmolair); // (Hmolair in KJ/mol) + this->FigureAirEnthalpy(this->AirSup.TairIntoBlower, Hmolair); // (Hmolair in KJ/mol) // units, NdotDilutionAir in kmol/sec.; Hmolair in KJ/mol , // factor of 1000's to get to J/s or watts - FuelCell(GeneratorNum).FCPM.DilutionAirInEnthalpy = Hmolair * 1000.0 * FuelCell(GeneratorNum).FCPM.NdotDilutionAir * 1000.0; - FuelCell(GeneratorNum).FCPM.DilutionAirOutEnthalpy = - FuelCell(GeneratorNum).FCPM.DilutionAirInEnthalpy + FuelCell(GeneratorNum).FCPM.StackHeatLossToDilution; + this->FCPM.DilutionAirInEnthalpy = Hmolair * 1000.0 * this->FCPM.NdotDilutionAir * 1000.0; + this->FCPM.DilutionAirOutEnthalpy = this->FCPM.DilutionAirInEnthalpy + this->FCPM.StackHeatLossToDilution; // calculation Step 12, Calculate Reforming water out enthalpy - FigureGaseousWaterEnthalpy(FuelCell(GeneratorNum).FCPM.TprodGasLeavingFCPM, HGasWater); + Real64 HGasWater; // temp enthalpy of gaseous water in KJ/mol No Formation + FigureGaseousWaterEnthalpy(this->FCPM.TprodGasLeavingFCPM, HGasWater); - FuelCell(GeneratorNum).FCPM.WaterOutEnthalpy = HGasWater * 1000.0 * FuelCell(GeneratorNum).FCPM.NdotLiqwater * 1000.0; + this->FCPM.WaterOutEnthalpy = HGasWater * 1000.0 * this->FCPM.NdotLiqwater * 1000.0; // calculation Step 13, Calculate Heat balance // move all terms in Equation 7 to RHS and calculate imbalance - MagofImbalance = -FuelCell(GeneratorNum).FCPM.TotFuelInEnthalphy - FuelCell(GeneratorNum).FCPM.TotAirInEnthalphy - - FuelCell(GeneratorNum).FCPM.WaterInEnthalpy - FuelCell(GeneratorNum).FCPM.DilutionAirInEnthalpy - - FuelCell(GeneratorNum).FCPM.NdotFuel * FuelSupply(FuelCell(GeneratorNum).FuelSupNum).LHV * 1000000.0 - - FuelCell(GeneratorNum).FCPM.PelancillariesAC + FuelCell(GeneratorNum).FCPM.Pel + - FuelCell(GeneratorNum).FCPM.TotProdGasEnthalphy + FuelCell(GeneratorNum).FCPM.WaterOutEnthalpy + - FuelCell(GeneratorNum).FCPM.QdotStackCool + FuelCell(GeneratorNum).FCPM.QdotSkin + - FuelCell(GeneratorNum).FCPM.DilutionAirOutEnthalpy; + Real64 MagofImbalance = -this->FCPM.TotFuelInEnthalphy - this->FCPM.TotAirInEnthalphy - this->FCPM.WaterInEnthalpy - + this->FCPM.DilutionAirInEnthalpy - + this->FCPM.NdotFuel * DataGenerators::FuelSupply(this->FuelSupNum).LHV * 1000000.0 - this->FCPM.PelancillariesAC + + this->FCPM.Pel + this->FCPM.TotProdGasEnthalphy + this->FCPM.WaterOutEnthalpy + this->FCPM.QdotStackCool + + this->FCPM.QdotSkin + this->FCPM.DilutionAirOutEnthalpy; // Now find a new total prod Gas Enthalphy that would result in an energy balance // TODO check signs... - tmpTotProdGasEnthalphy = FuelCell(GeneratorNum).FCPM.TotProdGasEnthalphy - MagofImbalance; + Real64 tmpTotProdGasEnthalpy = this->FCPM.TotProdGasEnthalphy - MagofImbalance; // solve for a new TprodGasLeavingFCPM using regula falsi method - Acc = 0.01; // guessing need to refine - MaxIter = 150; // guessing need to refine - SolverFlag = 0; // init - Par(1) = double(GeneratorNum); - Par(2) = tmpTotProdGasEnthalphy; - Par(3) = FuelCell(GeneratorNum).FCPM.NdotProdGas; - tmpTprodGas = FuelCell(GeneratorNum).FCPM.TprodGasLeavingFCPM; - SolveRoot(Acc, MaxIter, SolverFlag, tmpTprodGas, FuelCellProductGasEnthResidual, MinProductGasTemp, MaxProductGasTemp, Par); + Real64 Acc = 0.01; // guessing need to refine + int MaxIter = 150; // guessing need to refine + SolverFlag = 0; // init + Array1D Par(2); // parameters passed in to SolveRoot + Par(1) = tmpTotProdGasEnthalpy; + Par(2) = this->FCPM.NdotProdGas; + Real64 tmpTprodGas = this->FCPM.TprodGasLeavingFCPM; + auto boundFunc = std::bind(&FCDataStruct::FuelCellProductGasEnthResidual, this, std::placeholders::_1, std::placeholders::_2); + General::SolveRoot( + Acc, MaxIter, SolverFlag, tmpTprodGas, boundFunc, DataGenerators::MinProductGasTemp, DataGenerators::MaxProductGasTemp, Par); if (SolverFlag == -2) { @@ -1962,59 +1832,56 @@ namespace FuelCellElectricGenerator { ShowWarningError("CalcFuelCellGeneratorModel: Root Solver problem, flag = -1, check accuracy and iterations, did not converge"); } if (SolverFlag > 0) { - FuelCell(GeneratorNum).FCPM.TprodGasLeavingFCPM = tmpTprodGas; + this->FCPM.TprodGasLeavingFCPM = tmpTprodGas; // write(*,*) 'Number of Root Solver iterations: ', solverFlag } - // moved call to HeatBalanceInternalGains. Call FigureFuelCellZoneGains(GeneratorNum) - // Control Step 3 determine interaction with electrical storage // How much power is really going into inverter? - PintoInverter = Pel + Pstorage; // Back out so we can reapply - ManageElectStorInteractions(GeneratorNum, Pdemand, PpcuLosses, ConstrainedStorage, Pstorage, PgridExtra); + Real64 PintoInverter = Pel + Pstorage; // Back out so we can reapply + bool ConstrainedStorage; + this->ManageElectStorInteractions(Pdemand, PpcuLosses, ConstrainedStorage, Pstorage, PgridExtra); PintoInverter = Pel - Pstorage; // refine power conditioning losses with more current power production - if (FuelCell(GeneratorNum).Inverter.EffMode == InverterEffConstant) { + if (this->Inverter.EffMode == DataGenerators::InverterEffConstant) { - PpcuLosses = (1.0 - FuelCell(GeneratorNum).Inverter.ConstEff) * PintoInverter; + PpcuLosses = (1.0 - this->Inverter.ConstEff) * PintoInverter; } - if (FuelCell(GeneratorNum).Inverter.EffMode == InverterEffQuadratic) { + if (this->Inverter.EffMode == DataGenerators::InverterEffQuadratic) { - PpcuLosses = (1.0 - CurveValue(FuelCell(GeneratorNum).Inverter.EffQuadraticCurveID, PintoInverter)) * PintoInverter; + PpcuLosses = (1.0 - CurveManager::CurveValue(this->Inverter.EffQuadraticCurveID, PintoInverter)) * PintoInverter; } PoutofInverter = PintoInverter - PpcuLosses; - FuelCell(GeneratorNum).ACPowerGen = PoutofInverter - FuelCell(GeneratorNum).FCPM.PelancillariesAC - - FuelCell(GeneratorNum).AirSup.PairCompEl - FuelSupply(FuelCell(GeneratorNum).FuelSupNum).PfuelCompEl - - FuelCell(GeneratorNum).WaterSup.PwaterCompEl; - FuelCell(GeneratorNum).Inverter.PCUlosses = PpcuLosses; + this->ACPowerGen = PoutofInverter - this->FCPM.PelancillariesAC - this->AirSup.PairCompEl - + DataGenerators::FuelSupply(this->FuelSupNum).PfuelCompEl - this->WaterSup.PwaterCompEl; + this->Inverter.PCUlosses = PpcuLosses; // model assumes air intake is drawn over power conditioner to recovery heat - FuelCell(GeneratorNum).Inverter.QairIntake = FuelCell(GeneratorNum).Inverter.PCUlosses; + this->Inverter.QairIntake = this->Inverter.PCUlosses; - CalcFuelCellAuxHeater(GeneratorNum); + this->CalcFuelCellAuxHeater(); - CalcFuelCellGenHeatRecovery(GeneratorNum); + this->CalcFuelCellGenHeatRecovery(); // calculation Step 11, If imbalance below threshold, then exit out of do loop. - if ((std::abs(MagofImbalance) < std::abs(ImBalanceTol * FuelCell(GeneratorNum).FCPM.Pel)) && (iter > 2)) { + if ((std::abs(MagofImbalance) < std::abs(DataGenerators::ImBalanceTol * this->FCPM.Pel)) && (iter > 2)) { break; } } // sequential substitution loop - FuelCell(GeneratorNum).FCPM.SeqSubstitIter = iter; - FuelCell(GeneratorNum).FCPM.RegulaFalsiIter = SolverFlag; + this->FCPM.SeqSubstitIter = iter; + this->FCPM.RegulaFalsiIter = SolverFlag; } - void ManageElectStorInteractions(int const Num, // Generator number, index for structure - Real64 const Pdemand, - Real64 const EP_UNUSED(PpcuLosses), - bool &Constrained, - Real64 &Pstorage, - Real64 &PgridOverage // electricity that can't be stored and needs to go out + void FCDataStruct::ManageElectStorInteractions(Real64 const Pdemand, + Real64 const EP_UNUSED(PpcuLosses), + bool &Constrained, + Real64 &Pstorage, + Real64 &PgridOverage // electricity that can't be stored and needs to go out ) { @@ -2027,52 +1894,23 @@ namespace FuelCellElectricGenerator { // PURPOSE OF THIS SUBROUTINE: // manage controls and calculations related to electrical storage in FuelCell model - // METHODOLOGY EMPLOYED: - - // REFERENCES: - // na - - // Using/Aliasing - using DataHVACGlobals::TimeStepSys; - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - Real64 tmpPdraw; // power draw from storage, working var - Real64 tmpPcharge; // power charge to storage, working var - bool drawing; // true if drawing power - bool charging; // true if charging - - // initialize locals - tmpPdraw = 0.0; - tmpPcharge = 0.0; - drawing = false; - charging = false; + Real64 tmpPdraw = 0.0; + Real64 tmpPcharge = 0.0; + bool drawing = false; // true if drawing power + bool charging = false; // true if charging Constrained = false; - Pstorage = 0.0; - PgridOverage = 0.0; // step 1 figure out what is desired of electrical storage system - if (FuelCell(Num).FCPM.Pel < (Pdemand)) { + if (this->FCPM.Pel < (Pdemand)) { // draw from storage - tmpPdraw = (Pdemand)-FuelCell(Num).FCPM.Pel; + tmpPdraw = (Pdemand) - this->FCPM.Pel; drawing = true; } - if (FuelCell(Num).FCPM.Pel > (Pdemand)) { + if (this->FCPM.Pel > (Pdemand)) { // add to storage - tmpPcharge = FuelCell(Num).FCPM.Pel - (Pdemand); + tmpPcharge = this->FCPM.Pel - (Pdemand); charging = true; } @@ -2080,45 +1918,45 @@ namespace FuelCellElectricGenerator { if (charging) { - if (FuelCell(Num).ElecStorage.StorageModelMode == SimpleEffConstraints) { + if (this->ElecStorage.StorageModelMode == DataGenerators::SimpleEffConstraints) { - if (FuelCell(Num).ElecStorage.LastTimeStepStateOfCharge >= FuelCell(Num).ElecStorage.NominalEnergyCapacity) { + if (this->ElecStorage.LastTimeStepStateOfCharge >= this->ElecStorage.NominalEnergyCapacity) { // storage full! no more allowed! PgridOverage = tmpPcharge; tmpPcharge = 0.0; Constrained = true; } - if (tmpPcharge > FuelCell(Num).ElecStorage.MaxPowerStore) { - PgridOverage = tmpPcharge - FuelCell(Num).ElecStorage.MaxPowerStore; - tmpPcharge = FuelCell(Num).ElecStorage.MaxPowerStore; + if (tmpPcharge > this->ElecStorage.MaxPowerStore) { + PgridOverage = tmpPcharge - this->ElecStorage.MaxPowerStore; + tmpPcharge = this->ElecStorage.MaxPowerStore; Constrained = true; } // now add energy to storage from charging - if ((FuelCell(Num).ElecStorage.LastTimeStepStateOfCharge + - tmpPcharge * TimeStepSys * SecInHour * FuelCell(Num).ElecStorage.EnergeticEfficCharge) < - FuelCell(Num).ElecStorage.NominalEnergyCapacity) { + if ((this->ElecStorage.LastTimeStepStateOfCharge + + tmpPcharge * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour * this->ElecStorage.EnergeticEfficCharge) < + this->ElecStorage.NominalEnergyCapacity) { - FuelCell(Num).ElecStorage.ThisTimeStepStateOfCharge = - FuelCell(Num).ElecStorage.LastTimeStepStateOfCharge + - tmpPcharge * TimeStepSys * SecInHour * FuelCell(Num).ElecStorage.EnergeticEfficCharge; + this->ElecStorage.ThisTimeStepStateOfCharge = + this->ElecStorage.LastTimeStepStateOfCharge + + tmpPcharge * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour * this->ElecStorage.EnergeticEfficCharge; } else { // would over charge this time step - tmpPcharge = (FuelCell(Num).ElecStorage.NominalEnergyCapacity - FuelCell(Num).ElecStorage.LastTimeStepStateOfCharge) / - (TimeStepSys * SecInHour * FuelCell(Num).ElecStorage.EnergeticEfficCharge); + tmpPcharge = (this->ElecStorage.NominalEnergyCapacity - this->ElecStorage.LastTimeStepStateOfCharge) / + (DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour * this->ElecStorage.EnergeticEfficCharge); Constrained = true; - FuelCell(Num).ElecStorage.ThisTimeStepStateOfCharge = - FuelCell(Num).ElecStorage.LastTimeStepStateOfCharge + - tmpPcharge * TimeStepSys * SecInHour * FuelCell(Num).ElecStorage.EnergeticEfficCharge; + this->ElecStorage.ThisTimeStepStateOfCharge = + this->ElecStorage.LastTimeStepStateOfCharge + + tmpPcharge * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour * this->ElecStorage.EnergeticEfficCharge; } // losses go into QairIntake - FuelCell(Num).ElecStorage.QairIntake = tmpPcharge * (1.0 - FuelCell(Num).ElecStorage.EnergeticEfficCharge); + this->ElecStorage.QairIntake = tmpPcharge * (1.0 - this->ElecStorage.EnergeticEfficCharge); - } else if (FuelCell(Num).ElecStorage.StorageModelMode == LeadAcidBatterManwellMcGowan) { + } else if (this->ElecStorage.StorageModelMode == DataGenerators::LeadAcidBatterManwellMcGowan) { ShowWarningError("ManageElectStorInteractions: Not yet implemented: Lead Acid Battery By Manwell and McGowan 1993 "); - } else if (FuelCell(Num).ElecStorage.StorageModelMode == LeadAcidBatterySaupe) { + } else if (this->ElecStorage.StorageModelMode == DataGenerators::LeadAcidBatterySaupe) { ShowWarningError("ManageElectStorInteractions: Not yet implemented: Lead Acid Battery By Saupe 1993 "); } else { @@ -2131,41 +1969,41 @@ namespace FuelCellElectricGenerator { } // charging if (drawing) { - if (FuelCell(Num).ElecStorage.StorageModelMode == SimpleEffConstraints) { + if (this->ElecStorage.StorageModelMode == DataGenerators::SimpleEffConstraints) { - if (FuelCell(Num).ElecStorage.LastTimeStepStateOfCharge <= 0.0) { + if (this->ElecStorage.LastTimeStepStateOfCharge <= 0.0) { // storage empty no more allowed! tmpPdraw = 0.0; Constrained = true; drawing = false; } - if (tmpPdraw > FuelCell(Num).ElecStorage.MaxPowerDraw) { - tmpPdraw = FuelCell(Num).ElecStorage.MaxPowerDraw; + if (tmpPdraw > this->ElecStorage.MaxPowerDraw) { + tmpPdraw = this->ElecStorage.MaxPowerDraw; Constrained = true; } // now take energy from storage by drawing (amplified by energetic effic) - if ((FuelCell(Num).ElecStorage.LastTimeStepStateOfCharge - - tmpPdraw * TimeStepSys * SecInHour / FuelCell(Num).ElecStorage.EnergeticEfficDischarge) > 0.0) { + if ((this->ElecStorage.LastTimeStepStateOfCharge - + tmpPdraw * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour / this->ElecStorage.EnergeticEfficDischarge) > 0.0) { - FuelCell(Num).ElecStorage.ThisTimeStepStateOfCharge = - FuelCell(Num).ElecStorage.LastTimeStepStateOfCharge - - tmpPdraw * TimeStepSys * SecInHour / FuelCell(Num).ElecStorage.EnergeticEfficDischarge; + this->ElecStorage.ThisTimeStepStateOfCharge = + this->ElecStorage.LastTimeStepStateOfCharge - + tmpPdraw * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour / this->ElecStorage.EnergeticEfficDischarge; } else { // would over drain storage this timestep so reduce tmpPdraw - tmpPdraw = FuelCell(Num).ElecStorage.LastTimeStepStateOfCharge * FuelCell(Num).ElecStorage.EnergeticEfficDischarge / - (TimeStepSys * SecInHour); - FuelCell(Num).ElecStorage.ThisTimeStepStateOfCharge = - FuelCell(Num).ElecStorage.LastTimeStepStateOfCharge - - tmpPdraw * TimeStepSys * SecInHour / FuelCell(Num).ElecStorage.EnergeticEfficDischarge; + tmpPdraw = this->ElecStorage.LastTimeStepStateOfCharge * this->ElecStorage.EnergeticEfficDischarge / + (DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour); + this->ElecStorage.ThisTimeStepStateOfCharge = + this->ElecStorage.LastTimeStepStateOfCharge - + tmpPdraw * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour / this->ElecStorage.EnergeticEfficDischarge; Constrained = true; } // losses go into QairIntake - FuelCell(Num).ElecStorage.QairIntake = tmpPdraw * (1.0 / FuelCell(Num).ElecStorage.EnergeticEfficDischarge - 1.0); - } else if (FuelCell(Num).ElecStorage.StorageModelMode == LeadAcidBatterManwellMcGowan) { + this->ElecStorage.QairIntake = tmpPdraw * (1.0 / this->ElecStorage.EnergeticEfficDischarge - 1.0); + } else if (this->ElecStorage.StorageModelMode == DataGenerators::LeadAcidBatterManwellMcGowan) { ShowWarningError("ManageElectStorInteractions: Not yet implemented: Lead Acid Battery By Manwell and McGowan 1993 "); - } else if (FuelCell(Num).ElecStorage.StorageModelMode == LeadAcidBatterySaupe) { + } else if (this->ElecStorage.StorageModelMode == DataGenerators::LeadAcidBatterySaupe) { ShowWarningError("ManageElectStorInteractions: Not yet implemented: Lead Acid Battery By Saupe 1993 "); } else { @@ -2179,26 +2017,26 @@ namespace FuelCellElectricGenerator { if ((!charging) && (!drawing)) { - FuelCell(Num).ElecStorage.ThisTimeStepStateOfCharge = FuelCell(Num).ElecStorage.LastTimeStepStateOfCharge; - FuelCell(Num).ElecStorage.PelNeedFromStorage = 0.0; - FuelCell(Num).ElecStorage.PelFromStorage = 0.0; - FuelCell(Num).ElecStorage.QairIntake = 0.0; + this->ElecStorage.ThisTimeStepStateOfCharge = this->ElecStorage.LastTimeStepStateOfCharge; + this->ElecStorage.PelNeedFromStorage = 0.0; + this->ElecStorage.PelFromStorage = 0.0; + this->ElecStorage.QairIntake = 0.0; } if (Pstorage >= 0.0) { - FuelCell(Num).ElecStorage.PelIntoStorage = Pstorage; - FuelCell(Num).ElecStorage.PelFromStorage = 0.0; + this->ElecStorage.PelIntoStorage = Pstorage; + this->ElecStorage.PelFromStorage = 0.0; } if (Pstorage < 0.0) { - FuelCell(Num).ElecStorage.PelIntoStorage = 0.0; - FuelCell(Num).ElecStorage.PelFromStorage = -Pstorage; + this->ElecStorage.PelIntoStorage = 0.0; + this->ElecStorage.PelFromStorage = -Pstorage; } } - Real64 FuelCellProductGasEnthResidual(Real64 const TprodGas, // temperature, this is "x" being searched - Array1 const &Par // par(1) = Generator Number + Real64 FCDataStruct::FuelCellProductGasEnthResidual(Real64 const TprodGas, // temperature, this is "x" being searched + Array1 const &Par // par(1) = Generator Number ) { @@ -2217,50 +2055,20 @@ namespace FuelCellElectricGenerator { // Calculates residual function for product gas enthalpy // calls procedure FigureProductGasesEnthalpy - // REFERENCES: - // na - - // USE STATEMENTS: - // na - - // Return value Real64 Residuum; // F(x) - // Argument array dimensioning - - // Locals - // FUNCTION ARGUMENT DEFINITIONS: - // par(2) = Desired Enthalpy - // FUNCTION PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na - - // FUNCTION LOCAL VARIABLE DECLARATIONS: - int GeneratorNum; Real64 thisHmolalProdGases; - Real64 desiredHprodGases; - Real64 NdotProdGases; - - GeneratorNum = std::floor(Par(1)); - desiredHprodGases = Par(2); - NdotProdGases = Par(3); + Real64 desiredHprodGases = Par(1); + Real64 NdotProdGases = Par(2); - FigureProductGasesEnthalpy(GeneratorNum, TprodGas, thisHmolalProdGases); + this->FigureProductGasesEnthalpy(TprodGas, thisHmolalProdGases); Residuum = (thisHmolalProdGases * NdotProdGases * 1000000.0) - desiredHprodGases; return Residuum; } - void FigureAirHeatCap(int const GeneratorNum, // ID of generator FuelCell data structure - Real64 const FluidTemp, // degree C - Real64 &Cp // (J/mol*K) - ) + void FCDataStruct::FigureAirHeatCap(Real64 const FluidTemp, Real64 &Cp) { // SUBROUTINE INFORMATION: @@ -2279,25 +2087,6 @@ namespace FuelCellElectricGenerator { // REFERENCES: // NIST Webbook on gas phase thermochemistry - // USE STATEMENTS: - // na - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - Real64 tempCp; - int thisConstit; // loop index - int gasID; Real64 A; // shomate coeff Real64 B; // shomate coeff Real64 C; // shomate coeff @@ -2313,10 +2102,10 @@ namespace FuelCellElectricGenerator { // two different themodynamic curve fits might be used - tempCp = 0.0; + Real64 tempCp = 0.0; - Real64 const Tkel = (FluidTemp + KelvinConv); // temp for NASA eq. in Kelvin - Real64 const Tsho = (FluidTemp + KelvinConv) / 1000.0; // temp for Shomate eq in (Kelvin/1000) + Real64 const Tkel = (FluidTemp + DataGlobals::KelvinConv); // temp for NASA eq. in Kelvin + Real64 const Tsho = (FluidTemp + DataGlobals::KelvinConv) / 1000.0; // temp for Shomate eq in (Kelvin/1000) Real64 const pow_2_Tsho(pow_2(Tsho)); Real64 const pow_3_Tsho(pow_3(Tsho)); @@ -2324,31 +2113,30 @@ namespace FuelCellElectricGenerator { Real64 const pow_3_Tkel(pow_3(Tkel)); Real64 const pow_4_Tkel(pow_4(Tkel)); - for (thisConstit = 1; thisConstit <= FuelCell(GeneratorNum).AirSup.NumConstituents; ++thisConstit) { - gasID = FuelCell(GeneratorNum).AirSup.GasLibID(thisConstit); + for (int thisConstit = 1; thisConstit <= this->AirSup.NumConstituents; ++thisConstit) { + int gasID = this->AirSup.GasLibID(thisConstit); if (gasID > 0) { - if (GasPhaseThermoChemistryData(gasID).ThermoMode == NISTShomate) { + if (DataGenerators::GasPhaseThermoChemistryData(gasID).ThermoMode == DataGenerators::NISTShomate) { - A = GasPhaseThermoChemistryData(gasID).ShomateA; - B = GasPhaseThermoChemistryData(gasID).ShomateB; - C = GasPhaseThermoChemistryData(gasID).ShomateC; - D = GasPhaseThermoChemistryData(gasID).ShomateD; - E = GasPhaseThermoChemistryData(gasID).ShomateE; + A = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateA; + B = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateB; + C = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateC; + D = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateD; + E = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateE; - tempCp += ((A + B * Tsho + C * pow_2_Tsho + D * pow_3_Tsho + E / pow_2_Tsho) * - FuelCell(GeneratorNum).AirSup.ConstitMolalFract(thisConstit)); + tempCp += ((A + B * Tsho + C * pow_2_Tsho + D * pow_3_Tsho + E / pow_2_Tsho) * this->AirSup.ConstitMolalFract(thisConstit)); } - if (GasPhaseThermoChemistryData(gasID).ThermoMode == NASAPolynomial) { + if (DataGenerators::GasPhaseThermoChemistryData(gasID).ThermoMode == DataGenerators::NASAPolynomial) { - A1 = GasPhaseThermoChemistryData(gasID).NASA_A1; - A2 = GasPhaseThermoChemistryData(gasID).NASA_A2; - A3 = GasPhaseThermoChemistryData(gasID).NASA_A3; - A4 = GasPhaseThermoChemistryData(gasID).NASA_A4; - A5 = GasPhaseThermoChemistryData(gasID).NASA_A5; + A1 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A1; + A2 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A2; + A3 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A3; + A4 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A4; + A5 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A5; - tempCp += (A1 + A2 * Tkel + A3 * pow_2_Tkel + A4 * pow_3_Tkel + A5 * pow_4_Tkel) * RinKJperMolpK * - FuelCell(GeneratorNum).AirSup.ConstitMolalFract(thisConstit); + tempCp += (A1 + A2 * Tkel + A3 * pow_2_Tkel + A4 * pow_3_Tkel + A5 * pow_4_Tkel) * DataGenerators::RinKJperMolpK * + this->AirSup.ConstitMolalFract(thisConstit); } } } @@ -2356,10 +2144,7 @@ namespace FuelCellElectricGenerator { Cp = tempCp; } - void FigureAirEnthalpy(int const GeneratorNum, // ID of generator FuelCell data structure - Real64 const FluidTemp, // degree C - Real64 &Hair // (kJ/mol) - ) + void FCDataStruct::FigureAirEnthalpy(Real64 const FluidTemp, Real64 &Hair) { // SUBROUTINE INFORMATION: @@ -2378,46 +2163,26 @@ namespace FuelCellElectricGenerator { // REFERENCES: // NIST Webbook on gas phase thermochemistry - // USE STATEMENTS: - // na - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - Real64 tempHair; - Real64 HairI; - int thisConstit; // loop index - int gasID; // look up into Gas structure - Real64 A; // shomate coeff - Real64 B; // shomate coeff - Real64 C; // shomate coeff - Real64 D; // shomate coeff - Real64 E; // shomate coeff - Real64 F; // shomate coeff - Real64 H; // shomate coeff - Real64 A1; // NASA poly coeff - Real64 A2; // NASA poly coeff - Real64 A3; // NASA poly coeff - Real64 A4; // NASA poly coeff - Real64 A5; // NASA poly coeff - Real64 A6; // NASA poly coeff - - Real64 const Tsho = (FluidTemp + KelvinConv) / 1000.0; // temp for Shomate eq in (Kelvin/1000) - Real64 const Tkel = (FluidTemp + KelvinConv); // temp for NASA eq. in Kelvin + Real64 A; // shomate coeff + Real64 B; // shomate coeff + Real64 C; // shomate coeff + Real64 D; // shomate coeff + Real64 E; // shomate coeff + Real64 F; // shomate coeff + Real64 H; // shomate coeff + Real64 A1; // NASA poly coeff + Real64 A2; // NASA poly coeff + Real64 A3; // NASA poly coeff + Real64 A4; // NASA poly coeff + Real64 A5; // NASA poly coeff + Real64 A6; // NASA poly coeff + + Real64 const Tsho = (FluidTemp + DataGlobals::KelvinConv) / 1000.0; // temp for Shomate eq in (Kelvin/1000) + Real64 const Tkel = (FluidTemp + DataGlobals::KelvinConv); // temp for NASA eq. in Kelvin // loop through fuel constituents and sum up Cp - tempHair = 0.0; + Real64 tempHair = 0.0; Real64 const pow_2_Tsho(pow_2(Tsho)); Real64 const pow_3_Tsho(pow_3(Tsho)); @@ -2426,35 +2191,35 @@ namespace FuelCellElectricGenerator { Real64 const pow_3_Tkel(pow_3(Tkel)); Real64 const pow_4_Tkel(pow_4(Tkel)); - for (thisConstit = 1; thisConstit <= FuelCell(GeneratorNum).AirSup.NumConstituents; ++thisConstit) { - gasID = FuelCell(GeneratorNum).AirSup.GasLibID(thisConstit); + for (int thisConstit = 1; thisConstit <= this->AirSup.NumConstituents; ++thisConstit) { + int gasID = this->AirSup.GasLibID(thisConstit); if (gasID > 0) { - if (GasPhaseThermoChemistryData(gasID).ThermoMode == NISTShomate) { + if (DataGenerators::GasPhaseThermoChemistryData(gasID).ThermoMode == DataGenerators::NISTShomate) { - A = GasPhaseThermoChemistryData(gasID).ShomateA; - B = GasPhaseThermoChemistryData(gasID).ShomateB; - C = GasPhaseThermoChemistryData(gasID).ShomateC; - D = GasPhaseThermoChemistryData(gasID).ShomateD; - E = GasPhaseThermoChemistryData(gasID).ShomateE; - F = GasPhaseThermoChemistryData(gasID).ShomateF; - H = GasPhaseThermoChemistryData(gasID).ShomateH; + A = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateA; + B = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateB; + C = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateC; + D = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateD; + E = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateE; + F = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateF; + H = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateH; - HairI = (A * Tsho + B * pow_2_Tsho / 2.0 + C * pow_3_Tsho / 3.0 + D * pow_4_Tsho / 4.0 - E / Tsho + F - H); + Real64 HairI = (A * Tsho + B * pow_2_Tsho / 2.0 + C * pow_3_Tsho / 3.0 + D * pow_4_Tsho / 4.0 - E / Tsho + F - H); - tempHair += HairI * FuelCell(GeneratorNum).AirSup.ConstitMolalFract(thisConstit); + tempHair += HairI * this->AirSup.ConstitMolalFract(thisConstit); } - if (GasPhaseThermoChemistryData(gasID).ThermoMode == NASAPolynomial) { - A1 = GasPhaseThermoChemistryData(gasID).NASA_A1; - A2 = GasPhaseThermoChemistryData(gasID).NASA_A2; - A3 = GasPhaseThermoChemistryData(gasID).NASA_A3; - A4 = GasPhaseThermoChemistryData(gasID).NASA_A4; - A5 = GasPhaseThermoChemistryData(gasID).NASA_A5; - A6 = GasPhaseThermoChemistryData(gasID).NASA_A6; + if (DataGenerators::GasPhaseThermoChemistryData(gasID).ThermoMode == DataGenerators::NASAPolynomial) { + A1 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A1; + A2 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A2; + A3 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A3; + A4 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A4; + A5 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A5; + A6 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A6; tempHair += (((A1 + A2 * Tkel / 2.0 + A3 * pow_2_Tkel / 3.0 + A4 * pow_3_Tkel / 4.0 + A5 * pow_4_Tkel / 5.0 + A6 / Tkel) * - RinKJperMolpK * Tkel) - - GasPhaseThermoChemistryData(gasID).StdRefMolarEnthOfForm) * - FuelCell(GeneratorNum).AirSup.ConstitMolalFract(thisConstit); + DataGenerators::RinKJperMolpK * Tkel) - + DataGenerators::GasPhaseThermoChemistryData(gasID).StdRefMolarEnthOfForm) * + this->AirSup.ConstitMolalFract(thisConstit); } } } @@ -2462,10 +2227,7 @@ namespace FuelCellElectricGenerator { Hair = tempHair; } - void FigureFuelHeatCap(int const GeneratorNum, // ID of generator FuelCell data structure - Real64 const FluidTemp, // degree C - Real64 &Cp // (J/mol*K) - ) + void FCDataStruct::FigureFuelHeatCap(Real64 const FluidTemp, Real64 &Cp) { // SUBROUTINE INFORMATION: @@ -2484,42 +2246,23 @@ namespace FuelCellElectricGenerator { // REFERENCES: // NIST Webbook on gas phase thermochemistry - // USE STATEMENTS: - // na - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na + Real64 A; // shomate coeff + Real64 B; // shomate coeff + Real64 C; // shomate coeff + Real64 D; // shomate coeff + Real64 E; // shomate coeff + Real64 A1; // NASA poly coeff + Real64 A2; // NASA poly coeff + Real64 A3; // NASA poly coeff + Real64 A4; // NASA poly coeff + Real64 A5; // NASA poly coeff - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - Real64 tempCp; - int thisConstit; // loop index - int gasID; // look up into Gas structure - Real64 A; // shomate coeff - Real64 B; // shomate coeff - Real64 C; // shomate coeff - Real64 D; // shomate coeff - Real64 E; // shomate coeff - Real64 A1; // NASA poly coeff - Real64 A2; // NASA poly coeff - Real64 A3; // NASA poly coeff - Real64 A4; // NASA poly coeff - Real64 A5; // NASA poly coeff - - Real64 const Tsho = (FluidTemp + KelvinConv) / 1000.0; // temp for Shomate eq in (Kelvin/1000) - Real64 const Tkel = (FluidTemp + KelvinConv); // temp for NASA eq. in Kelvin + Real64 const Tsho = (FluidTemp + DataGlobals::KelvinConv) / 1000.0; // temp for Shomate eq in (Kelvin/1000) + Real64 const Tkel = (FluidTemp + DataGlobals::KelvinConv); // temp for NASA eq. in Kelvin // loop through fuel constituents and sum up Cp - tempCp = 0.0; + Real64 tempCp = 0.0; Real64 const pow_2_Tsho(pow_2(Tsho)); Real64 const pow_3_Tsho(pow_3(Tsho)); @@ -2527,30 +2270,30 @@ namespace FuelCellElectricGenerator { Real64 const pow_3_Tkel(pow_3(Tkel)); Real64 const pow_4_Tkel(pow_4(Tkel)); - for (thisConstit = 1; thisConstit <= FuelSupply(FuelCell(GeneratorNum).FuelSupNum).NumConstituents; ++thisConstit) { - gasID = FuelSupply(FuelCell(GeneratorNum).FuelSupNum).GasLibID(thisConstit); + for (int thisConstit = 1; thisConstit <= DataGenerators::FuelSupply(this->FuelSupNum).NumConstituents; ++thisConstit) { + int gasID = DataGenerators::FuelSupply(this->FuelSupNum).GasLibID(thisConstit); if (gasID > 0) { - if (GasPhaseThermoChemistryData(gasID).ThermoMode == NISTShomate) { + if (DataGenerators::GasPhaseThermoChemistryData(gasID).ThermoMode == DataGenerators::NISTShomate) { - A = GasPhaseThermoChemistryData(gasID).ShomateA; - B = GasPhaseThermoChemistryData(gasID).ShomateB; - C = GasPhaseThermoChemistryData(gasID).ShomateC; - D = GasPhaseThermoChemistryData(gasID).ShomateD; - E = GasPhaseThermoChemistryData(gasID).ShomateE; + A = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateA; + B = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateB; + C = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateC; + D = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateD; + E = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateE; tempCp += ((A + B * Tsho + C * pow_2_Tsho + D * pow_3_Tsho + E / pow_2_Tsho) * - FuelSupply(FuelCell(GeneratorNum).FuelSupNum).ConstitMolalFract(thisConstit)); + DataGenerators::FuelSupply(this->FuelSupNum).ConstitMolalFract(thisConstit)); } - if (GasPhaseThermoChemistryData(gasID).ThermoMode == NASAPolynomial) { - A1 = GasPhaseThermoChemistryData(gasID).NASA_A1; - A2 = GasPhaseThermoChemistryData(gasID).NASA_A2; - A3 = GasPhaseThermoChemistryData(gasID).NASA_A3; - A4 = GasPhaseThermoChemistryData(gasID).NASA_A4; - A5 = GasPhaseThermoChemistryData(gasID).NASA_A5; + if (DataGenerators::GasPhaseThermoChemistryData(gasID).ThermoMode == DataGenerators::NASAPolynomial) { + A1 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A1; + A2 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A2; + A3 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A3; + A4 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A4; + A5 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A5; - tempCp += (A1 + A2 * Tkel + A3 * pow_2_Tkel + A4 * pow_3_Tkel + A5 * pow_4_Tkel) * RinKJperMolpK * - FuelSupply(FuelCell(GeneratorNum).FuelSupNum).ConstitMolalFract(thisConstit); + tempCp += (A1 + A2 * Tkel + A3 * pow_2_Tkel + A4 * pow_3_Tkel + A5 * pow_4_Tkel) * DataGenerators::RinKJperMolpK * + DataGenerators::FuelSupply(this->FuelSupNum).ConstitMolalFract(thisConstit); } } } @@ -2558,10 +2301,7 @@ namespace FuelCellElectricGenerator { Cp = tempCp; } - void FigureFuelEnthalpy(int const GeneratorNum, // ID of generator FuelCell data structure - Real64 const FluidTemp, // degree C - Real64 &Hfuel // kJ/mol - ) + void FCDataStruct::FigureFuelEnthalpy(Real64 const FluidTemp, Real64 &Hfuel) { // SUBROUTINE INFORMATION: @@ -2580,46 +2320,26 @@ namespace FuelCellElectricGenerator { // REFERENCES: // NIST Webbook on gas phase thermochemistry - // USE STATEMENTS: - // na - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - Real64 tempHfuel; - Real64 HfuelI; - int thisConstit; // loop index - int gasID; // look up into Gas structure - Real64 A; // shomate coeff - Real64 B; // shomate coeff - Real64 C; // shomate coeff - Real64 D; // shomate coeff - Real64 E; // shomate coeff - Real64 F; // shomate coeff - Real64 H; // shomate coeff - Real64 A1; // NASA poly coeff - Real64 A2; // NASA poly coeff - Real64 A3; // NASA poly coeff - Real64 A4; // NASA poly coeff - Real64 A5; // NASA poly coeff - Real64 A6; // NASA poly coeff - - Real64 const Tsho = (FluidTemp + KelvinConv) / 1000.0; // temp for Shomate eq in (Kelvin/1000) - Real64 const Tkel = (FluidTemp + KelvinConv); // temp for NASA eq. in Kelvin + Real64 A; // shomate coeff + Real64 B; // shomate coeff + Real64 C; // shomate coeff + Real64 D; // shomate coeff + Real64 E; // shomate coeff + Real64 F; // shomate coeff + Real64 H; // shomate coeff + Real64 A1; // NASA poly coeff + Real64 A2; // NASA poly coeff + Real64 A3; // NASA poly coeff + Real64 A4; // NASA poly coeff + Real64 A5; // NASA poly coeff + Real64 A6; // NASA poly coeff + + Real64 const Tsho = (FluidTemp + DataGlobals::KelvinConv) / 1000.0; // temp for Shomate eq in (Kelvin/1000) + Real64 const Tkel = (FluidTemp + DataGlobals::KelvinConv); // temp for NASA eq. in Kelvin // loop through fuel constituents and sum up Cp - tempHfuel = 0.0; + Real64 tempHfuel = 0.0; Real64 const pow_2_Tsho(pow_2(Tsho)); Real64 const pow_3_Tsho(pow_3(Tsho)); @@ -2628,35 +2348,35 @@ namespace FuelCellElectricGenerator { Real64 const pow_3_Tkel(pow_3(Tkel)); Real64 const pow_4_Tkel(pow_4(Tkel)); - for (thisConstit = 1; thisConstit <= FuelSupply(FuelCell(GeneratorNum).FuelSupNum).NumConstituents; ++thisConstit) { - gasID = FuelSupply(FuelCell(GeneratorNum).FuelSupNum).GasLibID(thisConstit); + for (int thisConstit = 1; thisConstit <= DataGenerators::FuelSupply(this->FuelSupNum).NumConstituents; ++thisConstit) { + int gasID = DataGenerators::FuelSupply(this->FuelSupNum).GasLibID(thisConstit); if (gasID > 0) { - if (GasPhaseThermoChemistryData(gasID).ThermoMode == NISTShomate) { - A = GasPhaseThermoChemistryData(gasID).ShomateA; - B = GasPhaseThermoChemistryData(gasID).ShomateB; - C = GasPhaseThermoChemistryData(gasID).ShomateC; - D = GasPhaseThermoChemistryData(gasID).ShomateD; - E = GasPhaseThermoChemistryData(gasID).ShomateE; - F = GasPhaseThermoChemistryData(gasID).ShomateF; - H = GasPhaseThermoChemistryData(gasID).ShomateH; - - HfuelI = (A * Tsho + B * pow_2_Tsho / 2.0 + C * pow_3_Tsho / 3.0 + D * pow_4_Tsho / 4.0 - E / Tsho + F - H); - - tempHfuel += HfuelI * FuelSupply(FuelCell(GeneratorNum).FuelSupNum).ConstitMolalFract(thisConstit); + if (DataGenerators::GasPhaseThermoChemistryData(gasID).ThermoMode == DataGenerators::NISTShomate) { + A = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateA; + B = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateB; + C = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateC; + D = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateD; + E = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateE; + F = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateF; + H = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateH; + + Real64 HfuelI = (A * Tsho + B * pow_2_Tsho / 2.0 + C * pow_3_Tsho / 3.0 + D * pow_4_Tsho / 4.0 - E / Tsho + F - H); + + tempHfuel += HfuelI * DataGenerators::FuelSupply(this->FuelSupNum).ConstitMolalFract(thisConstit); } - if (GasPhaseThermoChemistryData(gasID).ThermoMode == NASAPolynomial) { + if (DataGenerators::GasPhaseThermoChemistryData(gasID).ThermoMode == DataGenerators::NASAPolynomial) { - A1 = GasPhaseThermoChemistryData(gasID).NASA_A1; - A2 = GasPhaseThermoChemistryData(gasID).NASA_A2; - A3 = GasPhaseThermoChemistryData(gasID).NASA_A3; - A4 = GasPhaseThermoChemistryData(gasID).NASA_A4; - A5 = GasPhaseThermoChemistryData(gasID).NASA_A5; - A6 = GasPhaseThermoChemistryData(gasID).NASA_A6; + A1 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A1; + A2 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A2; + A3 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A3; + A4 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A4; + A5 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A5; + A6 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A6; tempHfuel += (((A1 + A2 * Tkel / 2.0 + A3 * pow_2_Tkel / 3.0 + A4 * pow_3_Tkel / 4.0 + A5 * pow_4_Tkel / 5.0 + A6 / Tkel) * - RinKJperMolpK * Tkel) - - GasPhaseThermoChemistryData(gasID).StdRefMolarEnthOfForm) * - FuelSupply(FuelCell(GeneratorNum).FuelSupNum).ConstitMolalFract(thisConstit); + DataGenerators::RinKJperMolpK * Tkel) - + DataGenerators::GasPhaseThermoChemistryData(gasID).StdRefMolarEnthOfForm) * + DataGenerators::FuelSupply(this->FuelSupNum).ConstitMolalFract(thisConstit); } } } @@ -2664,10 +2384,7 @@ namespace FuelCellElectricGenerator { Hfuel = tempHfuel; } - void FigureProductGasesEnthalpy(int const GeneratorNum, // ID of generator FuelCell data structure - Real64 const FluidTemp, // degree C - Real64 &HProdGases // kJ/mol - ) + void FCDataStruct::FigureProductGasesEnthalpy(Real64 const FluidTemp, Real64 &HProdGases) { // SUBROUTINE INFORMATION: @@ -2686,45 +2403,26 @@ namespace FuelCellElectricGenerator { // REFERENCES: // NIST Webbook on gas phase thermochemistry - // USE STATEMENTS: - // na - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - Real64 tempHprodGases; - int thisConstit; // loop index - int gasID; // look up into Gas structure - Real64 A; // shomate coeff - Real64 B; // shomate coeff - Real64 C; // shomate coeff - Real64 D; // shomate coeff - Real64 E; // shomate coeff - Real64 F; // shomate coeff - Real64 H; // shomate coeff - Real64 A1; // NASA poly coeff - Real64 A2; // NASA poly coeff - Real64 A3; // NASA poly coeff - Real64 A4; // NASA poly coeff - Real64 A5; // NASA poly coeff - Real64 A6; // NASA poly coeff - - Real64 const Tsho = (FluidTemp + KelvinConv) / 1000.0; // temp for Shomate eq in (Kelvin/1000) - Real64 const Tkel = (FluidTemp + KelvinConv); // temp for NASA eq. in Kelvin + Real64 A; // shomate coeff + Real64 B; // shomate coeff + Real64 C; // shomate coeff + Real64 D; // shomate coeff + Real64 E; // shomate coeff + Real64 F; // shomate coeff + Real64 H; // shomate coeff + Real64 A1; // NASA poly coeff + Real64 A2; // NASA poly coeff + Real64 A3; // NASA poly coeff + Real64 A4; // NASA poly coeff + Real64 A5; // NASA poly coeff + Real64 A6; // NASA poly coeff + + Real64 const Tsho = (FluidTemp + DataGlobals::KelvinConv) / 1000.0; // temp for Shomate eq in (Kelvin/1000) + Real64 const Tkel = (FluidTemp + DataGlobals::KelvinConv); // temp for NASA eq. in Kelvin // loop through fuel constituents and sum up Cp - tempHprodGases = 0.0; + Real64 tempHprodGases = 0.0; Real64 const pow_2_Tsho(pow_2(Tsho)); Real64 const pow_3_Tsho(pow_3(Tsho)); @@ -2733,33 +2431,33 @@ namespace FuelCellElectricGenerator { Real64 const pow_3_Tkel(pow_3(Tkel)); Real64 const pow_4_Tkel(pow_4(Tkel)); - for (thisConstit = 1; thisConstit <= 5; ++thisConstit) { - gasID = FuelCell(GeneratorNum).FCPM.GasLibID(thisConstit); + for (int thisConstit = 1; thisConstit <= 5; ++thisConstit) { + int gasID = this->FCPM.GasLibID(thisConstit); if (gasID > 0) { - if (GasPhaseThermoChemistryData(gasID).ThermoMode == NISTShomate) { - A = GasPhaseThermoChemistryData(gasID).ShomateA; - B = GasPhaseThermoChemistryData(gasID).ShomateB; - C = GasPhaseThermoChemistryData(gasID).ShomateC; - D = GasPhaseThermoChemistryData(gasID).ShomateD; - E = GasPhaseThermoChemistryData(gasID).ShomateE; - F = GasPhaseThermoChemistryData(gasID).ShomateF; - H = GasPhaseThermoChemistryData(gasID).ShomateH; + if (DataGenerators::GasPhaseThermoChemistryData(gasID).ThermoMode == DataGenerators::NISTShomate) { + A = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateA; + B = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateB; + C = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateC; + D = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateD; + E = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateE; + F = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateF; + H = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateH; tempHprodGases += ((A * Tsho + B * pow_2_Tsho / 2.0 + C * pow_3_Tsho / 3.0 + D * pow_4_Tsho / 4.0 - E / Tsho + F - H) * - FuelCell(GeneratorNum).FCPM.ConstitMolalFract(thisConstit)); + this->FCPM.ConstitMolalFract(thisConstit)); } - if (GasPhaseThermoChemistryData(gasID).ThermoMode == NASAPolynomial) { - A1 = GasPhaseThermoChemistryData(gasID).NASA_A1; - A2 = GasPhaseThermoChemistryData(gasID).NASA_A2; - A3 = GasPhaseThermoChemistryData(gasID).NASA_A3; - A4 = GasPhaseThermoChemistryData(gasID).NASA_A4; - A5 = GasPhaseThermoChemistryData(gasID).NASA_A5; - A6 = GasPhaseThermoChemistryData(gasID).NASA_A6; + if (DataGenerators::GasPhaseThermoChemistryData(gasID).ThermoMode == DataGenerators::NASAPolynomial) { + A1 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A1; + A2 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A2; + A3 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A3; + A4 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A4; + A5 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A5; + A6 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A6; tempHprodGases += (((A1 + A2 * Tkel / 2.0 + A3 * pow_2_Tkel / 3.0 + A4 * pow_3_Tkel / 4.0 + A5 * pow_4_Tkel / 5.0 + A6 / Tkel) * - RinKJperMolpK * Tkel) - - GasPhaseThermoChemistryData(gasID).StdRefMolarEnthOfForm) * - FuelCell(GeneratorNum).FCPM.ConstitMolalFract(thisConstit); + DataGenerators::RinKJperMolpK * Tkel) - + DataGenerators::GasPhaseThermoChemistryData(gasID).StdRefMolarEnthOfForm) * + this->FCPM.ConstitMolalFract(thisConstit); } } // gasid > 0 } @@ -2767,10 +2465,7 @@ namespace FuelCellElectricGenerator { HProdGases = tempHprodGases; } - void FigureProductGasHeatCap(int const GeneratorNum, // ID of generator FuelCell data structure - Real64 const FluidTemp, // degree C - Real64 &Cp // (J/mol*K) - ) + void FCDataStruct::FigureProductGasHeatCap(Real64 const FluidTemp, Real64 &Cp) { // SUBROUTINE INFORMATION: @@ -2779,168 +2474,20 @@ namespace FuelCellElectricGenerator { // MODIFIED na // RE-ENGINEERED na - // PURPOSE OF THIS SUBROUTINE: - // - - // METHODOLOGY EMPLOYED: - // - - // REFERENCES: - // na - - // USE STATEMENTS: - // na - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - // na - - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - // na - - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: Real64 tempCp; - int thisConstit; // loop index - int gasID; // look up into Gas structure - Real64 A; // shomate coeff - Real64 B; // shomate coeff - Real64 C; // shomate coeff - Real64 D; // shomate coeff - Real64 E; // shomate coeff - Real64 A1; // NASA poly coeff - Real64 A2; // NASA poly coeff - Real64 A3; // NASA poly coeff - Real64 A4; // NASA poly coeff - Real64 A5; // NASA poly coeff - - Real64 const Tsho = (FluidTemp + KelvinConv) / 1000.0; // temp for Shomate eq in (Kelvin/1000) - Real64 const Tkel = (FluidTemp + KelvinConv); // temp for NASA eq. in Kelvin - - // loop through fuel constituents and sum up Cp - - tempCp = 0.0; - - Real64 const pow_2_Tsho(pow_2(Tsho)); - Real64 const pow_3_Tsho(pow_3(Tsho)); - Real64 const pow_2_Tkel(pow_2(Tkel)); - Real64 const pow_3_Tkel(pow_3(Tkel)); - Real64 const pow_4_Tkel(pow_4(Tkel)); - - for (thisConstit = 1; thisConstit <= isize(FuelCell(GeneratorNum).FCPM.GasLibID); ++thisConstit) { - gasID = FuelCell(GeneratorNum).FCPM.GasLibID(thisConstit); - if (gasID > 0) { - if (GasPhaseThermoChemistryData(gasID).ThermoMode == NISTShomate) { - - A = GasPhaseThermoChemistryData(gasID).ShomateA; - B = GasPhaseThermoChemistryData(gasID).ShomateB; - C = GasPhaseThermoChemistryData(gasID).ShomateC; - D = GasPhaseThermoChemistryData(gasID).ShomateD; - E = GasPhaseThermoChemistryData(gasID).ShomateE; - - tempCp += ((A + B * Tsho + C * pow_2_Tsho + D * pow_3_Tsho + E / pow_2_Tsho) * - FuelCell(GeneratorNum).FCPM.ConstitMolalFract(thisConstit)); - } - - if (GasPhaseThermoChemistryData(gasID).ThermoMode == NASAPolynomial) { - A1 = GasPhaseThermoChemistryData(gasID).NASA_A1; - A2 = GasPhaseThermoChemistryData(gasID).NASA_A2; - A3 = GasPhaseThermoChemistryData(gasID).NASA_A3; - A4 = GasPhaseThermoChemistryData(gasID).NASA_A4; - A5 = GasPhaseThermoChemistryData(gasID).NASA_A5; - - tempCp += (A1 + A2 * Tkel + A3 * pow_2_Tkel + A4 * pow_3_Tkel + A5 * pow_4_Tkel) * RinKJperMolpK * - FuelCell(GeneratorNum).FCPM.ConstitMolalFract(thisConstit); - } - } - } - - Cp = tempCp; - } - - void FigureAuxilHeatGasHeatCap(int const GeneratorNum, // ID of generator FuelCell data structure - Real64 const FluidTemp, // degree C - Real64 &Cp // (J/mol*K) - ) - { - - // SUBROUTINE INFORMATION: - // AUTHOR Brent Griffith - // DATE WRITTEN Aug. 2005 - // MODIFIED na - // RE-ENGINEERED na - - // PURPOSE OF THIS SUBROUTINE: - // - - // METHODOLOGY EMPLOYED: - // - - // REFERENCES: - // na - - // USE STATEMENTS: - // na - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - // na - - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - // na - - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na + Real64 A; // shomate coeff + Real64 B; // shomate coeff + Real64 C; // shomate coeff + Real64 D; // shomate coeff + Real64 E; // shomate coeff + Real64 A1; // NASA poly coeff + Real64 A2; // NASA poly coeff + Real64 A3; // NASA poly coeff + Real64 A4; // NASA poly coeff + Real64 A5; // NASA poly coeff - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - Real64 tempCp; - int thisConstit; // loop index - int gasID; // look up into Gas structure - Real64 A; // shomate coeff - Real64 B; // shomate coeff - Real64 C; // shomate coeff - Real64 D; // shomate coeff - Real64 E; // shomate coeff - Real64 A1; // NASA poly coeff - Real64 A2; // NASA poly coeff - Real64 A3; // NASA poly coeff - Real64 A4; // NASA poly coeff - Real64 A5; // NASA poly coeff - - Real64 const Tsho = (FluidTemp + KelvinConv) / 1000.0; // temp for Shomate eq in (Kelvin/1000) - Real64 const Tkel = (FluidTemp + KelvinConv); // temp for NASA eq. in Kelvin + Real64 const Tsho = (FluidTemp + DataGlobals::KelvinConv) / 1000.0; // temp for Shomate eq in (Kelvin/1000) + Real64 const Tkel = (FluidTemp + DataGlobals::KelvinConv); // temp for NASA eq. in Kelvin // loop through fuel constituents and sum up Cp @@ -2952,30 +2499,29 @@ namespace FuelCellElectricGenerator { Real64 const pow_3_Tkel(pow_3(Tkel)); Real64 const pow_4_Tkel(pow_4(Tkel)); - for (thisConstit = 1; thisConstit <= isize(FuelCell(GeneratorNum).AuxilHeat.GasLibID); ++thisConstit) { - gasID = FuelCell(GeneratorNum).AuxilHeat.GasLibID(thisConstit); + for (int thisConstit = 1; thisConstit <= isize(this->FCPM.GasLibID); ++thisConstit) { + int gasID = this->FCPM.GasLibID(thisConstit); if (gasID > 0) { - if (GasPhaseThermoChemistryData(gasID).ThermoMode == NISTShomate) { + if (DataGenerators::GasPhaseThermoChemistryData(gasID).ThermoMode == DataGenerators::NISTShomate) { - A = GasPhaseThermoChemistryData(gasID).ShomateA; - B = GasPhaseThermoChemistryData(gasID).ShomateB; - C = GasPhaseThermoChemistryData(gasID).ShomateC; - D = GasPhaseThermoChemistryData(gasID).ShomateD; - E = GasPhaseThermoChemistryData(gasID).ShomateE; + A = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateA; + B = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateB; + C = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateC; + D = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateD; + E = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateE; - tempCp += ((A + B * Tsho + C * pow_2_Tsho + D * pow_3_Tsho + E / pow_2_Tsho) * - FuelCell(GeneratorNum).AuxilHeat.ConstitMolalFract(thisConstit)); + tempCp += ((A + B * Tsho + C * pow_2_Tsho + D * pow_3_Tsho + E / pow_2_Tsho) * this->FCPM.ConstitMolalFract(thisConstit)); } - if (GasPhaseThermoChemistryData(gasID).ThermoMode == NASAPolynomial) { - A1 = GasPhaseThermoChemistryData(gasID).NASA_A1; - A2 = GasPhaseThermoChemistryData(gasID).NASA_A2; - A3 = GasPhaseThermoChemistryData(gasID).NASA_A3; - A4 = GasPhaseThermoChemistryData(gasID).NASA_A4; - A5 = GasPhaseThermoChemistryData(gasID).NASA_A5; + if (DataGenerators::GasPhaseThermoChemistryData(gasID).ThermoMode == DataGenerators::NASAPolynomial) { + A1 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A1; + A2 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A2; + A3 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A3; + A4 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A4; + A5 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A5; - tempCp += (A1 + A2 * Tkel + A3 * pow_2_Tkel + A4 * pow_3_Tkel + A5 * pow_4_Tkel) * RinKJperMolpK * - FuelCell(GeneratorNum).AuxilHeat.ConstitMolalFract(thisConstit); + tempCp += (A1 + A2 * Tkel + A3 * pow_2_Tkel + A4 * pow_3_Tkel + A5 * pow_4_Tkel) * DataGenerators::RinKJperMolpK * + this->FCPM.ConstitMolalFract(thisConstit); } } } @@ -2983,10 +2529,7 @@ namespace FuelCellElectricGenerator { Cp = tempCp; } - void FigureHXleavingGasHeatCap(int const GeneratorNum, // ID of generator FuelCell data structure - Real64 const FluidTemp, // degree C - Real64 &Cp // (J/mol*K) - ) + void FCDataStruct::FigureAuxilHeatGasHeatCap(Real64 const FluidTemp, Real64 &Cp) { // SUBROUTINE INFORMATION: @@ -2995,60 +2538,20 @@ namespace FuelCellElectricGenerator { // MODIFIED na // RE-ENGINEERED na - // PURPOSE OF THIS SUBROUTINE: - // - - // METHODOLOGY EMPLOYED: - // - - // REFERENCES: - // na - - // USE STATEMENTS: - // na - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - // na - - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - // na - - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: Real64 tempCp; - int thisConstit; // loop index - int gasID; // look up into Gas structure - Real64 A; // shomate coeff - Real64 B; // shomate coeff - Real64 C; // shomate coeff - Real64 D; // shomate coeff - Real64 E; // shomate coeff - Real64 A1; // NASA poly coeff - Real64 A2; // NASA poly coeff - Real64 A3; // NASA poly coeff - Real64 A4; // NASA poly coeff - Real64 A5; // NASA poly coeff - - Real64 const Tsho = (FluidTemp + KelvinConv) / 1000.0; // temp for Shomate eq in (Kelvin/1000) - Real64 const Tkel = (FluidTemp + KelvinConv); // temp for NASA eq. in Kelvin + Real64 A; // shomate coeff + Real64 B; // shomate coeff + Real64 C; // shomate coeff + Real64 D; // shomate coeff + Real64 E; // shomate coeff + Real64 A1; // NASA poly coeff + Real64 A2; // NASA poly coeff + Real64 A3; // NASA poly coeff + Real64 A4; // NASA poly coeff + Real64 A5; // NASA poly coeff + + Real64 const Tsho = (FluidTemp + DataGlobals::KelvinConv) / 1000.0; // temp for Shomate eq in (Kelvin/1000) + Real64 const Tkel = (FluidTemp + DataGlobals::KelvinConv); // temp for NASA eq. in Kelvin // loop through fuel constituents and sum up Cp @@ -3060,30 +2563,29 @@ namespace FuelCellElectricGenerator { Real64 const pow_3_Tkel(pow_3(Tkel)); Real64 const pow_4_Tkel(pow_4(Tkel)); - for (thisConstit = 1; thisConstit <= isize(FuelCell(GeneratorNum).ExhaustHX.GasLibID); ++thisConstit) { - gasID = FuelCell(GeneratorNum).ExhaustHX.GasLibID(thisConstit); + for (int thisConstit = 1; thisConstit <= isize(this->AuxilHeat.GasLibID); ++thisConstit) { + int gasID = this->AuxilHeat.GasLibID(thisConstit); if (gasID > 0) { - if (GasPhaseThermoChemistryData(gasID).ThermoMode == NISTShomate) { + if (DataGenerators::GasPhaseThermoChemistryData(gasID).ThermoMode == DataGenerators::NISTShomate) { - A = GasPhaseThermoChemistryData(gasID).ShomateA; - B = GasPhaseThermoChemistryData(gasID).ShomateB; - C = GasPhaseThermoChemistryData(gasID).ShomateC; - D = GasPhaseThermoChemistryData(gasID).ShomateD; - E = GasPhaseThermoChemistryData(gasID).ShomateE; + A = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateA; + B = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateB; + C = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateC; + D = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateD; + E = DataGenerators::GasPhaseThermoChemistryData(gasID).ShomateE; - tempCp += ((A + B * Tsho + C * pow_2_Tsho + D * pow_3_Tsho + E / pow_2_Tsho) * - FuelCell(GeneratorNum).ExhaustHX.ConstitMolalFract(thisConstit)); + tempCp += ((A + B * Tsho + C * pow_2_Tsho + D * pow_3_Tsho + E / pow_2_Tsho) * this->AuxilHeat.ConstitMolalFract(thisConstit)); } - if (GasPhaseThermoChemistryData(gasID).ThermoMode == NASAPolynomial) { - A1 = GasPhaseThermoChemistryData(gasID).NASA_A1; - A2 = GasPhaseThermoChemistryData(gasID).NASA_A2; - A3 = GasPhaseThermoChemistryData(gasID).NASA_A3; - A4 = GasPhaseThermoChemistryData(gasID).NASA_A4; - A5 = GasPhaseThermoChemistryData(gasID).NASA_A5; + if (DataGenerators::GasPhaseThermoChemistryData(gasID).ThermoMode == DataGenerators::NASAPolynomial) { + A1 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A1; + A2 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A2; + A3 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A3; + A4 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A4; + A5 = DataGenerators::GasPhaseThermoChemistryData(gasID).NASA_A5; - tempCp += (A1 + A2 * Tkel + A3 * pow_2_Tkel + A4 * pow_3_Tkel + A5 * pow_4_Tkel) * RinKJperMolpK * - FuelCell(GeneratorNum).ExhaustHX.ConstitMolalFract(thisConstit); + tempCp += (A1 + A2 * Tkel + A3 * pow_2_Tkel + A4 * pow_3_Tkel + A5 * pow_4_Tkel) * DataGenerators::RinKJperMolpK * + this->AuxilHeat.ConstitMolalFract(thisConstit); } } } @@ -3091,8 +2593,8 @@ namespace FuelCellElectricGenerator { Cp = tempCp; } - void FigureGaseousWaterEnthalpy(Real64 const FluidTemp, // degree C - Real64 &HGasWater // kJ/mol + void FCDataStruct::FigureGaseousWaterEnthalpy(Real64 const FluidTemp, // degree C + Real64 &HGasWater // kJ/mol ) { @@ -3104,44 +2606,24 @@ namespace FuelCellElectricGenerator { // PURPOSE OF THIS SUBROUTINE: // calculate Enthalpy from Shomate equations for gaseous water - // No ethalphy of formation in this one. - - // METHODOLOGY EMPLOYED: + // No enthalpy of formation in this one. // REFERENCES: // NIST Webbook on gas phase thermochemistry - // USE STATEMENTS: - // na - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - Real64 const A = 29.0373; // shomate coeff - Real64 const B = 10.2573; // shomate coeff - Real64 const C = 2.81048; // shomate coeff - Real64 const D = -0.95914; // shomate coeff - Real64 const E = 0.11725; // shomate coeff - Real64 const F = -250.569; // shomate coeff - // REAL(r64) :: H ! shomate coeff - - Real64 const Tsho = (FluidTemp + KelvinConv) / 1000.0; // temp for Shomate eq in (Kelvin/1000) + Real64 const A = 29.0373; // shomate coeff + Real64 const B = 10.2573; // shomate coeff + Real64 const C = 2.81048; // shomate coeff + Real64 const D = -0.95914; // shomate coeff + Real64 const E = 0.11725; // shomate coeff + Real64 const F = -250.569; // shomate coeff + Real64 const Tsho = (FluidTemp + DataGlobals::KelvinConv) / 1000.0; // temp for Shomate eq in (Kelvin/1000) HGasWater = A * Tsho + B * pow_2(Tsho) / 2.0 + C * pow_3(Tsho) / 3.0 + D * pow_4(Tsho) / 4.0 - E / Tsho + F; //- H } - void FigureLiquidWaterEnthalpy(Real64 const FluidTemp, // degree C - Real64 &HLiqWater // kJ/mol + void FCDataStruct::FigureLiquidWaterEnthalpy(Real64 const FluidTemp, // degree C + Real64 &HLiqWater // kJ/mol ) { @@ -3155,42 +2637,23 @@ namespace FuelCellElectricGenerator { // calculate Enthalpy from Shomate equations for liquid water // No enthalpy of formation in this one - // METHODOLOGY EMPLOYED: - // REFERENCES: // NIST Webbook on gas phase thermochemistry - // USE STATEMENTS: - // na - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: Real64 const A = -203.606; // shomate coeff Real64 const B = 1523.29; // shomate coeff Real64 const C = -3196.413; // shomate coeff Real64 const D = 2474.455; // shomate coeff Real64 const E = 3.85533; // shomate coeff Real64 const F = -256.5478; // shomate coeff - // Real64 const H = -285.8304; // shomate coeff (currently unused) - Real64 const Tsho = (FluidTemp + KelvinConv) / 1000.0; // temp for Shomate eq in (Kelvin/1000) + Real64 const Tsho = (FluidTemp + DataGlobals::KelvinConv) / 1000.0; // temp for Shomate eq in (Kelvin/1000) HLiqWater = A * Tsho + B * pow_2(Tsho) / 2.0 + C * pow_3(Tsho) / 3.0 + D * pow_4(Tsho) / 4.0 - E / Tsho + F; //- H } - void FigureLiquidWaterHeatCap(Real64 const FluidTemp, // degree C - Real64 &Cp // (J/mol*K) + void FCDataStruct::FigureLiquidWaterHeatCap(Real64 const FluidTemp, // degree C + Real64 &Cp // (J/mol*K) ) { @@ -3203,114 +2666,17 @@ namespace FuelCellElectricGenerator { // PURPOSE OF THIS SUBROUTINE: // calculate shomate eq. for pure liquid water - // METHODOLOGY EMPLOYED: - // - - // REFERENCES: - // na - - // USE STATEMENTS: - // na - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - // na - - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - // na - - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: Real64 const A = -203.606; // shomate coeff Real64 const B = 1523.29; // shomate coeff Real64 const C = -3196.413; // shomate coeff Real64 const D = 2474.455; // shomate coeff Real64 const E = 3.85533; // shomate coeff - - Real64 const Tsho = (FluidTemp + KelvinConv) / 1000.0; + Real64 const Tsho = (FluidTemp + DataGlobals::KelvinConv) / 1000.0; Cp = A + B * Tsho + C * pow_2(Tsho) + D * pow_3(Tsho) + E / pow_2(Tsho); } - void FigureLHVofFuel(int const Num, Real64 const NdotFuel, Real64 const NdotCO2, Real64 const NdotH20, Real64 &LHV) - { - - // SUBROUTINE INFORMATION: - // AUTHOR B Griffith - // DATE WRITTEN Aug 2005 - // MODIFIED na - // RE-ENGINEERED na - - // PURPOSE OF THIS SUBROUTINE: - // Calculate LHV - - // METHODOLOGY EMPLOYED: - // ANNEX 42 eq. 6 method from molar enthalpies - - // REFERENCES: - // na - - // USE STATEMENTS: - // na - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - Real64 DelfHfuel; - Real64 DelfHCO2; - Real64 DelfHH20; - int i; - Real64 h_i; - int CO2dataID; - int WaterDataID; - int thisGasID; - - CO2dataID = 1; // hard-coded in SetupFuelAndAirConstituentData - WaterDataID = 4; // hard-coded in SetupFuelAndAirConstituentData - DelfHfuel = 0.0; - - for (i = 1; i <= FuelSupply(FuelCell(Num).FuelSupNum).NumConstituents; ++i) { - thisGasID = FuelSupply(FuelCell(Num).FuelSupNum).GasLibID(i); - - h_i = GasPhaseThermoChemistryData(thisGasID).StdRefMolarEnthOfForm; - - DelfHfuel += NdotFuel * h_i * FuelSupply(FuelCell(Num).FuelSupNum).ConstitMolalFract(i); - } - - DelfHCO2 = GasPhaseThermoChemistryData(CO2dataID).StdRefMolarEnthOfForm * NdotCO2; - - DelfHH20 = GasPhaseThermoChemistryData(WaterDataID).StdRefMolarEnthOfForm * NdotH20; - - LHV = (DelfHfuel - DelfHCO2 - DelfHH20) / NdotFuel; // Equation 6 - } - - void FigureACAncillaries(int const GeneratorNum, Real64 &PacAncill) + void FCDataStruct::FigureACAncillaries(Real64 &PacAncill) { // SUBROUTINE INFORMATION: @@ -3322,52 +2688,25 @@ namespace FuelCellElectricGenerator { // PURPOSE OF THIS SUBROUTINE: // Calculate the AC ancillaries to determine Pel - // METHODOLOGY EMPLOYED: - // - - // REFERENCES: - // na - - // USE STATEMENTS: - // na - // Using/Aliasing - using CurveManager::CurveValue; - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - // Using lagged values inside a sequential substitution loop PacAncill = 0.0; // sect. 5.9 - FuelCell(GeneratorNum).FCPM.PelancillariesAC = - FuelCell(GeneratorNum).FCPM.ANC0 + FuelCell(GeneratorNum).FCPM.ANC1 * FuelCell(GeneratorNum).FCPM.NdotFuel; + this->FCPM.PelancillariesAC = this->FCPM.ANC0 + this->FCPM.ANC1 * this->FCPM.NdotFuel; // sect 6.0 - FuelCell(GeneratorNum).AirSup.PairCompEl = CurveValue(FuelCell(GeneratorNum).AirSup.BlowerPowerCurveID, FuelCell(GeneratorNum).FCPM.NdotAir); + this->AirSup.PairCompEl = CurveManager::CurveValue(this->AirSup.BlowerPowerCurveID, this->FCPM.NdotAir); // sect 7.0 - FuelSupply(FuelCell(GeneratorNum).FuelSupNum).PfuelCompEl = - CurveValue(FuelSupply(FuelCell(GeneratorNum).FuelSupNum).CompPowerCurveID, FuelCell(GeneratorNum).FCPM.NdotFuel); + DataGenerators::FuelSupply(this->FuelSupNum).PfuelCompEl = + CurveManager::CurveValue(DataGenerators::FuelSupply(this->FuelSupNum).CompPowerCurveID, this->FCPM.NdotFuel); // sect. 8.0 - FuelCell(GeneratorNum).WaterSup.PwaterCompEl = - CurveValue(FuelCell(GeneratorNum).WaterSup.PmpPowerCurveID, FuelCell(GeneratorNum).FCPM.NdotLiqwater); + this->WaterSup.PwaterCompEl = CurveManager::CurveValue(this->WaterSup.PmpPowerCurveID, this->FCPM.NdotLiqwater); - PacAncill = FuelCell(GeneratorNum).FCPM.PelancillariesAC + FuelCell(GeneratorNum).AirSup.PairCompEl + - FuelSupply(FuelCell(GeneratorNum).FuelSupNum).PfuelCompEl + FuelCell(GeneratorNum).WaterSup.PwaterCompEl; + PacAncill = this->FCPM.PelancillariesAC + this->AirSup.PairCompEl + DataGenerators::FuelSupply(this->FuelSupNum).PfuelCompEl + + this->WaterSup.PwaterCompEl; } - void FigurePowerConditioningLosses(int const GeneratorNum, Real64 const Pdemand, Real64 &PpcuLosses) + void FCDataStruct::FigurePowerConditioningLosses(Real64 const Pdemand, Real64 &PpcuLosses) { // SUBROUTINE INFORMATION: @@ -3379,60 +2718,30 @@ namespace FuelCellElectricGenerator { // PURPOSE OF THIS SUBROUTINE: // Calculate inverter losses - // METHODOLOGY EMPLOYED: - // - - // REFERENCES: - // na - - // USE STATEMENTS: - // na - // Using/Aliasing - using CurveManager::CurveValue; - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - Real64 lastPpcuLosses; // used in iterative solution - int iter; - Real64 Pel; - - if (FuelCell(GeneratorNum).Inverter.EffMode == InverterEffConstant) { - - PpcuLosses = Pdemand * (1 - FuelCell(GeneratorNum).Inverter.ConstEff) / FuelCell(GeneratorNum).Inverter.ConstEff; + if (this->Inverter.EffMode == DataGenerators::InverterEffConstant) { + PpcuLosses = Pdemand * (1 - this->Inverter.ConstEff) / this->Inverter.ConstEff; } - if (FuelCell(GeneratorNum).Inverter.EffMode == InverterEffQuadratic) { + if (this->Inverter.EffMode == DataGenerators::InverterEffQuadratic) { // first use Pdemand instead of Pel to get initial estimate - lastPpcuLosses = Pdemand * (1.0 - CurveValue(FuelCell(GeneratorNum).Inverter.EffQuadraticCurveID, Pdemand)) / - CurveValue(FuelCell(GeneratorNum).Inverter.EffQuadraticCurveID, Pdemand); + Real64 lastPpcuLosses = Pdemand * (1.0 - CurveManager::CurveValue(this->Inverter.EffQuadraticCurveID, Pdemand)) / + CurveManager::CurveValue(this->Inverter.EffQuadraticCurveID, Pdemand); - for (iter = 1; iter <= 20; ++iter) { // seems like need to iterate (??) Need to investigate number and convergence success here + for (int iter = 1; iter <= 20; ++iter) { // seems like need to iterate (??) Need to investigate number and convergence success here - Pel = Pdemand + lastPpcuLosses; + Real64 Pel = Pdemand + lastPpcuLosses; - lastPpcuLosses = (1.0 - CurveValue(FuelCell(GeneratorNum).Inverter.EffQuadraticCurveID, Pel)) * Pel; + lastPpcuLosses = (1.0 - CurveManager::CurveValue(this->Inverter.EffQuadraticCurveID, Pel)) * Pel; } PpcuLosses = lastPpcuLosses; } } - void FigureTransientConstraints(int const GeneratorNum, // index number for accessing correct generator - Real64 &Pel, // DC power control setting for power module - bool &Constrained, // true if transient constraints kick in - Real64 &PelDiff // if constrained then this is the difference, positive + void FCDataStruct::FigureTransientConstraints(Real64 &Pel, // DC power control setting for power module + bool &Constrained, // true if transient constraints kick in + Real64 &PelDiff // if constrained then this is the difference, positive ) { @@ -3442,83 +2751,52 @@ namespace FuelCellElectricGenerator { // MODIFIED na // RE-ENGINEERED na - // PURPOSE OF THIS SUBROUTINE: - // + Real64 PelInput = Pel; // hold initial value of inout var - // METHODOLOGY EMPLOYED: - // - - // REFERENCES: - // na - - // USE STATEMENTS: - // na - // Using/Aliasing - using DataHVACGlobals::SysTimeElapsed; - using DataHVACGlobals::TimeStepSys; - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - // unused REAL(r64) :: CurrentHours - Real64 CurrentFractionalDay; // working var, time in decimal days - Real64 EndingFractionalDay; // working var, time is decimal days - Real64 MaxPel; // working variable for max allowed by transient constraint - Real64 MinPel; // working variabel for min allowed by transient constraint - Real64 PelInput; // hold initial value of inout var - - PelInput = Pel; + Real64 CurrentFractionalDay = + double(DataGlobals::DayOfSim) + + (int(DataGlobals::CurrentTime) + (DataHVACGlobals::SysTimeElapsed + (DataGlobals::CurrentTime - int(DataGlobals::CurrentTime)))) / + DataGlobals::HoursInDay; // Check if in start up and if it still should be - if (FuelCell(GeneratorNum).FCPM.DuringStartUp) { + if (this->FCPM.DuringStartUp) { // calculate time for end of start up period - CurrentFractionalDay = double(DayOfSim) + (int(CurrentTime) + (SysTimeElapsed + (CurrentTime - int(CurrentTime)))) / HoursInDay; - - EndingFractionalDay = FuelCell(GeneratorNum).FCPM.FractionalDayofLastStartUp + FuelCell(GeneratorNum).FCPM.StartUpTime / HoursInDay; + Real64 EndingFractionalDay = this->FCPM.FractionalDayofLastStartUp + this->FCPM.StartUpTime / DataGlobals::HoursInDay; if (CurrentFractionalDay > EndingFractionalDay) { // start up period is now over - FuelCell(GeneratorNum).FCPM.DuringStartUp = false; + this->FCPM.DuringStartUp = false; } } // Check if in shut down up and if it still should be - if (FuelCell(GeneratorNum).FCPM.DuringShutDown) { + if (this->FCPM.DuringShutDown) { // calculate time for end of shut down period - CurrentFractionalDay = double(DayOfSim) + (int(CurrentTime) + (SysTimeElapsed + (CurrentTime - int(CurrentTime)))) / HoursInDay; - - EndingFractionalDay = FuelCell(GeneratorNum).FCPM.FractionalDayofLastShutDown + FuelCell(GeneratorNum).FCPM.ShutDownTime / HoursInDay; + Real64 EndingFractionalDay = this->FCPM.FractionalDayofLastShutDown + this->FCPM.ShutDownTime / DataGlobals::HoursInDay; if (CurrentFractionalDay > EndingFractionalDay) { // start up period is now over - FuelCell(GeneratorNum).FCPM.DuringShutDown = false; + this->FCPM.DuringShutDown = false; } } // compare - if (!(FuelCell(GeneratorNum).FCPM.DuringShutDown) && !(FuelCell(GeneratorNum).FCPM.DuringStartUp)) { + if (!(this->FCPM.DuringShutDown) && !(this->FCPM.DuringStartUp)) { // unit is neither starting or stopping and the only constraints would come from transient limits - if (Pel > FuelCell(GeneratorNum).FCPM.PelLastTimeStep) { // powering up - MaxPel = FuelCell(GeneratorNum).FCPM.PelLastTimeStep + FuelCell(GeneratorNum).FCPM.UpTranLimit * TimeStepSys * SecInHour; + if (Pel > this->FCPM.PelLastTimeStep) { // powering up + // working variable for max allowed by transient constraint + Real64 MaxPel = this->FCPM.PelLastTimeStep + this->FCPM.UpTranLimit * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; if (MaxPel < Pel) { Pel = MaxPel; Constrained = true; } else { Constrained = false; } - } else if (Pel < FuelCell(GeneratorNum).FCPM.PelLastTimeStep) { // powering down - MinPel = FuelCell(GeneratorNum).FCPM.PelLastTimeStep - FuelCell(GeneratorNum).FCPM.DownTranLimit * TimeStepSys * SecInHour; + } else if (Pel < this->FCPM.PelLastTimeStep) { // powering down + // working variable for min allowed by transient constraint + Real64 MinPel = this->FCPM.PelLastTimeStep - this->FCPM.DownTranLimit * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; if (Pel < MinPel) { Pel = MinPel; Constrained = true; @@ -3532,13 +2810,13 @@ namespace FuelCellElectricGenerator { } // not in start up or shut down - if (FuelCell(GeneratorNum).FCPM.DuringStartUp) { + if (this->FCPM.DuringStartUp) { // constant during start up modeling artifact - Pel = FuelCell(GeneratorNum).FCPM.StartUpElectProd / FuelCell(GeneratorNum).FCPM.StartUpTime; + Pel = this->FCPM.StartUpElectProd / this->FCPM.StartUpTime; Constrained = true; } - if (FuelCell(GeneratorNum).FCPM.DuringShutDown) { + if (this->FCPM.DuringShutDown) { Pel = 0.0; // assumes no power generated during shut down Constrained = true; @@ -3550,51 +2828,18 @@ namespace FuelCellElectricGenerator { } } - void CalcFuelCellAuxHeater(int const Num) // Generator number + void FCDataStruct::CalcFuelCellAuxHeater() // Generator number { - // SUBROUTINE INFORMATION: - // AUTHOR - // DATE WRITTEN - // MODIFIED na - // RE-ENGINEERED na - - // PURPOSE OF THIS SUBROUTINE: - // - - // METHODOLOGY EMPLOYED: - // - - // REFERENCES: - // na - - // USE STATEMENTS: - // na - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - // na - // not yet implemented, just pass product gases thru nul domain - FuelCell(Num).AuxilHeat.TauxMix = FuelCell(Num).FCPM.TprodGasLeavingFCPM; - FuelCell(Num).AuxilHeat.NdotAuxMix = FuelCell(Num).FCPM.NdotProdGas; - FuelCell(Num).AuxilHeat.ConstitMolalFract = FuelCell(Num).FCPM.ConstitMolalFract; - FuelCell(Num).AuxilHeat.GasLibID = FuelCell(Num).FCPM.GasLibID; + this->AuxilHeat.TauxMix = this->FCPM.TprodGasLeavingFCPM; + this->AuxilHeat.NdotAuxMix = this->FCPM.NdotProdGas; + this->AuxilHeat.ConstitMolalFract = this->FCPM.ConstitMolalFract; + this->AuxilHeat.GasLibID = this->FCPM.GasLibID; } - void CalcFuelCellGenHeatRecovery(int const Num) // Generator number + void FCDataStruct::CalcFuelCellGenHeatRecovery() // Generator number { // SUBROUTINE INFORMATION: // AUTHOR: Brent Griffith @@ -3608,249 +2853,194 @@ namespace FuelCellElectricGenerator { // REFERENCES: Annex 42 model documentation - // Using/Aliasing - using DataPlant::PlantLoop; - using FluidProperties::GetSpecificHeatGlycol; - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE PARAMETER DEFINITIONS: static std::string const RoutineName("CalcFuelCellGenHeatRecovery"); - // DERIVED TYPE DEFINITIONS - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - Real64 eHX; // fixed effectiveness - Real64 MdotWater(0.0); - int inNodeNum(0); - Real64 MWwater; - Real64 NdotWater; - Real64 TwaterIn; - Real64 CpWaterMol; - Real64 NdotGas; - Real64 TprodGasIn; - Real64 CpProdGasMol; - Real64 NdotCp; - Real64 qHX(0.0); - Real64 UAeff; - Real64 TauxMix; - Real64 NdotCpWater; - Real64 NdotCpAuxMix; - Real64 THXexh(0.0); - Real64 TwaterOut(0.0); - Real64 hgas; - Real64 hwater; - static Real64 waterFract(0.0); - Real64 NdotWaterVapor; - Real64 TcondThresh; - Real64 hxl1; - Real64 hxl2; - static Real64 NdotWaterCond(0.0); - Real64 hfpwater; - int i; - - Real64 qSens; - Real64 qLatent; - int loop; - Real64 Cp; - { - auto const SELECT_CASE_var(FuelCell(Num).ExhaustHX.HXmodelMode); + auto const SELECT_CASE_var(this->ExhaustHX.HXmodelMode); - if (SELECT_CASE_var == FixedEffectiveness) { // Method 1 + if (SELECT_CASE_var == DataGenerators::FixedEffectiveness) { // Method 1 - eHX = FuelCell(Num).ExhaustHX.HXEffect; + Real64 eHX = this->ExhaustHX.HXEffect; - inNodeNum = FuelCell(Num).ExhaustHX.WaterInNode; - - MdotWater = FuelCell(Num).ExhaustHX.WaterMassFlowRate; - MWwater = GasPhaseThermoChemistryData(4).MolecularWeight; - NdotWater = MdotWater / MWwater; - TwaterIn = FuelCell(Num).ExhaustHX.WaterInletTemp; + Real64 MWwater = DataGenerators::GasPhaseThermoChemistryData(4).MolecularWeight; + Real64 NdotWater = this->ExhaustHX.WaterMassFlowRate / MWwater; + Real64 TwaterIn = this->ExhaustHX.WaterInletTemp; + Real64 CpWaterMol; FigureLiquidWaterHeatCap(TwaterIn, CpWaterMol); - NdotGas = FuelCell(Num).AuxilHeat.NdotAuxMix; - TprodGasIn = FuelCell(Num).AuxilHeat.TauxMix; - FigureAuxilHeatGasHeatCap(Num, TprodGasIn, CpProdGasMol); // Cp in (J/mol*K) + Real64 NdotGas = this->AuxilHeat.NdotAuxMix; + Real64 TprodGasIn = this->AuxilHeat.TauxMix; + Real64 CpProdGasMol; + this->FigureAuxilHeatGasHeatCap(TprodGasIn, CpProdGasMol); // Cp in (J/mol*K) // factor of 1000.0 for kmol -> mol - NdotCp = min(NdotGas * CpProdGasMol * 1000.0, NdotWater * CpWaterMol * 1000.0); + Real64 NdotCp = min(NdotGas * CpProdGasMol * 1000.0, NdotWater * CpWaterMol * 1000.0); - qHX = eHX * NdotCp * (TprodGasIn - TwaterIn); + this->ExhaustHX.qHX = eHX * NdotCp * (TprodGasIn - TwaterIn); - THXexh = TprodGasIn - qHX / (NdotGas * CpProdGasMol * 1000.0); + this->ExhaustHX.THXexh = TprodGasIn - this->ExhaustHX.qHX / (NdotGas * CpProdGasMol * 1000.0); - Cp = GetSpecificHeatGlycol( - PlantLoop(FuelCell(Num).CWLoopNum).FluidName, TwaterIn, PlantLoop(FuelCell(Num).CWLoopNum).FluidIndex, RoutineName); + Real64 Cp = FluidProperties::GetSpecificHeatGlycol( + DataPlant::PlantLoop(this->CWLoopNum).FluidName, TwaterIn, DataPlant::PlantLoop(this->CWLoopNum).FluidIndex, RoutineName); - if (MdotWater * Cp <= 0.0) { - TwaterOut = TwaterIn; + if (this->ExhaustHX.WaterMassFlowRate * Cp <= 0.0) { + this->ExhaustHX.WaterOutletTemp = TwaterIn; } else { - TwaterOut = TwaterIn + qHX / (MdotWater * Cp); + this->ExhaustHX.WaterOutletTemp = TwaterIn + this->ExhaustHX.qHX / (this->ExhaustHX.WaterMassFlowRate * Cp); } - } else if (SELECT_CASE_var == LMTDempiricalUAeff) { // method 2 - inNodeNum = FuelCell(Num).ExhaustHX.WaterInNode; - MdotWater = FuelCell(Num).ExhaustHX.WaterMassFlowRate; - MWwater = GasPhaseThermoChemistryData(4).MolecularWeight; - NdotWater = MdotWater / MWwater; - NdotGas = FuelCell(Num).AuxilHeat.NdotAuxMix; + } else if (SELECT_CASE_var == DataGenerators::LMTDempiricalUAeff) { // method 2 + Real64 MWwater = DataGenerators::GasPhaseThermoChemistryData(4).MolecularWeight; + Real64 NdotWater = this->ExhaustHX.WaterMassFlowRate / MWwater; + Real64 NdotGas = this->AuxilHeat.NdotAuxMix; - UAeff = FuelCell(Num).ExhaustHX.hxs0 + FuelCell(Num).ExhaustHX.hxs1 * NdotWater + FuelCell(Num).ExhaustHX.hxs2 * pow_2(NdotWater) + - FuelCell(Num).ExhaustHX.hxs3 * NdotGas + FuelCell(Num).ExhaustHX.hxs4 * pow_2(NdotGas); + Real64 UAeff = this->ExhaustHX.hxs0 + this->ExhaustHX.hxs1 * NdotWater + this->ExhaustHX.hxs2 * pow_2(NdotWater) + + this->ExhaustHX.hxs3 * NdotGas + this->ExhaustHX.hxs4 * pow_2(NdotGas); - TauxMix = FuelCell(Num).AuxilHeat.TauxMix; - TwaterIn = FuelCell(Num).ExhaustHX.WaterInletTemp; + Real64 TauxMix = this->AuxilHeat.TauxMix; + Real64 TwaterIn = this->ExhaustHX.WaterInletTemp; + Real64 CpWaterMol; FigureLiquidWaterHeatCap(TwaterIn, CpWaterMol); // factor of 1000.0 for kmol -> mol - NdotCpWater = NdotWater * CpWaterMol * 1000.0; - FigureAuxilHeatGasHeatCap(Num, TauxMix, CpProdGasMol); // Cp in (J/mol*K) - NdotCpAuxMix = NdotGas * CpProdGasMol * 1000.0; - - // commented out protection for taking exponent of too large a number - // because it hasn't been a problem in testing - // testVal = LOG(huge(NdotCpAuxMix)) - // ExpTestVal = 700.0 - // IF (UAeff*(1/NdotCpAuxMix) > ExpTestVal) THEN - // write(*,*) 'Houston, we have a problem, EXP [] func will fail for UAeff*(1/NdotCpAuxMix):', UAeff*(1/NdotCpAuxMix) - // ELSEIF (UAeff*(1/NdotCpWater) > ExpTestVal) THEN - // write(*,*) 'Houston, we have a problem, EXP [] func will fail for UAeff*(1/NdotCpWater:', UAeff*(1/NdotCpWater) - // ELSE + Real64 NdotCpWater = NdotWater * CpWaterMol * 1000.0; + Real64 CpProdGasMol; + this->FigureAuxilHeatGasHeatCap(TauxMix, CpProdGasMol); // Cp in (J/mol*K) + Real64 NdotCpAuxMix = NdotGas * CpProdGasMol * 1000.0; if ((NdotCpWater != 0.0) && (NdotCpAuxMix != 0.0)) { // trap divide by zero // now evaluate Eq. 44 - THXexh = ((1.0 - NdotCpAuxMix / NdotCpWater) / - (std::exp(UAeff * (1.0 / NdotCpAuxMix - 1.0 / NdotCpWater)) - NdotCpAuxMix / NdotCpWater)) * - TauxMix + - ((std::exp(UAeff * (1.0 / NdotCpAuxMix - 1.0 / NdotCpWater)) - 1.0) / - (std::exp(UAeff * (1.0 / NdotCpAuxMix - 1.0 / NdotCpWater)) - NdotCpAuxMix / NdotCpWater)) * - TwaterIn; + this->ExhaustHX.THXexh = ((1.0 - NdotCpAuxMix / NdotCpWater) / + (std::exp(UAeff * (1.0 / NdotCpAuxMix - 1.0 / NdotCpWater)) - NdotCpAuxMix / NdotCpWater)) * + TauxMix + + ((std::exp(UAeff * (1.0 / NdotCpAuxMix - 1.0 / NdotCpWater)) - 1.0) / + (std::exp(UAeff * (1.0 / NdotCpAuxMix - 1.0 / NdotCpWater)) - NdotCpAuxMix / NdotCpWater)) * + TwaterIn; - TwaterOut = TwaterIn + (NdotCpAuxMix / NdotCpWater) * (TauxMix - THXexh); // Eq. 42 + this->ExhaustHX.WaterOutletTemp = TwaterIn + (NdotCpAuxMix / NdotCpWater) * (TauxMix - this->ExhaustHX.THXexh); // Eq. 42 } else { - THXexh = TauxMix; - TwaterOut = TwaterIn; + this->ExhaustHX.THXexh = TauxMix; + this->ExhaustHX.WaterOutletTemp = TwaterIn; } // ENDIF - if ((THXexh - TwaterIn) != 0.0) { // trap divide by zero - qHX = UAeff * ((TauxMix - TwaterOut) - (THXexh - TwaterIn)) / std::log((TauxMix - TwaterOut) / (THXexh - TwaterIn)); + if ((this->ExhaustHX.THXexh - TwaterIn) != 0.0) { // trap divide by zero + this->ExhaustHX.qHX = UAeff * ((TauxMix - this->ExhaustHX.WaterOutletTemp) - (this->ExhaustHX.THXexh - TwaterIn)) / + std::log((TauxMix - this->ExhaustHX.WaterOutletTemp) / (this->ExhaustHX.THXexh - TwaterIn)); } else { - qHX = 0.0; + this->ExhaustHX.qHX = 0.0; } - } else if (SELECT_CASE_var == LMTDfundementalUAeff) { // method 3 - NdotGas = FuelCell(Num).AuxilHeat.NdotAuxMix; - inNodeNum = FuelCell(Num).ExhaustHX.WaterInNode; - MdotWater = FuelCell(Num).ExhaustHX.WaterMassFlowRate; - MWwater = GasPhaseThermoChemistryData(4).MolecularWeight; - NdotWater = MdotWater / MWwater; - - hgas = - FuelCell(Num).ExhaustHX.h0gas * std::pow(NdotGas / FuelCell(Num).ExhaustHX.NdotGasRef, FuelCell(Num).ExhaustHX.nCoeff); // Eq. 48 + } else if (SELECT_CASE_var == DataGenerators::LMTDfundementalUAeff) { // method 3 + Real64 NdotGas = this->AuxilHeat.NdotAuxMix; + Real64 MWwater = DataGenerators::GasPhaseThermoChemistryData(4).MolecularWeight; + Real64 NdotWater = this->ExhaustHX.WaterMassFlowRate / MWwater; - hwater = FuelCell(Num).ExhaustHX.h0Water * - std::pow(NdotWater / FuelCell(Num).ExhaustHX.NdotWaterRef, FuelCell(Num).ExhaustHX.mCoeff); // Eq. 48 + Real64 hgas = this->ExhaustHX.h0gas * std::pow(NdotGas / this->ExhaustHX.NdotGasRef, this->ExhaustHX.nCoeff); // Eq. 48 + Real64 hwater = this->ExhaustHX.h0Water * std::pow(NdotWater / this->ExhaustHX.NdotWaterRef, this->ExhaustHX.mCoeff); // Eq. 48 // now equation 47 - UAeff = 1.0 / (1.0 / (hgas * FuelCell(Num).ExhaustHX.AreaGas) + 1.0 / (hwater * FuelCell(Num).ExhaustHX.AreaWater) + - FuelCell(Num).ExhaustHX.Fadjust); + Real64 UAeff = 1.0 / (1.0 / (hgas * this->ExhaustHX.AreaGas) + 1.0 / (hwater * this->ExhaustHX.AreaWater) + this->ExhaustHX.Fadjust); - TauxMix = FuelCell(Num).AuxilHeat.TauxMix; - TwaterIn = FuelCell(Num).ExhaustHX.WaterInletTemp; + Real64 TauxMix = this->AuxilHeat.TauxMix; + Real64 TwaterIn = this->ExhaustHX.WaterInletTemp; + Real64 CpWaterMol; FigureLiquidWaterHeatCap(TwaterIn, CpWaterMol); - NdotCpWater = NdotWater * CpWaterMol * 1000.0; - FigureAuxilHeatGasHeatCap(Num, TauxMix, CpProdGasMol); // Cp in (J/mol*K) - NdotCpAuxMix = NdotGas * CpProdGasMol * 1000.0; + Real64 NdotCpWater = NdotWater * CpWaterMol * 1000.0; + Real64 CpProdGasMol; + this->FigureAuxilHeatGasHeatCap(TauxMix, CpProdGasMol); // Cp in (J/mol*K) + Real64 NdotCpAuxMix = NdotGas * CpProdGasMol * 1000.0; if ((NdotCpWater != 0.0) && (NdotCpAuxMix != 0.0)) { // trap divide by zero // now evaluate Eq. 44 - THXexh = ((1.0 - NdotCpAuxMix / NdotCpWater) / - (std::exp(UAeff * (1.0 / NdotCpAuxMix - 1.0 / NdotCpWater)) - NdotCpAuxMix / NdotCpWater)) * - TauxMix + - ((std::exp(UAeff * (1.0 / NdotCpAuxMix - 1.0 / NdotCpWater)) - 1.0) / - (std::exp(UAeff * (1.0 / NdotCpAuxMix - 1.0 / NdotCpWater)) - NdotCpAuxMix / NdotCpWater)) * - TwaterIn; + this->ExhaustHX.THXexh = ((1.0 - NdotCpAuxMix / NdotCpWater) / + (std::exp(UAeff * (1.0 / NdotCpAuxMix - 1.0 / NdotCpWater)) - NdotCpAuxMix / NdotCpWater)) * + TauxMix + + ((std::exp(UAeff * (1.0 / NdotCpAuxMix - 1.0 / NdotCpWater)) - 1.0) / + (std::exp(UAeff * (1.0 / NdotCpAuxMix - 1.0 / NdotCpWater)) - NdotCpAuxMix / NdotCpWater)) * + TwaterIn; - TwaterOut = TwaterIn + (NdotCpAuxMix / NdotCpWater) * (TauxMix - THXexh); // Eq. 42 + this->ExhaustHX.WaterOutletTemp = TwaterIn + (NdotCpAuxMix / NdotCpWater) * (TauxMix - this->ExhaustHX.THXexh); // Eq. 42 } else { - THXexh = TauxMix; - TwaterOut = TwaterIn; + this->ExhaustHX.THXexh = TauxMix; + this->ExhaustHX.WaterOutletTemp = TwaterIn; } - if ((THXexh - TwaterIn) != 0.0) { // trap divide by zero - qHX = UAeff * ((TauxMix - TwaterOut) - (THXexh - TwaterIn)) / std::log((TauxMix - TwaterOut) / (THXexh - TwaterIn)); + if ((this->ExhaustHX.THXexh - TwaterIn) != 0.0) { // trap divide by zero + this->ExhaustHX.qHX = UAeff * ((TauxMix - this->ExhaustHX.WaterOutletTemp) - (this->ExhaustHX.THXexh - TwaterIn)) / + std::log((TauxMix - this->ExhaustHX.WaterOutletTemp) / (this->ExhaustHX.THXexh - TwaterIn)); } else { - qHX = 0.0; + this->ExhaustHX.qHX = 0.0; } - } else if (SELECT_CASE_var == Condensing) { // method 4 - inNodeNum = FuelCell(Num).ExhaustHX.WaterInNode; - MdotWater = FuelCell(Num).ExhaustHX.WaterMassFlowRate; - if (MdotWater != 0.0) { + } else if (SELECT_CASE_var == DataGenerators::Condensing) { // method 4 + if (this->ExhaustHX.WaterMassFlowRate != 0.0) { - MWwater = GasPhaseThermoChemistryData(4).MolecularWeight; - NdotWater = MdotWater / MWwater; - NdotGas = FuelCell(Num).AuxilHeat.NdotAuxMix; + Real64 MWwater = DataGenerators::GasPhaseThermoChemistryData(4).MolecularWeight; + Real64 NdotWater = this->ExhaustHX.WaterMassFlowRate / MWwater; + Real64 NdotGas = this->AuxilHeat.NdotAuxMix; - UAeff = FuelCell(Num).ExhaustHX.hxs0 + FuelCell(Num).ExhaustHX.hxs1 * NdotWater + - FuelCell(Num).ExhaustHX.hxs2 * pow_2(NdotWater) + FuelCell(Num).ExhaustHX.hxs3 * NdotGas + - FuelCell(Num).ExhaustHX.hxs4 * pow_2(NdotGas); + Real64 UAeff = this->ExhaustHX.hxs0 + this->ExhaustHX.hxs1 * NdotWater + this->ExhaustHX.hxs2 * pow_2(NdotWater) + + this->ExhaustHX.hxs3 * NdotGas + this->ExhaustHX.hxs4 * pow_2(NdotGas); - TauxMix = FuelCell(Num).AuxilHeat.TauxMix; - TwaterIn = FuelCell(Num).ExhaustHX.WaterInletTemp; + Real64 TauxMix = this->AuxilHeat.TauxMix; + Real64 TwaterIn = this->ExhaustHX.WaterInletTemp; + Real64 CpWaterMol; FigureLiquidWaterHeatCap(TwaterIn, CpWaterMol); - NdotCpWater = NdotWater * CpWaterMol * 1000.0; - FigureAuxilHeatGasHeatCap(Num, TauxMix, CpProdGasMol); // Cp in (J/mol*K) - NdotCpAuxMix = NdotGas * CpProdGasMol * 1000.0; + Real64 NdotCpWater = NdotWater * CpWaterMol * 1000.0; + Real64 CpProdGasMol; + this->FigureAuxilHeatGasHeatCap(TauxMix, CpProdGasMol); // Cp in (J/mol*K) + Real64 NdotCpAuxMix = NdotGas * CpProdGasMol * 1000.0; // find water fraction in incoming gas stream - for (i = 1; i <= isize(FuelCell(Num).AuxilHeat.GasLibID); ++i) { - if (FuelCell(Num).AuxilHeat.GasLibID(i) == 4) waterFract = FuelCell(Num).AuxilHeat.ConstitMolalFract(i); + for (int i = 1; i <= isize(this->AuxilHeat.GasLibID); ++i) { + if (this->AuxilHeat.GasLibID(i) == 4) this->ExhaustHX.WaterVaporFractExh = this->AuxilHeat.ConstitMolalFract(i); } - NdotWaterVapor = waterFract * NdotGas; + Real64 NdotWaterVapor = this->ExhaustHX.WaterVaporFractExh * NdotGas; - TcondThresh = FuelCell(Num).ExhaustHX.CondensationThresholdTemp; - hxl1 = FuelCell(Num).ExhaustHX.l1Coeff; - hxl2 = FuelCell(Num).ExhaustHX.l2Coeff; + Real64 TcondThresh = this->ExhaustHX.CondensationThresholdTemp; + Real64 hxl1 = this->ExhaustHX.l1Coeff; + Real64 hxl2 = this->ExhaustHX.l2Coeff; - NdotWaterCond = (TcondThresh - TwaterIn) * (hxl1 * (NdotWaterVapor / NdotGas) + hxl2 * pow_2(NdotWaterVapor / NdotGas)); + this->ExhaustHX.CondensateRate = + (TcondThresh - TwaterIn) * (hxl1 * (NdotWaterVapor / NdotGas) + hxl2 * pow_2(NdotWaterVapor / NdotGas)); - if (NdotWaterCond < 0.0) NdotWaterCond = 0.0; + if (this->ExhaustHX.CondensateRate < 0.0) this->ExhaustHX.CondensateRate = 0.0; - hfpwater = 4.4004e+07; // molal heat of vaporization of water J/kmol) + Real64 hfpwater = 4.4004e+07; // molal heat of vaporization of water J/kmol) if ((NdotCpWater != 0.0) && (NdotCpAuxMix != 0.0)) { // trap divide by zero // now evaluate Eq. 44 - THXexh = ((1.0 - NdotCpAuxMix / NdotCpWater) / - (std::exp(UAeff * (1.0 / NdotCpAuxMix - 1.0 / NdotCpWater)) - NdotCpAuxMix / NdotCpWater)) * - TauxMix + - ((std::exp(UAeff * (1.0 / NdotCpAuxMix - 1.0 / NdotCpWater)) - 1.0) / - (std::exp(UAeff * (1.0 / NdotCpAuxMix - 1.0 / NdotCpWater)) - NdotCpAuxMix / NdotCpWater)) * - TwaterIn; - - TwaterOut = TwaterIn + (NdotCpAuxMix / NdotCpWater) * (TauxMix - THXexh) + (NdotWaterCond * hfpwater) / NdotCpWater; - - if (NdotWaterCond > 0) { // Eq. 44 is not correct. use its result as first guess for revised way... - - for (loop = 1; loop <= 5; - ++loop) { // iterative soluion because in condensing case THXexh is function of qSens and qLatent - - if ((THXexh - TwaterIn) != 0.0 && - ((TauxMix - TwaterOut) / (THXexh - TwaterIn) > 0.0001)) { // trap divide by zero and negative log - qSens = - UAeff * ((TauxMix - TwaterOut) - (THXexh - TwaterIn)) / std::log((TauxMix - TwaterOut) / (THXexh - TwaterIn)); + this->ExhaustHX.THXexh = ((1.0 - NdotCpAuxMix / NdotCpWater) / + (std::exp(UAeff * (1.0 / NdotCpAuxMix - 1.0 / NdotCpWater)) - NdotCpAuxMix / NdotCpWater)) * + TauxMix + + ((std::exp(UAeff * (1.0 / NdotCpAuxMix - 1.0 / NdotCpWater)) - 1.0) / + (std::exp(UAeff * (1.0 / NdotCpAuxMix - 1.0 / NdotCpWater)) - NdotCpAuxMix / NdotCpWater)) * + TwaterIn; + + this->ExhaustHX.WaterOutletTemp = TwaterIn + (NdotCpAuxMix / NdotCpWater) * (TauxMix - this->ExhaustHX.THXexh) + + (this->ExhaustHX.CondensateRate * hfpwater) / NdotCpWater; + + if (this->ExhaustHX.CondensateRate > 0) { // Eq. 44 is not correct. use its result as first guess for revised way... + // iterative solution because in condensing case THXexh is function of qSens and qLatent + for (int loop = 1; loop <= 5; ++loop) { + + Real64 qSens; + Real64 qLatent; + + if ((this->ExhaustHX.THXexh - TwaterIn) != 0.0 && + ((TauxMix - this->ExhaustHX.WaterOutletTemp) / (this->ExhaustHX.THXexh - TwaterIn) > + 0.0001)) { // trap divide by zero and negative log + qSens = UAeff * ((TauxMix - this->ExhaustHX.WaterOutletTemp) - (this->ExhaustHX.THXexh - TwaterIn)) / + std::log((TauxMix - this->ExhaustHX.WaterOutletTemp) / (this->ExhaustHX.THXexh - TwaterIn)); } else { qSens = 0.0; } - qLatent = NdotWaterCond * hfpwater; + qLatent = this->ExhaustHX.CondensateRate * hfpwater; if (qSens > 0) { - THXexh = + this->ExhaustHX.THXexh = TauxMix * ((1.0 - NdotCpAuxMix / NdotCpWater) / ((std::exp(UAeff * (1.0 / NdotCpAuxMix - 1.0 / NdotCpWater)) / (std::exp((UAeff * qLatent) / (NdotCpWater * qSens)))) - NdotCpAuxMix / NdotCpWater)) + @@ -3864,178 +3054,83 @@ namespace FuelCellElectricGenerator { (std::exp((UAeff * qLatent) / (NdotCpWater * qSens))) - NdotCpAuxMix / NdotCpWater)); } else { - THXexh = TauxMix; + this->ExhaustHX.THXexh = TauxMix; } - TwaterOut = TwaterIn + (NdotCpAuxMix / NdotCpWater) * (TauxMix - THXexh) + (NdotWaterCond * hfpwater) / NdotCpWater; + this->ExhaustHX.WaterOutletTemp = TwaterIn + (NdotCpAuxMix / NdotCpWater) * (TauxMix - this->ExhaustHX.THXexh) + + (this->ExhaustHX.CondensateRate * hfpwater) / NdotCpWater; } } } else { - THXexh = TauxMix; - TwaterOut = TwaterIn; + this->ExhaustHX.THXexh = TauxMix; + this->ExhaustHX.WaterOutletTemp = TwaterIn; } - if ((THXexh - TwaterIn) != 0.0 && - ((TauxMix - TwaterOut) / (THXexh - TwaterIn) > 0.0001)) { // trap divide by zero and negative log + if ((this->ExhaustHX.THXexh - TwaterIn) != 0.0 && + ((TauxMix - this->ExhaustHX.WaterOutletTemp) / (this->ExhaustHX.THXexh - TwaterIn) > + 0.0001)) { // trap divide by zero and negative log - qHX = UAeff * ((TauxMix - TwaterOut) - (THXexh - TwaterIn)) / std::log((TauxMix - TwaterOut) / (THXexh - TwaterIn)) + - NdotWaterCond * hfpwater; + this->ExhaustHX.qHX = UAeff * ((TauxMix - this->ExhaustHX.WaterOutletTemp) - (this->ExhaustHX.THXexh - TwaterIn)) / + std::log((TauxMix - this->ExhaustHX.WaterOutletTemp) / (this->ExhaustHX.THXexh - TwaterIn)) + + this->ExhaustHX.CondensateRate * hfpwater; } else { - qHX = 0.0; + this->ExhaustHX.qHX = 0.0; } } else { // no cooling water flow, model will blow up. - qHX = 0.0; - THXexh = FuelCell(Num).AuxilHeat.TauxMix; - TwaterOut = FuelCell(Num).ExhaustHX.WaterInletTemp; - NdotWaterCond = 0.0; - waterFract = -9999.0; // not defined + this->ExhaustHX.qHX = 0.0; + this->ExhaustHX.THXexh = this->AuxilHeat.TauxMix; + this->ExhaustHX.WaterOutletTemp = this->ExhaustHX.WaterInletTemp; + this->ExhaustHX.CondensateRate = 0.0; + this->ExhaustHX.WaterVaporFractExh = -9999.0; // not defined } - // init input from Auxiliary heater - // FuelCell(Num)%ExhaustHX%NdotHXleaving = FuelCell(Num)%AuxilHeat%NdotAuxMix - // FuelCell(Num)%ExhaustHX%ConstitMolalFract = FuelCell(Num)%AuxilHeat%ConstitMolalFract - // FuelCell(Num)%ExhaustHX%GasLibID = FuelCell(Num)%AuxilHeat%GasLibID - - // now modify leaving gas constituents for condensed water. - // FuelCell(Num)%ExhaustHX%NdotHXleaving = FuelCell(Num)%AuxilHeat%NdotAuxMix - NdotWaterCond - // If ( FuelCell(Num)%ExhaustHX%NdotHXleaving > 0) then - // DO I = 1, SIZE(FuelCell(Num)%AuxilHeat%GasLibID) - // If (FuelCell(Num)%AuxilHeat%GasLibID(I) == 4) then ! water constituent - // FuelCell(Num)%ExhaustHX%ConstitMolalFract(I) = & - // (FuelCell(Num)%AuxilHeat%ConstitMolalFract(I)* FuelCell(Num)%AuxilHeat%NdotAuxMix - NdotWaterCond) & - // / FuelCell(Num)%ExhaustHX%NdotHXleaving - // cycle - // ENDIF - - // FuelCell(Num)%ExhaustHX%ConstitMolalFract(I) = FuelCell(Num)%AuxilHeat%ConstitMolalFract(I) & - // * FuelCell(Num)%AuxilHeat%NdotAuxMix / FuelCell(Num)%ExhaustHX%NdotHXleaving - // ENDDO - // ENDIF - - // get new average heat capacity - // CALL FigureHXleavingGasHeatCap(Num, (THXexh + TauxMix)/2 , CpHXleavingGasMol) - - // NdotCpHXleaving = FuelCell(Num)%ExhaustHX%NdotHXleaving*CpHXleavingGasMol* 1000.0 - - // update gas leaving temperature with modified heat transfer rate - // IF ((NdotCpHXleaving > 0) .AND. (qHX > 0)) THEN - // THXexh = TauxMix - (qHX / NdotCpHXleaving) - // ELSE - // THXexh = TauxMix - // ENDIF - // update water leaving temperature with modified heat transfer rate - // IF (MdotWater * CPCW( (TwaterIn + TwaterOut)/2 ) <= 0.0) THEN - // TwaterOut = TwaterIn - // ELSE - // TwaterOut = TwaterIn + qHX / (MdotWater * CPCW( (TwaterIn + TwaterOut)/2 )) - // ENDIF - } else { assert(false); // Variables not set are used below } } // update results in data structure. - FuelCell(Num).ExhaustHX.qHX = qHX; - FuelCell(Num).ExhaustHX.THXexh = THXexh; - FuelCell(Num).ExhaustHX.WaterMassFlowRate = MdotWater; - FuelCell(Num).ExhaustHX.WaterVaporFractExh = waterFract; - - FuelCell(Num).ExhaustHX.CondensateRate = NdotWaterCond; - FuelCell(Num).ExhaustHX.WaterOutletTemp = TwaterOut; - FuelCell(Num).ExhaustHX.WaterOutletEnthalpy = Node(inNodeNum).Enthalpy + qHX; - - // now update water outlet node Changing to Kg/s! - // OutNodeNum = FuelCell(Num)%ExhaustHX%WaterOutNode - // inNodeNum = FuelCell(Num)%ExhaustHX%WaterInNode - // Node(OutNodeNum)%Temp = Twaterout - // Node(OutNodeNum)%Enthalpy = - // Node(OutNodeNum)%MassFlowRate = MdotWater + this->ExhaustHX.WaterOutletEnthalpy = DataLoopNode::Node(this->ExhaustHX.WaterInNode).Enthalpy + this->ExhaustHX.qHX; } - void SimFuelCellPlantHeatRecovery(std::string const &EP_UNUSED(CompType), - std::string const &CompName, - int const CompTypeNum, - int &CompNum, - bool const EP_UNUSED(RunFlag), - bool &InitLoopEquip, - Real64 &EP_UNUSED(MyLoad), // unused1208 - Real64 &MaxCap, - Real64 &MinCap, - Real64 &OptCap, - bool const FirstHVACIteration // TRUE if First iteration of simulation - ) + void FCDataStruct::getDesignCapacities(const PlantLocation &EP_UNUSED(calledFromLocation), Real64 &MaxLoad, Real64 &MinLoad, Real64 &OptLoad) { + MaxLoad = 0.0; + MinLoad = 0.0; + OptLoad = 0.0; + } - // SUBROUTINE INFORMATION: - // AUTHOR B. Griffith - // DATE WRITTEN Jan 2006 - // MODIFIED na - // RE-ENGINEERED na - - // PURPOSE OF THIS SUBROUTINE: - // makes sure input are gotten and setup from Plant loop perspective. - // does not (re)simulate entire FuelCell model - - // Using/Aliasing - using DataPlant::TypeOf_Generator_FCExhaust; - using DataPlant::TypeOf_Generator_FCStackCooler; - using PlantUtilities::UpdateComponentHeatRecoverySide; - - if (GetFuelCellInput) { - - // Read input data. - GetFuelCellGeneratorInput(); - GetFuelCellInput = false; - } - - if (InitLoopEquip) { - if (CompTypeNum == TypeOf_Generator_FCExhaust) { - CompNum = UtilityRoutines::FindItemInList(CompName, FuelCell, &FCDataStruct::NameExhaustHX); - } else if (CompTypeNum == TypeOf_Generator_FCStackCooler) { - CompNum = UtilityRoutines::FindItemInList(CompName, FuelCell, &FCDataStruct::NameStackCooler); - } - if (CompNum == 0) { - ShowFatalError("SimFuelCellPlantHeatRecovery: Fuel Cell Generator Unit not found=" + CompName); - } - MinCap = 0.0; - MaxCap = 0.0; - OptCap = 0.0; - return; - } // End Of InitLoopEquip - - if (CompTypeNum == TypeOf_Generator_FCStackCooler) { - UpdateComponentHeatRecoverySide(FuelCell(CompNum).CWLoopNum, - FuelCell(CompNum).CWLoopSideNum, - TypeOf_Generator_FCStackCooler, - FuelCell(CompNum).StackCooler.WaterInNode, - FuelCell(CompNum).StackCooler.WaterOutNode, - FuelCell(CompNum).Report.qHX, - FuelCell(CompNum).Report.HeatRecInletTemp, - FuelCell(CompNum).Report.HeatRecOutletTemp, - FuelCell(CompNum).Report.HeatRecMdot, - FirstHVACIteration); - } else if (CompTypeNum == TypeOf_Generator_FCExhaust) { - UpdateComponentHeatRecoverySide(FuelCell(CompNum).CWLoopNum, - FuelCell(CompNum).CWLoopSideNum, - TypeOf_Generator_FCExhaust, - FuelCell(CompNum).ExhaustHX.WaterInNode, - FuelCell(CompNum).ExhaustHX.WaterOutNode, - FuelCell(CompNum).ExhaustHX.qHX, - FuelCell(CompNum).ExhaustHX.WaterInletTemp, - FuelCell(CompNum).ExhaustHX.WaterOutletTemp, - FuelCell(CompNum).ExhaustHX.WaterMassFlowRate, - FirstHVACIteration); + void FCDataStruct::simulate(const PlantLocation &EP_UNUSED(calledFromLocation), + bool FirstHVACIteration, + Real64 &EP_UNUSED(CurLoad), + bool EP_UNUSED(RunFlag)) + { + if (this->TypeOf == DataPlant::TypeOf_Generator_FCStackCooler) { + PlantUtilities::UpdateComponentHeatRecoverySide(this->CWLoopNum, + this->CWLoopSideNum, + DataPlant::TypeOf_Generator_FCStackCooler, + this->StackCooler.WaterInNode, + this->StackCooler.WaterOutNode, + this->Report.qHX, + this->Report.HeatRecInletTemp, + this->Report.HeatRecOutletTemp, + this->Report.HeatRecMdot, + FirstHVACIteration); + } else if (this->TypeOf == DataPlant::TypeOf_Generator_FCExhaust) { + PlantUtilities::UpdateComponentHeatRecoverySide(this->CWLoopNum, + this->CWLoopSideNum, + DataPlant::TypeOf_Generator_FCExhaust, + this->ExhaustHX.WaterInNode, + this->ExhaustHX.WaterOutNode, + this->ExhaustHX.qHX, + this->ExhaustHX.WaterInletTemp, + this->ExhaustHX.WaterOutletTemp, + this->ExhaustHX.WaterMassFlowRate, + FirstHVACIteration); } } - // End FuelCell Generator Module Model Subroutines - // ***************************************************************************** - - // Begin FuelCell Generator Module Utility Subroutines - // ***************************************************************************** - - void InitFuelCellGenerators(int const FCnum) // index to specific fuel cell generator + void FCDataStruct::initialize() // index to specific fuel cell generator { // SUBROUTINE INFORMATION: @@ -4050,239 +3145,158 @@ namespace FuelCellElectricGenerator { // METHODOLOGY EMPLOYED: // Uses the status flags to trigger initializations. - // REFERENCES: - // na - - // USE STATEMENTS: - - // Using/Aliasing - using DataGlobals::BeginEnvrnFlag; - using DataGlobals::HourOfDay; - using DataGlobals::SecInHour; - using DataGlobals::TimeStep; - using DataGlobals::TimeStepZone; - using DataHVACGlobals::SysTimeElapsed; - using DataHVACGlobals::TimeStepSys; - using DataLoopNode::Node; - using DataPlant::PlantLoop; - using DataPlant::TypeOf_Generator_FCExhaust; - using FluidProperties::GetDensityGlycol; - using PlantUtilities::InitComponentNodes; - using PlantUtilities::ScanPlantLoopsForObject; - using PlantUtilities::SetComponentFlowRate; - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE PARAMETER DEFINITIONS: static std::string const RoutineName("InitFuelCellGenerators"); - // INTERFACE BLOCK SPECIFICATIONS - // na - - // DERIVED TYPE DEFINITIONS - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - static bool InitGeneratorOnce(true); // flag for 1 time initialization - static Array1D_bool MyEnvrnFlag; // flag for init once at start of environment - static Array1D_bool MyWarmupFlag; // flag for init after warmup complete - int inNode; // inlet index in Node array - int outNode; // outlet, index in Node array - Real64 TimeElapsed; // Fraction of the current hour that has elapsed (h) - static Array1D_bool MyPlantScanFlag; - Real64 mdot; // local temporary mass flow rate - Real64 rho; // local temporary fluid density - bool errFlag; - - // FLOW: - // Do the one time initializations - if (InitGeneratorOnce) { - MyEnvrnFlag.allocate(NumFuelCellGenerators); - MyWarmupFlag.allocate(NumFuelCellGenerators); - MyPlantScanFlag.allocate(NumFuelCellGenerators); - MyEnvrnFlag = true; - MyWarmupFlag = false; - InitGeneratorOnce = false; - MyPlantScanFlag = true; - } // end one time setups and inits - - if (MyPlantScanFlag(FCnum) && allocated(PlantLoop)) { - errFlag = false; - - ScanPlantLoopsForObject(FuelCell(FCnum).NameExhaustHX, - TypeOf_Generator_FCExhaust, - FuelCell(FCnum).CWLoopNum, - FuelCell(FCnum).CWLoopSideNum, - FuelCell(FCnum).CWBranchNum, - FuelCell(FCnum).CWCompNum, - errFlag, - _, - _, - _, - _, - _); + if (this->MyPlantScanFlag_Init && allocated(DataPlant::PlantLoop)) { + bool errFlag = false; + + PlantUtilities::ScanPlantLoopsForObject(this->NameExhaustHX, + DataPlant::TypeOf_Generator_FCExhaust, + this->CWLoopNum, + this->CWLoopSideNum, + this->CWBranchNum, + this->CWCompNum, + errFlag, + _, + _, + _, + _, + _); // if there is a stack cooler option it might be connected to plant as well if (errFlag) { ShowFatalError("InitFuelCellGenerators: Program terminated due to previous condition(s)."); } - MyPlantScanFlag(FCnum) = false; + this->MyPlantScanFlag_Init = false; } // Do the Begin Environment initializations - if (BeginEnvrnFlag && MyEnvrnFlag(FCnum) && !MyPlantScanFlag(FCnum)) { - - FuelSupply(FuelCell(FCnum).FuelSupNum).PfuelCompEl = 0.0; - FuelSupply(FuelCell(FCnum).FuelSupNum).TfuelIntoFCPM = 0.0; - FuelSupply(FuelCell(FCnum).FuelSupNum).TfuelIntoCompress = 0.0; - FuelSupply(FuelCell(FCnum).FuelSupNum).QskinLoss = 0.0; - - FuelCell(FCnum).AirSup.TairIntoFCPM = 0.0; - FuelCell(FCnum).AirSup.PairCompEl = 0.0; - FuelCell(FCnum).AirSup.TairIntoBlower = 0.0; - FuelCell(FCnum).AirSup.QskinLoss = 0.0; - FuelCell(FCnum).AirSup.QintakeRecovery = 0.0; - FuelCell(FCnum).FCPM.NumCycles = 0; - FuelCell(FCnum).FCPM.Pel = 0.0; - FuelCell(FCnum).FCPM.PelLastTimeStep = 0.0; - FuelCell(FCnum).FCPM.Eel = 0.0; - FuelCell(FCnum).FCPM.PelancillariesAC = 0.0; - FuelCell(FCnum).FCPM.NdotFuel = 0.0; - FuelCell(FCnum).FCPM.TotFuelInEnthalphy = 0.0; - FuelCell(FCnum).FCPM.NdotProdGas = 0.0; - FuelCell(FCnum).FCPM.TprodGasLeavingFCPM = 0.0; - FuelCell(FCnum).FCPM.TotProdGasEnthalphy = 0.0; - FuelCell(FCnum).FCPM.NdotAir = 0.0; - FuelCell(FCnum).FCPM.TotAirInEnthalphy = 0.0; - FuelCell(FCnum).FCPM.NdotLiqwater = 0.0; - FuelCell(FCnum).FCPM.TwaterInlet = 0.0; - FuelCell(FCnum).FCPM.WaterInEnthalpy = 0.0; - FuelCell(FCnum).FCPM.TprodGasLeavingFCPM = 200.0; - FuelCell(FCnum).FCPM.FractionalDayofLastStartUp = 0.0; - FuelCell(FCnum).FCPM.FractionalDayofLastShutDown = 0.0; - FuelCell(FCnum).FCPM.HasBeenOn = true; - FuelCell(FCnum).FCPM.DuringShutDown = false; - FuelCell(FCnum).FCPM.DuringStartUp = false; - FuelCell(FCnum).WaterSup.TwaterIntoCompress = 0.0; - FuelCell(FCnum).WaterSup.TwaterIntoFCPM = 0.0; - FuelCell(FCnum).WaterSup.PwaterCompEl = 0.0; - FuelCell(FCnum).WaterSup.QskinLoss = 0.0; - FuelCell(FCnum).AuxilHeat.TauxMix = 0.0; - FuelCell(FCnum).AuxilHeat.NdotAuxMix = 0.0; - FuelCell(FCnum).AuxilHeat.QskinLoss = 0.0; - FuelCell(FCnum).AuxilHeat.QairIntake = 0.0; - FuelCell(FCnum).ExhaustHX.NdotHXleaving = 0.0; - FuelCell(FCnum).ExhaustHX.WaterOutletTemp = 0.0; - FuelCell(FCnum).ExhaustHX.WaterOutletEnthalpy = 0.0; - - FuelCell(FCnum).ElecStorage.LastTimeStepStateOfCharge = FuelCell(FCnum).ElecStorage.StartingEnergyStored; - FuelCell(FCnum).ElecStorage.ThisTimeStepStateOfCharge = FuelCell(FCnum).ElecStorage.StartingEnergyStored; - FuelCell(FCnum).ElecStorage.PelNeedFromStorage = 0.0; - FuelCell(FCnum).ElecStorage.IdesiredDischargeCurrent = 0.0; - FuelCell(FCnum).ElecStorage.PelFromStorage = 0.0; - FuelCell(FCnum).ElecStorage.IfromStorage = 0.0; - FuelCell(FCnum).ElecStorage.PelIntoStorage = 0.0; - FuelCell(FCnum).ElecStorage.QairIntake = 0.0; - - FuelCell(FCnum).Inverter.PCUlosses = 0.0; - FuelCell(FCnum).Inverter.QairIntake = 0.0; - - rho = GetDensityGlycol( - PlantLoop(FuelCell(FCnum).CWLoopNum).FluidName, InitHRTemp, PlantLoop(FuelCell(FCnum).CWLoopNum).FluidIndex, RoutineName); - - FuelCell(FCnum).ExhaustHX.WaterMassFlowRateDesign = FuelCell(FCnum).ExhaustHX.WaterVolumeFlowMax * rho; - FuelCell(FCnum).ExhaustHX.WaterMassFlowRate = FuelCell(FCnum).ExhaustHX.WaterMassFlowRateDesign; - inNode = FuelCell(FCnum).ExhaustHX.WaterInNode; - outNode = FuelCell(FCnum).ExhaustHX.WaterOutNode; - Node(inNode).Temp = InitHRTemp; - Node(outNode).Temp = InitHRTemp; - - InitComponentNodes(0.0, - FuelCell(FCnum).ExhaustHX.WaterMassFlowRateDesign, - inNode, - outNode, - FuelCell(FCnum).CWLoopNum, - FuelCell(FCnum).CWLoopSideNum, - FuelCell(FCnum).CWBranchNum, - FuelCell(FCnum).CWCompNum); - - MyEnvrnFlag(FCnum) = false; - MyWarmupFlag(FCnum) = true; + if (DataGlobals::BeginEnvrnFlag && this->MyEnvrnFlag_Init && !this->MyPlantScanFlag_Init) { + + DataGenerators::FuelSupply(this->FuelSupNum).PfuelCompEl = 0.0; + DataGenerators::FuelSupply(this->FuelSupNum).TfuelIntoFCPM = 0.0; + DataGenerators::FuelSupply(this->FuelSupNum).TfuelIntoCompress = 0.0; + DataGenerators::FuelSupply(this->FuelSupNum).QskinLoss = 0.0; + + this->AirSup.TairIntoFCPM = 0.0; + this->AirSup.PairCompEl = 0.0; + this->AirSup.TairIntoBlower = 0.0; + this->AirSup.QskinLoss = 0.0; + this->AirSup.QintakeRecovery = 0.0; + this->FCPM.NumCycles = 0; + this->FCPM.Pel = 0.0; + this->FCPM.PelLastTimeStep = 0.0; + this->FCPM.Eel = 0.0; + this->FCPM.PelancillariesAC = 0.0; + this->FCPM.NdotFuel = 0.0; + this->FCPM.TotFuelInEnthalphy = 0.0; + this->FCPM.NdotProdGas = 0.0; + this->FCPM.TprodGasLeavingFCPM = 0.0; + this->FCPM.TotProdGasEnthalphy = 0.0; + this->FCPM.NdotAir = 0.0; + this->FCPM.TotAirInEnthalphy = 0.0; + this->FCPM.NdotLiqwater = 0.0; + this->FCPM.TwaterInlet = 0.0; + this->FCPM.WaterInEnthalpy = 0.0; + this->FCPM.TprodGasLeavingFCPM = 200.0; + this->FCPM.FractionalDayofLastStartUp = 0.0; + this->FCPM.FractionalDayofLastShutDown = 0.0; + this->FCPM.HasBeenOn = true; + this->FCPM.DuringShutDown = false; + this->FCPM.DuringStartUp = false; + this->WaterSup.TwaterIntoCompress = 0.0; + this->WaterSup.TwaterIntoFCPM = 0.0; + this->WaterSup.PwaterCompEl = 0.0; + this->WaterSup.QskinLoss = 0.0; + this->AuxilHeat.TauxMix = 0.0; + this->AuxilHeat.NdotAuxMix = 0.0; + this->AuxilHeat.QskinLoss = 0.0; + this->AuxilHeat.QairIntake = 0.0; + this->ExhaustHX.NdotHXleaving = 0.0; + this->ExhaustHX.WaterOutletTemp = 0.0; + this->ExhaustHX.WaterOutletEnthalpy = 0.0; + this->ElecStorage.LastTimeStepStateOfCharge = this->ElecStorage.StartingEnergyStored; + this->ElecStorage.ThisTimeStepStateOfCharge = this->ElecStorage.StartingEnergyStored; + this->ElecStorage.PelNeedFromStorage = 0.0; + this->ElecStorage.IdesiredDischargeCurrent = 0.0; + this->ElecStorage.PelFromStorage = 0.0; + this->ElecStorage.IfromStorage = 0.0; + this->ElecStorage.PelIntoStorage = 0.0; + this->ElecStorage.QairIntake = 0.0; + + this->Inverter.PCUlosses = 0.0; + this->Inverter.QairIntake = 0.0; + + Real64 rho = FluidProperties::GetDensityGlycol(DataPlant::PlantLoop(this->CWLoopNum).FluidName, + DataGenerators::InitHRTemp, + DataPlant::PlantLoop(this->CWLoopNum).FluidIndex, + RoutineName); + + this->ExhaustHX.WaterMassFlowRateDesign = this->ExhaustHX.WaterVolumeFlowMax * rho; + this->ExhaustHX.WaterMassFlowRate = this->ExhaustHX.WaterMassFlowRateDesign; + DataLoopNode::Node(this->ExhaustHX.WaterInNode).Temp = DataGenerators::InitHRTemp; + DataLoopNode::Node(this->ExhaustHX.WaterOutNode).Temp = DataGenerators::InitHRTemp; + + PlantUtilities::InitComponentNodes(0.0, + this->ExhaustHX.WaterMassFlowRateDesign, + this->ExhaustHX.WaterInNode, + this->ExhaustHX.WaterOutNode, + this->CWLoopNum, + this->CWLoopSideNum, + this->CWBranchNum, + this->CWCompNum); + + this->MyEnvrnFlag_Init = false; + this->MyWarmupFlag_Init = true; } // end environmental inits - if (!BeginEnvrnFlag) { - MyEnvrnFlag(FCnum) = true; + if (!DataGlobals::BeginEnvrnFlag) { + this->MyEnvrnFlag_Init = true; } - if (MyWarmupFlag(FCnum) && (!WarmupFlag)) { + if (this->MyWarmupFlag_Init && (!DataGlobals::WarmupFlag)) { // need to reset initial state of charge at beginning of environment but after warm up is complete - FuelCell(FCnum).ElecStorage.LastTimeStepStateOfCharge = FuelCell(FCnum).ElecStorage.StartingEnergyStored; - FuelCell(FCnum).ElecStorage.ThisTimeStepStateOfCharge = FuelCell(FCnum).ElecStorage.StartingEnergyStored; - MyWarmupFlag(FCnum) = false; + this->ElecStorage.LastTimeStepStateOfCharge = this->ElecStorage.StartingEnergyStored; + this->ElecStorage.ThisTimeStepStateOfCharge = this->ElecStorage.StartingEnergyStored; + this->MyWarmupFlag_Init = false; } // using and elapsed time method rather than FirstHVACIteration here - TimeElapsed = HourOfDay + TimeStep * TimeStepZone + SysTimeElapsed; - if (FuelCell(FCnum).TimeElapsed != TimeElapsed) { + Real64 timeElapsed = DataGlobals::HourOfDay + DataGlobals::TimeStep * DataGlobals::TimeStepZone + DataHVACGlobals::SysTimeElapsed; + if (this->TimeElapsed != timeElapsed) { - FuelCell(FCnum).ElecStorage.LastTimeStepStateOfCharge = FuelCell(FCnum).ElecStorage.ThisTimeStepStateOfCharge; - FuelCell(FCnum).FCPM.PelLastTimeStep = FuelCell(FCnum).FCPM.Pel; + this->ElecStorage.LastTimeStepStateOfCharge = this->ElecStorage.ThisTimeStepStateOfCharge; + this->FCPM.PelLastTimeStep = this->FCPM.Pel; - inNode = FuelCell(FCnum).ExhaustHX.WaterInNode; - outNode = FuelCell(FCnum).ExhaustHX.WaterOutNode; // intialize flow rate in water loop, this is "requesting" flow - mdot = FuelCell(FCnum).ExhaustHX.WaterMassFlowRateDesign; - - SetComponentFlowRate(mdot, - inNode, - outNode, - FuelCell(FCnum).CWLoopNum, - FuelCell(FCnum).CWLoopSideNum, - FuelCell(FCnum).CWBranchNum, - FuelCell(FCnum).CWCompNum); - - FuelCell(FCnum).ExhaustHX.WaterMassFlowRate = mdot; - FuelCell(FCnum).ExhaustHX.WaterInletTemp = Node(inNode).Temp; - FuelCell(FCnum).TimeElapsed = TimeElapsed; + Real64 mdot = this->ExhaustHX.WaterMassFlowRateDesign; + + PlantUtilities::SetComponentFlowRate(mdot, + this->ExhaustHX.WaterInNode, + this->ExhaustHX.WaterOutNode, + this->CWLoopNum, + this->CWLoopSideNum, + this->CWBranchNum, + this->CWCompNum); + + this->ExhaustHX.WaterMassFlowRate = mdot; + this->ExhaustHX.WaterInletTemp = DataLoopNode::Node(this->ExhaustHX.WaterInNode).Temp; + this->TimeElapsed = timeElapsed; } else { - inNode = FuelCell(FCnum).ExhaustHX.WaterInNode; - SetComponentFlowRate(FuelCell(FCnum).ExhaustHX.WaterMassFlowRate, - FuelCell(FCnum).ExhaustHX.WaterInNode, - FuelCell(FCnum).ExhaustHX.WaterOutNode, - FuelCell(FCnum).CWLoopNum, - FuelCell(FCnum).CWLoopSideNum, - FuelCell(FCnum).CWBranchNum, - FuelCell(FCnum).CWCompNum); + PlantUtilities::SetComponentFlowRate(this->ExhaustHX.WaterMassFlowRate, + this->ExhaustHX.WaterInNode, + this->ExhaustHX.WaterOutNode, + this->CWLoopNum, + this->CWLoopSideNum, + this->CWBranchNum, + this->CWCompNum); - FuelCell(FCnum).ExhaustHX.WaterInletTemp = Node(inNode).Temp; + this->ExhaustHX.WaterInletTemp = DataLoopNode::Node(this->ExhaustHX.WaterInNode).Temp; } } - void getFuelCellGeneratorHeatRecoveryInfo(std::string const &GeneratorName, // user specified name of Generator - std::string &heatRecoveryCompName) - { - - if (GetFuelCellInput) { - - // Read input data. - GetFuelCellGeneratorInput(); - GetFuelCellInput = false; - } - - int thisFuelCell = UtilityRoutines::FindItemInList(GeneratorName, FuelCell); - if (thisFuelCell > 0) { - heatRecoveryCompName = FuelCell(thisFuelCell).ExhaustHX.Name; - } - } - // End FuelCell Generator Module Utility Subroutines - // ***************************************************************************** - - // Beginning of Record Keeping subroutines for the FuelCell Generator Module - // ***************************************************************************** - void FigureFuelCellZoneGains() { @@ -4293,24 +3307,19 @@ namespace FuelCellElectricGenerator { // RE-ENGINEERED na // PURPOSE OF THIS SUBROUTINE: - // Couple equpment skin losses to the Zone Heat Balance + // Couple equipment skin losses to the Zone Heat Balance // calculate skin losses from different subsystems and set the value // METHODOLOGY EMPLOYED: // This routine adds up the various skin losses and then // sets the values in the ZoneIntGain structure - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - // unused INTEGER :: thisZone ! index in Zone structure array - Real64 TotalZoneHeatGain; // working variable for zone gain [w] - // INTEGER :: ZoneNum - int FCnum; // number of fuel cell static bool MyEnvrnFlag(true); if (NumFuelCellGenerators == 0) return; - if (BeginEnvrnFlag && MyEnvrnFlag) { - for (auto &e : FuelSupply) + if (DataGlobals::BeginEnvrnFlag && MyEnvrnFlag) { + for (auto &e : DataGenerators::FuelSupply) e.QskinLoss = 0.0; MyEnvrnFlag = false; for (int i = FuelCell.l(), e = FuelCell.u(); i <= e; ++i) { @@ -4331,92 +3340,49 @@ namespace FuelCellElectricGenerator { } } - if (!BeginEnvrnFlag) MyEnvrnFlag = true; + if (!DataGlobals::BeginEnvrnFlag) MyEnvrnFlag = true; // this routine needs to do something for zone gains during sizing // first collect skin losses from different subsystems - for (FCnum = 1; FCnum <= NumFuelCellGenerators; ++FCnum) { - TotalZoneHeatGain = FuelCell(FCnum).AirSup.QskinLoss + FuelSupply(FuelCell(FCnum).FuelSupNum).QskinLoss + - FuelCell(FCnum).WaterSup.QskinLoss + FuelCell(FCnum).AuxilHeat.QskinLoss + - FuelCell(FCnum).FCPM.QdotSkin; // intake Blower losses to zone | fuel compressor losses to zone | water pump losses to - // zone | auxil burner losses to zone | power module (stack and reformer) losses to - // zone + for (int FCnum = 1; FCnum <= NumFuelCellGenerators; ++FCnum) { + auto &thisFC = FuelCell(FCnum); + Real64 TotalZoneHeatGain = thisFC.AirSup.QskinLoss + DataGenerators::FuelSupply(thisFC.FuelSupNum).QskinLoss + thisFC.WaterSup.QskinLoss + + thisFC.AuxilHeat.QskinLoss + thisFC.FCPM.QdotSkin; // intake Blower losses to zone | fuel compressor losses to + // zone | water pump losses to zone | auxil burner losses to + // zone | power module (stack and reformer) losses to zone // now account for other subsystems that may or may not have air intake recovery { - auto const SELECT_CASE_var(FuelCell(FCnum).AirSup.IntakeRecoveryMode); + auto const SELECT_CASE_var(thisFC.AirSup.IntakeRecoveryMode); - if (SELECT_CASE_var == NoRecoveryOnAirIntake) { // then the heat has to go into zone - TotalZoneHeatGain += - FuelCell(FCnum).AuxilHeat.QairIntake + FuelCell(FCnum).ElecStorage.QairIntake + FuelCell(FCnum).Inverter.QairIntake; - } else if (SELECT_CASE_var == RecoverAuxiliaryBurner) { - TotalZoneHeatGain += FuelCell(FCnum).ElecStorage.QairIntake + FuelCell(FCnum).Inverter.QairIntake; + if (SELECT_CASE_var == DataGenerators::NoRecoveryOnAirIntake) { // then the heat has to go into zone + TotalZoneHeatGain += thisFC.AuxilHeat.QairIntake + thisFC.ElecStorage.QairIntake + thisFC.Inverter.QairIntake; + } else if (SELECT_CASE_var == DataGenerators::RecoverAuxiliaryBurner) { + TotalZoneHeatGain += thisFC.ElecStorage.QairIntake + thisFC.Inverter.QairIntake; - } else if (SELECT_CASE_var == RecoverInverterBatt) { - TotalZoneHeatGain += FuelCell(FCnum).AuxilHeat.QairIntake; + } else if (SELECT_CASE_var == DataGenerators::RecoverInverterBatt) { + TotalZoneHeatGain += thisFC.AuxilHeat.QairIntake; - } else if (SELECT_CASE_var == RecoverInverter) { - TotalZoneHeatGain += FuelCell(FCnum).AuxilHeat.QairIntake + FuelCell(FCnum).ElecStorage.QairIntake; - } else if (SELECT_CASE_var == RecoverBattery) { - TotalZoneHeatGain += FuelCell(FCnum).AuxilHeat.QairIntake + FuelCell(FCnum).Inverter.QairIntake; + } else if (SELECT_CASE_var == DataGenerators::RecoverInverter) { + TotalZoneHeatGain += thisFC.AuxilHeat.QairIntake + thisFC.ElecStorage.QairIntake; + } else if (SELECT_CASE_var == DataGenerators::RecoverBattery) { + TotalZoneHeatGain += thisFC.AuxilHeat.QairIntake + thisFC.Inverter.QairIntake; - } else if (SELECT_CASE_var == RecoverBurnInvertBatt) { + } else if (SELECT_CASE_var == DataGenerators::RecoverBurnInvertBatt) { // do nothing } } - FuelCell(FCnum).QconvZone = TotalZoneHeatGain * (1 - FuelCell(FCnum).FCPM.RadiativeFract); - FuelCell(FCnum).Report.SkinLossConvect = FuelCell(FCnum).QconvZone; - FuelCell(FCnum).QradZone = TotalZoneHeatGain * FuelCell(FCnum).FCPM.RadiativeFract; - FuelCell(FCnum).Report.SkinLossRadiat = FuelCell(FCnum).QradZone; + thisFC.QconvZone = TotalZoneHeatGain * (1 - thisFC.FCPM.RadiativeFract); + thisFC.Report.SkinLossConvect = thisFC.QconvZone; + thisFC.QradZone = TotalZoneHeatGain * thisFC.FCPM.RadiativeFract; + thisFC.Report.SkinLossRadiat = thisFC.QradZone; } // over number of Fuel cells - - // IF(DoingSizing)THEN - - // ENDIF } - void UpdateExhaustAirFlows(int const EP_UNUSED(Num)) // generator number - { - - // SUBROUTINE INFORMATION: - // AUTHOR - // DATE WRITTEN - // MODIFIED na - // RE-ENGINEERED na - - // PURPOSE OF THIS SUBROUTINE: - // - - // METHODOLOGY EMPLOYED: - // - - // REFERENCES: - // na - - // USE STATEMENTS: - // na - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - // na - } - - void CalcUpdateHeatRecovery(int const Num, // Generator number - bool const EP_UNUSED(FirstHVACIteration)) + void FCDataStruct::CalcUpdateHeatRecovery(bool const EP_UNUSED(FirstHVACIteration)) { // SUBROUTINE INFORMATION: @@ -4428,224 +3394,104 @@ namespace FuelCellElectricGenerator { // PURPOSE OF THIS SUBROUTINE: // update plant loop interactions, do any calcs needed - // METHODOLOGY EMPLOYED: - // - - // REFERENCES: - // na - - // Using/Aliasing - using PlantUtilities::SafeCopyPlantNode; - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na + // now update water outlet node Changing to Kg/s! - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int InNodeNum; - int OutNodeNum; + PlantUtilities::SafeCopyPlantNode(this->ExhaustHX.WaterInNode, this->ExhaustHX.WaterOutNode); - // now update water outlet node Changing to Kg/s! - OutNodeNum = FuelCell(Num).ExhaustHX.WaterOutNode; - InNodeNum = FuelCell(Num).ExhaustHX.WaterInNode; - - SafeCopyPlantNode(InNodeNum, OutNodeNum); - - Node(OutNodeNum).Temp = FuelCell(Num).ExhaustHX.WaterOutletTemp; - Node(OutNodeNum).Enthalpy = FuelCell(Num).ExhaustHX.WaterOutletEnthalpy; - - // IF (FirstHVACIteration) Then - // Node(InNodeNum)%MassFlowRateMaxAvail = FuelCell(Num)%ExhaustHX%WaterMassFlowRateDesign - // Node(InNodeNum)%MassFlowRateMinAvail = 0.0D0 - // Node(InNodeNum)%MassFlowRate = MAX(FuelCell(Num)%ExhaustHX%WaterMassFlowRateDesign, & - // Node(InNodeNum)%MassFlowRateMin) - // Node(InNodeNum)%MassFlowRate = MIN(FuelCell(Num)%ExhaustHX%WaterMassFlowRateDesign, & - // Node(InNodeNum)%MassFlowRateMax) - // ELSE - // Node(InNodeNum)%MassFlowRate = MAX(FuelCell(Num)%ExhaustHX%WaterMassFlowRateDesign, & - // Node(InNodeNum)%MassFlowRateMin) - // Node(InNodeNum)%MassFlowRate = MAX(FuelCell(Num)%ExhaustHX%WaterMassFlowRateDesign, & - // Node(InNodeNum)%MassFlowRateMinAvail) - // Node(InNodeNum)%MassFlowRate = MIN(FuelCell(Num)%ExhaustHX%WaterMassFlowRateDesign, & - // Node(InNodeNum)%MassFlowRateMax) - // Node(InNodeNum)%MassFlowRate = MIN(FuelCell(Num)%ExhaustHX%WaterMassFlowRateDesign, & - // Node(InNodeNum)%MassFlowRateMaxAvail) - // ENDIF - // Node(OutNodeNum)%MassFlowRate = Node(InNodeNum)%MassFlowRate - // Node(OutNodeNum)%MassFlowRateMaxAvail = Node(InNodeNum)%MassFlowRateMaxAvail - // Node(OutNodeNum)%MassFlowRateMinAvail = Node(InNodeNum)%MassFlowRateMinAvail - // Node(OutNodeNum)%MassFlowRateMax = Node(InNodeNum)%MassFlowRateMax - // Node(OutNodeNum)%MassFlowRateMin = Node(InNodeNum)%MassFlowRateMin + DataLoopNode::Node(this->ExhaustHX.WaterOutNode).Temp = this->ExhaustHX.WaterOutletTemp; + DataLoopNode::Node(this->ExhaustHX.WaterOutNode).Enthalpy = this->ExhaustHX.WaterOutletEnthalpy; } - void UpdateFuelCellGeneratorRecords(bool const EP_UNUSED(RunFlag), // TRUE if Generator operating - int const Num // Generator number - ) + void FCDataStruct::UpdateFuelCellGeneratorRecords() { - // SUBROUTINE INFORMATION: - // AUTHOR: BG - // DATE WRITTEN: - - // PURPOSE OF THIS SUBROUTINE: - // reporting - - // METHODOLOGY EMPLOYED: na - - // REFERENCES: na - - // USE STATEMENTS: na - // Using/Aliasing - using DataHVACGlobals::TimeStepSys; - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // DERIVED TYPE DEFINITIONS - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - - FuelCell(Num).Report.ACPowerGen = FuelCell(Num).ACPowerGen; // electrical power produced [W] - FuelCell(Num).Report.ACEnergyGen = FuelCell(Num).ACPowerGen * TimeStepSys * SecInHour; // energy produced (J) - FuelCell(Num).Report.QdotExhaust = 0.0; // reporting: exhaust gas heat recovered (W) - FuelCell(Num).Report.TotalHeatEnergyRec = 0.0; // reporting: total heat recovered (J) - FuelCell(Num).Report.ExhaustEnergyRec = 0.0; // reporting: exhaust gas heat recovered (J) - FuelCell(Num).Report.HeatRecInletTemp = 0.0; // reporting: Heat Recovery Loop Inlet Temperature (C) - FuelCell(Num).Report.HeatRecOutletTemp = 0.0; // reporting: Heat Recovery Loop Outlet Temperature (C) - FuelCell(Num).Report.HeatRecMdot = 0.0; // reporting: Heat Recovery Loop Mass flow rate (kg/s) - - FuelCell(Num).Report.ElectEfficiency = 0.0; - FuelCell(Num).Report.ThermalEfficiency = 0.0; - FuelCell(Num).Report.OverallEfficiency = 0.0; - FuelCell(Num).Report.ExergyEfficiency = 0.0; - - FuelCell(Num).Report.TairInlet = FuelCell(Num).AirSup.TairIntoBlower; // State point 1 - FuelCell(Num).Report.TairIntoFCPM = FuelCell(Num).AirSup.TairIntoFCPM; // State point 4 - FuelCell(Num).Report.NdotAir = FuelCell(Num).FCPM.NdotAir; // air flow in kmol/sec - FuelCell(Num).Report.TotAirInEnthalphy = FuelCell(Num).FCPM.TotAirInEnthalphy; // State point 4 - FuelCell(Num).Report.BlowerPower = FuelCell(Num).AirSup.PairCompEl; // electrical power used by air supply blower - FuelCell(Num).Report.BlowerEnergy = FuelCell(Num).AirSup.PairCompEl * TimeStepSys * SecInHour; // electrical energy - FuelCell(Num).Report.BlowerSkinLoss = FuelCell(Num).AirSup.QskinLoss; // heat rate of losses by blower - - FuelCell(Num).Report.TfuelInlet = FuelSupply(FuelCell(Num).FuelSupNum).TfuelIntoCompress; // State point 2 - FuelCell(Num).Report.TfuelIntoFCPM = FuelSupply(FuelCell(Num).FuelSupNum).TfuelIntoFCPM; // TEmperature state point 5 [C] - FuelCell(Num).Report.NdotFuel = FuelCell(Num).FCPM.NdotFuel; // fuel flow in kmol/sec - FuelCell(Num).Report.TotFuelInEnthalpy = FuelCell(Num).FCPM.TotFuelInEnthalphy; // enthalpy at state point 5 [W] - FuelCell(Num).Report.FuelCompressPower = FuelSupply(FuelCell(Num).FuelSupNum).PfuelCompEl; + this->Report.ACPowerGen = this->ACPowerGen; // electrical power produced [W] + this->Report.ACEnergyGen = this->ACPowerGen * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; // energy produced (J) + this->Report.QdotExhaust = 0.0; // reporting: exhaust gas heat recovered (W) + this->Report.TotalHeatEnergyRec = 0.0; // reporting: total heat recovered (J) + this->Report.ExhaustEnergyRec = 0.0; // reporting: exhaust gas heat recovered (J) + + this->Report.HeatRecInletTemp = 0.0; // reporting: Heat Recovery Loop Inlet Temperature (C) + this->Report.HeatRecOutletTemp = 0.0; // reporting: Heat Recovery Loop Outlet Temperature (C) + this->Report.HeatRecMdot = 0.0; // reporting: Heat Recovery Loop Mass flow rate (kg/s) + + this->Report.ElectEfficiency = 0.0; + this->Report.ThermalEfficiency = 0.0; + this->Report.OverallEfficiency = 0.0; + this->Report.ExergyEfficiency = 0.0; + + this->Report.TairInlet = this->AirSup.TairIntoBlower; // State point 1 + this->Report.TairIntoFCPM = this->AirSup.TairIntoFCPM; // State point 4 + this->Report.NdotAir = this->FCPM.NdotAir; // air flow in kmol/sec + this->Report.TotAirInEnthalphy = this->FCPM.TotAirInEnthalphy; // State point 4 + this->Report.BlowerPower = this->AirSup.PairCompEl; // electrical power used by air supply blower + this->Report.BlowerEnergy = this->AirSup.PairCompEl * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; // electrical energy + this->Report.BlowerSkinLoss = this->AirSup.QskinLoss; // heat rate of losses by blower + + this->Report.TfuelInlet = DataGenerators::FuelSupply(this->FuelSupNum).TfuelIntoCompress; // State point 2 + this->Report.TfuelIntoFCPM = DataGenerators::FuelSupply(this->FuelSupNum).TfuelIntoFCPM; // TEmperature state point 5 [C] + this->Report.NdotFuel = this->FCPM.NdotFuel; // fuel flow in kmol/sec + this->Report.TotFuelInEnthalpy = this->FCPM.TotFuelInEnthalphy; // enthalpy at state point 5 [W] + this->Report.FuelCompressPower = DataGenerators::FuelSupply(this->FuelSupNum).PfuelCompEl; // electrical power used by fuel supply compressor [W] - FuelCell(Num).Report.FuelCompressEnergy = FuelSupply(FuelCell(Num).FuelSupNum).PfuelCompEl * TimeStepSys * SecInHour; // elect energy - FuelCell(Num).Report.FuelCompressSkinLoss = FuelSupply(FuelCell(Num).FuelSupNum).QskinLoss; + this->Report.FuelCompressEnergy = + DataGenerators::FuelSupply(this->FuelSupNum).PfuelCompEl * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; // elect energy + this->Report.FuelCompressSkinLoss = DataGenerators::FuelSupply(this->FuelSupNum).QskinLoss; // heat rate of losses.by fuel supply compressor [W] - FuelCell(Num).Report.FuelEnergyLHV = FuelCell(Num).FCPM.NdotFuel * FuelSupply(FuelCell(Num).FuelSupNum).LHV * 1000000.0 * TimeStepSys * - SecInHour; // reporting: Fuel Energy used (J) - FuelCell(Num).Report.FuelEnergyUseRateLHV = - FuelCell(Num).FCPM.NdotFuel * FuelSupply(FuelCell(Num).FuelSupNum).LHV * 1000000.0; // reporting: Fuel Energy used (W) - FuelCell(Num).Report.FuelEnergyHHV = FuelCell(Num).FCPM.NdotFuel * FuelSupply(FuelCell(Num).FuelSupNum).HHV * - FuelSupply(FuelCell(Num).FuelSupNum).KmolPerSecToKgPerSec * TimeStepSys * SecInHour; - - FuelCell(Num).Report.FuelEnergyUseRateHHV = - FuelCell(Num).FCPM.NdotFuel * FuelSupply(FuelCell(Num).FuelSupNum).HHV * FuelSupply(FuelCell(Num).FuelSupNum).KmolPerSecToKgPerSec; - - FuelCell(Num).Report.FuelRateMdot = 0.0; // (Kg/s) - - FuelCell(Num).Report.TwaterInlet = FuelCell(Num).WaterSup.TwaterIntoCompress; - FuelCell(Num).Report.TwaterIntoFCPM = FuelCell(Num).WaterSup.TwaterIntoFCPM; - FuelCell(Num).Report.NdotWater = FuelCell(Num).FCPM.NdotLiqwater; // water flow in kmol/sec (reformer water) - FuelCell(Num).Report.WaterPumpPower = FuelCell(Num).WaterSup.PwaterCompEl; - FuelCell(Num).Report.WaterPumpEnergy = FuelCell(Num).WaterSup.PwaterCompEl * TimeStepSys * SecInHour; // electrical energy - FuelCell(Num).Report.WaterIntoFCPMEnthalpy = FuelCell(Num).FCPM.WaterInEnthalpy; - - FuelCell(Num).Report.TprodGas = FuelCell(Num).FCPM.TprodGasLeavingFCPM; // temperature at State point 7 - FuelCell(Num).Report.EnthalProdGas = FuelCell(Num).FCPM.TotProdGasEnthalphy; // enthalpy at State point 7 - FuelCell(Num).Report.NdotProdGas = FuelCell(Num).FCPM.NdotProdGas; // flow rate at point 7 [kmol/sec] - FuelCell(Num).Report.NdotProdAr = FuelCell(Num).FCPM.ConstitMolalFract(5) * FuelCell(Num).FCPM.NdotProdGas; - FuelCell(Num).Report.NdotProdCO2 = FuelCell(Num).FCPM.ConstitMolalFract(1) * FuelCell(Num).FCPM.NdotProdGas; - FuelCell(Num).Report.NdotProdH2O = FuelCell(Num).FCPM.ConstitMolalFract(4) * FuelCell(Num).FCPM.NdotProdGas; - FuelCell(Num).Report.NdotProdN2 = FuelCell(Num).FCPM.ConstitMolalFract(2) * FuelCell(Num).FCPM.NdotProdGas; - FuelCell(Num).Report.NdotProdO2 = FuelCell(Num).FCPM.ConstitMolalFract(3) * FuelCell(Num).FCPM.NdotProdGas; - - FuelCell(Num).Report.qHX = FuelCell(Num).ExhaustHX.qHX; - FuelCell(Num).Report.HXenergy = FuelCell(Num).ExhaustHX.qHX * TimeStepSys * SecInHour; - FuelCell(Num).Report.THXexh = FuelCell(Num).ExhaustHX.THXexh; - FuelCell(Num).Report.WaterVaporFractExh = FuelCell(Num).ExhaustHX.WaterVaporFractExh; - FuelCell(Num).Report.CondensateRate = FuelCell(Num).ExhaustHX.CondensateRate; - - FuelCell(Num).Report.SeqSubstIterations = FuelCell(Num).FCPM.SeqSubstitIter; // number of iterations in FuelCell loop - FuelCell(Num).Report.RegulaFalsiIterations = FuelCell(Num).FCPM.RegulaFalsiIter; // number of iterations in Tproduct gas solving - - FuelCell(Num).Report.ACancillariesPower = FuelCell(Num).FCPM.PelancillariesAC; - FuelCell(Num).Report.ACancillariesEnergy = FuelCell(Num).FCPM.PelancillariesAC * TimeStepSys * SecInHour; - - FuelCell(Num).Report.PCUlosses = FuelCell(Num).Inverter.PCUlosses; // inverter losses - FuelCell(Num).Report.DCPowerGen = FuelCell(Num).FCPM.Pel; // DC power out of FCPM. - FuelCell(Num).Report.DCPowerEff = FuelCell(Num).FCPM.Eel; // FCPM efficienty Eel. - FuelCell(Num).Report.ElectEnergyinStorage = FuelCell(Num).ElecStorage.ThisTimeStepStateOfCharge; - FuelCell(Num).Report.StoredPower = FuelCell(Num).ElecStorage.PelIntoStorage; - FuelCell(Num).Report.StoredEnergy = FuelCell(Num).ElecStorage.PelIntoStorage * TimeStepSys * SecInHour; - FuelCell(Num).Report.DrawnPower = FuelCell(Num).ElecStorage.PelFromStorage; - FuelCell(Num).Report.DrawnEnergy = FuelCell(Num).ElecStorage.PelFromStorage * TimeStepSys * SecInHour; - - FuelCell(Num).Report.SkinLossPower = FuelCell(Num).QconvZone + FuelCell(Num).QradZone; - FuelCell(Num).Report.SkinLossEnergy = (FuelCell(Num).QconvZone + FuelCell(Num).QradZone) * TimeStepSys * SecInHour; - FuelCell(Num).Report.SkinLossConvect = FuelCell(Num).QconvZone; - FuelCell(Num).Report.SkinLossRadiat = FuelCell(Num).QradZone; - } - - void GetFuelCellGeneratorResults(int const EP_UNUSED(GeneratorType), // type of Generator - int const GeneratorIndex, - Real64 &GeneratorPower, // electrical power - Real64 &GeneratorEnergy, // electrical energy - Real64 &ThermalPower, // heat power - Real64 &ThermalEnergy // heat energy - ) - { - - // SUBROUTINE INFORMATION: - // AUTHOR B. Griffith - // DATE WRITTEN March 2008 - // MODIFIED na - // RE-ENGINEERED na - - // PURPOSE OF THIS SUBROUTINE: - // provide a get method to collect results at the load center level - - // METHODOLOGY EMPLOYED: - // - - // REFERENCES: - // na - - // USE STATEMENTS: - // na - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - GeneratorPower = FuelCell(GeneratorIndex).Report.ACPowerGen; - GeneratorEnergy = FuelCell(GeneratorIndex).Report.ACEnergyGen; - ThermalPower = FuelCell(GeneratorIndex).Report.qHX; - ThermalEnergy = FuelCell(GeneratorIndex).Report.HXenergy; + this->Report.FuelEnergyLHV = this->FCPM.NdotFuel * DataGenerators::FuelSupply(this->FuelSupNum).LHV * 1000000.0 * + DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; // reporting: Fuel Energy used (J) + this->Report.FuelEnergyUseRateLHV = + this->FCPM.NdotFuel * DataGenerators::FuelSupply(this->FuelSupNum).LHV * 1000000.0; // reporting: Fuel Energy used (W) + this->Report.FuelEnergyHHV = this->FCPM.NdotFuel * DataGenerators::FuelSupply(this->FuelSupNum).HHV * + DataGenerators::FuelSupply(this->FuelSupNum).KmolPerSecToKgPerSec * DataHVACGlobals::TimeStepSys * + DataGlobals::SecInHour; + + this->Report.FuelEnergyUseRateHHV = this->FCPM.NdotFuel * DataGenerators::FuelSupply(this->FuelSupNum).HHV * + DataGenerators::FuelSupply(this->FuelSupNum).KmolPerSecToKgPerSec; + + this->Report.FuelRateMdot = 0.0; // (Kg/s) + + this->Report.TwaterInlet = this->WaterSup.TwaterIntoCompress; + this->Report.TwaterIntoFCPM = this->WaterSup.TwaterIntoFCPM; + this->Report.NdotWater = this->FCPM.NdotLiqwater; // water flow in kmol/sec (reformer water) + this->Report.WaterPumpPower = this->WaterSup.PwaterCompEl; + this->Report.WaterPumpEnergy = this->WaterSup.PwaterCompEl * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; // electrical energy + this->Report.WaterIntoFCPMEnthalpy = this->FCPM.WaterInEnthalpy; + + this->Report.TprodGas = this->FCPM.TprodGasLeavingFCPM; // temperature at State point 7 + this->Report.EnthalProdGas = this->FCPM.TotProdGasEnthalphy; // enthalpy at State point 7 + this->Report.NdotProdGas = this->FCPM.NdotProdGas; // flow rate at point 7 [kmol/sec] + this->Report.NdotProdAr = this->FCPM.ConstitMolalFract(5) * this->FCPM.NdotProdGas; + this->Report.NdotProdCO2 = this->FCPM.ConstitMolalFract(1) * this->FCPM.NdotProdGas; + this->Report.NdotProdH2O = this->FCPM.ConstitMolalFract(4) * this->FCPM.NdotProdGas; + this->Report.NdotProdN2 = this->FCPM.ConstitMolalFract(2) * this->FCPM.NdotProdGas; + this->Report.NdotProdO2 = this->FCPM.ConstitMolalFract(3) * this->FCPM.NdotProdGas; + + this->Report.qHX = this->ExhaustHX.qHX; + this->Report.HXenergy = this->ExhaustHX.qHX * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; + this->Report.THXexh = this->ExhaustHX.THXexh; + this->Report.WaterVaporFractExh = this->ExhaustHX.WaterVaporFractExh; + this->Report.CondensateRate = this->ExhaustHX.CondensateRate; + + this->Report.SeqSubstIterations = this->FCPM.SeqSubstitIter; // number of iterations in FuelCell loop + this->Report.RegulaFalsiIterations = this->FCPM.RegulaFalsiIter; // number of iterations in Tproduct gas solving + + this->Report.ACancillariesPower = this->FCPM.PelancillariesAC; + this->Report.ACancillariesEnergy = this->FCPM.PelancillariesAC * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; + + this->Report.PCUlosses = this->Inverter.PCUlosses; // inverter losses + this->Report.DCPowerGen = this->FCPM.Pel; // DC power out of FCPM. + this->Report.DCPowerEff = this->FCPM.Eel; // FCPM efficiency Eel. + this->Report.ElectEnergyinStorage = this->ElecStorage.ThisTimeStepStateOfCharge; + this->Report.StoredPower = this->ElecStorage.PelIntoStorage; + this->Report.StoredEnergy = this->ElecStorage.PelIntoStorage * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; + this->Report.DrawnPower = this->ElecStorage.PelFromStorage; + this->Report.DrawnEnergy = this->ElecStorage.PelFromStorage * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; + + this->Report.SkinLossPower = this->QconvZone + this->QradZone; + this->Report.SkinLossEnergy = (this->QconvZone + this->QradZone) * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; + this->Report.SkinLossConvect = this->QconvZone; + this->Report.SkinLossRadiat = this->QradZone; } } // namespace FuelCellElectricGenerator diff --git a/src/EnergyPlus/FuelCellElectricGenerator.hh b/src/EnergyPlus/FuelCellElectricGenerator.hh index 7ff13b5ccc1..c17711e5073 100644 --- a/src/EnergyPlus/FuelCellElectricGenerator.hh +++ b/src/EnergyPlus/FuelCellElectricGenerator.hh @@ -53,179 +53,566 @@ // EnergyPlus Headers #include +#include namespace EnergyPlus { namespace FuelCellElectricGenerator { - // Data - // MODULE PARAMETER DEFINITIONS + struct FCPowerModuleStruct + { + std::string Name; // name of this PowerModule data + int EffMode; // mode for efficiency curves + int EffCurveID; // pointer to curve for efficiency + Real64 NomEff; // nominal efficiency + Real64 NomPel; // nominal power rate at rating point + int NumCycles; // number of start stop cycles + Real64 CyclingDegradRat; // rate of degradation from cycles + Real64 NumRunHours; // number of hours of operation + Real64 OperateDegradRat; // rate of degradation from run time (per hour) + Real64 ThreshRunHours; // number of hours before degradation starts + Real64 UpTranLimit; // power up transient limit + Real64 DownTranLimit; // power down tran limit + Real64 StartUpTime; // time for start up [hours] + Real64 StartUpFuel; // fuel use during start up + Real64 StartUpElectConsum; // electricity used during start up + Real64 StartUpElectProd; // electricity produced during start up + Real64 ShutDownTime; // time to shut down [hours] + Real64 ShutDownFuel; // fuel consumed during shut down + Real64 ShutDownElectConsum; // Elect consumed during shut down + Real64 ANC0; // Ancilliary Loads constant term + Real64 ANC1; // Ancilliary Loads linear term + int SkinLossMode; // how are skin losses determined + std::string ZoneName; + int ZoneID; // "pointer" to zone with component in it + Real64 RadiativeFract; + Real64 QdotSkin; + Real64 UAskin; + int SkinLossCurveID; + int WaterSupplyCurveID; // pointer to curve for water use in reforming + Real64 NdotDilutionAir; // user defined constant flow of dilution air (kmol/sec) + Real64 StackHeatLossToDilution; // (watts) + std::string DilutionInletNodeName; // dilution -> AirHR ?? added air heat recovery path + int DilutionInletNode; // pointer to node for inlet + std::string DilutionExhaustNodeName; + int DilutionExhaustNode; // pointer to node getting exhaust + Real64 PelMin; // minimum operating point for FCPM electrical power Pel + Real64 PelMax; // maximum operating point for FCPM electrical power Pel + // Calculated values and input from elsewhere + Real64 Pel; // current DC electrical power produced + Real64 PelLastTimeStep; + Real64 Eel; // power module efficiency + Real64 QdotStackCool; // Heat removed by stack cooler + Real64 FractionalDayofLastStartUp; // fractional days into simulation + Real64 FractionalDayofLastShutDown; // fractional Days into simulations + bool HasBeenOn; + bool DuringShutDown; + bool DuringStartUp; + Real64 NdotFuel; // molar fuel use rate. (kmol/sec) + Real64 TotFuelInEnthalphy; // Enthalpy of fuel coming into FCPM (watts) + Real64 NdotProdGas; // (kmol/sec) + Array1D ConstitMolalFract; + Array1D_int GasLibID; // lookup ID in Gas Phase ThermoChemistry Structure Array + Real64 TprodGasLeavingFCPM; + Real64 NdotAir; // molar air use rate (kmol/sec) + Real64 TotAirInEnthalphy; // Enthalpy of air coming nto FCPM energy balance (watts) + Real64 NdotLiqwater; // molar water use rate (kmol/sec) + Real64 TwaterInlet; + Real64 WaterInEnthalpy; // Enthalpy of liquid water used for reforming (watts) + Real64 DilutionAirInEnthalpy; // Enthalpy of Dilution air coming into FCPM (watts) + Real64 DilutionAirOutEnthalpy; + Real64 PelancillariesAC; // ancillary power (watts) + Real64 TotProdGasEnthalphy; // Enthalphy of product gases leaving FCPM (watts) + Real64 WaterOutEnthalpy; // enthalpy of vapor from water used for reforming + int SeqSubstitIter; + int RegulaFalsiIter; + + // Default Constructor + FCPowerModuleStruct() + : EffMode(0), EffCurveID(0), NomEff(0.0), NomPel(0.0), NumCycles(0), CyclingDegradRat(0.0), NumRunHours(0.0), OperateDegradRat(0.0), + ThreshRunHours(0.0), UpTranLimit(0.0), DownTranLimit(0.0), StartUpTime(0.0), StartUpFuel(0.0), StartUpElectConsum(0.0), + StartUpElectProd(0.0), ShutDownTime(0.0), ShutDownFuel(0.0), ShutDownElectConsum(0.0), ANC0(0.0), ANC1(0.0), SkinLossMode(0), ZoneID(0), + RadiativeFract(0.0), QdotSkin(0.0), UAskin(0.0), SkinLossCurveID(0), WaterSupplyCurveID(0), NdotDilutionAir(0.0), + StackHeatLossToDilution(0.0), DilutionInletNode(0), DilutionExhaustNode(0), PelMin(0.0), PelMax(0.0), Pel(0.0), PelLastTimeStep(0.0), + Eel(0.0), QdotStackCool(0.0), FractionalDayofLastStartUp(0.0), FractionalDayofLastShutDown(0.0), HasBeenOn(true), DuringShutDown(false), + DuringStartUp(false), NdotFuel(0.0), TotFuelInEnthalphy(0.0), NdotProdGas(0.0), ConstitMolalFract(14, 0.0), GasLibID(14, 0), + TprodGasLeavingFCPM(0.0), NdotAir(0.0), TotAirInEnthalphy(0.0), NdotLiqwater(0.0), TwaterInlet(0.0), WaterInEnthalpy(0.0), + DilutionAirInEnthalpy(0.0), DilutionAirOutEnthalpy(0.0), PelancillariesAC(0.0), TotProdGasEnthalphy(0.0), WaterOutEnthalpy(0.0), + SeqSubstitIter(0), RegulaFalsiIter(0) + { + } + }; + + struct FCAirSupplyDataStruct + { + std::string Name; // name of this + std::string NodeName; // Air supply node name + int SupNodeNum; // Air supply node ID + int BlowerPowerCurveID; // "pointer" to blower power quadratic + Real64 BlowerHeatLossFactor; // alpha for blower heat loss fraction + int AirSupRateMode; // control for modeling method used to deterime supply air flow rate + Real64 Stoics; // excess air ratio + int AirFuncPelCurveID; // "pointer" to curve for air as function of power + Real64 AirTempCoeff; // coeff a3 in equ 16. + int AirFuncNdotCurveID; // "pointer" to curve for air as function of fuel flow rate + int IntakeRecoveryMode; + int ConstituentMode; // how are air data input + int NumConstituents; + Array1D_string ConstitName; + Array1D ConstitMolalFract; + // Calculated values and input from elsewhere + Array1D_int GasLibID; // lookup ID in Gas Phase ThermoChemistry Structure Array + Real64 O2fraction; + Real64 TairIntoBlower; // temperature entering blower + Real64 TairIntoFCPM; // temperature leaving blower and entering FCPM + Real64 PairCompEl; // power drawn by compressor + Real64 QskinLoss; // pumping losses for zone + Real64 QintakeRecovery; // heat recovered on intake air by accessories + + // Default Constructor + FCAirSupplyDataStruct() + : SupNodeNum(0), BlowerPowerCurveID(0), BlowerHeatLossFactor(0.0), AirSupRateMode(0), Stoics(0.0), AirFuncPelCurveID(0), + AirTempCoeff(0.0), AirFuncNdotCurveID(0), IntakeRecoveryMode(0), ConstituentMode(0), NumConstituents(0), ConstitName(14), + ConstitMolalFract(14, 0.0), GasLibID(14, 0), O2fraction(0.0), TairIntoBlower(0.0), TairIntoFCPM(0.0), PairCompEl(0.0), QskinLoss(0.0), + QintakeRecovery(0.0) + { + } + }; + + struct FCWaterSupplyDataStruct + { + std::string Name; // name of this water supply module + int WaterTempMode; // temperature of water inlet determination + std::string NodeName; // node name for temperature at input + int NodeNum; // node number for temperature at input + int SchedNum; // water temperature at input + int WaterSupRateCurveID; // "pointer" to water flow rate curve as a function of fuel rate + int PmpPowerCurveID; // "pointer to Pump power curve as a function of water flow Rate + Real64 PmpPowerLossFactor; // Pump heat loss factor + // calculated data + bool IsModeled; + Real64 TwaterIntoCompress; // inlet Water Temperature + Real64 TwaterIntoFCPM; // pumped water temp + Real64 PwaterCompEl; // water pump power + Real64 QskinLoss; // pumping losses for zone + + // Default Constructor + FCWaterSupplyDataStruct() + : WaterTempMode(0), NodeNum(0), SchedNum(0), WaterSupRateCurveID(0), PmpPowerCurveID(0), PmpPowerLossFactor(0.0), IsModeled(true), + TwaterIntoCompress(0.0), TwaterIntoFCPM(0.0), PwaterCompEl(0.0), QskinLoss(0.0) + { + } + }; + + struct FCAuxilHeatDataStruct + { + std::string Name; // name of this auxiliary heating module + std::string ZoneName; + int ZoneID; + Real64 UASkin; // for skin losses to zone + Real64 ExcessAirRAT; + Real64 ANC0; + Real64 ANC1; + int SkinLossDestination; // control mode for where lost heat goes + Real64 MaxPowerW; + Real64 MinPowerW; + Real64 MaxPowerkmolperSec; + Real64 MinPowerkmolperSec; + // calculated and from elsewhere + int NumConstituents; + Real64 TauxMix; + Real64 NdotAuxMix; + Array1D ConstitMolalFract; + Array1D_int GasLibID; // lookup ID in Gas Phase ThermoChemistry Structure Array + Real64 QskinLoss; // Heat lost to room + Real64 QairIntake; // heat into intake air + + // Default Constructor + FCAuxilHeatDataStruct() + : ZoneID(0), UASkin(0.0), ExcessAirRAT(0.0), ANC0(0.0), ANC1(0.0), SkinLossDestination(0), MaxPowerW(0.0), MinPowerW(0.0), + MaxPowerkmolperSec(0.0), MinPowerkmolperSec(0.0), NumConstituents(0), TauxMix(0.0), NdotAuxMix(0.0), ConstitMolalFract(14, 0.0), + GasLibID(14, 0), QskinLoss(0.0), QairIntake(0.0) + { + } + }; + + struct FCExhaustHXDataStruct + { + std::string Name; // name of this exhaust gas heat recovery + std::string WaterInNodeName; // HR Water Inlet Node + int WaterInNode; // HR Water Outlet Node ID + std::string WaterOutNodeName; // HR water outlet Node name + int WaterOutNode; // HR Water outlet Node ID + Real64 WaterVolumeFlowMax; // HR water flow rate max avail + std::string ExhaustOutNodeName; // air node for exhaust flow + int ExhaustOutNode; // Exhaust Air node ID + int HXmodelMode; // Heat Exchanger Calculation Method + Real64 HXEffect; // Heat Exchanger Effectiveness (method 1) + Real64 hxs0; // (method 2) + Real64 hxs1; // (method 2) + Real64 hxs2; // (method 2) + Real64 hxs3; // (method 2) + Real64 hxs4; // (method 2) + Real64 h0gas; // (method 3) + Real64 NdotGasRef; // (method 3) + Real64 nCoeff; // (method 3) + Real64 AreaGas; // (method 3) + Real64 h0Water; // (method 3) + Real64 NdotWaterRef; // (method 3) + Real64 mCoeff; // (method 3) + Real64 AreaWater; // (method 3) + Real64 Fadjust; // (method 3) + Real64 l1Coeff; // (method 4) + Real64 l2Coeff; // (method 4) + Real64 CondensationThresholdTemp; // (method 4) [degrees C] + // calculated + Real64 qHX; // heat flow from gas stream to water + Real64 THXexh; // temperature of exhaust gases leaving heat exchanger. + Real64 WaterMassFlowRateDesign; // Design level of water flow rate + Real64 WaterMassFlowRate; // water flow rate in plant loop + Real64 WaterInletTemp; + Real64 WaterVaporFractExh; // water vapor fraction in exhaust gas stream. + Real64 CondensateRate; // water condensation rate. + Array1D ConstitMolalFract; + Array1D_int GasLibID; // lookup ID in Gas Phase ThermoChemistry Structure Array + Real64 NdotHXleaving; + Real64 WaterOutletTemp; + Real64 WaterOutletEnthalpy; + + // Default Constructor + FCExhaustHXDataStruct() + : WaterInNode(0), WaterOutNode(0), WaterVolumeFlowMax(0.0), ExhaustOutNode(0), HXmodelMode(0), HXEffect(0.0), hxs0(0.0), hxs1(0.0), + hxs2(0.0), hxs3(0.0), hxs4(0.0), h0gas(0.0), NdotGasRef(0.0), nCoeff(0.0), AreaGas(0.0), h0Water(0.0), NdotWaterRef(0.0), mCoeff(0.0), + AreaWater(0.0), Fadjust(0.0), l1Coeff(0.0), l2Coeff(0.0), CondensationThresholdTemp(0.0), qHX(0.0), THXexh(0.0), + WaterMassFlowRateDesign(0.0), WaterMassFlowRate(0.0), WaterInletTemp(0.0), WaterVaporFractExh(0.0), CondensateRate(0.0), + ConstitMolalFract(14, 0.0), GasLibID(14, 0), NdotHXleaving(0.0), WaterOutletTemp(0.0), WaterOutletEnthalpy(0.0) + { + } + }; + + struct BatteryDichargeDataStruct + { + std::string Name; // name of this battery data set + Real64 NumInSeries; + Real64 NumInParallel; + Real64 NominalVoltage; + Real64 LowVoltsDischarged; // not used + int NumTablePairs; + Array1D DischargeCurrent; // amps + Array1D DischargeTime; // hours + // calculated variables + Real64 k; // parameter in Manwell McGowan model + Real64 c; // parameter in Manwell McGowan model + Real64 qmax; // parameter in Manwell McGowan model + + // Default Constructor + BatteryDichargeDataStruct() + : NumInSeries(0.0), NumInParallel(0.0), NominalVoltage(0.0), LowVoltsDischarged(0.0), NumTablePairs(0), k(0.0), c(0.0), qmax(0.0) + { + } + }; + + struct FCElecStorageDataStruct + { + std::string Name; // name of this electrical storage module + int StorageModelMode; + Real64 StartingEnergyStored; // joules inside + Real64 EnergeticEfficCharge; // for + Real64 EnergeticEfficDischarge; + Real64 MaxPowerDraw; // for simple bucket method 0 + Real64 MaxPowerStore; // for simple bucket method 0 + Real64 NominalVoltage; + Real64 NominalEnergyCapacity; // [J] + // calculated and from elsewhere vars + Real64 ThisTimeStepStateOfCharge; // [J] + Real64 LastTimeStepStateOfCharge; // [J] + Real64 PelNeedFromStorage; + Real64 IdesiredDischargeCurrent; + Real64 PelFromStorage; // power + Real64 IfromStorage; // current this timestepm + Real64 PelIntoStorage; + Real64 QairIntake; // heat into intake air + // nested structures + BatteryDichargeDataStruct Battery; + + // Default Constructor + FCElecStorageDataStruct() + : StorageModelMode(0), StartingEnergyStored(0.0), EnergeticEfficCharge(0.0), EnergeticEfficDischarge(0.0), MaxPowerDraw(0.0), + MaxPowerStore(0.0), NominalVoltage(0.0), NominalEnergyCapacity(0.0), ThisTimeStepStateOfCharge(0.0), LastTimeStepStateOfCharge(0.0), + PelNeedFromStorage(0.0), IdesiredDischargeCurrent(0.0), PelFromStorage(0.0), IfromStorage(0.0), PelIntoStorage(0.0), QairIntake(0.0) + { + } + }; + + struct FCInverterDataStruct + { + std::string Name; // name of this inverter + int EffMode; // efficiency calculation mode + Real64 ConstEff; + int EffQuadraticCurveID; + // calculated and from elsewhere + Real64 PCUlosses; + Real64 QairIntake; + + // Default Constructor + FCInverterDataStruct() : EffMode(0), ConstEff(0.0), EffQuadraticCurveID(0), PCUlosses(0.0), QairIntake(0.0) + { + } + }; + + struct FCReportDataStruct + { + // Members + Real64 ACPowerGen; // reporting: power (W) + Real64 ACEnergyGen; // reporting: energy (J) + Real64 QdotExhaust; // reporting: exhaust gas heat recovered (W) + Real64 TotalHeatEnergyRec; // reporting: total heat recovered (J) + Real64 ExhaustEnergyRec; // reporting: exhaust gas heat recovered (J) + Real64 FuelEnergyLHV; // reporting: Fuel Energy used in Lower Heating Value(J) + Real64 FuelEnergyUseRateLHV; // reporting: Fuel Energy used in Lower Heating Value(W) + Real64 FuelEnergyHHV; // reporting: Fuel Energy used in Lower Heating Value(J) + Real64 FuelEnergyUseRateHHV; // reporting: Fuel Energy used in Lower Heating Value(W) + Real64 FuelRateMdot; // (Kg/s) + Real64 HeatRecInletTemp; // reporting: Heat Recovery Loop Inlet Temperature (C) + Real64 HeatRecOutletTemp; // reporting: Heat Recovery Loop Outlet Temperature (C) + Real64 HeatRecMdot; // reporting: Heat Recovery Loop Mass flow rate (kg/s) + // air supply and blower + Real64 TairInlet; // State point 1 + Real64 TairIntoFCPM; // Temperature at State point 4 + Real64 NdotAir; // air flow in kmol/sec + Real64 TotAirInEnthalphy; // Enthalpy at State point 4 + Real64 BlowerPower; // electrical power used by air supply blower + Real64 BlowerEnergy; // electrical energy used by air supply blower + Real64 BlowerSkinLoss; // heat rate of losses by blower + // fuel supply and compressor + Real64 TfuelInlet; // State point 2 [C] + Real64 TfuelIntoFCPM; // state point 5 [C] + Real64 NdotFuel; // fuel flow in [kmol/sec] + Real64 TotFuelInEnthalpy; // state point 5 [W] + Real64 FuelCompressPower; // electrical power used by fuel supply compressor [W] + Real64 FuelCompressEnergy; // electrical energy used by fuel supply compressor [J] + Real64 FuelCompressSkinLoss; // heat rate of losses.by fuel supply compressor [W] + // reformer water supply + Real64 TwaterInlet; // State point 3 + Real64 TwaterIntoFCPM; // State point 6 + Real64 NdotWater; // water flow in kmol/sec (reformer water) + Real64 WaterPumpPower; // electrical power used by water pump [W] + Real64 WaterPumpEnergy; // electrical energy used by water pump [J] + Real64 WaterIntoFCPMEnthalpy; // state point 6 + // product (exhaust) gas leaving power module + Real64 TprodGas; // State point 7 Product Gas temperature + Real64 EnthalProdGas; // state point 7 product gas enthalpy + Real64 NdotProdGas; // point 7 flow rate [kmol/sec] + Real64 NdotProdAr; // argon flow rate at point 7 + Real64 NdotProdCO2; // carbon dioxide flow rate at point 7 + Real64 NdotProdH2O; // water vapor flow rate at point 7 + Real64 NdotProdN2; // nitrogen flow rate at point 7 + Real64 NdotProdO2; // oxygen flow rate at point 7 + // heat exchanger for water to exhaust heat recovery + Real64 qHX; // heat flow from gas stream to water [W] + Real64 HXenergy; // energy from gas stream to water [J] + Real64 THXexh; // temperature of exhaust gases leaving heat exchanger. + Real64 WaterVaporFractExh; // water vapor fraction in exhaust gas stream + // relative to water vapor entering HX (NdotH20/Ndoaux-mix) + Real64 CondensateRate; // water condensation rate [kmol/s] + int SeqSubstIterations; // number of iterations in SOFC loop + int RegulaFalsiIterations; // number of iterations in Tproduct gas solving + Real64 ACancillariesPower; + Real64 ACancillariesEnergy; + Real64 PCUlosses; // power conditioning Unit losses + Real64 DCPowerGen; // Pel, Power module power level [W] + Real64 DCPowerEff; // Eel, power module efficiency [] + Real64 ElectEnergyinStorage; // State of charge in Electrical Storage [J] + Real64 StoredPower; // Power added to Electrical Storage [W] + Real64 StoredEnergy; // energy added to Electrical STorage [J] + Real64 DrawnPower; // Power drawn from Electrical STorage [W] + Real64 DrawnEnergy; // Energy drawn from Electrical STorage [J] + Real64 SkinLossPower; // heat loss to surrounding zone [W] + Real64 SkinLossEnergy; // heat loss to surround zone [J] + Real64 SkinLossConvect; // convective heat loss to zone [W] + Real64 SkinLossRadiat; // radiative heat loss to zone [W} + Real64 ElectEfficiency; + Real64 ThermalEfficiency; + Real64 OverallEfficiency; + Real64 ExergyEfficiency; + + // Default Constructor + FCReportDataStruct() + : ACPowerGen(0.0), ACEnergyGen(0.0), QdotExhaust(0.0), TotalHeatEnergyRec(0.0), ExhaustEnergyRec(0.0), FuelEnergyLHV(0.0), + FuelEnergyUseRateLHV(0.0), FuelEnergyHHV(0.0), FuelEnergyUseRateHHV(0.0), FuelRateMdot(0.0), HeatRecInletTemp(0.0), + HeatRecOutletTemp(0.0), HeatRecMdot(0.0), TairInlet(0.0), TairIntoFCPM(0.0), NdotAir(0.0), TotAirInEnthalphy(0.0), BlowerPower(0.0), + BlowerEnergy(0.0), BlowerSkinLoss(0.0), TfuelInlet(0.0), TfuelIntoFCPM(0.0), NdotFuel(0.0), TotFuelInEnthalpy(0.0), + FuelCompressPower(0.0), FuelCompressEnergy(0.0), FuelCompressSkinLoss(0.0), TwaterInlet(0.0), TwaterIntoFCPM(0.0), NdotWater(0.0), + WaterPumpPower(0.0), WaterPumpEnergy(0.0), WaterIntoFCPMEnthalpy(0.0), TprodGas(0.0), EnthalProdGas(0.0), NdotProdGas(0.0), + NdotProdAr(0.0), NdotProdCO2(0.0), NdotProdH2O(0.0), NdotProdN2(0.0), NdotProdO2(0.0), qHX(0.0), HXenergy(0.0), THXexh(0.0), + WaterVaporFractExh(0.0), CondensateRate(0.0), SeqSubstIterations(0), RegulaFalsiIterations(0), ACancillariesPower(0.0), + ACancillariesEnergy(0.0), PCUlosses(0.0), DCPowerGen(0.0), DCPowerEff(0.0), ElectEnergyinStorage(0.0), StoredPower(0.0), + StoredEnergy(0.0), DrawnPower(0.0), DrawnEnergy(0.0), SkinLossPower(0.0), SkinLossEnergy(0.0), SkinLossConvect(0.0), + SkinLossRadiat(0.0), ElectEfficiency(0.0), ThermalEfficiency(0.0), OverallEfficiency(0.0), ExergyEfficiency(0.0) + { + } + }; + + struct FCStackCoolerDataStruct + { + std::string Name; // name of this stack cooler module + std::string WaterInNodeName; // HR Water Inlet Node + int WaterInNode; // HR Water Outlet Node ID + std::string WaterOutNodeName; // HR water outlet Node name + int WaterOutNode; // HR Water outlet Node ID + Real64 TstackNom; // nominal fuel cell stack temperature + Real64 TstackActual; // actual fuel cell stack temperature + Real64 r0; // stack cooling power coefficient r0 + Real64 r1; // stack cooling power coefficient r1 + Real64 r2; // stack cooling power coefficient r2 + Real64 r3; // stack cooling power coefficient r3 + Real64 MdotStackCoolant; // stack coolant flow rate kg/s + Real64 UAs_cool; // stack heat transfer coef + Real64 Fs_cogen; + Real64 As_cogen; + Real64 MdotCogenNom; + Real64 hCogenNom; + Real64 ns; + Real64 PstackPumpEl; + Real64 PmpPowerLossFactor; + Real64 f0; + Real64 f1; + Real64 f2; + // calculated and from elsewhere + bool StackCoolerPresent; // control modeling + Real64 qs_cool; + Real64 qs_air; + + // Default Constructor + FCStackCoolerDataStruct() + : WaterInNode(0), WaterOutNode(0), TstackNom(0.0), TstackActual(0.0), r0(0.0), r1(0.0), r2(0.0), r3(0.0), MdotStackCoolant(0.0), + UAs_cool(0.0), Fs_cogen(0.0), As_cogen(0.0), MdotCogenNom(0.0), hCogenNom(0.0), ns(0.0), PstackPumpEl(0.0), PmpPowerLossFactor(0.0), + f0(0.0), f1(0.0), f2(0.0), StackCoolerPresent(false), qs_cool(0.0), qs_air(0.0) + { + } + }; + + struct FCDataStruct : PlantComponent + { + // Members + // from input data and nested types for subsystems + int TypeOf; + std::string Name; // user identifier + std::string NameFCPM; // name of FC Power Module + FCPowerModuleStruct FCPM; // data for Power Module + std::string NameFCAirSup; // name of air supply module for fuel cell + FCAirSupplyDataStruct AirSup; // data for air supply module + std::string NameFCFuelSup; // name of fuel supply module + int FuelSupNum; // index for fuel supply module structure + std::string NameFCWaterSup; // name of water supply module + FCWaterSupplyDataStruct WaterSup; // data for water supply module + std::string NameFCAuxilHeat; // name of auxiliary heating module + FCAuxilHeatDataStruct AuxilHeat; // data for auxiliary heating module + std::string NameExhaustHX; // name of Exhaust HX module + FCExhaustHXDataStruct ExhaustHX; // data for Exhaust heat exchanger module + std::string NameElecStorage; // name of Battery module + FCElecStorageDataStruct ElecStorage; // data for Battery module + std::string NameInverter; // name of Inverter Module + FCInverterDataStruct Inverter; // data for Inverter module + std::string NameStackCooler; // name of Inverter Module + FCStackCoolerDataStruct StackCooler; // data for Inverter module + int CWLoopNum; // cooling water plant loop index number + int CWLoopSideNum; // cooling water plant loop side index + int CWBranchNum; // cooling water plant loop branch index + int CWCompNum; // cooling water plant loop component index + FCReportDataStruct Report; // data for reporting as E+ output variables + // calculated whole-system level variables + Real64 ACPowerGen; // Net output from SOFC unit + Real64 QconvZone; // convective heat lost to surrounding zone + Real64 QradZone; // radiative heat lost to surrounding zone + int DynamicsControlID; + Real64 TimeElapsed; // used to track when timestep has changed + bool MyEnvrnFlag_Init; + bool MyWarmupFlag_Init; + bool MyPlantScanFlag_Init; + + // Default Constructor + FCDataStruct() + : TypeOf(0), FuelSupNum(0), CWLoopNum(0), CWLoopSideNum(0), CWBranchNum(0), CWCompNum(0), ACPowerGen(0.0), QconvZone(0.0), QradZone(0.0), + DynamicsControlID(0), TimeElapsed(0.0), MyEnvrnFlag_Init(true), MyWarmupFlag_Init(false), MyPlantScanFlag_Init(true) + { + } + + static PlantComponent *factory(std::string const &objectName); + + static PlantComponent *factory_exhaust(std::string const &objectName); + + void initialize(); + + void getDesignCapacities(const PlantLocation &calledFromLocation, Real64 &MaxLoad, Real64 &MinLoad, Real64 &OptLoad) override; + + void setupOutputVars(); + + void simulate(const PlantLocation &calledFromLocation, bool FirstHVACIteration, Real64 &CurLoad, bool RunFlag) override; + + void FigureAirHeatCap(Real64 FluidTemp, Real64 &Cp); + + void FigureAirEnthalpy(Real64 FluidTemp, Real64 &Hair); + + void FigureFuelHeatCap(Real64 FluidTemp, Real64 &Cp); + + void FigureFuelEnthalpy(Real64 FluidTemp, Real64 &Hfuel); + + void FigureProductGasesEnthalpy(Real64 FluidTemp, Real64 &HProdGases); + + void FigureProductGasHeatCap(Real64 FluidTemp, Real64 &Cp); + + void FigureAuxilHeatGasHeatCap(Real64 FluidTemp, Real64 &Cp); + + void FigureACAncillaries(Real64 &PacAncill); + + void FigurePowerConditioningLosses(Real64 Pdemand, Real64 &PpcuLosses); + + void FigureTransientConstraints(Real64 &Pel, // DC power control setting for power module + bool &Constrained, // true if transient constraints kick in (TODO: never used anywhere) + Real64 &PelDiff // if constrained then this is the difference, positive + ); - // DERIVED TYPE DEFINITIONS + Real64 FuelCellProductGasEnthResidual(Real64 TprodGas, Array1 const &Par); - // MODULE VARIABLE DECLARATIONS: - extern bool GetFuelCellInput; // When TRUE, calls subroutine to read input file. - extern Array1D_bool CheckEquipName; - - // SUBROUTINE SPECIFICATIONS FOR MODULE FuelCell ElectricGenerator - - // PRIVATE SetupFuelAndAirConstituentData ! hardwired data for gas phase thermochemistry calcs - - // Functions - - void SimFuelCellGenerator(int const GeneratorType, // type of Generator - std::string const &GeneratorName, // user specified name of Generator - int &GeneratorIndex, - bool const RunFlag, // simulate Generator when TRUE - Real64 const MyLoad, // demand on electric generator - bool const FirstHVACIteration); - - // End FuelCell Generator Module Driver Subroutines - //****************************************************************************** - - // Beginning of FuelCell Generator Module Get Input subroutines - //****************************************************************************** - - void GetFuelCellGeneratorInput(); - - // End of Get Input subroutines for the FuelCell Generator Module - - // Beginning of Generator model Subroutines - // ***************************************************************************** - - void CalcFuelCellGeneratorModel(int const GeneratorNum, // Generator number - bool const RunFlag, // TRUE when Generator operating - Real64 const MyLoad, // Generator demand - bool const FirstHVACIteration); - - void ManageElectStorInteractions(int const Num, // Generator number, index for structure - Real64 const Pdemand, - Real64 const PpcuLosses, - bool &Constrained, // TODO: This one is never used anywhere in the code - Real64 &Pstorage, - Real64 &PgridOverage // electricity that can't be stored and needs to go out - ); - - Real64 FuelCellProductGasEnthResidual(Real64 const TprodGas, // temperature, this is "x" being searched - Array1 const &Par // par(1) = Generator Number - ); - - void FigureAirHeatCap(int const GeneratorNum, // ID of generator FuelCell data structure - Real64 const FluidTemp, // degree C - Real64 &Cp // (J/mol*K) - ); + static void FigureGaseousWaterEnthalpy(Real64 FluidTemp, Real64 &HGasWater); - void FigureAirEnthalpy(int const GeneratorNum, // ID of generator FuelCell data structure - Real64 const FluidTemp, // degree C - Real64 &Hair // (kJ/mol) - ); + static void FigureLiquidWaterEnthalpy(Real64 FluidTemp, Real64 &HLiqWater); - void FigureFuelHeatCap(int const GeneratorNum, // ID of generator FuelCell data structure - Real64 const FluidTemp, // degree C - Real64 &Cp // (J/mol*K) - ); + static void FigureLiquidWaterHeatCap(Real64 FluidTemp, Real64 &Cp); - void FigureFuelEnthalpy(int const GeneratorNum, // ID of generator FuelCell data structure - Real64 const FluidTemp, // degree C - Real64 &Hfuel // kJ/mol - ); + void CalcFuelCellAuxHeater(); - void FigureProductGasesEnthalpy(int const GeneratorNum, // ID of generator FuelCell data structure - Real64 const FluidTemp, // degree C - Real64 &HProdGases // kJ/mol - ); + void CalcFuelCellGenHeatRecovery(); - void FigureProductGasHeatCap(int const GeneratorNum, // ID of generator FuelCell data structure - Real64 const FluidTemp, // degree C - Real64 &Cp // (J/mol*K) - ); + void CalcFuelCellGeneratorModel(bool RunFlag, Real64 MyLoad, bool FirstHVACIteration); - void FigureAuxilHeatGasHeatCap(int const GeneratorNum, // ID of generator FuelCell data structure - Real64 const FluidTemp, // degree C - Real64 &Cp // (J/mol*K) - ); + void CalcUpdateHeatRecovery(bool FirstHVACIteration); - void FigureHXleavingGasHeatCap(int const GeneratorNum, // ID of generator FuelCell data structure - Real64 const FluidTemp, // degree C - Real64 &Cp // (J/mol*K) - ); + void ManageElectStorInteractions(Real64 Pdemand, + Real64 PpcuLosses, + bool &Constrained, // TODO: This one is never used anywhere in the code + Real64 &Pstorage, + Real64 &PgridOverage // electricity that can't be stored and needs to go out + ); - void FigureGaseousWaterEnthalpy(Real64 const FluidTemp, // degree C - Real64 &HGasWater // kJ/mol - ); + void SimFuelCellGenerator(bool RunFlag, // simulate Generator when TRUE + Real64 MyLoad, // demand on electric generator + bool FirstHVACIteration); - void FigureLiquidWaterEnthalpy(Real64 const FluidTemp, // degree C - Real64 &HLiqWater // kJ/mol - ); + void UpdateFuelCellGeneratorRecords(); + }; - void FigureLiquidWaterHeatCap(Real64 const FluidTemp, // degree C - Real64 &Cp // (J/mol*K) - ); + void clear_state(); - void FigureLHVofFuel(int const Num, Real64 const NdotFuel, Real64 const NdotCO2, Real64 const NdotH20, Real64 &LHV); - - void FigureACAncillaries(int const GeneratorNum, Real64 &PacAncill); - - void FigurePowerConditioningLosses(int const GeneratorNum, Real64 const Pdemand, Real64 &PpcuLosses); - - void FigureTransientConstraints(int const GeneratorNum, // index number for accessing correct generator - Real64 &Pel, // DC power control setting for power module - bool &Constrained, // true if transient constraints kick in (TODO: never used anywhere) - Real64 &PelDiff // if constrained then this is the difference, positive - ); - - void CalcFuelCellAuxHeater(int const Num); // Generator number - - void CalcFuelCellGenHeatRecovery(int const Num); // Generator number - - void SimFuelCellPlantHeatRecovery(std::string const &CompType, - std::string const &CompName, - int const CompTypeNum, - int &CompNum, - bool const RunFlag, - bool &InitLoopEquip, - Real64 &MyLoad, // unused1208 - Real64 &MaxCap, - Real64 &MinCap, - Real64 &OptCap, - bool const FirstHVACIteration // TRUE if First iteration of simulation - ); - - // End FuelCell Generator Module Model Subroutines - // ***************************************************************************** - - // Begin FuelCell Generator Module Utility Subroutines - // ***************************************************************************** - - void InitFuelCellGenerators(int const FCnum); // index to specific fuel cell generator - - void getFuelCellGeneratorHeatRecoveryInfo(std::string const &GeneratorName, // user specified name of Generator - std::string &heatRecoveryCompName); - - // End FuelCell Generator Module Utility Subroutines - // ***************************************************************************** - - // Beginning of Record Keeping subroutines for the FuelCell Generator Module - // ***************************************************************************** + void getFuelCellInput(); void FigureFuelCellZoneGains(); - void UpdateExhaustAirFlows(int const Num); // generator number - - void CalcUpdateHeatRecovery(int const Num, // Generator number - bool const FirstHVACIteration); - - void UpdateFuelCellGeneratorRecords(bool const RunFlag, // TRUE if Generator operating - int const Num // Generator number - ); - - void GetFuelCellGeneratorResults(int const GeneratorType, // type of Generator - int const GeneratorIndex, - Real64 &GeneratorPower, // electrical power - Real64 &GeneratorEnergy, // electrical energy - Real64 &ThermalPower, // heat power - Real64 &ThermalEnergy // heat energy - ); + extern bool getFuelCellInputFlag; + extern int NumFuelCellGenerators; + extern Array1D_bool CheckEquipName; + extern Array1D FuelCell; } // namespace FuelCellElectricGenerator diff --git a/src/EnergyPlus/MicroCHPElectricGenerator.cc b/src/EnergyPlus/MicroCHPElectricGenerator.cc index 57cc53634bf..2aa4d050709 100644 --- a/src/EnergyPlus/MicroCHPElectricGenerator.cc +++ b/src/EnergyPlus/MicroCHPElectricGenerator.cc @@ -1265,8 +1265,7 @@ namespace MicroCHPElectricGenerator { if (NumMicroCHPs == 0) return; if (DataGlobals::BeginEnvrnFlag && MyEnvrnFlag) { - for (auto &e : DataGenerators::FuelSupply) - e.QskinLoss = 0.0; + for (auto &e : DataGenerators::FuelSupply) e.QskinLoss = 0.0; for (auto &e : MicroCHP) { e.A42Model.QdotSkin = 0.0; e.A42Model.SkinLossConvect = 0.0; diff --git a/src/EnergyPlus/Plant/PlantManager.cc b/src/EnergyPlus/Plant/PlantManager.cc index d43bddedd72..401acc62926 100644 --- a/src/EnergyPlus/Plant/PlantManager.cc +++ b/src/EnergyPlus/Plant/PlantManager.cc @@ -73,6 +73,7 @@ #include #include #include +#include #include #include #include @@ -106,6 +107,7 @@ #include #include #include +#include #include namespace EnergyPlus { @@ -978,6 +980,7 @@ namespace EnergyPlus { this_comp.TypeOf_Num = TypeOf_WaterUseConnection; this_comp.GeneralEquipType = GenEquipTypes_WaterUse; this_comp.CurOpSchemeType = DemandOpSchemeType; + this_comp.compPtr = WaterUse::WaterConnectionsType::factory(CompNames(CompNum)); } else if (UtilityRoutines::SameString(this_comp_type, "Coil:Cooling:Water")) { this_comp.TypeOf_Num = TypeOf_CoilWaterCooling; this_comp.GeneralEquipType = GenEquipTypes_DemandCoil; @@ -1137,10 +1140,10 @@ namespace EnergyPlus { this_comp.TypeOf_Num = TypeOf_CoolingTower_VarSpdMerkel; this_comp.GeneralEquipType = GenEquipTypes_CoolingTower; this_comp.compPtr = CondenserLoopTowers::CoolingTower::factory(CompNames(CompNum)); - } else if (UtilityRoutines::SameString(this_comp_type, - "Generator:FuelCell:ExhaustGasToWaterHeatExchanger")) { + } else if (UtilityRoutines::SameString(this_comp_type, "Generator:FuelCell:ExhaustGasToWaterHeatExchanger")) { this_comp.TypeOf_Num = TypeOf_Generator_FCExhaust; this_comp.GeneralEquipType = GenEquipTypes_Generator; + this_comp.compPtr = FuelCellElectricGenerator::FCDataStruct::factory_exhaust(CompNames(CompNum)); if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -1298,6 +1301,7 @@ namespace EnergyPlus { } else if (UtilityRoutines::SameString(this_comp_type, "Generator:FuelCell:StackCooler")) { this_comp.TypeOf_Num = TypeOf_Generator_FCStackCooler; this_comp.GeneralEquipType = GenEquipTypes_Generator; + this_comp.compPtr = FuelCellElectricGenerator::FCDataStruct::factory(CompNames(CompNum)); if (LoopSideNum == DemandSide) { this_comp.CurOpSchemeType = DemandOpSchemeType; } else if (LoopSideNum == SupplySide) { @@ -1308,7 +1312,6 @@ namespace EnergyPlus { this_comp.GeneralEquipType = GenEquipTypes_FluidCooler; this_comp.compPtr = FluidCoolers::FluidCoolerspecs::factory( TypeOf_FluidCooler_SingleSpd, CompNames(CompNum)); - // } else if (UtilityRoutines::SameString(this_comp_type, "FluidCooler:TwoSpeed")) { this_comp.TypeOf_Num = TypeOf_FluidCooler_TwoSpd; this_comp.GeneralEquipType = GenEquipTypes_FluidCooler; diff --git a/src/EnergyPlus/PlantLoopEquip.cc b/src/EnergyPlus/PlantLoopEquip.cc index 0d8629b81c2..9e4f9c2e3c6 100644 --- a/src/EnergyPlus/PlantLoopEquip.cc +++ b/src/EnergyPlus/PlantLoopEquip.cc @@ -187,7 +187,6 @@ namespace PlantLoopEquip { using Pumps::SimPumps; using ScheduleManager::GetCurrentScheduleValue; using WaterThermalTanks::SimWaterThermalTank; - using FuelCellElectricGenerator::SimFuelCellPlantHeatRecovery; using PlantHeatExchangerFluidToFluid::SimFluidHeatExchanger; using BaseboardRadiator::UpdateBaseboardPlantConnection; using HVACVariableRefrigerantFlow::SimVRFCondenserPlant; @@ -198,7 +197,6 @@ namespace PlantLoopEquip { using RefrigeratedCase::SimRefrigCondenser; using SteamBaseboardRadiator::UpdateSteamBaseboardPlantConnection; using WaterCoils::UpdateWaterToAirCoilPlantConnection; - using WaterUse::SimulateWaterUseConnection; // SUBROUTINE LOCAL VARIABLE DECLARATIONS: int EquipNum; // Plant side component list equipment number @@ -809,42 +807,12 @@ namespace PlantLoopEquip { // for heat recovery plant interactions. if (EquipTypeNum == TypeOf_Generator_FCExhaust) { - SimFuelCellPlantHeatRecovery(sim_component.TypeOf, - sim_component.Name, - TypeOf_Generator_FCExhaust, - EquipNum, - RunFlag, - InitLoopEquip, - CurLoad, - MaxLoad, - MinLoad, - OptLoad, - FirstHVACIteration); // DSU - if (InitLoopEquip) { - sim_component.MaxLoad = MaxLoad; - sim_component.MinLoad = MinLoad; - sim_component.OptLoad = OptLoad; - sim_component.CompNum = EquipNum; - } + dynamic_cast (sim_component.compPtr)->TypeOf = DataPlant::TypeOf_Generator_FCExhaust; + sim_component.compPtr->simulate(sim_component_location, FirstHVACIteration, CurLoad, RunFlag); } else if (EquipTypeNum == TypeOf_Generator_FCStackCooler) { - SimFuelCellPlantHeatRecovery(sim_component.TypeOf, - sim_component.Name, - TypeOf_Generator_FCStackCooler, - EquipNum, - RunFlag, - InitLoopEquip, - CurLoad, - MaxLoad, - MinLoad, - OptLoad, - FirstHVACIteration); // DSU - if (InitLoopEquip) { - sim_component.MaxLoad = MaxLoad; - sim_component.MinLoad = MinLoad; - sim_component.OptLoad = OptLoad; - sim_component.CompNum = EquipNum; - } + dynamic_cast (sim_component.compPtr)->TypeOf = DataPlant::TypeOf_Generator_FCStackCooler; + sim_component.compPtr->simulate(sim_component_location, FirstHVACIteration, CurLoad, RunFlag); } else if (EquipTypeNum == TypeOf_Generator_MicroCHP) { sim_component.compPtr->simulate(sim_component_location, FirstHVACIteration, CurLoad, RunFlag); @@ -935,11 +903,8 @@ namespace PlantLoopEquip { if (EquipTypeNum == TypeOf_WaterUseConnection) { - SimulateWaterUseConnection(EquipTypeNum, sim_component.Name, EquipNum, InitLoopEquip, FirstHVACIteration); + sim_component.compPtr->simulate(sim_component_location, FirstHVACIteration, CurLoad, RunFlag); - if (InitLoopEquip) { - sim_component.CompNum = EquipNum; - } } else { ShowSevereError("SimPlantEquip: Invalid Load Coil Type=" + sim_component.TypeOf); ShowContinueError("Occurs in Plant Loop=" + PlantLoop(LoopNum).Name); diff --git a/src/EnergyPlus/WaterUse.cc b/src/EnergyPlus/WaterUse.cc index 1d8f594ad58..aff5ff37f6e 100644 --- a/src/EnergyPlus/WaterUse.cc +++ b/src/EnergyPlus/WaterUse.cc @@ -61,9 +61,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -85,87 +83,53 @@ namespace WaterUse { // MODIFIED Brent Griffith, plant upgrade // RE-ENGINEERED na - // Using/Aliasing - using namespace DataPrecisionGlobals; - using DataGlobals::BeginEnvrnFlag; - using DataGlobals::NumOfZones; - using DataGlobals::WarmupFlag; - - // MODULE PARAMETER DEFINITIONS: - int const HeatRecoveryHXIdeal(1); - int const HeatRecoveryHXCounterFlow(2); - int const HeatRecoveryHXCrossFlow(3); - - int const HeatRecoveryConfigPlant(1); - int const HeatRecoveryConfigEquipment(2); - int const HeatRecoveryConfigPlantAndEquip(3); - - static std::string const BlankString; - - // MODULE VARIABLE DECLARATIONS: - int NumWaterEquipment(0); - int NumWaterConnections(0); - bool GetWaterUseInputFlag(true); + bool getWaterUseInputFlag(true); + int numWaterEquipment(0); + int numWaterConnections(0); Array1D_bool CheckEquipName; - Array1D_bool CheckPlantLoop; - // Object Data Array1D WaterEquipment; Array1D WaterConnections; void clear_state() { - NumWaterEquipment = 0; - NumWaterConnections = 0; - GetWaterUseInputFlag = true; + numWaterEquipment = 0; + numWaterConnections = 0; + getWaterUseInputFlag = true; CheckEquipName.deallocate(); - CheckPlantLoop.deallocate(); WaterEquipment.deallocate(); WaterConnections.deallocate(); } - void SimulateWaterUse(bool const FirstHVACIteration) + void SimulateWaterUse(bool FirstHVACIteration) { // SUBROUTINE INFORMATION: // AUTHOR Peter Graham Ellis // DATE WRITTEN August 2006 - // MODIFIED Brent Griffith, March 2010, seperated plant connected to different sim routine + // MODIFIED Brent Griffith, March 2010, separated plant connected to different sim routine // RE-ENGINEERED na // PURPOSE OF THIS SUBROUTINE: // This routine is called from non zone equipment manager and serves to call // water use and connections that are not connected to a full plant loop - // METHODOLOGY EMPLOYED: - - // Using/Aliasing - using General::RoundSigDigits; - - // Locals - // SUBROUTINE PARAMETER DEFINITIONS: int const MaxIterations(100); Real64 const Tolerance(0.1); // Make input? - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: int WaterEquipNum; int WaterConnNum; int NumIteration; - static int MaxIterationsErrorCount; - static bool MyEnvrnFlag(true); + static bool MyEnvrnFlagLocal(true); - // FLOW: - if (GetWaterUseInputFlag) { + if (getWaterUseInputFlag) { GetWaterUseInput(); - GetWaterUseInputFlag = false; + getWaterUseInputFlag = false; } - if (BeginEnvrnFlag && MyEnvrnFlag) { - MaxIterationsErrorCount = 0; - if (NumWaterEquipment > 0) { + if (DataGlobals::BeginEnvrnFlag && MyEnvrnFlagLocal) { + if (numWaterEquipment > 0) { for (auto &e : WaterEquipment) { e.SensibleRate = 0.0; e.SensibleEnergy = 0.0; @@ -177,46 +141,46 @@ namespace WaterUse { } } - if (NumWaterConnections > 0) { + if (numWaterConnections > 0) { for (auto &e : WaterConnections) e.TotalMassFlowRate = 0.0; } - MyEnvrnFlag = false; + MyEnvrnFlagLocal = false; } - if (!BeginEnvrnFlag) MyEnvrnFlag = true; + if (!DataGlobals::BeginEnvrnFlag) MyEnvrnFlagLocal = true; // Simulate all unconnected WATER USE EQUIPMENT objects - for (WaterEquipNum = 1; WaterEquipNum <= NumWaterEquipment; ++WaterEquipNum) { + for (WaterEquipNum = 1; WaterEquipNum <= numWaterEquipment; ++WaterEquipNum) { if (WaterEquipment(WaterEquipNum).Connections == 0) { - CalcEquipmentFlowRates(WaterEquipNum); - CalcEquipmentDrainTemp(WaterEquipNum); + WaterEquipment(WaterEquipNum).CalcEquipmentFlowRates(); + WaterEquipment(WaterEquipNum).CalcEquipmentDrainTemp(); } } // WaterEquipNum ReportStandAloneWaterUse(); // Simulate WATER USE CONNECTIONS objects and connected WATER USE EQUIPMENT objects - for (WaterConnNum = 1; WaterConnNum <= NumWaterConnections; ++WaterConnNum) { + for (WaterConnNum = 1; WaterConnNum <= numWaterConnections; ++WaterConnNum) { if (!WaterConnections(WaterConnNum).StandAlone) continue; // only model non plant connections here - InitConnections(WaterConnNum); + WaterConnections(WaterConnNum).InitConnections(); NumIteration = 0; while (true) { ++NumIteration; - CalcConnectionsFlowRates(WaterConnNum, FirstHVACIteration); - CalcConnectionsDrainTemp(WaterConnNum); - CalcConnectionsHeatRecovery(WaterConnNum); + WaterConnections(WaterConnNum).CalcConnectionsFlowRates(FirstHVACIteration); + WaterConnections(WaterConnNum).CalcConnectionsDrainTemp(); + WaterConnections(WaterConnNum).CalcConnectionsHeatRecovery(); if (WaterConnections(WaterConnNum).TempError < Tolerance) { break; } else if (NumIteration > MaxIterations) { - if (!WarmupFlag) { + if (!DataGlobals::WarmupFlag) { if (WaterConnections(WaterConnNum).MaxIterationsErrorIndex == 0) { ShowWarningError("WaterUse:Connections = " + WaterConnections(WaterConnNum).Name + ": Heat recovery temperature did not converge"); @@ -231,15 +195,36 @@ namespace WaterUse { } // WHILE - UpdateWaterConnections(WaterConnNum); - - ReportWaterUse(WaterConnNum); + WaterConnections(WaterConnNum).UpdateWaterConnections(); + WaterConnections(WaterConnNum).ReportWaterUse(); } // WaterConnNum } - void SimulateWaterUseConnection( - int const EP_UNUSED(EquipTypeNum), std::string const &CompName, int &CompIndex, bool const InitLoopEquip, bool const FirstHVACIteration) + PlantComponent *WaterConnectionsType::factory(std::string const &objectName) + { + // Process the input data + if (getWaterUseInputFlag) { + GetWaterUseInput(); + getWaterUseInputFlag = false; + } + + // Now look for this particular object in the list + for (auto &thisWC : WaterConnections) { + if (thisWC.Name == objectName) { + return &thisWC; + } + } + // If we didn't find it, fatal + ShowFatalError("LocalWaterUseConnectionFactory: Error getting inputs for object named: " + objectName); // LCOV_EXCL_LINE + // Shut up the compiler + return nullptr; // LCOV_EXCL_LINE + } + + void WaterConnectionsType::simulate(const PlantLocation &EP_UNUSED(calledFromLocation), + bool FirstHVACIteration, + Real64 &EP_UNUSED(CurLoad), + bool EP_UNUSED(RunFlag)) { // SUBROUTINE INFORMATION: @@ -250,109 +235,60 @@ namespace WaterUse { // PURPOSE OF THIS SUBROUTINE: // Plant sim call for plant loop connected water use and connections - // (based on SimulateWaterUse by P. Ellis) - - // METHODOLOGY EMPLOYED: - // Using/Aliasing - using General::RoundSigDigits; - using General::TrimSigDigits; - - // Locals - // SUBROUTINE PARAMETER DEFINITIONS: int const MaxIterations(100); Real64 const Tolerance(0.1); // Make input? - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - // INTEGER :: WaterEquipNum - int WaterConnNum; - int NumIteration; - static int MaxIterationsErrorCount; - static bool MyEnvrnFlag(true); - - // FLOW: - if (GetWaterUseInputFlag) { - GetWaterUseInput(); - GetWaterUseInputFlag = false; - } - - if (CompIndex == 0) { - WaterConnNum = UtilityRoutines::FindItemInList(CompName, WaterConnections); - if (WaterConnNum == 0) { - ShowFatalError("SimulateWaterUseConnection: Unit not found=" + CompName); - } - CompIndex = WaterConnNum; - } else { - WaterConnNum = CompIndex; - if (WaterConnNum > NumWaterConnections || WaterConnNum < 1) { - ShowFatalError("SimulateWaterUseConnection: Invalid CompIndex passed=" + TrimSigDigits(WaterConnNum) + - ", Number of Units=" + TrimSigDigits(NumWaterConnections) + ", Entered Unit name=" + CompName); - } - if (CheckEquipName(WaterConnNum)) { - if (CompName != WaterConnections(WaterConnNum).Name) { - ShowFatalError("SimulateWaterUseConnection: Invalid CompIndex passed=" + TrimSigDigits(WaterConnNum) + ", Unit name=" + CompName + - ", stored Unit Name for that index=" + WaterConnections(WaterConnNum).Name); - } - CheckEquipName(WaterConnNum) = false; - } - } - - if (InitLoopEquip) { - return; - } - - if (BeginEnvrnFlag && MyEnvrnFlag) { - MaxIterationsErrorCount = 0; - if (NumWaterEquipment > 0) { + if (DataGlobals::BeginEnvrnFlag && this->MyEnvrnFlag) { + if (numWaterEquipment > 0) { for (int i = WaterEquipment.l(), e = WaterEquipment.u(); i <= e; ++i) { WaterEquipment(i).reset(); + + if (WaterEquipment(i).setupMyOutputVars) { + WaterEquipment(i).setupOutputVars(); + WaterEquipment(i).setupMyOutputVars = false; + } } } - if (NumWaterConnections > 0) { + if (numWaterConnections > 0) { for (auto &e : WaterConnections) e.TotalMassFlowRate = 0.0; } - MyEnvrnFlag = false; + this->MyEnvrnFlag = false; } - if (!BeginEnvrnFlag) MyEnvrnFlag = true; + if (!DataGlobals::BeginEnvrnFlag) this->MyEnvrnFlag = true; - InitConnections(WaterConnNum); + this->InitConnections(); - NumIteration = 0; + int NumIteration = 0; while (true) { ++NumIteration; - CalcConnectionsFlowRates(WaterConnNum, FirstHVACIteration); - CalcConnectionsDrainTemp(WaterConnNum); - CalcConnectionsHeatRecovery(WaterConnNum); + this->CalcConnectionsFlowRates(FirstHVACIteration); + this->CalcConnectionsDrainTemp(); + this->CalcConnectionsHeatRecovery(); - if (WaterConnections(WaterConnNum).TempError < Tolerance) { + if (this->TempError < Tolerance) { break; } else if (NumIteration > MaxIterations) { - if (!WarmupFlag) { - if (WaterConnections(WaterConnNum).MaxIterationsErrorIndex == 0) { - ShowWarningError("WaterUse:Connections = " + WaterConnections(WaterConnNum).Name + - ": Heat recovery temperature did not converge"); + if (!DataGlobals::WarmupFlag) { + if (this->MaxIterationsErrorIndex == 0) { + ShowWarningError("WaterUse:Connections = " + this->Name + ": Heat recovery temperature did not converge"); ShowContinueErrorTimeStamp(""); } - ShowRecurringWarningErrorAtEnd("WaterUse:Connections = " + WaterConnections(WaterConnNum).Name + - ": Heat recovery temperature did not converge", - WaterConnections(WaterConnNum).MaxIterationsErrorIndex); + ShowRecurringWarningErrorAtEnd("WaterUse:Connections = " + this->Name + ": Heat recovery temperature did not converge", + this->MaxIterationsErrorIndex); } break; } - } // WHILE - UpdateWaterConnections(WaterConnNum); - - ReportWaterUse(WaterConnNum); + this->UpdateWaterConnections(); + this->ReportWaterUse(); } void GetWaterUseInput() @@ -364,282 +300,263 @@ namespace WaterUse { // MODIFIED na // RE-ENGINEERED na - // PURPOSE OF THIS SUBROUTINE: - - // METHODOLOGY EMPLOYED: - // Standard EnergyPlus methodology. - - // Using/Aliasing - using namespace DataIPShortCuts; // Data for field names, blank numerics - using BranchNodeConnections::TestCompSet; - using NodeInputManager::GetOnlySingleNode; - using ScheduleManager::GetScheduleIndex; - using namespace DataLoopNode; - using namespace DataHeatBalance; - using PlantUtilities::RegisterPlantCompDesignFlow; - using Psychrometrics::RhoH2O; - using WaterManager::SetupTankDemandComponent; - using WaterManager::SetupTankSupplyComponent; - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - static bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine - int IOStatus; // Used in GetObjectItem - int NumAlphas; // Number of Alphas for each GetObjectItem call - int NumNumbers; // Number of Numbers for each GetObjectItem call - // unused1208 INTEGER :: NumArgs - int WaterEquipNum; - int WaterConnNum; + bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine + int IOStatus; // Used in GetObjectItem + int NumAlphas; // Number of Alphas for each GetObjectItem call + int NumNumbers; // Number of Numbers for each GetObjectItem call int AlphaNum; - int thisWaterEquipNum; - - // FLOW: - cCurrentModuleObject = "WaterUse:Equipment"; - NumWaterEquipment = inputProcessor->getNumObjectsFound(cCurrentModuleObject); + DataIPShortCuts::cCurrentModuleObject = "WaterUse:Equipment"; + numWaterEquipment = inputProcessor->getNumObjectsFound(DataIPShortCuts::cCurrentModuleObject); - if (NumWaterEquipment > 0) { - WaterEquipment.allocate(NumWaterEquipment); + if (numWaterEquipment > 0) { + WaterEquipment.allocate(numWaterEquipment); - for (WaterEquipNum = 1; WaterEquipNum <= NumWaterEquipment; ++WaterEquipNum) { - inputProcessor->getObjectItem(cCurrentModuleObject, + for (int WaterEquipNum = 1; WaterEquipNum <= numWaterEquipment; ++WaterEquipNum) { + inputProcessor->getObjectItem(DataIPShortCuts::cCurrentModuleObject, WaterEquipNum, - cAlphaArgs, + DataIPShortCuts::cAlphaArgs, NumAlphas, - rNumericArgs, + DataIPShortCuts::rNumericArgs, NumNumbers, IOStatus, _, - lAlphaFieldBlanks, - cAlphaFieldNames, - cNumericFieldNames); - UtilityRoutines::IsNameEmpty(cAlphaArgs(1), cCurrentModuleObject, ErrorsFound); - WaterEquipment(WaterEquipNum).Name = cAlphaArgs(1); + DataIPShortCuts::lAlphaFieldBlanks, + DataIPShortCuts::cAlphaFieldNames, + DataIPShortCuts::cNumericFieldNames); + UtilityRoutines::IsNameEmpty(DataIPShortCuts::cAlphaArgs(1), DataIPShortCuts::cCurrentModuleObject, ErrorsFound); + WaterEquipment(WaterEquipNum).Name = DataIPShortCuts::cAlphaArgs(1); - WaterEquipment(WaterEquipNum).EndUseSubcatName = cAlphaArgs(2); + WaterEquipment(WaterEquipNum).EndUseSubcatName = DataIPShortCuts::cAlphaArgs(2); - WaterEquipment(WaterEquipNum).PeakVolFlowRate = rNumericArgs(1); + WaterEquipment(WaterEquipNum).PeakVolFlowRate = DataIPShortCuts::rNumericArgs(1); - if ((NumAlphas > 2) && (!lAlphaFieldBlanks(3))) { - WaterEquipment(WaterEquipNum).FlowRateFracSchedule = GetScheduleIndex(cAlphaArgs(3)); + if ((NumAlphas > 2) && (!DataIPShortCuts::lAlphaFieldBlanks(3))) { + WaterEquipment(WaterEquipNum).FlowRateFracSchedule = ScheduleManager::GetScheduleIndex(DataIPShortCuts::cAlphaArgs(3)); // If no FlowRateFracSchedule, fraction defaults to 1.0 if (WaterEquipment(WaterEquipNum).FlowRateFracSchedule == 0) { - ShowSevereError("Invalid " + cAlphaFieldNames(3) + '=' + cAlphaArgs(3)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + cAlphaArgs(1)); + ShowSevereError("Invalid " + DataIPShortCuts::cAlphaFieldNames(3) + '=' + DataIPShortCuts::cAlphaArgs(3)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + DataIPShortCuts::cAlphaArgs(1)); ErrorsFound = true; } } - if ((NumAlphas > 3) && (!lAlphaFieldBlanks(4))) { - WaterEquipment(WaterEquipNum).TargetTempSchedule = GetScheduleIndex(cAlphaArgs(4)); + if ((NumAlphas > 3) && (!DataIPShortCuts::lAlphaFieldBlanks(4))) { + WaterEquipment(WaterEquipNum).TargetTempSchedule = ScheduleManager::GetScheduleIndex(DataIPShortCuts::cAlphaArgs(4)); if (WaterEquipment(WaterEquipNum).TargetTempSchedule == 0) { - ShowSevereError("Invalid " + cAlphaFieldNames(4) + '=' + cAlphaArgs(4)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + cAlphaArgs(1)); + ShowSevereError("Invalid " + DataIPShortCuts::cAlphaFieldNames(4) + '=' + DataIPShortCuts::cAlphaArgs(4)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + DataIPShortCuts::cAlphaArgs(1)); ErrorsFound = true; } } - if ((NumAlphas > 4) && (!lAlphaFieldBlanks(5))) { - WaterEquipment(WaterEquipNum).HotTempSchedule = GetScheduleIndex(cAlphaArgs(5)); + if ((NumAlphas > 4) && (!DataIPShortCuts::lAlphaFieldBlanks(5))) { + WaterEquipment(WaterEquipNum).HotTempSchedule = ScheduleManager::GetScheduleIndex(DataIPShortCuts::cAlphaArgs(5)); // If no HotTempSchedule, there is no hot water. // HotTempSchedule is ignored if connected to a plant loop via WATER USE CONNECTIONS if (WaterEquipment(WaterEquipNum).HotTempSchedule == 0) { - ShowSevereError("Invalid " + cAlphaFieldNames(5) + '=' + cAlphaArgs(5)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + cAlphaArgs(1)); + ShowSevereError("Invalid " + DataIPShortCuts::cAlphaFieldNames(5) + '=' + DataIPShortCuts::cAlphaArgs(5)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + DataIPShortCuts::cAlphaArgs(1)); ErrorsFound = true; } } - if ((NumAlphas > 5) && (!lAlphaFieldBlanks(6))) { - WaterEquipment(WaterEquipNum).ColdTempSchedule = GetScheduleIndex(cAlphaArgs(6)); + if ((NumAlphas > 5) && (!DataIPShortCuts::lAlphaFieldBlanks(6))) { + WaterEquipment(WaterEquipNum).ColdTempSchedule = ScheduleManager::GetScheduleIndex(DataIPShortCuts::cAlphaArgs(6)); // If no ColdTempSchedule, temperatures will be calculated by WATER MAINS TEMPERATURES object if (WaterEquipment(WaterEquipNum).ColdTempSchedule == 0) { - ShowSevereError("Invalid " + cAlphaFieldNames(6) + '=' + cAlphaArgs(6)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + cAlphaArgs(1)); + ShowSevereError("Invalid " + DataIPShortCuts::cAlphaFieldNames(6) + '=' + DataIPShortCuts::cAlphaArgs(6)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + DataIPShortCuts::cAlphaArgs(1)); ErrorsFound = true; } } - if ((NumAlphas > 6) && (!lAlphaFieldBlanks(7))) { - WaterEquipment(WaterEquipNum).Zone = UtilityRoutines::FindItemInList(cAlphaArgs(7), Zone); + if ((NumAlphas > 6) && (!DataIPShortCuts::lAlphaFieldBlanks(7))) { + WaterEquipment(WaterEquipNum).Zone = UtilityRoutines::FindItemInList(DataIPShortCuts::cAlphaArgs(7), DataHeatBalance::Zone); if (WaterEquipment(WaterEquipNum).Zone == 0) { - ShowSevereError("Invalid " + cAlphaFieldNames(7) + '=' + cAlphaArgs(7)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + cAlphaArgs(1)); + ShowSevereError("Invalid " + DataIPShortCuts::cAlphaFieldNames(7) + '=' + DataIPShortCuts::cAlphaArgs(7)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + DataIPShortCuts::cAlphaArgs(1)); ErrorsFound = true; } } - if ((NumAlphas > 7) && (!lAlphaFieldBlanks(8))) { - WaterEquipment(WaterEquipNum).SensibleFracSchedule = GetScheduleIndex(cAlphaArgs(8)); + if ((NumAlphas > 7) && (!DataIPShortCuts::lAlphaFieldBlanks(8))) { + WaterEquipment(WaterEquipNum).SensibleFracSchedule = ScheduleManager::GetScheduleIndex(DataIPShortCuts::cAlphaArgs(8)); if (WaterEquipment(WaterEquipNum).SensibleFracSchedule == 0) { - ShowSevereError("Invalid " + cAlphaFieldNames(8) + '=' + cAlphaArgs(8)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + cAlphaArgs(1)); + ShowSevereError("Invalid " + DataIPShortCuts::cAlphaFieldNames(8) + '=' + DataIPShortCuts::cAlphaArgs(8)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + DataIPShortCuts::cAlphaArgs(1)); ErrorsFound = true; } } - if ((NumAlphas > 8) && (!lAlphaFieldBlanks(9))) { - WaterEquipment(WaterEquipNum).LatentFracSchedule = GetScheduleIndex(cAlphaArgs(9)); + if ((NumAlphas > 8) && (!DataIPShortCuts::lAlphaFieldBlanks(9))) { + WaterEquipment(WaterEquipNum).LatentFracSchedule = ScheduleManager::GetScheduleIndex(DataIPShortCuts::cAlphaArgs(9)); if (WaterEquipment(WaterEquipNum).LatentFracSchedule == 0) { - ShowSevereError("Invalid " + cAlphaFieldNames(9) + '=' + cAlphaArgs(9)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + cAlphaArgs(1)); + ShowSevereError("Invalid " + DataIPShortCuts::cAlphaFieldNames(9) + '=' + DataIPShortCuts::cAlphaArgs(9)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + DataIPShortCuts::cAlphaArgs(1)); ErrorsFound = true; } } } // WaterEquipNum - if (ErrorsFound) ShowFatalError("Errors found in processing input for " + cCurrentModuleObject); + if (ErrorsFound) ShowFatalError("Errors found in processing input for " + DataIPShortCuts::cCurrentModuleObject); } - cCurrentModuleObject = "WaterUse:Connections"; - NumWaterConnections = inputProcessor->getNumObjectsFound(cCurrentModuleObject); + DataIPShortCuts::cCurrentModuleObject = "WaterUse:Connections"; + numWaterConnections = inputProcessor->getNumObjectsFound(DataIPShortCuts::cCurrentModuleObject); - if (NumWaterConnections > 0) { - WaterConnections.allocate(NumWaterConnections); + if (numWaterConnections > 0) { + WaterConnections.allocate(numWaterConnections); - for (WaterConnNum = 1; WaterConnNum <= NumWaterConnections; ++WaterConnNum) { - inputProcessor->getObjectItem(cCurrentModuleObject, + for (int WaterConnNum = 1; WaterConnNum <= numWaterConnections; ++WaterConnNum) { + inputProcessor->getObjectItem(DataIPShortCuts::cCurrentModuleObject, WaterConnNum, - cAlphaArgs, + DataIPShortCuts::cAlphaArgs, NumAlphas, - rNumericArgs, + DataIPShortCuts::rNumericArgs, NumNumbers, IOStatus, _, - lAlphaFieldBlanks, - cAlphaFieldNames, - cNumericFieldNames); - UtilityRoutines::IsNameEmpty(cAlphaArgs(1), cCurrentModuleObject, ErrorsFound); - WaterConnections(WaterConnNum).Name = cAlphaArgs(1); - - if ((!lAlphaFieldBlanks(2)) || (!lAlphaFieldBlanks(3))) { - WaterConnections(WaterConnNum).InletNode = GetOnlySingleNode(cAlphaArgs(2), - ErrorsFound, - cCurrentModuleObject, - cAlphaArgs(1), - NodeType_Water, - NodeConnectionType_Inlet, - 1, - ObjectIsNotParent); - WaterConnections(WaterConnNum).OutletNode = GetOnlySingleNode(cAlphaArgs(3), - ErrorsFound, - cCurrentModuleObject, - cAlphaArgs(1), - NodeType_Water, - NodeConnectionType_Outlet, - 1, - ObjectIsNotParent); + DataIPShortCuts::lAlphaFieldBlanks, + DataIPShortCuts::cAlphaFieldNames, + DataIPShortCuts::cNumericFieldNames); + UtilityRoutines::IsNameEmpty(DataIPShortCuts::cAlphaArgs(1), DataIPShortCuts::cCurrentModuleObject, ErrorsFound); + WaterConnections(WaterConnNum).Name = DataIPShortCuts::cAlphaArgs(1); + + if ((!DataIPShortCuts::lAlphaFieldBlanks(2)) || (!DataIPShortCuts::lAlphaFieldBlanks(3))) { + WaterConnections(WaterConnNum).InletNode = NodeInputManager::GetOnlySingleNode(DataIPShortCuts::cAlphaArgs(2), + ErrorsFound, + DataIPShortCuts::cCurrentModuleObject, + DataIPShortCuts::cAlphaArgs(1), + DataLoopNode::NodeType_Water, + DataLoopNode::NodeConnectionType_Inlet, + 1, + DataLoopNode::ObjectIsNotParent); + WaterConnections(WaterConnNum).OutletNode = NodeInputManager::GetOnlySingleNode(DataIPShortCuts::cAlphaArgs(3), + ErrorsFound, + DataIPShortCuts::cCurrentModuleObject, + DataIPShortCuts::cAlphaArgs(1), + DataLoopNode::NodeType_Water, + DataLoopNode::NodeConnectionType_Outlet, + 1, + DataLoopNode::ObjectIsNotParent); // Check plant connections - TestCompSet(cCurrentModuleObject, cAlphaArgs(1), cAlphaArgs(2), cAlphaArgs(3), "DHW Nodes"); + BranchNodeConnections::TestCompSet(DataIPShortCuts::cCurrentModuleObject, + DataIPShortCuts::cAlphaArgs(1), + DataIPShortCuts::cAlphaArgs(2), + DataIPShortCuts::cAlphaArgs(3), + "DHW Nodes"); } else { // If no plant nodes are connected, simulate in stand-alone mode. WaterConnections(WaterConnNum).StandAlone = true; } - if (!lAlphaFieldBlanks(4)) { - SetupTankDemandComponent(WaterConnections(WaterConnNum).Name, - cCurrentModuleObject, - cAlphaArgs(4), - ErrorsFound, - WaterConnections(WaterConnNum).SupplyTankNum, - WaterConnections(WaterConnNum).TankDemandID); + if (!DataIPShortCuts::lAlphaFieldBlanks(4)) { + WaterManager::SetupTankDemandComponent(WaterConnections(WaterConnNum).Name, + DataIPShortCuts::cCurrentModuleObject, + DataIPShortCuts::cAlphaArgs(4), + ErrorsFound, + WaterConnections(WaterConnNum).SupplyTankNum, + WaterConnections(WaterConnNum).TankDemandID); } - if (!lAlphaFieldBlanks(5)) { - SetupTankSupplyComponent(WaterConnections(WaterConnNum).Name, - cCurrentModuleObject, - cAlphaArgs(5), - ErrorsFound, - WaterConnections(WaterConnNum).RecoveryTankNum, - WaterConnections(WaterConnNum).TankSupplyID); + if (!DataIPShortCuts::lAlphaFieldBlanks(5)) { + WaterManager::SetupTankSupplyComponent(WaterConnections(WaterConnNum).Name, + DataIPShortCuts::cCurrentModuleObject, + DataIPShortCuts::cAlphaArgs(5), + ErrorsFound, + WaterConnections(WaterConnNum).RecoveryTankNum, + WaterConnections(WaterConnNum).TankSupplyID); } - if (!lAlphaFieldBlanks(6)) { - WaterConnections(WaterConnNum).HotTempSchedule = GetScheduleIndex(cAlphaArgs(6)); + if (!DataIPShortCuts::lAlphaFieldBlanks(6)) { + WaterConnections(WaterConnNum).HotTempSchedule = ScheduleManager::GetScheduleIndex(DataIPShortCuts::cAlphaArgs(6)); // If no HotTempSchedule, there is no hot water. // HotTempSchedule is ignored if connected to a plant loop via WATER USE CONNECTIONS if (WaterConnections(WaterConnNum).HotTempSchedule == 0) { - ShowSevereError("Invalid " + cAlphaFieldNames(6) + '=' + cAlphaArgs(6)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + cAlphaArgs(1)); + ShowSevereError("Invalid " + DataIPShortCuts::cAlphaFieldNames(6) + '=' + DataIPShortCuts::cAlphaArgs(6)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + DataIPShortCuts::cAlphaArgs(1)); ErrorsFound = true; } } - if (!lAlphaFieldBlanks(7)) { - WaterConnections(WaterConnNum).ColdTempSchedule = GetScheduleIndex(cAlphaArgs(7)); + if (!DataIPShortCuts::lAlphaFieldBlanks(7)) { + WaterConnections(WaterConnNum).ColdTempSchedule = ScheduleManager::GetScheduleIndex(DataIPShortCuts::cAlphaArgs(7)); // If no ColdTempSchedule, temperatures will be calculated by WATER MAINS TEMPERATURES object if (WaterConnections(WaterConnNum).ColdTempSchedule == 0) { - ShowSevereError("Invalid " + cAlphaFieldNames(7) + '=' + cAlphaArgs(7)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + cAlphaArgs(1)); + ShowSevereError("Invalid " + DataIPShortCuts::cAlphaFieldNames(7) + '=' + DataIPShortCuts::cAlphaArgs(7)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + DataIPShortCuts::cAlphaArgs(1)); ErrorsFound = true; } } - if ((!lAlphaFieldBlanks(8)) && (cAlphaArgs(8) != "NONE")) { + if ((!DataIPShortCuts::lAlphaFieldBlanks(8)) && (DataIPShortCuts::cAlphaArgs(8) != "NONE")) { WaterConnections(WaterConnNum).HeatRecovery = true; { - auto const SELECT_CASE_var(cAlphaArgs(8)); + auto const SELECT_CASE_var(DataIPShortCuts::cAlphaArgs(8)); if (SELECT_CASE_var == "IDEAL") { - WaterConnections(WaterConnNum).HeatRecoveryHX = HeatRecoveryHXIdeal; + WaterConnections(WaterConnNum).HeatRecoveryHX = HeatRecoveryHXEnum::Ideal; } else if (SELECT_CASE_var == "COUNTERFLOW") { - WaterConnections(WaterConnNum).HeatRecoveryHX = HeatRecoveryHXCounterFlow; + WaterConnections(WaterConnNum).HeatRecoveryHX = HeatRecoveryHXEnum::CounterFlow; } else if (SELECT_CASE_var == "CROSSFLOW") { - WaterConnections(WaterConnNum).HeatRecoveryHX = HeatRecoveryHXCrossFlow; + WaterConnections(WaterConnNum).HeatRecoveryHX = HeatRecoveryHXEnum::CrossFlow; } else { - ShowSevereError("Invalid " + cAlphaFieldNames(8) + '=' + cAlphaArgs(8)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + cAlphaArgs(1)); + ShowSevereError("Invalid " + DataIPShortCuts::cAlphaFieldNames(8) + '=' + DataIPShortCuts::cAlphaArgs(8)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + DataIPShortCuts::cAlphaArgs(1)); ErrorsFound = true; } } { - auto const SELECT_CASE_var(cAlphaArgs(9)); + auto const SELECT_CASE_var(DataIPShortCuts::cAlphaArgs(9)); if (SELECT_CASE_var == "PLANT") { - WaterConnections(WaterConnNum).HeatRecoveryConfig = HeatRecoveryConfigPlant; + WaterConnections(WaterConnNum).HeatRecoveryConfig = HeatRecoveryConfigEnum::Plant; } else if (SELECT_CASE_var == "EQUIPMENT") { - WaterConnections(WaterConnNum).HeatRecoveryConfig = HeatRecoveryConfigEquipment; + WaterConnections(WaterConnNum).HeatRecoveryConfig = HeatRecoveryConfigEnum::Equipment; } else if (SELECT_CASE_var == "PLANTANDEQUIPMENT") { - WaterConnections(WaterConnNum).HeatRecoveryConfig = HeatRecoveryConfigPlantAndEquip; + WaterConnections(WaterConnNum).HeatRecoveryConfig = HeatRecoveryConfigEnum::PlantAndEquip; } else { - ShowSevereError("Invalid " + cAlphaFieldNames(9) + '=' + cAlphaArgs(9)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + cAlphaArgs(1)); + ShowSevereError("Invalid " + DataIPShortCuts::cAlphaFieldNames(9) + '=' + DataIPShortCuts::cAlphaArgs(9)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + DataIPShortCuts::cAlphaArgs(1)); ErrorsFound = true; } } } - WaterConnections(WaterConnNum).HXUA = rNumericArgs(1); + WaterConnections(WaterConnNum).HXUA = DataIPShortCuts::rNumericArgs(1); - WaterConnections(WaterConnNum).WaterEquipment.allocate(NumAlphas - 9); + WaterConnections(WaterConnNum).myWaterEquipArr.allocate(NumAlphas - 9); for (AlphaNum = 10; AlphaNum <= NumAlphas; ++AlphaNum) { - WaterEquipNum = UtilityRoutines::FindItemInList(cAlphaArgs(AlphaNum), WaterEquipment); + int WaterEquipNum = UtilityRoutines::FindItemInList(DataIPShortCuts::cAlphaArgs(AlphaNum), WaterEquipment); if (WaterEquipNum == 0) { - ShowSevereError("Invalid " + cAlphaFieldNames(AlphaNum) + '=' + cAlphaArgs(AlphaNum)); - ShowContinueError("Entered in " + cCurrentModuleObject + '=' + cAlphaArgs(1)); + ShowSevereError("Invalid " + DataIPShortCuts::cAlphaFieldNames(AlphaNum) + '=' + DataIPShortCuts::cAlphaArgs(AlphaNum)); + ShowContinueError("Entered in " + DataIPShortCuts::cCurrentModuleObject + '=' + DataIPShortCuts::cAlphaArgs(1)); ErrorsFound = true; } else { if (WaterEquipment(WaterEquipNum).Connections > 0) { - ShowSevereError(cCurrentModuleObject + " = " + cAlphaArgs(1) + ": WaterUse:Equipment = " + cAlphaArgs(AlphaNum) + + ShowSevereError(DataIPShortCuts::cCurrentModuleObject + " = " + DataIPShortCuts::cAlphaArgs(1) + + ": WaterUse:Equipment = " + DataIPShortCuts::cAlphaArgs(AlphaNum) + " is already referenced by another object."); ErrorsFound = true; } else { WaterEquipment(WaterEquipNum).Connections = WaterConnNum; ++WaterConnections(WaterConnNum).NumWaterEquipment; - WaterConnections(WaterConnNum).WaterEquipment(WaterConnections(WaterConnNum).NumWaterEquipment) = WaterEquipNum; + WaterConnections(WaterConnNum).myWaterEquipArr(WaterConnections(WaterConnNum).NumWaterEquipment) = WaterEquipNum; WaterConnections(WaterConnNum).PeakVolFlowRate += WaterEquipment(WaterEquipNum).PeakVolFlowRate; // this does not include possible multipliers @@ -649,419 +566,257 @@ namespace WaterUse { } // WaterConnNum - if (ErrorsFound) ShowFatalError("Errors found in processing input for " + cCurrentModuleObject); + if (ErrorsFound) ShowFatalError("Errors found in processing input for " + DataIPShortCuts::cCurrentModuleObject); - if (NumWaterConnections > 0) { - CheckEquipName.allocate(NumWaterConnections); - CheckPlantLoop.allocate(NumWaterConnections); + if (numWaterConnections > 0) { + CheckEquipName.allocate(numWaterConnections); CheckEquipName = true; - CheckPlantLoop = true; } } // determine connection's peak mass flow rates. - if (NumWaterConnections > 0) { - for (WaterConnNum = 1; WaterConnNum <= NumWaterConnections; ++WaterConnNum) { + if (numWaterConnections > 0) { + for (int WaterConnNum = 1; WaterConnNum <= numWaterConnections; ++WaterConnNum) { WaterConnections(WaterConnNum).PeakMassFlowRate = 0.0; - for (WaterEquipNum = 1; WaterEquipNum <= WaterConnections(WaterConnNum).NumWaterEquipment; ++WaterEquipNum) { - thisWaterEquipNum = WaterConnections(WaterConnNum).WaterEquipment(WaterEquipNum); + for (int WaterEquipNum = 1; WaterEquipNum <= WaterConnections(WaterConnNum).NumWaterEquipment; ++WaterEquipNum) { + int thisWaterEquipNum = WaterConnections(WaterConnNum).myWaterEquipArr(WaterEquipNum); if (WaterEquipment(thisWaterEquipNum).Zone > 0) { WaterConnections(WaterConnNum).PeakMassFlowRate += - WaterEquipment(thisWaterEquipNum).PeakVolFlowRate * RhoH2O(DataGlobals::InitConvTemp) * - Zone(WaterEquipment(thisWaterEquipNum).Zone).Multiplier * Zone(WaterEquipment(thisWaterEquipNum).Zone).ListMultiplier; + WaterEquipment(thisWaterEquipNum).PeakVolFlowRate * Psychrometrics::RhoH2O(DataGlobals::InitConvTemp) * + DataHeatBalance::Zone(WaterEquipment(thisWaterEquipNum).Zone).Multiplier * + DataHeatBalance::Zone(WaterEquipment(thisWaterEquipNum).Zone).ListMultiplier; } else { // can't have multipliers WaterConnections(WaterConnNum).PeakMassFlowRate += - WaterEquipment(thisWaterEquipNum).PeakVolFlowRate * RhoH2O(DataGlobals::InitConvTemp); + WaterEquipment(thisWaterEquipNum).PeakVolFlowRate * Psychrometrics::RhoH2O(DataGlobals::InitConvTemp); } } - RegisterPlantCompDesignFlow(WaterConnections(WaterConnNum).InletNode, - WaterConnections(WaterConnNum).PeakMassFlowRate / RhoH2O(DataGlobals::InitConvTemp)); + PlantUtilities::RegisterPlantCompDesignFlow(WaterConnections(WaterConnNum).InletNode, + WaterConnections(WaterConnNum).PeakMassFlowRate / + Psychrometrics::RhoH2O(DataGlobals::InitConvTemp)); } } + } - // Setup EQUIPMENT report variables (now that connections have been established) - // CurrentModuleObject='WaterUse:Equipment' - for (WaterEquipNum = 1; WaterEquipNum <= NumWaterEquipment; ++WaterEquipNum) { + void WaterEquipmentType::setupOutputVars() + { + SetupOutputVariable( + "Water Use Equipment Hot Water Mass Flow Rate", OutputProcessor::Unit::kg_s, this->HotMassFlowRate, "System", "Average", this->Name); - SetupOutputVariable("Water Use Equipment Hot Water Mass Flow Rate", - OutputProcessor::Unit::kg_s, - WaterEquipment(WaterEquipNum).HotMassFlowRate, - "System", - "Average", - WaterEquipment(WaterEquipNum).Name); + SetupOutputVariable( + "Water Use Equipment Cold Water Mass Flow Rate", OutputProcessor::Unit::kg_s, this->ColdMassFlowRate, "System", "Average", this->Name); - SetupOutputVariable("Water Use Equipment Cold Water Mass Flow Rate", - OutputProcessor::Unit::kg_s, - WaterEquipment(WaterEquipNum).ColdMassFlowRate, - "System", - "Average", - WaterEquipment(WaterEquipNum).Name); + SetupOutputVariable( + "Water Use Equipment Total Mass Flow Rate", OutputProcessor::Unit::kg_s, this->TotalMassFlowRate, "System", "Average", this->Name); - SetupOutputVariable("Water Use Equipment Total Mass Flow Rate", - OutputProcessor::Unit::kg_s, - WaterEquipment(WaterEquipNum).TotalMassFlowRate, - "System", - "Average", - WaterEquipment(WaterEquipNum).Name); + SetupOutputVariable( + "Water Use Equipment Hot Water Volume Flow Rate", OutputProcessor::Unit::m3_s, this->HotVolFlowRate, "System", "Average", this->Name); - SetupOutputVariable("Water Use Equipment Hot Water Volume Flow Rate", - OutputProcessor::Unit::m3_s, - WaterEquipment(WaterEquipNum).HotVolFlowRate, - "System", - "Average", - WaterEquipment(WaterEquipNum).Name); + SetupOutputVariable( + "Water Use Equipment Cold Water Volume Flow Rate", OutputProcessor::Unit::m3_s, this->ColdVolFlowRate, "System", "Average", this->Name); - SetupOutputVariable("Water Use Equipment Cold Water Volume Flow Rate", - OutputProcessor::Unit::m3_s, - WaterEquipment(WaterEquipNum).ColdVolFlowRate, - "System", - "Average", - WaterEquipment(WaterEquipNum).Name); + SetupOutputVariable( + "Water Use Equipment Total Volume Flow Rate", OutputProcessor::Unit::m3_s, this->TotalVolFlowRate, "System", "Average", this->Name); - SetupOutputVariable("Water Use Equipment Total Volume Flow Rate", - OutputProcessor::Unit::m3_s, - WaterEquipment(WaterEquipNum).TotalVolFlowRate, - "System", - "Average", - WaterEquipment(WaterEquipNum).Name); + SetupOutputVariable("Water Use Equipment Hot Water Volume", OutputProcessor::Unit::m3, this->HotVolume, "System", "Sum", this->Name); - SetupOutputVariable("Water Use Equipment Hot Water Volume", - OutputProcessor::Unit::m3, - WaterEquipment(WaterEquipNum).HotVolume, - "System", - "Sum", - WaterEquipment(WaterEquipNum).Name); + SetupOutputVariable("Water Use Equipment Cold Water Volume", OutputProcessor::Unit::m3, this->ColdVolume, "System", "Sum", this->Name); - SetupOutputVariable("Water Use Equipment Cold Water Volume", - OutputProcessor::Unit::m3, - WaterEquipment(WaterEquipNum).ColdVolume, - "System", - "Sum", - WaterEquipment(WaterEquipNum).Name); + SetupOutputVariable("Water Use Equipment Total Volume", + OutputProcessor::Unit::m3, + this->TotalVolume, + "System", + "Sum", + this->Name, + _, + "Water", + "WATERSYSTEMS", + this->EndUseSubcatName, + "Plant"); + SetupOutputVariable("Water Use Equipment Mains Water Volume", + OutputProcessor::Unit::m3, + this->TotalVolume, + "System", + "Sum", + this->Name, + _, + "MainsWater", + "WATERSYSTEMS", + this->EndUseSubcatName, + "Plant"); + + SetupOutputVariable("Water Use Equipment Hot Water Temperature", OutputProcessor::Unit::C, this->HotTemp, "System", "Average", this->Name); - SetupOutputVariable("Water Use Equipment Total Volume", - OutputProcessor::Unit::m3, - WaterEquipment(WaterEquipNum).TotalVolume, + SetupOutputVariable("Water Use Equipment Cold Water Temperature", OutputProcessor::Unit::C, this->ColdTemp, "System", "Average", this->Name); + + SetupOutputVariable( + "Water Use Equipment Target Water Temperature", OutputProcessor::Unit::C, this->TargetTemp, "System", "Average", this->Name); + + SetupOutputVariable( + "Water Use Equipment Mixed Water Temperature", OutputProcessor::Unit::C, this->MixedTemp, "System", "Average", this->Name); + + SetupOutputVariable( + "Water Use Equipment Drain Water Temperature", OutputProcessor::Unit::C, this->DrainTemp, "System", "Average", this->Name); + + SetupOutputVariable("Water Use Equipment Heating Rate", OutputProcessor::Unit::W, this->Power, "System", "Average", this->Name); + + if (this->Connections == 0) { + SetupOutputVariable("Water Use Equipment Heating Energy", + OutputProcessor::Unit::J, + this->Energy, "System", "Sum", - WaterEquipment(WaterEquipNum).Name, + this->Name, _, - "Water", + "DISTRICTHEATING", "WATERSYSTEMS", - WaterEquipment(WaterEquipNum).EndUseSubcatName, + this->EndUseSubcatName, "Plant"); - SetupOutputVariable("Water Use Equipment Mains Water Volume", - OutputProcessor::Unit::m3, - WaterEquipment(WaterEquipNum).TotalVolume, + + } else if (WaterConnections(this->Connections).StandAlone) { + SetupOutputVariable("Water Use Equipment Heating Energy", + OutputProcessor::Unit::J, + this->Energy, "System", "Sum", - WaterEquipment(WaterEquipNum).Name, + this->Name, _, - "MainsWater", + "DISTRICTHEATING", "WATERSYSTEMS", - WaterEquipment(WaterEquipNum).EndUseSubcatName, + this->EndUseSubcatName, "Plant"); - SetupOutputVariable("Water Use Equipment Hot Water Temperature", - OutputProcessor::Unit::C, - WaterEquipment(WaterEquipNum).HotTemp, - "System", - "Average", - WaterEquipment(WaterEquipNum).Name); - - SetupOutputVariable("Water Use Equipment Cold Water Temperature", - OutputProcessor::Unit::C, - WaterEquipment(WaterEquipNum).ColdTemp, - "System", - "Average", - WaterEquipment(WaterEquipNum).Name); - - SetupOutputVariable("Water Use Equipment Target Water Temperature", - OutputProcessor::Unit::C, - WaterEquipment(WaterEquipNum).TargetTemp, + } else { // The EQUIPMENT is coupled to a plant loop via a CONNECTIONS object + SetupOutputVariable("Water Use Equipment Heating Energy", + OutputProcessor::Unit::J, + this->Energy, "System", - "Average", - WaterEquipment(WaterEquipNum).Name); + "Sum", + this->Name, + _, + "ENERGYTRANSFER", + "WATERSYSTEMS", + this->EndUseSubcatName, + "Plant"); + } - SetupOutputVariable("Water Use Equipment Mixed Water Temperature", - OutputProcessor::Unit::C, - WaterEquipment(WaterEquipNum).MixedTemp, - "System", - "Average", - WaterEquipment(WaterEquipNum).Name); + if (this->Zone > 0) { + SetupOutputVariable( + "Water Use Equipment Zone Sensible Heat Gain Rate", OutputProcessor::Unit::W, this->SensibleRate, "System", "Average", this->Name); + SetupOutputVariable( + "Water Use Equipment Zone Sensible Heat Gain Energy", OutputProcessor::Unit::J, this->SensibleEnergy, "System", "Sum", this->Name); - SetupOutputVariable("Water Use Equipment Drain Water Temperature", - OutputProcessor::Unit::C, - WaterEquipment(WaterEquipNum).DrainTemp, - "System", - "Average", - WaterEquipment(WaterEquipNum).Name); + SetupOutputVariable( + "Water Use Equipment Zone Latent Gain Rate", OutputProcessor::Unit::W, this->LatentRate, "System", "Average", this->Name); + SetupOutputVariable( + "Water Use Equipment Zone Latent Gain Energy", OutputProcessor::Unit::J, this->LatentEnergy, "System", "Sum", this->Name); - SetupOutputVariable("Water Use Equipment Heating Rate", - OutputProcessor::Unit::W, - WaterEquipment(WaterEquipNum).Power, + SetupOutputVariable("Water Use Equipment Zone Moisture Gain Mass Flow Rate", + OutputProcessor::Unit::kg_s, + this->MoistureRate, "System", "Average", - WaterEquipment(WaterEquipNum).Name); - - if (WaterEquipment(WaterEquipNum).Connections == 0) { - SetupOutputVariable("Water Use Equipment Heating Energy", - OutputProcessor::Unit::J, - WaterEquipment(WaterEquipNum).Energy, - "System", - "Sum", - WaterEquipment(WaterEquipNum).Name, - _, - "DISTRICTHEATING", - "WATERSYSTEMS", - WaterEquipment(WaterEquipNum).EndUseSubcatName, - "Plant"); - - } else if (WaterConnections(WaterEquipment(WaterEquipNum).Connections).StandAlone) { - SetupOutputVariable("Water Use Equipment Heating Energy", - OutputProcessor::Unit::J, - WaterEquipment(WaterEquipNum).Energy, - "System", - "Sum", - WaterEquipment(WaterEquipNum).Name, - _, - "DISTRICTHEATING", - "WATERSYSTEMS", - WaterEquipment(WaterEquipNum).EndUseSubcatName, - "Plant"); - - } else { // The EQUIPMENT is coupled to a plant loop via a CONNECTIONS object - SetupOutputVariable("Water Use Equipment Heating Energy", - OutputProcessor::Unit::J, - WaterEquipment(WaterEquipNum).Energy, - "System", - "Sum", - WaterEquipment(WaterEquipNum).Name, - _, - "ENERGYTRANSFER", - "WATERSYSTEMS", - WaterEquipment(WaterEquipNum).EndUseSubcatName, - "Plant"); - } - - if (WaterEquipment(WaterEquipNum).Zone > 0) { - SetupOutputVariable("Water Use Equipment Zone Sensible Heat Gain Rate", - OutputProcessor::Unit::W, - WaterEquipment(WaterEquipNum).SensibleRate, - "System", - "Average", - WaterEquipment(WaterEquipNum).Name); - SetupOutputVariable("Water Use Equipment Zone Sensible Heat Gain Energy", - OutputProcessor::Unit::J, - WaterEquipment(WaterEquipNum).SensibleEnergy, - "System", - "Sum", - WaterEquipment(WaterEquipNum).Name); - - SetupOutputVariable("Water Use Equipment Zone Latent Gain Rate", - OutputProcessor::Unit::W, - WaterEquipment(WaterEquipNum).LatentRate, - "System", - "Average", - WaterEquipment(WaterEquipNum).Name); - SetupOutputVariable("Water Use Equipment Zone Latent Gain Energy", - OutputProcessor::Unit::J, - WaterEquipment(WaterEquipNum).LatentEnergy, - "System", - "Sum", - WaterEquipment(WaterEquipNum).Name); - - SetupOutputVariable("Water Use Equipment Zone Moisture Gain Mass Flow Rate", - OutputProcessor::Unit::kg_s, - WaterEquipment(WaterEquipNum).MoistureRate, - "System", - "Average", - WaterEquipment(WaterEquipNum).Name); - SetupOutputVariable("Water Use Equipment Zone Moisture Gain Mass", - OutputProcessor::Unit::kg, - WaterEquipment(WaterEquipNum).MoistureMass, - "System", - "Sum", - WaterEquipment(WaterEquipNum).Name); - - SetupZoneInternalGain(WaterEquipment(WaterEquipNum).Zone, - "WaterUse:Equipment", - WaterEquipment(WaterEquipNum).Name, - IntGainTypeOf_WaterUseEquipment, - WaterEquipment(WaterEquipNum).SensibleRateNoMultiplier, - _, - _, - WaterEquipment(WaterEquipNum).LatentRateNoMultiplier); - } + this->Name); + SetupOutputVariable( + "Water Use Equipment Zone Moisture Gain Mass", OutputProcessor::Unit::kg, this->MoistureMass, "System", "Sum", this->Name); + + SetupZoneInternalGain(this->Zone, + "WaterUse:Equipment", + this->Name, + DataHeatBalance::IntGainTypeOf_WaterUseEquipment, + this->SensibleRateNoMultiplier, + _, + _, + this->LatentRateNoMultiplier); + } + } - } // WaterEquipNum + void WaterConnectionsType::setupOutputVars() + { + SetupOutputVariable( + "Water Use Connections Hot Water Mass Flow Rate", OutputProcessor::Unit::kg_s, this->HotMassFlowRate, "System", "Average", this->Name); - // Setup CONNECTIONS report variables (don't put any on meters; they are metered at WATER USE EQUIPMENT level) - // CurrentModuleObject='WaterUse:Connections' - for (WaterConnNum = 1; WaterConnNum <= NumWaterConnections; ++WaterConnNum) { + SetupOutputVariable( + "Water Use Connections Cold Water Mass Flow Rate", OutputProcessor::Unit::kg_s, this->ColdMassFlowRate, "System", "Average", this->Name); - SetupOutputVariable("Water Use Connections Hot Water Mass Flow Rate", - OutputProcessor::Unit::kg_s, - WaterConnections(WaterConnNum).HotMassFlowRate, - "System", - "Average", - WaterConnections(WaterConnNum).Name); + SetupOutputVariable( + "Water Use Connections Total Mass Flow Rate", OutputProcessor::Unit::kg_s, this->TotalMassFlowRate, "System", "Average", this->Name); - SetupOutputVariable("Water Use Connections Cold Water Mass Flow Rate", - OutputProcessor::Unit::kg_s, - WaterConnections(WaterConnNum).ColdMassFlowRate, - "System", - "Average", - WaterConnections(WaterConnNum).Name); + SetupOutputVariable("Water Use Connections Drain Water Mass Flow Rate", + OutputProcessor::Unit::kg_s, + this->DrainMassFlowRate, + "System", + "Average", + this->Name); - SetupOutputVariable("Water Use Connections Total Mass Flow Rate", - OutputProcessor::Unit::kg_s, - WaterConnections(WaterConnNum).TotalMassFlowRate, - "System", - "Average", - WaterConnections(WaterConnNum).Name); + SetupOutputVariable("Water Use Connections Heat Recovery Mass Flow Rate", + OutputProcessor::Unit::kg_s, + this->RecoveryMassFlowRate, + "System", + "Average", + this->Name); - SetupOutputVariable("Water Use Connections Drain Water Mass Flow Rate", - OutputProcessor::Unit::kg_s, - WaterConnections(WaterConnNum).DrainMassFlowRate, - "System", - "Average", - WaterConnections(WaterConnNum).Name); + SetupOutputVariable( + "Water Use Connections Hot Water Volume Flow Rate", OutputProcessor::Unit::m3_s, this->HotVolFlowRate, "System", "Average", this->Name); - SetupOutputVariable("Water Use Connections Heat Recovery Mass Flow Rate", - OutputProcessor::Unit::kg_s, - WaterConnections(WaterConnNum).RecoveryMassFlowRate, - "System", - "Average", - WaterConnections(WaterConnNum).Name); + SetupOutputVariable( + "Water Use Connections Cold Water Volume Flow Rate", OutputProcessor::Unit::m3_s, this->ColdVolFlowRate, "System", "Average", this->Name); - SetupOutputVariable("Water Use Connections Hot Water Volume Flow Rate", - OutputProcessor::Unit::m3_s, - WaterConnections(WaterConnNum).HotVolFlowRate, - "System", - "Average", - WaterConnections(WaterConnNum).Name); + SetupOutputVariable( + "Water Use Connections Total Volume Flow Rate", OutputProcessor::Unit::m3_s, this->TotalVolFlowRate, "System", "Average", this->Name); - SetupOutputVariable("Water Use Connections Cold Water Volume Flow Rate", - OutputProcessor::Unit::m3_s, - WaterConnections(WaterConnNum).ColdVolFlowRate, - "System", - "Average", - WaterConnections(WaterConnNum).Name); + SetupOutputVariable("Water Use Connections Hot Water Volume", OutputProcessor::Unit::m3, this->HotVolume, "System", "Sum", this->Name); - SetupOutputVariable("Water Use Connections Total Volume Flow Rate", - OutputProcessor::Unit::m3_s, - WaterConnections(WaterConnNum).TotalVolFlowRate, - "System", - "Average", - WaterConnections(WaterConnNum).Name); + SetupOutputVariable("Water Use Connections Cold Water Volume", OutputProcessor::Unit::m3, this->ColdVolume, "System", "Sum", this->Name); - SetupOutputVariable("Water Use Connections Hot Water Volume", - OutputProcessor::Unit::m3, - WaterConnections(WaterConnNum).HotVolume, - "System", - "Sum", - WaterConnections(WaterConnNum).Name); + SetupOutputVariable("Water Use Connections Total Volume", OutputProcessor::Unit::m3, this->TotalVolume, "System", "Sum", + this->Name); //, & + // ResourceTypeKey='Water', EndUseKey='DHW', EndUseSubKey=EndUseSubcategoryName, GroupKey='Plant') + // tHIS WAS double counting - SetupOutputVariable("Water Use Connections Cold Water Volume", - OutputProcessor::Unit::m3, - WaterConnections(WaterConnNum).ColdVolume, - "System", - "Sum", - WaterConnections(WaterConnNum).Name); + SetupOutputVariable("Water Use Connections Hot Water Temperature", OutputProcessor::Unit::C, this->HotTemp, "System", "Average", this->Name); - SetupOutputVariable("Water Use Connections Total Volume", - OutputProcessor::Unit::m3, - WaterConnections(WaterConnNum).TotalVolume, - "System", - "Sum", - WaterConnections(WaterConnNum).Name); //, & - // ResourceTypeKey='Water', EndUseKey='DHW', EndUseSubKey=EndUseSubcategoryName, GroupKey='Plant') - // tHIS WAS double counting + SetupOutputVariable( + "Water Use Connections Cold Water Temperature", OutputProcessor::Unit::C, this->ColdTemp, "System", "Average", this->Name); - SetupOutputVariable("Water Use Connections Hot Water Temperature", - OutputProcessor::Unit::C, - WaterConnections(WaterConnNum).HotTemp, - "System", - "Average", - WaterConnections(WaterConnNum).Name); + SetupOutputVariable( + "Water Use Connections Drain Water Temperature", OutputProcessor::Unit::C, this->DrainTemp, "System", "Average", this->Name); - SetupOutputVariable("Water Use Connections Cold Water Temperature", - OutputProcessor::Unit::C, - WaterConnections(WaterConnNum).ColdTemp, - "System", - "Average", - WaterConnections(WaterConnNum).Name); + SetupOutputVariable( + "Water Use Connections Return Water Temperature", OutputProcessor::Unit::C, this->ReturnTemp, "System", "Average", this->Name); - SetupOutputVariable("Water Use Connections Drain Water Temperature", - OutputProcessor::Unit::C, - WaterConnections(WaterConnNum).DrainTemp, - "System", - "Average", - WaterConnections(WaterConnNum).Name); + SetupOutputVariable( + "Water Use Connections Waste Water Temperature", OutputProcessor::Unit::C, this->WasteTemp, "System", "Average", this->Name); - SetupOutputVariable("Water Use Connections Return Water Temperature", - OutputProcessor::Unit::C, - WaterConnections(WaterConnNum).ReturnTemp, - "System", - "Average", - WaterConnections(WaterConnNum).Name); + SetupOutputVariable( + "Water Use Connections Heat Recovery Water Temperature", OutputProcessor::Unit::C, this->RecoveryTemp, "System", "Average", this->Name); - SetupOutputVariable("Water Use Connections Waste Water Temperature", - OutputProcessor::Unit::C, - WaterConnections(WaterConnNum).WasteTemp, - "System", - "Average", - WaterConnections(WaterConnNum).Name); + SetupOutputVariable( + "Water Use Connections Heat Recovery Effectiveness", OutputProcessor::Unit::None, this->Effectiveness, "System", "Average", this->Name); - SetupOutputVariable("Water Use Connections Heat Recovery Water Temperature", - OutputProcessor::Unit::C, - WaterConnections(WaterConnNum).RecoveryTemp, - "System", - "Average", - WaterConnections(WaterConnNum).Name); + SetupOutputVariable( + "Water Use Connections Heat Recovery Rate", OutputProcessor::Unit::W, this->RecoveryRate, "System", "Average", this->Name); + SetupOutputVariable( + "Water Use Connections Heat Recovery Energy", OutputProcessor::Unit::J, this->RecoveryEnergy, "System", "Sum", this->Name); + // Does this go on a meter? - SetupOutputVariable("Water Use Connections Heat Recovery Effectiveness", - OutputProcessor::Unit::None, - WaterConnections(WaterConnNum).Effectiveness, - "System", - "Average", - WaterConnections(WaterConnNum).Name); + // To do: Add report variable for starved flow when tank can't deliver? - SetupOutputVariable("Water Use Connections Heat Recovery Rate", - OutputProcessor::Unit::W, - WaterConnections(WaterConnNum).RecoveryRate, - "System", - "Average", - WaterConnections(WaterConnNum).Name); - SetupOutputVariable("Water Use Connections Heat Recovery Energy", + if (!this->StandAlone) { + SetupOutputVariable("Water Use Connections Plant Hot Water Energy", OutputProcessor::Unit::J, - WaterConnections(WaterConnNum).RecoveryEnergy, + this->Energy, "System", "Sum", - WaterConnections(WaterConnNum).Name); - // Does this go on a meter? - - // To do: Add report variable for starved flow when tank can't deliver? - - if (!WaterConnections(WaterConnNum).StandAlone) { - SetupOutputVariable("Water Use Connections Plant Hot Water Energy", - OutputProcessor::Unit::J, - WaterConnections(WaterConnNum).Energy, - "System", - "Sum", - WaterConnections(WaterConnNum).Name, - _, - "PLANTLOOPHEATINGDEMAND", - "WATERSYSTEMS", - _, - "Plant"); - } - - } // WaterConnNum + this->Name, + _, + "PLANTLOOPHEATINGDEMAND", + "WATERSYSTEMS", + _, + "Plant"); + } } - void CalcEquipmentFlowRates(int const WaterEquipNum) + void WaterEquipmentType::CalcEquipmentFlowRates() { // SUBROUTINE INFORMATION: @@ -1073,111 +828,90 @@ namespace WaterUse { // PURPOSE OF THIS SUBROUTINE: // Calculate desired hot and cold water flow rates - // METHODOLOGY EMPLOYED: - - // Using/Aliasing - using DataEnvironment::WaterMainsTemp; - using DataHeatBalance::Zone; - using Psychrometrics::RhoH2O; - using ScheduleManager::GetCurrentScheduleValue; - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int WaterConnNum; - - // FLOW: - WaterConnNum = WaterEquipment(WaterEquipNum).Connections; + if (this->setupMyOutputVars) { + this->setupOutputVars(); + this->setupMyOutputVars = false; + } - if (WaterConnNum > 0) { + if (this->Connections > 0) { // Get water temperature conditions from the CONNECTIONS object - WaterEquipment(WaterEquipNum).ColdTemp = WaterConnections(WaterConnNum).ColdTemp; - WaterEquipment(WaterEquipNum).HotTemp = WaterConnections(WaterConnNum).HotTemp; + this->ColdTemp = WaterConnections(this->Connections).ColdTemp; + this->HotTemp = WaterConnections(this->Connections).HotTemp; } else { // Get water temperature conditions from the WATER USE EQUIPMENT schedules - if (WaterEquipment(WaterEquipNum).ColdTempSchedule > 0) { - WaterEquipment(WaterEquipNum).ColdTemp = GetCurrentScheduleValue(WaterEquipment(WaterEquipNum).ColdTempSchedule); + if (this->ColdTempSchedule > 0) { + this->ColdTemp = ScheduleManager::GetCurrentScheduleValue(this->ColdTempSchedule); } else { // If no ColdTempSchedule, use the mains temperature - WaterEquipment(WaterEquipNum).ColdTemp = WaterMainsTemp; + this->ColdTemp = DataEnvironment::WaterMainsTemp; } - if (WaterEquipment(WaterEquipNum).HotTempSchedule > 0) { - WaterEquipment(WaterEquipNum).HotTemp = GetCurrentScheduleValue(WaterEquipment(WaterEquipNum).HotTempSchedule); + if (this->HotTempSchedule > 0) { + this->HotTemp = ScheduleManager::GetCurrentScheduleValue(this->HotTempSchedule); } else { // If no HotTempSchedule, use all cold water - WaterEquipment(WaterEquipNum).HotTemp = WaterEquipment(WaterEquipNum).ColdTemp; + this->HotTemp = this->ColdTemp; } } - if (WaterEquipment(WaterEquipNum).TargetTempSchedule > 0) { - WaterEquipment(WaterEquipNum).TargetTemp = GetCurrentScheduleValue(WaterEquipment(WaterEquipNum).TargetTempSchedule); + if (this->TargetTempSchedule > 0) { + this->TargetTemp = ScheduleManager::GetCurrentScheduleValue(this->TargetTempSchedule); } else { // If no TargetTempSchedule, use all hot water - WaterEquipment(WaterEquipNum).TargetTemp = WaterEquipment(WaterEquipNum).HotTemp; + this->TargetTemp = this->HotTemp; } // Get the requested total flow rate - // 11-17-2006 BG Added multipliers in next block - if (WaterEquipment(WaterEquipNum).Zone > 0) { - if (WaterEquipment(WaterEquipNum).FlowRateFracSchedule > 0) { - WaterEquipment(WaterEquipNum).TotalVolFlowRate = - WaterEquipment(WaterEquipNum).PeakVolFlowRate * GetCurrentScheduleValue(WaterEquipment(WaterEquipNum).FlowRateFracSchedule) * - Zone(WaterEquipment(WaterEquipNum).Zone).Multiplier * Zone(WaterEquipment(WaterEquipNum).Zone).ListMultiplier; + if (this->Zone > 0) { + if (this->FlowRateFracSchedule > 0) { + this->TotalVolFlowRate = this->PeakVolFlowRate * ScheduleManager::GetCurrentScheduleValue(this->FlowRateFracSchedule) * + DataHeatBalance::Zone(this->Zone).Multiplier * DataHeatBalance::Zone(this->Zone).ListMultiplier; } else { - WaterEquipment(WaterEquipNum).TotalVolFlowRate = WaterEquipment(WaterEquipNum).PeakVolFlowRate * - Zone(WaterEquipment(WaterEquipNum).Zone).Multiplier * - Zone(WaterEquipment(WaterEquipNum).Zone).ListMultiplier; + this->TotalVolFlowRate = + this->PeakVolFlowRate * DataHeatBalance::Zone(this->Zone).Multiplier * DataHeatBalance::Zone(this->Zone).ListMultiplier; } } else { - if (WaterEquipment(WaterEquipNum).FlowRateFracSchedule > 0) { - WaterEquipment(WaterEquipNum).TotalVolFlowRate = - WaterEquipment(WaterEquipNum).PeakVolFlowRate * GetCurrentScheduleValue(WaterEquipment(WaterEquipNum).FlowRateFracSchedule); + if (this->FlowRateFracSchedule > 0) { + this->TotalVolFlowRate = this->PeakVolFlowRate * ScheduleManager::GetCurrentScheduleValue(this->FlowRateFracSchedule); } else { - WaterEquipment(WaterEquipNum).TotalVolFlowRate = WaterEquipment(WaterEquipNum).PeakVolFlowRate; + this->TotalVolFlowRate = this->PeakVolFlowRate; } } - WaterEquipment(WaterEquipNum).TotalMassFlowRate = WaterEquipment(WaterEquipNum).TotalVolFlowRate * RhoH2O(DataGlobals::InitConvTemp); + this->TotalMassFlowRate = this->TotalVolFlowRate * Psychrometrics::RhoH2O(DataGlobals::InitConvTemp); // Calculate hot and cold water mixing at the tap - if (WaterEquipment(WaterEquipNum).TotalMassFlowRate > 0.0) { + if (this->TotalMassFlowRate > 0.0) { // Calculate the flow rates needed to meet the target temperature - if (WaterEquipment(WaterEquipNum).HotTemp == WaterEquipment(WaterEquipNum).ColdTemp) { // Avoid divide by zero + if (this->HotTemp == this->ColdTemp) { // Avoid divide by zero // There is no hot water - WaterEquipment(WaterEquipNum).HotMassFlowRate = 0.0; + this->HotMassFlowRate = 0.0; // Need a special case for HotTemp < ColdTemp, due to bad user input (but could happen in a plant loop accidentally) - } else if (WaterEquipment(WaterEquipNum).TargetTemp > WaterEquipment(WaterEquipNum).HotTemp) { - WaterEquipment(WaterEquipNum).HotMassFlowRate = WaterEquipment(WaterEquipNum).TotalMassFlowRate; + } else if (this->TargetTemp > this->HotTemp) { + this->HotMassFlowRate = this->TotalMassFlowRate; } else { - WaterEquipment(WaterEquipNum).HotMassFlowRate = WaterEquipment(WaterEquipNum).TotalMassFlowRate * - (WaterEquipment(WaterEquipNum).TargetTemp - WaterEquipment(WaterEquipNum).ColdTemp) / - (WaterEquipment(WaterEquipNum).HotTemp - WaterEquipment(WaterEquipNum).ColdTemp); + this->HotMassFlowRate = this->TotalMassFlowRate * (this->TargetTemp - this->ColdTemp) / (this->HotTemp - this->ColdTemp); } - if (WaterEquipment(WaterEquipNum).HotMassFlowRate < 0.0) { + if (this->HotMassFlowRate < 0.0) { // Target temp is colder than the cold water temp; don't allow colder - WaterEquipment(WaterEquipNum).HotMassFlowRate = 0.0; + this->HotMassFlowRate = 0.0; } - WaterEquipment(WaterEquipNum).ColdMassFlowRate = - WaterEquipment(WaterEquipNum).TotalMassFlowRate - WaterEquipment(WaterEquipNum).HotMassFlowRate; + this->ColdMassFlowRate = this->TotalMassFlowRate - this->HotMassFlowRate; - if (WaterEquipment(WaterEquipNum).ColdMassFlowRate < 0.0) WaterEquipment(WaterEquipNum).ColdMassFlowRate = 0.0; + if (this->ColdMassFlowRate < 0.0) this->ColdMassFlowRate = 0.0; - WaterEquipment(WaterEquipNum).MixedTemp = (WaterEquipment(WaterEquipNum).ColdMassFlowRate * WaterEquipment(WaterEquipNum).ColdTemp + - WaterEquipment(WaterEquipNum).HotMassFlowRate * WaterEquipment(WaterEquipNum).HotTemp) / - WaterEquipment(WaterEquipNum).TotalMassFlowRate; + this->MixedTemp = (this->ColdMassFlowRate * this->ColdTemp + this->HotMassFlowRate * this->HotTemp) / this->TotalMassFlowRate; } else { - WaterEquipment(WaterEquipNum).HotMassFlowRate = 0.0; - WaterEquipment(WaterEquipNum).ColdMassFlowRate = 0.0; - WaterEquipment(WaterEquipNum).MixedTemp = WaterEquipment(WaterEquipNum).TargetTemp; + this->HotMassFlowRate = 0.0; + this->ColdMassFlowRate = 0.0; + this->MixedTemp = this->TargetTemp; } } - void CalcEquipmentDrainTemp(int const WaterEquipNum) + void WaterEquipmentType::CalcEquipmentDrainTemp() { // SUBROUTINE INFORMATION: @@ -1189,96 +923,61 @@ namespace WaterUse { // PURPOSE OF THIS SUBROUTINE: // Calculate drainwater temperature and heat and moisture gains to zone. - // METHODOLOGY EMPLOYED: - - // Using/Aliasing - using DataEnvironment::OutBaroPress; - using DataGlobals::SecInHour; - using DataHeatBalance::Zone; - using DataHeatBalFanSys::MAT; - using DataHeatBalFanSys::ZoneAirHumRat; - using DataHVACGlobals::TimeStepSys; - using Psychrometrics::CPHW; - using Psychrometrics::PsyHfgAirFnWTdb; - using Psychrometrics::PsyRhoAirFnPbTdbW; - using Psychrometrics::PsyWFnTdbRhPb; - using ScheduleManager::GetCurrentScheduleValue; - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int ZoneNum; - Real64 ZoneMAT; - Real64 ZoneHumRat; - Real64 ZoneHumRatSat; - Real64 RhoAirDry; - Real64 ZoneMassMax; - Real64 FlowMassMax; - Real64 MoistureMassMax; - static std::string const RoutineName("CalcEquipmentDrainTemp"); - // FLOW: - - WaterEquipment(WaterEquipNum).SensibleRate = 0.0; - WaterEquipment(WaterEquipNum).SensibleEnergy = 0.0; - WaterEquipment(WaterEquipNum).LatentRate = 0.0; - WaterEquipment(WaterEquipNum).LatentEnergy = 0.0; + this->SensibleRate = 0.0; + this->SensibleEnergy = 0.0; + this->LatentRate = 0.0; + this->LatentEnergy = 0.0; - if ((WaterEquipment(WaterEquipNum).Zone == 0) || (WaterEquipment(WaterEquipNum).TotalMassFlowRate == 0.0)) { - WaterEquipment(WaterEquipNum).DrainTemp = WaterEquipment(WaterEquipNum).MixedTemp; - WaterEquipment(WaterEquipNum).DrainMassFlowRate = WaterEquipment(WaterEquipNum).TotalMassFlowRate; + if ((this->Zone == 0) || (this->TotalMassFlowRate == 0.0)) { + this->DrainTemp = this->MixedTemp; + this->DrainMassFlowRate = this->TotalMassFlowRate; } else { - ZoneNum = WaterEquipment(WaterEquipNum).Zone; - ZoneMAT = MAT(ZoneNum); - if (WaterEquipment(WaterEquipNum).SensibleFracSchedule == 0) { - WaterEquipment(WaterEquipNum).SensibleRate = 0.0; - WaterEquipment(WaterEquipNum).SensibleEnergy = 0.0; + if (this->SensibleFracSchedule == 0) { + this->SensibleRate = 0.0; + this->SensibleEnergy = 0.0; } else { - WaterEquipment(WaterEquipNum).SensibleRate = GetCurrentScheduleValue(WaterEquipment(WaterEquipNum).SensibleFracSchedule) * - WaterEquipment(WaterEquipNum).TotalMassFlowRate * CPHW(DataGlobals::InitConvTemp) * - (WaterEquipment(WaterEquipNum).MixedTemp - ZoneMAT); - WaterEquipment(WaterEquipNum).SensibleEnergy = WaterEquipment(WaterEquipNum).SensibleRate * TimeStepSys * SecInHour; + this->SensibleRate = ScheduleManager::GetCurrentScheduleValue(this->SensibleFracSchedule) * this->TotalMassFlowRate * + Psychrometrics::CPHW(DataGlobals::InitConvTemp) * (this->MixedTemp - DataHeatBalFanSys::MAT(this->Zone)); + this->SensibleEnergy = this->SensibleRate * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; } - if (WaterEquipment(WaterEquipNum).LatentFracSchedule == 0) { - WaterEquipment(WaterEquipNum).LatentRate = 0.0; - WaterEquipment(WaterEquipNum).LatentEnergy = 0.0; + if (this->LatentFracSchedule == 0) { + this->LatentRate = 0.0; + this->LatentEnergy = 0.0; } else { - ZoneHumRat = ZoneAirHumRat(ZoneNum); - ZoneHumRatSat = PsyWFnTdbRhPb(ZoneMAT, 1.0, OutBaroPress, RoutineName); // Humidratio at 100% relative humidity - RhoAirDry = PsyRhoAirFnPbTdbW(OutBaroPress, ZoneMAT, 0.0); - - ZoneMassMax = (ZoneHumRatSat - ZoneHumRat) * RhoAirDry * Zone(ZoneNum).Volume; // Max water that can be evaporated to zone - FlowMassMax = WaterEquipment(WaterEquipNum).TotalMassFlowRate * TimeStepSys * SecInHour; // Max water in flow - MoistureMassMax = min(ZoneMassMax, FlowMassMax); - - WaterEquipment(WaterEquipNum).MoistureMass = - GetCurrentScheduleValue(WaterEquipment(WaterEquipNum).LatentFracSchedule) * MoistureMassMax; - WaterEquipment(WaterEquipNum).MoistureRate = WaterEquipment(WaterEquipNum).MoistureMass / (TimeStepSys * SecInHour); - - WaterEquipment(WaterEquipNum).LatentRate = WaterEquipment(WaterEquipNum).MoistureRate * PsyHfgAirFnWTdb(ZoneHumRat, ZoneMAT); - WaterEquipment(WaterEquipNum).LatentEnergy = WaterEquipment(WaterEquipNum).LatentRate * TimeStepSys * SecInHour; + Real64 ZoneHumRat = DataHeatBalFanSys::ZoneAirHumRat(this->Zone); + Real64 ZoneHumRatSat = Psychrometrics::PsyWFnTdbRhPb( + DataHeatBalFanSys::MAT(this->Zone), 1.0, DataEnvironment::OutBaroPress, RoutineName); // Humidratio at 100% relative humidity + Real64 RhoAirDry = Psychrometrics::PsyRhoAirFnPbTdbW(DataEnvironment::OutBaroPress, DataHeatBalFanSys::MAT(this->Zone), 0.0); + Real64 ZoneMassMax = + (ZoneHumRatSat - ZoneHumRat) * RhoAirDry * DataHeatBalance::Zone(this->Zone).Volume; // Max water that can be evaporated to zone + Real64 FlowMassMax = this->TotalMassFlowRate * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; // Max water in flow + Real64 MoistureMassMax = min(ZoneMassMax, FlowMassMax); + + this->MoistureMass = ScheduleManager::GetCurrentScheduleValue(this->LatentFracSchedule) * MoistureMassMax; + this->MoistureRate = this->MoistureMass / (DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour); + + this->LatentRate = this->MoistureRate * Psychrometrics::PsyHfgAirFnWTdb(ZoneHumRat, DataHeatBalFanSys::MAT(this->Zone)); + this->LatentEnergy = this->LatentRate * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; } - WaterEquipment(WaterEquipNum).DrainMassFlowRate = - WaterEquipment(WaterEquipNum).TotalMassFlowRate - WaterEquipment(WaterEquipNum).MoistureRate; + this->DrainMassFlowRate = this->TotalMassFlowRate - this->MoistureRate; - if (WaterEquipment(WaterEquipNum).DrainMassFlowRate == 0.0) { - WaterEquipment(WaterEquipNum).DrainTemp = WaterEquipment(WaterEquipNum).MixedTemp; + if (this->DrainMassFlowRate == 0.0) { + this->DrainTemp = this->MixedTemp; } else { - WaterEquipment(WaterEquipNum).DrainTemp = - (WaterEquipment(WaterEquipNum).TotalMassFlowRate * CPHW(DataGlobals::InitConvTemp) * WaterEquipment(WaterEquipNum).MixedTemp - - WaterEquipment(WaterEquipNum).SensibleRate - WaterEquipment(WaterEquipNum).LatentRate) / - (WaterEquipment(WaterEquipNum).DrainMassFlowRate * CPHW(DataGlobals::InitConvTemp)); + this->DrainTemp = (this->TotalMassFlowRate * Psychrometrics::CPHW(DataGlobals::InitConvTemp) * this->MixedTemp - this->SensibleRate - + this->LatentRate) / + (this->DrainMassFlowRate * Psychrometrics::CPHW(DataGlobals::InitConvTemp)); } } } - void InitConnections(int const WaterConnNum) + void WaterConnectionsType::InitConnections() { // SUBROUTINE INFORMATION: @@ -1287,120 +986,88 @@ namespace WaterUse { // MODIFIED Brent Griffith 2010, demand side update // RE-ENGINEERED na - // PURPOSE OF THIS SUBROUTINE: + if (this->setupMyOutputVars) { + this->setupOutputVars(); + this->setupMyOutputVars = false; + } - // METHODOLOGY EMPLOYED: - - // Using/Aliasing - using DataEnvironment::WaterMainsTemp; - using DataGlobals::DoingSizing; - using DataHeatBalance::Zone; - using DataLoopNode::Node; - using DataPlant::PlantLoop; - using DataPlant::TypeOf_WaterUseConnection; - using DataWater::WaterStorage; - using PlantUtilities::InitComponentNodes; - using PlantUtilities::ScanPlantLoopsForObject; - using ScheduleManager::GetCurrentScheduleValue; - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int InletNode; - int OutletNode; - static bool MyOneTimeFlag(true); // one time flag !DSU - static Array1D_bool SetLoopIndexFlag; // get loop number flag !DSU - bool errFlag; - - if (MyOneTimeFlag) { // DSU - SetLoopIndexFlag.dimension(NumWaterConnections, true); // DSU - MyOneTimeFlag = false; // DSU - } // DSU - - if (SetLoopIndexFlag(WaterConnNum)) { // DSU - if (allocated(PlantLoop) && !WaterConnections(WaterConnNum).StandAlone) { // DSU - errFlag = false; - ScanPlantLoopsForObject(WaterConnections(WaterConnNum).Name, - TypeOf_WaterUseConnection, - WaterConnections(WaterConnNum).PlantLoopNum, - WaterConnections(WaterConnNum).PlantLoopSide, - WaterConnections(WaterConnNum).PlantLoopBranchNum, - WaterConnections(WaterConnNum).PlantLoopCompNum, - errFlag, - _, - _, - _, - _, - _); // DSU | DSU | DSU | DSU | DSU | DSU | DSU - if (errFlag) { // DSU - ShowFatalError("InitConnections: Program terminated due to previous condition(s)."); // DSU - } // DSU - SetLoopIndexFlag(WaterConnNum) = false; // DSU - } // DSU - if (WaterConnections(WaterConnNum).StandAlone) SetLoopIndexFlag(WaterConnNum) = false; + if (allocated(DataPlant::PlantLoop) && !this->StandAlone) { + bool errFlag = false; + PlantUtilities::ScanPlantLoopsForObject(this->Name, + DataPlant::TypeOf_WaterUseConnection, + this->PlantLoopNum, + this->PlantLoopSide, + this->PlantLoopBranchNum, + this->PlantLoopCompNum, + errFlag, + _, + _, + _, + _, + _); + if (errFlag) { + ShowFatalError("InitConnections: Program terminated due to previous condition(s)."); + } } // Set the cold water temperature - if (WaterConnections(WaterConnNum).SupplyTankNum > 0) { - WaterConnections(WaterConnNum).ColdSupplyTemp = WaterStorage(WaterConnections(WaterConnNum).SupplyTankNum).Twater; + if (this->SupplyTankNum > 0) { + this->ColdSupplyTemp = DataWater::WaterStorage(this->SupplyTankNum).Twater; - } else if (WaterConnections(WaterConnNum).ColdTempSchedule > 0) { - WaterConnections(WaterConnNum).ColdSupplyTemp = GetCurrentScheduleValue(WaterConnections(WaterConnNum).ColdTempSchedule); + } else if (this->ColdTempSchedule > 0) { + this->ColdSupplyTemp = ScheduleManager::GetCurrentScheduleValue(this->ColdTempSchedule); } else { - WaterConnections(WaterConnNum).ColdSupplyTemp = WaterMainsTemp; + this->ColdSupplyTemp = DataEnvironment::WaterMainsTemp; } // Initially set ColdTemp to the ColdSupplyTemp; with heat recovery, ColdTemp will change during iteration - WaterConnections(WaterConnNum).ColdTemp = WaterConnections(WaterConnNum).ColdSupplyTemp; + this->ColdTemp = this->ColdSupplyTemp; // Set the hot water temperature - if (WaterConnections(WaterConnNum).StandAlone) { - if (WaterConnections(WaterConnNum).HotTempSchedule > 0) { - WaterConnections(WaterConnNum).HotTemp = GetCurrentScheduleValue(WaterConnections(WaterConnNum).HotTempSchedule); + if (this->StandAlone) { + if (this->HotTempSchedule > 0) { + this->HotTemp = ScheduleManager::GetCurrentScheduleValue(this->HotTempSchedule); } else { // If no HotTempSchedule, use all cold water - WaterConnections(WaterConnNum).HotTemp = WaterConnections(WaterConnNum).ColdTemp; + this->HotTemp = this->ColdTemp; } } else { - InletNode = WaterConnections(WaterConnNum).InletNode; - OutletNode = WaterConnections(WaterConnNum).OutletNode; - if (BeginEnvrnFlag && WaterConnections(WaterConnNum).Init) { + if (DataGlobals::BeginEnvrnFlag && this->Init) { // Clear node initial conditions - if (InletNode > 0 && OutletNode > 0) { - InitComponentNodes(0.0, - WaterConnections(WaterConnNum).PeakMassFlowRate, - InletNode, - OutletNode, - WaterConnections(WaterConnNum).PlantLoopNum, - WaterConnections(WaterConnNum).PlantLoopSide, - WaterConnections(WaterConnNum).PlantLoopBranchNum, - WaterConnections(WaterConnNum).PlantLoopCompNum); - - WaterConnections(WaterConnNum).ReturnTemp = Node(InletNode).Temp; + if (this->InletNode > 0 && this->OutletNode > 0) { + PlantUtilities::InitComponentNodes(0.0, + this->PeakMassFlowRate, + this->InletNode, + this->OutletNode, + this->PlantLoopNum, + this->PlantLoopSide, + this->PlantLoopBranchNum, + this->PlantLoopCompNum); + + this->ReturnTemp = DataLoopNode::Node(this->InletNode).Temp; } - WaterConnections(WaterConnNum).Init = false; + this->Init = false; } - if (!BeginEnvrnFlag) WaterConnections(WaterConnNum).Init = true; + if (!DataGlobals::BeginEnvrnFlag) this->Init = true; - if (InletNode > 0) { - if (!DoingSizing) { - WaterConnections(WaterConnNum).HotTemp = Node(InletNode).Temp; + if (this->InletNode > 0) { + if (!DataGlobals::DoingSizing) { + this->HotTemp = DataLoopNode::Node(this->InletNode).Temp; } else { // plant loop will not be running so need a value here. // should change to use tank setpoint but water use connections don't have knowledge of the tank they are fed by - WaterConnections(WaterConnNum).HotTemp = 60.0; + this->HotTemp = 60.0; } } } } - void CalcConnectionsFlowRates(int const WaterConnNum, bool const FirstHVACIteration) + void WaterConnectionsType::CalcConnectionsFlowRates(bool FirstHVACIteration) { // SUBROUTINE INFORMATION: @@ -1412,89 +1079,51 @@ namespace WaterUse { // PURPOSE OF THIS SUBROUTINE: // Calculate summed values for WATER USE CONNECTIONS (to prepare to request flow from plant, and for reporting). - // METHODOLOGY EMPLOYED: - - // Using/Aliasing - using DataLoopNode::Node; - using DataWater::WaterStorage; - using PlantUtilities::SetComponentFlowRate; - using Psychrometrics::RhoH2O; - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int WaterEquipNum; - int Loop; - int InletNode; - int OutletNode; - int LoopNum; - int LoopSideNum; - Real64 AvailableFraction; - Real64 DesiredHotWaterMassFlow; // store original request - - // FLOW: - WaterConnections(WaterConnNum).ColdMassFlowRate = 0.0; - WaterConnections(WaterConnNum).HotMassFlowRate = 0.0; + this->ColdMassFlowRate = 0.0; + this->HotMassFlowRate = 0.0; - for (Loop = 1; Loop <= WaterConnections(WaterConnNum).NumWaterEquipment; ++Loop) { - WaterEquipNum = WaterConnections(WaterConnNum).WaterEquipment(Loop); + for (int Loop = 1; Loop <= this->NumWaterEquipment; ++Loop) { + int WaterEquipNum = this->myWaterEquipArr(Loop); - CalcEquipmentFlowRates(WaterEquipNum); + WaterEquipment(WaterEquipNum).CalcEquipmentFlowRates(); - WaterConnections(WaterConnNum).ColdMassFlowRate += WaterEquipment(WaterEquipNum).ColdMassFlowRate; - WaterConnections(WaterConnNum).HotMassFlowRate += WaterEquipment(WaterEquipNum).HotMassFlowRate; + this->ColdMassFlowRate += WaterEquipment(WaterEquipNum).ColdMassFlowRate; + this->HotMassFlowRate += WaterEquipment(WaterEquipNum).HotMassFlowRate; } // Loop - WaterConnections(WaterConnNum).TotalMassFlowRate = - WaterConnections(WaterConnNum).ColdMassFlowRate + WaterConnections(WaterConnNum).HotMassFlowRate; + this->TotalMassFlowRate = this->ColdMassFlowRate + this->HotMassFlowRate; - if (!WaterConnections(WaterConnNum).StandAlone) { // Interact with the plant loop - InletNode = WaterConnections(WaterConnNum).InletNode; - OutletNode = WaterConnections(WaterConnNum).OutletNode; - LoopNum = WaterConnections(WaterConnNum).PlantLoopNum; - LoopSideNum = WaterConnections(WaterConnNum).PlantLoopSide; - if (InletNode > 0) { + if (!this->StandAlone) { // Interact with the plant loop + if (this->InletNode > 0) { if (FirstHVACIteration) { // Request the mass flow rate from the demand side manager - // Node(InletNode)%MassFlowRate = WaterConnections(WaterConnNum)%HotMassFlowRate - // Node(InletNode)%MassFlowRateMaxAvail = WaterConnections(WaterConnNum)%PeakMassFlowRate - // Node(InletNode)%MassFlowRateMinAvail = 0.0D0 - SetComponentFlowRate(WaterConnections(WaterConnNum).HotMassFlowRate, - InletNode, - OutletNode, - LoopNum, - LoopSideNum, - WaterConnections(WaterConnNum).PlantLoopBranchNum, - WaterConnections(WaterConnNum).PlantLoopCompNum); + PlantUtilities::SetComponentFlowRate(this->HotMassFlowRate, + this->InletNode, + this->OutletNode, + this->PlantLoopNum, + this->PlantLoopSide, + this->PlantLoopBranchNum, + this->PlantLoopCompNum); } else { - DesiredHotWaterMassFlow = WaterConnections(WaterConnNum).HotMassFlowRate; - SetComponentFlowRate(DesiredHotWaterMassFlow, - InletNode, - OutletNode, - LoopNum, - LoopSideNum, - WaterConnections(WaterConnNum).PlantLoopBranchNum, - WaterConnections(WaterConnNum).PlantLoopCompNum); - // DSU3 Node(InletNode)%MassFlowRate = MIN(WaterConnections(WaterConnNum)%HotMassFlowRate, Node(InletNode)%MassFlowRateMaxAvail) - // DSU3 Node(InletNode)%MassFlowRate = MAX(WaterConnections(WaterConnNum)%HotMassFlowRate, Node(InletNode)%MassFlowRateMinAvail) + Real64 DesiredHotWaterMassFlow = this->HotMassFlowRate; + PlantUtilities::SetComponentFlowRate(DesiredHotWaterMassFlow, + this->InletNode, + this->OutletNode, + this->PlantLoopNum, + this->PlantLoopSide, + this->PlantLoopBranchNum, + this->PlantLoopCompNum); // readjust if more than actual available mass flow rate determined by the demand side manager - if ((WaterConnections(WaterConnNum).HotMassFlowRate != DesiredHotWaterMassFlow) && - (WaterConnections(WaterConnNum).HotMassFlowRate > 0.0)) { // plant didn't give what was asked for + if ((this->HotMassFlowRate != DesiredHotWaterMassFlow) && (this->HotMassFlowRate > 0.0)) { // plant didn't give what was asked for - // DSU3 Node(InletNode)%MassFlowRate = Node(InletNode)%MassFlowRateMaxAvail + Real64 AvailableFraction = DesiredHotWaterMassFlow / this->HotMassFlowRate; - AvailableFraction = DesiredHotWaterMassFlow / WaterConnections(WaterConnNum).HotMassFlowRate; - - // DSU3 WaterConnections(WaterConnNum)%HotMassFlowRate = Node(InletNode)%MassFlowRateMaxAvail - WaterConnections(WaterConnNum).ColdMassFlowRate = - WaterConnections(WaterConnNum).TotalMassFlowRate - - WaterConnections(WaterConnNum).HotMassFlowRate; // Preserve the total mass flow rate + this->ColdMassFlowRate = this->TotalMassFlowRate - this->HotMassFlowRate; // Preserve the total mass flow rate // Proportionally reduce hot water and increase cold water for all WATER USE EQUIPMENT - for (Loop = 1; Loop <= WaterConnections(WaterConnNum).NumWaterEquipment; ++Loop) { - WaterEquipNum = WaterConnections(WaterConnNum).WaterEquipment(Loop); + for (int Loop = 1; Loop <= this->NumWaterEquipment; ++Loop) { + int WaterEquipNum = this->myWaterEquipArr(Loop); // Recalculate flow rates for water equipment within connection WaterEquipment(WaterEquipNum).HotMassFlowRate *= AvailableFraction; @@ -1516,22 +1145,20 @@ namespace WaterUse { } } - if (WaterConnections(WaterConnNum).SupplyTankNum > 0) { + if (this->SupplyTankNum > 0) { // Set the demand request for supply water from water storage tank - WaterConnections(WaterConnNum).ColdVolFlowRate = WaterConnections(WaterConnNum).ColdMassFlowRate / RhoH2O(DataGlobals::InitConvTemp); - WaterStorage(WaterConnections(WaterConnNum).SupplyTankNum).VdotRequestDemand(WaterConnections(WaterConnNum).TankDemandID) = - WaterConnections(WaterConnNum).ColdVolFlowRate; + this->ColdVolFlowRate = this->ColdMassFlowRate / Psychrometrics::RhoH2O(DataGlobals::InitConvTemp); + DataWater::WaterStorage(this->SupplyTankNum).VdotRequestDemand(this->TankDemandID) = this->ColdVolFlowRate; // Check if cold flow rate should be starved by restricted flow from tank // Currently, the tank flow is not really starved--water continues to flow at the tank water temperature // But the user can see the error by comparing report variables for TankVolFlowRate < ColdVolFlowRate - WaterConnections(WaterConnNum).TankVolFlowRate = - WaterStorage(WaterConnections(WaterConnNum).SupplyTankNum).VdotAvailDemand(WaterConnections(WaterConnNum).TankDemandID); - WaterConnections(WaterConnNum).TankMassFlowRate = WaterConnections(WaterConnNum).TankVolFlowRate * RhoH2O(DataGlobals::InitConvTemp); + this->TankVolFlowRate = DataWater::WaterStorage(this->SupplyTankNum).VdotAvailDemand(this->TankDemandID); + this->TankMassFlowRate = this->TankVolFlowRate * Psychrometrics::RhoH2O(DataGlobals::InitConvTemp); } } - void CalcConnectionsDrainTemp(int const WaterConnNum) + void WaterConnectionsType::CalcConnectionsDrainTemp() { // SUBROUTINE INFORMATION: @@ -1540,45 +1167,28 @@ namespace WaterUse { // MODIFIED na // RE-ENGINEERED na - // PURPOSE OF THIS SUBROUTINE: - // Calculate + Real64 MassFlowTempSum = 0.0; + this->DrainMassFlowRate = 0.0; - // METHODOLOGY EMPLOYED: + for (int Loop = 1; Loop <= this->NumWaterEquipment; ++Loop) { + int WaterEquipNum = this->myWaterEquipArr(Loop); - // Using/Aliasing - using Psychrometrics::RhoH2O; - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int WaterEquipNum; - int Loop; - Real64 MassFlowTempSum; + WaterEquipment(WaterEquipNum).CalcEquipmentDrainTemp(); - // FLOW: - WaterConnections(WaterConnNum).DrainMassFlowRate = 0.0; - MassFlowTempSum = 0.0; - - for (Loop = 1; Loop <= WaterConnections(WaterConnNum).NumWaterEquipment; ++Loop) { - WaterEquipNum = WaterConnections(WaterConnNum).WaterEquipment(Loop); - - CalcEquipmentDrainTemp(WaterEquipNum); - - WaterConnections(WaterConnNum).DrainMassFlowRate += WaterEquipment(WaterEquipNum).DrainMassFlowRate; + this->DrainMassFlowRate += WaterEquipment(WaterEquipNum).DrainMassFlowRate; MassFlowTempSum += WaterEquipment(WaterEquipNum).DrainMassFlowRate * WaterEquipment(WaterEquipNum).DrainTemp; } // Loop - if (WaterConnections(WaterConnNum).DrainMassFlowRate > 0.0) { - WaterConnections(WaterConnNum).DrainTemp = MassFlowTempSum / WaterConnections(WaterConnNum).DrainMassFlowRate; + if (this->DrainMassFlowRate > 0.0) { + this->DrainTemp = MassFlowTempSum / this->DrainMassFlowRate; } else { - WaterConnections(WaterConnNum).DrainTemp = WaterConnections(WaterConnNum).HotTemp; + this->DrainTemp = this->HotTemp; } - WaterConnections(WaterConnNum).DrainVolFlowRate = WaterConnections(WaterConnNum).DrainMassFlowRate * RhoH2O(DataGlobals::InitConvTemp); + this->DrainVolFlowRate = this->DrainMassFlowRate * Psychrometrics::RhoH2O(DataGlobals::InitConvTemp); } - void CalcConnectionsHeatRecovery(int const WaterConnNum) + void WaterConnectionsType::CalcConnectionsHeatRecovery() { // SUBROUTINE INFORMATION: @@ -1590,121 +1200,91 @@ namespace WaterUse { // PURPOSE OF THIS SUBROUTINE: // Calculate drainwater heat recovery - // METHODOLOGY EMPLOYED: - - // Using/Aliasing - using Psychrometrics::CPHW; - // unused0909 USE DataEnvironment, ONLY: WaterMainsTemp - using DataWater::WaterStorage; - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - Real64 CapacityRatio; - Real64 NTU; - Real64 ExpVal; - Real64 HXCapacityRate; - Real64 DrainCapacityRate; - Real64 MinCapacityRate; - - // FLOW: - if (!WaterConnections(WaterConnNum).HeatRecovery) { - WaterConnections(WaterConnNum).RecoveryTemp = WaterConnections(WaterConnNum).ColdSupplyTemp; - WaterConnections(WaterConnNum).ReturnTemp = WaterConnections(WaterConnNum).ColdSupplyTemp; - WaterConnections(WaterConnNum).WasteTemp = WaterConnections(WaterConnNum).DrainTemp; - - } else if (WaterConnections(WaterConnNum).TotalMassFlowRate == 0.0) { - WaterConnections(WaterConnNum).Effectiveness = 0.0; - WaterConnections(WaterConnNum).RecoveryRate = 0.0; - WaterConnections(WaterConnNum).RecoveryTemp = WaterConnections(WaterConnNum).ColdSupplyTemp; - WaterConnections(WaterConnNum).ReturnTemp = WaterConnections(WaterConnNum).ColdSupplyTemp; - WaterConnections(WaterConnNum).WasteTemp = WaterConnections(WaterConnNum).DrainTemp; + if (!this->HeatRecovery) { + this->RecoveryTemp = this->ColdSupplyTemp; + this->ReturnTemp = this->ColdSupplyTemp; + this->WasteTemp = this->DrainTemp; + + } else if (this->TotalMassFlowRate == 0.0) { + this->Effectiveness = 0.0; + this->RecoveryRate = 0.0; + this->RecoveryTemp = this->ColdSupplyTemp; + this->ReturnTemp = this->ColdSupplyTemp; + this->WasteTemp = this->DrainTemp; } else { // WaterConnections(WaterConnNum)%TotalMassFlowRate > 0.0 { - auto const SELECT_CASE_var(WaterConnections(WaterConnNum).HeatRecoveryConfig); - if (SELECT_CASE_var == HeatRecoveryConfigPlant) { - WaterConnections(WaterConnNum).RecoveryMassFlowRate = WaterConnections(WaterConnNum).HotMassFlowRate; - } else if (SELECT_CASE_var == HeatRecoveryConfigEquipment) { - WaterConnections(WaterConnNum).RecoveryMassFlowRate = WaterConnections(WaterConnNum).ColdMassFlowRate; - } else if (SELECT_CASE_var == HeatRecoveryConfigPlantAndEquip) { - WaterConnections(WaterConnNum).RecoveryMassFlowRate = WaterConnections(WaterConnNum).TotalMassFlowRate; + auto const SELECT_CASE_var(this->HeatRecoveryConfig); + if (SELECT_CASE_var == HeatRecoveryConfigEnum::Plant) { + this->RecoveryMassFlowRate = this->HotMassFlowRate; + } else if (SELECT_CASE_var == HeatRecoveryConfigEnum::Equipment) { + this->RecoveryMassFlowRate = this->ColdMassFlowRate; + } else if (SELECT_CASE_var == HeatRecoveryConfigEnum::PlantAndEquip) { + this->RecoveryMassFlowRate = this->TotalMassFlowRate; } } - HXCapacityRate = CPHW(DataGlobals::InitConvTemp) * WaterConnections(WaterConnNum).RecoveryMassFlowRate; - DrainCapacityRate = CPHW(DataGlobals::InitConvTemp) * WaterConnections(WaterConnNum).DrainMassFlowRate; - MinCapacityRate = min(DrainCapacityRate, HXCapacityRate); + Real64 HXCapacityRate = Psychrometrics::CPHW(DataGlobals::InitConvTemp) * this->RecoveryMassFlowRate; + Real64 DrainCapacityRate = Psychrometrics::CPHW(DataGlobals::InitConvTemp) * this->DrainMassFlowRate; + Real64 MinCapacityRate = min(DrainCapacityRate, HXCapacityRate); { - auto const SELECT_CASE_var(WaterConnections(WaterConnNum).HeatRecoveryHX); - if (SELECT_CASE_var == HeatRecoveryHXIdeal) { - WaterConnections(WaterConnNum).Effectiveness = 1.0; + auto const SELECT_CASE_var(this->HeatRecoveryHX); + if (SELECT_CASE_var == HeatRecoveryHXEnum::Ideal) { + this->Effectiveness = 1.0; - } else if (SELECT_CASE_var == HeatRecoveryHXCounterFlow) { // Unmixed - CapacityRatio = MinCapacityRate / max(DrainCapacityRate, HXCapacityRate); - NTU = WaterConnections(WaterConnNum).HXUA / MinCapacityRate; + } else if (SELECT_CASE_var == HeatRecoveryHXEnum::CounterFlow) { // Unmixed + Real64 CapacityRatio = MinCapacityRate / max(DrainCapacityRate, HXCapacityRate); + Real64 NTU = this->HXUA / MinCapacityRate; if (CapacityRatio == 1.0) { - WaterConnections(WaterConnNum).Effectiveness = NTU / (1.0 + NTU); + this->Effectiveness = NTU / (1.0 + NTU); } else { - ExpVal = std::exp(-NTU * (1.0 - CapacityRatio)); - WaterConnections(WaterConnNum).Effectiveness = (1.0 - ExpVal) / (1.0 - CapacityRatio * ExpVal); + Real64 ExpVal = std::exp(-NTU * (1.0 - CapacityRatio)); + this->Effectiveness = (1.0 - ExpVal) / (1.0 - CapacityRatio * ExpVal); } - } else if (SELECT_CASE_var == HeatRecoveryHXCrossFlow) { // Unmixed - CapacityRatio = MinCapacityRate / max(DrainCapacityRate, HXCapacityRate); - NTU = WaterConnections(WaterConnNum).HXUA / MinCapacityRate; - WaterConnections(WaterConnNum).Effectiveness = + } else if (SELECT_CASE_var == HeatRecoveryHXEnum::CrossFlow) { // Unmixed + Real64 CapacityRatio = MinCapacityRate / max(DrainCapacityRate, HXCapacityRate); + Real64 NTU = this->HXUA / MinCapacityRate; + this->Effectiveness = 1.0 - std::exp((std::pow(NTU, 0.22) / CapacityRatio) * (std::exp(-CapacityRatio * std::pow(NTU, 0.78)) - 1.0)); } } - WaterConnections(WaterConnNum).RecoveryRate = WaterConnections(WaterConnNum).Effectiveness * MinCapacityRate * - (WaterConnections(WaterConnNum).DrainTemp - WaterConnections(WaterConnNum).ColdSupplyTemp); - - WaterConnections(WaterConnNum).RecoveryTemp = - WaterConnections(WaterConnNum).ColdSupplyTemp + - WaterConnections(WaterConnNum).RecoveryRate / (CPHW(DataGlobals::InitConvTemp) * WaterConnections(WaterConnNum).TotalMassFlowRate); - - WaterConnections(WaterConnNum).WasteTemp = - WaterConnections(WaterConnNum).DrainTemp - - WaterConnections(WaterConnNum).RecoveryRate / (CPHW(DataGlobals::InitConvTemp) * WaterConnections(WaterConnNum).TotalMassFlowRate); + this->RecoveryRate = this->Effectiveness * MinCapacityRate * (this->DrainTemp - this->ColdSupplyTemp); + this->RecoveryTemp = + this->ColdSupplyTemp + this->RecoveryRate / (Psychrometrics::CPHW(DataGlobals::InitConvTemp) * this->TotalMassFlowRate); + this->WasteTemp = this->DrainTemp - this->RecoveryRate / (Psychrometrics::CPHW(DataGlobals::InitConvTemp) * this->TotalMassFlowRate); - if (WaterConnections(WaterConnNum).RecoveryTankNum > 0) { - WaterStorage(WaterConnections(WaterConnNum).RecoveryTankNum).VdotAvailSupply(WaterConnections(WaterConnNum).TankSupplyID) = - WaterConnections(WaterConnNum).DrainVolFlowRate; - WaterStorage(WaterConnections(WaterConnNum).RecoveryTankNum).TwaterSupply(WaterConnections(WaterConnNum).TankSupplyID) = - WaterConnections(WaterConnNum).WasteTemp; + if (this->RecoveryTankNum > 0) { + DataWater::WaterStorage(this->RecoveryTankNum).VdotAvailSupply(this->TankSupplyID) = this->DrainVolFlowRate; + DataWater::WaterStorage(this->RecoveryTankNum).TwaterSupply(this->TankSupplyID) = this->WasteTemp; } { - auto const SELECT_CASE_var(WaterConnections(WaterConnNum).HeatRecoveryConfig); - if (SELECT_CASE_var == HeatRecoveryConfigPlant) { - WaterConnections(WaterConnNum).TempError = 0.0; // No feedback back to the cold supply - // WaterConnections(WaterConnNum)%ColdTemp = WaterConnections(WaterConnNum)%ColdSupplyTemp - WaterConnections(WaterConnNum).ReturnTemp = WaterConnections(WaterConnNum).RecoveryTemp; + auto const SELECT_CASE_var(this->HeatRecoveryConfig); + if (SELECT_CASE_var == HeatRecoveryConfigEnum::Plant) { + this->TempError = 0.0; // No feedback back to the cold supply + this->ReturnTemp = this->RecoveryTemp; - } else if (SELECT_CASE_var == HeatRecoveryConfigEquipment) { - WaterConnections(WaterConnNum).TempError = - std::abs(WaterConnections(WaterConnNum).ColdTemp - WaterConnections(WaterConnNum).RecoveryTemp); + } else if (SELECT_CASE_var == HeatRecoveryConfigEnum::Equipment) { + this->TempError = std::abs(this->ColdTemp - this->RecoveryTemp); - WaterConnections(WaterConnNum).ColdTemp = WaterConnections(WaterConnNum).RecoveryTemp; - WaterConnections(WaterConnNum).ReturnTemp = WaterConnections(WaterConnNum).ColdSupplyTemp; + this->ColdTemp = this->RecoveryTemp; + this->ReturnTemp = this->ColdSupplyTemp; - } else if (SELECT_CASE_var == HeatRecoveryConfigPlantAndEquip) { - WaterConnections(WaterConnNum).TempError = - std::abs(WaterConnections(WaterConnNum).ColdTemp - WaterConnections(WaterConnNum).RecoveryTemp); + } else if (SELECT_CASE_var == HeatRecoveryConfigEnum::PlantAndEquip) { + this->TempError = std::abs(this->ColdTemp - this->RecoveryTemp); - WaterConnections(WaterConnNum).ColdTemp = WaterConnections(WaterConnNum).RecoveryTemp; - WaterConnections(WaterConnNum).ReturnTemp = WaterConnections(WaterConnNum).RecoveryTemp; + this->ColdTemp = this->RecoveryTemp; + this->ReturnTemp = this->RecoveryTemp; } } } } - void UpdateWaterConnections(int const WaterConnNum) + void WaterConnectionsType::UpdateWaterConnections() { // SUBROUTINE INFORMATION: @@ -1716,33 +1296,12 @@ namespace WaterUse { // PURPOSE OF THIS SUBROUTINE: // Updates the node variables with local variables. - // METHODOLOGY EMPLOYED: - // Standard EnergyPlus methodology. - - // Using/Aliasing - using DataLoopNode::Node; - using PlantUtilities::SafeCopyPlantNode; - - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int InletNode; - int OutletNode; - int LoopNum; - - // FLOW: - InletNode = WaterConnections(WaterConnNum).InletNode; - OutletNode = WaterConnections(WaterConnNum).OutletNode; - LoopNum = WaterConnections(WaterConnNum).PlantLoopNum; - - if (InletNode > 0 && OutletNode > 0) { + if (this->InletNode > 0 && this->OutletNode > 0) { // Pass all variables from inlet to outlet node - SafeCopyPlantNode(InletNode, OutletNode, LoopNum); - // DSU3 Node(OutletNode) = Node(InletNode) + PlantUtilities::SafeCopyPlantNode(this->InletNode, this->OutletNode, this->PlantLoopNum); // Set outlet node variables that are possibly changed - Node(OutletNode).Temp = WaterConnections(WaterConnNum).ReturnTemp; + DataLoopNode::Node(this->OutletNode).Temp = this->ReturnTemp; // should add enthalpy update to return? } } @@ -1759,45 +1318,28 @@ namespace WaterUse { // PURPOSE OF THIS SUBROUTINE: // Calculates report variables for stand alone water use - // METHODOLOGY EMPLOYED: - // Standard EnergyPlus methodology. - - // Using/Aliasing - using DataGlobals::SecInHour; - using DataHVACGlobals::TimeStepSys; - using Psychrometrics::CPHW; - using Psychrometrics::RhoH2O; + for (int WaterEquipNum = 1; WaterEquipNum <= numWaterEquipment; ++WaterEquipNum) { + auto &thisWEq = WaterEquipment(WaterEquipNum); + thisWEq.ColdVolFlowRate = thisWEq.ColdMassFlowRate / Psychrometrics::RhoH2O(DataGlobals::InitConvTemp); + thisWEq.HotVolFlowRate = thisWEq.HotMassFlowRate / Psychrometrics::RhoH2O(DataGlobals::InitConvTemp); + thisWEq.TotalVolFlowRate = thisWEq.ColdVolFlowRate + thisWEq.HotVolFlowRate; - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: + thisWEq.ColdVolume = thisWEq.ColdVolFlowRate * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; + thisWEq.HotVolume = thisWEq.HotVolFlowRate * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; + thisWEq.TotalVolume = thisWEq.TotalVolFlowRate * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; - int WaterEquipNum; - - // FLOW: - for (WaterEquipNum = 1; WaterEquipNum <= NumWaterEquipment; ++WaterEquipNum) { - WaterEquipment(WaterEquipNum).ColdVolFlowRate = WaterEquipment(WaterEquipNum).ColdMassFlowRate / RhoH2O(DataGlobals::InitConvTemp); - WaterEquipment(WaterEquipNum).HotVolFlowRate = WaterEquipment(WaterEquipNum).HotMassFlowRate / RhoH2O(DataGlobals::InitConvTemp); - WaterEquipment(WaterEquipNum).TotalVolFlowRate = - WaterEquipment(WaterEquipNum).ColdVolFlowRate + WaterEquipment(WaterEquipNum).HotVolFlowRate; - - WaterEquipment(WaterEquipNum).ColdVolume = WaterEquipment(WaterEquipNum).ColdVolFlowRate * TimeStepSys * SecInHour; - WaterEquipment(WaterEquipNum).HotVolume = WaterEquipment(WaterEquipNum).HotVolFlowRate * TimeStepSys * SecInHour; - WaterEquipment(WaterEquipNum).TotalVolume = WaterEquipment(WaterEquipNum).TotalVolFlowRate * TimeStepSys * SecInHour; - - if (WaterEquipment(WaterEquipNum).Connections == 0) { - WaterEquipment(WaterEquipNum).Power = WaterEquipment(WaterEquipNum).HotMassFlowRate * CPHW(DataGlobals::InitConvTemp) * - (WaterEquipment(WaterEquipNum).HotTemp - WaterEquipment(WaterEquipNum).ColdTemp); + if (thisWEq.Connections == 0) { + thisWEq.Power = thisWEq.HotMassFlowRate * Psychrometrics::CPHW(DataGlobals::InitConvTemp) * (thisWEq.HotTemp - thisWEq.ColdTemp); } else { - WaterEquipment(WaterEquipNum).Power = - WaterEquipment(WaterEquipNum).HotMassFlowRate * CPHW(DataGlobals::InitConvTemp) * - (WaterEquipment(WaterEquipNum).HotTemp - WaterConnections(WaterEquipment(WaterEquipNum).Connections).ReturnTemp); + thisWEq.Power = thisWEq.HotMassFlowRate * Psychrometrics::CPHW(DataGlobals::InitConvTemp) * + (thisWEq.HotTemp - WaterConnections(thisWEq.Connections).ReturnTemp); } - WaterEquipment(WaterEquipNum).Energy = WaterEquipment(WaterEquipNum).Power * TimeStepSys * SecInHour; + thisWEq.Energy = thisWEq.Power * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; } } - void ReportWaterUse(int const WaterConnNum) + void WaterConnectionsType::ReportWaterUse() { // SUBROUTINE INFORMATION: @@ -1809,59 +1351,37 @@ namespace WaterUse { // PURPOSE OF THIS SUBROUTINE: // Calculates report variables. - // METHODOLOGY EMPLOYED: - // Standard EnergyPlus methodology. - - // Using/Aliasing - using DataGlobals::SecInHour; - using DataHVACGlobals::TimeStepSys; - using Psychrometrics::CPHW; - using Psychrometrics::RhoH2O; + for (int Loop = 1; Loop <= this->NumWaterEquipment; ++Loop) { - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: + int WaterEquipNum = this->myWaterEquipArr(Loop); + auto &thisWEq = WaterEquipment(WaterEquipNum); - int Loop; - int WaterEquipNum; + thisWEq.ColdVolFlowRate = thisWEq.ColdMassFlowRate / Psychrometrics::RhoH2O(DataGlobals::InitConvTemp); + thisWEq.HotVolFlowRate = thisWEq.HotMassFlowRate / Psychrometrics::RhoH2O(DataGlobals::InitConvTemp); + thisWEq.TotalVolFlowRate = thisWEq.ColdVolFlowRate + thisWEq.HotVolFlowRate; + thisWEq.ColdVolume = thisWEq.ColdVolFlowRate * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; + thisWEq.HotVolume = thisWEq.HotVolFlowRate * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; + thisWEq.TotalVolume = thisWEq.TotalVolFlowRate * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; - // FLOW: - for (Loop = 1; Loop <= WaterConnections(WaterConnNum).NumWaterEquipment; ++Loop) { - WaterEquipNum = WaterConnections(WaterConnNum).WaterEquipment(Loop); - WaterEquipment(WaterEquipNum).ColdVolFlowRate = WaterEquipment(WaterEquipNum).ColdMassFlowRate / RhoH2O(DataGlobals::InitConvTemp); - WaterEquipment(WaterEquipNum).HotVolFlowRate = WaterEquipment(WaterEquipNum).HotMassFlowRate / RhoH2O(DataGlobals::InitConvTemp); - WaterEquipment(WaterEquipNum).TotalVolFlowRate = - WaterEquipment(WaterEquipNum).ColdVolFlowRate + WaterEquipment(WaterEquipNum).HotVolFlowRate; - - WaterEquipment(WaterEquipNum).ColdVolume = WaterEquipment(WaterEquipNum).ColdVolFlowRate * TimeStepSys * SecInHour; - WaterEquipment(WaterEquipNum).HotVolume = WaterEquipment(WaterEquipNum).HotVolFlowRate * TimeStepSys * SecInHour; - WaterEquipment(WaterEquipNum).TotalVolume = WaterEquipment(WaterEquipNum).TotalVolFlowRate * TimeStepSys * SecInHour; - - if (WaterEquipment(WaterEquipNum).Connections == 0) { - WaterEquipment(WaterEquipNum).Power = WaterEquipment(WaterEquipNum).HotMassFlowRate * CPHW(DataGlobals::InitConvTemp) * - (WaterEquipment(WaterEquipNum).HotTemp - WaterEquipment(WaterEquipNum).ColdTemp); + if (thisWEq.Connections == 0) { + thisWEq.Power = thisWEq.HotMassFlowRate * Psychrometrics::CPHW(DataGlobals::InitConvTemp) * (thisWEq.HotTemp - thisWEq.ColdTemp); } else { - WaterEquipment(WaterEquipNum).Power = - WaterEquipment(WaterEquipNum).HotMassFlowRate * CPHW(DataGlobals::InitConvTemp) * - (WaterEquipment(WaterEquipNum).HotTemp - WaterConnections(WaterEquipment(WaterEquipNum).Connections).ReturnTemp); + thisWEq.Power = thisWEq.HotMassFlowRate * Psychrometrics::CPHW(DataGlobals::InitConvTemp) * + (thisWEq.HotTemp - WaterConnections(thisWEq.Connections).ReturnTemp); } - WaterEquipment(WaterEquipNum).Energy = WaterEquipment(WaterEquipNum).Power * TimeStepSys * SecInHour; + thisWEq.Energy = thisWEq.Power * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; } - WaterConnections(WaterConnNum).ColdVolFlowRate = WaterConnections(WaterConnNum).ColdMassFlowRate / RhoH2O(DataGlobals::InitConvTemp); - WaterConnections(WaterConnNum).HotVolFlowRate = WaterConnections(WaterConnNum).HotMassFlowRate / RhoH2O(DataGlobals::InitConvTemp); - WaterConnections(WaterConnNum).TotalVolFlowRate = - WaterConnections(WaterConnNum).ColdVolFlowRate + WaterConnections(WaterConnNum).HotVolFlowRate; - - WaterConnections(WaterConnNum).ColdVolume = WaterConnections(WaterConnNum).ColdVolFlowRate * TimeStepSys * SecInHour; - WaterConnections(WaterConnNum).HotVolume = WaterConnections(WaterConnNum).HotVolFlowRate * TimeStepSys * SecInHour; - WaterConnections(WaterConnNum).TotalVolume = WaterConnections(WaterConnNum).TotalVolFlowRate * TimeStepSys * SecInHour; - - WaterConnections(WaterConnNum).Power = WaterConnections(WaterConnNum).HotMassFlowRate * CPHW(DataGlobals::InitConvTemp) * - (WaterConnections(WaterConnNum).HotTemp - WaterConnections(WaterConnNum).ReturnTemp); - WaterConnections(WaterConnNum).Energy = WaterConnections(WaterConnNum).Power * TimeStepSys * SecInHour; - - WaterConnections(WaterConnNum).RecoveryEnergy = WaterConnections(WaterConnNum).RecoveryRate * TimeStepSys * SecInHour; + this->ColdVolFlowRate = this->ColdMassFlowRate / Psychrometrics::RhoH2O(DataGlobals::InitConvTemp); + this->HotVolFlowRate = this->HotMassFlowRate / Psychrometrics::RhoH2O(DataGlobals::InitConvTemp); + this->TotalVolFlowRate = this->ColdVolFlowRate + this->HotVolFlowRate; + this->ColdVolume = this->ColdVolFlowRate * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; + this->HotVolume = this->HotVolFlowRate * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; + this->TotalVolume = this->TotalVolFlowRate * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; + this->Power = this->HotMassFlowRate * Psychrometrics::CPHW(DataGlobals::InitConvTemp) * (this->HotTemp - this->ReturnTemp); + this->Energy = this->Power * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; + this->RecoveryEnergy = this->RecoveryRate * DataHVACGlobals::TimeStepSys * DataGlobals::SecInHour; } void CalcWaterUseZoneGains() @@ -1876,22 +1396,11 @@ namespace WaterUse { // PURPOSE OF THIS SUBROUTINE: // Calculates the zone internal gains due to water use sensible and latent loads. - // METHODOLOGY EMPLOYED: + bool MyEnvrnFlagLocal(true); - // Using/Aliasing - using DataGlobals::BeginEnvrnFlag; - using DataHeatBalance::Zone; + if (numWaterEquipment == 0) return; - // Locals - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int WaterEquipNum; - int ZoneNum; - static bool MyEnvrnFlag(true); - - // FLOW: - if (NumWaterEquipment == 0) return; - - if (BeginEnvrnFlag && MyEnvrnFlag) { + if (DataGlobals::BeginEnvrnFlag && MyEnvrnFlagLocal) { for (auto &e : WaterEquipment) { e.SensibleRate = 0.0; e.SensibleEnergy = 0.0; @@ -1908,30 +1417,21 @@ namespace WaterUse { e.ColdMassFlowRate = 0.0; e.HotMassFlowRate = 0.0; } - MyEnvrnFlag = false; + MyEnvrnFlagLocal = false; } - if (!BeginEnvrnFlag) MyEnvrnFlag = true; + if (!DataGlobals::BeginEnvrnFlag) MyEnvrnFlagLocal = true; - for (WaterEquipNum = 1; WaterEquipNum <= NumWaterEquipment; ++WaterEquipNum) { + for (int WaterEquipNum = 1; WaterEquipNum <= numWaterEquipment; ++WaterEquipNum) { if (WaterEquipment(WaterEquipNum).Zone == 0) continue; - ZoneNum = WaterEquipment(WaterEquipNum).Zone; + int ZoneNum = WaterEquipment(WaterEquipNum).Zone; WaterEquipment(WaterEquipNum).SensibleRateNoMultiplier = WaterEquipment(WaterEquipNum).SensibleRate / - (Zone(ZoneNum).Multiplier * Zone(ZoneNum).ListMultiplier); // CR7401, back out multipliers + (DataHeatBalance::Zone(ZoneNum).Multiplier * DataHeatBalance::Zone(ZoneNum).ListMultiplier); WaterEquipment(WaterEquipNum).LatentRateNoMultiplier = - WaterEquipment(WaterEquipNum).LatentRate / (Zone(ZoneNum).Multiplier * Zone(ZoneNum).ListMultiplier); // CR7401, back out multipliers + WaterEquipment(WaterEquipNum).LatentRate / + (DataHeatBalance::Zone(ZoneNum).Multiplier * DataHeatBalance::Zone(ZoneNum).ListMultiplier); } - - // ! this routine needs to model approx zone gains for use during sizing - // IF(DoingSizing)THEN - // DO WaterEquipNum = 1, NumWaterEquipment - // WaterEquipment(WaterEquipNum)%SensibleRateNoMultiplier = - // WaterEquipment(WaterEquipNum)%LatentRateNoMultiplier = - // END DO - // ENDIF } - } // namespace WaterUse - } // namespace EnergyPlus diff --git a/src/EnergyPlus/WaterUse.hh b/src/EnergyPlus/WaterUse.hh index 55f717a02f9..4f85fabb42b 100644 --- a/src/EnergyPlus/WaterUse.hh +++ b/src/EnergyPlus/WaterUse.hh @@ -54,43 +54,32 @@ // EnergyPlus Headers #include #include +#include namespace EnergyPlus { namespace WaterUse { - // Using/Aliasing - - // Data - // MODULE PARAMETER DEFINITIONS: - extern int const HeatRecoveryHXIdeal; - extern int const HeatRecoveryHXCounterFlow; - extern int const HeatRecoveryHXCrossFlow; - - extern int const HeatRecoveryConfigPlant; - extern int const HeatRecoveryConfigEquipment; - extern int const HeatRecoveryConfigPlantAndEquip; - - // DERIVED TYPE DEFINITIONS: + enum struct HeatRecoveryHXEnum + { + Ideal, + CounterFlow, + CrossFlow + }; - // MODULE VARIABLE TYPE DECLARATIONS: + enum struct HeatRecoveryConfigEnum + { + Plant, + Equipment, + PlantAndEquip + }; - // MODULE VARIABLE DECLARATIONS: - extern int NumWaterEquipment; - extern int NumWaterConnections; - // INTEGER :: MaxIterationsErrorCount =0 - extern bool GetWaterUseInputFlag; + extern bool getWaterUseInputFlag; extern Array1D_bool CheckEquipName; - extern Array1D_bool CheckPlantLoop; - - // SUBROUTINE SPECIFICATIONS: - - // Types struct WaterEquipmentType { - // Members std::string Name; // Name of DHW std::string EndUseSubcatName; int Connections; // Index for WATER USE CONNECTIONS object @@ -127,15 +116,15 @@ namespace WaterUse { Real64 TotalVolume; // Water consumption (m3) Real64 Power; // Heating rate required to meet the mixed water temperature (W) Real64 Energy; // Heating energy required to meet the mixed water temperature (J) + bool setupMyOutputVars; - // Default Constructor WaterEquipmentType() : Connections(0), PeakVolFlowRate(0.0), FlowRateFracSchedule(0), ColdVolFlowRate(0.0), HotVolFlowRate(0.0), TotalVolFlowRate(0.0), ColdMassFlowRate(0.0), HotMassFlowRate(0.0), TotalMassFlowRate(0.0), DrainMassFlowRate(0.0), ColdTempSchedule(0), HotTempSchedule(0), TargetTempSchedule(0), ColdTemp(0.0), HotTemp(0.0), TargetTemp(0.0), MixedTemp(0.0), DrainTemp(0.0), Zone(0), SensibleFracSchedule(0), SensibleRate(0.0), SensibleEnergy(0.0), SensibleRateNoMultiplier(0.0), LatentFracSchedule(0), LatentRate(0.0), LatentEnergy(0.0), LatentRateNoMultiplier(0.0), MoistureRate(0.0), MoistureMass(0.0), ColdVolume(0.0), HotVolume(0.0), TotalVolume(0.0), Power(0.0), - Energy(0.0) + Energy(0.0), setupMyOutputVars(true) { } @@ -150,11 +139,16 @@ namespace WaterUse { TotalMassFlowRate = 0.0; DrainTemp = 0.0; } + + void CalcEquipmentFlowRates(); + + void CalcEquipmentDrainTemp(); + + void setupOutputVars(); }; - struct WaterConnectionsType + struct WaterConnectionsType : PlantComponent { - // Members std::string Name; // Name of DHW bool Init; // Flag for initialization: TRUE means do the init bool InitSizing; // Flag for initialization of plant sizing @@ -166,8 +160,8 @@ namespace WaterUse { int TankDemandID; // array to request flow from supply tank int TankSupplyID; // array to send flow to recovery tank bool HeatRecovery; - int HeatRecoveryHX; - int HeatRecoveryConfig; + HeatRecoveryHXEnum HeatRecoveryHX; + HeatRecoveryConfigEnum HeatRecoveryConfig; Real64 HXUA; Real64 Effectiveness; Real64 RecoveryRate; @@ -208,62 +202,61 @@ namespace WaterUse { Real64 Energy; // Heating energy required to raise temperature from cold to hot (J) int NumWaterEquipment; int MaxIterationsErrorIndex; // recurring error index - Array1D_int WaterEquipment; + Array1D_int myWaterEquipArr; int PlantLoopNum; int PlantLoopSide; int PlantLoopBranchNum; int PlantLoopCompNum; + bool MyEnvrnFlag; + bool setupMyOutputVars; - // Default Constructor WaterConnectionsType() : Init(true), InitSizing(true), StandAlone(false), InletNode(0), OutletNode(0), SupplyTankNum(0), RecoveryTankNum(0), TankDemandID(0), - TankSupplyID(0), HeatRecovery(false), HeatRecoveryHX(HeatRecoveryHXIdeal), HeatRecoveryConfig(HeatRecoveryConfigPlant), HXUA(0.0), - Effectiveness(0.0), RecoveryRate(0.0), RecoveryEnergy(0.0), MainsMassFlowRate(0.0), TankMassFlowRate(0.0), ColdMassFlowRate(0.0), - HotMassFlowRate(0.0), TotalMassFlowRate(0.0), DrainMassFlowRate(0.0), RecoveryMassFlowRate(0.0), PeakVolFlowRate(0.0), - MainsVolFlowRate(0.0), TankVolFlowRate(0.0), ColdVolFlowRate(0.0), HotVolFlowRate(0.0), TotalVolFlowRate(0.0), DrainVolFlowRate(0.0), - PeakMassFlowRate(0.0), ColdTempSchedule(0), HotTempSchedule(0), MainsTemp(0.0), TankTemp(0.0), ColdSupplyTemp(0.0), ColdTemp(0.0), - HotTemp(0.0), DrainTemp(0.0), RecoveryTemp(0.0), ReturnTemp(0.0), WasteTemp(0.0), TempError(0.0), MainsVolume(0.0), TankVolume(0.0), - ColdVolume(0.0), HotVolume(0.0), TotalVolume(0.0), Power(0.0), Energy(0.0), NumWaterEquipment(0), MaxIterationsErrorIndex(0), - PlantLoopNum(0), PlantLoopSide(0), PlantLoopBranchNum(0), PlantLoopCompNum(0) + TankSupplyID(0), HeatRecovery(false), HeatRecoveryHX(HeatRecoveryHXEnum::Ideal), HeatRecoveryConfig(HeatRecoveryConfigEnum::Plant), + HXUA(0.0), Effectiveness(0.0), RecoveryRate(0.0), RecoveryEnergy(0.0), MainsMassFlowRate(0.0), TankMassFlowRate(0.0), + ColdMassFlowRate(0.0), HotMassFlowRate(0.0), TotalMassFlowRate(0.0), DrainMassFlowRate(0.0), RecoveryMassFlowRate(0.0), + PeakVolFlowRate(0.0), MainsVolFlowRate(0.0), TankVolFlowRate(0.0), ColdVolFlowRate(0.0), HotVolFlowRate(0.0), TotalVolFlowRate(0.0), + DrainVolFlowRate(0.0), PeakMassFlowRate(0.0), ColdTempSchedule(0), HotTempSchedule(0), MainsTemp(0.0), TankTemp(0.0), + ColdSupplyTemp(0.0), ColdTemp(0.0), HotTemp(0.0), DrainTemp(0.0), RecoveryTemp(0.0), ReturnTemp(0.0), WasteTemp(0.0), TempError(0.0), + MainsVolume(0.0), TankVolume(0.0), ColdVolume(0.0), HotVolume(0.0), TotalVolume(0.0), Power(0.0), Energy(0.0), NumWaterEquipment(0), + MaxIterationsErrorIndex(0), PlantLoopNum(0), PlantLoopSide(0), PlantLoopBranchNum(0), PlantLoopCompNum(0), MyEnvrnFlag(true), + setupMyOutputVars(true) { } - }; - // Object Data - extern Array1D WaterEquipment; - extern Array1D WaterConnections; + static PlantComponent *factory(std::string const &objectName); - // Functions + void simulate(const PlantLocation &calledFromLocation, bool FirstHVACIteration, Real64 &CurLoad, bool RunFlag) override; - void clear_state(); + void InitConnections(); - void SimulateWaterUse(bool const FirstHVACIteration); + void CalcConnectionsFlowRates(bool FirstHVACIteration); - void SimulateWaterUseConnection( - int const EquipTypeNum, std::string const &CompName, int &CompIndex, bool const InitLoopEquip, bool const FirstHVACIteration); + void CalcConnectionsDrainTemp(); - void GetWaterUseInput(); + void CalcConnectionsHeatRecovery(); - void CalcEquipmentFlowRates(int const WaterEquipNum); + void UpdateWaterConnections(); - void CalcEquipmentDrainTemp(int const WaterEquipNum); + void ReportWaterUse(); - void InitConnections(int const WaterConnNum); - - void CalcConnectionsFlowRates(int const WaterConnNum, bool const FirstHVACIteration); + void setupOutputVars(); + }; - void CalcConnectionsDrainTemp(int const WaterConnNum); + void clear_state(); - void CalcConnectionsHeatRecovery(int const WaterConnNum); + void SimulateWaterUse(bool FirstHVACIteration); - void UpdateWaterConnections(int const WaterConnNum); + void GetWaterUseInput(); void ReportStandAloneWaterUse(); - void ReportWaterUse(int const WaterConnNum); - void CalcWaterUseZoneGains(); + extern Array1D WaterEquipment; + + extern Array1D WaterConnections; + } // namespace WaterUse } // namespace EnergyPlus diff --git a/tst/EnergyPlus/unit/FuelCellElectricGenerator.unit.cc b/tst/EnergyPlus/unit/FuelCellElectricGenerator.unit.cc index 4f167ea876e..e35e66bcd36 100644 --- a/tst/EnergyPlus/unit/FuelCellElectricGenerator.unit.cc +++ b/tst/EnergyPlus/unit/FuelCellElectricGenerator.unit.cc @@ -60,7 +60,11 @@ using namespace EnergyPlus; using namespace ObjexxFCL; -TEST_F(EnergyPlusFixture, FuelCellTest_LowInletEnthalySover1) +class FuelCellGenFixture : public EnergyPlusFixture +{ +}; + +TEST_F(FuelCellGenFixture, FuelCellTest_LowInletEnthalySover1) { std::string const idf_objects = delimited_string({