Heat Pump Water Heater Sizer, Documentation

HPWHulator Copyright (C) 2020 Ecotope Inc.

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.

class HPWHsizer.HPWHsizer

The main class to organize a primary and temperature maintenance HPWH system and size it using the Ecotope Modified ASHRAE Method (EMASHRAE) and the “More Accurate Method” referred to in the 2015 ASHRAE HVAC Applications handbook pages 50.15 - 50.16. The EMASHRAE approach accounts for the water heating equipment being able to produce hot water as it is being used by building occupants, allowing the system to be sized smaller. Detailed documentation on the methodology can be found at https://ecosizer.ecotope.com/sizer/docs/

This tool provides the minimum heating capacity and storage volume to meet the load determined by user inputs. The coldest weather conditions should be used for sizing. With the results, users need to select HPWHs according to their heating capacity at the weather condition used for sizing. Note that many HPWHs have defrost cycles and therefore a derated output capacity when ambient temperatures are below 50°F. Users should also consider the HPWH refrigerant when considering the hot water storage temperature, not all HPWH’s can produce hot water > 150°F. Users should also pay attention to the advanced input for the storage aquastat fraction and make sure the input value properly reflects the location of the aquastat sensor port in the primary storage system.

Two schematics are provided in for sizing in the tool, a “parallel loop tank” and a “swing tank.”

A “Swing Tank” design is a proven technique to use the primary heat pumps to support the temperature maintenance load, while keeping the heat pump equipment isolated from the warm water returning from the recirculation loop. This design strategy is best suited for buildings with low temperature maintenance loop losses (< 60W/apt) and relies on increased storage volume (with tanks piped in series) to ensure storage stratification. Swing tank systems have an electric resistance element in the temperature maintenance tank as a back-up safety factor. Sizing a swing tank system also means increasing the heating capacity and storage volume of the primary system. The temperature maintenance storage volume for the swing tank can be small.

Single-pass heat pump water heaters are most efficient when heating cool city water to hot storage temperatures, whereas multi-pass equipment can still operate efficiently when incoming water temperatures are around 120°F. A parallel loop configuration is one strategy used to isolate the temperature maintenance task from the task of heating the primary storage. A “Parallel Loop Tank” is an electric resistance element or a multi-pass heat pump that is piped in parallel with the primary system, specifically to handle the temperature maintenance load.

The class uses the initialization functions, initializeFromFile(args), initPrimaryByUnits(args), and initPrimaryByPeople(args) to pass the variables to a HPWHsizerRead class. The HPWHsizerRead object proccesses the inputs by checking the variables and calculating extra variables. The loadshift array is defined and checked with the arguement setLoadShiftforPrimary(args).

The system is sized with the function build_size(), and further information is available by pulling the size following the ASHRAE “more accurate” method with getASHRAEResult(). Plots for the sizing curves can be pulled from the sized system with plotSizingCurve(). Additionally, a plot simulating the design day can be created with plotStorageLoadSim().

When initializing the system there are some presets users can use.

When initializing with initPrimaryByUnits(args) the ratio of people can be inputas a string not a list of 6 entries. The sting key access the presets, the keys include “CA” and “ASHSTD” for standard market rate buildings or “CTCAC” and “ASHLOW” for low income buildings.

The presets for gpdpp include ‘ashLow’ (20gpdpp), ‘ashMed’ (49 gpdpp), the recomended ‘ecoMark’ (25 gpdpp). When using the initPrimaryByUnits(args) function gpdpp_BR can also use the preset “CA” which calculates the gpdpp from hot water draws used in CBECC-Res, as well as the other options. However the ASHRAE and Ecotope numbers repeat for each unit size.

The load shape input loadShapeNorm has a preset recommended to be used, accessed by setting loadShapeNorm = “stream” in the initilization function, shown in the examples below. If a user knows their load shape they can also enter a load shape normalized by the total daily use, as a list of length 24, where each entry corresponds to the hour of the day.

Examples

Example 1: Find the recommended size for a parallel loop tank schematic.

First to initialize the system:

>>> from HPWHsizer import HPWHsizer
>>> hpwh = HPWHsizer()
>>> hpwh.initPrimaryByPeople(nPeople = 100,
                             nApt = 36,
                             gpdpp = 22.,
                             loadShapeNorm = "stream",
                             supplyT_F = 120,
                             incomingT_F = 50,
                             storageT_F = 150.,
                             compRuntime_hr = 16.,
                             percentUseable = .9,
                             aquaFract = 0.4,
                             schematic = "paralleltank")
>>> hpwh.initTempMaint(Wapt = 100,
                       setpointTM_F = 135,
                       TMonTemp_F = 125)

And then in order to find proper for the system in the order of primary storage volume, primary heating capacity, temperature maintenance storage volume, temperature maintenance heating capacity:

>>> hpwh.build_size()
[346.1021666666667, 114.86110625, 48.15823981105004, 32.244741899999994]

To get the primary sizing curve to find solutions for the primary system at higher heating capacities and lower storage:

>>> fig = hpwh.plotSizingCurve(return_as_div=False)
>>> fig.show()

And to see the how the system performs in a simple simulation:

>>> fig = hpwh.plotStorageLoadSim(return_as_div=False)
>>> fig.show()

Plotly figures can also be saved as html with write_html():

>>> fig.write_html("output.html")

Example 2: Use a custom ratio of bedrooms and gallons per day per person for each bedroom type.

Start by initilizing the system, here the example just uses a primary system. The example uses a 100 apartment unit building with 25 studios, 1, 2, and 3 Bedroom units. The ratio of people in each unit size is customly defined in rBR as 1, 1.5, 1.9, and 2.5 respectively. Other presets include “CA” and “ASHSTD” for standard market rate buildings or “CTCAC” and “ASHLOW” for low income buildings.

This example also uses differing peak gallons per day per person for each unit size. Here the numbers are 26, 22, 20, and 19 gallons per day for each unit size. The presets for gpdpp_BR include ‘ashLow’ (20gpdpp), ‘ashMed’ (49 gpdpp), ‘ecoMark’ (recommended, 25 gpdpp), or “CA” which calculates the gpdpp from hot water draws used in CBECC-Res.

>>> from HPWHsizer import HPWHsizer
>>> hpwh = HPWHsizer()
>>> hpwh.initPrimaryByUnits(nBR = [25, 25, 25, 25, 0, 0],
                            rBR = [1, 1.5, 1.9, 2.5, 0, 0],
                            gpdpp_BR = [26, 22, 20, 19, 0, 0],
                            loadShapeNorm = "stream",
                            supplyT_F = 125,
                            incomingT_F = 50,
                            storageT_F= 150.,
                            compRuntime_hr = 16.,
                            percentUseable = .8,
                            aquaFract = 0.4,
                            schematic = "primary")

Then construct the system by building the connections between the components and size it. To find proper sizing for the system in the order of primary storage volume, primary heating capacity:

>>> hpwh.build_size()
[724.0097811562501, 141.45536806640627]

To get the primary sizing curve to find solutions for the primary system at higher heating capacities and lower storage volumes and save it to an html:

>>> fig = hpwh.plotSizingCurve(return_as_div=False)
>>> fig.write_html("output.html")

Example 3: Use CA Title24 software Hot Water Draws.

If a user wants to align their sizing with the CA Title24 software use the initPrimaryByUnits() function follow:

>>> from HPWHsizer import HPWHsizer
>>> hpwh = HPWHsizer()
>>> hpwh.initPrimaryByUnits(nBR = [6,12,12,6,0,0],
                            rBR = "CA",
                            gpdpp_BR = "CA",
                            loadShapeNorm = "stream",
                            supplyT_F = 125,
                            incomingT_F = 50,
                            storageT_F= 150.,
                            compRuntime_hr = 16.,
                            percentUseable = .8,
                            aquaFract = 0.4,
                            schematic = "swingtank")

Which will use the California occupancy ratios and the California daily hot water draws. Then create the temperature maintenance load with:

>>> hpwh.initTempMaint( Wapt = 100, safetyTM = 1.75 )

Construct the system by building the connections between the components and size it. To find proper sizing for the system in the order of primary storage volume, primary heating capacity, temperature maintenance storage volume, temperature maintenance heating capacity:

>>> hpwh.build_size()
[275.08088575585305, 87.32317975282498, '80', 21.4964946]

To get the primary sizing curve to find solutions for the primary system at higher heating capacities and lower storage:

>>> fig = hpwh.plotSizingCurve(return_as_div=False)
>>> fig.show()

And to see the how the system performs in a simple simulation:

>>> fig = hpwh.plotStorageLoadSim(return_as_div=False)
>>> fig.show()

Example 4: Load shifting a swing tank system.

Start by initilizing a swing tank system as before:

>>> from HPWHsizer import HPWHsizer
>>> hpwh = HPWHsizer()
>>> hpwh.initPrimaryByPeople(nPeople = 100,
                            nApt = 36,
                            gpdpp = 22.,
                            loadShapeNorm = "stream",
                            supplyT_F = 120,
                            incomingT_F = 50,
                            storageT_F= 150.,
                            compRuntime_hr = 16.,
                            percentUseable = .8,
                            aquaFract = 0.4,
                            schematic = "swingtank")

And create the temperature maintenance load as before with:

>>> hpwh.initTempMaint( Wapt = 100 )

Then create the load shift array, where 0’s are off and 1’s represent run freely. The array must be of length 24 for each hour of the day. The example given is off between 5 and 9 PM. Then add it to the system:

>>> loadshift = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 0,0,0,0, 1,1,1]
>>> hpwh.setLoadShiftforPrimary(loadshift)
>>> hpwh.build_size()
[843.657112791371, 94.1487558229551, '80', 21.4964946]

And to see the how the system performs with loadshift in a simple simulation by saving the file to an html:

>>> fig = hpwh.plotStorageLoadSim(return_as_div=False)
>>> fig.write_html("output.html")

Of course load shifting can be set for primary no-recirculation system and parallel loop systems as well. Those systems must be initialized properly as shown in previous examples.

Attributes
validbuildboolean

Initialized as false, is true if the system is created susccesfully on a call to buildSystem()

systemSizedboolean

Initialized as false, is true if the system is successfully sized.

doLoadShiftboolean

Set to true if doing loadshift with a call to setLoadShiftforPrimary()

inputsHPWHsizerRead()

The input handler that checks for valid inputs

primarySystemPrimarySystem_SP

The primary component of the HPWH system of class PrimarySystem_SP

tempmaintSystemParallelLoopTank/SwingTank

The temperature maintenance component of the HPWH system of class ParallelLoopTank or SwingTank

ashraeSizeASHRAEsizer

The primary component of the HPWH system, which is sized using the ASHRAE method of class ASHRAEsizer

swingTankLoad_Wfloat

The fraction of the distrubution losses that the primary HPWH has to cover when using a swing tank schematic.

Methods

initializeFromFile(fileName)

Function to initialize a HPWHsystem from a file.

initPrimaryByUnits(nBR, rBR, gpdpp_BR, loadShapeNorm, supplyT_F,

incomingT_F, storageT_F, compRuntime_hr, percentUseable, aquaFract, schematic, defrostFactor=1, singlePass=True) Function to initialize the primary component of a HPWH system from the list of inputs using a list of the number of apartments and a ratio of people per apartment. This is what users should use to align with CA Title24, see example 2.

initPrimaryByPeople(nPeople, nApt, gpdpp, loadShapeNorm, supplyT_F,

incomingT_F, storageT_F, compRuntime_hr, percentUseable, aquaFract, schematic, defrostFactor = 1, singlePass=True) Function to initialize the primary component of a HPWH system from the list of inputs using the full number of people and apartments.

initTempMaint( Wapt, setpointTM_F = 135, TMonTemp_F = 0 )

Function to initialize the temperature maintenence component of a HPWH system from the list of inputs.

setLoadShiftforPrimary(ls_arr)

Adds a specified load shifting scenario to the HPWH system.

buildSystem()

Organizes the HPWH system inputs around the schematic to put together the primary and temperature maintenance system

sizeSystem()

Sizes the built HPWH system and returns the minimum sizing results, volume and capacity for the primary and temperature maintence systems

build_size()

Builds and sizes the system.

getASHRAEResult()

Returns just the minimum result for the primary component of the HPWH system from the sized system following the “more accurate” method from ASHRAE

plotSizingCurve( return_as_div = True)

Returns the primary sizing curve, storage volume vs. heating capacity

plotStorageLoadSim(return_as_div = True)

Runs and returns a plot for the primary system simulating storage volume with HPWH heating agains the design load shape

writeToFile(fileName)

Writes the results of sizing the primary and temperature maintenance systems to a file.

buildSystem()

Builds a single pass centralized HPWH plant. Organizes the inputs to the relevant classes and passes important constants between the classes.

Raises
Exception: If am invalid schematic string is passed here throws error
Exception: If trying to use multipass heat pumps for the primary system throws erros
Exception: If the system does not build correctly.
build_size()

One function to build and size the HPWH system after initalization, that returns minimum results

Returns
list

[PVol_G_atStorageT, PCap_kBTUhr, TMVol_G, TMCap_kBTUhr] - The sized volume and heating capacacity for the primary then temperature maintenance systems

getASHRAEResult()

Gets the results from the system using the “more accurate method” from ASHRAE after building the system.

Returns
list

[PVol_G_atStorageT, PCap_kBTUhr] - The sized volume and heating capacacity

initPrimaryByPeople(nPeople, nApt, gpdpp, loadShapeNorm, supplyT_F, incomingT_F, storageT_F, compRuntime_hr, percentUseable, aquaFract, schematic, defrostFactor=1, singlePass=True)

Initializes the primary system by the number of total units and number of total people

Attributes
nPeopleflaot

The estimated total number of people that will occupy the building

nAptflaot

The total number of apartment units in the project

gpdppflaot

The design gallons per day per person at 120°F, or can be given as a string key to lookup values from ASHRAE low or medium or Ecotope design value

loadShapeNormarray_like or str

A one dimensional array with length 24 that describes the hot water usage for each hour of the day as a fraction of the total daily load. If string will lookup the loadshape data

incomingT_Ffloat

Incoming city water temperature (design temperature in winter). [°F]

storageT_F: float

Storage temperature of the primary hot water storage tanks. [°F]

supplyT_Ffloat

Supply hot water temperature to occupants, typically 120°F. [°F]

percentUsablefloat

Percent of primary hot water storage that is usable due to sufficient thermal stratification.

compRuntime_hrfloat

Hour per day central heat pump equipment can run, duty cycle [hrs/day]

percentUseablefloat

Percent of primary hot water storage that is usable due to sufficient thermal stratification.

defrostFactorfloat

A factor that reduces heating capacity at low temperatures based on need for defrost cycles to remove ice from evaporator coils.

aquaFractfloat

The fraction of the total hieght of the primary hot water tanks at which the Aquastat is located.

schematicfloat

The schematic used, options are “primary”, “paralleltank”, or “swingtank”

defrostFactor: float

A factor that reduces heating capacity at low temperatures based on need for defrost cycles to remove ice from evaporator coils. Defaults to 1.

singlePassfloat

Whether sizing a single pass or multipass system. There is no support for multipass primary sytems right now. Defaults to True.

initPrimaryByUnits(nBR, rBR, gpdpp_BR, loadShapeNorm, supplyT_F, incomingT_F, storageT_F, compRuntime_hr, percentUseable, aquaFract, schematic, defrostFactor=1, singlePass=True)

Initializes the primary system by the number of units by number of bedrooms and number of people per unit. If aligning the sizing requriements with CA this is the method that should be used.

Attributes
nBRarray_like

A list of the number of units by size in the order 0 bedroom units, 1 bedroom units, 2 bedroom units, 3 bedroom units, 4 bedroom units, 5 bedroom units.

rBRarray_like

A list of the average number people in each unit by size in the order 0 bedroom units, 1 bedroom units, 2 bedroom units, 3 bedroom units, 4 bedroom units, 5 bedroom units.

gpdpp_BRarray_like

A list of the design gallons used per unit by each unit by size in the order 0 bedroom units, 1 bedroom units, 2 bedroom units, 3 bedroom units, 4 bedroom units, 5 bedroom units. .

loadShapeNormarray_like or str

A one dimensional array with length 24 that describes the hot water usage for each hour of the day as a fraction of the total daily load. If string will lookup the loadshape data

incomingT_Ffloat

Incoming city water temperature (design temperature in winter). [°F]

storageT_F: float

Storage temperature of the primary hot water storage tanks. [°F]

supplyT_Ffloat

Supply hot water temperature to occupants, typically 120°F. [°F]

percentUsablefloat

Percent of primary hot water storage that is usable due to sufficient thermal stratification.

compRuntime_hrfloat

Hour per day central heat pump equipment can run, duty cycle [hrs/day]

percentUseablefloat

Percent of primary hot water storage that is usable due to sufficient thermal stratification.

aquaFractfloat

The fraction of the total hieght of the primary hot water tanks at which the Aquastat is located.

schematicfloat

The schematic used, options are “primary”, “paralleltank”, or “swingtank”

defrostFactor: float

A factor that reduces heating capacity at low temperatures based on need for defrost cycles to remove ice from evaporator coils. Defaults to 1.

singlePassfloat

Whether sizing a single pass or multipass system. There is no support for multipass primary sytems right now. Defaults to True.

initTempMaint(Wapt, safetyTM=1.75, setpointTM_F=130, TMonTemp_F=120, offTime_hr=0.333)

Initializes the temperature maintanence system after the primary system was initialized with either “swingtank” or “paralleltank”.

Raises
Exception: Error if primary system hasn’t been created yet.
Attributes
Waptfloat

The recicuplation loop losses in terms of Watts per apartment.

safetyTMfloat

The saftey factor for the temperature maintenance system.

setpointTM_Ffloat

The setpoint of the temprature maintence tank. Defaults to 130 °F.

TMonTemp_Ffloat

The temperature where parallel loop tank will turn on. Defaults to 120 °F.

initializeFromFile(fileName)

Initilizes a system from a file

Attributes
fileNamestr

Name of file to open. File should have lines for each variable with format: <name of variable> <value> i.e. compRuntime_hr 16, or for list: nBR 10 10 10 0 0

plotParallelTankCurve(return_as_div=True)

Returns a plot of the sizing curve as a div or a plotly figure

Parameters
return_as_div

A logical on the output, as a div (true) or as a figure (false)

Returns
——-
div/fig

plot_div

plotSizingCurve(return_as_div=True)

Returns a plot of the sizing curve as a div or as a plotly fig

Parameters
return_as_div

A logical on the output, as a div (true) or as a figure (false)

Returns
——-
div/fig

plot_div

plotStorageLoadSim(return_as_div=True)

Returns a plot of the of the simulation for the minimum sized primary system as a div or plotly figure. Can plot the minute level simulation

Parameters
return_as_div

A logical on the output, as a div (true) or as a figure (false)

Returns
——-
div/fig

plot_div

runStorage_Load_Sim(Pcapacity=None, Pvolume=None)

Returns sizing storage depletion and load results for water volumes at the supply temperature

Parameters
Pcapacityfloat

The primary heating capacity in kBTUhr to use for the simulation, default is the sized system

Pvolumefloat

The primary storage volume in gallons to to use for the simulation, default is the sized system

Returns
list [ V, G_hw, D_hw, run ]
V - Volume of HW in the tank with time at the strorage temperature.
G_hw - The generation of HW with time at the supply temperature
D_hw - The hot water demand with time at the tsupply temperature
run - The actual output in gallons of the HPWH with time
setLoadShiftforPrimary(ls_arr, cdf_shift=1)

Sets the load shift to user defined list of 0s of false for force HPWH not to run, and 1s or true for run.

Attributes
ls_arrarray_like

Array of zeros and ones of length 24 for each hour of the day to define when HPWH’s are allowed to run during a day for load shift.

sizeSystem()

Sizes the system after building with buildSystem()

Returns
list

[PVol_G_atStorageT, PCap_kBTUhr, TMVol_G_atStorageT, TMCap_kBTUhr]

class HPWHsizer.HPWHsizerRead

Class for gathering hpwh sizing inputs and checking them. Will gather inputs by manual entry or from a file. A pulls data from string inputs.

Methods

calcedVariables()

Calculate other variables needed.

checkInputs(gpdpp, loadShapeNorm, supplyT_F, …)

Checks inputs are all valid

initTempMaintInputs(Wapt, safetyTM, …)

Assign temperature maintenance variables with either “swingtank” or “paralleltank”

initializeFromFile(fileName)

“Read in a formated file with filename

setLoadShift(ls_arr, cdf_shift)

Checks and initilize the load shift variable.

initPrimaryByPeople

initPrimaryByUnits

calcedVariables()

Calculate other variables needed.

checkInputs(gpdpp, loadShapeNorm, supplyT_F, incomingT_F, storageT_F, compRuntime_hr, percentUseable, aquaFract, schematic, defrostFactor, singlePass)

Checks inputs are all valid

initTempMaintInputs(Wapt, safetyTM, setpointTM_F, TMonTemp_F, offTime_hr)

Assign temperature maintenance variables with either “swingtank” or “paralleltank”

initializeFromFile(fileName)

“Read in a formated file with filename

setLoadShift(ls_arr, cdf_shift)

Checks and initilize the load shift variable.

Parameters

ls_arr (TYPE) – array of 0’s and 1’s or Boolean where 1 or True is .

Raises

Exception – Loadshift input array not on length 24.

Returns

None.

HPWHsizer.checkLiqudWater(var_F)

Checks if the variable has a temperuter with in the range of liquid water at atm pressure

Parameters

var_F (float) – Temperature of water.

Returns

True if liquid, False if solid or gas.

Return type

bool

HPWHsizer.loadgpdpp(gpdpp, nBR=None)

Loads data for the gpdpp inputs if it is of string type, but passes gpdpp thorugh if it’s not string and is just a number. Valid string keys are ‘ashLow’, ‘ashMed’, or ‘ecoMark’, and for the advanced processing of the California data use “CA”. If using the “CA” option the number of units by bedrooms (nBR) is needed. The CA data has assumtions about the ratio of people per unit size.

Raises
Exception :

If asking for the “CA” option and the number of units by bedroom size and number of people aren’t defined

Attributes
gpdppfloat/ string

The gallons per day per person value or a string key to lookup, valid keys are: ‘ashLow’, ‘ashMed’, or ‘ecoMark’, and “CA”

nBRlist

List of the number of units by bedroom size for 0 bedroom units (studios) to 5+ bedroom units, for example: [ 0, 12, 12, 12, 0, 0]

HPWHulator Copyright (C) 2020 Ecotope Inc.

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.

class Simulator.Simulator(G_hw, D_hw, V0, Vtrig, Tcw, Tstorage, Tsupply, schematic='primary', swing_V0=None, swing_Ttrig=None, Qrecirc_W=None, Swing_Elem_kW=None)

Simulator class runs a simplified simulation to check the primary and swing tank systems.

This class will run the primary simulation (schematic = “primary”) or primary with swing tank simulation (schematic = “swingtank”). Both are run on a minute timestep to approximate the available storage volume in the primary system and the average tank temperature in the swing tank, if applicable.

The primary system is run assuming the system is perfectly stratified and all of the hot water above the cold temperature line is at the storage temperature. Each time step some hot water is removed and some added according to the inputs.

The swing tank is run assuming that the swing tank is well mixed and can be tracked by the average tank temperature and that the system loses the recirculation loop losses as a constant Watts. Since the swing tank is in series with the primary system the temperature needs to be tracked to inform inputs for primary step, unlike the parallel loop tank which is separated from the primary system.

The swing tank is also assumed to have an 8 °F deadband from the swing heating trigger temperature.

Examples

An example usage to simulate a swing tank system:

First make sure the hot water draws are in gpm. For examples starting with gph for each hour of the day, a list can be converted to gpm for each minute oof the day following:

>>> import numpy as np
>>> from cfg import HRLIST_to_MINLIST
>>> D_hw_gph = [ 27, 12, 8, 8, 24, 40, 74, 87, 82, 67, 40, 34, 29, 27,
                29, 34, 40, 48, 51, 55, 59, 51, 38, 36]
>>> D_hw_gpm = np.array(HRLIST_to_MINLIST(D_hw_gph)) / 60

Then the simulator can be imported and initilized, with the desired inputs.

>>> from HPWHsizer import Simulator
>>> hpwhsim = Simulator(G_hw = [64]*24*60,
                        D_hw = D_hw_gpm,
                        V0 = 300,
                        Vtrig = 180,
                        Tcw = 50,
                        Tstorage = 150,
                        Tsupply = 120,
                        schematic = "swingtank",
                        swing_V0 = 80,
                        swing_Ttrig = 121,
                        Qrecirc_W = 2700,
                        Swing_Elem_kW = 5 )

And then in order to find proper for the system in the order of primary storage volume, primary heating capacity, temperature maintenance storage volume, temperature maintenance heating capacity:

>>> primaryVol, G_hw, D_hw, primaryGen, swingTemp, swingHeat, hw_outSwing = hpwhsim.simulate()
Attributes
G_hwlist

The primary hot water generation rate in gallons per minute .

D_hwlist

The hot water draw rate at the supply temperature.

V0float

The storage volume of the primary system at the storage temperature

Vtrigfloat

The remaining volume of the primary storage volume when heating is triggered, note this equals V0*(1 - aquaFract)

Tcwfloat

The cold makeup water temperature

Tstoragefloat

The hot water storage temperature

Tsupplyfloat

The hot water supply temperature to occupants.

schematicstring

The schematic string, either “primary”, “paralleltank”, or “swingtank”. Controls the model run. Defaults to “primary”.

swing_V0float

The storage volume of the swing tank. Is not need unless schematic is set to “swingtank”. Defaults to None.

swing_Ttrigfloat

The swing tank tempeature when the swing tank resistance elements turn on. Is not need unless schematic is set to “swingtank”. Defaults to None.

Qrecirc_Wfloat

The recirculation loop losses in Watts. Is not need unless schematic is set to “swingtank”. Defaults to None.

Swing_Elem_kWfloat

The swing tank resistance elements power output in kWatts. Is not need unless schematic is set to “swingtank”. Defaults to None.

Methods

runOnePrimaryStep(Vcurr, hw_out, hw_in)

Runs one step on the primary system.

runOneSwingStep(Tcurr, hw_out)

Runs one step on the swing tank step.

simJustSwing([initST])

simulate([initPV, initST])

runOnePrimaryStep(Vcurr, hw_out, hw_in)

Runs one step on the primary system. This changes the volume of the primary system by assuming there is hot water removed at a volume of hw_out and hot water generated or added at a volume of hw_in. This is assuming the system is perfectly stratified and all of the hot water above the cold temperature is at the storage temperature.

Parameters
Vcurrfloat

The primary volume at the timestep.

hw_outfloat

The volume of DHW removed from the primary system, assumed that 100% of what of what is removed is replaced

hw_infloat

The volume of hot water generated in a time step

Returns
Vnewfloat

The new primary volume at the timestep.

did_runfloat

The volume of hot water generated during the time step.

runOneSwingStep(Tcurr, hw_out)

Runs one step on the swing tank step. Since the swing tank is in series with the primary system the temperature needs to be tracked to inform inputs for primary step. The driving assumptions hereare that the swing tank is well mixed and can be tracked by the average tank temperature and that the system loses the recirculation loop losses as a constant Watts and thus the actual flow rate and return temperature from the loop are irrelevant.

Parameters
Tcurrfloat

The current temperature at the timestep.

hw_outfloat

The volume of DHW removed from the swing tank system.

hw_infloat

The volume of DHW added to the system.

Returns
Tnewfloat

The new swing tank tempeature the timestep assuming the tank is well mixed.

did_runint

Logic if heated during time step (1) or not (0)

simJustSwing(initST=None)
simulate(initPV=None, initST=None)

HPWHulator Copyright (C) 2020 Ecotope Inc.

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.

class HPWHComponents.ParallelLoopTank(nApt, Wapt, safetyTM, setpointTM_F, TMonTemp_F, offTime_hr)

Class containing attributes and methods to describe and size the parrallel loop tank arrangement. Unlike a swing tank, a parrallel loop tank will have equipment to provide heat for periods of low or no hot water use.

Attributes
nApt: integer

The number of apartments. Use with Qdot_apt to determine total recirculation losses.

Wapt: float

Watts of heat lost in through recirculation piping system. Used with N_apt to determine total recirculation losses.

offTime_hr: integer

Maximum hours per day the temperature maintenance equipment can run.

TMRuntime_hr: float

Run time required for temperature maintenance equipment to meet setpoint.

setpointTM_F: float

Temperature maintenance tank setpoint.

TMonTemp_F: float

Temperature at which temperature maintenance equipment will engauge.

TMCap_kBTUhr

Temperature maintenance equipment capacity.

TMVol_G_atStorageT

Volume of parrallel loop tank.

Methods

getSizingResults()

Returns sizing results as array

sizeVol_Cap()

Sizes the volume in gallons and heat capactiy in kBTU/h

tempMaintCurve([runtime])

Returns the sizing curve for a parallel loop tank

getSizingResults()

Returns sizing results as array

Returns
list

self.TMVol_G, self.TMCap_kBTUhr

sizeVol_Cap()

Sizes the volume in gallons and heat capactiy in kBTU/h

tempMaintCurve(runtime=0.3333333333333333)

Returns the sizing curve for a parallel loop tank

Returns
list

volN_G, capacity

class HPWHComponents.PrimarySystem_SP(totalHWLoad, loadShapeNorm, nPeople, incomingT_F, supplyT_F, storageT_F, percentUseable, compRuntime_hr, aquaFract, defrostFactor, swingTank=None)

Class containing attributes and methods to describe and size the primary heat pump and storage for single pass systems.

Attributes
totalHWLoadfloat

Total hot water load [btu/hr]

loadShapeNormnumpy array

A one dimensional array with length 24 that describes the hot water usage for each hour of the day as a fraction of the total daily load.

nPeople: integer

Number of residents.

incomingT_Ffloat

Incoming city water temperature (design temperature in winter). [°F]

storageT_F: float

Storage temperature of the primary hot water storage tanks. [°F]

supplyT_Ffloat

Supply hot water temperature to occupants, typically 120°F. [°F]

percentUsablefloat

Percent of primary hot water storage that is usable due to sufficient thermal stratification.

aquaFract: float

The fraction of the total hieght of the primary hot water tanks at which the Aquastat is located.

compRuntime_hrfloat

Hour per day central heat pump equipment can run, duty cycle [hrs/day]

defrostFactor: float

A factor that reduces heating capacity at low temperatures based on need for defrost cycles to remove ice from evaporator coils.

PCap_kBTUhrfloat

Primary heat pump water heater capacity [kBtu]

PVol_G_atStorageTfloat

Primary storage tank volume [gals]

aquaFractfloat

Fractional hieght of the aquastat in the tank.

SwingTankswingtank

The swing tank object associated with the primary system if there is one.

swingTankLoad_Wfloat

Extra load in Watts that is added to the primary system.

fractDHWfloat

Fraction describing the decreased total volume to be met for load shift based on the total number of days to meet.

LSconstrainedboolean

If the load shift requirement for the recommended system is larger than the system without load shift recommended.

Methods

getSizingResults()

Returns the minimum primary volume and heating capacity sizing results

primaryCurve()

Sizes the primary system curve.

primaryHeatHrs2kBTUHR(heathours[, …])

Converts from hours of heating in a day to heating capacity.

setLoadShift(schedule[, fractDHW])

Sets the load shifting schedule from input schedule

sizePrimaryTankVolume(heatHrs)

Calculates the primary storage using the Ecotope sizing methodology

sizeVol_Cap()

Calculates the minimum primary volume and heating capacity for the primary system: PVol_G_atStorageT and PCap_kBTUhr

getSizingResults()

Returns the minimum primary volume and heating capacity sizing results

Returns
list

self.PVol_G_atStorageT, self.PCap_kBTUhr

primaryCurve()

Sizes the primary system curve. Will catch the point at which the aquatstat fraction is too small for system and cuts the return arrays to match cutoff point.

Returns
volN

Array of volume in the tank at each hour.

array

Array of heating capacity in kBTU/hr

primaryHeatHrs2kBTUHR(heathours, effSwingVolFract=1)

Converts from hours of heating in a day to heating capacity.

Parameters
heathoursfloat or numpy.ndarray

The number of hours primary heating equipment can run.

effSwingVolFractfloat or numpy.ndarray

The fractional adjustment to the total hot water load for the primary system. Only used in a swing tank system.

Returns
heatCap

The heating capacity in [btu/hr].

setLoadShift(schedule, fractDHW=1)

Sets the load shifting schedule from input schedule

Parameters
schedulearray_like

List or array of 0’s and 1’s for don’t run and run.

fractDHWfloat

Fraction of DHW load corresponding to percent of days to be shifted in a load shift scenario

sizePrimaryTankVolume(heatHrs)

Calculates the primary storage using the Ecotope sizing methodology

Parameters
heatHrsfloat

The number of hours primary heating equipment can run in a day.

Returns
totalVolMaxfloat

The total storage volume in gallons adjusted to the storage tempreature

sizeVol_Cap()

Calculates the minimum primary volume and heating capacity for the primary system: PVol_G_atStorageT and PCap_kBTUhr

class HPWHComponents.SwingTank(nApt, Wapt, safetyTM)

Class containing attributes and methods to describe and size the swing tank. Unlike a temperature maintenance tank, the swing tank is sized so the primary system heat adds heat to cover about up to 70% of the reciculation losses.

Attributes
nAptinteger

The number of apartments. Use with Qdot_apt to determine total recirculation losses.

Waptfloat

Watts of heat lost in through recirculation piping system. Used with N_apt to determine total recirculation losses.

TMCap_kBTUhrfloat

The required capacity of temperature maintenance equipment.

TMVol_Gfloat

The volume of the swing tank required to ride out the low use period.

Methods

getSizingResults()

Returns sizing results as array

getSizingTable([CA])

Returns sizing table for a swing tank

sizeVol_Cap([CA])

Sizes the volume in gallons and heat capactiy in kBTU/hr

getSizingResults()

Returns sizing results as array

Returns
list

self.TMVol_G, self.TMCap_kBTUhr

getSizingTable(CA=True)

Returns sizing table for a swing tank

Returns
list

self.Table_Napts, self.Table

sizeVol_Cap(CA=False)

Sizes the volume in gallons and heat capactiy in kBTU/hr

Returns
TMVol_G

Calculated swing tank volume.

TMCap_kBTUhr

Calculated temperature maintenance equipment capacity.

HPWHComponents.getPeakIndices(diff1)

Finds the points of an array where the values go from positive to negative

Parameters
diff1array_like

A 1 dimensional array.

Returns
ndarray

Array of indices in which input array changes from positive to negative

Copyright (C) 2020 Ecotope Inc.

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.

class ashraesizer.ASHRAEsizer(nPeople, gpdpp, incomingT_F, supplyT_F, storageT_F, percentUseable, compRuntime_hr, defrostFactor=1)

Class containing attributes and methods to describe and size the primary system according the “More Accurate Method” referred to in the 2015 ASHRAE HVAC Applications handbook pages 50.15 - 50.16.

Examples

An example usage to find the recommended size following the ASHRAE method is:

>>> from ashraesizer import ASHRAEsizer
>>> a = ASHRAEsizer(100, 20, 50, 120, 150, 1, 0.8, 16)
>>> a.sizeVol_Cap()
[73.09343125000001, 25.060605000000002]
Attributes
ashraeMediumLUarray_like

The medium table derived from ASHRAE to deretrime hot water usage

ashraeLowLUarray_like

The low table derived from ASHRAE to deretrime hot water usage

nPeoplefloat

The number of people in estimated to live in the project.

gpdppfloat

The volume of water in gallons at 120F each person uses per dat.[°F]

incomingT_Ffloat

The incoming city water temperature on the design day. [°F]

supplyT_Ffloat

The hot water supply temperature to the occupants.[°F]

storageT_Ffloat

The hot water storage temperature. [°F]

percentUseablefloat

The fraction of the storage volume that can be filled with hot water.

compRuntime_hrfloat

The number of hours the compressor will run on the design day. [Hr]

defrostFactorfloat

A multipier used to account for defrost in the final heating capacity. Default equals 1.

peakFlowTablearray_like

A array to describe the peak hot water flow events from 5 minutes to 24 hours, found from interpolating/extrapolating between the ASHRAE Low and Medium tables

PCap_KBTUHRfloat

The primary heating capacity for the sized system using the ASHRAE “more accurate” method [kBTU/hr]

PVol_G_atStorageTfloat

The storage volume in gallons at the storage temperature for the sized system using the ASHRAE “more accurate” method [gallons]

primaryVolArr_atStorageTarray_like

An array of possible storage volumes found using the using the ASHRAE “more accurate” method corresponding to heating capacitys in accurateRecoveryTonsArr [gallons]

accurateRecoveryTonsArrarray_like

An array of possible heating capacitys found using the using the ASHRAE “more accurate” method corresponding to storage volumes in primaryVolArr_atStorageT [kBTU/hr]

Methods

sizePrimaryCurveAshrae(flowTable)

General function to size the water heating system based on a flow table, ASHRAE low, medium, or an interpolated table based on the input for gpdpp primaryCurve() Function to return the sized ASHRAE curve for the linear interpolated/extrapolated gallons per day per person from the ASHRAE Low and Medium Cruves getMediumCurve() Returns the ASHRAE medium sizing curve getLowCurve() Returns the ASHRAE low sizing curve tonsRecoveryForMaxDaily() Calculates the system heating capacity for a given compressor run time by interpolating from the ASHRAE curve sizeVol_Cap() Sizes the system following the ASHRAE “more accurate” methodolgy and returns the heating capacity and tons.

getLowCurve()

Get the sizing curve for the ASHRAE LOW table following the ASHRAE “more accurate” method

Returns
[vol_g, cap_kbtuhr]list

Sized volume in gallons at storage temperature and heating capactiy in kBTU/hr

getMediumCurve()

Get the sizing curve for the ASHRAE MEDIUM table following the ASHRAE “more accurate” method

Returns
[vol_g, cap_kbtuhr]list

Sized volume in gallons at storage temperature and heating capactiy in kBTU/hr

primaryCurve()

Function to return the sized ASHRAE curve for the linear interpolated/extrapolated gallons per day per person from the ASHRAE Low and Medium Cruves

Returns
[primaryVolArr_atStorageT, accurateRecoveryKBTUHr]list

The primary storage options in gallons at the storage temperature with the corresponding list of heating capacity options in kBTU/hr

sizePrimaryCurveAshrae(flowTable)

General function to size the water heating system based on a flow table, ASHRAE low, medium, or an interpolated table based on the input for gpdpp :param flowTable: A array of pairs describing volume flow at increasing lengths of time. :type flowTable: array_like

Returns
[primaryVol, accurateRecoveryTons]list

Returns a list of pairs for the sizing the primary HPWH following the ASHRAE “more accurate” method

sizeVol_Cap()

Function sizes the system following the ASHRAE “more accurate” methodolgy

Returns
[PCap_KBTUHR, PVol_G_atStorageT]list

The primary heating capacity on the design day in kBTU/hr and the primary volume in gallons at the storage temperature.

tonsRecoveryForMaxDaily()

Calculates the system heating capacity for a given compressor run time by interpolating from the ASHRAE curve

Returns
heatCapfloat

The heating capacity in tons.

Indices and tables