Skip to content

Commit

Permalink
Update NFP and implement/test thermosiphon model
Browse files Browse the repository at this point in the history
  • Loading branch information
rraustad committed Apr 9, 2024
1 parent 53991f8 commit f882b68
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 13 deletions.
18 changes: 10 additions & 8 deletions design/FY2024/NFP-Refrigerant-Migration-Decarbonization.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ New Feature for Plant Decarbonization
**Florida Solar Energy Center***

- Original Date: Feb 27, 2024
- Final NFP - updated Apr 9, 2024

## Justification for Feature Update

Expand Down Expand Up @@ -37,35 +38,36 @@ Figure 1. Operating envelope and conditions for refrigerant migration

### Approach

This feature proposes to add 2 optional fields to chillers representing the refrigerant migration empirical model. Tentatively at the end of the object but these fields could be inserted near the capacity and COP inputs if that seems better placement. The curve is likely the only required input field to denote the use of this equipment enhancement (i.e., the resulting curve fraction will determine if the chiller can meet the load using only refrigerant migration), however, the zero crossing of the performance curve may not accurately represent the actual operating range and an additional field is suggested as Refrigerant Migration Minimum Temperature Difference (see following example for HeatPump:PlantLoop:EIR:Cooling). It is anticipated that both of these fields will be implemented in each chiller type.
This feature proposes to add 2 optional fields to chillers representing the refrigerant migration (or generically a thermosiphon for passive heat exchange) empirical model. Tentatively at the end of the object but these fields could be inserted near the capacity and COP inputs if that seems better placement. The curve is likely the only required input field to denote the use of this equipment enhancement (i.e., the resulting curve fraction will determine if the chiller can meet the load using only refrigerant migration), however, the zero crossing of the performance curve may not accurately represent the actual operating range and an additional field is suggested as Refrigerant Migration Minimum Temperature Difference (see following example for HeatPump:PlantLoop:EIR:Cooling). It is anticipated that both of these fields will be implemented in each chiller type.

```
HeatPump:PlantLoop:EIR:Cooling,
A13, \field Refrigerant Migration Temperature Difference Curve Name
A13, \field Thermosiphon Temperature Difference Curve Name
\type object-list
\object-list UniVariateFunctions
\note quadratic curve = a + b * dT is typical, other univariate curves may be used
N10; \field Refrigerant Migration Minimum Temperature Difference
\note dT = evaporator outlet temperature minus condenser inlet temperature
N10; \field Thermosiphon Minimum Temperature Difference
\type real
\minimum>=0
\minimum 0.0
\default 0.0
\note refirgerant migration is disabled below this minimum limit and
\note thermosiphon model is disabled below this minimum limit and
\note when the load is greater than calculated using the prevoius field.
Chiller:Electric,
A14; \field Refrigerant Migration Temperature Difference Curve Name
A14; \field Thermosiphon Temperature Difference Curve Name
\type object-list
\object-list UniVariateFunctions
\note quadratic curve = a + b * dT is typical, other univariate curves may be used
Chiller:Electric:EIR,
A17; \field Refrigerant Migration Temperature Difference Curve Name
A17; \field Thermosiphon Temperature Difference Curve Name
\type object-list
\object-list UniVariateFunctions
\note quadratic curve = a + b * dT is typical, other univariate curves may be used
Chiller:Electric:Reformulated:EIR,
A16; \field Refrigerant Migration Temperature Difference Curve Name
A16; \field Thermosiphon Temperature Difference Curve Name
\type object-list
\object-list UniVariateFunctions
\note quadratic curve = a + b * dT is typical, other univariate curves may be used
Expand Down
15 changes: 15 additions & 0 deletions doc/input-output-reference/src/overview/group-plant-equipment.tex
Original file line number Diff line number Diff line change
Expand Up @@ -5451,6 +5451,14 @@ \subsubsection{Inputs}\label{plhp_eir_cooling_inputs}

This optional alpha field specifies the name of a univariate curve or table that defines the maximum supply water temperature.

\paragraph{Field: Thermosiphon Temperature Difference Curve Name}\label{plhp_eir_cooling_inputs_thermosiphon_temperature_difference_curve_name}

This optional alpha field specifies the name of a univariate curve or table that defines the thermosiphon capacity fraction as a function of temperature difference between the load side outlet node and source side inlet node. If this field is blank, the thermosiphon model is disabled.

\paragraph{Field: Thermosiphon Minimum Temperature Difference}\label{plhp_eir_cooling_inputs_thermosiphon_minimum_temperature_difference}

This optional numeric field specifies the temperature difference above which the thermosiphon model is active. The default value is 0. Above this temperature difference the heat pump compressor will be off.

\subsection{HeatPump:PlantLoop:EIR:Heating}\label{plhp_eir_heating}

The EIR-formulated heating model objects are described.
Expand Down Expand Up @@ -5696,6 +5704,13 @@ \subsubsection{Outputs}\label{plhp_eir_outputs}
HVAC,Average,Heat Pump Source Side Mass Flow Rate {[}kg/s{]}
\end{itemize}

Outputs specific to HeatPump:PlantLoop:EIR:Cooling

\begin{itemize}
\item
HVAC,Average,Heat Pump Thermosiphon Status {[}{]}
\end{itemize}

Outputs specific to HeatPump:PlantLoop:EIR:Heating

\begin{itemize}
Expand Down
15 changes: 14 additions & 1 deletion idd/Energy+.idd.in
Original file line number Diff line number Diff line change
Expand Up @@ -74991,11 +74991,24 @@ HeatPump:PlantLoop:EIR:Cooling,
\object-list UniVariateFunctions
\note quadratic curve = a + b*OAT is typical, other univariate curves may be used
\note OAT = Outdoor Dry-Bulb Temperature
N10; \field Maximum Supply Water Temperature Curve Name
N10, \field Maximum Supply Water Temperature Curve Name
\type object-list
\object-list UniVariateFunctions
\note quadratic curve = a + b*OAT is typical, other univariate curves may be used
\note OAT = Outdoor Dry-Bulb Temperature
A13, \field Thermosiphon Temperature Difference Curve Name
\type object-list
\object-list UniVariateFunctions
\note quadratic curve = a + b * dT is typical, other univariate curves may be used
\note dT = evaporator outlet temperature minus condenser inlet temperature
\note If this field is blank the thermosiphon model is disabled.
N11; \field Thermosiphon Minimum Temperature Difference
\type real
\minimum 0.0
\default 0.0
\note Thermosiphon model is disabled below this minimum limit and
\note when the load is greater than calculated using the prevoius field.


HeatPump:PlantLoop:EIR:Heating,
\memo An EIR formulated water to water heat pump model, heating operation
Expand Down
46 changes: 44 additions & 2 deletions src/EnergyPlus/PlantLoopHeatPumpEIR.cc
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ void EIRPlantLoopHeatPump::resetReportingVariables()
this->partLoadRatio = 0.0;
this->cyclingRatio = 0.0;
this->defrostPowerMultiplier = 1.0;
this->thermosiphonStatus = 0;
}

void EIRPlantLoopHeatPump::setOperatingFlowRatesWSHP(EnergyPlusData &state, bool FirstHVACIteration)
Expand Down Expand Up @@ -375,6 +376,7 @@ void EIRPlantLoopHeatPump::doPhysicsASHP(EnergyPlusData &state, Real64 currentLo

void EIRPlantLoopHeatPump::calcAvailableCapacity(EnergyPlusData &state, Real64 const currentLoad, Real64 &availableCapacity, Real64 &partLoadRatio)
{
this->thermosiphonStatus = 0;
// get setpoint on the load side outlet
Real64 loadSideOutletSetpointTemp = this->getLoadSideOutletSetPointTemp(state);
Real64 originalLoadSideOutletSPTemp = loadSideOutletSetpointTemp;
Expand Down Expand Up @@ -507,8 +509,10 @@ void EIRPlantLoopHeatPump::calcPowerUsage(EnergyPlusData &state)
this->eirModCurveCheck(state, eirModifierFuncTemp, eirModifierFuncPLR);

// compute power usage
this->powerUsage = (this->loadSideHeatTransfer / this->referenceCOP) * eirModifierFuncPLR * eirModifierFuncTemp * this->defrostPowerMultiplier *
this->cyclingRatio;
if (this->thermosiphonDisabled(state)) {
this->powerUsage = (this->loadSideHeatTransfer / this->referenceCOP) * eirModifierFuncPLR * eirModifierFuncTemp *
this->defrostPowerMultiplier * this->cyclingRatio;
}
}

void EIRPlantLoopHeatPump::calcSourceSideHeatTransferWSHP(EnergyPlusData &state)
Expand Down Expand Up @@ -1450,6 +1454,16 @@ void EIRPlantLoopHeatPump::processInputForEIRPLHP(EnergyPlusData &state)
thisPLHP.maxSupplyWaterTempCurveIndex =
Curve::GetCurveIndex(state, Util::makeUPPER(maximumSupplyWaterTempCurveName.value().get<std::string>()));
}
// fields only in cooling object
if (thisPLHP.EIRHPType == DataPlant::PlantEquipmentType::HeatPumpEIRCooling) {
auto const thermosiphonTempCurveName = fields.find("thermosiphon_temperature_difference_curve_name");
if (thermosiphonTempCurveName != fields.end()) {
thisPLHP.thermosiphonTempCurveIndex =
Curve::GetCurveIndex(state, Util::makeUPPER(thermosiphonTempCurveName.value().get<std::string>()));
}
thisPLHP.thermosiphonMinTempDiff = state.dataInputProcessing->inputProcessor->getRealFieldValue(
fields, schemaProps, "thermosiphon_minimum_temperature_difference");
}

std::string flowControlTypeName =
Util::makeUPPER(state.dataInputProcessing->inputProcessor->getAlphaFieldValue(fields, schemaProps, "flow_mode"));
Expand Down Expand Up @@ -1788,6 +1802,13 @@ void EIRPlantLoopHeatPump::oneTimeInit(EnergyPlusData &state)
OutputProcessor::Group::Plant,
OutputProcessor::EndUseCat::Cooling,
"Heat Pump");
SetupOutputVariable(state,
"Heat Pump Thermosiphon Status",
Constant::Units::None,
this->thermosiphonStatus,
OutputProcessor::TimeStepType::System,
OutputProcessor::StoreType::Average,
this->name);
} else if (this->EIRHPType == DataPlant::PlantEquipmentType::HeatPumpEIRHeating) { // energy from HeatPump:PlantLoop:EIR:Heating object
SetupOutputVariable(state,
"Heat Pump Electricity Energy",
Expand Down Expand Up @@ -1929,6 +1950,27 @@ void EIRPlantLoopHeatPump::oneTimeInit(EnergyPlusData &state)
}
}

bool EIRPlantLoopHeatPump::thermosiphonDisabled(EnergyPlusData &state)
{
if (this->thermosiphonTempCurveIndex > 0) {
this->thermosiphonStatus = 0;
Real64 dT = this->loadSideOutletTemp - this->sourceSideInletTemp;
if (dT < this->thermosiphonMinTempDiff) {
return true;
}
Real64 thermosiphonCapFrac = Curve::CurveValue(state, this->thermosiphonTempCurveIndex, dT);
Real64 capFrac = this->partLoadRatio * this->cyclingRatio;
if (thermosiphonCapFrac > capFrac && this->loadSideHeatTransfer > 0.0) {
this->thermosiphonStatus = 1;
this->powerUsage = 0.0;
return false;
}
return true;
} else {
return true;
}
}

void EIRPlantLoopHeatPump::report(EnergyPlusData &state)
{

Expand Down
7 changes: 7 additions & 0 deletions src/EnergyPlus/PlantLoopHeatPumpEIR.hh
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,11 @@ namespace EIRPlantLoopHeatPumps {
Real64 maxOutdoorTemperatureDefrost = 0.0;
Real64 defrostPowerMultiplier = 1.0; // defrost power adjustment factor

// thermosiphon model
int thermosiphonTempCurveIndex = 0;
Real64 thermosiphonMinTempDiff = 0.0;
int thermosiphonStatus = 0;

// a couple worker functions to easily allow merging of cooling and heating operations
std::function<Real64(Real64, Real64)> calcLoadOutletTemp;
std::function<Real64(Real64, Real64)> calcQsource;
Expand Down Expand Up @@ -291,6 +296,8 @@ namespace EIRPlantLoopHeatPumps {
void isPlantInletOrOutlet(EnergyPlusData &state);

void oneTimeInit(EnergyPlusData &state) override;

bool thermosiphonDisabled(EnergyPlusData &state);
};

struct EIRFuelFiredHeatPump : public EIRPlantLoopHeatPump
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8441,7 +8441,13 @@
EIRCurveFuncPLR, !- Electric Input to Output Ratio Modifier Function of Part Load Ratio Curve Name
Setpoint, !- Control Type
VariableSpeedPumping, !- Flow Mode
0.2; !- Minimum Part Load Ratio
0.2, !- Minimum Part Load Ratio
, !- Minimum Source Inlet Temperature
, !- Maximum Source Inlet Temperature
, !- Minimum Supply Water Temperature Curve Name
, !- Maximum Supply Water Temperature Curve Name
ThermosiphonCurve, !- Thermosiphon Temperature Difference Curve Name
2.0; !- Thermosiphon Minimum Temperature Difference

OutdoorAir:Node,
AWHP_1 Cooling Side Condenser Air Inlet Node,
Expand All @@ -8465,7 +8471,22 @@
EIRCurveFuncPLR, !- Electric Input to Output Ratio Modifier Function of Part Load Ratio Curve Name
Setpoint, !- Control Type
VariableSpeedPumping, !- Flow Mode
0.2; !- Minimum Part Load Ratio
0.2, !- Minimum Part Load Ratio
, !- Minimum Source Inlet Temperature
, !- Maximum Source Inlet Temperature
, !- Minimum Supply Water Temperature Curve Name
, !- Maximum Supply Water Temperature Curve Name
ThermosiphonCurve, !- Thermosiphon Temperature Difference Curve Name
2.0; !- Thermosiphon Minimum Temperature Difference

Curve:Linear,
ThermosiphonCurve, !- Name
0, !- Coefficient1 Constant
0.06, !- Coefficient2 x
0, !- Minimum Value of x
30.0, !- Maximum Value of x
0.0, !- Minimum Curve Output
1.0; !- Maximum Curve Output

!- ACX 140 Biquadratic cooling curves provided by Trane
Curve:Biquadratic,
Expand Down Expand Up @@ -10315,6 +10336,7 @@ Curve:Biquadratic,
Output:Variable,*,Heat Pump Electricity Rate,hourly; !- HVAC Average [W]
Output:Variable,*,Heat Pump Load Side Mass Flow Rate,hourly; !- HVAC Average [kg/s]
Output:Variable,*,Heat Pump Source Side Mass Flow Rate,hourly; !- HVAC Average [kg/s]
Output:Variable,*,Heat Pump Thermosiphon Status,hourly; !- HVAC Average [kg/s]

Output:Variable,*,Boiler Heating Rate,hourly; !- HVAC Average [W]
Output:Variable,*,Boiler Inlet Temperature,hourly; !- HVAC Average [C]
Expand Down

5 comments on commit f882b68

@nrel-bot-2
Copy link

Choose a reason for hiding this comment

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

NFP-Refrigerant-Migration-Decarbonization (rraustad) - x86_64-Linux-Ubuntu-22.04-gcc-11.4: OK (3595 of 3595 tests passed, 4 test warnings)

Messages:\n

  • 4 tests had: AUD diffs.
  • 4 tests had: RDD diffs.
  • 1 test had: MTD diffs.

Build Badge Test Badge

@nrel-bot
Copy link

Choose a reason for hiding this comment

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

NFP-Refrigerant-Migration-Decarbonization (rraustad) - Win64-Windows-10-VisualStudio-16: OK (2766 of 2766 tests passed, 0 test warnings)

Build Badge Test Badge

@nrel-bot-2b
Copy link

Choose a reason for hiding this comment

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

NFP-Refrigerant-Migration-Decarbonization (rraustad) - x86_64-Linux-Ubuntu-22.04-gcc-11.4-UnitTestsCoverage-Debug: OK (1978 of 1978 tests passed, 0 test warnings)

Build Badge Test Badge Coverage Badge

@nrel-bot-2c
Copy link

Choose a reason for hiding this comment

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

NFP-Refrigerant-Migration-Decarbonization (rraustad) - x86_64-Linux-Ubuntu-22.04-gcc-11.4-IntegrationCoverage-Debug: OK (791 of 791 tests passed, 0 test warnings)

Build Badge Test Badge Coverage Badge

@nrel-bot-3
Copy link

Choose a reason for hiding this comment

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

NFP-Refrigerant-Migration-Decarbonization (rraustad) - x86_64-MacOS-10.18-clang-15.0.0: OK (3554 of 3554 tests passed, 4 test warnings)

Messages:\n

  • 4 tests had: AUD diffs.
  • 4 tests had: RDD diffs.
  • 1 test had: MTD diffs.

Build Badge Test Badge

Please sign in to comment.