Skip to content

water_use

SECDAY = 86400.0 module-attribute

WaterUse

Source code in process/models/water_use.py
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
class WaterUse:
    def __init__(self):
        self.outfile = constants.NOUT

    def run(self, output: bool):
        """Routine to call the water usage calculation routines.
        This routine calls the different water usage routines.

        Parameters
        ----------
        output :
            indicate whether output should be written to the output file, or not
        """
        rejected_heat = heat_transport_variables.p_plant_primary_heat_mw * (
            1 - heat_transport_variables.eta_turbine
        )

        wastethermeng = rejected_heat * SECDAY

        if output:
            po.oheadr(
                self.outfile, "Water usage during plant operation (secondary cooling)"
            )
            po.ocmmnt(
                self.outfile,
                "Estimated amount of water used through different cooling system options:",
            )
            po.ocmmnt(self.outfile, "1. Cooling towers")
            po.ocmmnt(
                self.outfile,
                "2. Water bodies (pond, lake, river): recirculating or once-through",
            )

        # call subroutines for cooling mechanisms:

        # cooling towers
        self.cooling_towers(wastethermeng, output=output)

        # water-body cooling
        self.cooling_water_body(wastethermeng, output=output)

    def cooling_towers(self, wastetherm: float, output: bool):
        """Water used in cooling towers

        Parameters
        ----------
        wastetherm:
            thermal energy (MJ) to be cooled by this system
        output:

        """
        water_usage_variables.evapratio = 1.0e0 - (
            (
                -0.000279e0 * water_usage_variables.airtemp**3
                + 0.00109e0 * water_usage_variables.airtemp**2
                - 0.345e0 * water_usage_variables.airtemp
                + 26.7e0
            )
            / 100.0e0
        )
        # Diehl et al. USGS Report 2013-5188, http://dx.doi.org/10.3133/sir20135188

        water_usage_variables.volheat = (
            water_usage_variables.waterdens * water_usage_variables.latentheat
        )

        water_usage_variables.energypervol = (
            water_usage_variables.volheat / water_usage_variables.evapratio
        )

        water_usage_variables.volperenergy = (
            1.0e0 / water_usage_variables.energypervol * 1000000.0e0
        )

        water_usage_variables.evapvol = wastetherm * water_usage_variables.volperenergy

        # find water withdrawn from external source
        water_usage_variables.waterusetower = 1.4e0 * water_usage_variables.evapvol
        # Estimated as a ratio to evaporated water (averaged across observed dataset)
        #  as per Diehl et al. USGS Report 2014-5184, http://dx.doi.org/10.3133/sir20145184

        # end break

        #  Output section
        if output:
            po.ovarre(
                self.outfile,
                "Volume used in cooling tower (m3/day)",
                "(waterusetower)",
                water_usage_variables.waterusetower,
                "OP ",
            )

    def cooling_water_body(self, wastetherm: float, output: bool):
        """Water evaporated in cooling through water bodies
        Based on spreadsheet from Diehl et al. USGS Report 2013-5188, which includes
        cooling coefficients found through fits across a dataset containing a wide range of
        temperatures, windspeeds, and heat loading:
        http://pubs.usgs.gov/sir/2013/5188/appendix/sir2013-5188_appendix4_fews_version_3.104.xlsx


        Parameters
        ----------
        wastetherm:
            thermal energy (MJ) to be cooled by this system
        output:

        """
        evapsum = 0.0e0

        for icool in range(1, 4):
            if icool == 1:
                # small pond as a cooling body
                # heat loading, MW/acre, based on estimations from US power plants
                heatload = 0.35e0
                # coefficients as per Brady et al. 1969:
                # wind function coefficients
                a = 2.47e0
                b = 0e0
                c = 0.12e0
                # fitted coefficients of heat loading
                d = 3061.331e0
                e = -48.810e0
                f = -78.559e0
                g = -291.820e0
                h = 0.267e0
                i = -0.610e0
                j = 33.497e0

            elif icool == 2:
                # large lake or reservoir as a cooling body
                # heat loading, MW/acre, based on estimations from US power plants
                heatload = 0.10e0
                # coefficients as per Webster et al. 1995:
                # wind function coefficients
                a = 1.04e0
                b = 1.05e0
                c = 0.0e0
                # fitted coefficients of heat loading
                d = 3876.843e0
                e = -49.071e0
                f = -295.246e0
                g = -327.935e0
                h = 0.260e0
                i = 10.528e0
                j = 40.188e0

            elif icool == 3:
                # stream or river as a cooling body
                # heat loading, MW/acre, based on estimations from US power plants
                heatload = 0.20e0
                # coefficients as per Gulliver et al. 1986:
                # wind function coefficients
                a = 2.96e0
                b = 0.64e0
                c = 0.0e0
                # fitted coefficients of heat loading
                d = 2565.009e0
                e = -43.636e0
                f = -93.834e0
                g = -203.767e0
                h = 0.257e0
                i = 2.408e0
                j = 20.596e0

            # Unfortunately, the source spreadsheet was from the US, so the fits for
            #   water body heating due to heat loading and the cooling wind functions
            #   are in non-metric units, hence the conversions required here.
            # Limitations: maximum wind speed of ~5 m/s; initial water_usage_variables.watertemp < 25 degC

            # convert water_usage_variables.windspeed to mph
            water_usage_variables.windspeedmph = (
                water_usage_variables.windspeed * 2.237e0
            )

            # convert heat loading into cal/(cm2.sec)
            heatloadimp = heatload * 1000000.0e0 * 0.239e0 / 40469000.0e0

            # estimate how heat loading will raise temperature, for this water body
            heatratio = (
                d
                + (e * water_usage_variables.watertemp)
                + (f * water_usage_variables.windspeedmph)
                + (g * heatload)
                + (h * water_usage_variables.watertemp**2)
                + (i * water_usage_variables.windspeedmph**2)
                + (j * heatload**2)
            )

            # estimate resultant heated water temperature
            water_usage_variables.watertempheated = water_usage_variables.watertemp + (
                heatloadimp * heatratio
            )

            # find wind function, m/(day.kPa), applicable to this water body:
            windfunction = (
                a
                + (b * water_usage_variables.windspeed)
                + (c * water_usage_variables.windspeed**2)
            ) / 1000.0e0

            # difference in saturation vapour pressure (Clausius-Clapeyron approximation)
            satvapdelta = (
                0.611e0
                * np.exp(
                    (17.27e0 * water_usage_variables.watertempheated)
                    / (237.3e0 + water_usage_variables.watertempheated)
                )
            ) - (
                0.611e0
                * np.exp(
                    (17.27e0 * water_usage_variables.watertemp)
                    / (237.3e0 + water_usage_variables.watertemp)
                )
            )

            # find 'forced evaporation' driven by heat inserted into system
            deltae = (
                water_usage_variables.waterdens
                * water_usage_variables.latentheat
                * windfunction
                * satvapdelta
            )

            # convert heat loading to J/(m2.day)
            heatloadmet = heatload * 1000000.0e0 / 4046.85642e0 * SECDAY

            # find evaporation ratio: ratio of the heat used to evaporate water
            #   to the total heat discharged through the tower
            water_usage_variables.evapratio = deltae / heatloadmet
            # Diehl et al. USGS Report 2013-5188, http://dx.doi.org/10.3133/sir20135188

            water_usage_variables.volheat = (
                water_usage_variables.waterdens * water_usage_variables.latentheat
            )

            water_usage_variables.energypervol = (
                water_usage_variables.volheat / water_usage_variables.evapratio
            )

            water_usage_variables.volperenergy = (
                1.0e0 / water_usage_variables.energypervol * 1000000.0e0
            )

            water_usage_variables.evapvol = (
                wastetherm * water_usage_variables.volperenergy
            )

            # using this method the estimates for pond, lake and river evaporation produce similar results,
            #   the average will be taken and used in the next stage of calculation
            evapsum = evapsum + water_usage_variables.evapvol

        evapsum = evapsum / icool

        # water volume withdrawn from external source depends on recirculation or 'once-through' system choice
        #   Estimated as a ratio to evaporated water (averaged across observed dataset)
        #   as per Diehl et al. USGS Report 2014-5184, http://dx.doi.org/10.3133/sir20145184

        # recirculating water system:
        water_usage_variables.wateruserecirc = 1.0e0 * evapsum

        # once-through water system:
        water_usage_variables.wateruseonethru = 98.0e0 * evapsum

        # end break

        #  Output section
        if output:
            po.ovarre(
                self.outfile,
                "Volume used in recirculating water system (m3/day)",
                "(wateruserecirc)",
                water_usage_variables.wateruserecirc,
                "OP ",
            )
            po.ovarre(
                self.outfile,
                "Volume used in once-through water system (m3/day)",
                "(wateruseonethru)",
                water_usage_variables.wateruseonethru,
                "OP ",
            )

outfile = constants.NOUT instance-attribute

run(output)

Routine to call the water usage calculation routines. This routine calls the different water usage routines.

Parameters:

Name Type Description Default
output bool

indicate whether output should be written to the output file, or not

required
Source code in process/models/water_use.py
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
def run(self, output: bool):
    """Routine to call the water usage calculation routines.
    This routine calls the different water usage routines.

    Parameters
    ----------
    output :
        indicate whether output should be written to the output file, or not
    """
    rejected_heat = heat_transport_variables.p_plant_primary_heat_mw * (
        1 - heat_transport_variables.eta_turbine
    )

    wastethermeng = rejected_heat * SECDAY

    if output:
        po.oheadr(
            self.outfile, "Water usage during plant operation (secondary cooling)"
        )
        po.ocmmnt(
            self.outfile,
            "Estimated amount of water used through different cooling system options:",
        )
        po.ocmmnt(self.outfile, "1. Cooling towers")
        po.ocmmnt(
            self.outfile,
            "2. Water bodies (pond, lake, river): recirculating or once-through",
        )

    # call subroutines for cooling mechanisms:

    # cooling towers
    self.cooling_towers(wastethermeng, output=output)

    # water-body cooling
    self.cooling_water_body(wastethermeng, output=output)

cooling_towers(wastetherm, output)

Water used in cooling towers

Parameters:

Name Type Description Default
wastetherm float

thermal energy (MJ) to be cooled by this system

required
output bool
required
Source code in process/models/water_use.py
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
def cooling_towers(self, wastetherm: float, output: bool):
    """Water used in cooling towers

    Parameters
    ----------
    wastetherm:
        thermal energy (MJ) to be cooled by this system
    output:

    """
    water_usage_variables.evapratio = 1.0e0 - (
        (
            -0.000279e0 * water_usage_variables.airtemp**3
            + 0.00109e0 * water_usage_variables.airtemp**2
            - 0.345e0 * water_usage_variables.airtemp
            + 26.7e0
        )
        / 100.0e0
    )
    # Diehl et al. USGS Report 2013-5188, http://dx.doi.org/10.3133/sir20135188

    water_usage_variables.volheat = (
        water_usage_variables.waterdens * water_usage_variables.latentheat
    )

    water_usage_variables.energypervol = (
        water_usage_variables.volheat / water_usage_variables.evapratio
    )

    water_usage_variables.volperenergy = (
        1.0e0 / water_usage_variables.energypervol * 1000000.0e0
    )

    water_usage_variables.evapvol = wastetherm * water_usage_variables.volperenergy

    # find water withdrawn from external source
    water_usage_variables.waterusetower = 1.4e0 * water_usage_variables.evapvol
    # Estimated as a ratio to evaporated water (averaged across observed dataset)
    #  as per Diehl et al. USGS Report 2014-5184, http://dx.doi.org/10.3133/sir20145184

    # end break

    #  Output section
    if output:
        po.ovarre(
            self.outfile,
            "Volume used in cooling tower (m3/day)",
            "(waterusetower)",
            water_usage_variables.waterusetower,
            "OP ",
        )

cooling_water_body(wastetherm, output)

Water evaporated in cooling through water bodies Based on spreadsheet from Diehl et al. USGS Report 2013-5188, which includes cooling coefficients found through fits across a dataset containing a wide range of temperatures, windspeeds, and heat loading: http://pubs.usgs.gov/sir/2013/5188/appendix/sir2013-5188_appendix4_fews_version_3.104.xlsx

Parameters:

Name Type Description Default
wastetherm float

thermal energy (MJ) to be cooled by this system

required
output bool
required
Source code in process/models/water_use.py
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
def cooling_water_body(self, wastetherm: float, output: bool):
    """Water evaporated in cooling through water bodies
    Based on spreadsheet from Diehl et al. USGS Report 2013-5188, which includes
    cooling coefficients found through fits across a dataset containing a wide range of
    temperatures, windspeeds, and heat loading:
    http://pubs.usgs.gov/sir/2013/5188/appendix/sir2013-5188_appendix4_fews_version_3.104.xlsx


    Parameters
    ----------
    wastetherm:
        thermal energy (MJ) to be cooled by this system
    output:

    """
    evapsum = 0.0e0

    for icool in range(1, 4):
        if icool == 1:
            # small pond as a cooling body
            # heat loading, MW/acre, based on estimations from US power plants
            heatload = 0.35e0
            # coefficients as per Brady et al. 1969:
            # wind function coefficients
            a = 2.47e0
            b = 0e0
            c = 0.12e0
            # fitted coefficients of heat loading
            d = 3061.331e0
            e = -48.810e0
            f = -78.559e0
            g = -291.820e0
            h = 0.267e0
            i = -0.610e0
            j = 33.497e0

        elif icool == 2:
            # large lake or reservoir as a cooling body
            # heat loading, MW/acre, based on estimations from US power plants
            heatload = 0.10e0
            # coefficients as per Webster et al. 1995:
            # wind function coefficients
            a = 1.04e0
            b = 1.05e0
            c = 0.0e0
            # fitted coefficients of heat loading
            d = 3876.843e0
            e = -49.071e0
            f = -295.246e0
            g = -327.935e0
            h = 0.260e0
            i = 10.528e0
            j = 40.188e0

        elif icool == 3:
            # stream or river as a cooling body
            # heat loading, MW/acre, based on estimations from US power plants
            heatload = 0.20e0
            # coefficients as per Gulliver et al. 1986:
            # wind function coefficients
            a = 2.96e0
            b = 0.64e0
            c = 0.0e0
            # fitted coefficients of heat loading
            d = 2565.009e0
            e = -43.636e0
            f = -93.834e0
            g = -203.767e0
            h = 0.257e0
            i = 2.408e0
            j = 20.596e0

        # Unfortunately, the source spreadsheet was from the US, so the fits for
        #   water body heating due to heat loading and the cooling wind functions
        #   are in non-metric units, hence the conversions required here.
        # Limitations: maximum wind speed of ~5 m/s; initial water_usage_variables.watertemp < 25 degC

        # convert water_usage_variables.windspeed to mph
        water_usage_variables.windspeedmph = (
            water_usage_variables.windspeed * 2.237e0
        )

        # convert heat loading into cal/(cm2.sec)
        heatloadimp = heatload * 1000000.0e0 * 0.239e0 / 40469000.0e0

        # estimate how heat loading will raise temperature, for this water body
        heatratio = (
            d
            + (e * water_usage_variables.watertemp)
            + (f * water_usage_variables.windspeedmph)
            + (g * heatload)
            + (h * water_usage_variables.watertemp**2)
            + (i * water_usage_variables.windspeedmph**2)
            + (j * heatload**2)
        )

        # estimate resultant heated water temperature
        water_usage_variables.watertempheated = water_usage_variables.watertemp + (
            heatloadimp * heatratio
        )

        # find wind function, m/(day.kPa), applicable to this water body:
        windfunction = (
            a
            + (b * water_usage_variables.windspeed)
            + (c * water_usage_variables.windspeed**2)
        ) / 1000.0e0

        # difference in saturation vapour pressure (Clausius-Clapeyron approximation)
        satvapdelta = (
            0.611e0
            * np.exp(
                (17.27e0 * water_usage_variables.watertempheated)
                / (237.3e0 + water_usage_variables.watertempheated)
            )
        ) - (
            0.611e0
            * np.exp(
                (17.27e0 * water_usage_variables.watertemp)
                / (237.3e0 + water_usage_variables.watertemp)
            )
        )

        # find 'forced evaporation' driven by heat inserted into system
        deltae = (
            water_usage_variables.waterdens
            * water_usage_variables.latentheat
            * windfunction
            * satvapdelta
        )

        # convert heat loading to J/(m2.day)
        heatloadmet = heatload * 1000000.0e0 / 4046.85642e0 * SECDAY

        # find evaporation ratio: ratio of the heat used to evaporate water
        #   to the total heat discharged through the tower
        water_usage_variables.evapratio = deltae / heatloadmet
        # Diehl et al. USGS Report 2013-5188, http://dx.doi.org/10.3133/sir20135188

        water_usage_variables.volheat = (
            water_usage_variables.waterdens * water_usage_variables.latentheat
        )

        water_usage_variables.energypervol = (
            water_usage_variables.volheat / water_usage_variables.evapratio
        )

        water_usage_variables.volperenergy = (
            1.0e0 / water_usage_variables.energypervol * 1000000.0e0
        )

        water_usage_variables.evapvol = (
            wastetherm * water_usage_variables.volperenergy
        )

        # using this method the estimates for pond, lake and river evaporation produce similar results,
        #   the average will be taken and used in the next stage of calculation
        evapsum = evapsum + water_usage_variables.evapvol

    evapsum = evapsum / icool

    # water volume withdrawn from external source depends on recirculation or 'once-through' system choice
    #   Estimated as a ratio to evaporated water (averaged across observed dataset)
    #   as per Diehl et al. USGS Report 2014-5184, http://dx.doi.org/10.3133/sir20145184

    # recirculating water system:
    water_usage_variables.wateruserecirc = 1.0e0 * evapsum

    # once-through water system:
    water_usage_variables.wateruseonethru = 98.0e0 * evapsum

    # end break

    #  Output section
    if output:
        po.ovarre(
            self.outfile,
            "Volume used in recirculating water system (m3/day)",
            "(wateruserecirc)",
            water_usage_variables.wateruserecirc,
            "OP ",
        )
        po.ovarre(
            self.outfile,
            "Volume used in once-through water system (m3/day)",
            "(wateruseonethru)",
            water_usage_variables.wateruseonethru,
            "OP ",
        )