Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Absorption Chiller Plant Component Refactor #7639

Merged
merged 14 commits into from
Dec 10, 2019
2,522 changes: 1,074 additions & 1,448 deletions src/EnergyPlus/ChillerAbsorption.cc

Large diffs are not rendered by default.

185 changes: 72 additions & 113 deletions src/EnergyPlus/ChillerAbsorption.hh
Original file line number Diff line number Diff line change
Expand Up @@ -54,51 +54,52 @@
// EnergyPlus Headers
#include <EnergyPlus/DataGlobals.hh>
#include <EnergyPlus/EnergyPlus.hh>
#include <EnergyPlus/PlantComponent.hh>

namespace EnergyPlus {

namespace ChillerAbsorption {

// Using/Aliasing

// Data
// MODULE PARAMETER DEFINITIONS:
// chiller flow modes
extern int const FlowModeNotSet;
extern int const ConstantFlow;
extern int const NotModulated;
extern int const LeavingSetPointModulated;

// DERIVED TYPE DEFINITIONS:

// MODULE VARIABLE DECLARATIONS:
extern int NumBLASTAbsorbers; // number of Absorption Chillers specified in input

extern Real64 CondMassFlowRate; // Kg/s - condenser mass flow rate, water side
extern Real64 EvapMassFlowRate; // Kg/s - evaporator mass flow rate, water side
extern Real64 SteamMassFlowRate; // Kg/s - steam mass flow rate, water side
extern Real64 CondOutletTemp; // C - condenser outlet temperature, water side
extern Real64 EvapOutletTemp; // C - evaporator outlet temperature, water side
extern Real64 GenOutletTemp; // C - generator fluid outlet temperature
extern Real64 SteamOutletEnthalpy; // J/kg - generator fluid outlet enthalpy
extern Real64 PumpingPower; // W - rate of Absorber energy use
extern Real64 PumpingEnergy; // J - Absorber energy use
extern Real64 QGenerator; // W - rate of Absorber steam use
extern Real64 GeneratorEnergy; // J - Absorber steam use
extern Real64 QEvaporator; // W - rate of heat transfer to the evaporator coil
extern Real64 EvaporatorEnergy; // J - heat transfer to the evaporator coil
extern Real64 QCondenser; // W - rate of heat transfer to the condenser coil
extern Real64 CondenserEnergy; // J - heat transfer to the condenser coil
extern int numBlastAbsorbers; // number of Absorption Chillers specified in input

extern Array1D_bool CheckEquipName;
extern bool getInput; // When TRUE, calls subroutine to read input file
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note for later, a lot of times these getInput flags aren't actually needed to be defined and exposed via the header file, it can be defined at the top of the cc file only, so just watch out for that on later refactors. Note there are occasions where this isn't actually true, so I'm just throwing this out there.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Myoldmopar thanks. This is externed because FaultsManager uses it.


extern bool GetInput; // When TRUE, calls subroutine to read input file

// SUBROUTINE SPECIFICATIONS FOR MODULE:
struct ReportVars
{
// Members
Real64 PumpingPower; // reporting: electric pumping power
Real64 QGenerator; // reporting: steam heat transfer rate
Real64 QEvap; // reporting: evaporator heat transfer rate
Real64 QCond; // reporting: condenser heat transfer rate
Real64 PumpingEnergy; // reporting: electric pumping power
Real64 GeneratorEnergy; // reporting: steam heat transfer rate
Real64 EvapEnergy; // reporting: evaporator heat transfer rate
Real64 CondEnergy; // reporting: condenser heat transfer rate
Real64 CondInletTemp; // reporting: condenser inlet temperature
Real64 EvapInletTemp; // reporting: evaporator inlet temperature
Real64 CondOutletTemp; // reporting: condenser outlet temperature
Real64 EvapOutletTemp; // reporting: evaporator outlet temperature
Real64 Evapmdot; // reporting: evaporator mass flow rate
Real64 Condmdot; // reporting: condenser mass flow rate
Real64 Genmdot; // reporting: generator mass flow rate when connected to plant
Real64 SteamMdot; // reporting: steam mass flow rate
Real64 ActualCOP; // reporting: coefficient of performance = QEvap/QGenerator

// Types
// Default Constructor
ReportVars()
: PumpingPower(0.0), QGenerator(0.0), QEvap(0.0), QCond(0.0), PumpingEnergy(0.0), GeneratorEnergy(0.0), EvapEnergy(0.0), CondEnergy(0.0),
CondInletTemp(0.0), EvapInletTemp(0.0), CondOutletTemp(0.0), EvapOutletTemp(0.0), Evapmdot(0.0), Condmdot(0.0), Genmdot(0.0),
SteamMdot(0.0), ActualCOP(0.0)
{
}
};

struct BLASTAbsorberSpecs
struct BLASTAbsorberSpecs : PlantComponent
{
// Members
std::string Name; // user identifier
Expand Down Expand Up @@ -157,6 +158,26 @@ namespace ChillerAbsorption {
int FaultyChillerSWTIndex; // Index of the fault object corresponding to the chiller
Real64 FaultyChillerSWTOffset; // Chiller SWT sensor offset
bool PossibleSubcooling; // flag to indicate chiller is doing less cooling that requested
Real64 CondMassFlowRate; // Kg/s - condenser mass flow rate, water side
Real64 EvapMassFlowRate; // Kg/s - evaporator mass flow rate, water side
Real64 SteamMassFlowRate; // Kg/s - steam mass flow rate, water side
Real64 CondOutletTemp; // C - condenser outlet temperature, water side
Real64 EvapOutletTemp; // C - evaporator outlet temperature, water side
Real64 GenOutletTemp; // C - generator fluid outlet temperature
Real64 SteamOutletEnthalpy; // J/kg - generator fluid outlet enthalpy
Real64 PumpingPower; // W - rate of Absorber energy use
Real64 PumpingEnergy; // J - Absorber energy use
Real64 QGenerator; // W - rate of Absorber steam use
Real64 GeneratorEnergy; // J - Absorber steam use
Real64 QEvaporator; // W - rate of heat transfer to the evaporator coil
Real64 EvaporatorEnergy; // J - heat transfer to the evaporator coil
Real64 QCondenser; // W - rate of heat transfer to the condenser coil
Real64 CondenserEnergy; // J - heat transfer to the condenser coil
bool MyOneTimeFlag;
bool MyEnvrnFlag;
bool GenInputOutputNodesUsed;
ReportVars Report;
int EquipFlowCtrl;

// Default Constructor
BLASTAbsorberSpecs()
Expand All @@ -169,104 +190,42 @@ namespace ChillerAbsorption {
GenHeatSourceType(0), GeneratorVolFlowRate(0.0), GeneratorVolFlowRateWasAutoSized(false), GeneratorSubcool(0.0), SteamFluidIndex(0),
GeneratorDeltaTemp(-99999.0), GeneratorDeltaTempWasAutoSized(true), CWLoopNum(0), CWLoopSideNum(0), CWBranchNum(0), CWCompNum(0),
CDLoopNum(0), CDLoopSideNum(0), CDBranchNum(0), CDCompNum(0), GenLoopNum(0), GenLoopSideNum(0), GenBranchNum(0), GenCompNum(0),
FaultyChillerSWTFlag(false), FaultyChillerSWTIndex(0), FaultyChillerSWTOffset(0.0), PossibleSubcooling(false)
FaultyChillerSWTFlag(false), FaultyChillerSWTIndex(0), FaultyChillerSWTOffset(0.0), PossibleSubcooling(false), CondMassFlowRate(0.0),
EvapMassFlowRate(0.0), SteamMassFlowRate(0.0), CondOutletTemp(0.0), EvapOutletTemp(0.0), GenOutletTemp(0.0), SteamOutletEnthalpy(0.0),
PumpingPower(0.0), PumpingEnergy(0.0), QGenerator(0.0), GeneratorEnergy(0.0), QEvaporator(0.0), EvaporatorEnergy(0.0), QCondenser(0.0),
CondenserEnergy(0.0), MyOneTimeFlag(true), MyEnvrnFlag(true), GenInputOutputNodesUsed(false), EquipFlowCtrl(0)
{
}
};

struct ReportVars
{
// Members
Real64 PumpingPower; // reporting: electric pumping power
Real64 QGenerator; // reporting: steam heat transfer rate
Real64 QEvap; // reporting: evaporator heat transfer rate
Real64 QCond; // reporting: condensor heat transfer rate
Real64 PumpingEnergy; // reporting: electric pumping power
Real64 GeneratorEnergy; // reporting: steam heat transfer rate
Real64 EvapEnergy; // reporting: evaporator heat transfer rate
Real64 CondEnergy; // reporting: condensor heat transfer rate
Real64 CondInletTemp; // reporting: condenser inlet temperature
Real64 EvapInletTemp; // reporting: evaporator inlet temperature
Real64 CondOutletTemp; // reporting: condenser outlet temperature
Real64 EvapOutletTemp; // reporting: evaporator outlet temperature
Real64 Evapmdot; // reporting: evaporator mass flow rate
Real64 Condmdot; // reporting: condenser mass flow rate
Real64 Genmdot; // reporting: generatore mass flow rate when connected to plant
Real64 SteamMdot; // reporting: steam mass flow rate
Real64 ActualCOP; // reporting: coefficient of performance = QEvap/QGenerator

// Default Constructor
ReportVars()
: PumpingPower(0.0), QGenerator(0.0), QEvap(0.0), QCond(0.0), PumpingEnergy(0.0), GeneratorEnergy(0.0), EvapEnergy(0.0), CondEnergy(0.0),
CondInletTemp(0.0), EvapInletTemp(0.0), CondOutletTemp(0.0), EvapOutletTemp(0.0), Evapmdot(0.0), Condmdot(0.0), Genmdot(0.0),
SteamMdot(0.0), ActualCOP(0.0)
{
}
};

// Object Data
extern Array1D<BLASTAbsorberSpecs> BLASTAbsorber; // dimension to number of machines
extern Array1D<ReportVars> BLASTAbsorberReport;
static PlantComponent *factory(std::string const &objectName);

// Functions
void simulate(const PlantLocation &calledFromLocation, bool FirstHVACIteration, Real64 &CurLoad, bool RunFlag) override;

void SimBLASTAbsorber(std::string const &AbsorberType, // type of Absorber
std::string const &AbsorberName, // user specified name of Absorber
int const EquipFlowCtrl, // Flow control mode for the equipment
int const LoopNum, // Plant loop index for where called from
int const LoopSide, // Plant loop side index for where called from
int &CompIndex, // Chiller number pointer
bool const RunFlag, // simulate Absorber when TRUE
bool const FirstIteration, // initialize variables when TRUE
bool &InitLoopEquip, // If not zero, calculate the max load for operating conditions
Real64 &MyLoad, // loop demand component will meet
Real64 &MaxCap, // Maximum operating capacity of chiller [W]
Real64 &MinCap, // Minimum operating capacity of chiller [W]
Real64 &OptCap, // Optimal operating capacity of chiller [W]
bool const GetSizingFactor, // TRUE when just the sizing factor is requested
Real64 &SizingFactor, // sizing factor
Real64 &TempCondInDesign);
void onInitLoopEquip(const PlantLocation &calledFromLocation) override;

// End Absorption Chiller Module Driver Subroutines
//******************************************************************************
void getDesignCapacities(const PlantLocation &calledFromLocation, Real64 &MaxLoad, Real64 &MinLoad, Real64 &OptLoad) override;

// Beginning of Absorption Chiller Module Get Input subroutines
//******************************************************************************

void GetBLASTAbsorberInput();
void getDesignTemperatures(Real64 &tempDesCondIn, Real64 &TempDesEvapOut) override;

// End of Get Input subroutines for the Absorption Chiller Module
//******************************************************************************
void getSizingFactor(Real64 &sizFac) override;

void InitBLASTAbsorberModel(int const ChillNum, // number of the current electric chiller being simulated
bool const RunFlag, // TRUE when chiller operating
Real64 const MyLoad);
void initialize(bool RunFlag, Real64 MyLoad);

void SizeAbsorpChiller(int const ChillNum);
void setupOutputVars();

// Beginning of Absorber model Subroutines
// *****************************************************************************
void sizeChiller();

void CalcBLASTAbsorberModel(int &ChillNum, // Absorber number
Real64 &MyLoad, // operating load
bool const RunFlag, // TRUE when Absorber operating
bool const FirstIteration, // TRUE when first iteration of timestep !unused1208
int const EquipFlowCtrl // Flow control mode for the equipment
);
void calculate(Real64 &MyLoad, bool RunFlag);

// End of Absorption Chiller Module Utility Subroutines
// *****************************************************************************
void updateRecords(Real64 MyLoad, bool RunFlag);
};

// Beginning of Record Keeping subroutines for the Absorption Chiller Module
// *****************************************************************************
// Object Data
extern Array1D<BLASTAbsorberSpecs> BLASTAbsorber; // dimension to number of machines

void UpdateBLASTAbsorberRecords(Real64 const MyLoad, // current load
bool const RunFlag, // TRUE if Absorber operating
int const Num // Absorber number
);
void clear_state();

// End of Record Keeping subroutines for the Absorption Chiller Module
// *****************************************************************************
void GetBLASTAbsorberInput();

} // namespace ChillerAbsorption

Expand Down
4 changes: 2 additions & 2 deletions src/EnergyPlus/FaultsManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1401,9 +1401,9 @@ namespace FaultsManager {

} else if (UtilityRoutines::SameString(SELECT_CASE_VAR, "Chiller:Absorption")) {
// Read in chiller if not done yet
if (ChillerAbsorption::GetInput) {
if (ChillerAbsorption::getInput) {
ChillerAbsorption::GetBLASTAbsorberInput();
ChillerAbsorption::GetInput = false;
ChillerAbsorption::getInput = false;
}
// Check whether the chiller name and chiller type match each other
ChillerNum =
Expand Down
5 changes: 3 additions & 2 deletions src/EnergyPlus/Plant/PlantManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
#include <EnergyPlus/Boilers.hh>
#include <EnergyPlus/BoilerSteam.hh>
#include <EnergyPlus/BranchInputManager.hh>
#include <EnergyPlus/ChillerAbsorption.hh>
#include <EnergyPlus/CondenserLoopTowers.hh>
#include <EnergyPlus/CTElectricGenerator.hh>
#include <EnergyPlus/DataBranchAirLoopPlant.hh>
Expand Down Expand Up @@ -1121,6 +1122,7 @@ namespace EnergyPlus {
} else if (LoopSideNum == SupplySide) {
this_comp.CurOpSchemeType = UnknownStatusOpSchemeType;
}
this_comp.compPtr = ChillerAbsorption::BLASTAbsorberSpecs::factory(CompNames(CompNum));
} else if (UtilityRoutines::SameString(this_comp_type, "CoolingTower:SingleSpeed")) {
this_comp.TypeOf_Num = TypeOf_CoolingTower_SingleSpd;
this_comp.GeneralEquipType = GenEquipTypes_CoolingTower;
Expand Down Expand Up @@ -3935,8 +3937,7 @@ namespace EnergyPlus {
this_component.FlowCtrl = ControlType_Active;
this_component.FlowPriority = LoopFlowStatus_TakesWhatGets;
this_component.HowLoadServed = HowMet_ByNominalCap;
} else if (SELECT_CASE_var ==
TypeOf_Chiller_Absorption) { // = 3 ! older BLAST absorption chiller
} else if (SELECT_CASE_var == TypeOf_Chiller_Absorption) { // = 3 ! older BLAST absorption chiller
this_component.FlowCtrl = ControlType_Active;
if (LoopSideCtr == DemandSide) {
this_component.FlowPriority = LoopFlowStatus_NeedyAndTurnsLoopOn;
Expand Down
29 changes: 2 additions & 27 deletions src/EnergyPlus/PlantLoopEquip.cc
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,6 @@ namespace PlantLoopEquip {
// na

// Using/Aliasing
using ChillerAbsorption::SimBLASTAbsorber;
using ChillerElectricEIR::SimElectricEIRChiller;
using ChillerExhaustAbsorption::SimExhaustAbsorber;
using ChillerGasAbsorption::SimGasAbsorber;
Expand Down Expand Up @@ -343,32 +342,8 @@ namespace PlantLoopEquip {
}

} else if (EquipTypeNum == TypeOf_Chiller_Absorption) {
SimBLASTAbsorber(sim_component.TypeOf,
sim_component.Name,
EquipFlowCtrl,
LoopNum,
LoopSideNum,
EquipNum,
RunFlag,
FirstHVACIteration,
InitLoopEquip,
CurLoad,
MaxLoad,
MinLoad,
OptLoad,
GetCompSizFac,
SizingFac,
TempCondInDesign);
if (InitLoopEquip) {
sim_component.MaxLoad = MaxLoad;
sim_component.MinLoad = MinLoad;
sim_component.OptLoad = OptLoad;
sim_component.CompNum = EquipNum;
sim_component.TempDesCondIn = TempCondInDesign;
}
if (GetCompSizFac) {
sim_component.SizFac = SizingFac;
}

sim_component.compPtr->simulate(sim_component_location, FirstHVACIteration, CurLoad, RunFlag);

} else if (EquipTypeNum == TypeOf_Chiller_Indirect_Absorption) {
SimIndirectAbsorber(sim_component.TypeOf,
Expand Down
13 changes: 6 additions & 7 deletions tst/EnergyPlus/unit/ChillerAbsorption.unit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@

// Google Test Headers
#include <gtest/gtest.h>

// ObjexxFCL Headers
#include <ObjexxFCL/Array1D.hh>

// EnergyPlus Headers
#include <EnergyPlus/ChillerAbsorption.hh>
#include <EnergyPlus/DataLoopNode.hh>
#include <EnergyPlus/DataPlant.hh>
#include <EnergyPlus/OutputProcessor.hh>
#include <EnergyPlus/SimulationManager.hh>
#include <EnergyPlus/UtilityRoutines.hh>

#include "Fixtures/EnergyPlusFixture.hh"

Expand Down Expand Up @@ -1775,15 +1775,13 @@ TEST_F(EnergyPlusFixture, ChillerAbsorption_Calc)

ASSERT_TRUE(process_idf(idf_objects));

// OutputProcessor::TimeValue.allocate(2);
SimulationManager::ManageSimulation(); // run the design day

// set conditions for test
int AbsChillNum = 1;
int EquipFlowCtrl = 1;
Real64 AbsChillEvapLoad = 0.0;
Real64 AbsChillEvapLoad;
bool AbsChillRunFlag = true;
bool FirstIteration = true;
// check chiller inputs
EXPECT_EQ(BLASTAbsorber(AbsChillNum).NomCap, 100000.0);
EXPECT_EQ(BLASTAbsorber(AbsChillNum).FlowMode, ChillerAbsorption::LeavingSetPointModulated);
Expand Down Expand Up @@ -1819,8 +1817,9 @@ TEST_F(EnergyPlusFixture, ChillerAbsorption_Calc)
int GenLoopSideNum = BLASTAbsorber(AbsChillNum).GenLoopSideNum;
PlantLoop(GenLoopNum).LoopSide(GenLoopSideNum).FlowLock = 0;
// run CalcBLASTAbsorberModel
ChillerAbsorption::CalcBLASTAbsorberModel(AbsChillNum, AbsChillEvapLoad, AbsChillRunFlag, FirstIteration, EquipFlowCtrl);
// check generator hot water mass flow rate is propotional to the chilled water flow rate
ChillerAbsorption::BLASTAbsorber(1).EquipFlowCtrl = EquipFlowCtrl;
ChillerAbsorption::BLASTAbsorber(1).calculate(AbsChillEvapLoad, AbsChillRunFlag);
// check generator hot water mass flow rate is proportional to the chilled water flow rate
EXPECT_EQ(DataLoopNode::Node(GeneratorInletNode).MassFlowRate, GenMassFlowRateTestResult);
EXPECT_EQ(DataLoopNode::Node(GeneratorOutletNode).MassFlowRate, GenMassFlowRateTestResult);
}
Loading