Skip to content

Commit

Permalink
more swimming pool changes
Browse files Browse the repository at this point in the history
more code updates
  • Loading branch information
RKStrand committed Oct 20, 2014
1 parent 5501d34 commit 63aaee4
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 42 deletions.
2 changes: 2 additions & 0 deletions src/EnergyPlus/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,8 @@ SET( SRC
SurfaceGeometry.hh
SurfaceGroundHeatExchanger.cc
SurfaceGroundHeatExchanger.hh
SwimmingPool.cc
SwimmingPool.hh
SystemAvailabilityManager.cc
SystemAvailabilityManager.hh
SystemReports.cc
Expand Down
32 changes: 26 additions & 6 deletions src/EnergyPlus/HeatBalanceSurfaceManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
#include <ScheduleManager.hh>
#include <SolarShading.hh>
#include <SteamBaseboardRadiator.hh>
#include <SwimmingPool.hh>
#include <ThermalComfort.hh>
#include <UtilityRoutines.hh>
#include <WindowEquivalentLayer.hh>
Expand Down Expand Up @@ -4992,6 +4993,7 @@ CalcHeatBalanceInsideSurf( Optional_int_const ZoneToResimulate ) // if passed in
using DataSizing::CurOverallSimDay;
using namespace DataTimings;
using WindowEquivalentLayer::EQLWindowOutsideEffectiveEmiss;
using SwimmingPool::SimSwimmingPool;

// Locals
// SUBROUTINE ARGUMENT DEFINITIONS:
Expand Down Expand Up @@ -5250,10 +5252,11 @@ CalcHeatBalanceInsideSurf( Optional_int_const ZoneToResimulate ) // if passed in

// Perform heat balance on the inside face of the surface ...
// The following are possibilities here:
// (a) the surface is a partition, in which case the temperature of both sides are the same
// (b) standard (or interzone) opaque surface with no movable insulation, normal heat balance equation
// (c) standard (or interzone) window: call to CalcWindowHeatBalance to get window layer temperatures
// (d) standard opaque surface with movable insulation, special two-part equation
// (a) the surface is a pool (no movable insulation, no source/sink, only CTF solution algorithm)
// (b) the surface is a partition, in which case the temperature of both sides are the same
// (c) standard (or interzone) opaque surface with no movable insulation, normal heat balance equation
// (d) standard (or interzone) window: call to CalcWindowHeatBalance to get window layer temperatures
// (e) standard opaque surface with movable insulation, special two-part equation
// In the surface calculation there are the following Algorithm types for opaque surfaces that
// do not have movable insulation:
// (a) the regular CTF calc (SolutionAlgo = UseCTF)
Expand All @@ -5262,7 +5265,24 @@ CalcHeatBalanceInsideSurf( Optional_int_const ZoneToResimulate ) // if passed in
// (d) the HAMT calc (solutionalgo = UseHAMT).

auto & zone( Zone( ZoneNum ) );
if ( surface.ExtBoundCond == SurfNum && surface.Class != SurfaceClass_Window ) {
if ( surface.IsPool ) {
// This surface is a pool, first check solution method and presence of movable insulation or radiant source/sink
if ( ( surface.HeatTransferAlgorithm == HeatTransferModel_CTF ) && ( surface.MaterialMovInsulInt <= 0 ) && ( ! Construct( ConstrNum ).SourceSinkPresent ) ) {
SimSwimmingPool( SurfNum, TempSurfIn( SurfNum ), RefAirTemp( SurfNum ), IterDampConst, TempInsOld( SurfNum ) );
TempSurfIn( SurfNum ) = TempSurfInTmp( SurfNum );
} else {
// Something present that is not allowed for a swimming pool (non-CTF algorithm, movable insulation, or radiant source/sink
if ( surface.HeatTransferAlgorithm /= HeatTransferModel_CTF ) {
ShowFatalError( surface.Name + " is a pool and is attempting to use a non-CTF solution algorithm. This is not allowed. Use the CTF solution algorithm for this surface." );
}
if ( surface.MaterialMovInsulInt > 0 ) {
ShowFatalError( surface.Name + " is a pool and has movable insulation. This is not allowed. Remove the movable insulation for this surface." );
}
if ( Construct( ConstrNum ).SourceSinkPresent ) {
ShowFatalError( surface.Name + " is a pool and uses a construction with a source/sink. This is not allowed. Use a standard construction for this surface." );
}
}
} else if ( surface.ExtBoundCond == SurfNum && surface.Class != SurfaceClass_Window ) {
//CR6869 -- let Window HB take care of it IF (Surface(SurfNum)%ExtBoundCond == SurfNum) THEN
// Surface is a partition
if ( surface.HeatTransferAlgorithm == HeatTransferModel_CTF || surface.HeatTransferAlgorithm == HeatTransferModel_EMPD ) { // Regular CTF Surface and/or EMPD surface
Expand Down Expand Up @@ -6240,7 +6260,7 @@ GatherComponentLoadsSurfAbsFact()
// *****************************************************************************

// NOTICE
// Copyright © 1996-2014 The Board of Trustees of the University of Illinois
// Copyright 1996-2014 The Board of Trustees of the University of Illinois
// and The Regents of the University of California through Ernest Orlando Lawrence
// Berkeley National Laboratory. All rights reserved.
// Portions of the EnergyPlus software package have been developed and copyrighted
Expand Down
125 changes: 95 additions & 30 deletions src/EnergyPlus/SwimmingPool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <SwimmingPool.hh>
#include <BranchNodeConnections.hh>
#include <DataBranchAirLoopPlant.hh>
#include <DataConversions.hh>
#include <DataEnvironment.hh>
#include <DataHeatBalance.hh>
#include <DataHeatBalFanSys.hh>
Expand Down Expand Up @@ -95,7 +96,11 @@ namespace SwimmingPool {

void
SimSwimmingPool (
int & SurfNum
int const SurfNum,
Real64 & TempSurfIn,
Real64 const RefAirTemp,
Real64 const IterDampConst,
Real64 const TempInsOld
)
{

Expand Down Expand Up @@ -134,12 +139,11 @@ namespace SwimmingPool {

// SUBROUTINE LOCAL VARIABLE DECLARATIONS:
static bool GetInputFlag( true ); // First time, input is "gotten"
static bool ErrorsFound( false ); // Set to true if something goes wrong
int PoolNum; // Pool number index

// FLOW:
if ( GetInputFlag ) {
GetSwimmingPool( ErrorsFound );
GetSwimmingPool;
GetInputFlag = false;
}

Expand All @@ -151,7 +155,7 @@ namespace SwimmingPool {

InitSwimmingPool( PoolNum );

CalcSwimmingPool( PoolNum );
CalcSwimmingPool( PoolNum, SurfNum, TempSurfIn, RefAirTemp, IterDampConst, TempInsOld );

UpdateSwimmingPool( PoolNum );

Expand All @@ -160,9 +164,7 @@ namespace SwimmingPool {
}

void
GetSwimmingPool(
bool ErrorsFound
)
GetSwimmingPool( )
{

// SUBROUTINE INFORMATION:
Expand Down Expand Up @@ -220,6 +222,7 @@ namespace SwimmingPool {
// na

// SUBROUTINE LOCAL VARIABLE DECLARATIONS:
static bool ErrorsFound( false ); // Set to true if something goes wrong
std::string CurrentModuleObject; // for ease in getting objects
FArray1D_string Alphas; // Alpha items for object
FArray1D_string cAlphaFields; // Alpha field names
Expand Down Expand Up @@ -346,7 +349,7 @@ namespace SwimmingPool {
Pool( Item ).CoverEvapFactor = MinCoverFactor;
} else if ( Pool( Item).CoverEvapFactor > MaxCoverFactor ) {
ShowWarningError( RoutineName + CurrentModuleObject + "=\"" + Alphas( 1 ) + " has an evaporation cover factor greater than one." );
ShowContinueError( "The evaporation cover factor has been reset to zero." );
ShowContinueError( "The evaporation cover factor has been reset to one." );
Pool( Item ).CoverEvapFactor = MaxCoverFactor;
}

Expand All @@ -357,7 +360,7 @@ namespace SwimmingPool {
Pool( Item ).CoverConvFactor = MinCoverFactor;
} else if ( Pool( Item).CoverConvFactor > MaxCoverFactor ) {
ShowWarningError( RoutineName + CurrentModuleObject + "=\"" + Alphas( 1 ) + " has a convection cover factor greater than one." );
ShowContinueError( "The convection cover factor has been reset to zero." );
ShowContinueError( "The convection cover factor has been reset to one." );
Pool( Item ).CoverConvFactor = MaxCoverFactor;
}

Expand All @@ -368,7 +371,7 @@ namespace SwimmingPool {
Pool( Item ).CoverSWRadFactor = MinCoverFactor;
} else if ( Pool( Item).CoverSWRadFactor > MaxCoverFactor ) {
ShowWarningError( RoutineName + CurrentModuleObject + "=\"" + Alphas( 1 ) + " has a short-wavelength radiation cover factor greater than one." );
ShowContinueError( "The short-wavelength radiation cover factor has been reset to zero." );
ShowContinueError( "The short-wavelength radiation cover factor has been reset to one." );
Pool( Item ).CoverSWRadFactor = MaxCoverFactor;
}

Expand All @@ -379,7 +382,7 @@ namespace SwimmingPool {
Pool( Item ).CoverLWRadFactor = MinCoverFactor;
} else if ( Pool( Item).CoverLWRadFactor > MaxCoverFactor ) {
ShowWarningError( RoutineName + CurrentModuleObject + "=\"" + Alphas( 1 ) + " has a long-wavelength radiation cover factor greater than one." );
ShowContinueError( "The long-wavelength radiation cover factor has been reset to zero." );
ShowContinueError( "The long-wavelength radiation cover factor has been reset to one." );
Pool( Item ).CoverLWRadFactor = MaxCoverFactor;
}

Expand Down Expand Up @@ -485,7 +488,6 @@ namespace SwimmingPool {
// na

// Using/Aliasing
using DataGlobals::NumOfZones;
using DataGlobals::BeginEnvrnFlag;
using DataGlobals::AnyPlantInModel;
using DataLoopNode::Node;
Expand All @@ -503,6 +505,8 @@ namespace SwimmingPool {

// SUBROUTINE PARAMETER DEFINITIONS:
static std::string const RoutineName( "InitSwimmingPool" );
Real64 const MinActivityFactor = 0.0; // Minimum value for activity factor
Real64 const MaxActivityFactor = 10.0; // Maximum value for activity factor (realistically)

// INTERFACE BLOCK SPECIFICATIONS
// na
Expand All @@ -528,7 +532,7 @@ namespace SwimmingPool {
if ( Pool( PoolNum ).WaterInletNode > 0 ) {
ScanPlantLoopsForObject( Pool( PoolNum ).Name, TypeOf_SwimmingPool_Indoor, Pool( PoolNum ).HWLoopNum, Pool( PoolNum ).HWLoopSide, Pool( PoolNum ).HWBranchNum, Pool( PoolNum ).HWCompNum, _, _, _, Pool( PoolNum ).WaterInletNode, _, errFlag );
if ( errFlag ) {
ShowFatalError( "InitSwimmingPool: Program terminated due to previous condition(s)." );
ShowFatalError( RoutineName + ": Program terminated due to previous condition(s)." );
}
}
MyPlantScanFlagPool( PoolNum ) = false;
Expand Down Expand Up @@ -561,10 +565,20 @@ namespace SwimmingPool {

// get the schedule values for different scheduled parameters
if ( Pool( PoolNum ).ActivityFactorSchedPtr > 0 ) {
Pool( PoolNum ).ActivityFactorSchedPtr = GetCurrentScheduleValue( Pool( PoolNum ).CoverSchedPtr );
Pool( PoolNum ).CurActivityFactor = GetCurrentScheduleValue( Pool( PoolNum ).ActivityFactorSchedPtr );
if ( Pool( PoolNum ).CurActivityFactor < MinActivityFactor ) {
Pool( PoolNum ).CurActivityFactor = MinActivityFactor;
ShowWarningError( RoutineName + ": Swimming Pool =\"" + Pool( PoolNum ).Name + " Activity Factor Schedule =\"" + Pool( PoolNum ).ActivityFactorSchedName + " has a negative value. This is not allowed." );
ShowContinueError( "The activity factor has been reset to zero." );
}
if ( Pool( PoolNum ).CurActivityFactor > MaxActivityFactor ) {
Pool( PoolNum ).CurActivityFactor = 1.0;
ShowWarningError( RoutineName + ": Swimming Pool =\"" + Pool( PoolNum ).Name + " Activity Factor Schedule =\"" + Pool( PoolNum ).ActivityFactorSchedName + " has a value larger than 10. This is not allowed." );
ShowContinueError( "The activity factor has been reset to unity." );
}
} else {
// default is activity factor of 1.0
Pool( PoolNum ).ActivityFactorSchedPtr = 1.0;
Pool( PoolNum ).CurActivityFactor = 1.0;
}

Pool( PoolNum ).CurSetPtTemp = GetCurrentScheduleValue( Pool( PoolNum ).SetPtTempSchedPtr );
Expand All @@ -580,14 +594,14 @@ namespace SwimmingPool {
if ( Pool( PoolNum ).PeopleHeatGainSchedPtr > 0 ) {
HeatGainPerPerson = GetCurrentScheduleValue( Pool(PoolNum).PeopleHeatGainSchedPtr );
if ( HeatGainPerPerson < 0.0 ) {
ShowWarningError( RoutineName + " Swimming Pool =\"" + Pool( PoolNum ).Name + " Heat Gain Schedule =\"" + Pool( PoolNum ).PeopleHeatGainSchedName + " has a negative value. This is not allowed." );
ShowWarningError( RoutineName + ": Swimming Pool =\"" + Pool( PoolNum ).Name + " Heat Gain Schedule =\"" + Pool( PoolNum ).PeopleHeatGainSchedName + " has a negative value. This is not allowed." );
ShowContinueError( "The heat gain per person has been reset to zero." );
HeatGainPerPerson = 0.0;
}
if ( Pool( PoolNum ).PeopleSchedPtr > 0 ) {
PeopleModifier = GetCurrentScheduleValue( Pool( PoolNum ).PeopleSchedPtr );
if ( PeopleModifier < 0.0 ) {
ShowWarningError( RoutineName + " Swimming Pool =\"" + Pool( PoolNum ).Name + " People Schedule =\"" + Pool( PoolNum ).PeopleSchedName + " has a negative value. This is not allowed." );
ShowWarningError( RoutineName + ": Swimming Pool =\"" + Pool( PoolNum ).Name + " People Schedule =\"" + Pool( PoolNum ).PeopleSchedName + " has a negative value. This is not allowed." );
ShowContinueError( "The number of people has been reset to zero." );
PeopleModifier = 0.0;
}
Expand Down Expand Up @@ -626,7 +640,12 @@ namespace SwimmingPool {

void
CalcSwimmingPool(
int const PoolNum // number of the swimming pool
int const PoolNum, // number of the swimming pool
int const SurfNum,
Real64 & TempSurfIn,
Real64 const RefAirTemp,
Real64 const IterDampConst,
Real64 const TempInsOld
)
{

Expand All @@ -642,10 +661,12 @@ namespace SwimmingPool {
// METHODOLOGY EMPLOYED:
// The swimming pool is modeled as a SURFACE to get access to all of the existing
// surface related algorithms. This subroutine mainly models the components of the
// swimming pool so that information can be passed to the heat balance. The heat
// balance will use this information to obtain a proper heat balance based on the
// swimming pool model.

// swimming pool so that information can be used in a standard surface heat balance.
// The pool is assumed to be located at the inside surface face with a possible cover
// affecting the heat balance. The pool model takes the form of an equation solving
// for the inside surface temperature which is assumed to be the same as the pool
// water temperature.

// REFERENCES:
// 1. ASHRAE (2011). 2011 ASHRAE Handbook – HVAC Applications. Atlanta: American Society of Heating,
// Refrigerating and Air-Conditioning Engineers, Inc., p.5.6-5.9.
Expand All @@ -656,22 +677,29 @@ namespace SwimmingPool {
// Indoor Swimming Pools. ASHRAE Transactions 99(2), p.864-874.

// Using/Aliasing
using namespace DataZoneEnergyDemands;
using DataHeatBalance::MRT;
using DataHeatBalance::Zone;
using DataHeatBalance::ZoneData;
using DataHeatBalFanSys::MAT;
using DataHVACGlobals::SmallLoad;
using DataLoopNode::Node;
using DataHeatBalFanSys::ZoneAirHumRatAvg;
using ScheduleManager::GetCurrentScheduleValue;
using PlantUtilities::SetComponentFlowRate;
using DataBranchAirLoopPlant::MassFlowTolerance;
using DataConversions::CFA;
using DataConversions::CFMF;
using Psychrometrics::PsyPsatFnTemp;
using Psychrometrics::PsyRhFnTdbWPb;
using Psychrometrics::PsyHfgAirFnWTdb;
using DataEnvironment::OutBaroPress;
using DataHeatBalance::QRadThermInAbs;
using DataHeatBalSurface::NetLWRadToSurf;
using DataHeatBalFanSys::QHTRadSysSurf;
using DataHeatBalFanSys::QHWBaseboardSurf;
using DataHeatBalFanSys::QSteamBaseboardSurf;
using DataHeatBalFanSys::QElecBaseboardSurf;
using DataHeatBalSurface::QRadSWInAbs;

// Locals
// SUBROUTINE ARGUMENT DEFINITIONS:

// SUBROUTINE PARAMETER DEFINITIONS:
static std::string const RoutineName( "CalcSwimmingPool" );
static Real64 const CFinHg( 0.00029613 ); // Multiple pressure in Pa by this constant to get inches of Hg

// INTERFACE BLOCK SPECIFICATIONS
// na
Expand All @@ -680,10 +708,45 @@ namespace SwimmingPool {
// na

// SUBROUTINE LOCAL VARIABLE DECLARATIONS:
Real64 HConvIn; // convection coefficient for pool
Real64 EvapRate; // evaporation rate for pool in kg/s
Real64 EvapEnergyLossPerArea; // energy effect of evaporation rate per unit area in W/m2
Real64 PSatPool; // saturation pressure at pool water temperature
Real64 PParAir; // partial pressure of vapor of zone air
int ZoneNum; // index to zone array
Real64 LWtotal; // total flux from long-wavelength radiation to surface
Real64 LWsum; // summation of all long-wavelenth radiation going to surface
Real64 SWtotal; // total flux from short-wavelength radiation to surface


// FLOW:
// initialize local variables

// Standard Heat Balance Equation:
// TempSurfInTmp( SurfNum ) = ( CTFConstInPart( SurfNum ) + QRadThermInAbs( SurfNum ) + QRadSWInAbs( SurfNum ) + HConvIn( SurfNum ) * RefAirTemp( SurfNum ) + NetLWRadToSurf( SurfNum ) + Construct( ConstrNum ).CTFSourceIn( 0 ) * QsrcHist( SurfNum, 1 ) + QHTRadSysSurf( SurfNum ) + QHWBaseboardSurf( SurfNum ) + QSteamBaseboardSurf( SurfNum ) + QElecBaseboardSurf( SurfNum ) + IterDampConst * TempInsOld( SurfNum ) + Construct( ConstrNum ).CTFCross( 0 ) * TH11 ) / ( Construct( ConstrNum ).CTFInside( 0 ) + HConvIn( SurfNum ) + IterDampConst ); // Constant part of conduction eq (history terms) | LW radiation from internal sources | SW radiation from internal sources | Convection from surface to zone air | Net radiant exchange with other zone surfaces | Heat source/sink term for radiant systems | (if there is one present) | Radiant flux from high temp radiant heater | Radiant flux from a hot water baseboard heater | Radiant flux from a steam baseboard heater | Radiant flux from an electric baseboard heater | Iterative damping term (for stability) | Current conduction from | the outside surface | Coefficient for conduction (current time) | Convection and damping term

// Convection coefficient calculation
HConvIn = 0.22 * std::pow( abs( Pool( PoolNum ).PoolWaterTemp - RefAirTemp ), 1.0 / 3.0 ) * Pool( PoolNum ).CurCoverConvFac;

// Evaporation calculation:
// Evaporation Rate (lb/h) = 0.1 * Area (ft2) * Activity Factor * (Psat,pool - Ppar,air) (in Hg)
// So evaporation rate, area, and pressures have to be converted to standard E+ units (kg/s, m2, and Pa, respectively)
// Evaporation Rate per Area = Evaporation Rate * Heat of Vaporization / Area of Surface
PSatPool = PsyPsatFnTemp( Pool( PoolNum ).PoolWaterTemp, RoutineName );
ZoneNum = Surface( SurfNum ).Zone;
PParAir = PsyPsatFnTemp( MAT( ZoneNum ), RoutineName ) * PsyRhFnTdbWPb( MAT( ZoneNum ), ZoneAirHumRatAvg( ZoneNum ), OutBaroPress );
if ( PSatPool < PParAir ) PSatPool = PParAir;
EvapRate = ( 0.1 * ( Surface( SurfNum ).Area / CFA ) * Pool( PoolNum ).CurActivityFactor * ( ( PSatPool - PParAir ) * CFinHg ) ) * CFMF * Pool( PoolNum ).CurCoverEvapFac;
EvapEnergyLossPerArea = -EvapRate * PsyHfgAirFnWTdb( ZoneAirHumRatAvg( ZoneNum ), MAT( ZoneNum ) ) / Surface( SurfNum ).Area;

// LW and SW radiation term modification: any "excess" radiation blocked by the cover gets convected
// to the air directly and added to the zone air heat balance
LWsum = ( QRadThermInAbs( SurfNum ) + NetLWRadToSurf( SurfNum ) + QHTRadSysSurf( SurfNum ) + QHWBaseboardSurf( SurfNum ) + QSteamBaseboardSurf( SurfNum ) + QElecBaseboardSurf( SurfNum ) );
LWtotal = Pool( PoolNum ).CurCoverLWRadFac * LWsum;
SWtotal = Pool( PoolNum ).CurCoverSWRadFac * QRadSWInAbs( SurfNum );
Pool( PoolNum ).RadConvertToConvect = ( ( 1.0 - Pool( PoolNum ).CurCoverLWRadFac ) * LWsum ) + ( ( 1.0 - Pool( PoolNum ).CurCoverSWRadFac ) * QRadSWInAbs( SurfNum ) );


}

void
Expand Down Expand Up @@ -734,6 +797,8 @@ namespace SwimmingPool {
// SUBROUTINE LOCAL VARIABLE DECLARATIONS:

// FLOW:

// Don't forget to total up convective gains to various zones from pool cover!

}

Expand Down
Loading

6 comments on commit 63aaee4

@nrel-bot
Copy link

Choose a reason for hiding this comment

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

972110-SwimmingPool (RKStrand) - x86_64-Linux-Ubuntu-14.04-gcc-4.8: Tests Failed

Build Badge Test Badge

@nrel-bot
Copy link

Choose a reason for hiding this comment

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

972110-SwimmingPool (RKStrand) - x86_64-Linux-Ubuntu-14.04-cppcheck-1.61: OK (0 of 0 tests passed)

Build Badge

@nrel-bot
Copy link

Choose a reason for hiding this comment

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

972110-SwimmingPool (RKStrand) - x86_64-MacOS-10.9-clang: Tests Failed

Build Badge Test Badge

@nrel-bot
Copy link

Choose a reason for hiding this comment

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

972110-SwimmingPool (RKStrand) - x86_64-MacOS-10.9-clang-Debug: Tests Failed

Build Badge Test Badge

@nrel-bot
Copy link

Choose a reason for hiding this comment

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

972110-SwimmingPool (RKStrand) - i386-Windows-7-VisualStudio-12: Tests Failed

Build Badge Test Badge

@nrel-bot
Copy link

Choose a reason for hiding this comment

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

972110-SwimmingPool (RKStrand) - Win64-Windows-7-VisualStudio-12: Tests Failed

Build Badge Test Badge

Please sign in to comment.