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 7265da82e93..a38b7899515 100644 --- a/src/EnergyPlus/Plant/PlantManager.cc +++ b/src/EnergyPlus/Plant/PlantManager.cc @@ -73,6 +73,7 @@ #include #include #include +#include #include #include #include @@ -1134,10 +1135,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) { @@ -1295,6 +1296,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) { @@ -1305,7 +1307,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 8b1aa7ff179..c49189216ae 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; @@ -811,42 +810,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); 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({