From 68ab73fd9c66b1ca3c5b466e950df1ea7b4e89ae Mon Sep 17 00:00:00 2001 From: Matt Mitchell Date: Fri, 29 Jan 2021 09:43:13 -0700 Subject: [PATCH] moving GHE Slinky input to JSON constructor --- src/EnergyPlus/GroundHeatExchangers.cc | 480 ++++++++++++++++--------- src/EnergyPlus/GroundHeatExchangers.hh | 3 + 2 files changed, 318 insertions(+), 165 deletions(-) diff --git a/src/EnergyPlus/GroundHeatExchangers.cc b/src/EnergyPlus/GroundHeatExchangers.cc index aa99ccf8a38..1d6fe9dff81 100644 --- a/src/EnergyPlus/GroundHeatExchangers.cc +++ b/src/EnergyPlus/GroundHeatExchangers.cc @@ -62,7 +62,6 @@ #include #include #include -#include #include #include #include @@ -125,6 +124,140 @@ namespace EnergyPlus::GroundHeatExchangers { //****************************************************************************** + GLHESlinky::GLHESlinky(EnergyPlusData &state, std::string const &objName, nlohmann::json const &j) + { + // Check for duplicates + for (auto &existingObj : state.dataGroundHeatExchanger->singleBoreholesVector) { + if (objName == existingObj->name) { + ShowFatalError(state, "Invalid input for " + this->moduleName + " object: Duplicate name found: " + existingObj->name); + } + } + + bool errorsFound = false; + + this->name = objName; + + std::string inletNodeName = UtilityRoutines::MakeUPPERCase(j["inlet_node_name"]); + std::string outletNodeName = UtilityRoutines::MakeUPPERCase(j["outlet_node_name"]); + + // get inlet node num + this->inletNodeNum = NodeInputManager::GetOnlySingleNode( + state, inletNodeName, errorsFound, this->moduleName, this->name, NodeType_Water, NodeConnectionType_Inlet, 1, ObjectIsNotParent); + + // get outlet node num + this->outletNodeNum = NodeInputManager::GetOnlySingleNode( + state, outletNodeName, errorsFound, this->moduleName, this->name, NodeType_Water, NodeConnectionType_Outlet, 1, ObjectIsNotParent); + + this->available = true; + this->on = true; + + BranchNodeConnections::TestCompSet(state, + this->moduleName, + this->name, + inletNodeName, + outletNodeName, + "Condenser Water Nodes"); + + // load data + this->designFlow = j["design_flow_rate"]; + PlantUtilities::RegisterPlantCompDesignFlow(this->inletNodeNum, this->designFlow); + + this->soil.k = j["soil_thermal_conductivity"]; + + Real64 const rho = j["soil_density"]; + Real64 const cp = j["soil_specific_heat"]; + this->soil.rhoCp = rho * cp; + this->pipe.k = j["pipe_thermal_conductivity"]; + this->pipe.rho = j["pipe_density"]; + this->pipe.cp = j["pipe_specific_heat"]; + this->pipe.outDia = j["pipe_outer_diameter"]; + this->pipe.outRadius = this->pipe.outDia / 2.0; + this->pipe.thickness = j["pipe_thickness"]; + + std::string const hxConfig = UtilityRoutines::MakeUPPERCase(j["heat_exchanger_configuration"]); + if (UtilityRoutines::SameString(hxConfig, "VERTICAL")) { + this->verticalConfig = true; + } else if (UtilityRoutines::SameString(hxConfig, "HORIZONTAL")) { + this->verticalConfig = false; + } + + this->coilDiameter = j["coil_diameter"]; + this->coilPitch = j["coil_pitch"]; + this->trenchDepth = j["trench_depth"]; + this->trenchLength = j["trench_length"]; + this->numTrenches = j["number_of_trenches"]; + this->trenchSpacing = j["horizontal_spacing_between_pipes"]; + this->maxSimYears = j["maximum_length_of_simulation"]; + + // Need to add a response factor object for the slinky model + std::shared_ptr thisRF(new GLHEResponseFactors); + thisRF->name = + "Response Factor Object Auto Generated No: " + fmt::to_string(state.dataGroundHeatExchanger->numAutoGeneratedResponseFactors + 1); + this->myRespFactors = thisRF; + state.dataGroundHeatExchanger->responseFactorsVector.push_back(thisRF); + + // Number of coils + this->numCoils = static_cast(this->trenchLength / this->coilPitch); + + // Total tube length + this->totalTubeLength = + DataGlobalConstants::Pi * this->coilDiameter * this->trenchLength * this->numTrenches / this->coilPitch; + + // Get g function data + this->SubAGG = 15; + this->AGG = 192; + + // Average coil depth + if (this->verticalConfig) { + // Vertical configuration + if (this->trenchDepth - this->coilDiameter < 0.0) { + // Error: part of the coil is above ground + ShowSevereError(state, this->moduleName + "=\"" + this->name + "\", invalid value in field."); + ShowContinueError(state, format("...{}=[{:.3R}].", "Trench Depth", this->trenchDepth)); + ShowContinueError(state, format("...{}=[{:.3R}].", "Coil Depth", this->coilDepth)); + ShowContinueError(state, "...Part of coil will be above ground."); + errorsFound = true; + + } else { + // Entire coil is below ground + this->coilDepth = this->trenchDepth - (this->coilDiameter / 2.0); + } + + } else { + // Horizontal configuration + this->coilDepth = this->trenchDepth; + } + + // Thermal diffusivity of the ground + this->soil.diffusivity = this->soil.k / this->soil.rhoCp; + + state.dataGroundHeatExchanger->prevTimeSteps.allocate(static_cast((this->SubAGG + 1) * maxTSinHr + 1)); + state.dataGroundHeatExchanger->prevTimeSteps = 0.0; + + if (this->pipe.thickness >= this->pipe.outDia / 2.0) { + ShowSevereError(state, this->moduleName + "=\"" + this->name + "\", invalid value in field."); + ShowContinueError(state, format("...{}=[{:.3R}].", "Pipe Thickness", this->pipe.thickness)); + ShowContinueError(state, format("...{}=[{:.3R}].", "Pipe Outer Diameter", this->pipe.outDia)); + ShowContinueError(state, "...Radius will be <=0."); + errorsFound = true; + } + + // Initialize ground temperature model and get pointer reference + std::string const gtmType = UtilityRoutines::MakeUPPERCase(j["undisturbed_ground_temperature_model_type"]); + std::string const gtmName = UtilityRoutines::MakeUPPERCase(j["undisturbed_ground_temperature_model_name"]); + this->groundTempModel = GetGroundTempModelAndInit(state, gtmType, gtmName); + if (this->groundTempModel) { + errorsFound = this->groundTempModel->errorsFound; + } + + // Check for Errors + if (errorsFound) { + ShowFatalError(state, "Errors found in processing input for " + this->moduleName); + } + } + + //****************************************************************************** + GLHEVert::GLHEVert(EnergyPlusData &state, std::string const &objName, nlohmann::json const &j) { // Check for duplicates @@ -2482,173 +2615,190 @@ namespace EnergyPlus::GroundHeatExchangers { if (state.dataGroundHeatExchanger->numSlinkyGLHEs > 0) { - DataIPShortCuts::cCurrentModuleObject = "GroundHeatExchanger:Slinky"; - - for (int GLHENum = 1; GLHENum <= state.dataGroundHeatExchanger->numSlinkyGLHEs; ++GLHENum) { - - // just a few vars to pass in and out to GetObjectItem - int ioStatus; - int numAlphas; - int numNumbers; - - // get the input data and store it in the Shortcuts structures - inputProcessor->getObjectItem(state, - DataIPShortCuts::cCurrentModuleObject, - GLHENum, - DataIPShortCuts::cAlphaArgs, - numAlphas, - DataIPShortCuts::rNumericArgs, - numNumbers, - ioStatus, - DataIPShortCuts::lNumericFieldBlanks, - DataIPShortCuts::lAlphaFieldBlanks, - DataIPShortCuts::cAlphaFieldNames, - DataIPShortCuts::cNumericFieldNames); - - // the input processor validates the numeric inputs based on the IDD definition - // still validate the name to make sure there aren't any duplicates or blanks - // blanks are easy: fatal if blank - if (DataIPShortCuts::lAlphaFieldBlanks[0]) { - ShowFatalError(state, "Invalid input for " + DataIPShortCuts::cCurrentModuleObject + " object: Name cannot be blank"); - } - - // we just need to loop over the existing vector elements to check for duplicates since we haven't add this one yet - for (auto &existingSlinkyGLHE : state.dataGroundHeatExchanger->slinkyGLHE) { - if (DataIPShortCuts::cAlphaArgs(1) == existingSlinkyGLHE.name) { - ShowFatalError(state, - "Invalid input for " + DataIPShortCuts::cCurrentModuleObject + - " object: Duplicate name found: " + existingSlinkyGLHE.name); - } - } - - // Build out new instance - GLHESlinky thisGLHE; - thisGLHE.name = DataIPShortCuts::cAlphaArgs(1); - - // get inlet node num - thisGLHE.inletNodeNum = NodeInputManager::GetOnlySingleNode(state, - DataIPShortCuts::cAlphaArgs(2), - errorsFound, - DataIPShortCuts::cCurrentModuleObject, - DataIPShortCuts::cAlphaArgs(1), - NodeType_Water, - NodeConnectionType_Inlet, - 1, - ObjectIsNotParent); - - // get outlet node num - thisGLHE.outletNodeNum = NodeInputManager::GetOnlySingleNode(state, - DataIPShortCuts::cAlphaArgs(3), - errorsFound, - DataIPShortCuts::cCurrentModuleObject, - DataIPShortCuts::cAlphaArgs(1), - NodeType_Water, - NodeConnectionType_Outlet, - 1, - ObjectIsNotParent); - thisGLHE.available = true; - thisGLHE.on = true; - - BranchNodeConnections::TestCompSet(state, - DataIPShortCuts::cCurrentModuleObject, - DataIPShortCuts::cAlphaArgs(1), - DataIPShortCuts::cAlphaArgs(2), - DataIPShortCuts::cAlphaArgs(3), - "Condenser Water Nodes"); - - // load data - thisGLHE.designFlow = DataIPShortCuts::rNumericArgs(1); - PlantUtilities::RegisterPlantCompDesignFlow(thisGLHE.inletNodeNum, thisGLHE.designFlow); - - thisGLHE.soil.k = DataIPShortCuts::rNumericArgs(2); - thisGLHE.soil.rhoCp = DataIPShortCuts::rNumericArgs(3) * DataIPShortCuts::rNumericArgs(4); - thisGLHE.pipe.k = DataIPShortCuts::rNumericArgs(5); - thisGLHE.pipe.rho = DataIPShortCuts::rNumericArgs(6); - thisGLHE.pipe.cp = DataIPShortCuts::rNumericArgs(7); - thisGLHE.pipe.outDia = DataIPShortCuts::rNumericArgs(8); - thisGLHE.pipe.outRadius = thisGLHE.pipe.outDia / 2.0; - thisGLHE.pipe.thickness = DataIPShortCuts::rNumericArgs(9); - - if (UtilityRoutines::SameString(DataIPShortCuts::cAlphaArgs(4), "VERTICAL")) { - thisGLHE.verticalConfig = true; - } else if (UtilityRoutines::SameString(DataIPShortCuts::cAlphaArgs(4), "HORIZONTAL")) { - thisGLHE.verticalConfig = false; - } - - thisGLHE.coilDiameter = DataIPShortCuts::rNumericArgs(10); - thisGLHE.coilPitch = DataIPShortCuts::rNumericArgs(11); - thisGLHE.trenchDepth = DataIPShortCuts::rNumericArgs(12); - thisGLHE.trenchLength = DataIPShortCuts::rNumericArgs(13); - thisGLHE.numTrenches = DataIPShortCuts::rNumericArgs(14); - thisGLHE.trenchSpacing = DataIPShortCuts::rNumericArgs(15); - thisGLHE.maxSimYears = DataIPShortCuts::rNumericArgs(16); - - // Need to add a response factor object for the slinky model - std::shared_ptr thisRF(new GLHEResponseFactors); - thisRF->name = - "Response Factor Object Auto Generated No: " + fmt::to_string(state.dataGroundHeatExchanger->numAutoGeneratedResponseFactors + 1); - thisGLHE.myRespFactors = thisRF; - state.dataGroundHeatExchanger->responseFactorsVector.push_back(thisRF); - - // Number of coils - thisGLHE.numCoils = static_cast(thisGLHE.trenchLength / thisGLHE.coilPitch); - - // Total tube length - thisGLHE.totalTubeLength = - DataGlobalConstants::Pi * thisGLHE.coilDiameter * thisGLHE.trenchLength * thisGLHE.numTrenches / thisGLHE.coilPitch; - - // Get g function data - thisGLHE.SubAGG = 15; - thisGLHE.AGG = 192; - - // Average coil depth - if (thisGLHE.verticalConfig) { - // Vertical configuration - if (thisGLHE.trenchDepth - thisGLHE.coilDiameter < 0.0) { - // Error: part of the coil is above ground - ShowSevereError(state, DataIPShortCuts::cCurrentModuleObject + "=\"" + thisGLHE.name + "\", invalid value in field."); - ShowContinueError(state, format("...{}=[{:.3R}].", DataIPShortCuts::cNumericFieldNames(13), thisGLHE.trenchDepth)); - ShowContinueError(state, format("...{}=[{:.3R}].", DataIPShortCuts::cNumericFieldNames(10), thisGLHE.coilDepth)); - ShowContinueError(state, "...Average coil depth will be <=0."); - errorsFound = true; - - } else { - // Entire coil is below ground - thisGLHE.coilDepth = thisGLHE.trenchDepth - (thisGLHE.coilDiameter / 2.0); - } - - } else { - // Horizontal configuration - thisGLHE.coilDepth = thisGLHE.trenchDepth; - } - - // Thermal diffusivity of the ground - thisGLHE.soil.diffusivity = thisGLHE.soil.k / thisGLHE.soil.rhoCp; - - state.dataGroundHeatExchanger->prevTimeSteps.allocate(static_cast((thisGLHE.SubAGG + 1) * maxTSinHr + 1)); - state.dataGroundHeatExchanger->prevTimeSteps = 0.0; - - if (thisGLHE.pipe.thickness >= thisGLHE.pipe.outDia / 2.0) { - ShowSevereError(state, DataIPShortCuts::cCurrentModuleObject + "=\"" + thisGLHE.name + "\", invalid value in field."); - ShowContinueError(state, format("...{}=[{:.3R}].", DataIPShortCuts::cNumericFieldNames(12), thisGLHE.pipe.thickness)); - ShowContinueError(state, format("...{}=[{:.3R}].", DataIPShortCuts::cNumericFieldNames(10), thisGLHE.pipe.outDia)); - ShowContinueError(state, "...Radius will be <=0."); - errorsFound = true; - } - - // Initialize ground temperature model and get pointer reference - thisGLHE.groundTempModel = GetGroundTempModelAndInit(state, DataIPShortCuts::cAlphaArgs(5), DataIPShortCuts::cAlphaArgs(6)); - if (thisGLHE.groundTempModel) { - errorsFound = thisGLHE.groundTempModel->errorsFound; - } + std::string currObj = "GroundHeatExchanger:Slinky"; - // Check for Errors - if (errorsFound) { - ShowFatalError(state, "Errors found in processing input for " + DataIPShortCuts::cCurrentModuleObject); - } + auto const instances = inputProcessor->epJSON.find(currObj); + if (instances == inputProcessor->epJSON.end()) { + ShowSevereError(state, // LCOV_EXCL_LINE + currObj + ": Somehow getNumObjectsFound was > 0 but epJSON.find found 0"); // LCOV_EXCL_LINE + } - state.dataGroundHeatExchanger->slinkyGLHE.push_back(thisGLHE); + auto &instancesValue = instances.value(); + for (auto it = instancesValue.begin(); it != instancesValue.end(); ++it) { + auto const &instance = it.value(); + auto const &objName = it.key(); + auto const &objNameUC = UtilityRoutines::MakeUPPERCase(objName); + inputProcessor->markObjectAsUsed(currObj, objName); + state.dataGroundHeatExchanger->slinkyGLHE.emplace_back(state, objNameUC, instance); } + +// DataIPShortCuts::cCurrentModuleObject = "GroundHeatExchanger:Slinky"; +// +// for (int GLHENum = 1; GLHENum <= state.dataGroundHeatExchanger->numSlinkyGLHEs; ++GLHENum) { +// +// // just a few vars to pass in and out to GetObjectItem +// int ioStatus; +// int numAlphas; +// int numNumbers; +// +// // get the input data and store it in the Shortcuts structures +// inputProcessor->getObjectItem(state, +// DataIPShortCuts::cCurrentModuleObject, +// GLHENum, +// DataIPShortCuts::cAlphaArgs, +// numAlphas, +// DataIPShortCuts::rNumericArgs, +// numNumbers, +// ioStatus, +// DataIPShortCuts::lNumericFieldBlanks, +// DataIPShortCuts::lAlphaFieldBlanks, +// DataIPShortCuts::cAlphaFieldNames, +// DataIPShortCuts::cNumericFieldNames); +// +// // the input processor validates the numeric inputs based on the IDD definition +// // still validate the name to make sure there aren't any duplicates or blanks +// // blanks are easy: fatal if blank +// if (DataIPShortCuts::lAlphaFieldBlanks[0]) { +// ShowFatalError(state, "Invalid input for " + DataIPShortCuts::cCurrentModuleObject + " object: Name cannot be blank"); +// } +// +// // we just need to loop over the existing vector elements to check for duplicates since we haven't add this one yet +// for (auto &existingSlinkyGLHE : state.dataGroundHeatExchanger->slinkyGLHE) { +// if (DataIPShortCuts::cAlphaArgs(1) == existingSlinkyGLHE.name) { +// ShowFatalError(state, +// "Invalid input for " + DataIPShortCuts::cCurrentModuleObject + +// " object: Duplicate name found: " + existingSlinkyGLHE.name); +// } +// } +// +// // Build out new instance +// GLHESlinky thisGLHE; +// thisGLHE.name = DataIPShortCuts::cAlphaArgs(1); +// +// // get inlet node num +// thisGLHE.inletNodeNum = NodeInputManager::GetOnlySingleNode(state, +// DataIPShortCuts::cAlphaArgs(2), +// errorsFound, +// DataIPShortCuts::cCurrentModuleObject, +// DataIPShortCuts::cAlphaArgs(1), +// NodeType_Water, +// NodeConnectionType_Inlet, +// 1, +// ObjectIsNotParent); +// +// // get outlet node num +// thisGLHE.outletNodeNum = NodeInputManager::GetOnlySingleNode(state, +// DataIPShortCuts::cAlphaArgs(3), +// errorsFound, +// DataIPShortCuts::cCurrentModuleObject, +// DataIPShortCuts::cAlphaArgs(1), +// NodeType_Water, +// NodeConnectionType_Outlet, +// 1, +// ObjectIsNotParent); +// thisGLHE.available = true; +// thisGLHE.on = true; +// +// BranchNodeConnections::TestCompSet(state, +// DataIPShortCuts::cCurrentModuleObject, +// DataIPShortCuts::cAlphaArgs(1), +// DataIPShortCuts::cAlphaArgs(2), +// DataIPShortCuts::cAlphaArgs(3), +// "Condenser Water Nodes"); +// +// // load data +// thisGLHE.designFlow = DataIPShortCuts::rNumericArgs(1); +// PlantUtilities::RegisterPlantCompDesignFlow(thisGLHE.inletNodeNum, thisGLHE.designFlow); +// +// thisGLHE.soil.k = DataIPShortCuts::rNumericArgs(2); +// thisGLHE.soil.rhoCp = DataIPShortCuts::rNumericArgs(3) * DataIPShortCuts::rNumericArgs(4); +// thisGLHE.pipe.k = DataIPShortCuts::rNumericArgs(5); +// thisGLHE.pipe.rho = DataIPShortCuts::rNumericArgs(6); +// thisGLHE.pipe.cp = DataIPShortCuts::rNumericArgs(7); +// thisGLHE.pipe.outDia = DataIPShortCuts::rNumericArgs(8); +// thisGLHE.pipe.outRadius = thisGLHE.pipe.outDia / 2.0; +// thisGLHE.pipe.thickness = DataIPShortCuts::rNumericArgs(9); +// +// if (UtilityRoutines::SameString(DataIPShortCuts::cAlphaArgs(4), "VERTICAL")) { +// thisGLHE.verticalConfig = true; +// } else if (UtilityRoutines::SameString(DataIPShortCuts::cAlphaArgs(4), "HORIZONTAL")) { +// thisGLHE.verticalConfig = false; +// } +// +// thisGLHE.coilDiameter = DataIPShortCuts::rNumericArgs(10); +// thisGLHE.coilPitch = DataIPShortCuts::rNumericArgs(11); +// thisGLHE.trenchDepth = DataIPShortCuts::rNumericArgs(12); +// thisGLHE.trenchLength = DataIPShortCuts::rNumericArgs(13); +// thisGLHE.numTrenches = DataIPShortCuts::rNumericArgs(14); +// thisGLHE.trenchSpacing = DataIPShortCuts::rNumericArgs(15); +// thisGLHE.maxSimYears = DataIPShortCuts::rNumericArgs(16); +// +// // Need to add a response factor object for the slinky model +// std::shared_ptr thisRF(new GLHEResponseFactors); +// thisRF->name = +// "Response Factor Object Auto Generated No: " + fmt::to_string(state.dataGroundHeatExchanger->numAutoGeneratedResponseFactors + 1); +// thisGLHE.myRespFactors = thisRF; +// state.dataGroundHeatExchanger->responseFactorsVector.push_back(thisRF); +// +// // Number of coils +// thisGLHE.numCoils = static_cast(thisGLHE.trenchLength / thisGLHE.coilPitch); +// +// // Total tube length +// thisGLHE.totalTubeLength = +// DataGlobalConstants::Pi * thisGLHE.coilDiameter * thisGLHE.trenchLength * thisGLHE.numTrenches / thisGLHE.coilPitch; +// +// // Get g function data +// thisGLHE.SubAGG = 15; +// thisGLHE.AGG = 192; +// +// // Average coil depth +// if (thisGLHE.verticalConfig) { +// // Vertical configuration +// if (thisGLHE.trenchDepth - thisGLHE.coilDiameter < 0.0) { +// // Error: part of the coil is above ground +// ShowSevereError(state, DataIPShortCuts::cCurrentModuleObject + "=\"" + thisGLHE.name + "\", invalid value in field."); +// ShowContinueError(state, format("...{}=[{:.3R}].", DataIPShortCuts::cNumericFieldNames(13), thisGLHE.trenchDepth)); +// ShowContinueError(state, format("...{}=[{:.3R}].", DataIPShortCuts::cNumericFieldNames(10), thisGLHE.coilDepth)); +// ShowContinueError(state, "...Average coil depth will be <=0."); +// errorsFound = true; +// +// } else { +// // Entire coil is below ground +// thisGLHE.coilDepth = thisGLHE.trenchDepth - (thisGLHE.coilDiameter / 2.0); +// } +// +// } else { +// // Horizontal configuration +// thisGLHE.coilDepth = thisGLHE.trenchDepth; +// } +// +// // Thermal diffusivity of the ground +// thisGLHE.soil.diffusivity = thisGLHE.soil.k / thisGLHE.soil.rhoCp; +// +// state.dataGroundHeatExchanger->prevTimeSteps.allocate(static_cast((thisGLHE.SubAGG + 1) * maxTSinHr + 1)); +// state.dataGroundHeatExchanger->prevTimeSteps = 0.0; +// +// if (thisGLHE.pipe.thickness >= thisGLHE.pipe.outDia / 2.0) { +// ShowSevereError(state, DataIPShortCuts::cCurrentModuleObject + "=\"" + thisGLHE.name + "\", invalid value in field."); +// ShowContinueError(state, format("...{}=[{:.3R}].", DataIPShortCuts::cNumericFieldNames(12), thisGLHE.pipe.thickness)); +// ShowContinueError(state, format("...{}=[{:.3R}].", DataIPShortCuts::cNumericFieldNames(10), thisGLHE.pipe.outDia)); +// ShowContinueError(state, "...Radius will be <=0."); +// errorsFound = true; +// } +// +// // Initialize ground temperature model and get pointer reference +// thisGLHE.groundTempModel = GetGroundTempModelAndInit(state, DataIPShortCuts::cAlphaArgs(5), DataIPShortCuts::cAlphaArgs(6)); +// if (thisGLHE.groundTempModel) { +// errorsFound = thisGLHE.groundTempModel->errorsFound; +// } +// +// // Check for Errors +// if (errorsFound) { +// ShowFatalError(state, "Errors found in processing input for " + DataIPShortCuts::cCurrentModuleObject); +// } +// +// state.dataGroundHeatExchanger->slinkyGLHE.push_back(thisGLHE); +// } } } diff --git a/src/EnergyPlus/GroundHeatExchangers.hh b/src/EnergyPlus/GroundHeatExchangers.hh index 3c041018db1..775a9f614a1 100644 --- a/src/EnergyPlus/GroundHeatExchangers.hh +++ b/src/EnergyPlus/GroundHeatExchangers.hh @@ -401,6 +401,7 @@ namespace GroundHeatExchangers { ~GLHESlinky() override = default; // Members + std::string const moduleName = "GroundHeatExchanger:Slinky"; bool verticalConfig; // HX Configuration Flag Real64 coilDiameter; // Diameter of the slinky coils [m] Real64 coilPitch; // Center-to-center slinky coil spacing [m] @@ -423,6 +424,8 @@ namespace GroundHeatExchangers { { } + GLHESlinky(EnergyPlusData &state, std::string const &objName, nlohmann::json const &j); + Real64 calcHXResistance(EnergyPlusData &state) override; void calcGFunctions(EnergyPlusData &state) override;