/Users/huttone/Devel/sedflux-new/sedflux/trunk/ew/hydrotrend/hydrosnow.c

Go to the documentation of this file.
00001 /*
00002  *  HydroSnow.c
00003  *
00004  *  Calculates the daily snow fall or melt for each altitude bin.
00005  *  Also calculates the groundwater flow and time lag due to the snow.
00006  *
00007  *  This needs to be updated with a thermodynamically based routine
00008  *  like SNTHERM or ...
00009  *
00010  *  Author:    M.D. Morehead  (Dec 1998)
00011  *  Author2:   S.D. Peckham   (Dec 2001)
00012  *
00013  * Variable             Def.Location    Type    Units   Usage
00014  * --------             ------------    ----    -----   -----
00015  * err                  various                 int             -               error flag halts program
00016  * ii                   various                 int             -               temporary loop counter
00017  * jj                   various                 int             -               temporary loop counter
00018  * kk                   various                 int             -               temporary loop counter
00019  * shldday[]    HydroSnow.c             double  m^3/s   shoulder discharge array
00020  * Tcorrection  HydroSnow.c             double  degC    melt modifier for rain fall
00021  * melt                 HydroSnow.c             double  m               snow melt on a given day
00022  * Minput               HydroSnow.c             double  m^3/a   snow input in a year
00023  * Mout                 HydroSnow.c             double  m^3/a   snow melt output in a year
00024  * Mwrapin              HydroSnow.c             double  m^3/a   nival discharge from previous year
00025  * Mwrapout             HydroSnow.c             double  m^3/a   nival discharge to next year
00026  * Mgw                  HydroSnow.c             double  m^3/a   total nival discharge put into GW
00027  * Mnival               HydroSnow.c             double  m^3/a   total nival discharge
00028  *
00029  *
00030  *  The ELA index for each year (ELAindex) was found in HydroGlacial.c
00031  *  The FLA index for each day (FLAindex[]) was found in HydroHypsom.c
00032  *  The FLAflag (=9999) indicates the snow line was above the maximum
00033  *  altitude of the basin on that day
00034  *
00035  */
00036 
00037 #include <stdlib.h>
00038 #include "hydroclimate.h"
00039 #include "hydroparams.h"
00040 #include "hydrotimeser.h"
00041 #include "hydroinout.h"
00042 #include "hydrodaysmonths.h"
00043 
00044 /*----------------------
00045  *  Start of HydroSnow
00046  *----------------------*/
00047 int hydrosnow()
00048 {
00049 
00050 /*-------------------
00051  *  Local Variables
00052  *-------------------*/
00053 #ifdef DBG
00054 FILE *fid;
00055 #endif
00056 
00057 int err, ii, jj, kk;
00058 double shldday[maxday], Tcorrection, melt;
00059 double Minput, Mout, Mwrapin, Mwrapout, Mgw, Mnival;
00060 
00061 /*-----------------
00062  *  Set Variables
00063  *-----------------*/
00064 err = 0;
00065 Minput          = 0.0;
00066 Mgw                     = 0.0;
00067 Mnival          = 0.0;
00068 Mout            = 0.0;
00069 MPnival         = 0.0;
00070 Mwrapin         = 0.0;
00071 Mwrapout        = 0.0;
00072 Msnowend        = 0.0;
00073 Msnowstart      = 0.0;
00074 Snowremains     = 0.0;
00075 
00076 /*-----------------------------------------------
00077  *  Make sure the shoulder day arrays are clean
00078  *-----------------------------------------------*/
00079 for( ii=0; ii<maxday; ii++ )
00080    shldday[ii] = 0.0;
00081 
00082 /*----------------------------------------------------
00083  *  Calculate the carryover snow for mass balance.
00084  *  Storing the carryover of snow from previous year
00085  *  is done in HydroHypsom.c
00086  *----------------------------------------------------*/
00087 for( kk=0; kk<nelevbins; kk++ )
00088       Msnowstart += Snowelevday[kk][0] * areabins[kk];
00089 
00090 /*--------------------------------------
00091  *  print out Snow values for checking
00092  *--------------------------------------*/
00093 #ifdef DBG
00094   if( tblstart[ep] <= yr && yr <= tblend[ep] ) {
00095     if( (fid = fopen("hydro.snow1","a+")) == NULL) {
00096       printf("  HydroHypsim ERROR: Unable to open the snow file hydro.snow1 \n");
00097       printf("     non-fatal error, continueing. \n\n");
00098     }
00099     else {
00100       fprintf( fid,"%%\n%%\n%%HydroSnow: Starting Snow array for epoch %d, year %d \n%%\n%%", ep+1, yr );
00101       fprintf( fid,"%%   Elev \t    day \t Snow (m) \n" );
00102       fprintf( fid,"%%   ---- \t  --------- \t ------------ \n" );
00103       for( ii=0; ii<daysiy; ii++ )
00104          for(kk=0; kk<nelevbins; kk++)
00105             fprintf( fid,"%7.1f \t %d \t %f \n", elevbins[kk], ii, Snowelevday[kk][ii] );
00106       fclose(fid);
00107     }
00108   }
00109 #endif
00110 
00111 /*-----------------------------------------------------------
00112  *  Loop through the days adding snowfall
00113  *  Loop through the Temperature Elevation bins looking for
00114  *  potential snowfall.
00115  *  "Snow" only occurs above the FLA and below the ELA
00116  *  everything above the ELA is considered "Ice"
00117  *  Snow is stored in "m" of water equivalent
00118  *-----------------------------------------------------------*/
00119 for( ii=0; ii<daysiy; ii++ )
00120    for( kk=FLAindex[ii]; kk<nelevbins && kk<ELAindex; kk++ )
00121       if( Pdaily[ii] > 0.0 ) {
00122          Snowelevday[kk][ii] += Pdaily[ii];
00123          MPnival += Pdaily[ii]*areabins[kk];
00124       }
00125 
00126 /*--------------------------------------
00127  *  Print out Snow values for checking
00128  *--------------------------------------*/
00129 #ifdef DBG
00130   if( tblstart[ep] <= yr && yr <= tblend[ep] ) {
00131     if( (fid = fopen("hydro.snow2","a+")) == NULL) {
00132       printf("  HydroHypsim ERROR: Unable to open the snow file hydro.snow2 \n");
00133       printf("     non-fatal error, continueing. \n\n");
00134     }
00135     else {
00136       fprintf( fid,"%%\n%%\nHydroSnow: Filled Snow array for epoch %d, year %d \n%%\n%%", ep+1, yr );
00137       fprintf( fid,"%%   Elev \t    day \t Snow (m) \n" );
00138       fprintf( fid,"%%   ---- \t  --------- \t ------------ \n" );
00139       for( ii=0; ii<daysiy; ii++ )
00140          for(kk=0; kk<nelevbins; kk++)
00141             fprintf( fid,"%7.1f \t %d \t %f \n", elevbins[kk], ii, Snowelevday[kk][ii] );
00142       fclose(fid);
00143     }
00144   }
00145 #endif
00146 
00147 /*----------------------------------------------------
00148  *  Loop through the days/elev bins melting snowfall
00149  *----------------------------------------------------*/
00150 for( ii=0; ii<daysiy; ii++ ) {
00151    for( kk=0; kk<ELAindex && kk<nelevbins; kk++ ) {
00152 
00153       /*--------------------------------------------------------
00154        *  Melt snow if T is warm enough (and if there is snow)
00155        *--------------------------------------------------------*/
00156       if( Televday[kk][ii] > 1.0 && Snowelevday[kk][ii] > 0.0 ) {
00157 
00158          /*---------------------------------------------------
00159           *  Snow melt = 1cm/degC  ( -1cm if it is raining )
00160           *  Meltrate  = x m/degC
00161           *  Snow melt = Meltrate * T = m/degC * degC = m
00162           *---------------------------------------------------*/
00163          Tcorrection = 0.0;
00164          if( Pdaily[ii] > 0.0 )
00165             Tcorrection = 1.0;
00166          melt = mn( Meltrate[ep]*(Televday[kk][ii]-Tcorrection), Snowelevday[kk][ii] );
00167 
00168          /*---------------------------------------------------------------------
00169           *  (Mark's version of routing)
00170           *  Add the time lag for the distance up the basin (distbins[elabin])
00171           *---------------------------------------------------------------------*/
00172          Qnival[ii+distbins[kk]]        += melt*areabins[kk]/dTOs;
00173          Snowelevday[kk][ii]            -= melt;
00174       }
00175    }
00176 
00177    /*-------------------------------------------------
00178     *  Check how much snow is remaining on August 31
00179     *-------------------------------------------------*/
00180 //      if( ii == dayendm[7] ) {
00181         if ( ii == end_of(Aug) ) {
00182                 for( kk=0; kk<nelevbins; kk++ )
00183                         Snowremains += Snowelevday[kk][ii]*areabins[kk];
00184 
00185 #ifdef DBG
00186 fprintf( stderr, "\n HydroSnow: \t Snow on August 31 = %e (m^3) \n", Snowremains );
00187 fprintf( fidlog, "\n HydroSnow: \n\n" );
00188 fprintf( fidlog, "\t Snow on August 31 \t\t = %e (m^3) \n", Snowremains );
00189 #endif
00190         if (setstartmeanQandQs == 4)
00191                 if( Snowremains > 1 ) {
00192                         fprintf( stderr, "\n \t HydroSnow Warning: There is Snow remaining on August 31 \n" );
00193                         fprintf( stderr, " \t Snowremains \t = %e (m^3) \n", Snowremains );
00194                         fprintf( stderr, " \t in year: %d \n",yr );
00195                         fprintf( fidlog, "\n \t HydroSnow Warning: There is Snow remaining on August 31 \n" );
00196                         fprintf( fidlog, " \t Snowremains \t = %e (m^3) \n", Snowremains );
00197                         fprintf( fidlog, " \t in year: %d \n",yr );
00198                 }
00199         }
00200 
00201   /*------------------------------------------
00202    *  Add any remaining snow to the next day
00203    *------------------------------------------*/
00204    for( kk=0; kk<nelevbins; kk++ )
00205       if( ii < daysiy-1 ) {
00206          Snowelevday[kk][ii+1] += Snowelevday[kk][ii];
00207          Snowelevday[kk][ii] = 0.0;
00208       }
00209 } /* end daily loop */
00210 
00211 /*--------------------------------------
00212  *  Print out Snow values for checking
00213  *--------------------------------------*/
00214 #ifdef DBG
00215   if( tblstart[ep] <= yr && yr <= tblend[ep] ) {
00216     if( (fid = fopen("hydro.snow3","a+")) == NULL) {
00217       printf("  HydroHypsim ERROR: Unable to open the snow file hydro.snow3 \n");
00218       printf("     non-fatal error, continueing. \n\n");
00219     }
00220     else {
00221       fprintf( fid,"%%\n%%\n%%HydroSnow: Emptied Snow array for epoch %d, year %d \n%%\n%%", ep+1, yr );
00222       fprintf( fid,"%%   Elev \t    day \t Snow (m) \n" );
00223       fprintf( fid,"%%   ---- \t  --------- \t ------------ \n" );
00224       for( ii=0; ii<daysiy; ii++ )
00225          for(kk=0; kk<nelevbins; kk++)
00226             fprintf( fid,"%7.1f \t %d \t %f \n", elevbins[kk], ii, Snowelevday[kk][ii] );
00227       fclose(fid);
00228     }
00229   }
00230 #endif
00231 
00232 /*-------------------------------------------------------------------
00233  *  Distribute the melted snow to E, GW, and shoulders for each day
00234  *  account for evaporation (m/day)
00235  *  I have distributed the E by the area of the basin
00236  *  which is not technically correct, but creates the
00237  *  correct units
00238  *-------------------------------------------------------------------*/
00239 for( ii=0; ii<daysiy; ii++ ) {
00240    Enivalannual += Qnival[ii]*dryevap[ep]*dTOs/totalarea[ep];
00241    Qnival[ii]  -= Qnival[ii]*dryevap[ep];
00242 }
00243 
00244 /*------------------------------------------------------------
00245  *  Create the shoulder events (Murray's version of routing)
00246  *  there is one left (preceeding) day scaled as:
00247  *  shoulderleft*event
00248  *  the main event is scaled down to:
00249  *  shouldermain*event
00250  *  there are 1 or more right (following days) scaled to:
00251  *  shoulderright[]*event
00252  *  1.0 = Sum(shoulderleft+shouldermain+shoulderright[])
00253  *------------------------------------------------------------*/
00254 ii = 0;
00255 if( Qnival[ii] > 0.0 ) {
00256    shldday[ii] += shoulderleft*Qnival[ii];
00257    for( jj=0; jj<shouldern-2; jj++ )
00258       shldday[ii+jj+1] += shoulderright[jj]*Qnival[ii];
00259    Qnival[ii] = shouldermain*Qnival[ii];
00260 }
00261 for( ii=1; ii<daysiy; ii++ )
00262    if( Qnival[ii] > 0.0 ) {
00263       shldday[ii-1] += shoulderleft*Qnival[ii];
00264       for( jj=0; jj<shouldern-2; jj++ )
00265          shldday[ii+jj+1] += shoulderright[jj]*Qnival[ii];
00266       Qnival[ii] = shouldermain*Qnival[ii];
00267    }
00268 
00269 /*----------------------------------------------------------------
00270  *  Add the shoulder events and the main events to get the total
00271  *----------------------------------------------------------------*/
00272 for( ii=0; ii<maxday; ii++ )
00273    Qnival[ii]   += shldday[ii];
00274 
00275 /*--------------------------------------------
00276  *  Add the carryover from the previous year
00277  *  and track it's mass
00278  *--------------------------------------------*/
00279 for( ii=0; ii<maxday-daysiy; ii++ ) {
00280    Qnival[ii]   += Qnivalwrap[ii];
00281    Mwrapin      += Qnivalwrap[ii]*dTOs;
00282 }
00283 
00284 #ifdef DBG
00285 fprintf( fidlog, "\t Snow Mwrapin \t = %e (m^3) \n", Mwrapin );
00286 #endif
00287 
00288 /*-------------------------------------------------------------
00289  *  Add to the flux to the Groundwater pool
00290  *  The actual addition to the GW pool is done in HydroRain.c
00291  *-------------------------------------------------------------*/
00292 for( ii=0; ii<daysiy; ii++ ) {
00293    Qnivaltogw[ii]       = percentgw[ep]*Qnival[ii];
00294    Qnival[ii]           -= Qnivaltogw[ii];
00295    Mgw                  += Qnivaltogw[ii]*dTOs;
00296 }
00297 
00298 /*--------------------------------
00299  *  Check the mass balance (m^3)
00300  *--------------------------------*/
00301 for( ii=0; ii<daysiy; ii++ )
00302    Mnival       += Qnival[ii]*dTOs;
00303 for( ii=daysiy; ii<maxday; ii++ )
00304    Mwrapout     += Qnival[ii]*dTOs;
00305 for( kk=0; kk<nelevbins; kk++ )         /* the remaining snow */
00306    Msnowend     += Snowelevday[kk][daysiy-1]*areabins[kk];
00307 
00308 #ifdef DBG
00309  if( yr >= 4690 ) {
00310     fprintf(stderr, " Msnowend = %f \n", Msnowend );
00311     for( kk=0; kk<nelevbins; kk++ )
00312        fprintf(stderr, " snow = %f, area = %f \n", Snowelevday[kk][daysiy-1], areabins[kk] );
00313  }
00314 #endif
00315 
00316 Mout = Mgw + Mnival + Enivalannual*totalarea[ep] + Msnowend + Mwrapout;
00317 Minput = MPnival + Mwrapin + Msnowstart;
00318 
00319 if( (fabs(Mout-Minput)/Minput) > masscheck ) {
00320    fprintf( stderr, "\nERROR in HydroSnow: \n");
00321    fprintf( stderr, "  Mass Balance error: Mout != Minput \n\n");
00322 
00323    fprintf( stderr, "\t fabs(Mout-Minput)/Minput > masscheck \n" );
00324    fprintf( stderr, "\t note: masscheck set in HydroParams.h \n" );
00325    fprintf( stderr, "\t masscheck     \t = %f (%%) \n", masscheck );
00326    fprintf( stderr, "\t abs(out-in)/in\t = %f (%%) \n", fabs(Mout-Minput)/Minput );
00327    fprintf( stderr, "\t out-in        \t = %e (m^3) \n\n", Mout-Minput );
00328 
00329    fprintf( stderr, " \t Minput = MPnival + Mwrapin + Msnowstart (m^3) \n" );
00330    fprintf( stderr, " \t Minput       \t = %e \n", Minput );
00331    fprintf( stderr, " \t MPnival      \t = %e \n", MPnival );
00332    fprintf( stderr, " \t Mwrapin      \t = %e \n", Mwrapin );
00333    fprintf( stderr, " \t Msnowstart   \t = %e \n\n", Msnowstart );
00334 
00335    fprintf( stderr, " \t Mout = Mnival + Mgw + Enivalannual + Msnowend + Mwrapout (m^3) \n" );
00336    fprintf( stderr, " \t Mout         \t = %e \n", Mout );
00337    fprintf( stderr, " \t Mnival       \t = %e \n", Mnival );
00338    fprintf( stderr, " \t Mgw          \t = %e \n", Mgw );
00339    fprintf( stderr, " \t Enivalannual \t = %e \n", Enivalannual*totalarea[ep] );
00340    fprintf( stderr, " \t Mwrapout     \t = %e \n", Mwrapout );
00341    fprintf( stderr, " \t Msnowend     \t = %e \n\n", Msnowend );
00342    exit(-1);
00343 }
00344 
00345 return(err);
00346 }  /* end of HydroSnow.c */
00347 

Generated on Fri Jan 4 18:04:14 2008 for sedflux by  doxygen 1.5.2