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

Refactor RAFN CheckEquipName for forced air zone equipment #10452

Open
wants to merge 24 commits into
base: develop
Choose a base branch
from

Conversation

lgu1234
Copy link
Contributor

@lgu1234 lgu1234 commented Mar 28, 2024

Pull request overview

The existing CheckEquipName uses Alpha fields of object inputs to get supply and return node names. When any object inputs change, the code has to be revised accordingly. The function refactor will use inlet and outlet node number from different zone equipment directly. There is no potential maintenance issue.

There are 3 types of zone equipment: forced air, convective and radiative, and terminal units. Phase 1 refactors forced air zone equipment, while Phase 2 and 3 will handle convective and radiative, and terminal units, respectively and will start after Phase 1 is merged.

Phase 1 use inlet and outlet nodes directly from each force air zone equipment. Since this module is called after calling GetZoneEquipmentData in the DataZoneEquipment module, all inlet and outlet node information is available before calling CheckEquipName function.

The test file is an example file as RoomAirflowNetwork.idf.

Pull Request Author

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

  • [X ] 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 the Defect Includes code to repair a defect in EnergyPlus label Mar 28, 2024
@@ -2676,7 +2697,7 @@ namespace RoomAir {
std::string const &EquipName, // Equipment Name
std::string &SupplyNodeName, // Supply node name
std::string &ReturnNodeName, // Return node name
int TotNumEquip, // how many of this equipment type
int EquipIndex, // Equipment index
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 is no need for TotNumEquip. EquipIndex is added to get index for each type of zone equipment

SupplyNodeName = Alphas(6);
ReturnNodeName = Alphas(5);
SupplyNodeNum = state.dataFanCoilUnits->FanCoil(EquipIndex).AirOutNode;
ReturnNodeNum = state.dataFanCoilUnits->FanCoil(EquipIndex).AirInNode;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Get air inlet and outlet nodes directly from FanCoilUnits based on EquipIndex

Copy link
Contributor

Choose a reason for hiding this comment

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

@Myoldmopar At some point in the past, we frowned on looking directly into other components' data structures, e.g.
SupplyNodeNum = state.dataFanCoilUnits->FanCoil(EquipIndex).AirOutNode;
and preferred using mining functions, e.g.
SupplyNodeNum = HVACVariableRefrigerantFlow::GetVRFTUZoneInletAirNode(state, EquipIndex);

What's our current preference?

Copy link
Collaborator

@amirroth amirroth Apr 11, 2024

Choose a reason for hiding this comment

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

There are two questions here. One is whether we should use access functions or direct access. There are two benefits to using access functions:

  • The ability to control/enforce simultaneous and internally consistent of related member variables.
  • The ability to support an external API.
    The downside of course is overhead, both in terms of code but also at runtime.

If we want to go with access functions, there are two choices:

  • Mining functions that take an object index: overhead is higher, but can double as an API if needed (I think not). We use this pattern fairly extensively.
  • Methods: low overhead, but no API support. We hardly use this.

Unfortunately, there is also a non-choice that we use extensively:

  • Mining functions that take an object name and have to search for the object on every call. Yikes! We need to sweep this idiom out and the most recent fans PR does that for that module.

I personally favor direct access, but there are some advantages to access methods and if people want to go that round I would not scream too loud.

Copy link
Contributor

Choose a reason for hiding this comment

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

The only reason I see for using mining functions is the call to getInput. If the fan coil has been read in then accessing that data, so the user doesn't have to provide it, seems reasonable (line 2735 above). If the fan coil has not been read in, then a mining function will do the trick. I envision keeping the getIndex for each component type and using direct access for everything else. The problem here is EquipIndex = state.dataZoneEquip->ZoneEquipList(iZone).EquipIndex(thisZoneEquipNum); may still be 0 at this point (I didn't trace back to see if all the equipment has been read in) or does not necessarily point to the component index and could instead point to the index from 1-n of the type of zone equipment (e.g. PTAC 1 to 3, or PTHP 1 to 4, etc). So index = 1 would point to UnitarySystem 1 of 7. Since we don't have example files with various mixes of component types, the mistakes don't show up until a user provides a broken input file with a mix of multiple equipment types.

I've tried to explain this concept as best I can in the past.

This is what gets passed back from the simulate function:

    CompIndex = this->m_EquipCompNum;

And this is how that variable gets set (because of zone availability managers):

                    // zone equipment require a 1-n index for access to zone availability managers
                    switch (getPTUnitType) {
                    case 1: // Excuse me?
                        ++numPTAC;
                        thisSys.m_EquipCompNum = numPTAC;
                        break;
                    case 2: // Baking powder?
                        ++numPTHP;
                        thisSys.m_EquipCompNum = numPTHP;
                        break;
                    case 3:
                        ++numPTWSHP;
                        thisSys.m_EquipCompNum = numPTWSHP;
                        break;

Copy link
Contributor

@rraustad rraustad Apr 11, 2024

Choose a reason for hiding this comment

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

Out of curiosity, this is what PackagedTerminalHeatPump did prior to #9052:

// Find the correct packaged terminal heat pump
if (CompIndex == 0) {
    PTUnitNum = UtilityRoutines::FindItemInList(CompName, state.dataPTHP->PTUnit);
    if (PTUnitNum == 0) {
        ShowFatalError(state, "SimPackagedTerminalUnit: Unit not found=" + std::string{CompName});
    }
    CompIndex = state.dataPTHP->PTUnit(PTUnitNum).PTObjectIndex;
} else {
    {
        auto const SELECT_CASE_var(PTUnitType);
        if (SELECT_CASE_var == PkgTermHPAirToAir_Num) {
            PTUnitNum = CompIndex;
        } else if (SELECT_CASE_var == PkgTermACAirToAir_Num) {
            PTUnitNum = CompIndex + state.dataPTHP->NumPTHP;
        } else if (SELECT_CASE_var == PkgTermHPWaterToAir_Num) {
            PTUnitNum = CompIndex + state.dataPTHP->NumPTHP + state.dataPTHP->NumPTAC;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I ran another example file as FanCoilAutoSize.idf to see if which one of getRoomAirModeInput and getFanCoilInput gets first. The getRoomAirModeInput comes first, and getFanCoilInput comes much later. Therefore, the direct access may not work well for every case. In order to be consistent, I use the access functions for every zone equipment type check.

SupplyNodeName = Alphas(4);
ReturnNodeName = Alphas(3);
SupplyNodeNum = state.dataUnitarySystems->unitarySys[EquipIndex - 1].getAirOutNode(state, EquipName, 0, errorfound);
ReturnNodeNum = state.dataUnitarySystems->unitarySys[EquipIndex - 1].getAirInNode(state, EquipName, 0, errorfound);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Get inlet and outlet nodes from existing functions

Copy link
Contributor

Choose a reason for hiding this comment

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

The problem here is that EquipIndex is the index to the type of PTUnit equipment (i.e., PTAC, PTHP, or PTWSHP) which is not the same as the index to the unitarySys struct.

                    // zone equipment require a 1-n index for access to zone availability managers
                    switch (getPTUnitType) {
                    case 1: // Excuse me?
                        ++numPTAC;
                        thisSys.m_EquipCompNum = numPTAC;
                        break;
                    case 2: // Baking powder?
                        ++numPTHP;
                        thisSys.m_EquipCompNum = numPTHP;
                        break;
                    case 3:
                        ++numPTWSHP;
                        thisSys.m_EquipCompNum = numPTWSHP;
                        break;
                    default:
                        assert(true);
                    }
                    int thisSysNum = state.dataUnitarySystems->numUnitarySystems - 1;
                    state.dataUnitarySystems->unitarySys[thisSysNum] = thisSys;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@rraustad I am going to check it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@rraustad What I need is to find UnitarySys index from state.dataZoneEquip->ZoneEquipList

                int EquipIndex = 0;
                for (int thisZoneEquipNum = 1; thisZoneEquipNum <= state.dataZoneEquip->ZoneEquipList(iZone).NumOfEquipTypes;
                     ++thisZoneEquipNum) {
                    if (Util::SameString(state.dataZoneEquip->ZoneEquipList(iZone).EquipName(thisZoneEquipNum), roomAFNNodeHVAC.Name)) {
                        EquipIndex = state.dataZoneEquip->ZoneEquipList(iZone).EquipIndex(thisZoneEquipNum);
                    }
                }

Then I look at UnitarySys inlet and outlet nodes. thisSys.m_EquipCompNum is irrelevant for this Check.

Copy link
Contributor

Choose a reason for hiding this comment

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

thisSys.m_EquipCompNum is the value that gets passed back from void UnitarySys::simulate to the calling function. It is VERY relevant.

    CompIndex = this->m_EquipCompNum;

} break;
case DataZoneEquipment::ZoneEquipType::BaseboardElectric: { // ZoneHVAC : Baseboard : RadiantConvective : Electric
// convective equipment without node connection. Will handle later
Copy link
Contributor Author

Choose a reason for hiding this comment

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

WIll handle in Phase 2

ReturnNodeName = "";
// Air teminal components are handled later
// SupplyNodeName = Alphas(1);
// ReturnNodeName = "";
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will handle in Phase 3

if (check) {
EXPECT_EQ("SupplyNode", SupplyNodeName);
EXPECT_EQ("ReturnNode", ReturnNodeName);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

These last 2 unit tests are looking at the PTAC unitarySys object (report the object type and name to find out) and since you are using the same node names and node 1 and 2, all these results give the same answer. This unit test should use unique node names and multiple PTUnits and UnitarySystems. For zone equipment, PTAC, PTHP, PTWSHP and UnitarySystem all have indexes 1 - n.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@rraustad Although I use the same name, I did debug it and found they are correct.

int EquipIndex = 0;
for (int thisZoneEquipNum = 1; thisZoneEquipNum <= state.dataZoneEquip->ZoneEquipList(iZone).NumOfEquipTypes;
++thisZoneEquipNum) {
if (Util::SameString(state.dataZoneEquip->ZoneEquipList(iZone).EquipName(thisZoneEquipNum), roomAFNNodeHVAC.Name)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This should also check roomAFNNodeHVAC.zoneEquipType. It's not common, but it is allowable for different types of zone equipment to have the same 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.

A good suggestion. Done!

for (int thisZoneEquipNum = 1; thisZoneEquipNum <= state.dataZoneEquip->ZoneEquipList(iZone).NumOfEquipTypes;
++thisZoneEquipNum) {
if (Util::SameString(state.dataZoneEquip->ZoneEquipList(iZone).EquipName(thisZoneEquipNum), roomAFNNodeHVAC.Name)) {
EquipIndex = state.dataZoneEquip->ZoneEquipList(iZone).EquipIndex(thisZoneEquipNum);
Copy link
Contributor

Choose a reason for hiding this comment

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

@rraustad Would it work here to save this value, then pass it in to CheckEquipName to be used for the equipment types supported by unitarysystem?

HVACSystemData * compPointer;
compPointer = state.dataZoneEquip->ZoneEquipList(iZone).compPointer[thisZoneEquipNum];

See SimZoneEquipment

case ZoneEquipType::PackagedTerminalHeatPump: // 'ZoneHVAC:PackagedTerminalHeatPump'
case ZoneEquipType::PackagedTerminalAirConditioner: // 'ZoneHVAC:PackagedTerminalAirConditioner'
case ZoneEquipType::PackagedTerminalHeatPumpWaterToAir: // 'ZoneHVAC:WaterToAirHeatPump'
case ZoneEquipType::UnitarySystem: { // 'AirloopHVAC:UnitarySystem'
int AirLoopNum = 0;
bool HeatingActive = false;
bool CoolingActive = false;
int OAUnitNum = 0;
Real64 OAUCoilOutTemp = 0.0;
bool ZoneEquipFlag = true;
zoneEquipList.compPointer[EquipPtr]->simulate(state,
state.dataZoneEquipmentManager->PrioritySimOrder(EquipTypeNum).EquipName,
FirstHVACIteration,
AirLoopNum,
zoneEquipList.EquipIndex(EquipPtr),
HeatingActive,
CoolingActive,
OAUnitNum,
OAUCoilOutTemp,
ZoneEquipFlag,
SysOutputProvided,
LatOutputProvided);

Copy link
Contributor

Choose a reason for hiding this comment

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

It should. I can't say if this pointer is available on the first call to RoomAirModelManager (calling order) but once available the pointer is saved in the index to the equipment in the equipment list (not the component index). If the UnitarySystem (or other types managed by UnitarySystem) is 4th in the equipment list then it is .compPointer[4].

thisZoneEquipList.compPointer.resize(thisZoneEquipList.NumOfEquipTypes + 1);

HVACSystemData * compPointer = state.dataZoneEquip->ZoneEquipList(iZone).compPointer[1 <= n <= NumOfEquipTypes];

@@ -2676,7 +2697,7 @@ namespace RoomAir {
std::string const &EquipName, // Equipment Name
std::string &SupplyNodeName, // Supply node name
std::string &ReturnNodeName, // 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.

In one of your later phases, these should be changed to NodeNum instead of passing and saving node names.

EquipIndex = state.dataZoneEquip->ZoneEquipList(iZone).EquipIndex(thisZoneEquipNum);
break;
}
}
IntEquipError = CheckEquipName(state,
Copy link
Contributor

Choose a reason for hiding this comment

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

Minor, but the name IntEquipError is misleading, better would be IntEquipFound?

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!

@lgu1234
Copy link
Contributor Author

lgu1234 commented Apr 12, 2024

Thanks for all valuable comments. I will take care after my vacation.

@Myoldmopar Myoldmopar assigned lgu1234 and unassigned mjwitte Apr 24, 2024
@Myoldmopar Myoldmopar assigned mjwitte and unassigned lgu1234 May 8, 2024
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 great improvement, but I have some concerns about the impact of this causing a getinput call for the various system types in a full simulation. The only example file with RoomAir:Node:AirflowNetwork:HVACEquipment is all PTAC equipment. It would be good to add Room AFN to a couple of other example files with different equipment types to make sure the possibly early getinput doesn't break anything. Maybe a fancoil, and a heat pump water heater just to cover some different system types. I'm not suggesting these as formal example files, just a quick test to make sure it runs ok.

zoneEquipType = DataZoneEquipment::ZoneEquipType::VariableRefrigerantFlowTerminal;
state->dataHVACVarRefFlow->NumVRFTU = 1;
check = CheckEquipName(*state, EquipName, SupplyNodeName, ReturnNodeName, EquipIndex, zoneEquipType);
if (check) {
Copy link
Contributor

Choose a reason for hiding this comment

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

All of these if (check) blocks should be replaced with EXPECT_TRUE(check). As it stands if the check fails the unit test will pass, because the other EXPECT_EQs will not execute.

@lgu1234
Copy link
Contributor Author

lgu1234 commented May 22, 2024

@mjwitte I am going to create more test files with different equipment types, such as fan coils and others.

@lgu1234
Copy link
Contributor Author

lgu1234 commented May 29, 2024

@mjwitte Thanks for your comments.
I created a test file with FanCoil and uploaed it as RoomAirWithFanCoil.idf in DevSupport\EnergyPlusDevSupport\DefectFiles\6000s\6321. When I debug the function CheckEngineName, I realized EquipIndex is 0. In other words, the GetInput function of FanCoil is not called. Then I check calling sequences how to get EquipIndex.

Before calling CheckEngineName, EquipIndex is available for 4 types of zone equipment in the function processZoneEquipmentInput to process EquipIndex

                if (thisZoneEquipList.EquipType(ZoneEquipTypeNum) == ZoneEquipType::UnitarySystem ||
                    thisZoneEquipList.EquipType(ZoneEquipTypeNum) == ZoneEquipType::PackagedTerminalAirConditioner ||
                    thisZoneEquipList.EquipType(ZoneEquipTypeNum) == ZoneEquipType::PackagedTerminalHeatPump ||
                    thisZoneEquipList.EquipType(ZoneEquipTypeNum) == ZoneEquipType::PackagedTerminalHeatPumpWaterToAir) {
                    // loop index accesses correct pointer to equipment on this equipment list
                    // EquipIndex is used to access specific equipment for a single class of equipment (e.g., PTAC 1, 2 and 3)
                    thisZoneEquipList.compPointer[ZoneEquipTypeNum] = UnitarySystems::UnitarySys::factory(
                        state, HVAC::UnitarySysType::Unitary_AnyCoilType, thisZoneEquipList.EquipName(ZoneEquipTypeNum), true, 0);
                    thisZoneEquipList.EquipIndex(ZoneEquipTypeNum) = thisZoneEquipList.compPointer[ZoneEquipTypeNum]->getEquipIndex();
                }

The EquipIndex of the rest of equipment types is obtained from the function SimZoneEquipment in the ZoneequipmentManager after calling CheckEngineName.

I slightly modified both functions to get FanCoil inlet and outlet node by adding one more argument as EquipName:

        SupplyNodeNum = FanCoilUnits::GetFanCoilZoneInletAirNode(state, EquipIndex, EquipName);
        ReturnNodeNum = FanCoilUnits::GetFanCoilAirInNode(state, EquipIndex, EquipName);

If EquipIndex = 0, the function will search supply and return node number based on EquipName.

Please take a look at code modification of FanCoil and let me know what you think.

Thanks.

SupplyNodeName = Alphas(4);
ReturnNodeName = Alphas(3);
SupplyNodeNum = state.dataUnitarySystems->unitarySys[EquipIndex - 1].getAirOutNode(state, EquipName, 0, errorfound);
ReturnNodeNum = state.dataUnitarySystems->unitarySys[EquipIndex - 1].getAirInNode(state, EquipName, 0, errorfound);
Copy link
Contributor

Choose a reason for hiding this comment

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

@lgu1234 and I discussed using a getIndex function in the parent objects, specifically for all objects managed by UnitarySystem, to directly access the state variables for UnitarySystem. So this should look like:

int usIndex = UnitarySys::GetIndex(state, EquipName);  <-- this will need EquipType if names are not unique
SupplyNodeNum = state.dataUnitarySystems->unitarySys[usIndex].AirOutNode;
ReturnNodeNum = state.dataUnitarySystems->unitarySys[usIndex].AirInNode;

@lgu1234
Copy link
Contributor Author

lgu1234 commented May 29, 2024

@rraustad The revision provides correct index for Unitary systems. Please check it.

getIndex(EnergyPlusData &state, std::string const &UnitarySysName, DataZoneEquipment::ZoneEquipType zoneEquipType, bool &errFlag)
{

int EquipIndex = 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

The index should be initialized to -1 for 0-based array

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@rraustad Corrected.

@lgu1234
Copy link
Contributor Author

lgu1234 commented May 30, 2024

@rraustad Your comments have been addressed. Please take a look.

{

if (state.dataUnitarySystems->getInputOnceFlag) {
UnitarySystems::UnitarySys::getUnitarySystemInput(state, UnitarySysName, false, OAUnitNum);
Copy link
Contributor

Choose a reason for hiding this comment

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

The zone equipment flag should be true

UnitarySystems::UnitarySys::getUnitarySystemInput(state, UnitarySysName, true, OAUnitNum);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@rraustad I am going to make a change.

@Myoldmopar
Copy link
Member

Can confirm locally @rraustad :

$ ./scripts/dev/custom_check.sh 
No command line arg sent for repo root, assuming . (repository root)
Found the license check file, command configuration seems correct, running...
Running Custom-Check: license-check
Running Custom-Check: check_stray_fields_in_idd
Running Custom-Check: verify_idfs_in_cmake
Running Custom-Check: check_non_utf8
Running Custom-Check: verify_file_encodings
Running Custom-Check: validate_idd_units
Running Custom-Check: find_byref_bool_override
{"tool": "find_byref_bool_overide", "file": "src/EnergyPlus/HVACStandAloneERV.cc", "line": 1700, "messagetype": "error", "message": "Boolean flag `bool &errFlag` reset to false in src/EnergyPlus/HVACStandAloneERV.cc:getEqIndex(), on line 1700"}
{"tool": "find_byref_bool_overide", "file": "src/EnergyPlus/HVACVariableRefrigerantFlow.cc", "line": 10782, "messagetype": "error", "message": "Boolean flag `bool &errFlag` reset to false in src/EnergyPlus/HVACVariableRefrigerantFlow.cc:getEqIndex(), on line 10782"}
Running Custom-Check: check_for_tabs
Running Custom-Check: check_for_bom_in_idfs
Running Custom-Check: verify_cmake_dirs

@lgu1234
Copy link
Contributor Author

lgu1234 commented Jun 6, 2024

@mjwitte @rraustad It is ready for further review.

@mjwitte Since AFN does not support heat pump water heater, I don't generate a test file. The test file of fan coil was generated.

@mjwitte
Copy link
Contributor

mjwitte commented Jun 6, 2024

@mjwitte Since AFN does not support heat pump water heater, I don't generate a test file. The test file of fan coil was generated.

@lgu1234 I'm confused. I see "WaterHeater:HeatPump" as a valid key choice in RoomAir:Node:AirflowNetwork:HVACEquipment and there's a case for it in the new function:

 case DataZoneEquipment::ZoneEquipType::HeatPumpWaterHeater: { // WaterHeater : HeatPump

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Defect Includes code to repair a defect in EnergyPlus
Projects
None yet
Development

Successfully merging this pull request may close these issues.

RoomAirModelManager::CheckEquipName function possible issues
10 participants