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"
|
---|
7 | #include "../Exceptions/exceptions.h"
|
---|
8 | #include <cmath>
|
---|
9 |
|
---|
10 | IssmDouble 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.;
|
---|
34 |
|
---|
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);
|
---|
73 |
|
---|
74 | #if !defined(_HAVE_ADOLC_)
|
---|
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;
|
---|
77 | #else
|
---|
78 | _error_("Cannot differentiate erfc, talk to ADOLC folks (http://functions.wolfram.com/GammaBetaErf/Erfc/20/01/)");
|
---|
79 | #endif
|
---|
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
|
---|
93 |
|
---|
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 | }
|
---|
102 |
|
---|
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
|
---|
110 |
|
---|
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 | }
|
---|
128 |
|
---|
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 | }
|
---|