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
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
Returns sizing results as array
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
Returns the minimum primary volume and heating capacity sizing results
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
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
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.