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

📄 read_soilparam.c

📁 本人独自开发的土壤计算及分析工具
💻 C
字号:
#include <stdio.h>
#include <stdlib.h>
#include <vicNl.h>
#include <string.h>

static char vcid[] = "$Id: read_soilparam.c,v 4.2.2.10 2004/07/08 01:46:02 tbohn Exp $";

soil_con_struct read_soilparam(FILE *soilparam,
			       int   RUN_MODEL)
/**********************************************************************
	read_soilparam		Dag Lohmann		January 1996

  This routine reads soil parameters for each grid cell.

  Parameters Read from File:
  TYPE   NAME                    UNITS   DESCRIPTION
  int    gridcel;                N/A     grid cell number
  float  lat;		         degrees grid cell central latitude
  float  lng;		         degrees grid cell central longitude
  double b_infilt;  	         N/A     infiltration parameter
  double Ds;		         fract   fraction of maximum subsurface
                                         flow rate
  double Dsmax;  	         mm/day  maximum subsurface flow rate
  double Ws;		         fract   fraction of maximum soil moisture
  double c;                      N/A     exponent
  double expt[MAX_LAYERS];         N/A     pore-size distribution, HBH 5.15
  double Ksat[MAX_LAYERS];         mm/day  saturated hydraulic  conductivity
  double phi_s[MAX_LAYERS];        mm/mm   saturated matrix potential
  double init_moist[MAX_LAYERS];   mm      initial layer moisture level
  float  elevation;	         m       grid cell elevation
  double depth[MAX_LAYERS];        m       thickness of each layer
  double avg_temp;	         C       average soil temperature
  double dp;		         m       soil thermal damping depth
  double bubble;	         cm      bubbling pressure, HBH 5.15
  double quartz;	         fract   quartz content of soil
  double bulk_density[MAX_LAYERS]; kg/m^3  soil bulk density
  double soil_density;		 kg/m^3  soil partical density
  double rough;		         m       soil surface roughness
  double snow_rough;             m       snow surface roughness

  Parameters Computed from those in the File:
  TYPE   NAME                    UNITS   DESCRIPTION
  double max_moist[MAX_LAYERS];    mm      maximum moisture content per layer
  double max_infil;	         N/A     maximum infiltration rate
  double Wcr[MAX_LAYERS];	         mm      critical moisture level for soil
                                         layer, evaporation is no longer
                                         affected moisture stress in the soil
  double Wpwp[MAX_LAYERS];         mm      soil moisture content at permanent
                                         wilting point
  float  time_zone_lng;	         degrees central meridian of the time zone


  Modifications:
  7-19-96	Modified to read through variable layers, and
		read soil depth and average temperature for
		full energy and frozen soil versions of the
		model.						KAC
  4-12-98       Modified to read all parameters from a single
                standard input file.                            KAC
  3-13-00       Modified to read more parameters as separate
                layer values                                    KAC
  6-6-2000      Modified to skip individual parameter reads
                if model grid cell is not read.                 KAC
  10-Oct-03     Modified to read ARNO baseflow parameters d1, d2,
		d3, and d4 and convert to Ds, Dsmax, Ws, and c,
		if options.ARNO_PARAMS is TRUE.			TJB
  07-May-04	Replaced rint(something) with (float)(int)(something + 0.5)
		to handle rounding without resorting to rint().	TJB
  11-May-04	Removed extraneous tmp variable.		TJB
  11-May-04	(fix by Chunmei Zhu and Alan Hamlet)
		Added check to make sure that wilting point is
		greater than residual moisture.			TJB
  16-Jun-04	Added logic to read optional extra field containing
		average July air temperature, if JULY_TAVG_SUPPLIED
		= TRUE.						TJB
  07-Jul-04	Changed lower limit on initial soil moisture to be
		residual moisture rather than wilting point.  Also
		cleaned up validation statements.		TJB
  07-Jul-04	Validation of initial soil moisture is only performed
		if INIT_STATE = FALSE.				TJB

**********************************************************************/
{
  extern option_struct options;
#if LINK_DEBUG
  extern debug_struct debug;
#endif

  char            ErrStr[MAXSTRING];
  char            NotRunStr[2048];
  int             layer, i, tempint;
  double          Wcr_FRACT[MAX_LAYERS];
  double          Wpwp_FRACT[MAX_LAYERS];
  double          off_gmt;
  soil_con_struct temp; 

  if ( RUN_MODEL ) {

    fscanf(soilparam, "%d", &temp.gridcel);
    fscanf(soilparam, "%f", &temp.lat);
    fscanf(soilparam, "%f", &temp.lng);
#if VERBOSE
    /* add print statements for grid cell number -- EDM */
    fprintf(stderr,"\ncell: %d,  lat: %.4f, long: %.4f\n",temp.gridcel,temp.lat,temp.lng);
#endif
    
    /* read infiltration parameter */
    fscanf(soilparam, "%lf", &temp.b_infilt);
    
    /* read fraction of baseflow rate */
    fscanf(soilparam, "%lf", &temp.Ds);
    
    /* read maximum baseflow rate */
    fscanf(soilparam, "%lf", &temp.Dsmax);
    
    /* read fraction of bottom soil layer moisture */
    fscanf(soilparam, "%lf", &temp.Ws);
    
    /* read exponential */
    fscanf(soilparam, "%lf", &temp.c);
    
    /* read expt for each layer */
    for(layer = 0; layer < options.Nlayer; layer++) 
      fscanf(soilparam, "%lf", &temp.expt[layer]);
    
    /* read layer saturated hydraulic conductivity */
    for(layer = 0; layer < options.Nlayer; layer++)
      fscanf(soilparam, "%lf", &temp.Ksat[layer]);
    
    /* read layer phi_s */
    for(layer = 0; layer < options.Nlayer; layer++)
      fscanf(soilparam, "%lf", &temp.phi_s[layer]);
    
    /* read layer initial moisture */
    for(layer = 0; layer < options.Nlayer; layer++) {
      fscanf(soilparam, "%lf", &temp.init_moist[layer]);
      if(temp.init_moist[layer] < 0.) {
	sprintf(ErrStr,"ERROR: Initial moisture for layer %i cannot be negative (%f)",layer,temp.init_moist[layer]);
	nrerror(ErrStr);
      }
    }
    
    /* read cell mean elevation */
    fscanf(soilparam, "%f", &temp.elevation);
    
    /* soil layer thicknesses */
    for(layer = 0; layer < options.Nlayer; layer++) {
      fscanf(soilparam, "%lf", &temp.depth[layer]);
      temp.depth[layer] = (float)(int)(temp.depth[layer] * 1000 + 0.5) / 1000;
      if(temp.depth[layer] < MINSOILDEPTH) {
	sprintf(ErrStr,"ERROR: Model will not function with layer %i depth %f < %f m.\n",
		layer,temp.depth[layer],MINSOILDEPTH);
	nrerror(ErrStr);
      }
    }
    if(options.GRND_FLUX && (temp.depth[0] > temp.depth[1])) {
      sprintf(ErrStr,"ERROR: Model will not function with layer %i depth (%f m) < layer %i depth (%f m).\n",
	      0,temp.depth[0],1,temp.depth[1]);
      nrerror(ErrStr);
    }
    
    /* read average soil temperature */
    fscanf(soilparam, "%lf", &temp.avg_temp);
    if(options.FULL_ENERGY && (temp.avg_temp>100. || temp.avg_temp<-50)) {
      fprintf(stderr,"Need valid average soil temperature in degrees C to run");
      fprintf(stderr," Full Energy model, %f is not acceptable.\n",
	      temp.avg_temp);
      exit(0);
    }
    
    /* read soil damping depth */
    fscanf(soilparam, "%lf", &temp.dp);
    
    /* read layer bubbling pressure */
    for(layer = 0; layer < options.Nlayer; layer++) 
      fscanf(soilparam, "%lf", &temp.bubble[layer]);
    
    /* read layer quartz content */
    for(layer = 0; layer < options.Nlayer; layer++) {
      fscanf(soilparam, "%lf", &temp.quartz[layer]);
      if(options.FULL_ENERGY 
	 && (temp.quartz[layer] > 1. || temp.quartz[layer] < 0)) {
	fprintf(stderr,"Need valid quartz content as a fraction to run");
	fprintf(stderr," Full Energy model, %f is not acceptable.\n",
		temp.quartz[layer]);
	exit(0);
      }
    }
    
    /* read layer bulk density */
    for(layer = 0; layer < options.Nlayer; layer++)
      fscanf(soilparam, "%lf", &temp.bulk_density[layer]);
    
    /* read layer soil density */
    for(layer = 0; layer < options.Nlayer; layer++) {
      fscanf(soilparam, "%lf", &temp.soil_density[layer]);
      if(temp.bulk_density[layer]>=temp.soil_density[layer])
	nrerror("Layer bulk density must be less then soil density");
    }
    
    /* read cell gmt offset */
    fscanf(soilparam, "%lf", &off_gmt);
    
    /* read layer critical point */
    for(layer=0;layer<options.Nlayer;layer++)
      fscanf(soilparam, "%lf", &(Wcr_FRACT[layer]));
    
    /* read layer wilting point */
    for(layer=0;layer<options.Nlayer;layer++)
      fscanf(soilparam, "%lf", &(Wpwp_FRACT[layer]));
    
    /* read soil roughness */
    fscanf(soilparam, "%lf", &temp.rough);
    
    /* read snow roughness */
    fscanf(soilparam, "%lf", &temp.snow_rough);
    
    /* read cell annual precipitation */
    fscanf(soilparam, "%lf", &temp.annual_prec);
    
    /* read layer residual moisture content */
    for(layer = 0; layer < options.Nlayer; layer++) 
      fscanf(soilparam, "%lf", &temp.resid_moist[layer]);
    
    /* read frozen soil active flag */
    fscanf(soilparam, "%i", &tempint);
    temp.FS_ACTIVE = (char)tempint;
    
    if (options.JULY_TAVG_SUPPLIED) {
      /* read cell average July air temperature */
      fscanf(soilparam, "%lf", &temp.avgJulyAirTemp);
    }

    /*******************************************
      Compute Soil Layer Properties
    *******************************************/
    for(layer = 0; layer < options.Nlayer; layer++) {
      if (temp.resid_moist[layer] == MISSING)
        temp.resid_moist[layer] = RESID_MOIST;
      temp.porosity[layer] = 1.0 - temp.bulk_density[layer]
        / temp.soil_density[layer];
      temp.max_moist[layer] = temp.depth[layer] * temp.porosity[layer] * 1000.;
    }

    /*******************************************
      Validate Initial Soil Layer Moisture Content
    *******************************************/
    if (!options.INIT_STATE) {  // only do this if we're not getting initial moisture from a state file
      for(layer = 0; layer < options.Nlayer; layer++) {
        if(temp.init_moist[layer] > temp.max_moist[layer]) {
          fprintf(stderr,"Initial soil moisture (%f mm) is greater than the maximum moisture (%f mm) for layer %i.\n\tResetting soil moisture to maximum.\n",
                  temp.init_moist[layer], temp.max_moist[layer], layer);
          temp.init_moist[layer] = temp.max_moist[layer];
        }
        if(temp.init_moist[layer] < temp.resid_moist[layer] * temp.depth[layer] * 1000.) {
          fprintf(stderr,"Initial soil moisture (%f mm) is less than calculated residual moisture (%f mm) for layer %i.\n\tResetting soil moisture to residual moisture.\n",
                  temp.init_moist[layer], temp.resid_moist[layer] * temp.depth[layer] * 1000., layer);
          temp.init_moist[layer] = temp.resid_moist[layer] * temp.depth[layer] * 1000.;
        }
      }
    }

    /**********************************************
      Compute Maximum Infiltration for Upper Layers
    **********************************************/
    if(options.Nlayer==2)
      temp.max_infil = (1.0+temp.b_infilt)*temp.max_moist[0];
    else
      temp.max_infil = (1.0+temp.b_infilt)*(temp.max_moist[0]+temp.max_moist[1]);
    
    /****************************************************************
      Compute Soil Layer Critical and Wilting Point Moisture Contents
    ****************************************************************/
    for(layer=0;layer<options.Nlayer;layer++) {
      temp.Wcr[layer]  = Wcr_FRACT[layer] * temp.max_moist[layer];
      temp.Wpwp[layer] = Wpwp_FRACT[layer] * temp.max_moist[layer];
      if(temp.Wpwp[layer] > temp.Wcr[layer]) {
        sprintf(ErrStr,"Calculated wilting point moisture (%f mm) is greater than calculated critical point moisture (%f mm) for layer %i.\n\tIn the soil parameter file, Wpwp_FRACT MUST be <= Wcr_FRACT.\n",
                temp.Wpwp[layer], temp.Wcr[layer], layer);
        nrerror(ErrStr);
      }
      if(temp.Wpwp[layer] < temp.resid_moist[layer] * temp.depth[layer] * 1000.) {
        sprintf(ErrStr,"Calculated wilting point moisture (%f mm) is less than calculated residual moisture (%f mm) for layer %i.\n\tIn the soil parameter file, Wpwp_FRACT MUST be >= resid_moist / (1.0 - bulk_density/soil_density).\n",
                temp.Wpwp[layer], temp.resid_moist[layer] * temp.depth[layer] * 1000., layer);
        nrerror(ErrStr);
      }
    }


    /*************************************************
      If ARNO_PARAMS = TRUE then convert ARNO baseflow
      parameters d1, d2, d3, and d4 to Ds, Dsmax, Ws, and c
    *************************************************/
    if(options.ARNO_PARAMS) {
      layer = options.Nlayer-1;
      temp.Dsmax = temp.Dsmax *
        pow((double)(1./(temp.max_moist[layer]-temp.Ws)), -temp.c) +
        temp.Ds * temp.max_moist[layer];
      temp.Ds = temp.Ds * temp.Ws / temp.Dsmax;
      temp.Ws = temp.Ws/temp.max_moist[layer];
    }



    /*************************************************
      Determine Central Longitude of Current Time Zone 
    *************************************************/
    temp.time_zone_lng = off_gmt * 360./24.;

    /* Allocate Layer - Node fraction array */
    temp.layer_node_fract = (float **)malloc((options.Nlayer+1)*sizeof(float *));
    for(layer=0;layer<=options.Nlayer;layer++) 
      temp.layer_node_fract[layer] = (float *)malloc(options.Nnode*sizeof(float));

  }
  else {
   
    /* Grid cell is not active, skip soil parameter data */
    fgets(NotRunStr, 2048, soilparam);

  }
    
  return temp;

} 

⌨️ 快捷键说明

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