00001 /* ***************************************************** */ 00002 /* Compute Potential Evapotranspiration (ETP). */ 00003 /* calc_etp_mf.c */ 00004 /* ***************************************************** */ 00005 /* Author: Christian Page, CERFACS, Toulouse, France. */ 00006 /* ***************************************************** */ 00011 /* LICENSE BEGIN 00012 00013 Copyright Cerfacs (Christian Page) (2015) 00014 00015 christian.page@cerfacs.fr 00016 00017 This software is a computer program whose purpose is to downscale climate 00018 scenarios using a statistical methodology based on weather regimes. 00019 00020 This software is governed by the CeCILL license under French law and 00021 abiding by the rules of distribution of free software. You can use, 00022 modify and/ or redistribute the software under the terms of the CeCILL 00023 license as circulated by CEA, CNRS and INRIA at the following URL 00024 "http://www.cecill.info". 00025 00026 As a counterpart to the access to the source code and rights to copy, 00027 modify and redistribute granted by the license, users are provided only 00028 with a limited warranty and the software's author, the holder of the 00029 economic rights, and the successive licensors have only limited 00030 liability. 00031 00032 In this respect, the user's attention is drawn to the risks associated 00033 with loading, using, modifying and/or developing or reproducing the 00034 software by the user in light of its specific status of free software, 00035 that may mean that it is complicated to manipulate, and that also 00036 therefore means that it is reserved for developers and experienced 00037 professionals having in-depth computer knowledge. Users are therefore 00038 encouraged to load and test the software's suitability as regards their 00039 requirements in conditions enabling the security of their systems and/or 00040 data to be ensured and, more generally, to use and operate it in the 00041 same conditions as regards security. 00042 00043 The fact that you are presently reading this means that you have had 00044 knowledge of the CeCILL license and that you accept its terms. 00045 00046 LICENSE END */ 00047 00048 00049 00050 00051 00052 00053 00054 #include <utils.h> 00055 00057 void 00058 calc_etp_mf(double *etp, double *tas, double *hus, double *rsds, double *rlds, double *uvas, double *pmsl, double fillvalue, int ni, int nj) { 00059 00073 /* 00074 ; Calculate Evapotranspiration 00075 ;! 00076 ;! Calculate ETP: 00077 ;! 00078 ;! Convert original specific humidity (kg/kg) into relative humidity (%) 00079 ;! ISBA F90 method: 00080 ;! (ZPP (Pa), ZQSAT (kg/kg), ZTA_FRC(K)) 00081 ;! Method of Etchevers gene_forc_hydro.f 00082 ;! 00083 ;! Donnees d'entree journalieres en unites SI 00084 ;! 00085 ;! ETP = ETP1 + ETP2 00086 ;! ETP1 = desat * Rnet / (desat + gamma) / lambda 00087 ;! ETP2 = (gamma / (desat + gamma)) * 0.26 * (1 + 0.4*U(10m)) * (es - ea) / tau 00088 ;! 00089 ;! ETP en mm/s 00090 ;! Rn = rayonnement Net en W/m2 (albedo 0.2 et emissivite 0.95) 00091 ;! T = temperature a 2 m en K 00092 ;! U(10m) = vitesse du vent a 10 m en m/s 00093 ;! es = pression vapeur d'eau saturation en hPa 00094 ;! ea = pression vapeur d'eau a 2 m en hPa 00095 ;! gamma = constante psychrometrique = 65 Pa/k 00096 ;! lamba = chaleur latente de vaporisation de l'eau = 2.45E6 J/kg 00097 ;! tau = constante de temps = 86400 sec. 00098 ;! 00099 ;! EP1 >= 0 && EP2 >= 0 && EP <= 9 mm/jour 00100 ;! 00101 */ 00102 00103 int i; /* Loop counter */ 00104 00105 double albedo; 00106 double emissivity; 00107 double gamma; 00108 double stefan; 00109 double lvtt; 00110 double avogadro; 00111 double boltz; 00112 double md; 00113 double mv; 00114 double rd; 00115 double rv; 00116 00117 double pp; 00118 double factd; 00119 double factm; 00120 00121 double esat; 00122 double wmix; 00123 double epres; 00124 double desat; 00125 double rnet; 00126 00127 double etp1; 00128 double etp2; 00129 double ea; 00130 00131 /* Setup some constants */ 00132 albedo = 0.20; 00133 emissivity = 0.95; 00134 gamma = 65.0; /* Pa K^-1 */ 00135 /* tau = 86400.0; */ 00136 00137 stefan = 5.6697 * pow(10.0, -8.0); /* 5 670 400.E-8 in J K^-4 m^-2 s^-1 */ 00138 lvtt = 2.5008 * pow(10.0, 6.0); /* units are in J kg^-1 */ 00139 avogadro = 6.0221367 * pow(10.0, 23.0); /* units are in mol^-1 */ 00140 boltz = 1.380658 * pow(10.0, -23.0); /* units are in J K^-1 */ 00141 md = 28.9644 * pow(10.0,-3.0); /* Masse molaire d'air sec (Md = 28.96455E-3 kg mol-1 ) */ 00142 mv = 18.0153 * pow(10.0,-3.0); /* Masse molaire de la vapeur d'eau (Mv = 18.01528E-3 kg mol-1 ) */ 00143 rd = avogadro * boltz / md; /* Units J kg^-1 K^-1 */ 00144 rv = avogadro * boltz / mv; /* Units J kg^-1 K^-1 */ 00145 00146 /* if (keyword_set(hourly)) then begin 00147 factd = 24.0 00148 factm = 86400.0/factd 00149 endif else begin */ 00150 00151 factd = 86400.0; 00152 factm = 1.0; 00153 00154 for (i=0; i<(ni*nj); i++) { 00155 00156 if (tas[i] != fillvalue) { 00157 pp = pmsl[i] * 100.0; /* Pa */ 00158 00159 esat = 610.8 * exp( 17.27 * (tas[i] - K_TKELVIN) / (tas[i] - 35.86) ); /* Pa */ 00160 wmix = hus[i] / (1.0 - hus[i]); /* kg/kg */ 00161 epres = pp * wmix / ( (rd/rv) + wmix ); /* Pa */ 00162 desat = esat * 4098.0 / pow((tas[i] - 35.86), 2.0); /* desat/dT : Pa/K */ 00163 rnet = ((1.0 - albedo) * rsds[i]) + (emissivity * rlds[i]) - (emissivity * stefan * pow(tas[i],4.0)); /* W m^-2 */ 00164 00165 /* 00166 ; Pa K^-1 W m^-2 / J kg^-1 Pa K^-1 = W m^-2 J^-1 kg = J s^-1 m^-2 J^-1 kg = kg s^-1 m^-2 00167 ; kg s^-1 m^-2 = mm/s avec densite implicite de 1000 kg m^-3 qui fait la conversion m en mm 00168 */ 00169 etp1 = (desat * rnet) / (lvtt * (desat + gamma)) * factm; 00170 00171 if (etp1 < 0.0) etp1 = 0.0; 00172 00173 /* 00174 ; We divide by 100.0 because ew must be in hPa for ea to be in mm/day 00175 ; Units kg m^-2 s^-1 = mm/s avec densite implicite de 1000 kg m^-3 qui fait la conversion m en mm 00176 ; si unites SI sont utilisees. Dans ce cas, esat est en Pa, pas en kPa 00177 */ 00178 ea = 0.26 * (1.0 + 0.4 * uvas[i]) * (esat - epres) / 100.0; 00179 00180 etp2 = (gamma * ea) / (desat + gamma) / factd; 00181 if (etp2 < 0.0) etp2 = 0.0; 00182 00183 /* etp in mm/s */ 00184 etp[i] = etp1 + etp2; 00185 if (etp[i] > 9.0) etp[i] = 9.0; 00186 } 00187 else { 00188 etp[i] = fillvalue; 00189 } 00190 } 00191 }