Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Global Boilers and Chillers #7968

Merged
merged 20 commits into from
May 14, 2020
Merged

Global Boilers and Chillers #7968

merged 20 commits into from
May 14, 2020

Conversation

mitchute
Copy link
Collaborator

@mitchute mitchute commented May 5, 2020

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

@mitchute mitchute added the Refactoring Includes code changes that don't change the functionality of the program, just perform refactoring label May 5, 2020
@mitchute mitchute added this to the EnergyPlus 9.4.0 milestone May 5, 2020
@mitchute mitchute self-assigned this May 5, 2020
@mitchute mitchute changed the title Global Boilers Global Boilers and Chillers May 5, 2020
@Myoldmopar
Copy link
Member

I didn't wait on the build to finish before pushing, but I think that takes care of it. The includes went circular. DataPlant.hh was including the plant topology, and deep down in the plant topology classes, it included the big Data.hh file. I moved those to forward declarations and that shouldn't happen anymore for plant components now.

@Myoldmopar
Copy link
Member

There we go, that's nice and green

@mitchute
Copy link
Collaborator Author

mitchute commented May 7, 2020

The windows unit test failure passes on my VM. I won't worry about it any further at this point.

@mjwitte
Copy link
Contributor

mjwitte commented May 7, 2020

@mitchute Yeah, these have been showing up randomly on the Windows CI lately.
unknown file: error: C++ exception with description "InitializeMeters: Could not open file eplusout.mtd for output (write)." thrown in the test body.

@Myoldmopar
Copy link
Member

I think once we get the mtd file converted over to the new OutputFiles structure, these will go away.

Copy link
Collaborator Author

@mitchute mitchute left a comment

Choose a reason for hiding this comment

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

Another step towards controlling the global state of E+. A nice pattern is beginning to emerge here.


void onInitLoopEquip(EnergyPlusData &EP_UNUSED(state), const PlantLocation &EP_UNUSED(calledFromLocation)) override;

static PlantComponent *factory(std::string const &objectName);
static PlantComponent *factory(BoilerSteamData &boilers, std::string const &objectName);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Boiler and chiller data classes now being passed into the factory and GetInput methods.

Copy link
Member

Choose a reason for hiding this comment

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

That's interesting. I didn't think of that side-effect of this. We'll be passing a reference to the state around to all the factories. It makes me wonder if the factories will eventually become part of the state data classes. Pondering, pondering...

@@ -233,75 +201,76 @@ namespace Boilers {
// ErrorsFound will be set to True if problem was found, left untouched otherwise
GlobalNames::VerifyUniqueBoilerName(
DataIPShortCuts::cCurrentModuleObject, DataIPShortCuts::cAlphaArgs(1), ErrorsFound, DataIPShortCuts::cCurrentModuleObject + " Name");
Boiler(BoilerNum).Name = DataIPShortCuts::cAlphaArgs(1);
Boiler(BoilerNum).TypeNum = DataPlant::TypeOf_Boiler_Simple;
auto &thisBoiler = boilers.Boiler(BoilerNum);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Adding the state class reference to the front of everything was starting to get cumbersome to look at. auto & added where possible.

// MODULE VARIABLE DECLARATIONS:
extern int NumBoilers; // Number of boilers
extern bool GetBoilerInputFlag; // Boiler input flag, false if input is processed
enum class TempMode
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

New enum to get rid of some of these externs. The other boilers don't appear to need anything like this, so I left it in the header file.

Copy link
Member

Choose a reason for hiding this comment

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

👍 👍


int const waterIndex(1);
const char * fluidNameWater = "WATER";
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Better than string literals all over the place? 🤷‍♂️

The following was suggested,

constexpr char * fluidName = "Water";

but it throws warnings on my machine.

warning: ISO C++11 does not allow conversion from string literal to 'char *const' [-Wwritable-strings]

Copy link
Member

Choose a reason for hiding this comment

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

I think it's better than string literals. Using a pointer to a constant character makes good sense until we come up with anything better. The warning is because a string literal is by definition a constant character string. It cannot be changed. The way you've declared it here, it's all fine, you have a pointer to a const char (const char *). The constexpr way was trying to make it a constant pointer to a non-constant char (char * const), which won't work because the string literal is constant.


BLASTAbsorber.allocate(numBlastAbsorbers);
chillers.BLASTAbsorber.allocate(chillers.numBlastAbsorbers);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Missed auto & here. Add it?

Copy link
Member

Choose a reason for hiding this comment

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

No, the allocate call just returns a reference to the original object, no need to capture it (in our use cases, anyway).

// Functions

void SimCostEstimate()
void SimCostEstimate(EnergyPlusData &state)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

A few new &state references in places.

@@ -68,6 +79,107 @@ namespace EnergyPlus {
// }
//};

struct BoilersData : BaseGlobalStruct {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Most of these boilers and chiller data classes only contain three members: a getInput flag, an integer numObjects member, and a 1D array of objects. These should probably get consolidated later.

Copy link
Member

Choose a reason for hiding this comment

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

This is going to prove to be exceedingly common as we move through plant components.

@@ -261,6 +261,23 @@ namespace DataPlant {
extern int PlantManageSubIterations; // tracks plant iterations to characterize solver
extern int PlantManageHalfLoopCalls; // tracks number of half loop calls

// Enum classes
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

New enums I mentioned earlier.

GTChiller.deallocate();
ConstCOPChiller.deallocate();
}
Real64 constexpr KJtoJ(1000.0); // convert Kjoules to joules
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

constexpr for numerical constants. There's probably something similar for the string constants.

@@ -250,16 +247,8 @@ void EnergyPlus::clearAllStates()
AirflowNetworkBalanceManager::clear_state();
BaseboardElectric::clear_state();
BaseboardRadiator::clear_state();
Boilers::clear_state();
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

All of this now happens over in the state data class.

@mitchute mitchute mentioned this pull request May 13, 2020
20 tasks
Copy link
Member

@Myoldmopar Myoldmopar left a comment

Choose a reason for hiding this comment

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

This is just a great effort. The only thing that I really want to fix up before merging is the pointer usage in the unit test code. It will be a very quick change to just make it a reference instead. It could be nice to propagate that same change elsewhere in the unit tests, but that doesn't have to be here. I may make those changes though.


void onInitLoopEquip(EnergyPlusData &EP_UNUSED(state), const PlantLocation &EP_UNUSED(calledFromLocation)) override;

static PlantComponent *factory(std::string const &objectName);
static PlantComponent *factory(BoilerSteamData &boilers, std::string const &objectName);
Copy link
Member

Choose a reason for hiding this comment

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

That's interesting. I didn't think of that side-effect of this. We'll be passing a reference to the state around to all the factories. It makes me wonder if the factories will eventually become part of the state data classes. Pondering, pondering...

// MODULE VARIABLE DECLARATIONS:
extern int NumBoilers; // Number of boilers
extern bool GetBoilerInputFlag; // Boiler input flag, false if input is processed
enum class TempMode
Copy link
Member

Choose a reason for hiding this comment

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

👍 👍


int const waterIndex(1);
const char * fluidNameWater = "WATER";
Copy link
Member

Choose a reason for hiding this comment

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

I think it's better than string literals. Using a pointer to a constant character makes good sense until we come up with anything better. The warning is because a string literal is by definition a constant character string. It cannot be changed. The way you've declared it here, it's all fine, you have a pointer to a const char (const char *). The constexpr way was trying to make it a constant pointer to a non-constant char (char * const), which won't work because the string literal is constant.

ShowSevereError("No " + DataIPShortCuts::cCurrentModuleObject + " equipment specified in input file");
// See if load distribution manager has already gotten the input
ErrorsFound = true;
}

if (allocated(BLASTAbsorber)) return;
if (allocated(chillers.BLASTAbsorber)) return;
Copy link
Member

Choose a reason for hiding this comment

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

You are welcome to change variable names like BLASTAbsorber if you want. You can ping me or others if you want an idea, but in this case, I think it would be just more clear to just say chillers.absorptionChillers or something. No big deal for now though, carry on!

@@ -1784,42 +1783,43 @@ TEST_F(EnergyPlusFixture, ChillerAbsorption_Calc)
Real64 AbsChillEvapLoad;
bool AbsChillRunFlag = true;
// check chiller inputs
EXPECT_EQ(BLASTAbsorber(AbsChillNum).NomCap, 100000.0);
EXPECT_EQ(BLASTAbsorber(AbsChillNum).FlowMode, ChillerAbsorption::LeavingSetPointModulated);
auto thisChiller = &state.dataChillerAbsorbers.BLASTAbsorber(AbsChillNum);
Copy link
Member

Choose a reason for hiding this comment

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

This is creating a pointer. While I'm not afraid of pointers, I think it would be good to avoid this pattern too broadly. I would suggest making the subtle change:

auto thisChiller = &state.dataChillerAbsorbers.BLASTAbsorber(AbsChillNum);
          to
auto & thisChiller = state.dataChillerAbsorbers.BLASTAbsorber(AbsChillNum);

This way you are creating a reference instead of a pointer.


DataPlant::PlantLoop(1).Name = "ChilledWaterLoop";
DataPlant::PlantLoop(1).FluidName = "ChilledWater";
DataPlant::PlantLoop(1).FluidIndex = 1;
DataPlant::PlantLoop(1).PlantSizNum = 1;
DataPlant::PlantLoop(1).FluidName = "WATER";
DataPlant::PlantLoop(1).LoopSide(1).Branch(1).Comp(1).Name = ConstCOPChiller(1).Name;
DataPlant::PlantLoop(1).LoopSide(1).Branch(1).Comp(1).Name = state.dataPlantChillers.ConstCOPChiller(1).Name;
Copy link
Member

Choose a reason for hiding this comment

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

Creating another reference to this chiller is a great way to clean up this test like you did with the absorber.

@@ -140,21 +252,73 @@ namespace EnergyPlus {
}
};

struct PlantChillersData : BaseGlobalStruct {
Copy link
Member

Choose a reason for hiding this comment

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

Yes. This class should be split into four different ones. Sorta. Each one will again only have a num integer, getinput bool, and an array of objects. I think I see where this is going for reals.

Copy link
Member

@Myoldmopar Myoldmopar left a comment

Choose a reason for hiding this comment

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

All good here. Thanks for the quick fixes.

@@ -120,7 +120,7 @@ namespace ChillerAbsorption {
chillers.getInput = false;
}
// Now look for this particular object
for (auto &thisAbs : chillers.BLASTAbsorber) {
for (auto &thisAbs : chillers.absorptionChillers) {
Copy link
Member

Choose a reason for hiding this comment

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

Yeah, that's nicer 😄

auto thisChiller = &state.dataChillerAbsorbers.BLASTAbsorber(AbsChillNum);
EXPECT_EQ(thisChiller->NomCap, 100000.0);
EXPECT_EQ(thisChiller->FlowMode, DataPlant::FlowMode::LEAVINGSETPOINTMODULATED);
auto &thisChiller = state.dataChillerAbsorbers.absorptionChillers(AbsChillNum);
Copy link
Member

Choose a reason for hiding this comment

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

Yes. Thanks!

@Myoldmopar
Copy link
Member

@mitchute I then #7972 will merge in shortly, then I'll pull develop into this branch locally and run regressions. Assuming all is well I think this will go in directly.

@Myoldmopar
Copy link
Member

Pulled develop in and ran regressions overnight. All good here. Merging.

@Myoldmopar Myoldmopar merged commit be87902 into develop May 14, 2020
@Myoldmopar Myoldmopar deleted the global_boiler branch May 14, 2020 14:10
# for free to join this conversation on GitHub. Already have an account? # 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.

8 participants