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

OA Limiting Factor enum and Related Cleanup #9947

Merged
merged 21 commits into from
May 6, 2023

Conversation

mjwitte
Copy link
Contributor

@mjwitte mjwitte commented Apr 11, 2023

Pull request overview

  • Closes Air System Outdoor Air Limiting Factor can be wrong for simple OA controls due to tiny differences #8802
    The original defect file for this was a bit of a red herring, because it is an airflownetwork MultizoneWithDistribution model. So, the AFN connection causes slight changes in the mixed air mass flow rate which leads to the supposed anomalies in the OA limiting factor output. Even through the mass flow differences are tiny, the OA controller logic is doing what it is supposed to. So, 8802 can be closed as-designed.
  • Move OA limiting factor to an enum
  • Minor refactoring of CalcMechVentController

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)
  • Label the PR with at least one of: Defect, Refactoring, NewFeature, Performance, and/or DoNoPublish
  • Pull requests that impact EnergyPlus code must also include unit tests to cover enhancement or defect repair
  • 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

@mjwitte mjwitte added the Refactoring Includes code changes that don't change the functionality of the program, just perform refactoring label Apr 11, 2023
@@ -3924,6 +3906,15 @@ void VentilationMechanicalProps::CalcMechVentController(

// Calculate zone maximum target CO2 concentration in PPM
if (this->SystemOAMethod == DataSizing::SysOAMethod::ProportionalControlDesOcc) {
// Accumulate CO2 generation from people at design occupancy and current activity level
Real64 CO2PeopleGeneration = 0.0;
for (int PeopleNum = 1; PeopleNum <= state.dataHeatBal->TotPeople; ++PeopleNum) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can probably do for (auto const &people : state.dataHeatBal->People).

// Accumulate CO2 generation from people at design occupancy and current activity level
Real64 CO2PeopleGeneration = 0.0;
for (int PeopleNum = 1; PeopleNum <= state.dataHeatBal->TotPeople; ++PeopleNum) {
if (state.dataHeatBal->People(PeopleNum).ZonePtr != ZoneNum) continue;
Copy link
Collaborator

Choose a reason for hiding this comment

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

There are no per-zone PeopleNum lists I guess.

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 no per-zone PeopleNum lists I guess.

It does seem wrong to loop through all People statements for all zones. Options include making CO2PeopleGeneration an array and looping though once, storing the values, but this is a system-level thing here, so it only needs the zones on this systems, and a different system might use a different control option. So, per-zone PeopleNum lists are probably the best way to solve this, esp, because 99% of the time, it's a list of one element.

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 address this with #9969

enum class OALimitFactor
{
Invalid = -1,
None = 0, // No limit other than fixed OA amount
Copy link
Collaborator

Choose a reason for hiding this comment

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

Don't need the numbers.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Don't need the numbers.

Yes, but these get used as output variable values which are documented in the I/O Ref, so the numbers are here to emphasize that these shouldn't be rearranged or have anything inserted in the middle of the list.

@mjwitte
Copy link
Contributor Author

mjwitte commented Apr 18, 2023

@rraustad This is ready for review assuming CI comes back clean.
Due to possible bug #9969, saving the People loop changes for a different PR.

Copy link
Contributor Author

@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.

Selected developer comments

@@ -3648,6 +3617,7 @@ void VentilationMechanicalProps::CalcMechVentController(
// new local variables for DCV
// Zone OA flow rate based on each calculation method [m3/s]
std::array<Real64, static_cast<int>(DataSizing::OAFlowCalcMethod::Num)> ZoneOACalc{0.0};
Real64 CO2PeopleGeneration = 0; // CO2 generation from people at design level
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Keeping this here at the top, will move while addressing #9969

Copy link
Contributor

Choose a reason for hiding this comment

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

Understood

Comment on lines -3800 to -3802
if (this->SystemOAMethod == DataSizing::SysOAMethod::ProportionalControlDesOcc) {
// Accumulate CO2 generation from people at design occupancy and current activity level
for (int PeopleNum = 1; PeopleNum <= state.dataHeatBal->TotPeople; ++PeopleNum) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was moved lower, but left unchanged for now.

// Accumulate CO2 generation from people at design occupancy and current activity level
Real64 CO2PeopleGeneration = 0.0;
for (int PeopleNum = 1; PeopleNum <= state.dataHeatBal->TotPeople; ++PeopleNum) {
if (state.dataHeatBal->People(PeopleNum).ZonePtr != ZoneNum) continue;
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 address this with #9969

@mjwitte mjwitte mentioned this pull request Apr 18, 2023
20 tasks
Copy link
Contributor

@rraustad rraustad left a comment

Choose a reason for hiding this comment

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

Looks good.

@@ -874,8 +874,7 @@ void GetStandAloneERV(EnergyPlusData &state)
auto &thisOAController = state.dataMixedAir->OAController(OutAirNum);

thisOAController.Name = Alphas(1);
thisOAController.ControllerType = CurrentModuleObject;
thisOAController.ControllerType_Num = MixedAir::MixedAirControllerType::ControllerStandAloneERV;
thisOAController.ControllerType = MixedAir::MixedAirControllerType::ControllerStandAloneERV;
Copy link
Contributor

Choose a reason for hiding this comment

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

Combine type and num into one variable.

@@ -140,6 +140,9 @@ using namespace FaultsManager;

constexpr std::array<std::string_view, static_cast<int>(ControllerKind::Num)> ControllerKindNamesUC{"CONTROLLER:WATERCOIL", "CONTROLLER:OUTDOORAIR"};

constexpr std::array<std::string_view, static_cast<int>(MixedAirControllerType::Num)> MixedAirControllerTypeNames{
"Controller:OutdoorAir", "ZoneHVAC:EnergyRecoveryVentilator:Controller"};

Copy link
Contributor

Choose a reason for hiding this comment

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

and either is available with the new enum and type array

thisVentilationMechanical.ZoneSecondaryRecirculation.dimension(MechVentZoneCount, 0.0);
thisVentilationMechanical.ZoneDesignSpecADObjName.allocate(MechVentZoneCount);
thisVentilationMechanical.ZoneDesignSpecADObjIndex.dimension(MechVentZoneCount, 0);
thisVentilationMechanical.VentMechZone.allocate(MechVentZoneCount);
Copy link
Contributor

Choose a reason for hiding this comment

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

move all these mech vent arrays to a new class

break;
}
}
if (found) {
Copy link
Contributor

Choose a reason for hiding this comment

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

CppCheck says this could be done with any_of but will address that when the time comes.

[src/EnergyPlus/MixedAir.cc:1414]:(style),[useStlAlgorithm],Consider using std::any_of algorithm instead of a raw loop.

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

thisVentilationMechanical.VentMechZoneName(MechVentZoneCount) = state.dataHeatBal->Zone(ZoneNum).Name;
auto &thisMechVentZone = thisVentilationMechanical.VentMechZone(MechVentZoneCount);
thisMechVentZone.zoneNum = ZoneNum;
thisMechVentZone.name = state.dataHeatBal->Zone(ZoneNum).Name;
Copy link
Contributor

Choose a reason for hiding this comment

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

begin saving data into new struct


GetZoneData(*state, ErrorsFound);
GetOARequirements(*state);
GetZoneEquipment(*state);
GetOAControllerInputs(*state);
ZoneAirLoopEquipmentManager::GetZoneAirLoopEquipment(*state);
SingleDuct::GetSysInput(*state);
Copy link
Contributor

Choose a reason for hiding this comment

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

I see, so you could call single duct for both TUs.

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 see, so you could call single duct for both TUs.

And keep the connections simple, and not need a fan object, etc.

OAMassFlow = state->dataMixedAir->VentilationMechanical(1).CalcMechVentController(*state, SysMassFlow);

EXPECT_TRUE(OAMassFlow > DesignOAMassFlow); // Expect that the system OA is greater than the design OA air flow
EXPECT_TRUE(OAMassFlow == SysMassFlow); // Expect that the system OA is less than the system air flow
Copy link
Contributor

Choose a reason for hiding this comment

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

Well, comment says OA is less than system flow, but they are equal. Copy-paste.

EXPECT_EQ(SysOAMethod::IAQP, state->dataMixedAir->VentilationMechanical(1).SystemOAMethod);
state->dataMixedAir->VentilationMechanical(1).CalcMechVentController(*state, SysMassFlow, OAMassFlow);
OAMassFlow = state->dataMixedAir->VentilationMechanical(1).CalcMechVentController(*state, SysMassFlow);
Copy link
Contributor

Choose a reason for hiding this comment

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

now OA flow is returned from the function

EXPECT_EQ(0.0, OAMassFlow);

state->dataContaminantBalance->ZoneSysContDemand.deallocate();
state->dataScheduleMgr->Schedule.deallocate();
Copy link
Contributor

Choose a reason for hiding this comment

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

clean up unnecessary deallocate at end of unit test

state->dataLoopNodes->Node(primaryInletNode2).MassFlowRate = SupplyMassFlow2;
state->dataLoopNodes->Node(primaryOutletNode1).MassFlowRate = SupplyMassFlow1;
state->dataLoopNodes->Node(primaryOutletNode2).MassFlowRate = SupplyMassFlow2;
SysMassFlow = SupplyMassFlow1 + SupplyMassFlow2; // System supply mass flow rate [kg/s]
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure of the need for code duplication here, lines 5565-5572 and 5580-5585. I don't think those would have changed from previous test. You lost me on the "Starve one zone" comment

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, I see, before SupplyMassFlow1 was /0.5 and now it's *0.5. That makes sense. So the "1" vars changed.

@rraustad
Copy link
Contributor

Only diff is SolarShading, with no warnings.

@rraustad
Copy link
Contributor

It must be the any_of that caused these new diffs?

@@ -1471,15 +1466,9 @@ void GetOAControllerInputs(EnergyPlusData &state)
if (ZoneListNum > 0) {
for (int ScanZoneListNum = 1; ScanZoneListNum <= state.dataHeatBal->ZoneList(ZoneListNum).NumOfZones; ++ScanZoneListNum) {
// check to make sure zone name is unique (not listed more than once)...
int ZoneNum = state.dataHeatBal->ZoneList(ZoneListNum).Zone(ScanZoneListNum);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

So, I mistakenly deleted this line. How did it build, then? Is there another ZoneNum that's still in scope here?

Copy link
Contributor

Choose a reason for hiding this comment

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

Wise choice to change the var name. Same name in the outer loop.

@rraustad
Copy link
Contributor

@Myoldmopar this appears to be clean now so should be ready for merge soon.

@nrel-bot-2c
Copy link

@mjwitte it has been 8 days since this pull request was last updated.

@Myoldmopar
Copy link
Member

Wow, this is great! I'll get on this one now

@Myoldmopar
Copy link
Member

Everything looks good locally, let's get this in. Merging it now, thanks @mjwitte and @rraustad

@Myoldmopar Myoldmopar merged commit 0123f73 into develop May 6, 2023
@Myoldmopar Myoldmopar deleted the OALimitingFactor8802PlanD branch May 6, 2023 12:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Refactoring Includes code changes that don't change the functionality of the program, just perform refactoring
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Air System Outdoor Air Limiting Factor can be wrong for simple OA controls due to tiny differences
9 participants