[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 |
|
---|
| 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.;
|
---|
[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 | }
|
---|