⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 canopy_evap.c

📁 超强的大尺度水文模拟工具
💻 C
字号:
#include <stdio.h>#include <stdlib.h>#include <vicNl.h>static char vcid[] = "$Id: canopy_evap.c,v 4.1 2000/05/16 21:07:16 vicadmin Exp $";double canopy_evap(layer_data_struct *layer_wet,                   layer_data_struct *layer_dry,                   veg_var_struct    *veg_var_wet,                    veg_var_struct    *veg_var_dry, 		   char               CALC_EVAP,                   int                veg_class,                    int                month,                    double             mu,		   double            *Wdew,                   double             dt,                   double             rad,		   double             vpd,		   double             net_short,		   double             air_temp,                   double             ra,                   double             displacement,                   double             roughness,                   double             ref_height,		   double             elevation,                   double            *prec,		   double            *depth,		   double            *Wcr,		   double            *Wpwp,		   float             *root)/**********************************************************************	canopy_evap.c	Dag Lohmann		September 1995  This routine computes the evaporation, traspiration and throughfall  of the vegetation types for multi-layered model.  The value of x, the fraction of precipitation that exceeds the   canopy storage capacity, is returned by the subroutine.  UNITS:	moist (mm)		evap (mm)		prec (mm)		melt (mm)  VARIABLE TYPE        NAME          UNITS DESCRIPTION  atmos_data_struct    atmos         N/A   atmospheric forcing data structure  layer_data_struct   *layer         N/A   soil layer variable structure  veg_var_struct      *veg_var       N/A   vegetation variable structure  soil_con_struct      soil_con      N/A   soil parameter structure  char                 CALC_EVAP     N/A   TRUE = calculate evapotranspiration  int                  veg_class     N/A   vegetation class index number  int                  month         N/A   current month  global_param_struct  global        N/A   global parameter structure  double               mu            fract wet (or dry) fraction of grid cell  double               ra            s/m   aerodynamic resistance  double               prec          mm    precipitation  double               displacement  m     displacement height of surface cover  double               roughness     m     roughness height of surface cover  double               ref_height    m     measurement reference height  Modifications:  9/1/97	Greg O'Donnell  4-12-98  Code cleaned and final version prepared, KAC  06-25-98 modified for new distributed precipitation data structure KAC  01-19-00 modified to function with new simplified soil moisture            scheme                                                  KAC**********************************************************************/{  /** declare global variables **/  extern veg_lib_struct *veg_lib; #if LINK_DEBUG  extern debug_struct debug;#endif  extern option_struct options;  /** declare local variables **/  int                Ndist;  int                dist;  int                i;  double             ppt;		/* effective precipitation */  double             f;		/* fraction of time step used to fill canopy */  double             throughfall;  double             Evap;  double             tmp_Evap;  double             canopyevap;  double             tmp_Wdew;  double             layerevap[MAX_LAYERS];  layer_data_struct *tmp_layer;  veg_var_struct    *tmp_veg_var;  /**********************************************************************      CANOPY EVAPORATION     Calculation of evaporation from the canopy, including the     possibility of potential evaporation exhausting ppt+canopy storage     2.16 + 2.17     Index [0] refers to current time step, index [1] to next one     If f < 1.0 than veg_var->canopyevap = veg_var->Wdew + ppt and                     Wdew = 0.0     DEFINITIONS:     Wdmax - max monthly dew holding capacity     Wdew - dew trapped on vegetation     Modified      04-14-98 to work within calc_surf_energy_balance.c  KAC     07-24-98 fixed problem that caused hourly precipitation              to evaporate from the canopy during the same	      time step that it falls (OK for daily time step, 	      but causes oscilations in surface temperature	      for hourly time step)                      KAC, Dag	        **********************************************************************/   if(options.DIST_PRCP) Ndist = 2;  else Ndist = 1;  Evap = 0;  for(dist=0;dist<Ndist;dist++) {    /* Initialize variables */    for(i=0;i<options.Nlayer;i++) layerevap[i] = 0;    canopyevap = 0;    throughfall = 0;    /* Set parameters for distributed precipitation */    if(dist==0) {      tmp_layer   = layer_wet;      tmp_veg_var = veg_var_wet;      ppt         = prec[WET];      tmp_Wdew    = Wdew[WET];    }    else {      tmp_layer   = layer_dry;      tmp_veg_var = veg_var_dry;      ppt         = prec[DRY];      mu          = (1. - mu);      tmp_Wdew    = Wdew[DRY];    }          if(mu > 0) {      /****************************************************        Compute Evaporation from Canopy Intercepted Water      ****************************************************/      /** Due to month changes ..... Wdmax based on LAI **/      tmp_veg_var->Wdew = tmp_Wdew;      if (tmp_Wdew > veg_lib[veg_class].Wdmax[month-1]) {	throughfall = tmp_Wdew - veg_lib[veg_class].Wdmax[month-1];	tmp_Wdew    = veg_lib[veg_class].Wdmax[month-1];      }            canopyevap = pow((tmp_Wdew / veg_lib[veg_class].Wdmax[month-1]),		       (2.0/3.0))* penman(rad, vpd * 1000., ra, (double) 0.0, 					  veg_lib[veg_class].rarc,					  veg_lib[veg_class].LAI[month-1], 					  (double) 1.0, air_temp, 					  net_short, elevation, 					  veg_lib[veg_class].RGL) * dt / 24.0;      if (canopyevap > 0.0 && dt==24)	/** If daily time step, evap can include current precipitation **/	f = min(1.0,((tmp_Wdew + ppt) / canopyevap));      else if (canopyevap > 0.0)	/** If sub-daily time step, evap can not exceed current storage **/	f = min(1.0,((tmp_Wdew) / canopyevap));      else	f = 1.0;      canopyevap *= f;          tmp_Wdew += ppt - canopyevap;      if (tmp_Wdew < 0.0) 	tmp_Wdew = 0.0;      if (tmp_Wdew <= veg_lib[veg_class].Wdmax[month-1]) 	throughfall += 0.0;      else {	throughfall += tmp_Wdew - veg_lib[veg_class].Wdmax[month-1];	tmp_Wdew = veg_lib[veg_class].Wdmax[month-1];      }      /*******************************************        Compute Evapotranspiration from Vegetation      *******************************************/      if(CALC_EVAP)	transpiration(tmp_layer, veg_class, month, rad,		      vpd, net_short, air_temp, ra,		      ppt, f, dt, tmp_veg_var->Wdew, elevation,		      depth, Wcr, Wpwp, &tmp_Wdew,		      &canopyevap, layerevap, root);    }    tmp_veg_var->canopyevap = canopyevap;    tmp_veg_var->throughfall = throughfall;    tmp_veg_var->Wdew = tmp_Wdew;    tmp_Evap = canopyevap;    for(i=0;i<options.Nlayer;i++) {      tmp_layer[i].evap  = layerevap[i];      tmp_Evap          += layerevap[i];    }        Evap += tmp_Evap * mu / (1000. * dt * 3600.);  }  return (Evap);}/**********************************************************************	EVAPOTRANSPIRATION ROUTINE**********************************************************************/void transpiration(layer_data_struct *layer,		   int veg_class, 		   int month, 		   double rad,		   double vpd,		   double net_short,		   double air_temp,		   double ra,		   double ppt,		   double f,		   double dt,		   double Wdew,		   double elevation,		   double *depth,		   double *Wcr,		   double *Wpwp,		   double *new_Wdew,		   double *canopyevap,		   double *layerevap,		   float  *root)/**********************************************************************  Computes evapotranspiration for unfrozen soils  Allows for multiple layers.**********************************************************************/{  extern veg_lib_struct *veg_lib;  extern option_struct options;  int i;  double gsm_inv;               	/* soil moisture stress factor */  double moist1, moist2;                /* tmp holding of moisture */  double evap;                          /* tmp holding for evap total */  double Wcr1;                          /* tmp holding of critical water for upper layers */  double root_sum;                      /* proportion of roots in moist>Wcr zones */  double spare_evap;                    /* evap for 2nd distribution */  double avail_moist[MAX_LAYERS];         /* moisture available for trans */  /**********************************************************************      EVAPOTRANSPIRATION     Calculation of the evapotranspirations     2.18     First part: Soil moistures and root fractions of both layers     influence each other     Re-written to allow for multi-layers.  **********************************************************************/   /**************************************************    Compute moisture content in combined upper layers    **************************************************/  moist1 = 0.0;  Wcr1 = 0.0;    for(i=0;i<options.Nlayer-1;i++){    if(root[i] > 0.) {      avail_moist[i] = layer[i].moist - layer[i].ice;      moist1+=avail_moist[i];      Wcr1 += Wcr[i];    }    else avail_moist[i]=0.;  }  /*****************************************    Compute moisture content in lowest layer    *****************************************/  i=options.Nlayer-1;  moist2 = layer[i].moist - layer[i].ice;  avail_moist[i]=moist2;  /******************************************************************    CASE 1: Moisture in both layers exceeds Wcr, or Moisture in    layer with more than half of the roots exceeds Wcr.    Potential evapotranspiration not hindered by soil dryness.  If    layer with less than half the roots is dryer than Wcr, extra    evaporation is taken from the wetter layer.  Otherwise layers    contribute to evapotransipration based on root fraction.  ******************************************************************/  if( (moist1>=Wcr1 && moist2>=Wcr[options.Nlayer-1] && Wcr1>0.) ||      (moist1>=Wcr1 && (1-root[options.Nlayer-1])>= 0.5) ||      (moist2>=Wcr[options.Nlayer-1] &&      root[options.Nlayer-1]>=0.5) ){    gsm_inv=1.0;    evap = penman(rad, vpd * 1000., ra, veg_lib[veg_class].rmin,		  veg_lib[veg_class].rarc, veg_lib[veg_class].LAI[month-1], 		  gsm_inv, air_temp, net_short, elevation, 		  veg_lib[veg_class].RGL) * dt / 24.0 *      (1.0-f*pow((Wdew/veg_lib[veg_class].Wdmax[month-1]),		 (2.0/3.0)));    /** divide up evap based on root distribution **/    /** Note the indexing of the roots **/    root_sum=1.0;    spare_evap=0.0;    for(i=0;i<options.Nlayer;i++){      if(avail_moist[i]>=Wcr[i]){        layerevap[i]=evap*(double)root[i];      }      else {                  if (avail_moist[i] >= Wpwp[i])           gsm_inv = (avail_moist[i] - Wpwp[i]) /                    (Wcr[i] - Wpwp[i]);        else           gsm_inv=0.0;	            layerevap[i]  = evap*gsm_inv*(double)root[i];        root_sum     -= root[i];        spare_evap    = evap*(double)root[i]*(1.0-gsm_inv);      }    }    /** Assign excess evaporation to wetter layer **/    if(spare_evap>0.0){      for(i=0;i<options.Nlayer;i++){        if(avail_moist[i] >= Wcr[i]){          layerevap[i] += (double)root[i]*spare_evap/root_sum;        }      }    }  }  /*********************************************************************    CASE 2: Independent evapotranspirations    Evapotranspiration is restricted by low soil moisture. Evaporation    is computed independantly from each soil layer.  *********************************************************************/  else {    for(i=0;i<options.Nlayer;i++){      /** Set evaporation restriction factor **/      if(avail_moist[i] >= Wcr[i])	gsm_inv=1.0;      else if(avail_moist[i] >= Wpwp[i])	gsm_inv=(avail_moist[i] - Wpwp[i]) /	  (Wcr[i] - Wpwp[i]);      else 	gsm_inv=0.0;      if(gsm_inv > 0.0){	/** Compute potential evapotranspiration **/        layerevap[i] = penman(rad, vpd * 1000., ra, veg_lib[veg_class].rmin,			      veg_lib[veg_class].rarc, 			      veg_lib[veg_class].LAI[month-1], gsm_inv, 			      air_temp, net_short, elevation, 			      veg_lib[veg_class].RGL) * dt / 24.0 	  * (double)root[i] * (1.0-f*pow((Wdew/					  veg_lib[veg_class].Wdmax[month-1]),					 (2.0/3.0)));      }      else layerevap[i] = 0.0;    }  }      /****************************************************************    Check that evapotransipration does not cause soil moisture to     fall below wilting point.  ****************************************************************/  for(i=0;i<options.Nlayer;i++){    if(layerevap[i] > layer[i].moist - Wpwp[i]) {      layerevap[i] = layer[i].moist - Wpwp[i];    }    if ( layerevap[i] < 0.0 ) {      layerevap[i] = 0.0;    }  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -