forked from jhamman/DHSVM
-
Notifications
You must be signed in to change notification settings - Fork 0
/
EvapoTranspiration.c
executable file
·201 lines (169 loc) · 7.12 KB
/
EvapoTranspiration.c
1
2
3
4
5
6
7
8
9
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
/*
* SUMMARY: EvapoTranspiration.c - Calculate evapotranspiration
* USAGE: Part of DHSVM
*
* AUTHOR: Bart Nijssen
* ORG: University of Washington, Department of Civil Engineering
* E-MAIL: [email protected]
* ORIG-DATE: Apr-96
* DESCRIPTION: Calculate evapotranspiration
* DESCRIP-END.
* FUNCTIONS: EvapoTranspiration()
* COMMENTS:
* $Id: EvapoTranspiration.c,v 1.5 2007/03/02 22:02:01 lancuo Exp $
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include "settings.h"
#include "data.h"
#include "DHSVMerror.h"
#include "massenergy.h"
#include "constants.h"
#include "functions.h"
/*****************************************************************************
EvapoTranspiration()
*****************************************************************************/
void EvapoTranspiration(int Layer, int Dt, PIXMET * Met, float NetRad,
float Rp, VEGTABLE * VType, SOILTABLE * SType,
float MoistureFlux, SOILPIX * LocalSoil, float *Int,
EVAPPIX * LocalEvap, float *Adjust, float Ra)
{
float *Rc; /* canopy resistance associated with
conditions in each soil layer (s/m) */
float DryArea; /* relative dry leaf area */
float DryEvapTime; /* amount of time remaining during a timestep
after the interception storage is depleted
(sec) */
float F; /* Fractional coverage by vegetation layer */
float SoilMoisture; /* Amount of water in each soil layer (m) */
float WetArea; /* relative leaf area wetted by interception
storage */
float WetEvapRate; /* evaporation rate from wetted fraction per
unit ground area (m/s) */
float WetEvapTime; /* amount of time needed to evaporate the
amount of water in interception storage
(sec) */
int i; /* counter */
/* Convert the water amounts related to partial canopy cover to a pixel depth
as if the entire pixel is covered. These depths will be converted
back later on. */
F = VType->Fract[Layer];
*Int /= F;
NetRad /= F;
MoistureFlux /= F;
VType->MaxInt[Layer] /= F;
/* allocate memory for the canopy resistance array */
if (!(Rc = (float *) calloc(VType->NSoilLayers, sizeof(float))))
ReportError("EvapoTranspiration()", 1);
/* Calculate the evaporation rate in m/s */
LocalEvap->EPot[Layer] = (Met->Slope * NetRad +
Met->AirDens * CP * Met->Vpd / Ra) /
(WATER_DENSITY * Met->Lv * (Met->Slope + Met->Gamma));
/* The potential evaporation rate accounts for the amount of moisture that
the atmosphere can absorb. If we do not account for the amount of
evaporation from overlying evaporation, we can end up with the situation
that all vegetation layers and the soil layer transpire/evaporate at the
potential rate, resulting in an overprediction of the actual evaporation
rate. Thus we subtract the amount of evaporation that has already
been calculated for overlying layers from the potential evaporation.
Another mechanism that could be used to account for this would be to
decrease the vapor pressure deficit while going down through the canopy
(not implemented here) */
LocalEvap->EPot[Layer] -= MoistureFlux / Dt;
if (LocalEvap->EPot[Layer] < 0)
LocalEvap->EPot[Layer] = 0;
/* WetArea = pow(*Int/VType->MaxInt[Layer], (double) 2.0/3.0); */
WetArea = cbrt(*Int / VType->MaxInt[Layer]);
WetArea = WetArea * WetArea;
DryArea = 1 - WetArea;
/* calculate the amount of water that can evaporate from the interception
storage. Given this evaporation rate, calculate the amount of time it
will take to evaporate the entire amount of intercepted water. If this
time period is shorter than the length of the time interval, the
previously wetted leaves can transpire during the remaining part of the
time interval */
/* WORK IN PROGRESS: the amount of interception storage can be replenished
during (low intensity) rainstorms */
WetEvapRate = WetArea * LocalEvap->EPot[Layer];
if (WetEvapRate > 0) {
WetEvapTime = *Int / WetEvapRate;
if (WetEvapTime > Dt) {
WetEvapTime = Dt;
}
}
else if (*Int > 0)
WetEvapTime = Dt;
else
WetEvapTime = 0;
if (WetEvapRate > 0) {
if (WetEvapTime < Dt) {
LocalEvap->EInt[Layer] = *Int;
*Int = 0.0;
DryEvapTime = Dt - WetEvapTime;
}
else {
LocalEvap->EInt[Layer] = Dt * WetEvapRate;
*Int -= LocalEvap->EInt[Layer];
DryEvapTime = 0.0;
}
}
else {
LocalEvap->EInt[Layer] = 0.0;
if (*Int > 0)
DryEvapTime = 0.0;
else
DryEvapTime = Dt;
}
/* Correct the evaporation from interception and the interception storage for
the fractional overstory coverage */
LocalEvap->EInt[Layer] *= F;
LocalEvap->ETot += LocalEvap->EInt[Layer];
*Int *= F;
VType->MaxInt[Layer] *= F;
/* calculate the canopy conductances associated with the conditions in
each of the soil layers */
for (i = 0; i < VType->NSoilLayers; i++)
Rc[i] = CanopyResistance(VType->LAI[Layer], VType->RsMin[Layer],
VType->RsMax[Layer], VType->Rpc[Layer],
VType->VpdThres[Layer], VType->MoistThres[Layer],
SType->WP[i], LocalSoil->Temp[i],
LocalSoil->Moist[i], Met->Vpd, Rp);
/* calculate the transpiration rate for the current vegetation layer,
and adjust the soil moisture content in each of the soil layers */
for (i = 0; i < VType->NSoilLayers; i++) {
LocalEvap->ESoil[Layer][i] = (Met->Slope + Met->Gamma) /
(Met->Slope +
Met->Gamma * (1 +
Rc[i] / Ra)) * VType->RootFract[Layer][i] *
LocalEvap->EPot[Layer] * Adjust[i];
/* calculate the amounts of water transpirated during each timestep based
on the evaporation and transpiration rates. While there is still water
in interception storage only the area that is not covered by intercep-
ted water will transpire. When all of the interception storage has
disappeared all leaves will contribute to the transpiration */
LocalEvap->ESoil[Layer][i] *= WetEvapTime * (1 - WetArea) + DryEvapTime;
SoilMoisture = LocalSoil->Moist[i] * VType->RootDepth[i] * Adjust[i];
if (SoilMoisture < LocalEvap->ESoil[Layer][i])
LocalEvap->ESoil[Layer][i] = SoilMoisture;
/* correct the evaporation for the fractional overstory coverage and update
the soil moisture */
LocalEvap->ESoil[Layer][i] *= F;
SoilMoisture -= LocalEvap->ESoil[Layer][i];
LocalSoil->Moist[i] = SoilMoisture / (VType->RootDepth[i] * Adjust[i]);
}
for (i = 0, LocalEvap->EAct[Layer] = 0; i < VType->NSoilLayers; i++) {
LocalEvap->ETot += LocalEvap->ESoil[Layer][i];
LocalEvap->EAct[Layer] += LocalEvap->ESoil[Layer][i];
}
/* clean up */
free(Rc);
}
/*------------Define Function cbrt: cubic root--------------*/
/* double cbrt(double x) */
/* { */
/* if (fabs(x) < DBL_EPSILON) return 0.0; */
/* if (x > 0.0) return pow(x, 1.0/3.0); */
/* return -pow(-x, 1.0/3.0); */
/* } */