source: issm/trunk/src/c/shared/Elements/PddSurfaceMassBalanceSicopolis.cpp@ 26744

Last change on this file since 26744 was 26744, checked in by Mathieu Morlighem, 3 years ago

merged trunk-jpl and trunk for revision 26742

File size: 4.9 KB
RevLine 
[23317]1/* file: PddSurfaceMassBlanceSicopolis.cpp
2 Calculating the surface mass balance using the adapted PDD routine from SICOPOLIS.
3 */
4
5#include "./elements.h"
6#include "../Numerics/numerics.h"
[23322]7#include "../Exceptions/exceptions.h"
[24313]8#include <cmath>
[23317]9
10IssmDouble PddSurfaceMassBalanceSicopolis(IssmDouble* monthlytemperatures, IssmDouble* monthlyprec,
11 IssmDouble* melt, IssmDouble* accu, IssmDouble* melt_star, IssmDouble* t_ampl, IssmDouble* p_ampl,
12 IssmDouble yts, IssmDouble s, IssmDouble desfac,
13 IssmDouble s0t, IssmDouble s0p, IssmDouble rlaps,
14 IssmDouble rho_water,IssmDouble rho_ice){
15
16 int imonth; // month counter
17 IssmDouble B; // output: surface mass balance (m/a IE), melt+accumulation
18 IssmDouble frac_solid, snowfall, rainfall, runoff;
19 IssmDouble saccu; // yearly surface accumulation (m/a IE)
20 IssmDouble smelt; // yearly melt (m/a IE)
21 IssmDouble smelt_star; // yearly ...
22 IssmDouble precip; // total precipitation during 1 year
23 IssmDouble sconv; //rhow_rain/rhoi / 12 months
24 IssmDouble st; // elevation between altitude of the temp record and current altitude
25 IssmDouble sp; // elevation between altitude of the prec record and current altitude
26 IssmDouble q; // q is desert/elev. fact
27 IssmDouble pdd; // pdd factor (a * degC)
28 IssmDouble tstar; // monthly temp. after lapse rate correction (degC)
29 IssmDouble precip_star; // monthly precip after correction (m/a IE)
30 IssmDouble beta1 = 2.73; // 3 mm IE/(d*deg C), ablation factor for snow per positive degree day.
31 IssmDouble beta2 = 7.28; // 8 mm IE/(d*deg C), ablation factor for ice per pdd (Braithwaite 1995 from tarasov 2002).
32 IssmDouble Pmax = 0.6;
33 IssmDouble inv_twelve=1./12.;
[26744]34
[23317]35 sconv=(rho_water/rho_ice); //rhow_rain/rhoi
36
37 /* FIXME betas shoud be user input */
38 beta1=beta1*(0.001*365)*sconv; // (mm WE)/(d*deg C) --> (m IE)/(a*deg C)
39 beta2=beta2*(0.001*365)*sconv; // (mm WE)/(d*deg C) --> (m IE)/(a*deg C)
40
41 /* initalize fields */
42 precip=0.0;
43 tstar=0.0;
44 snowfall=0.0;
45 pdd=0.0;
46 /* seasonal loop */
47 for(imonth=0;imonth<12;imonth++){
48
49 /********* Surface temperature correction *******/
50 st=(s-s0t)/1000.;
51
52 // FIXME rlaps ??
53 rlaps=-6.309e-03+(-5.426e-03-(-6.309e-03))*sin((imonth+1-4)*PI/6.0)*1000.0;
54 monthlytemperatures[imonth]=monthlytemperatures[imonth]-rlaps*st;//*max(st,1e-3);
55 tstar=monthlytemperatures[imonth]+t_ampl[0];
56
57 /********* Precipitation correction *************/
58 /* Ref: Vizcaino et al 2010; DOI 10.1007/s00382-009-0591-y */
59 if(s0p<2000.0)
60 q=exp(desfac*(max(s,2000.0)-2000.0));
61 else
62 q=exp(desfac*(max(s,2000.0)-s0p));
63
64 precip_star=q*monthlyprec[imonth]*sconv*p_ampl[0]*yts; // convert precip from m/s -> m/a
65 precip=precip+precip_star*inv_twelve;
66
67 /********* compute PDD **************************/
68 /* Ref: Calov & Greve 2005 Journal of Glaciology, Vol. 51, No. 172, 2005, Correspondence */
69 IssmDouble s_stat=5.0;
70 IssmDouble inv_sqrt2pi =1.0/sqrt(2.0*PI);
71 IssmDouble inv_s_stat =1.0/s_stat;
72 IssmDouble inv_sqrt2 =1.0/sqrt(2.0);
[23321]73
[23323]74 #if !defined(_HAVE_ADOLC_)
[23317]75 pdd=pdd+(s_stat*inv_sqrt2pi*exp(-0.5*pow(tstar*inv_s_stat,2))
76 +0.5*tstar*erfc(-tstar*inv_s_stat*inv_sqrt2))*inv_twelve;
[23321]77 #else
78 _error_("Cannot differentiate erfc, talk to ADOLC folks (http://functions.wolfram.com/GammaBetaErf/Erfc/20/01/)");
79 #endif
[23317]80
81 /*Partition of precip in solid and liquid parts, Bales et al. (2009) */
82 IssmDouble temp_rain=7.2; // Threshold monthly mean temperature for
83 // precipitation = 101% rain, in deg C
84 IssmDouble temp_snow=-11.6; // Threshold monthly mean temperature for
85 // precipitation = 100% snow, in deg C
86
87 IssmDouble coeff1=5.4714e-01; // Coefficients
88 IssmDouble coeff2=-9.1603e-02; // of
89 IssmDouble coeff3=-3.314e-03; // the
90 IssmDouble coeff4= 4.66e-04; // fifth-order
91 IssmDouble coeff5=3.8e-05; // polynomial
92 IssmDouble coeff6=6.0e-07; // fit
[26744]93
[23317]94 if(tstar>=temp_rain)
95 frac_solid = 0.0;
96 else if(tstar<=temp_snow)
97 frac_solid = 1.0;
98 else{
99 frac_solid=coeff1+tstar*(coeff2
100 +tstar*(coeff3+tstar*(coeff4+tstar*(coeff5+tstar*coeff6))));
101 }
[26744]102
[23317]103 snowfall=snowfall+precip_star*frac_solid*inv_twelve;
104 }
105 /* end of seasonal loop */
106
107 rainfall=precip-snowfall;
108 if(snowfall<0.0) snowfall=0.0; // correction of
109 if(rainfall<0.0) rainfall=0.0; // negative values
[26744]110
[23317]111 if(rainfall<=(Pmax*snowfall)){
112 if((rainfall+beta1*pdd)<=(Pmax*snowfall)) {
113 smelt_star = rainfall+beta1*pdd;
114 smelt = 0.0;
115 runoff = smelt;
116 }
117 else{
118 smelt_star = Pmax*snowfall;
119 smelt = beta2*(pdd-(smelt_star-rainfall)/beta1);
120 runoff = smelt;
121 }
122 }
123 else{
124 smelt_star = Pmax*snowfall;
125 smelt = beta2*pdd;
126 runoff = smelt+rainfall-Pmax*snowfall;
127 }
[26744]128
[23317]129 saccu = precip;
130
131 /* asign output*/
132 melt[0]=runoff/yts;
133 accu[0]=saccu/yts;
134 melt_star[0]=smelt_star/yts;
135 B=(saccu-runoff)/yts;
136
137 return B;
138}
Note: See TracBrowser for help on using the repository browser.