Changeset 22249


Ignore:
Timestamp:
11/09/17 16:58:40 (7 years ago)
Author:
schlegel
Message:

CHG: update Gemb code to use tolerances on all absolute comparisons, make stricter archive tolerances, Smb output is now in m/yr ice so that it can be run with issm mass transport on

Location:
issm/trunk-jpl
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk-jpl/src/c/classes/Elements/Element.cpp

    r22239 r22249  
    25212521
    25222522        /*Intermediary variables: {{{*/
    2523         IssmDouble isinitialized;
    2524         IssmDouble zTop,dzTop,zMax,zMin,zY,dzMin;
    2525         IssmDouble Tmean;
    2526         IssmDouble C;
    2527         IssmDouble Tz,Vz;
     2523        IssmDouble isinitialized=0.0;
     2524        IssmDouble zTop=0.0;
     2525        IssmDouble dzTop=0.0;
     2526        IssmDouble zMax=0.0;
     2527        IssmDouble zMin=0.0;
     2528        IssmDouble zY=0.0;
     2529        IssmDouble dzMin=0.0;
     2530        IssmDouble Tmean=0.0;
     2531        IssmDouble C=0.0;
     2532        IssmDouble Tz,Vz=0.0;
    25282533        IssmDouble rho_ice, rho_water,aSnow,aIce;
    25292534        IssmDouble time,dt;
    25302535        IssmDouble t,smb_dt;
    25312536        IssmDouble yts;
    2532         IssmDouble Ta,V,dlw,dsw,P,eAir,pAir;
     2537        IssmDouble Ta=0.0;
     2538        IssmDouble V=0.0;
     2539        IssmDouble dlw=0.0;
     2540        IssmDouble dsw=0.0;
     2541        IssmDouble P=0.0;
     2542        IssmDouble eAir=0.0;
     2543        IssmDouble pAir=0.0;
    25332544        int        aIdx=0;
    25342545        int        denIdx=0;
    25352546        int        swIdx=0;
    25362547        IssmDouble cldFrac,t0wet, t0dry, K;
    2537         IssmDouble ulw;
    2538         IssmDouble netSW;
    2539         IssmDouble netLW;
    2540         IssmDouble lhf, shf, dayEC;
    2541         IssmDouble initMass;
    2542         IssmDouble sumR, sumM, sumEC, sumP, sumW,sumMassAdd;
    2543         IssmDouble sumdz_add;
    2544         IssmDouble sumMass,dMass;
     2548        IssmDouble ulw=0.0;
     2549        IssmDouble netSW=0.0;
     2550        IssmDouble netLW=0.0;
     2551        IssmDouble lhf=0.0;
     2552        IssmDouble shf=0.0;
     2553        IssmDouble dayEC=0.0;
     2554        IssmDouble initMass=0.0;
     2555        IssmDouble sumR=0.0;
     2556        IssmDouble sumM=0.0;
     2557        IssmDouble sumEC=0.0;
     2558        IssmDouble sumP=0.0;
     2559        IssmDouble sumW=0.0;
     2560        IssmDouble sumMassAdd=0.0;
     2561        IssmDouble sumdz_add=0.0;
     2562        IssmDouble sumMass=0.0;
     2563        IssmDouble dMass=0.0;
    25452564        bool isgraingrowth,isalbedo,isshortwave,isthermal,isaccumulation,ismelt,isdensification,isturbulentflux;
    2546         IssmDouble init_scaling;
     2565        IssmDouble init_scaling=0.0;
    25472566
    25482567        /*}}}*/
     
    25532572        IssmDouble* gdn = NULL;
    25542573        IssmDouble* gsp = NULL;
    2555         IssmDouble  EC = 0;
     2574        IssmDouble  EC = 0.0;
    25562575        IssmDouble* W = NULL;
    25572576        IssmDouble* a = NULL;
    25582577        IssmDouble* swf=NULL;
    25592578        IssmDouble* T = NULL;
    2560         IssmDouble  T_bottom;
    2561         IssmDouble  M;
    2562         IssmDouble  R;
    2563         IssmDouble  mAdd;
    2564         IssmDouble  dz_add;
    2565    
     2579        IssmDouble  T_bottom = 0.0;
     2580        IssmDouble  M = 0.0;
     2581        IssmDouble  R = 0.0;
     2582        IssmDouble  mAdd = 0.0;
     2583        IssmDouble  dz_add = 0.0;
     2584
    25662585        IssmDouble* dzini=NULL;
    25672586        IssmDouble* dini = NULL;
     
    25722591        IssmDouble* aini = NULL;
    25732592        IssmDouble* Tini = NULL;
    2574    
    2575         int         m;
     2593
     2594        int         m=0;
    25762595        int         count=0;
    25772596        /*}}}*/
     
    26062625        parameters->FindParam(&isturbulentflux,SmbIsturbulentfluxEnum);
    26072626        parameters->FindParam(&init_scaling,SmbInitDensityScalingEnum);
    2608    
     2627
    26092628        /*}}}*/
    26102629        /*Retrieve inputs: {{{*/
     
    26452664        /*First, check that the initial structures have been setup in GEMB. If not, initialize profile variables: layer thickness dz, * density d, temperature T, etc. {{{*/
    26462665        if(isinitialized==0.0){
    2647         if(VerboseSmb() && this->Sid()==0)_printf0_("smb core: Initializing grid\n");
    2648         //if(this->Sid()==1) for(int i=0;i<m;i++)_printf_("z[" << i << "]=" <<
    2649         //dz[i] << "\n");
    2650        
    2651         DoubleArrayInput* dz_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbDziniEnum)); _assert_(dz_input);
    2652         DoubleArrayInput* d_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbDiniEnum));_assert_(d_input);
    2653         DoubleArrayInput* re_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbReiniEnum));_assert_(re_input);
    2654         DoubleArrayInput* gdn_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbGdniniEnum));_assert_(gdn_input);
    2655         DoubleArrayInput* gsp_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbGspiniEnum));_assert_(gsp_input);
    2656         DoubleInput* EC_input= dynamic_cast<DoubleInput*>(this->GetInput(SmbECiniEnum));_assert_(EC_input);
    2657         DoubleArrayInput* W_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbWiniEnum));_assert_(W_input);
    2658         DoubleArrayInput* a_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbAiniEnum));_assert_(a_input);
    2659         DoubleArrayInput* T_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbTiniEnum));_assert_(T_input);
    2660 
    2661         dz_input->GetValues(&dzini,&m);
    2662         d_input->GetValues(&dini,&m);
    2663         re_input->GetValues(&reini,&m);
    2664         gdn_input->GetValues(&gdnini,&m);
    2665         gsp_input->GetValues(&gspini,&m);
    2666         EC_input->GetInputValue(&EC);
    2667         W_input->GetValues(&Wini,&m);
    2668         a_input->GetValues(&aini,&m);
    2669         T_input->GetValues(&Tini,&m);
    2670        
    2671         /*Retrive the correct value of m (without the zeroes at the end)*/
    2672         Input* Size_input=this->GetInput(SmbSizeiniEnum); _assert_(Size_input);
    2673         Size_input->GetInputValue(&m);
    2674        
    2675         if(m==2){ //Snow properties are initialized with default values. Vertical grid has to be initialized too
    2676 //            if(VerboseSmb() && this->Sid()==0)_printf0_("Snow properties initialized w DEFAULT values\n");
    2677            
    2678             /*initialize profile variables:*/
    2679             GembgridInitialize(&dz, &m, zTop, dzTop, zMax, zY);
    2680            
    2681             d = xNewZeroInit<IssmDouble>(m); for(int i=0;i<m;i++)d[i]=dini[0]; //ice density [kg m-3]
    2682             re = xNewZeroInit<IssmDouble>(m); for(int i=0;i<m;i++)re[i]=reini[0];         //set grain size to old snow [mm]
    2683             gdn = xNewZeroInit<IssmDouble>(m); for(int i=0;i<m;i++)gdn[i]=gdnini[0];         //set grain dentricity to old snow
    2684             gsp = xNewZeroInit<IssmDouble>(m); for(int i=0;i<m;i++)gsp[i]=gspini[0];         //set grain sphericity to old snow
    2685             W = xNewZeroInit<IssmDouble>(m); for(int i=0;i<m;i++)W[i]=Wini[0];             //set water content to zero [kg m-2]
    2686             a = xNewZeroInit<IssmDouble>(m); for(int i=0;i<m;i++)a[i]=aini[0];         //set albedo equal to fresh snow [fraction]
    2687             T = xNewZeroInit<IssmDouble>(m); for(int i=0;i<m;i++)T[i]=Tmean;         //set initial grid cell temperature to the annual mean temperature [K]
    2688 /*            /!\ Default value of T can not be retrived from SMBgemb.m (like other snow properties) because don't know Tmean yet when set default values.
    2689             Default value of 0C given in SMBgemb.m is overwritten here with value of Tmean*/
    2690            
    2691             //fixed lower temperature bounday condition - T is fixed
    2692             T_bottom=T[m-1];
    2693         }
    2694         else{ //Retrieve snow properties from previous run. Need to provide values for all layers
    2695 //            if(VerboseSmb() && this->Sid()==0)_printf0_("Snow properties initialized w RESTART values\n");
    2696            
    2697             dz = xNewZeroInit<IssmDouble>(m);for(int i=0;i<m;i++)dz[i]=dzini[i];
    2698             d = xNewZeroInit<IssmDouble>(m);for(int i=0;i<m;i++)d[i]=dini[i];
    2699             re = xNewZeroInit<IssmDouble>(m);for(int i=0;i<m;i++)re[i]=reini[i];
    2700             gdn = xNewZeroInit<IssmDouble>(m);for(int i=0;i<m;i++)gdn[i]=gdnini[i];
    2701             gsp = xNewZeroInit<IssmDouble>(m);for(int i=0;i<m;i++)gsp[i]=gspini[i];
    2702             W = xNewZeroInit<IssmDouble>(m);for(int i=0;i<m;i++)W[i]=Wini[i];
    2703             a = xNewZeroInit<IssmDouble>(m);for(int i=0;i<m;i++)a[i]=aini[i];
    2704             T = xNewZeroInit<IssmDouble>(m);for(int i=0;i<m;i++)T[i]=Tini[i];
    2705 
    2706             //fixed lower temperature bounday condition - T is fixed
    2707             T_bottom=T[m-1];
    2708         }
    2709        
    2710         /*Flag the initialization:*/
    2711         this->AddInput(new DoubleInput(SmbIsInitializedEnum,1.0));
    2712     }
    2713     else{
    2714         /*Recover inputs: */
    2715         DoubleArrayInput* dz_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbDzEnum)); _assert_(dz_input);
    2716         DoubleArrayInput* d_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbDEnum));_assert_(d_input);
    2717         DoubleArrayInput* re_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbReEnum));_assert_(re_input);
    2718         DoubleArrayInput* gdn_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbGdnEnum));_assert_(gdn_input);
    2719         DoubleArrayInput* gsp_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbGspEnum));_assert_(gsp_input);
    2720         DoubleInput* EC_input= dynamic_cast<DoubleInput*>(this->GetInput(SmbECEnum));_assert_(EC_input);
    2721         DoubleArrayInput* W_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbWEnum));_assert_(W_input);
    2722         DoubleArrayInput* a_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbAEnum));_assert_(a_input);
    2723         DoubleArrayInput* T_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbTEnum));_assert_(T_input);
    2724 
    2725         /*Recover arrays: */
    2726         dz_input->GetValues(&dz,&m);
    2727         d_input->GetValues(&d,&m);
    2728         re_input->GetValues(&re,&m);
    2729         gdn_input->GetValues(&gdn,&m);
    2730         gsp_input->GetValues(&gsp,&m);
    2731         EC_input->GetInputValue(&EC);
    2732         W_input->GetValues(&W,&m);
    2733         a_input->GetValues(&a,&m);
    2734         T_input->GetValues(&T,&m);
    2735 
    2736         //fixed lower temperature bounday condition - T is fixed
    2737         T_bottom=T[m-1];
    2738 
    2739     } /*}}}*/
     2666                if(VerboseSmb() && this->Sid()==0)_printf0_("smb core: Initializing grid\n");
     2667                //if(this->Sid()==1) for(int i=0;i<m;i++)_printf_("z[" << i << "]=" <<
     2668                //dz[i] << "\n");
     2669
     2670                DoubleArrayInput* dz_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbDziniEnum)); _assert_(dz_input);
     2671                DoubleArrayInput* d_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbDiniEnum));_assert_(d_input);
     2672                DoubleArrayInput* re_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbReiniEnum));_assert_(re_input);
     2673                DoubleArrayInput* gdn_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbGdniniEnum));_assert_(gdn_input);
     2674                DoubleArrayInput* gsp_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbGspiniEnum));_assert_(gsp_input);
     2675                DoubleInput* EC_input= dynamic_cast<DoubleInput*>(this->GetInput(SmbECiniEnum));_assert_(EC_input);
     2676                DoubleArrayInput* W_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbWiniEnum));_assert_(W_input);
     2677                DoubleArrayInput* a_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbAiniEnum));_assert_(a_input);
     2678                DoubleArrayInput* T_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbTiniEnum));_assert_(T_input);
     2679
     2680                dz_input->GetValues(&dzini,&m);
     2681                d_input->GetValues(&dini,&m);
     2682                re_input->GetValues(&reini,&m);
     2683                gdn_input->GetValues(&gdnini,&m);
     2684                gsp_input->GetValues(&gspini,&m);
     2685                EC_input->GetInputValue(&EC);
     2686                W_input->GetValues(&Wini,&m);
     2687                a_input->GetValues(&aini,&m);
     2688                T_input->GetValues(&Tini,&m);
     2689
     2690                /*Retrive the correct value of m (without the zeroes at the end)*/
     2691                Input* Size_input=this->GetInput(SmbSizeiniEnum); _assert_(Size_input);
     2692                Size_input->GetInputValue(&m);
     2693
     2694                if(m==2){ //Snow properties are initialized with default values. Vertical grid has to be initialized too
     2695                        //            if(VerboseSmb() && this->Sid()==0)_printf0_("Snow properties initialized w DEFAULT values\n");
     2696
     2697                        /*initialize profile variables:*/
     2698                        GembgridInitialize(&dz, &m, zTop, dzTop, zMax, zY);
     2699
     2700                        d = xNewZeroInit<IssmDouble>(m); for(int i=0;i<m;i++)d[i]=dini[0]; //ice density [kg m-3]
     2701                        re = xNewZeroInit<IssmDouble>(m); for(int i=0;i<m;i++)re[i]=reini[0];         //set grain size to old snow [mm]
     2702                        gdn = xNewZeroInit<IssmDouble>(m); for(int i=0;i<m;i++)gdn[i]=gdnini[0];         //set grain dentricity to old snow
     2703                        gsp = xNewZeroInit<IssmDouble>(m); for(int i=0;i<m;i++)gsp[i]=gspini[0];         //set grain sphericity to old snow
     2704                        W = xNewZeroInit<IssmDouble>(m); for(int i=0;i<m;i++)W[i]=Wini[0];             //set water content to zero [kg m-2]
     2705                        a = xNewZeroInit<IssmDouble>(m); for(int i=0;i<m;i++)a[i]=aini[0];         //set albedo equal to fresh snow [fraction]
     2706                        T = xNewZeroInit<IssmDouble>(m); for(int i=0;i<m;i++)T[i]=Tmean;         //set initial grid cell temperature to the annual mean temperature [K]
     2707                        /*            /!\ Default value of T can not be retrived from SMBgemb.m (like other snow properties) because don't know Tmean yet when set default values.
     2708                                                          Default value of 0C given in SMBgemb.m is overwritten here with value of Tmean*/
     2709
     2710                        //fixed lower temperature bounday condition - T is fixed
     2711                        T_bottom=T[m-1];
     2712                }
     2713                else{ //Retrieve snow properties from previous run. Need to provide values for all layers
     2714                        //            if(VerboseSmb() && this->Sid()==0)_printf0_("Snow properties initialized w RESTART values\n");
     2715
     2716                        dz = xNewZeroInit<IssmDouble>(m);for(int i=0;i<m;i++)dz[i]=dzini[i];
     2717                        d = xNewZeroInit<IssmDouble>(m);for(int i=0;i<m;i++)d[i]=dini[i];
     2718                        re = xNewZeroInit<IssmDouble>(m);for(int i=0;i<m;i++)re[i]=reini[i];
     2719                        gdn = xNewZeroInit<IssmDouble>(m);for(int i=0;i<m;i++)gdn[i]=gdnini[i];
     2720                        gsp = xNewZeroInit<IssmDouble>(m);for(int i=0;i<m;i++)gsp[i]=gspini[i];
     2721                        W = xNewZeroInit<IssmDouble>(m);for(int i=0;i<m;i++)W[i]=Wini[i];
     2722                        a = xNewZeroInit<IssmDouble>(m);for(int i=0;i<m;i++)a[i]=aini[i];
     2723                        T = xNewZeroInit<IssmDouble>(m);for(int i=0;i<m;i++)T[i]=Tini[i];
     2724
     2725                        //fixed lower temperature bounday condition - T is fixed
     2726                        T_bottom=T[m-1];
     2727                }
     2728
     2729                /*Flag the initialization:*/
     2730                this->AddInput(new DoubleInput(SmbIsInitializedEnum,1.0));
     2731        }
     2732        else{
     2733                /*Recover inputs: */
     2734                DoubleArrayInput* dz_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbDzEnum)); _assert_(dz_input);
     2735                DoubleArrayInput* d_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbDEnum));_assert_(d_input);
     2736                DoubleArrayInput* re_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbReEnum));_assert_(re_input);
     2737                DoubleArrayInput* gdn_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbGdnEnum));_assert_(gdn_input);
     2738                DoubleArrayInput* gsp_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbGspEnum));_assert_(gsp_input);
     2739                DoubleInput* EC_input= dynamic_cast<DoubleInput*>(this->GetInput(SmbECEnum));_assert_(EC_input);
     2740                DoubleArrayInput* W_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbWEnum));_assert_(W_input);
     2741                DoubleArrayInput* a_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbAEnum));_assert_(a_input);
     2742                DoubleArrayInput* T_input= dynamic_cast<DoubleArrayInput*>(this->GetInput(SmbTEnum));_assert_(T_input);
     2743
     2744                /*Recover arrays: */
     2745                dz_input->GetValues(&dz,&m);
     2746                d_input->GetValues(&d,&m);
     2747                re_input->GetValues(&re,&m);
     2748                gdn_input->GetValues(&gdn,&m);
     2749                gsp_input->GetValues(&gsp,&m);
     2750                EC_input->GetInputValue(&EC);
     2751                W_input->GetValues(&W,&m);
     2752                a_input->GetValues(&a,&m);
     2753                T_input->GetValues(&T,&m);
     2754
     2755                //fixed lower temperature bounday condition - T is fixed
     2756                T_bottom=T[m-1];
     2757
     2758        } /*}}}*/
    27402759
    27412760        // determine initial mass [kg]
    27422761        initMass=0; for(int i=0;i<m;i++) initMass += dz[i]*d[i] + W[i];
    2743    
    2744         // initialize cumulative variables
     2762
     2763        // initialize cumulative variables
    27452764        sumR = 0; sumM = 0; sumEC = 0; sumP = 0; sumMassAdd = 0;
    27462765        sumdz_add=0;
     
    27712790
    27722791                /*Snow, firn and ice albedo:*/
    2773                 if(isalbedo)albedo(a,aIdx,re,d,cldFrac,aIce, aSnow,T,W,P,EC,t0wet,t0dry,K,smb_dt,m,this->Sid());
    2774                
    2775                                        
     2792                if(isalbedo)albedo(a,aIdx,re,d,cldFrac,aIce, aSnow,T,W,P,EC,t0wet,t0dry,K,smb_dt,rho_ice,m,this->Sid());
     2793
     2794
    27762795                /*Distribution of absorbed short wave radation with depth:*/
    2777                 if(isshortwave)shortwave(&swf, swIdx, aIdx, dsw, a[0], d, dz, re,m,this->Sid());
    2778                
     2796                if(isshortwave)shortwave(&swf, swIdx, aIdx, dsw, a[0], d, dz, re,rho_ice,m,this->Sid());
     2797
    27792798                /*Calculate net shortwave [W m-2]*/
    27802799                netSW = cellsum(swf,m);
    27812800
    27822801                /*Thermal profile computation:*/
    2783                 if(isthermal)thermo(&EC, T, dz, d, swf, dlw, Ta, V, eAir, pAir, W[0], smb_dt, m, Vz, Tz,this->Sid());
     2802                if(isthermal)thermo(&EC, T, dz, d, swf, dlw, Ta, V, eAir, pAir, W[0], smb_dt, m, Vz, Tz,rho_ice,this->Sid());
    27842803
    27852804                /*Change in thickness of top cell due to evaporation/condensation  assuming same density as top cell.
    27862805                 * need to fix this in case all or more of cell evaporates */
    27872806                dz[0] = dz[0] + EC / d[0];
    2788                
     2807
    27892808                /*Add snow/rain to top grid cell adjusting cell depth, temperature and density*/
    2790                 if(isaccumulation)accumulation(&T, &dz, &d, &W, &a, &re, &gdn, &gsp, &m, Ta, P, dzMin, aSnow,this->Sid());
     2809                if(isaccumulation)accumulation(&T, &dz, &d, &W, &a, &re, &gdn, &gsp, &m, Ta, P, dzMin, aSnow,rho_ice,this->Sid());
    27912810
    27922811                /*Calculate water production, M [kg m-2] resulting from snow/ice temperature exceeding 273.15 deg K
    27932812                 * (> 0 deg C), runoff R [kg m-2] and resulting changes in density and determine wet compaction [m]*/
    2794                 if(ismelt)melt(&M, &R, &mAdd, &dz_add, &T, &d, &dz, &W, &a, &re, &gdn, &gsp, &m, dzMin, zMax, zMin, zTop,this->Sid());
     2813                if(ismelt)melt(&M, &R, &mAdd, &dz_add, &T, &d, &dz, &W, &a, &re, &gdn, &gsp, &m, dzMin, zMax, zMin, zTop,rho_ice,this->Sid());
    27952814
    27962815                /*Allow non-melt densification and determine compaction [m]*/
    27972816                if(isdensification)densification(d,dz, T, re, denIdx, C, smb_dt, Tmean,rho_ice,m,this->Sid());
    2798                
     2817
    27992818                /*Calculate upward longwave radiation flux [W m-2] not used in energy balance. Calculated for every
    28002819                 * sub-time step in thermo equations*/
     
    28032822                /*Calculate net longwave [W m-2]*/
    28042823                netLW = dlw - ulw;
    2805                
     2824
    28062825                /*Calculate turbulent heat fluxes [W m-2]*/
    2807                 if(isturbulentflux)turbulentFlux(&shf, &lhf, &dayEC, Ta, T[0], V, eAir, pAir, d[0], W[0], Vz, Tz,this->Sid());
    2808                
     2826                if(isturbulentflux)turbulentFlux(&shf, &lhf, &dayEC, Ta, T[0], V, eAir, pAir, d[0], W[0], Vz, Tz,rho_ice,this->Sid());
     2827
    28092828                /*Verbose some resuls in debug mode: {{{*/
    28102829                if(VerboseSmb() && 0){
    28112830                        _printf_("smb log: count[" << count << "] m[" << m << "] "
    2812                                 << setprecision(16)   << "T[" << cellsum(T,m)  << "] "
    2813                                                           << "d[" << cellsum(d,m)  << "] "
    2814                                                           << "dz[" << cellsum(dz,m)  << "] "
    2815                                                           << "a[" << cellsum(a,m)  << "] "
    2816                                                           << "W[" << cellsum(W,m)  << "] "
    2817                                                           << "re[" << cellsum(re,m)  << "] "
    2818                                                           << "gdn[" << cellsum(gdn,m)  << "] "
    2819                                                           << "gsp[" << cellsum(gsp,m)  << "] "
    2820                                                           << "swf[" << netSW << "] "
    2821                                                                           << "\n");
     2831                                                << setprecision(16)   << "T[" << cellsum(T,m)  << "] "
     2832                                                << "d[" << cellsum(d,m)  << "] "
     2833                                                << "dz[" << cellsum(dz,m)  << "] "
     2834                                                << "a[" << cellsum(a,m)  << "] "
     2835                                                << "W[" << cellsum(W,m)  << "] "
     2836                                                << "re[" << cellsum(re,m)  << "] "
     2837                                                << "gdn[" << cellsum(gdn,m)  << "] "
     2838                                                << "gsp[" << cellsum(gsp,m)  << "] "
     2839                                                << "swf[" << netSW << "] "
     2840                                                << "\n");
    28222841                } /*}}}*/
    2823                
     2842
    28242843                /*Sum component mass changes [kg m-2]*/
    28252844                sumMassAdd = mAdd + sumMassAdd;
     
    28412860                if (dMass != 0.0) _printf_("total system mass not conserved in MB function \n");
    28422861                #endif
    2843                
     2862
    28442863                /*Check bottom grid cell T is unchanged:*/
    28452864                if (T[m-1]!=T_bottom) _printf_("T(end)~=T_bottom" << "\n");
    2846                
     2865
    28472866                /*Free ressources: */
    28482867                xDelete<IssmDouble>(swf);
     
    28592878        this->AddInput(new DoubleArrayInput(SmbGspEnum,gsp,m));
    28602879        this->AddInput(new DoubleArrayInput(SmbTEnum,T,m));
    2861         this->AddInput(new DoubleInput(SmbECEnum,sumEC/yts));
     2880        this->AddInput(new DoubleInput(SmbECEnum,sumEC/dt/rho_ice));
    28622881        this->AddInput(new DoubleArrayInput(SmbWEnum,W,m));
    28632882        this->AddInput(new DoubleArrayInput(SmbAEnum,a,m));
    2864         this->AddInput(new DoubleInput(SmbMassBalanceEnum,(sumP + sumEC -sumR)/yts));
    2865         this->AddInput(new DoubleInput(SmbRunoffEnum,sumR/yts));
    2866         this->AddInput(new DoubleInput(SmbPrecipitationEnum,sumP/yts));
     2883        this->AddInput(new DoubleInput(SmbMassBalanceEnum,(sumP + sumEC -sumR)/dt/rho_ice));
     2884        this->AddInput(new DoubleInput(SmbMeltEnum,sumM/dt/rho_ice));
     2885        this->AddInput(new DoubleInput(SmbRunoffEnum,sumR/dt/rho_ice));
     2886        this->AddInput(new DoubleInput(SmbPrecipitationEnum,sumP/dt/rho_ice));
    28672887        this->AddInput(new DoubleInput(SmbDz_addEnum,sumdz_add/yts));
    2868         this->AddInput(new DoubleInput(SmbM_addEnum,sumMassAdd/yts));
     2888        this->AddInput(new DoubleInput(SmbM_addEnum,sumMassAdd/dt));
    28692889
    28702890        /*Free allocations:{{{*/
  • issm/trunk-jpl/src/c/modules/SurfaceMassBalancex/Gembx.cpp

    r22238 r22249  
    88
    99const double Pi = 3.141592653589793;
     10const double CtoK = 273.15;             // Kelvin to Celcius conversion/ice melt. point T in K
     11const double dts = 86400.0;              // Number of seconds in a day
     12
     13/* Tolerances have to be defined for if loops involving some specific values
     14        like densitiy of ice or melting point temp because values are "rounded"
     15        (e.g rho ice = 909.99... instead of 910.0) and we don't always go into the right loop */
     16const double Ttol = 1e-10;
     17const double Dtol = 1e-11;
     18const double Gdntol = 1e-10;
     19const double Wtol = 1e-13;
     20
     21const double CI = 2102.0;                       // heat capacity of snow/ice (J kg-1 k-1)
     22const double LF = 0.3345E6;             // latent heat of fusion (J kg-1)
     23const double LV = 2.495E6;               // latent heat of vaporization (J kg-1)
     24const double LS = 2.8295E6;             // latent heat of sublimation (J kg-1)
     25const double SB = 5.67E-8;                // Stefan-Boltzmann constant (W m-2 K-4)
     26const double CA = 1005.0;                    // heat capacity of air (J kg-1 k-1)
     27const double R = 8.314;                      // gas constant (mol-1 K-1)
    1028
    1129void Gembx(FemModel* femmodel){  /*{{{*/
     
    2543
    2644        /*intermediary:*/
    27         IssmDouble dgpTop;
    28         int gpTop, gpBottom;
    29         int i;
    30         IssmDouble gp0,z0;
     45        IssmDouble dgpTop=0.0;
     46        int gpTop=0;
     47        int gpBottom=0;
     48        int i=0;
     49        IssmDouble gp0=0.0;
     50        IssmDouble z0=0.0;
    3151        IssmDouble* dzT=NULL;
    3252        IssmDouble* dzB=NULL;
     
    101121
    102122        // initialize
    103         IssmDouble F = 0, H=0, G=0;
     123        IssmDouble F = 0.0, H=0.0, G=0.0;
    104124        const IssmDouble E = 0.09;        //[mm d-1] model time growth constant E
    105125        // convert T from K to ºC
    106         T = T - 273.15;
     126        T = T - CtoK;
    107127
    108128        // temperature coefficient F
    109129        if(T>-6.0) F =  0.7 + ((T/-6.0) * 0.3);
    110         if(T<=-6.0 && T>-22.0) F =  1 - ((T+6.0)/-16.0 * 0.8);
     130        if(T<=-6.0 && T>-22.0) F =  1.0 - ((T+6.0)/-16.0 * 0.8);
    111131        if(T<=-22.0 && T>-40.0) F =  0.2 - ((T+22.0)/-18.0 * 0.2);
    112132
     
    114134        if(d<150.0) H=1.0;
    115135
    116         if(d>=150.0 & d<400.0) H = 1 - ((d-150.0)/250.0);
     136        if(d>=150.0 & d<400.0) H = 1.0 - ((d-150.0)/250.0);
    117137
    118138        // temperature gradient coefficient G
     
    121141        if(dT >= 0.4  && dT < 0.5)  G = 0.67 + (((dT - 0.4)/0.1) * 0.23);
    122142        if(dT >= 0.5  && dT < 0.7)  G = 0.9 + (((dT - 0.5)/0.2) * 0.1);
    123         if(dT >= .7              )  G = 1.0;
     143        if(dT >= 0.7              )  G = 1.0;
    124144
    125145        // grouped coefficient Q
     
    164184
    165185        /*intermediary: */
    166         IssmDouble  dt;
     186        IssmDouble  dt=0.0;
    167187        IssmDouble* gsz=NULL;
    168188        IssmDouble* dT=NULL;
    169189        IssmDouble* zGPC=NULL;
    170190        IssmDouble* lwc=NULL;
    171         IssmDouble  Q=0;
     191        IssmDouble  Q=0.0;
    172192
    173193        if(VerboseSmb() && sid==0 && IssmComm::GetRank()==0)_printf0_("   grain growth module\n");
     
    183203
    184204        /*Convert dt from seconds to day: */
    185         dt=smb_dt/86400.0;
     205        dt=smb_dt/dts;
    186206
    187207        /*Determine liquid-water content in percentage: */
     
    189209
    190210        //set maximum water content by mass to 9 percent (Brun, 1980)
    191         for(int i=0;i<m;i++)if(lwc[i]>9.0) lwc[i]=9.0;
     211        for(int i=0;i<m;i++)if(lwc[i]>9.0-Wtol) lwc[i]=9.0;
    192212
    193213
     
    202222        for(int i=0;i<m;i++){
    203223                for (int j=0;j<=i;j++) zGPC[i]+=dz[j];
    204                 zGPC[i]-=dz[i]/2;
     224                zGPC[i]-=(dz[i]/2.0);
    205225        }
    206226
     
    217237        /*Snow metamorphism. Depends on value of snow dendricity and wetness of the snowpack: */
    218238        for(int i=0;i<m;i++){
    219                 if (gdn[i]>0){
     239                if (gdn[i]>0.0+Gdntol){
    220240
    221241                        //_printf_("Dendritic dry snow metamorphism\n");
    222242
    223243                        //index for dentricity > 0 and T gradients < 5 degC m-1 and >= 5 degC m-1
    224                         if(dT[i]<5.0){
     244                        if(dT[i]<5.0-Ttol){
    225245                                //determine coefficients
    226246                                IssmDouble A = - 2e8 * exp(-6e3 / T[i]) * dt;
     
    240260
    241261                        // wet snow metamorphism
    242                         if(W[i]>0.0){
     262                        if(W[i]>0.0+Wtol){
    243263
    244264                                //_printf_("D}ritic wet snow metamorphism\n");
     
    253273
    254274                        // dendricity and sphericity can not be > 1 or < 0
    255                         if (gdn[i]<0.0)gdn[i]=0.0;
    256                         if (gsp[i]<0.0)gsp[i]=0.0;
    257                         if (gdn[i]>1.0)gdn[i]=1.0;
    258                         if (gsp[i]>1.0)gsp[i]=1.0;
     275                        if (gdn[i]<0.0+Wtol)gdn[i]=0.0;
     276                        if (gsp[i]<0.0+Wtol)gsp[i]=0.0;
     277                        if (gdn[i]>1.0-Wtol)gdn[i]=1.0;
     278                        if (gsp[i]>1.0-Wtol)gsp[i]=1.0;
    259279
    260280                        // determine new grain size (mm)
    261                         gsz[i] = 0.1 + (1-gdn[i])*0.25 + (0.5-gsp[i])*0.1;
     281                        gsz[i] = 0.1 + (1.0-gdn[i])*0.25 + (0.5-gsp[i])*0.1;
    262282
    263283                }
     
    271291
    272292                        // calculate grain growth
    273                         gsz[i] += Q* dt;
     293                        gsz[i] += (Q*dt);
    274294
    275295                        //Wet snow metamorphism (Brun, 1989)
    276                         if(W[i]>0.0){
     296                        if(W[i]>0.0+Wtol){
    277297                                //_printf_("Nond}ritic wet snow metamorphism\n");
    278298                                //wet rate of change coefficient
    279                                 IssmDouble E = 1.28e-8 + (4.22e-10 * pow(lwc[i],3.0))* (dt *86400.0);   // [mm^3 s^-1]
     299                                IssmDouble E = 1.28e-8 + (4.22e-10 * pow(lwc[i],3.0))* (dt *dts);   // [mm^3 s^-1]
    280300
    281301                                // calculate change in grain volume and convert to grain size
     
    285305
    286306                        // grains with sphericity == 1 can not have grain sizes > 2 mm (Brun, 1992)
    287                         if (gsp[i]==1.0 && gsz[i]>2.0) gsz[i]=2.0;
     307                        if (fabs(gsp[i]-1.0)<Wtol && gsz[i]>2.0-Wtol) gsz[i]=2.0;
    288308
    289309                        // grains with sphericity == 0 can not have grain sizes > 5 mm (Brun, 1992)
    290                         if (gsp[i]!=1.0 && gsz[i]>5.0) gsz[i]=5.0;
     310                        if (fabs(gsp[i]-1.0)>Wtol && gsz[i]>5.0-Wtol) gsz[i]=5.0;
    291311                }
    292312
     
    302322
    303323}  /*}}}*/
    304 void albedo(IssmDouble* a, int aIdx, IssmDouble* re, IssmDouble* d, IssmDouble cldFrac, IssmDouble aIce, IssmDouble aSnow, IssmDouble* TK, IssmDouble* W, IssmDouble P, IssmDouble EC, IssmDouble t0wet, IssmDouble t0dry, IssmDouble K, IssmDouble dt, int m,int sid) { /*{{{*/
     324void albedo(IssmDouble* a, int aIdx, IssmDouble* re, IssmDouble* d, IssmDouble cldFrac, IssmDouble aIce, IssmDouble aSnow, IssmDouble* TK, IssmDouble* W, IssmDouble P, IssmDouble EC, IssmDouble t0wet, IssmDouble t0dry, IssmDouble K, IssmDouble dt, IssmDouble dIce, int m,int sid) { /*{{{*/
    305325
    306326        //// Calculates Snow, firn and ice albedo as a function of:
     
    350370        //some constants:
    351371        const IssmDouble dSnow = 300;   // density of fresh snow [kg m-3]       
    352         const IssmDouble dIce = 910;    // density of ice [kg m-3]
    353372
    354373        if(aIdx==1){
     
    356375       
    357376        //convert effective radius to specific surface area [cm2 g-1]
    358         IssmDouble S = 3.0 / (.091 * re[0]);
     377        IssmDouble S = 3.0 / (0.091 * re[0]);
    359378       
    360379        //determine broadband albedo
    361         a[0]= 1.48 - pow(S,-.07);
     380        a[0]= 1.48 - pow(S,-0.07);
    362381        }
    363382        else if(aIdx==2){
     
    369388       
    370389        // convert effective radius to grain size in meters
    371         IssmDouble gsz = (re[0] * 2) / 1000.0;
     390        IssmDouble gsz = (re[0] * 2.0) / 1000.0;
    372391       
    373392        // spectral range:
     
    398417        // where: t0 = timescale for albedo decay
    399418       
    400         dt = dt / 86400;    // convert from [s] to [d]
     419        dt = dt / dts;    // convert from [s] to [d]
    401420       
    402421        // initialize variables
     
    414433        // K = 7                // time scale temperature coef. (7) [d]
    415434        // W0 = 300;            // 200 - 600 [mm]
    416         const IssmDouble z_snow = 15;            // 16 - 32 [mm]
     435        const IssmDouble z_snow = 15.0;            // 16 - 32 [mm]
    417436       
    418437        // determine timescale for albedo decay
    419         for(int i=0;i<m;i++)if(W[i]>0)t0[i]=t0wet; // wet snow timescale
    420         for(int i=0;i<m;i++)T[i]=TK[i] - 273.15; // change T from K to degC
     438        for(int i=0;i<m;i++)if(W[i]>0.0+Wtol)t0[i]=t0wet; // wet snow timescale
     439        for(int i=0;i<m;i++)T[i]=TK[i] - CtoK; // change T from K to degC
    421440        for(int i=0;i<m;i++) t0warm[i]= fabs(T[i]) * K + t0dry; //// 'warm' snow timescale
    422         for(int i=0;i<m;i++)if(W[i]==0.0 && T[i]>=-10)t0[i]= t0warm[i];
    423         for(int i=0;i<m;i++)if(T[i]<-10) t0[i] =  10 * K + t0dry; // 'cold' snow timescale
     441        for(int i=0;i<m;i++)if(fabs(W[i])<Wtol && T[i]>=-10.0-Ttol)t0[i]= t0warm[i];
     442        for(int i=0;i<m;i++)if(T[i]<-10.0-Ttol) t0[i] =  10.0 * K + t0dry; // 'cold' snow timescale
    424443       
    425444        // calculate new albedo
     
    431450       
    432451        // check if condensation occurs & if it is deposited in solid phase
    433         if ( EC > 0 && T[0] < 0) P = P + (EC/dSnow) * 1000;  // add cond to precip [mm]
     452        if ( EC > 0.0 + Dtol && T[0] < 0.0-Ttol) P = P + (EC/dSnow) * 1000.0;  // add cond to precip [mm]
    434453       
    435454        a[0] = aSnow - (aSnow - a[0]) * exp(-P/z_snow);
     
    453472        else if (xIsNan(a[0])) _error_("albedo == NAN\n");
    454473}  /*}}}*/
    455 void thermo(IssmDouble* pEC, IssmDouble* T, IssmDouble* dz, IssmDouble* d, IssmDouble* swf, IssmDouble dlwrf, IssmDouble Ta, IssmDouble V, IssmDouble eAir, IssmDouble pAir, IssmDouble Ws, IssmDouble dt0, int m, IssmDouble Vz, IssmDouble Tz,int sid) { /*{{{*/
     474void thermo(IssmDouble* pEC, IssmDouble* T, IssmDouble* dz, IssmDouble* d, IssmDouble* swf, IssmDouble dlwrf, IssmDouble Ta, IssmDouble V, IssmDouble eAir, IssmDouble pAir, IssmDouble Ws, IssmDouble dt0, int m, IssmDouble Vz, IssmDouble Tz, IssmDouble dIce, int sid) { /*{{{*/
    456475
    457476        /* ENGLACIAL THERMODYNAMICS*/
     
    495514        IssmDouble* sw = NULL;
    496515        IssmDouble* dT_sw = NULL;
    497         IssmDouble* lw = NULL;
    498516        IssmDouble* T0 = NULL;
    499517        IssmDouble* Tu = NULL;
    500518        IssmDouble* Td = NULL;
    501519
    502         IssmDouble  z0;
    503         IssmDouble  dt;
    504         IssmDouble max_fdt=0;
    505         IssmDouble  Ts=0;
    506         IssmDouble  L;
    507         IssmDouble  eS;
    508         IssmDouble  Ri=0;
    509         IssmDouble  coefM;
    510         IssmDouble  coefH;
    511         IssmDouble An;
    512         IssmDouble C;
    513         IssmDouble shf;
    514         IssmDouble SB;
    515         IssmDouble CI;
    516         IssmDouble ds;
    517         IssmDouble dAir;
    518         IssmDouble TCs;
    519         IssmDouble lhf;
    520         IssmDouble EC_day;
    521         IssmDouble dT_turb;
    522         IssmDouble turb;
    523         IssmDouble ulw;
    524         IssmDouble dT_ulw;
    525         IssmDouble dlw;
    526         IssmDouble dT_dlw;
     520        IssmDouble  z0=0.0;     
     521        IssmDouble  dt=0.0;
     522        IssmDouble max_fdt=0.0;
     523        IssmDouble  Ts=0.0;
     524        IssmDouble  L=0.0;
     525        IssmDouble  eS=0.0;
     526        IssmDouble  Ri=0.0;
     527        IssmDouble  coefM=0.0;
     528        IssmDouble  coefH=0.0;
     529        IssmDouble An=0.0;
     530        IssmDouble C=0.0;
     531        IssmDouble shf=0.0;
     532        IssmDouble ds=0.0;
     533        IssmDouble dAir=0.0;
     534        IssmDouble TCs=0.0;
     535        IssmDouble lhf=0.0;
     536        IssmDouble EC_day=0.0;
     537        IssmDouble dT_turb=0.0;
     538        IssmDouble turb=0.0;
     539        IssmDouble ulw=0.0;
     540        IssmDouble dT_ulw=0.0;
     541        IssmDouble dlw=0.0;
     542        IssmDouble dT_dlw=0.0;
    527543       
    528544        /*outputs:*/
    529         IssmDouble EC;
     545        IssmDouble EC=0.0;
    530546
    531547        if(VerboseSmb() && sid==0 && IssmComm::GetRank()==0)_printf0_("   thermal module\n");
    532548
    533         // INITIALIZE
    534         CI = 2102;          // heat capacity of snow/ice (J kg-1 k-1)
    535         // CA = 1005;                  // heat capacity of air (J kg-1 k-1)
    536         // LF = 0.3345E6;              // latent heat of fusion(J kg-1)
    537         // LV = 2.495E6;               // latent heat of vaporization(J kg-1)
    538         // dIce = 910;                 // density of ice [kg m-3]
    539         // dSnow = 300;                // density of snow [kg m-3]
    540         SB = 5.67E-8;       // Stefan-Boltzmann constant [W m-2 K-4]
    541 
    542549        ds = d[0];      // density of top grid cell
    543550
    544551        // calculated air density [kg/m3]
    545         dAir = 0.029 * pAir /(8.314 * Ta);
     552        dAir = 0.029 * pAir /(R * Ta);
    546553
    547554        // thermal capacity of top grid cell [J/k]
     
    549556
    550557        //initialize Evaporation - Condenstation
    551         EC = 0;
     558        EC = 0.0;
    552559       
    553560        // check if all SW applied to surface or distributed throught subsurface
     
    556563        // SURFACE ROUGHNESS (Bougamont, 2006)
    557564        // wind/temperature surface roughness height [m]
    558         if (ds < 910 && Ws == 0) z0 = 0.00012;       // 0.12 mm for dry snow
    559         else if (ds >= 910) z0 = 0.0032;             // 3.2 mm for ice
     565        if (ds < dIce-Dtol && fabs(Ws) < Wtol) z0 = 0.00012;       // 0.12 mm for dry snow
     566        else if (ds >= dIce-Dtol) z0 = 0.0032;             // 3.2 mm for ice
    560567        else z0 = 0.0013;                            // 1.3 mm for wet snow
    561568
    562569        // if V = 0 goes to infinity therfore if V = 0 change
    563         if(V<.01)V=.01;
     570        if(V<0.01+Dtol)V=0.01;
    564571       
    565572        // Bulk-transfer coefficient for turbulent fluxes
     
    574581
    575582        // for snow and firn (density < 910 kg m-3) (Sturn et al, 1997)
    576         for(int i=0;i<m;i++) if(d[i]<910) K[i] = 0.138 - 1.01E-3 * d[i] + 3.233E-6 * (pow(d[i],2));
     583        for(int i=0;i<m;i++) if(d[i]<dIce-Dtol) K[i] = 0.138 - 1.01E-3 * d[i] + 3.233E-6 * (pow(d[i],2));
    577584
    578585        // for ice (density >= 910 kg m-3)
    579         for(int i=0;i<m;i++) if(d[i]>=910) K[i] = 9.828 * exp(-5.7E-3*T[i]);
     586        for(int i=0;i<m;i++) if(d[i]>=dIce-Dtol) K[i] = 9.828 * exp(-5.7E-3*T[i]);
    580587
    581588        // THERMAL DIFFUSION COEFFICIENTS
     
    632639        max_fdt=f[0];
    633640        for(int i=0;i<45;i++){
    634                 if (f[i]<dt)if(f[i]>=max_fdt)max_fdt=f[i];
     641                if (f[i]<dt-Dtol)if(f[i]>=max_fdt-Dtol)max_fdt=f[i];
    635642        }
    636643        dt=max_fdt;
     
    641648        Ap = xNew<IssmDouble>(m);
    642649        for(int i=0;i<m;i++){
    643                 Au[i] = pow((dzU[i]/2/KP[i] + dz[i]/2/KU[i]),-1);
    644                 Ad[i] = pow((dzD[i]/2/KP[i] + dz[i]/2/KD[i]),-1);
     650                Au[i] = pow((dzU[i]/2.0/KP[i] + dz[i]/2.0/KU[i]),-1.0);
     651                Ad[i] = pow((dzD[i]/2.0/KP[i] + dz[i]/2.0/KD[i]),-1.0);
    645652                Ap[i] = (d[i]*dz[i]*CI)/dt;
    646653        }
     
    653660                Nu[i] = Au[i] / Ap[i];
    654661                Nd[i] = Ad[i] / Ap[i];
    655                 Np[i]= 1 - Nu[i] - Nd[i];
     662                Np[i]= 1.0 - Nu[i] - Nd[i];
    656663        }
    657664       
    658665        // specify boundary conditions: constant flux at bottom
    659         Nu[m-1] = 0;
    660         Np[m-1] = 1;
     666        Nu[m-1] = 0.0;
     667        Np[m-1] = 1.0;
    661668       
    662669        // zero flux at surface
    663         Np[0] = 1 - Nd[0];
     670        Np[0] = 1.0 - Nd[0];
    664671       
    665672        // Create neighbor arrays for diffusion calculations instead of a tridiagonal matrix
    666         Nu[0] = 0;
    667         Nd[m-1] = 0;
     673        Nu[0] = 0.0;
     674        Nd[m-1] = 0.0;
    668675       
    669676        /* RADIATIVE FLUXES*/
     
    704711                // calculated.  The estimated enegy balance & melt are significanly
    705712                // less when Ts is taken as the mean of the x top grid cells.
    706                 Ts = (T[0] + T[1])/2;
    707                 Ts = fmin(273.15,Ts);    // don't allow Ts to exceed 273.15 K (0°C)
     713                Ts = (T[0] + T[1])/2.0;
     714                Ts = fmin(CtoK,Ts);    // don't allow Ts to exceed 273.15 K (0 degC)
    708715               
    709716                //TURBULENT HEAT FLUX
    710717   
    711                 // Monin–Obukhov Stability Correction
     718                // Monin-Obukhov Stability Correction
    712719                // Reference:
    713720                // Ohmura, A., 1982: Climate and Energy-Balance on the Arctic Tundra.
     
    715722
    716723                // calculate the Bulk Richardson Number (Ri)
    717                 Ri = (2*9.81* (Vz - z0) * (Ta - Ts)) / ((Ta + Ts)* pow(V,2.0));
     724                Ri = (2.0*9.81* (Vz - z0) * (Ta - Ts)) / ((Ta + Ts)* pow(V,2.0));
    718725               
    719                 // calculate Monin-–Obukhov stability factors 'coefM' and 'coefH'
     726                // calculate Monin-Obukhov stability factors 'coefM' and 'coefH'
    720727   
    721728                // do not allow Ri to exceed 0.19
     
    723730
    724731                // calculate momentum 'coefM' stability factor
    725                 if (Ri > 0){
     732                if (Ri > 0.0+Ttol){
    726733                        // if stable
    727                         coefM = 1/(1-5.2*Ri);
     734                        coefM = 1.0/(1.0-5.2*Ri);
    728735                }
    729736                else {
    730                         coefM =pow (1-18*Ri,-0.25);
     737                        coefM =pow (1.0-18*Ri,-0.25);
    731738                }
    732739               
    733740                // calculate heat/wind 'coef_H' stability factor
    734                 if (Ri < -0.03) coefH = 1.3 * coefM;
     741                if (Ri < -0.03-Ttol) coefH = 1.3 * coefM;
    735742                else coefH = coefM;
    736743               
    737744                //// Sensible Heat
    738745                // calculate the sensible heat flux [W m-2](Patterson, 1998)
    739                 shf = C * 1005 * (Ta - Ts);
     746                shf = C * CA * (Ta - Ts);
    740747
    741748                // adjust using Monin–Obukhov stability theory
     
    744751                //// Latent Heat
    745752                // determine if snow pack is melting & calcualte surface vapour pressure over ice or liquid water
    746                 if (Ts >= 273.15){
    747                         L = 2.495E6;
     753                if (Ts >= CtoK-Ttol){
     754                        L = LV;
    748755
    749756                        // for an ice surface Murphy and Koop, 2005 [Equation 7]
     
    751758                }
    752759                else{
    753                         L = 2.8295E6; // latent heat of sublimation for liquid surface (assume liquid on surface when Ts == 0 deg C)
     760                        L = LS; // latent heat of sublimation for liquid surface (assume liquid on surface when Ts == 0 deg C)
    754761                        // Wright (1997), US Meteorological Handbook from Murphy and Koop, 2005 Appendix A
    755                         eS = 611.21 * exp(17.502 * (Ts - 273.15) / (240.97 + Ts - 273.15));
     762                        eS = 611.21 * exp(17.502 * (Ts - CtoK) / (240.97 + Ts - CtoK));
    756763                }
    757764               
     
    759766                lhf = C * L * (eAir - eS) * 0.622 / pAir;
    760767               
    761                 // adjust using Monin–Obukhov stability theory (if lhf '+' then there is energy and mass gained at the surface,
     768                // adjust using Monin-Obukhov stability theory (if lhf '+' then there is energy and mass gained at the surface,
    762769                // if '-' then there is mass and energy loss at the surface.
    763770                lhf = lhf / (coefM * coefH);
    764771
    765772                //mass loss (-)/acreation(+) due to evaporation/condensation [kg]
    766                 EC_day = lhf * 86400 / L;
     773                EC_day = lhf * dts / L;
    767774
    768775                // temperature change due turbulent fluxes
     
    787794               
    788795                // calculate cumulative evaporation (+)/condensation(-)
    789                 EC = EC + (EC_day/86400)*dt;
     796                EC = EC + (EC_day/dts)*dt;
    790797   
    791798                /* CHECK FOR ENERGY (E) CONSERVATION [UNITS: J]
     
    819826        xDelete<IssmDouble>(sw);
    820827        xDelete<IssmDouble>(dT_sw);
    821         xDelete<IssmDouble>(lw);
    822828        xDelete<IssmDouble>(T0);
    823829        xDelete<IssmDouble>(Tu);
     
    829835
    830836}  /*}}}*/
    831 void shortwave(IssmDouble** pswf, int swIdx, int aIdx, IssmDouble dsw, IssmDouble as, IssmDouble* d, IssmDouble* dz, IssmDouble* re, int m, int sid){ /*{{{*/
     837void shortwave(IssmDouble** pswf, int swIdx, int aIdx, IssmDouble dsw, IssmDouble as, IssmDouble* d, IssmDouble* dz, IssmDouble* re, IssmDouble dIce, int m, int sid){ /*{{{*/
    832838
    833839        // DISTRIBUTES ABSORBED SHORTWAVE RADIATION WITHIN SNOW/ICE
     
    865871       
    866872                // calculate surface shortwave radiation fluxes [W m-2]
    867                 swf[0] = (1 - as) * dsw;
     873                swf[0] = (1.0 - as) * dsw;
    868874        }
    869875        else{ // sw radation is absorbed at depth within the glacier
     
    884890                        // convert effective radius [mm] to grain size [m]
    885891                        gsz=xNew<IssmDouble>(m);
    886                         for(int i=0;i<m;i++) gsz[i]= (re[i] * 2) / 1000;
     892                        for(int i=0;i<m;i++) gsz[i]= (re[i] * 2.0) / 1000.0;
    887893
    888894                        // Spectral fractions [0.3-0.8um 0.8-1.5um 1.5-2.8um]
     
    894900                        B2_cum=xNew<IssmDouble>(m+1);
    895901                        for(int i=0;i<m+1;i++){
    896                                 B1_cum[i]=1;
    897                                 B2_cum[i]=1;
     902                                B1_cum[i]=1.0;
     903                                B2_cum[i]=1.0;
    898904                        }
    899905
     
    901907                        // spectral albedos:
    902908                        // 0.3 - 0.8um
    903                         IssmDouble a0 = fmin(0.98, 1 - 1.58 *pow(gsz[0],0.5));
     909                        IssmDouble a0 = fmin(0.98, 1.0 - 1.58 *pow(gsz[0],0.5));
    904910                        // 0.8 - 1.5um
    905                         IssmDouble a1 = fmax(0, 0.95 - 15.4 *pow(gsz[0],0.5));
     911                        IssmDouble a1 = fmax(0.0, 0.95 - 15.4 *pow(gsz[0],0.5));
    906912                        // 1.5 - 2.8um
    907913                        IssmDouble a2 = fmax(0.127, 0.88 + 346.3*gsz[0] - 32.31*pow(gsz[0],0.5));
     
    909915                        // separate net shortwave radiative flux into spectral ranges
    910916                        IssmDouble swfS[3];
    911                         swfS[0] = (sF[0] * dsw) * (1 - a0);
    912                         swfS[1] = (sF[1] * dsw) * (1 - a1);
    913                         swfS[2] = (sF[2] * dsw) * (1 - a2);
     917                        swfS[0] = (sF[0] * dsw) * (1.0 - a0);
     918                        swfS[1] = (sF[1] * dsw) * (1.0 - a1);
     919                        swfS[2] = (sF[2] * dsw) * (1.0 - a2);
    914920
    915921                        // absorption coeficient for spectral range:
     
    918924                        B2 =xNew<IssmDouble>(m);
    919925                        for(int i=0;i<m;i++) h[i]= d[i] /(pow(gsz[i],0.5));
    920                         for(int i=0;i<m;i++) B1[i] = .0192 * h[i];                 // 0.3 - 0.8um
    921                         for(int i=0;i<m;i++) B2[i]= .1098 * h[i];                 // 0.8 - 1.5um
     926                        for(int i=0;i<m;i++) B1[i] = 0.0192 * h[i];                 // 0.3 - 0.8um
     927                        for(int i=0;i<m;i++) B2[i]= 0.1098 * h[i];                 // 0.8 - 1.5um
    922928                        // B3 = +inf                     // 1.5 - 2.8um
    923929
     
    986992
    987993                        // calculate surface shortwave radiation fluxes [W m-2]
    988                         IssmDouble swf_s = SWs * (1 - as) * dsw;
     994                        IssmDouble swf_s = SWs * (1.0 - as) * dsw;
    989995
    990996                        // calculate surface shortwave radiation fluxes [W m-2]
    991                         IssmDouble swf_ss = (1-SWs) * (1 - as) * dsw;
     997                        IssmDouble swf_ss = (1.0-SWs) * (1.0 - as) * dsw;
    992998
    993999                        // SW allowed to penetrate into snowpack
    994                         IssmDouble Bs = 10;    // snow SW extinction coefficient [m-1] (Bassford,2006)
     1000                        IssmDouble Bs = 10.0;    // snow SW extinction coefficient [m-1] (Bassford,2006)
    9951001                        IssmDouble Bi = 1.3;   // ice SW extinction coefficient [m-1] (Bassford,2006)
    9961002
    9971003                        // calculate extinction coefficient B [m-1] vector
    9981004                        B=xNew<IssmDouble>(m);
    999                         for(int i=0;i<m;i++) B[i] = Bs + (300 - d[i]) * ((Bs - Bi)/(910 - 300));
     1005                        for(int i=0;i<m;i++) B[i] = Bs + (300.0 - d[i]) * ((Bs - Bi)/(dIce - 300.0));
    10001006
    10011007                        // cumulative extinction factor
     
    10041010                        for(int i=0;i<m;i++)exp_B[i]=exp(-B[i]*dz[i]);
    10051011
    1006                         B_cum[0]=1;
     1012                        B_cum[0]=1.0;
    10071013                        for(int i=0;i<m;i++){
    10081014                                IssmDouble cum_B=exp_B[0];
     
    10321038
    10331039} /*}}}*/
    1034 void accumulation(IssmDouble** pT, IssmDouble** pdz, IssmDouble** pd, IssmDouble** pW, IssmDouble** pa, IssmDouble** pre, IssmDouble** pgdn, IssmDouble** pgsp, int* pm, IssmDouble T_air, IssmDouble P, IssmDouble dzMin, IssmDouble aSnow, int sid){ /*{{{*/
     1040void accumulation(IssmDouble** pT, IssmDouble** pdz, IssmDouble** pd, IssmDouble** pW, IssmDouble** pa, IssmDouble** pre, IssmDouble** pgdn, IssmDouble** pgsp, int* pm, IssmDouble T_air, IssmDouble P, IssmDouble dzMin, IssmDouble aSnow, IssmDouble dIce, int sid){ /*{{{*/
    10351041
    10361042        // Adds precipitation and deposition to the model grid
     
    10511057        // MAIN FUNCTION
    10521058        // specify constants
    1053         const IssmDouble dIce = 910;     // density of ice [kg m-3]
    10541059        const IssmDouble dSnow = 150;    // density of snow [kg m-3]
    10551060        const IssmDouble reNew = 0.1;    // new snow grain size [mm]
    1056         const IssmDouble gdnNew = 1;     // new snow dendricity
     1061        const IssmDouble gdnNew = 1.0;     // new snow dendricity
    10571062        const IssmDouble gspNew = 0.5;   // new snow sphericity
    10581063
     
    10601065        IssmDouble* mInit=NULL;
    10611066        bool        top=true;
    1062         IssmDouble  mass, massinit, mass_diff;
     1067        IssmDouble  mass=0;
     1068        IssmDouble  massinit=0;
     1069        IssmDouble  mass_diff=0;
    10631070
    10641071        /*output: */
     
    10711078        IssmDouble* gdn=NULL;
    10721079        IssmDouble* gsp=NULL;
    1073         int         m;
     1080        int         m=0;
    10741081
    10751082        if(VerboseSmb() && sid==0 && IssmComm::GetRank()==0)_printf0_("   accumulation module\n");
     
    10891096        mInit=xNew<IssmDouble>(m);
    10901097        for(int i=0;i<m;i++) mInit[i]= d[i] * dz[i];
    1091         massinit=0; for(int i=0;i<m;i++)massinit+=mInit[i];
    1092 
    1093         if (P > 0){
     1098        massinit=0.0;
     1099        for(int i=0;i<m;i++)massinit+=mInit[i];
     1100
     1101        if (P > 0.0+Dtol){
    10941102                       
    10951103
    1096                 if (T_air <= 273.15){ // if snow
     1104                if (T_air <= CtoK+Ttol){ // if snow
    10971105
    10981106                        IssmDouble  z_snow = P/dSnow;               // depth of snow
    10991107
    11001108                        // if snow depth is greater than specified min dz, new cell created
    1101                         if (z_snow > dzMin){
     1109                        if (z_snow > dzMin+Dtol){
    11021110
    11031111                                newcell(&T,T_air,top,m); //new cell T
    11041112                                newcell(&dz,z_snow,top,m); //new cell dz
    11051113                                newcell(&d,dSnow,top,m); //new cell d
    1106                                 newcell(&W,0,top,m); //new cell W
     1114                                newcell(&W,0.0,top,m); //new cell W
    11071115                                newcell(&a,aSnow,top,m); //new cell a
    11081116                                newcell(&re,reNew,top,m); //new cell grain size
     
    11371145                          makes the numerics easier.*/
    11381146
    1139                         IssmDouble LF = 0.3345E6;  // latent heat of fusion(J kg-1)
    1140                         IssmDouble CI = 2102;      // specific heat capacity of snow/ice (J kg-1 k-1)
    1141 
    11421147                        // grid cell adjust mass
    11431148                        mass = mInit[0] + P;
     
    11511156
    11521157                        // if d > the density of ice, d = dIce
    1153                         if (d[0] > dIce){
     1158                        if (d[0] > dIce+Dtol){
    11541159                                d[0] = dIce;           // adjust d
    11551160                                dz[0] = mass / d[0];    // dz is adjusted to conserve mass
     
    11631168               
    11641169                #ifndef _HAVE_ADOLC_  //avoid round operation. only check in forward mode.
    1165                 mass_diff = round(mass_diff * 100)/100;
     1170                mass_diff = round(mass_diff * 100.0)/100.0;
    11661171                if (mass_diff > 0) _error_("mass not conserved in accumulation function");
    11671172                #endif
     
    11821187        *pm=m;
    11831188} /*}}}*/
    1184 void melt(IssmDouble* pM, IssmDouble* pR, IssmDouble* pmAdd, IssmDouble* pdz_add, IssmDouble** pT, IssmDouble** pd, IssmDouble** pdz, IssmDouble** pW, IssmDouble** pa, IssmDouble** pre, IssmDouble** pgdn, IssmDouble** pgsp, int* pn, IssmDouble dzMin, IssmDouble zMax, IssmDouble zMin, IssmDouble zTop, int sid){ /*{{{*/
     1189void melt(IssmDouble* pM, IssmDouble* pR, IssmDouble* pmAdd, IssmDouble* pdz_add, IssmDouble** pT, IssmDouble** pd, IssmDouble** pdz, IssmDouble** pW, IssmDouble** pa, IssmDouble** pre, IssmDouble** pgdn, IssmDouble** pgsp, int* pn, IssmDouble dzMin, IssmDouble zMax, IssmDouble zMin, IssmDouble zTop, IssmDouble dIce, int sid){ /*{{{*/
    11851190
    11861191        //// MELT ROUTINE
     
    12001205        IssmDouble* F=NULL;
    12011206        IssmDouble* flxDn=NULL;
    1202         IssmDouble  ER=0;
     1207        IssmDouble  ER=0.0;
    12031208        IssmDouble* EI=NULL;
    12041209        IssmDouble* EW=NULL;
     
    12061211        int*       D=NULL;
    12071212       
    1208         IssmDouble sumM;
    1209         IssmDouble sumER;
    1210         IssmDouble addE;
    1211         IssmDouble mSum0;
    1212         IssmDouble sumE0;
    1213         IssmDouble mSum1;
    1214         IssmDouble sumE1;
    1215         IssmDouble dE;
    1216         IssmDouble dm;
    1217         IssmDouble X;
    1218         IssmDouble Wi;
     1213        IssmDouble sumM=0.0;
     1214        IssmDouble sumER=0.0;
     1215        IssmDouble addE=0.0;
     1216        IssmDouble mSum0=0.0;
     1217        IssmDouble sumE0=0.0;
     1218        IssmDouble mSum1=0.0;
     1219        IssmDouble sumE1=0.0;
     1220        IssmDouble dE=0.0;
     1221        IssmDouble dm=0.0;
     1222        IssmDouble X=0.0;
     1223        IssmDouble Wi=0.0;
    12191224   
    1220         IssmDouble Ztot;
    1221         IssmDouble T_bot;
    1222         IssmDouble m_bot;
    1223         IssmDouble dz_bot;
    1224         IssmDouble d_bot;
    1225         IssmDouble W_bot;
    1226         IssmDouble a_bot;
    1227         IssmDouble re_bot;
    1228         IssmDouble gdn_bot;
    1229         IssmDouble gsp_bot;
    1230         IssmDouble EI_bot;
    1231         IssmDouble EW_bot;
     1225        IssmDouble Ztot=0.0;
     1226        IssmDouble T_bot=0.0;
     1227        IssmDouble m_bot=0.0;
     1228        IssmDouble dz_bot=0.0;
     1229        IssmDouble d_bot=0.0;
     1230        IssmDouble W_bot=0.0;
     1231        IssmDouble a_bot=0.0;
     1232        IssmDouble re_bot=0.0;
     1233        IssmDouble gdn_bot=0.0;
     1234        IssmDouble gsp_bot=0.0;
     1235        IssmDouble EI_bot=0.0;
     1236        IssmDouble EW_bot=0.0;
    12321237        bool        top=false;
    12331238   
     
    12351240        IssmDouble* dzMin2=NULL;
    12361241        IssmDouble zY2=1.025;
    1237         bool lastCellFlag;
     1242        bool lastCellFlag = false;
    12381243        int X1=0;
    12391244        int X2=0;
    12401245   
    1241         int        D_size;
     1246        int        D_size = 0;
    12421247
    12431248        /*outputs:*/
    1244         IssmDouble  mAdd;
    1245         IssmDouble dz_add;
    1246         IssmDouble  Rsum;
     1249        IssmDouble  mAdd = 0.0;
     1250        IssmDouble dz_add = 0.0;
     1251        IssmDouble  Rsum = 0.0;
    12471252        IssmDouble* T=*pT;
    12481253        IssmDouble* d=*pd;
     
    12541259        IssmDouble* gsp=*pgsp;
    12551260        int         n=*pn;
    1256         IssmDouble* R=0;
     1261        IssmDouble* R=NULL;
    12571262       
    12581263        if(VerboseSmb() && sid==0 && IssmComm::GetRank()==0)_printf0_("   melt module\n");
     
    12651270        dW=xNew<IssmDouble>(n);
    12661271
    1267         // specify constants
    1268         const IssmDouble CtoK = 273.15;  // clecius to Kelvin conversion
    1269         const IssmDouble CI = 2102;      // specific heat capacity of snow/ice (J kg-1 k-1)
    1270         const IssmDouble LF = 0.3345E6;  // latent heat of fusion(J kg-1)
    1271         const IssmDouble dPHC = 830;     // pore hole close off density[kg m-3]
    1272         const IssmDouble dIce = 910;     // density of ice [kg m-3]
    1273 
    12741272        // store initial mass [kg] and energy [J]
    12751273        m=xNew<IssmDouble>(n); for(int i=0;i<n;i++) m[i] = dz[i]* d[i];                    // grid cell mass [kg]
     
    12811279
    12821280        // initialize melt and runoff scalars
    1283         Rsum = 0;       // runoff [kg]
    1284         sumM = 0;       // total melt [kg]
    1285         mAdd = 0;       // mass added/removed to/from base of model [kg]
    1286         addE = 0;       // energy added/removed to/from base of model [J]
    1287         dz_add=0;      // thickness of the layer added/removed to/from base of model [m]
     1281        Rsum = 0.0;       // runoff [kg]
     1282        sumM = 0.0;       // total melt [kg]
     1283        mAdd = 0.0;       // mass added/removed to/from base of model [kg]
     1284        addE = 0.0;       // energy added/removed to/from base of model [J]
     1285        dz_add=0.0;      // thickness of the layer added/removed to/from base of model [m]
    12881286
    12891287        // calculate temperature excess above 0 deg C
    12901288        exsT=xNewZeroInit<IssmDouble>(n);
    1291         for(int i=0;i<n;i++) exsT[i]= fmax(0, T[i] - CtoK);        // [K] to [°C]
     1289        for(int i=0;i<n;i++) exsT[i]= fmax(0.0, T[i] - CtoK);        // [K] to [degC]
    12921290
    12931291        // new grid point center temperature, T [K]
    1294         for(int i=0;i<n;i++) T[i]-=exsT[i];
    1295 
     1292        //for(int i=0;i<n;i++) T[i]-=exsT[i];
     1293        for(int i=0;i<n;i++) T[i]=fmin(T[i],CtoK);
     1294       
    12961295        // specify irreducible water content saturation [fraction]
    12971296        const IssmDouble Swi = 0.07;                     // assumed constant after Colbeck, 1974
     
    12991298        //// REFREEZE PORE WATER
    13001299        // check if any pore water
    1301         if (cellsum(W,n) > 0){
     1300        if (cellsum(W,n) >0.0+Wtol){
    13021301                if(VerboseSmb() && sid==0 && IssmComm::GetRank()==0)_printf0_("      pore water refreeze\n");
    13031302                // calculate maximum freeze amount, maxF [kg]
    1304                 for(int i=0;i<n;i++) maxF[i] = fmax(0, -((T[i] - CtoK) * m[i] * CI) / LF);
     1303                for(int i=0;i<n;i++) maxF[i] = fmax(0.0, -((T[i] - CtoK) * m[i] * CI) / LF);
    13051304
    13061305                // freeze pore water and change snow/ice properties
     
    13191318        exsW=xNew<IssmDouble>(n);
    13201319        for(int i=0;i<n;i++){
    1321                 Wi= (910 - d[i]) * Swi * (m[i] / d[i]);        // irreducible water content [kg]
    1322                 exsW[i] = fmax(0, W[i] - Wi);                  // water "squeezed" from snow [kg]
     1320                Wi= (dIce - d[i]) * Swi * (m[i] / d[i]);        // irreducible water content [kg]
     1321                exsW[i] = fmax(0.0, W[i] - Wi);                  // water "squeezed" from snow [kg]
    13231322        }
    13241323
     
    13261325
    13271326        // run melt algorithm if there is melt water or excess pore water
    1328         if ((cellsum(exsT,n) > 0) || (cellsum(exsW,n) > 0)){
     1327        if ((cellsum(exsT,n) > 0.0 + Ttol) || (cellsum(exsW,n) > 0.0 + Wtol)){
    13291328                // _printf_(""MELT OCCURS");
    13301329                // check to see if thermal energy exceeds energy to melt entire cell
     
    13321331                // (maximum T of snow before entire grid cell melts is a constant
    13331332                // LF/CI = 159.1342)
    1334                 surpT=xNew<IssmDouble>(n); for(int i=0;i<n;i++)surpT[i] = fmax(0, exsT [i]- 159.1342);
    1335        
    1336                 if (cellsum(surpT,n) > 0 ){
     1333                surpT=xNew<IssmDouble>(n); for(int i=0;i<n;i++)surpT[i] = fmax(0.0, exsT[i]- 159.1342);
     1334       
     1335                if (cellsum(surpT,n) > 0.0 + Ttol ){
    13371336                        // _printf_("T Surplus");
    13381337                        // calculate surplus energy
     
    13401339           
    13411340                        int i = 0;
    1342                         while (cellsum(surpE,n) > 0){
     1341                        while (cellsum(surpE,n) > 0.0 + Ttol){
    13431342                                // use surplus energy to increase the temperature of lower cell
    13441343                                T[i+1] = surpE[i]/m[i+1]/CI + T[i+1];
    13451344               
    1346                                 exsT[i+1] = fmax(0, T[i+1] - CtoK) + exsT[i+1];
     1345                                exsT[i+1] = fmax(0.0, T[i+1] - CtoK) + exsT[i+1];
    13471346                                T[i+1] = fmin(CtoK, T[i+1]);
    13481347               
    1349                                 surpT[i+1] = fmax(0, exsT[i+1] - 159.1342);
     1348                                surpT[i+1] = fmax(0.0, exsT[i+1] - 159.1342);
    13501349                                surpE[i+1] = surpT[i+1] * CI * m[i+1];
    13511350               
    13521351                                // adjust current cell properties (again 159.1342 is the max T)
    13531352                                exsT[i] = 159.1342;
    1354                                 surpE[i] = 0;
     1353                                surpE[i] = 0.0;
    13551354                                i = i + 1;
    13561355                        }
     
    13621361
    13631362                // calculate maximum refreeze amount, maxF [kg]
    1364                 for(int i=0;i<n;i++)maxF[i] = fmax(0, -((T[i] - CtoK) * d[i] * dz[i] * CI)/ LF);
     1363                for(int i=0;i<n;i++)maxF[i] = fmax(0.0, -((T[i] - CtoK) * d[i] * dz[i] * CI)/ LF);
    13651364
    13661365                // initialize refreeze, runoff, flxDn and dW vectors [kg]
     
    13681367                IssmDouble* R=xNewZeroInit<IssmDouble>(n);
    13691368
    1370                 for(int i=0;i<n;i++)dW[i] = 0;
     1369                for(int i=0;i<n;i++)dW[i] = 0.0;
    13711370                flxDn=xNewZeroInit<IssmDouble>(n+1); for(int i=0;i<n;i++)flxDn[i+1]=F[i];
    13721371
     
    13741373                X = 0;
    13751374                for(int i=n-1;i>=0;i--){
    1376                         if(M[i]>0 || reCast<int,IssmDouble>(exsW[i])){
     1375                        if(M[i]>0.0+Wtol || exsW[i]>0.0+Wtol){
    13771376                                X=i;
    13781377                                break;
     
    13861385
    13871386                        // break loop if there is no meltwater and if depth is > mw_depth
    1388                         if (inM == 0 && i > X){
     1387                        if (inM == 0.0 && i > X){
    13891388                                break;
    13901389                        }
    13911390
    13921391                        // if reaches impermeable ice layer all liquid water runs off (R)
    1393                         else if (d[i] >= dIce){  // dPHC = pore hole close off [kg m-3]
     1392                        else if (d[i] >= dIce-Dtol){  // dPHC = pore hole close off [kg m-3]
    13941393                                // _printf_("ICE LAYER");
    13951394                                // no water freezes in this cell
     
    13981397
    13991398                                m[i] = m[i] - M[i];                     // mass after melt
    1400                                 Wi = (910-d[i]) * Swi * (m[i]/d[i]);    // irreducible water
     1399                                Wi = (dIce-d[i]) * Swi * (m[i]/d[i]);    // irreducible water
    14011400                                dW[i] = fmin(inM, Wi - W[i]);            // change in pore water
    1402                                 R[i] = fmax(0, inM - dW[i]);             // runoff
     1401                                R[i] = fmax(0.0, inM - dW[i]);             // runoff
    14031402                        }
    14041403                        // check if no energy to refreeze meltwater
    1405                         else if (maxF[i] == 0){
     1404                        else if (fabs(maxF[i]) < Dtol){
    14061405                                // _printf_("REFREEZE == 0");
    14071406                                // no water freezes in this cell
     
    14091408
    14101409                                m[i] = m[i] - M[i];                     // mass after melt
    1411                                 Wi = (910-d[i]) * Swi * (m[i]/d[i]);    // irreducible water
     1410                                Wi = (dIce-d[i]) * Swi * (m[i]/d[i]);    // irreducible water
    14121411                                dW[i] = fmin(inM, Wi-W[i]);              // change in pore water
    1413                                 flxDn[i+1] = fmax(0, inM-dW[i]);         // meltwater out
    1414                                 F[i] = 0;                               // no freeze
     1412                                flxDn[i+1] = fmax(0.0, inM-dW[i]);         // meltwater out
     1413                                F[i] = 0.0;                               // no freeze
    14151414                        }
    14161415                        // some or all meltwater refreezes
     
    14261425
    14271426                                //-----------------------pore water-----------------------------
    1428                                 Wi = (910-d[i])* Swi * dz_0;            // irreducible water
     1427                                Wi = (dIce-d[i])* Swi * dz_0;            // irreducible water
    14291428                                dW[i] = fmin(inM - F1, Wi-W[i]);         // change in pore water
    1430                                 if (-dW[i]>W[i] ){
    1431                                         dW[i]= W[i];
     1429                                if (-1*dW[i]>W[i]-Wtol ){
     1430                                        dW[i]= -1*W[i];
    14321431                                }
    1433                                 IssmDouble F2 = 0;                                 
    1434 
    1435                                 if (dW[i] < 0){                         // excess pore water
     1432                                IssmDouble F2 = 0.0;                                 
     1433
     1434                                if (dW[i] < 0.0-Wtol){                         // excess pore water
    14361435                                        dMax = (dIce - d[i])*dz_0;          // maximum refreeze                                             
    14371436                                        IssmDouble maxF2 = fmin(dMax, maxF[i]-F1);      // maximum refreeze
    1438                                         F2 = fmin(-dW[i], maxF2);            // pore water refreeze
     1437                                        F2 = fmin(-1*dW[i], maxF2);            // pore water refreeze
    14391438                                        m[i] = m[i] + F2;                   // mass after refreeze
    14401439                                        d[i] = m[i]/dz_0;
     
    14461445
    14471446                                // check if an ice layer forms
    1448                                 if (d[i] == dIce){
     1447                                if (fabs(d[i] - dIce) < Dtol){
    14491448                                        // _printf_("ICE LAYER FORMS");
    14501449                                        // excess water runs off
    14511450                                        R[i] = flxDn[i+1];
    14521451                                        // no water percolates to lower cell
    1453                                         flxDn[i+1] = 0;
     1452                                        flxDn[i+1] = 0.0;
    14541453                                }
    14551454                        }
     
    14581457
    14591458                //// GRID CELL SPACING AND MODEL DEPTH
    1460                 for(int i=0;i<n;i++)if (W[i] < 0) _error_("negative pore water generated in melt equations");
     1459                for(int i=0;i<n;i++)if (W[i] < 0.0 - Wtol) _error_("negative pore water generated in melt equations");
    14611460               
    14621461                // delete all cells with zero mass
     
    14651464
    14661465                // delete all cells with zero mass
    1467                 D_size=0; for(int i=0;i<n;i++)if(m[i]!=0)D_size++; D=xNew<int>(D_size);
     1466                D_size=0; for(int i=0;i<n;i++)if(m[i]!=0)D_size++;
     1467                D=xNew<int>(D_size);
    14681468                D_size=0; for(int i=0;i<n;i++)if(m[i]!=0){ D[D_size] = i; D_size++;}
    14691469               
     
    15041504   
    15051505        for (int i=0;i<n;i++){
    1506                 if (Zcum[i]<=zTop){
     1506                if (Zcum[i]<=zTop+Dtol){
    15071507                        dzMin2[i]=dzMin;
    15081508                }
     
    15151515        X = 0;
    15161516        for(int i=n-1;i>=0;i--){
    1517                 if(dz[i]<dzMin2[i]){
     1517                if(dz[i]<dzMin2[i]-Dtol){
    15181518                        X=i;
    15191519                        break;
     
    15311531
    15321532        for (int i = 0; i<=X;i++){
    1533                 if (dz [i] < dzMin2[i]){                              // merge top cells
     1533                if (dz[i] < dzMin2[i]-Dtol){                              // merge top cells
    15341534                        // _printf_("dz > dzMin * 2')
    15351535                        // adjust variables as a linearly weighted function of mass
     
    15421542           
    15431543                        // merge with underlying grid cell and delete old cell
    1544                         dz [i+1] = dz[i] + dz[i+1];                 // combine cell depths
     1544                        dz[i+1] = dz[i] + dz[i+1];                 // combine cell depths
    15451545                        d[i+1] = m_new / dz[i+1];                   // combine top densities
    15461546                        W[i+1] = W[i+1] + W[i];                     // combine liquid water
     
    15721572       
    15731573                // merge with underlying grid cell and delete old cell
    1574                 dz [X1] = dz[X2] + dz[X1];                 // combine cell depths
     1574                dz[X1] = dz[X2] + dz[X1];                 // combine cell depths
    15751575                d[X1] = m_new / dz[X1];                   // combine top densities
    15761576                W[X1] = W[X1] + W[X2];                     // combine liquid water
     
    15821582
    15831583        // delete combined cells
    1584         D_size=0; for(int i=0;i<n;i++)if(m[i]!=99999)D_size++; D=xNew<int>(D_size);
     1584        D_size=0; for(int i=0;i<n;i++)if(m[i]!=99999)D_size++;
     1585        D=xNew<int>(D_size);
    15851586        D_size=0; for(int i=0;i<n;i++)if(m[i]!=99999){ D[D_size] = i; D_size++;}
    15861587
     
    16021603        X=0;
    16031604        for(int i=9;i>=0;i--){
    1604                 if(dz[i]> 2* dzMin){
     1605                if(dz[i]> 2.0*dzMin+Dtol){
    16051606                        X=i;
    16061607                        break;
     
    16081609        }
    16091610       
    1610         int i=0;
    1611         while(i<=X){
    1612                 if (dz [i] > dzMin *2){
     1611        int j=0;
     1612        while(j<=X){
     1613                if (dz[j] > dzMin*2.0+Dtol){
    16131614
    16141615                                // _printf_("dz > dzMin * 2");
    16151616                                // split in two
    1616                                 cellsplit(&dz, n, i,.5);
    1617                                 cellsplit(&W, n, i,.5);
    1618                                 cellsplit(&m, n, i,.5);
    1619                                 cellsplit(&T, n, i,1.0);
    1620                                 cellsplit(&d, n, i,1.0);
    1621                                 cellsplit(&a, n, i,1.0);
    1622                                 cellsplit(&EI, n, i,1.0);
    1623                                 cellsplit(&EW, n, i,1.0);
    1624                                 cellsplit(&re, n, i,1.0);
    1625                                 cellsplit(&gdn, n, i,1.0);
    1626                                 cellsplit(&gsp, n, i,1.0);
     1617                                cellsplit(&dz, n, j,.5);
     1618                                cellsplit(&W, n, j,.5);
     1619                                cellsplit(&m, n, j,.5);
     1620                                cellsplit(&T, n, j,1.0);
     1621                                cellsplit(&d, n, j,1.0);
     1622                                cellsplit(&a, n, j,1.0);
     1623                                cellsplit(&EI, n, j,1.0);
     1624                                cellsplit(&EW, n, j,1.0);
     1625                                cellsplit(&re, n, j,1.0);
     1626                                cellsplit(&gdn, n, j,1.0);
     1627                                cellsplit(&gsp, n, j,1.0);
    16271628                                n++;
    16281629                                X=X+1;
    16291630                }
    1630                 else i++;
     1631                else j++;
    16311632        }
    16321633
     
    16371638        Ztot = cellsum(dz,n);
    16381639   
    1639         if (Ztot < zMin){
     1640        if (Ztot < zMin-Dtol){
    16401641                // printf("Total depth < zMin %f \n", Ztot);
    16411642                // mass and energy to be added
     
    16711672                n=n+1;
    16721673        }
    1673         else if (Ztot > zMax){
     1674        else if (Ztot > zMax+Dtol){
    16741675                // printf("Total depth > zMax %f \n", Ztot);
    16751676                // mass and energy loss
     
    17101711
    17111712        /*checks: */
    1712         for(int i=0;i<n;i++) if (W[i]<0) _error_("negative pore water generated in melt equations\n");
     1713        for(int i=0;i<n;i++) if (W[i]<0.0-Wtol) _error_("negative pore water generated in melt equations\n");
    17131714       
    17141715        /*only in forward mode! avoid round in AD mode as it is not differentiable: */
     
    17531754
    17541755} /*}}}*/
    1755 void densification(IssmDouble* d,IssmDouble* dz, IssmDouble* T, IssmDouble* re, int denIdx, IssmDouble C, IssmDouble dt, IssmDouble Tmean,IssmDouble dIce, int m, int sid){ /*{{{*/
     1756void densification(IssmDouble* d,IssmDouble* dz, IssmDouble* T, IssmDouble* re, int denIdx, IssmDouble C, IssmDouble dt, IssmDouble Tmean, IssmDouble dIce, int m, int sid){ /*{{{*/
    17561757
    17571758        //// THIS NEEDS TO BE DOUBLE CHECKED AS THERE SEAMS TO BE LITTLE DENSIFICATION IN THE MODEL OUTOUT [MAYBE COMPATION IS COMPNSATED FOR BY TRACES OF SNOW???]
     
    17951796        //// MAIN FUNCTION
    17961797        // specify constants
    1797         dt      = dt / 86400;  // convert from [s] to [d]
     1798        dt      = dt / dts;  // convert from [s] to [d]
    17981799        // R     = 8.314        // gas constant [mol-1 K-1]
    17991800        // Ec    = 60           // activation energy for self-diffusion of water
     
    18021803
    18031804        /*intermediary: */
    1804         IssmDouble c0,c1,H;
     1805        IssmDouble c0=0.0;
     1806        IssmDouble c1=0.0;
     1807        IssmDouble H=0.0;
    18051808       
    18061809        if(VerboseSmb() && sid==0 && IssmComm::GetRank()==0)_printf0_("   densification module\n");
     
    18151818
    18161819        IssmDouble* obp = xNew<IssmDouble>(m);
    1817         obp[0]=0;
     1820        obp[0]=0.0;
    18181821        for(int i=1;i<m;i++)obp[i]=cumdz[i-1]*d[i-1];
    18191822       
     
    18261829                switch (denIdx){
    18271830                        case 1: // Herron and Langway (1980)
    1828                                 c0 = (11 * exp(-10160 / (T[i] * 8.314))) * C/1000;
    1829                                 c1 = (575 * exp(-21400 / (T[i]* 8.314))) * pow(C/1000,.5);
     1831                                c0 = (11.0 * exp(-10160.0 / (T[i] * 8.314))) * C/1000.0;
     1832                                c1 = (575.0 * exp(-21400.0 / (T[i]* 8.314))) * pow(C/1000.0,.5);
    18301833                                break;
    18311834                        case 2: // Arthern et al. (2010) [semi-emperical]
    18321835                                // common variable
    18331836                                // NOTE: Ec=60000, Eg=42400 (i.e. should be in J not kJ)
    1834                                 H = exp((-60000./(T[i] * 8.314)) + (42400./(Tmean * 8.314))) * (C * 9.81);
     1837                                H = exp((-60000.0/(T[i] * 8.314)) + (42400.0/(Tmean * 8.314))) * (C * 9.81);
    18351838                                c0 = 0.07 * H;
    18361839                                c1 = 0.03 * H;
     
    18401843
    18411844                                // common variable
    1842                                 H = exp((-60/(T[i] * 8.314))) * obp[i] / pow(re[i]/1000,2.0);
     1845                                H = exp((-60.0/(T[i] * 8.314))) * obp[i] / pow(re[i]/1000.0,2.0);
    18431846                                c0 = 9.2e-9 * H;
    18441847                                c1 = 3.7e-9 * H;
     
    18461849
    18471850                        case 4: // Li and Zwally (2004)
    1848                                 c0 = (C/dIce) * (139.21 - 0.542*Tmean)*8.36*pow(273.15 - T[i],-2.061);
     1851                                c0 = (C/dIce) * (139.21 - 0.542*Tmean)*8.36*pow(CtoK - T[i],-2.061);
    18491852                                c1 = c0;
    18501853                                break;
     
    18521855                        case 5: // Helsen et al. (2008)
    18531856                                // common variable
    1854                                 c0 = (C/dIce) * (76.138 - 0.28965*Tmean)*8.36*pow(273.15 - T[i],-2.061);
     1857                                c0 = (C/dIce) * (76.138 - 0.28965*Tmean)*8.36*pow(CtoK - T[i],-2.061);
    18551858                                c1 = c0;
    18561859                                break;
     
    18581861
    18591862                // new snow density
    1860                 if(d[i] <= 550) d[i] = d[i] + (c0 * (dIce - d[i]) / 365 * dt);
    1861                 else            d[i] = d[i] + (c1 * (dIce - d[i]) / 365 * dt);
     1863                if(d[i] <= 550.0+Dtol) d[i] = d[i] + (c0 * (dIce - d[i]) / 365.0 * dt);
     1864                else            d[i] = d[i] + (c1 * (dIce - d[i]) / 365.0 * dt);
    18621865
    18631866                //disp((num2str(nanmean(c0 .* (dIce - d(idx)) / 365 * dt))))
    18641867
    18651868                // do not allow densities to exceed the density of ice
    1866                 if(d[i]>dIce)d[i]=dIce;
     1869                if(d[i] > dIce-Dtol) d[i]=dIce;
    18671870
    18681871                // calculate new grid cell length
     
    18761879
    18771880} /*}}}*/
    1878 void turbulentFlux(IssmDouble* pshf, IssmDouble* plhf, IssmDouble* pEC, IssmDouble Ta, IssmDouble Ts, IssmDouble V, IssmDouble eAir, IssmDouble pAir, IssmDouble ds, IssmDouble Ws, IssmDouble Vz, IssmDouble Tz, int sid){ /*{{{*/
     1881void turbulentFlux(IssmDouble* pshf, IssmDouble* plhf, IssmDouble* pEC, IssmDouble Ta, IssmDouble Ts, IssmDouble V, IssmDouble eAir, IssmDouble pAir, IssmDouble ds, IssmDouble Ws, IssmDouble Vz, IssmDouble Tz, IssmDouble dIce, int sid){ /*{{{*/
    18791882
    18801883        //// TURBULENT HEAT FLUX
     
    18991902        //   Tz: height above ground at which temperature (T) was sampled [m]
    19001903
    1901         //// FUNCTION INITILIZATION
    1902 
    1903         // CA = 1005;                    // heat capacity of air (J kg-1 k-1)
    1904         // LF = 0.3345E6;                // latent heat of fusion(J kg-1)
    1905         // LV = 2.495E6;                 // latent heat of vaporization(J kg-1)
    1906         // dIce = 910;                   // density of ice [kg m-3]
    1907        
    19081904        /*intermediary:*/
    1909         IssmDouble d_air;
    1910         IssmDouble Ri;
    1911         IssmDouble z0;
    1912         IssmDouble coef_M,coef_H;
    1913         IssmDouble An, C;
    1914         IssmDouble L, eS;
     1905        IssmDouble d_air=0.0;
     1906        IssmDouble Ri=0.0;
     1907        IssmDouble z0=0.0;
     1908        IssmDouble coef_M=0.0;
     1909        IssmDouble coef_H=0.0;
     1910        IssmDouble An=0.0;
     1911        IssmDouble C=0.0;
     1912        IssmDouble L=0.0;
     1913        IssmDouble eS=0.0;
    19151914
    19161915        /*output: */
    1917         IssmDouble shf, lhf, EC;
     1916        IssmDouble shf=0.0;
     1917        IssmDouble lhf=0.0;
     1918        IssmDouble EC=0.0;
    19181919       
    19191920        if(VerboseSmb() && sid==0 && IssmComm::GetRank()==0)_printf0_("   turbulentFlux module\n");
    19201921
    19211922        // calculated air density [kg/m3]
    1922         d_air = 0.029 * pAir /(8.314 * Ta);
     1923        d_air = 0.029 * pAir /(R * Ta);
    19231924
    19241925        //// Determine Surface Roughness
    19251926        // Bougamont, 2006
    19261927        // wind/temperature surface roughness height [m]
    1927         if (ds < 910 && Ws == 0) z0 = 0.00012;               // 0.12 mm for dry snow
    1928         else if (ds >= 910) z0 = 0.0032;                // 3.2 mm for ice
     1928        if (ds < dIce-Dtol && fabs(Ws) < Wtol) z0 = 0.00012;               // 0.12 mm for dry snow
     1929        else if (ds >= dIce-Dtol) z0 = 0.0032;                // 3.2 mm for ice
    19291930        else z0 = 0.0013;                // 1.3 mm for wet snow
    19301931
    1931         //// Monin–Obukhov Stability Correction
     1932        //// Monin-Obukhov Stability Correction
    19321933        // Reference:
    19331934        // Ohmura, A., 1982: Climate and Energy-Balance on the Arctic Tundra.
     
    19351936
    19361937        // if V = 0 goes to infinity therfore if V = 0 change
    1937         if(V< .01) V=.01;
     1938        if(V < 0.01) V=0.01;
    19381939
    19391940        // calculate the Bulk Richardson Number (Ri)
    1940         Ri = (2*9.81* (Vz - z0) * (Ta - Ts)) / ((Ta + Ts)* pow(V,2));
    1941 
    1942         // calculate Monin–Obukhov stability factors 'coef_M' and 'coef_H'
     1941        Ri = (2.0*9.81* (Vz - z0) * (Ta - Ts)) / ((Ta + Ts)* pow(V,2));
     1942
     1943        // calculate Monin-Obukhov stability factors 'coef_M' and 'coef_H'
    19431944
    19441945        // do not allow Ri to exceed 0.19
    1945         if(Ri>.19)Ri= 0.19;
     1946        if(Ri>0.19-Ttol)Ri= 0.19;
    19461947
    19471948        // calculate momentum 'coef_M' stability factor
    1948         if (Ri > 0) coef_M = pow(1-5.2*Ri,-1); // if stable
    1949         else coef_M = pow(1-18*Ri,-0.25);
     1949        if (Ri > 0.0) coef_M = pow(1.0-5.2*Ri,-1.0); // if stable
     1950        else coef_M = pow(1.0-18*Ri,-0.25);
    19501951
    19511952        // calculate heat/wind 'coef_H' stability factor
     
    19591960        //// Sensible Heat
    19601961        // calculate the sensible heat flux [W m-2](Patterson, 1998)
    1961         shf = C * 1005 * (Ta - Ts);
    1962 
    1963         // adjust using Monin–Obukhov stability theory
     1962        shf = C * CA * (Ta - Ts);
     1963
     1964        // adjust using Monin-Obukhov stability theory
    19641965        shf = shf / (coef_M * coef_H);
    19651966
     
    19671968        // determine if snow pack is melting & calcualte surface vapour pressure
    19681969        // over ice or liquid water
    1969         if (Ts >= 273.15){
    1970                 L = 2.495E6;
     1970        if (Ts >= CtoK-Ttol){
     1971                L = LV;
    19711972
    19721973                // for an ice surface Murphy and Koop, 2005 [Equation 7]
     
    19741975        }
    19751976        else{
    1976                 L = 2.8295E6; // latent heat of sublimation
     1977                L = LS; // latent heat of sublimation
    19771978                // for liquid surface (assume liquid on surface when Ts == 0 deg C)
    19781979                // Wright (1997), US Meteorological Handbook from Murphy and Koop,
    19791980                // 2005 Apendix A
    1980                 eS = 611.21 * exp(17.502 * (Ts - 273.15) / (240.97 + Ts - 273.15));
     1981                eS = 611.21 * exp(17.502 * (Ts - CtoK) / (240.97 + Ts - CtoK));
    19811982        }
    19821983
     
    19841985        lhf = C * L * (eAir - eS) * 0.622 / pAir;
    19851986
    1986         // adjust using Monin–Obukhov stability theory (if lhf '+' then there is
     1987        // adjust using Monin-Obukhov stability theory (if lhf '+' then there is
    19871988        // energy and mass gained at the surface, if '-' then there is mass and
    19881989        // energy loss at the surface.
     
    19901991
    19911992        // mass loss (-)/acreation(+) due to evaporation/condensation [kg]
    1992         EC = lhf * 86400 / L;
     1993        EC = lhf * dts / L;
    19931994
    19941995        /*assign output poitners: */
  • issm/trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp

    r21469 r22249  
    271271        IssmDouble  h = -1.54e-5;
    272272        IssmDouble  smb,smbref,anomaly,yts,z;
    273    
    274     /* Get constants */
    275     femmodel->parameters->FindParam(&yts,ConstantsYtsEnum);
    276     /*iomodel->FindConstant(&yts,"md.constants.yts");*/
    277     /*this->parameters->FindParam(&yts,ConstantsYtsEnum);*/
    278     /*Mathieu original*/
    279     /*IssmDouble  smb,smbref,z;*/
    280    
     273
     274        /* Get constants */
     275        femmodel->parameters->FindParam(&yts,ConstantsYtsEnum);
     276        /*iomodel->FindConstant(&yts,"md.constants.yts");*/
     277        /*this->parameters->FindParam(&yts,ConstantsYtsEnum);*/
     278        /*Mathieu original*/
     279        /*IssmDouble  smb,smbref,z;*/
     280
    281281        /*Loop over all the elements of this partition*/
    282282        for(int i=0;i<femmodel->elements->Size();i++){
     
    298298                        anomaly = smblistref[v];
    299299
    300             /* Henning edited acc. to Riannes equations*/
    301             /* Set SMB maximum elevation, if dz = 0 -> z_critical = 1675 */
    302             z_critical = z_critical + dz;
    303            
    304             /* Calculate smb acc. to the surface elevation z */
    305             if(z<z_critical){
     300                        /* Henning edited acc. to Riannes equations*/
     301                        /* Set SMB maximum elevation, if dz = 0 -> z_critical = 1675 */
     302                        z_critical = z_critical + dz;
     303
     304                        /* Calculate smb acc. to the surface elevation z */
     305                        if(z<z_critical){
    306306                                smb = a + b*z + c;
    307307                        }
    308308                        else{
    309                           smb = (a + b*z)*(f + g*(z-z_critical) + h*(z-z_critical)*(z-z_critical)) + c;
    310                         }
    311            
     309                                smb = (a + b*z)*(f + g*(z-z_critical) + h*(z-z_critical)*(z-z_critical)) + c;
     310                        }
     311
    312312                        /* Compute smb including anomaly,
    313313                                correct for number of seconds in a year [s/yr]*/
  • issm/trunk-jpl/src/c/modules/SurfaceMassBalancex/SurfaceMassBalancex.h

    r21469 r22249  
    2525IssmDouble Marbouty(IssmDouble T, IssmDouble d, IssmDouble dT);
    2626void grainGrowth(IssmDouble* pre, IssmDouble* pgdn, IssmDouble* pgsp, IssmDouble* T,IssmDouble* dz,IssmDouble* d, IssmDouble* W,IssmDouble smb_dt,int m,int aIdx, int sid);
    27 void albedo(IssmDouble* a,int aIdx, IssmDouble* re, IssmDouble* d, IssmDouble cldFrac, IssmDouble aIce, IssmDouble aSnow, IssmDouble* T, IssmDouble* W, IssmDouble P, IssmDouble EC, IssmDouble t0wet, IssmDouble t0dry, IssmDouble K, IssmDouble dt,int m, int sid);
    28 void shortwave(IssmDouble** pswf, int swIdx, int aIdx, IssmDouble dsw, IssmDouble as, IssmDouble* d, IssmDouble* dz, IssmDouble* re, int m, int sid);
    29 void thermo(IssmDouble* pEC, IssmDouble* T, IssmDouble* dz, IssmDouble* d, IssmDouble* swf, IssmDouble dlw, IssmDouble Ta, IssmDouble V, IssmDouble eAir, IssmDouble pAir, IssmDouble Ws, IssmDouble dt0, int m, IssmDouble Vz, IssmDouble Tz, int sid);
    30 void accumulation(IssmDouble** pT, IssmDouble** pdz, IssmDouble** pd, IssmDouble** pW, IssmDouble** pa, IssmDouble** pre, IssmDouble** pgdn, IssmDouble** pgsp, int* pm, IssmDouble Ta, IssmDouble P, IssmDouble dzMin, IssmDouble aSnow, int sid);
    31 void melt(IssmDouble* pM, IssmDouble* pR, IssmDouble* pmAdd, IssmDouble* pdz_add, IssmDouble** pT, IssmDouble** pd, IssmDouble** pdz, IssmDouble** pW, IssmDouble** pa, IssmDouble** pre, IssmDouble** pgdn, IssmDouble** pgsp, int* pn, IssmDouble dzMin, IssmDouble zMax, IssmDouble zMin, IssmDouble zTop, int sid);
    32 void densification(IssmDouble* d,IssmDouble* dz, IssmDouble* T, IssmDouble* re, int denIdx, IssmDouble C, IssmDouble dt, IssmDouble Tmean,IssmDouble rho_ice,int m, int sid);
    33 void turbulentFlux(IssmDouble* pshf, IssmDouble* plhf, IssmDouble* pEC, IssmDouble Ta, IssmDouble Ts, IssmDouble V, IssmDouble eAir, IssmDouble pAir, IssmDouble ds, IssmDouble Ws, IssmDouble Vz, IssmDouble Tz, int sid);
     27void albedo(IssmDouble* a,int aIdx, IssmDouble* re, IssmDouble* d, IssmDouble cldFrac, IssmDouble aIce, IssmDouble aSnow, IssmDouble* T, IssmDouble* W, IssmDouble P, IssmDouble EC, IssmDouble t0wet, IssmDouble t0dry, IssmDouble K, IssmDouble dt, IssmDouble dIce, int m, int sid);
     28void shortwave(IssmDouble** pswf, int swIdx, int aIdx, IssmDouble dsw, IssmDouble as, IssmDouble* d, IssmDouble* dz, IssmDouble* re, IssmDouble dIce, int m, int sid);
     29void thermo(IssmDouble* pEC, IssmDouble* T, IssmDouble* dz, IssmDouble* d, IssmDouble* swf, IssmDouble dlw, IssmDouble Ta, IssmDouble V, IssmDouble eAir, IssmDouble pAir, IssmDouble Ws, IssmDouble dt0, int m, IssmDouble Vz, IssmDouble Tz, IssmDouble dIce, int sid);
     30void accumulation(IssmDouble** pT, IssmDouble** pdz, IssmDouble** pd, IssmDouble** pW, IssmDouble** pa, IssmDouble** pre, IssmDouble** pgdn, IssmDouble** pgsp, int* pm, IssmDouble Ta, IssmDouble P, IssmDouble dzMin, IssmDouble aSnow, IssmDouble dIce, int sid);
     31void melt(IssmDouble* pM, IssmDouble* pR, IssmDouble* pmAdd, IssmDouble* pdz_add, IssmDouble** pT, IssmDouble** pd, IssmDouble** pdz, IssmDouble** pW, IssmDouble** pa, IssmDouble** pre, IssmDouble** pgdn, IssmDouble** pgsp, int* pn, IssmDouble dzMin, IssmDouble zMax, IssmDouble zMin, IssmDouble zTop, IssmDouble dIce, int sid);
     32void densification(IssmDouble* d,IssmDouble* dz, IssmDouble* T, IssmDouble* re, int denIdx, IssmDouble C, IssmDouble dt, IssmDouble Tmean, IssmDouble dIce, int m, int sid);
     33void turbulentFlux(IssmDouble* pshf, IssmDouble* plhf, IssmDouble* pEC, IssmDouble Ta, IssmDouble Ts, IssmDouble V, IssmDouble eAir, IssmDouble pAir, IssmDouble ds, IssmDouble Ws, IssmDouble Vz, IssmDouble Tz, IssmDouble dIce, int sid);
    3434#endif  /* _SurfaceMassBalancex_H*/
  • issm/trunk-jpl/test/NightlyRun/test243.m

    r21222 r22249  
    4545%Fields and tolerances to track changes
    4646field_names      ={'SmbDz','SmbT' ,'SmbD' ,'SmbRe','SmbGdn','SmbGsp','SmbA' ,'SmbEC','SmbMassBalance'};
    47 field_tolerances ={5e-4,5e-5,0.0006,0.0002,1e-5,0.0003,2e-5,2e-7,1e-7};
     47field_tolerances ={1e-12,1e-12,1e-12,1e-12,1e-12,1e-12,1e-12,1e-12,1e-12};
    4848
    4949field_values={...
Note: See TracChangeset for help on using the changeset viewer.