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

Allow zone hvac to draw return air #8719

Merged
merged 51 commits into from Aug 5, 2021

Conversation

lgu1234
Copy link
Contributor

@lgu1234 lgu1234 commented Apr 16, 2021

Pull request overview

The new feature requests Zone HVAC objects to draw inlet air from return plenum and return duct. It should be pointed out that no return duct losses are calculated in Existing EnergyPlus, except for the AirflowNetwork model (beyond the topic for this new feature). Instead, light heat from return fraction is added to the return node after mixing. Therefore, light heat will be added into the drawn air for the scenario with return duct. There is no modification for the scenario with return plenum.

This new feature is applied to the system configuration only when a zone equipment and an AirLoop serve the same zone. The proposed IO modification will be made in the ZoneHVAC:EquipmentConnections object by adding a new field as Plenum or Return Air Node Name for the last position, so that no transition is needed for this new feature.

The feature request is GitHub Issue #8190 at #8190

Test files are attached here.

Pull Request Author

Add to this list or remove from it as applicable. This is a simple templated set of guidelines.

  • Title of PR should be user-synopsis style (clearly understandable in a standalone changelog context)
  • [ X] Label the PR with at least one of: Defect, Refactoring, NewFeature, Performance, and/or DoNoPublish
  • [X ] Pull requests that impact EnergyPlus code must also include unit tests to cover enhancement or defect repair
  • [X ] Author should provide a "walkthrough" of relevant code changes using a GitHub code review comment process
  • If any diffs are expected, author must demonstrate they are justified using plots and descriptions
  • If changes fix a defect, the fix should be demonstrated in plots and descriptions
  • If any defect files are updated to a more recent version, upload new versions here or on DevSupport
  • If IDD requires transition, transition source, rules, ExpandObjects, and IDFs must be updated, and add IDDChange label
  • If structural output changes, add to output rules file and add OutputChange label
  • If adding/removing any LaTeX docs or figures, update that document's CMakeLists file dependencies

Reviewer

This will not be exhaustively relevant to every PR.

  • Perform a Code Review on GitHub
  • If branch is behind develop, merge develop and build locally to check for side effects of the merge
  • If defect, verify by running develop branch and reproducing defect, then running PR and reproducing fix
  • If feature, test running new feature, try creative ways to break it
  • CI status: all green or justified
  • Check that performance is not impacted (CI Linux results include performance check)
  • Run Unit Test(s) locally
  • Check any new function arguments for performance impacts
  • Verify IDF naming conventions and styles, memos and notes and defaults
  • If new idf included, locally check the err file and other outputs

@lgu1234 lgu1234 added IDDChange Code changes impact the IDD file (cannot be merged after IO freeze) NewFeature Includes code to add a new feature to EnergyPlus labels Apr 16, 2021
@@ -648,6 +648,7 @@ namespace DataHeatBalance {
Real64 FractionReturnAirPlenTempCoeff1;
Real64 FractionReturnAirPlenTempCoeff2;
int ZoneReturnNum; // zone return index (not the node number) for return heat gain
int ZoneExhaustNodeNum; // Exhaust node number
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Add a new variable to store zone exhaust node number in the Lights object

Copy link
Contributor

Choose a reason for hiding this comment

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

Why a single node number here? And why do the lights care what kind of node this is?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mjwitte Although the Lights object does not care what kind of node is, this new feature only adds an additional exhaust node to share the return gain. The existing function only adds return heat gain into a single return node. If a user wants to have more return gain share, more Lights object may be listed.

@@ -265,6 +265,7 @@ namespace DataZoneEquipment {
Array1D_bool FixedReturnFlow; // true if return node is fixed and cannot be adjusted in CalcZoneReturnFlows
Array1D_int ReturnNodePlenumNum; // number of the return plenum attached to this return node (zero if none)
Array1D_int ReturnFlowBasisNode; // return air flow basis nodes
Array1D_int ReturnNodeExhaustNodeNum; // Exhaust node number flow to a corrsponding return node due to light heat gain
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Add a new 1-D array to store exhaust node number in ZoneEquipConfig

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see why ReturnNodeExhaustNodeNum is necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mjwitte Since we allow multiple Lights objects in a single zone, it is possible there are multiple exhaust nodes in a single zone, so that an 1-D array is created. If not necessary, do you have any suggestions to store exhaust node information in ZoneEquipConfig?

ShowContinueError(state, "..FanCoil inlet node name = " + state.dataLoopNodes->NodeID(FanCoil(FanCoilNum).AirInNode));
ErrorsFound = true;
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Allow FanCoil to accept an induced node of return plenum as an inlet node with ATMixer at the supply side, in addition to a zone exhaust node.

ShowContinueError(state,
"..Fan coil unit air inlet node name = " + state.dataLoopNodes->NodeID(FanCoil(FanCoilNum).AirInNode));
ErrorsFound = true;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Allow FanCoil to accept an induced node of return plenum as an inlet node without ATMixer, in addition to a zone exhaust node.

}
} else {
state.dataHeatBal->Lights(Loop).ZoneReturnNum = ZoneReturnNum;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Allow Lights object to accept a NodeList as Return Air Heat Gain, in addition to return node name.

Copy link
Contributor

Choose a reason for hiding this comment

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

If the Lights input is Return Air Heat Gain Node or NodeList Name then it should accept any number of nodes in the list. If there is a reason to limit it to a single return node and/or a single plenum induced air node, then there should be two input nodes for one node each. Why an Exhaust Node here? It should be a plenum induced air node, correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mjwitte I can make a change for Light object to add one more field. In this scenario, I would like to have a sing return node vs. a single exhaust node to share return heat gain. Induced node is not for this application.

ShowContinueError(state,
"Air Inlet Node " + loc_AirInNodeName +
" name does not match any controlled zone exhaust node name. Check ZoneHVAC:EquipmentConnections "
"object inputs.");
ShowContinueError(state, "or Induced Air Outlet Node Name specified in AirLoopHVAC:ReturnPlenum object.");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Provide information to allow an induced node from ZonePlenum

int ActualZoneNum; // Zone number
int ZoneNode; // Node number of controlled zone
int ReturnNode; // Node number of controlled zone's return air
int ReturnNodeExhaustNum; // Asscoaited exhaust node number, corresponding to the return node
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Add an array to store ReturnExhaust node number

@@ -4958,6 +4963,9 @@ void CalcZoneLeavingConditions(EnergyPlusData &state, bool const FirstHVACIterat
} else {
state.dataLoopNodes->Node(ReturnNode).Temp = TempRetAir;
}
if (ReturnNodeExhaustNum > 0 && state.dataLoopNodes->Node(ReturnNodeExhaustNum).MassFlowRate > 0.0 && QRetAir > 0.0) {
state.dataLoopNodes->Node(ReturnNodeExhaustNum).Temp = TempRetAir;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Assign node temperature after adding return heat to both nodes of return and zone exhaust.


return Nodefound;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ensure induced node is used as inlet node of zone equipment

@@ -212,6 +212,7 @@ add_simulation_test(IDF_FILE DOASDualDuctSchool.idf EPW_FILE USA_IL_Chicago-OHar
add_simulation_test(IDF_FILE DOAToFanCoilInlet.idf EPW_FILE USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.epw)
add_simulation_test(IDF_FILE DOAToFanCoilSupply.idf EPW_FILE USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.epw)
add_simulation_test(IDF_FILE DOAToPTAC.idf EPW_FILE USA_FL_Miami.Intl.AP.722020_TMY3.epw)
add_simulation_test(IDF_FILE DOAToPTAC_DrawReturnAir.idf EPW_FILE USA_FL_Miami.Intl.AP.722020_TMY3.epw)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Add a new example file for this new feature

@lgu1234
Copy link
Contributor Author

lgu1234 commented Apr 19, 2021

In addition to a new example file, five test files are provided for each of 5 zone equipment types:

FanCoilInlet_Test.txt
PTAC_Test.txt
PTHP_Test.txt
Unitary_Test.txt
UnitVentuilator_Test.txt

Copy link
Contributor

@mjwitte mjwitte left a comment

Choose a reason for hiding this comment

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

@lgu1234 This is a good start, but I have some questions below. If you would like to arrange a call next week to discuss, let me know.

Another way to simplify this would be to create some common functions for:
1.int GetControlledZoneNum(EquipType, EquipName)
2. bool validateZoneHVACEquipInlet(CtrlZoneNum, inletNodeNum) which could call:
3. bool isZoneReturnNode(CtrlZoneNum, NodeNum)
4. bool isReturnPlenumInducedNode(NodeNum, &ReturnPlenumNum?)

Perhaps get this working for one equipment type first, then the same code changes can be implemented in the other equipment types.

@@ -21153,13 +21153,14 @@ Lights,
\units 1/K
\minimum 0.0
\default 0.0
A7 ; \field Return Air Heat Gain Node Name
A7 ; \field Return Air Heat Gain Node or NodeList Name
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see why the Lights object needs to care what kind of node(s) it is connected to. The function which calculates the the heat gain to the node can simply look at one or more nodes and allocated the heat gain from this lights object to the node(s) on a mass-flow weighted basis.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mjwitte The current field input allows a single return node. The expansion allows a node list with a single return node and a single exhaust node to share the return heat gain.

Copy link
Contributor

Choose a reason for hiding this comment

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

@lgu1234 How about 2 node names here?
Return Air Heat Gain Node Name
Exhaust Heat Gain Node Name

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mjwitte I am OK with your suggestion. Therefore, A7 is kept as is. A8 will be added as Exhaust Heat Gain Node Name. Thanks.

@@ -648,6 +648,7 @@ namespace DataHeatBalance {
Real64 FractionReturnAirPlenTempCoeff1;
Real64 FractionReturnAirPlenTempCoeff2;
int ZoneReturnNum; // zone return index (not the node number) for return heat gain
int ZoneExhaustNodeNum; // Exhaust node number
Copy link
Contributor

Choose a reason for hiding this comment

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

Why a single node number here? And why do the lights care what kind of node this is?

@@ -265,6 +265,7 @@ namespace DataZoneEquipment {
Array1D_bool FixedReturnFlow; // true if return node is fixed and cannot be adjusted in CalcZoneReturnFlows
Array1D_int ReturnNodePlenumNum; // number of the return plenum attached to this return node (zero if none)
Array1D_int ReturnFlowBasisNode; // return air flow basis nodes
Array1D_int ReturnNodeExhaustNodeNum; // Exhaust node number flow to a corrsponding return node due to light heat gain
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see why ReturnNodeExhaustNodeNum is necessary.

Comment on lines 791 to 798
if (FanCoil(FanCoilNum).ControlZoneNum > 0) {
for (NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(FanCoil(FanCoilNum).ControlZoneNum).NumReturnNodes;
++NodeNum) {
InletNodeFound = ZonePlenum::ValidateInducedNode(
state, FanCoil(FanCoilNum).AirInNode, state.dataZoneEquip->ZoneEquipConfig(CtrlZone).ReturnNode(NodeNum));
if (InletNodeFound) break;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This block is testing to see of one if a zone return node is connected to the same plenum as the induced air node? Is this necessary?
This would be more efficient if the full list state.dataZoneEquip->ZoneEquipConfig(CtrlZone).ReturnNode is passed to the function. Then the function can first search for a plenum that matches the induced air node, then run through the return node list checking for a match there.
Also, if this fails because the induced node happens to be connected to a different plenum that does not return from the same zone, then the error message below will be confusing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mjwitte If a full list of return node is passed as an argument, return node do loop will occur inside the function. Therefore, do loop will be needed in either outside function or inside function. I can make change. By the way, how can I place a full list of return nodes as a single argument?

}
} else {
state.dataHeatBal->Lights(Loop).ZoneReturnNum = ZoneReturnNum;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

If the Lights input is Return Air Heat Gain Node or NodeList Name then it should accept any number of nodes in the list. If there is a reason to limit it to a single return node and/or a single plenum induced air node, then there should be two input nodes for one node each. Why an Exhaust Node here? It should be a plenum induced air node, correct?

Comment on lines 779 to 788
for (CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
for (int Num = 1; Num <= state.dataZoneEquip->ZoneEquipList(CtrlZone).NumOfEquipTypes; ++Num) {
if (UtilityRoutines::SameString(FanCoil(FanCoilNum).Name, state.dataZoneEquip->ZoneEquipList(CtrlZone).EquipName(Num)) &&
UtilityRoutines::SameString(FanCoil(FanCoilNum).UnitType,
state.dataZoneEquip->ZoneEquipList(CtrlZone).EquipType(Num))) {
FanCoil(FanCoilNum).ControlZoneNum = CtrlZone;
break;
}
}
if (FanCoil(FanCoilNum).ControlZoneNum > 0) break;
Copy link
Contributor

Choose a reason for hiding this comment

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

If this search to set FanCoil(FanCoilNum).ControlZoneNum was done before all of the node checking, then the loops for CtrlZone could be eliminated.
Also, the inlet node checks are the same for ATMixer_SupplySide or no mixer, so this can be structured to avoid duplicate code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mjwitte I debug the code and found FanCoil(FanCoilNum).ControlZoneNum is not assigned. There is a section to get ControlZoneNum without a mixer. Therefore, this section code is needed.

I agree that the inlet node checks are duplicated. I am going to created a new function.

Copy link
Contributor

@mjwitte mjwitte May 13, 2021

Choose a reason for hiding this comment

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

It would be better to always set ControlZoneNum before all of this connection checking. I don't think that would break anything else. So, this block can be moved higher up.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it can be done. However, this search is needed with ATMixer_SupplySide and an induced node is used as an inlet node. Therefore, this section is better to stay as is.

Copy link
Contributor

Choose a reason for hiding this comment

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

My point here is that I see three new loops over CtrlZone. It seems that one loop would be adequate.

@lgu1234
Copy link
Contributor Author

lgu1234 commented May 10, 2021

@mjwitte I checked code in UnitarySystem I modified. There is a do loop section:

                    for (int NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).NumReturnNodes; ++NodeNum) {
                        InducedNodeFound = ZonePlenum::ValidateInducedNode(
                            state, this->m_ATMixerSecNode, state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ReturnNode(NodeNum));
                        if (InducedNodeFound) break;
                    }

This section can be consolidated as you suggested: bool isReturnPlenumInducedNode(NodeNum, &ReturnPlenumNum?)

I would like to make changes in UnitarySystem first. As long as the change is OK, I can modify other modules. I would like to have a meeting. I am available either Thursday or Friday afternoon this week.

@lgu1234
Copy link
Contributor Author

lgu1234 commented May 12, 2021

@mjwitte I upload the code with a new common function for the FanCoil unit for review and comments. If OK, I hope to use this one as a starting point to generate more common functions in other modules.

Comment on lines 827 to 830
InletNodeFound = isReturnPlenumInducedNode(state,
FanCoil(FanCoilNum).AirInNode,
state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumReturnNodes,
state.dataZoneEquip->ZoneEquipConfig(CtrlZone).ReturnNode);
Copy link
Contributor

Choose a reason for hiding this comment

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

Looking at this more, isReturnPlenumInducedNode is not doing much. How about
ZonePlenum::ValidateInducedNode( state, InletNodeNum, state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumReturnNodes, state.dataZoneEquip->ZoneEquipConfig(CtrlZone).ReturnNode) right here. With the list of return nodes passed in, ValidateInducedNode can search the plenum induced air nodes first, then look for matching return node to plenum inlet node once the correct plenum is located.

@lgu1234
Copy link
Contributor Author

lgu1234 commented May 14, 2021

@mjwitte I revised the ZonePlenum::ValidateInducedNode function and uploaded the code. Please take a look to ensure the change is what you expect.


FanCoil(FanCoilNum).ControlZoneNum = ControlZoneNum;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There are two places to find zone number. I consolidate two places as a common function based on search scenario. The other cases may not need to use the zone number.

Comment on lines 1393 to 1394
for (InduceNodeCtr = 1; InduceNodeCtr <= state.dataZonePlenum->ZoneRetPlenCond(PlenumNum).NumInducedNodes; ++InduceNodeCtr) {
if (InduceNodeNum == state.dataZonePlenum->ZoneRetPlenCond(PlenumNum).InducedNode(InduceNodeCtr)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

If these lines are moved up after line 1389, then looking for the induced node first would be a little bit faster.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. Thanks.

@mjwitte mjwitte added this to the EnergyPlus 9.6 IOFreeze milestone May 20, 2021
@lgu1234
Copy link
Contributor Author

lgu1234 commented Jul 22, 2021

@mjwitte There is a warning in x86_64-MacOS-10.15-clang.
Capture
Could you let me know if this line can be removed or not?

@mjwitte
Copy link
Contributor

mjwitte commented Jul 22, 2021

@lgu1234 Yes, but it will be fixed when #8898 merges (deleted here). So, no need to fix it here.

@Myoldmopar
Copy link
Member

when #8898 merges

Oh right, thanks for the reminder. Heading over there to merge now...

Copy link
Contributor

@mjwitte mjwitte left a comment

Choose a reason for hiding this comment

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

@lgu1234 Ran some tests with the new example file, with bad node names.
Invalid return node failed as expected.
Invalid exhaust node was just a warning - should be severe and stop.
Exhaust node not in the same zone was just a warning - should be severe and stop.
Exhaust node with blank return node - no warning at all. This is ok.

@mjwitte
Copy link
Contributor

mjwitte commented Jul 23, 2021

Here are the test files.
8719-ZoneHVAC Return Air-TestNodeErrors.zip

@mjwitte
Copy link
Contributor

mjwitte commented Jul 23, 2021

Exhaust node with blank return node - no warning at all.
I forgot, this is valid, because blank will default to a valid return node if present. So this is ok.

Docs look good except a couple of warnings (see the file diffs page):

 Check warning on line 1029 in doc/input-output-reference/src/overview/group-unitary-equipment.tex

GitHub Actions
/ build
doc/input-output-reference/src/overview/group-unitary-equipment.tex#L1029
Label `field-supply-air-fan-operating-mode-schedule-name-4' multiply defined.

 Check warning on line 2263 in doc/input-output-reference/src/overview/group-zone-forced-air-units.tex

GitHub Actions
/ build
doc/input-output-reference/src/overview/group-zone-forced-air-units.tex#L2263
Label `field-supply-air-fan-operating-mode-schedule-name-4' multiply defined.

Looks like I never answered this question

Since we allow multiple Lights objects in a single zone, it is possible there are multiple exhaust nodes in a single zone, so that an 1-D array is created. If not necessary, do you have any suggestions to store exhaust node information in ZoneEquipConfig?

If multiple lights objects are present in the zone, it should be ok as long as the return node/exhaust node pair are the same node names. The internal heat gain tracking will add all of the gains to that return/exhaust node pair. But if LightsA reference ReturnNode1 and ExhaustNode1 and LightsB references ReturnNode1 and ExhaustNode2, I think the current code for lights will overwrite the exhaust node and only the last one will get the heat gain. This could be a valid case if there is more than one piece of equipment in the zone that is drawing from the return duct. So, this could be a vector which means a vector on each return node, which seems complicated.

Perhaps at this point, you should check if a given return node already has ReturnNodeExhaustNodeNum assigned then any additional Lights objects that reference it need to use the same exhaust node. Some notes about this should be added to the I/O Ref entry for the exhaust node. Also, add that any other return air heat gains (like from refrigetation equipment) on the same return node will impact the exhaust node as well.

Also, I don't see any Engineering Ref changes, but I can't find anyplace in the Engineering Ref that talks about return air heat gain. I thought there was some place in the docs that explained RetTempMax and how any load not added to the return air gets added to the zone, etc.

@Myoldmopar
Copy link
Member

Docs look good except a couple of warnings (see the file diffs page):

If those are the same warnings that have appeared in other branches, I think I have them fixed in one of my branches. If that is a new warning or a new field entirely or anything, then yeah, that should be fixed here.

@lgu1234
Copy link
Contributor Author

lgu1234 commented Jul 26, 2021

@mjwitte I resolved doc warning by replacing `field-supply-air-fan-operating-mode-schedule-name-4' in doc/input-output-reference/src/overview/group-unitary-equipment.tex#L1029 by '{field-unitaryheatcool-supply-air-fan-operating-mode-schedule-name}'.

Instead of using number to show difference, I add the object name in the beginning of the field name.

@lgu1234
Copy link
Contributor Author

lgu1234 commented Jul 26, 2021

@mjwitte I uploaded code by addressing partial comments.

  1. Remove warning from IO ref
  2. Add severe errors based 4 test files

DOAToPTAC_DrawReturnAir-ExhNodeNotInZone-Annual.idf
Current: warning
** Warning ** GetInternalHeatGains: Lights="SPACE1-1 LIGHTS 1", invalid Exhaust Air Heat Gain Node Name =SPACE4-1 PTAC INLET
** ~~~ ** No matching Zone Exhaust Air Node found.

Action: Severe and stop
** Severe ** GetInternalHeatGains: Lights="SPACE1-1 LIGHTS 1", invalid Exhaust Air Heat Gain Node Name = SPACE4-1 PTAC INLET
** ~~~ ** No matching Zone Exhaust Air Node found.
** Fatal ** GetInternalHeatGains: Errors found in Getting Internal Gains Input, Program Stopped

DOAToPTAC_LightsZero-DrawReturnAir-BadExhNode-Annual.idf
Current: Warning
Action: Same severe error
** Severe ** GetInternalHeatGains: Lights="SPACE1-1 LIGHTS 1", invalid Exhaust Air Heat Gain Node Name = SPACE1-1 ABC TERMINAL MIXER SECONDARY INLET
** ~~~ ** No matching Zone Exhaust Air Node found.
** Fatal ** GetInternalHeatGains: Errors found in Getting Internal Gains Input, Program Stopped

DOAToPTAC_LightsZero-DrawReturnAir-BadReturnNode-Annual.idf
Current: Warning and Severe
** Severe ** GetInternalHeatGains: Lights="SPACE1-1 LIGHTS 1", invalid Return Air Heat Gain Node Name =SPACE1-1 XYZ RETURN OUTLET
** ~~~ ** No matching Zone Return Air Node found.
** Warning ** GetInternalHeatGains: Lights="SPACE1-1 LIGHTS 1", Exhaust Air Heat Gain Node Name =SPACE1-1 AIR TERMINAL MIXER SECONDARY INLET is not used
** ~~~ ** No matching Zone Return Air Node found. The Exhaust Node requires Return Node to work together
** Fatal ** GetInternalHeatGains: Errors found in Getting Internal Gains Input, Program Stopped

Action: All severe
** Severe ** GetInternalHeatGains: Lights="SPACE1-1 LIGHTS 1", invalid Return Air Heat Gain Node Name =SPACE1-1 XYZ RETURN OUTLET
** ~~~ ** No matching Zone Return Air Node found.
** Severe ** GetInternalHeatGains: Lights="SPACE1-1 LIGHTS 1", Exhaust Air Heat Gain Node Name =SPACE1-1 AIR TERMINAL MIXER SECONDARY INLET is not used
** ~~~ ** No matching Zone Return Air Node found. The Exhaust Node requires Return Node to work together
** Fatal ** GetInternalHeatGains: Errors found in Getting Internal Gains Input, Program Stopped

DOAToPTAC_LightsZero-DrawReturnAir-NoReturnNode-Annual.idf

No action is needed.

I am think of a case with multiple return nodes with the same exhaust node.

Do you provide an example file with multiple airloops to serve a single zone?

@mjwitte
Copy link
Contributor

mjwitte commented Jul 26, 2021

@lgu1234 For examples with 2 airloops (and 2 returns) for each zone, see House-2FurnaceAC-SequentialLoad.idf (and other House-2FurnaceAC-*.idf).

@lgu1234
Copy link
Contributor Author

lgu1234 commented Jul 30, 2021

@mjwitte I upload the code and document to address the rest of comments.

The new feature can handle multiple return nodes and referred to the same exhaust node in multiple Lights objects. The Engineering reference was revised to add how the node temperatures are calculated with 3 scenarios: Return node only, a pair of return and exhaust nodes, multiple return nodes and a single exhaust node. The corresponding unit test for the last scenario was added.

Enclosed is a test file for the last scenario.
DoubleLightsSingleExhaust.idf.txt

Copy link
Contributor

@mjwitte mjwitte left a comment

Choose a reason for hiding this comment

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

@lgu1234 Thanks for addressing comments and adding the engineering ref section.


\(CpAir\) is the specific heat (J/kg)

Although a single Lights object allows a return node and an exhasut node, it is possible to have multiple Lights objects with different return nodes and referrred to the same exhaust node. Therefore, the exhaust node will share return heat from different return nodes. The temperature rise at i-th return node is given below:
Copy link
Contributor

Choose a reason for hiding this comment

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

Typo: exhasut

This is not the scenario I was asking about. What would this mean physically for a single zonehvac unit to draw from 2 different return ducts? I'm not sure we should allow this combination.

I was asking about the reverse, where 2 different zoneHVAC units draw from the same return duct. At this point, I'm ok with not allowing that just so we can call this complete.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mjwitte Thanks for finding typos. I corrected 4. I am going to upload the Eng. Ref.

I can remove the scenario for a single zonehvac unit to draw from 2 different return ducts. Please let me know if the scenario is removed or not.

@lgu1234
Copy link
Contributor Author

lgu1234 commented Aug 4, 2021

@mjwitte An error message was added if 2 different exhaust nodes draw from the same return node.

Enclosed is a test file.
SingleReturnDoubleExhaust.idf.txt

@mjwitte
Copy link
Contributor

mjwitte commented Aug 5, 2021

The new error check is correct when 2 different exhaust nodes are used with the same return node, as in SingleReturnDoubleExhaust.idf

But it should not be an error to use the same pair of exhaust node and return node multiples times. The internal gains tracking will sum the heat gains automatically. This file should run without error: DoubleLightsSingleExhaust-SingleReturn.idf.txt

@lgu1234
Copy link
Contributor Author

lgu1234 commented Aug 5, 2021

@mjwitte The code was changed and uploaded. No error is generated when the same return and exhaust nodes are used in two lights object.

Copy link
Contributor

@mjwitte mjwitte left a comment

Choose a reason for hiding this comment

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

Retested the new error messages and everything is working as expected. Will merge once CI finishes up.

@mjwitte
Copy link
Contributor

mjwitte commented Aug 5, 2021

Mac is green after the latest change. Merging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
IDDChange Code changes impact the IDD file (cannot be merged after IO freeze) NewFeature Includes code to add a new feature to EnergyPlus
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants