Skip to content
Draft
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,8 @@ \subsubsection{Common Pipe}\label{common-pipe}
The flow at the inlet node of the half loop is equal to the flow at the outlet node of the half loop.
\item
The pumps can have different schedules and any loop can be shut off when the other loop is still running.
\item
If the primary-side, or supply-side, inlet pump is a variable speed pump, the common pipe model accepts it. For CommonPipe, the primary flow remains governed by the pump and loop controls; for Two-Way CommonPipe, the solver can request primary flow through the pump while resolving the interface balances.
\end{itemize}

\begin{figure}[hbtp] % fig 125
Expand Down Expand Up @@ -709,6 +711,8 @@ \subsubsection{Two-Way Common Pipe}\label{two-way-common-pipe}
The mass flow rate at the Secondary Side Outlet Node is always equal to the mass flow rate at the Secondary Side Inlet Node.
\item
Only one additional node, either primary-side inlet or secondary-side inlet, (along with the primary-side/supply-side outlet node) can be controlled. The system of equations that describe the loop interface will be under specified if both the Primary and Secondary Inlet nodes have to be controlled.
\item
If the primary-side, or supply-side, inlet pump is a variable speed pump, the Two-Way Common Pipe solver can request primary flow through the pump as part of resolving the interface balances. The temperature control is still resolved by the common pipe flow balances using the available primary and secondary flows.
\end{itemize}

Figure~\ref{fig:schematic-of-a-two-way-common-pipe-used-in} shows a schematic of the Two-Way Common Pipe. There are two common pipe legs, shown as broken lines, allow for some recirculation at the half loop level.~ The model allows for common pipe flow in either or both directions. The model determines flow rates in the common pipes and temperatures at nodes based on the following:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ \subsubsection{Inputs}\label{inputs-035}

This field specifies a primary-secondary plant loop simulation. When a common pipe option is specified, the plant side of the loop is the primary loop and the demand side of the loop is the secondary loop, and a pump object must be placed on the demand side inlet branch. The three options are ``\textbf{None}'', ``\textbf{CommonPipe}'' and ``\textbf{TwoWayCommonPipe}''. ``\textbf{None}'' means that there is no secondary loop and the plant loop is modeled as a single primary loop. ``\textbf{CommonPipe}'' means that the common pipe interface does not attempt any temperature control, it only satisfies secondary (demand side) flow requests. ``\textbf{TwoWayCommonPipe}'' allows control of the secondary (demand side) inlet temperature or the primary (plant side) inlet temperature by placing a setpoint on the corresponding node. If this field is left blank, it will default to ''None''. If the field is set to ``None'' and the program finds a pump on the demand side it will result in a fatal error.~ If the field is set to ``CommonPipe'' or ``TwoWayCommonPipe'' and the program does not find a pump on the demand side it will result in a fatal error. The common pipe simulation is currently limited to simulating loop pumps, i.e.~each pump should be placed on the inlet branch of the plant side or demand side of the loop.

If a variable speed pump is placed on the plant side inlet branch with \textbf{CommonPipe}, the primary flow remains governed by the pump and loop flow controls. With \textbf{TwoWayCommonPipe}, the common pipe solver can request primary flow through a variable speed plant-side inlet pump when resolving the primary inlet temperature balance.

\paragraph{Field: Pressure Simulation Type}\label{field-pressure-simulation-type}

This field lets user to choose if this plant loop will be involved in a pressure drop calculation.~ This requires that at least one branch on the loop have pressure drop data.~ If not, an error will be thrown due to the input mismatch.~ Currently there are two pressure drop simulation types: ``PumpPowerCorrection'' and ``LoopFlowCorrection''.~ In both of these methods, branch pressure drop data is used to calculate a dynamic loop pressure drop and is used to update pumping power accordingly.~ The flow correction method allows the user to enter information regarding the pressure curve of a constant speed pump so that the simulation can dynamically resolve the pressure vs.~flow relationship in the plant loop.~ This is limited to constant speed pumps, as the variable speed pumps are expected to resolve as if it were controlled by a variable drive, so that they can inherently meet any pressure and flow demand required by the loop.~ This is also limited to ``loop pumps'', where there is a single pump on the plant loop. Common pipe simulations and ``branch pump'' simulations are not compatible with this level of pressure simulation.~ See the documentation for the \hyperref[pumpconstantspeed]{Pump:ConstantSpeed} in order to determine required inputs for this pressure simulation method to be performed.~ In the pressure drop system, parallel flow rates are not resolved (to match the pressure drop for the parallel system).~ Enhancements to this calculation are planned which will allow parallel branch flow resolution.~ See the Engineering Reference document for more information on how this works.
Expand Down
5 changes: 5 additions & 0 deletions idd/Energy+.idd.in
Original file line number Diff line number Diff line change
Expand Up @@ -83467,6 +83467,11 @@ PlantLoop,
\note TwoWayCommonPipe = Primary-secondary with control of secondary supply temperature or
\note primary return temperature (requires a setpoint be placed on the
\note plant side or demand side inlet node).
\note If a variable speed pump is placed on the plant side inlet branch with
\note CommonPipe or TwoWayCommonPipe, EnergyPlus accepts it. For
\note CommonPipe, the primary flow remains governed by the pump and loop
\note controls. For TwoWayCommonPipe, the solver can request primary flow
\note through the pump as part of resolving the common pipe balance.
\type choice
\key CommonPipe
\key TwoWayCommonPipe
Expand Down
72 changes: 43 additions & 29 deletions src/EnergyPlus/HVACInterfaceManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -839,9 +839,14 @@ void UpdateCommonPipe(EnergyPlusData &state,
ManageSingleCommonPipe(state, LoopNum, TankOutletLoopSide, TankAverageTemp, MixedOutletTemp);
// 2-way (controlled) common pipe simulation
} else if (CommonPipeType == DataPlant::CommonPipeType::TwoWay) {
PlantLocation TankOutletPlantLoc = {LoopNum, TankOutletLoopSide, 0, 0};
if (!state.dataHVACInterfaceMgr->CommonPipeSetupFinished) {
SetupCommonPipes(state);
}
auto const &plantCommonPipe = state.dataHVACInterfaceMgr->PlantCommonPipe(LoopNum);
auto const &tankOutletPlantLoc = (TankOutletLoopSide == DataPlant::LoopSideLocation::Supply) ? plantCommonPipe.SupplySideInletPlantLoc
: plantCommonPipe.DemandSideInletPlantLoc;

ManageTwoWayCommonPipe(state, TankOutletPlantLoc, TankAverageTemp);
ManageTwoWayCommonPipe(state, tankOutletPlantLoc, TankAverageTemp);
MixedOutletTemp = state.dataLoopNodes->Node(TankOutletNode).Temp;
}

Expand Down Expand Up @@ -1010,6 +1015,7 @@ void ManageTwoWayCommonPipe(EnergyPlusData &state, PlantLocation const &plantLoc

auto &plantCommonPipe(state.dataHVACInterfaceMgr->PlantCommonPipe(plantLoc.loopNum));
auto &thisPlantLoop = state.dataPlnt->PlantLoop(plantLoc.loopNum);
bool const canRequestPrimaryInletFlow = plantCommonPipe.SupplySideInletPlantLoc.side->FlowLock != DataPlant::FlowLock::Locked;

// fill local node indexes
int const NodeNumPriIn = thisPlantLoop.LoopSide(DataPlant::LoopSideLocation::Supply).NodeNumIn;
Expand Down Expand Up @@ -1117,19 +1123,23 @@ void ManageTwoWayCommonPipe(EnergyPlusData &state, PlantLocation const &plantLoc

// eq. 3
if ((plantCommonPipe.SupplySideInletPumpType == FlowType::Variable) && (curCallingCase == UpdateType::SupplyLedPrimaryInlet)) {
// MdotPri is a variable to be calculated and flow request needs to be made
if (std::abs(TempCPPrimaryCntrlSetPoint) > DataPlant::DeltaTempTol) {

MdotPri = (MdotPriRCLeg * TempPriOutTankOut + MdotPriToSec * TempSecOutTankOut) / (TempCPPrimaryCntrlSetPoint);

if (MdotPri < DataBranchAirLoopPlant::MassFlowTolerance) {
MdotPri = 0.0;
// Use the available secondary flow and request the primary recirculation needed to meet the primary inlet setpoint.
MdotPriToSec = MdotSec;
if (std::abs(TempCPPrimaryCntrlSetPoint - TempPriOutTankOut) > DataPlant::DeltaTempTol) {
MdotPriRCLeg = MdotPriToSec * (TempSecOutTankOut - TempCPPrimaryCntrlSetPoint) / (TempCPPrimaryCntrlSetPoint - TempPriOutTankOut);
if (MdotPriRCLeg < DataBranchAirLoopPlant::MassFlowTolerance) {
MdotPriRCLeg = 0.0;
}
} else {
MdotPri = MdotSec;
MdotPriRCLeg = 0.0;
}
MdotPri = MdotPriToSec + MdotPriRCLeg;
if (MdotPri < DataBranchAirLoopPlant::MassFlowTolerance) {
MdotPri = 0.0;
}
if (canRequestPrimaryInletFlow) {
PlantUtilities::SetActuatedBranchFlowRate(state, MdotPri, NodeNumPriIn, plantCommonPipe.SupplySideInletPlantLoc, false);
}
PlantLocation thisPlantLoc = {plantLoc.loopNum, DataPlant::LoopSideLocation::Supply, 1, 0};
PlantUtilities::SetActuatedBranchFlowRate(state, MdotPri, NodeNumPriIn, thisPlantLoc, false);
}

// eq. 2
Expand Down Expand Up @@ -1177,8 +1187,9 @@ void ManageTwoWayCommonPipe(EnergyPlusData &state, PlantLocation const &plantLoc
} else {
MdotPri = MdotSec;
}
PlantLocation thisPlantLoc = {plantLoc.loopNum, DataPlant::LoopSideLocation::Supply, 1, 0};
PlantUtilities::SetActuatedBranchFlowRate(state, MdotPri, NodeNumPriIn, thisPlantLoc, false);
if (canRequestPrimaryInletFlow) {
PlantUtilities::SetActuatedBranchFlowRate(state, MdotPri, NodeNumPriIn, plantCommonPipe.SupplySideInletPlantLoc, false);
}
}

// eq. 4
Expand Down Expand Up @@ -1232,6 +1243,10 @@ void SetupCommonPipes(EnergyPlusData &state)
auto &thisCommonPipe = state.dataHVACInterfaceMgr->PlantCommonPipe(CurLoopNum);
auto const &first_demand_component_type = thisPlantLoop.LoopSide(DataPlant::LoopSideLocation::Demand).Branch(1).Comp(1).Type;
auto const &first_supply_component_type = thisPlantLoop.LoopSide(DataPlant::LoopSideLocation::Supply).Branch(1).Comp(1).Type;
thisCommonPipe.SupplySideInletPlantLoc = {CurLoopNum, DataPlant::LoopSideLocation::Supply, 1, 0};
PlantUtilities::SetPlantLocationLinks(state, thisCommonPipe.SupplySideInletPlantLoc);
thisCommonPipe.DemandSideInletPlantLoc = {CurLoopNum, DataPlant::LoopSideLocation::Demand, 1, 0};
PlantUtilities::SetPlantLocationLinks(state, thisCommonPipe.DemandSideInletPlantLoc);

switch (thisPlantLoop.CommonPipeType) {
case DataPlant::CommonPipeType::No:
Expand Down Expand Up @@ -1261,12 +1276,12 @@ void SetupCommonPipes(EnergyPlusData &state)
OutputProcessor::StoreType::Average,
thisPlantLoop.Name);

if (first_supply_component_type == DataPlant::PlantEquipmentType::PumpVariableSpeed) {
// If/when the model supports variable-pumping primary, this can be removed.
ShowWarningError(state, "SetupCommonPipes: detected variable speed pump on supply inlet of CommonPipe plant loop");
ShowContinueError(state, std::format("Occurs on plant loop name = {}", thisPlantLoop.Name));
ShowContinueError(state, "The common pipe model does not support varying the flow rate on the primary/supply side");
ShowContinueError(state, "The primary/supply side will operate as if constant speed, and the simulation continues");
if (first_supply_component_type == DataPlant::PlantEquipmentType::PumpConstantSpeed ||
first_supply_component_type == DataPlant::PlantEquipmentType::PumpBankConstantSpeed) {
thisCommonPipe.SupplySideInletPumpType = FlowType::Constant;
} else if (first_supply_component_type == DataPlant::PlantEquipmentType::PumpVariableSpeed ||
first_supply_component_type == DataPlant::PlantEquipmentType::PumpBankVariableSpeed) {
thisCommonPipe.SupplySideInletPumpType = FlowType::Variable;
}
break;
case DataPlant::CommonPipeType::TwoWay: // Controlled ('two-way') common pipe
Expand Down Expand Up @@ -1301,20 +1316,19 @@ void SetupCommonPipes(EnergyPlusData &state)
thisPlantLoop.Name);

// check type of pump on supply side inlet
if (first_supply_component_type == DataPlant::PlantEquipmentType::PumpConstantSpeed) {
if (first_supply_component_type == DataPlant::PlantEquipmentType::PumpConstantSpeed ||
first_supply_component_type == DataPlant::PlantEquipmentType::PumpBankConstantSpeed) {
thisCommonPipe.SupplySideInletPumpType = FlowType::Constant;
} else if (first_supply_component_type == DataPlant::PlantEquipmentType::PumpVariableSpeed) {
} else if (first_supply_component_type == DataPlant::PlantEquipmentType::PumpVariableSpeed ||
first_supply_component_type == DataPlant::PlantEquipmentType::PumpBankVariableSpeed) {
thisCommonPipe.SupplySideInletPumpType = FlowType::Variable;
// If/when the model supports variable-pumping primary, this can be removed.
ShowWarningError(state, "SetupCommonPipes: detected variable speed pump on supply inlet of TwoWayCommonPipe plant loop");
ShowContinueError(state, std::format("Occurs on plant loop name = {}", thisPlantLoop.Name));
ShowContinueError(state, "The common pipe model does not support varying the flow rate on the primary/supply side");
ShowContinueError(state, "The primary/supply side will operate as if constant speed, and the simulation continues");
}
// check type of pump on demand side inlet
if (first_demand_component_type == DataPlant::PlantEquipmentType::PumpConstantSpeed) {
if (first_demand_component_type == DataPlant::PlantEquipmentType::PumpConstantSpeed ||
first_demand_component_type == DataPlant::PlantEquipmentType::PumpBankConstantSpeed) {
thisCommonPipe.DemandSideInletPumpType = FlowType::Constant;
} else if (first_demand_component_type == DataPlant::PlantEquipmentType::PumpVariableSpeed) {
} else if (first_demand_component_type == DataPlant::PlantEquipmentType::PumpVariableSpeed ||
first_demand_component_type == DataPlant::PlantEquipmentType::PumpBankVariableSpeed) {
thisCommonPipe.DemandSideInletPumpType = FlowType::Variable;
}
break;
Expand Down
2 changes: 2 additions & 0 deletions src/EnergyPlus/HVACInterfaceManager.hh
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ namespace HVACInterfaceManager {
DataPlant::CommonPipeType CommonPipeType = DataPlant::CommonPipeType::No; // type of common pipe used if any
FlowType SupplySideInletPumpType = FlowType::Invalid;
FlowType DemandSideInletPumpType = FlowType::Invalid;
PlantLocation SupplySideInletPlantLoc;
PlantLocation DemandSideInletPlantLoc;
// Following report variables are used in uncontrolled common pipe
int FlowDir = 0; // Direction in which flow is in Common Pipe
Real64 Flow = 0.0; // Flow in the Common Pipe
Expand Down
Loading
Loading