Пример #1
0
/*--------------------------------------------------------------------*\
 | FUNCTION     : get_times
 | COMMENT		:
 | PARAMETERS   :
 | RETURN VALUE : 
 | RESTRICTIONS :
\*--------------------------------------------------------------------*/
void get_times (void) {
  long *datetime;
  float *newvalue;

  datetime = (long *) control_var("start_time");
  Mstrttime->year = datetime[0];
  Mstrttime->month = datetime[1];
  Mstrttime->day = datetime[2];
  Mstrttime->hour = datetime[3];
  Mstrttime->min = datetime[4];
  Mstrttime->sec = datetime[5];

  datetime = (long *) control_var("end_time");
  Mendtime->year = datetime[0];
  Mendtime->month = datetime[1];
  Mendtime->day = datetime[2];
  Mendtime->hour = datetime[3];
  Mendtime->min = datetime[4];
  Mendtime->sec = datetime[5];

  /* compute julian day for start and end  - this fills in the julian date
     parts of the datetime data structure */

  julday(Mstrttime);
  julday(Mendtime);

  newvalue = (float *) control_var("initial_deltat");
  Mdeltat = (double)(*newvalue / 24.0);
  Mdeltanext = (double)(*newvalue / 24.0);
}
Пример #2
0
int main(void)
{
	int i,id,im,iy,n;
	char txt[MAXSTR];
	static char *name[]={"","january","february","march",
		"april","may","june","july","august","september",
		"october","november","december"};
	FILE *fp;

	if ((fp = fopen("dates1.dat","r")) == NULL)
		nrerror("Data file dates1.dat not found\n");
	fgets(txt,MAXSTR,fp);
	fscanf(fp,"%d %*s ",&n);
	printf("\n%5s %8s %6s %12s %9s\n","month","day","year",
		"julian day","event");
	for (i=1;i<=n;i++) {
		fscanf(fp,"%d %d %d ",&im,&id,&iy);
		fgets(txt,MAXSTR,fp);
		printf("%-10s %3d %6d %10ld %5s %s",name[im],id,iy,
			julday(im,id,iy)," ",txt);
	}
	fclose(fp);
	printf("\nYour choices: (negative to end)\n");
	printf("month day year (e.g. 1 13 1905)\n");
	for (i=1;i<=20;i++) {
		printf("\nmm dd yyyy ?\n");
		scanf("%d %d %d",&im,&id,&iy);
		if (im < 0) return 0;
		printf("julian day: %ld \n",julday(im,id,iy));
	}
	return 0;
}
Пример #3
0
int	 cal_date_lt( struct date date1,
				 struct date date2) 
{
	/*--------------------------------------------------------------*/
	/*	Local function declarations.								*/
	/*--------------------------------------------------------------*/
	long	julday( struct date );
	/*--------------------------------------------------------------*/
	/*	Local Variable Definition. 									*/
	/*--------------------------------------------------------------*/
	long	julday1;
	long	julday2;
	/*--------------------------------------------------------------*/
	/*	Check if the julian days are different.						*/
	/*--------------------------------------------------------------*/
	julday1 = julday(date1);
	julday2 = julday(date2);
	if ( julday1 == julday2 ){
		if ( date1.hour < date2.hour ){
			return(1);
		}
		else{
			return(0);
		}
	}
	else if ( julday1 < julday2 ){
		return(1);
	}
	else{
		return(0);
	}
} /*end cal_date_lt.c*/
Пример #4
0
int main(void)
{
	int i,id,idd,im,imm,iy,iyy,n;
	long j;
	char dummy[MAXSTR];
	static char *name[]={"","january","february","march",
		"april","may","june","july","august",
		"september","october","november","december"};
	FILE *fp;

	/* Check whether caldat properly undoes the operation of julday */
	if ((fp = fopen("dates1.dat","r")) == NULL)
		nrerror("Data file dates1.dat not found\n");
	fgets(dummy,MAXSTR,fp);
	fscanf(fp,"%d %*s ",&n);
	printf("\n %14s %43s\n","original date:","reconstructed date");
	printf("%8s %5s %6s %15s %12s %5s %6s\n","month","day","year",
		"julian day","month","day","year");
	for (i=1;i<=n;i++) {
		fscanf(fp,"%d %d %d ",&im,&id,&iy);
		fgets(dummy,MAXSTR,fp);
		j=julday(im,id,iy);
		caldat(j,&imm,&idd,&iyy);
		printf("%10s %3d %6d %13ld %16s %3d %6d\n",name[im],
			id,iy,j,name[imm],idd,iyy);
	}
	fclose(fp);
	return 0;
}
Пример #5
0
int date_conversion (int d ,
                     int m ,
                     int y ,		/* day, month, year */
                     centisec gutime, 	/* greenwich time in centiseconds */
                     char c,  /* calendar g[regorian]|j[ulian]|a[stro = greg] */
                     double *tgmt	
			/* julian date relative 0.Jan.1950 12:00 gmt */
			/* shift is 2433282 from absolute Julian date */
		    ) 
{ 
  int rday, rmon, ryear;
  double rut, jd;
  int gregflag = SE_JUL_CAL;
  if (c == 'g' || c == 'a')
    gregflag = SE_GREG_CAL;
  rut = gutime / 360000.0;	/* hours GMT */
  jd = julday(m, d, y, rut, gregflag);
  revjul(jd, gregflag, &rmon, &rday, &ryear, &rut);
  *tgmt = jd - JUL_OFFSET;
  if (rmon == m && rday == d && ryear == y) {
    return OK;
  } else {
    return ERR;
  }
}	/* end date_conversion */
/**
 * Convert UTC to Decyimal year and Julian day.
 * @return
 */
adcs_error_status time_converter() {

    decyear(&adcs_time);
    julday(&adcs_time);

    return error_propagation(ERROR_OK);
}
Пример #7
0
int main(int argc, char **argv)
{
  FILE *fpinfo, *fpappf, *fpoutf;

  int i, lines, apprecs,year,LP,nyrs;
  int st_yr, end_yr, st_mo, end_mo, st_day, end_day;
  int idx,rec,k;
  int coop_id, append_id;

  char str1[MAXLINE],infofile[80],cid[6];
  char appfile[80], outfile[80];
  char junkstr[MAXLINE];
  char **apid;
  float ***prec;
  float **junk;
  int *apyr;

  int match;
      
  /*     leap year always included in input data */
      
  printf("\nBe sure that the void number used is -99\n");

  /*     read command line arguments -- filenames
         1) station info file from CD data
         2) daily data (preprocessed) to be appended to record
         3) start year for data to be appended
         4) start month for data to be appended
         5) end year for data to be appended
         6) end month for data to be appended
         7) output file of data to be appended
         8) number of records (years * stations) in .daily file
  */
  if (argc!=9) {    /* Must be exactly 8 arguments behind the program name */
    printf("Incorrect number of commandline arguments \n");
    exit(EXIT_FAILURE);
  }

  strcpy(infofile,argv[1]);      printf("infofile %s \n",infofile);
  strcpy(appfile,argv[2]);       printf("appfile %s \n",appfile);
  st_yr=atoi(argv[3]);         printf("st_yr %d \n",st_yr);
  st_mo=atoi(argv[4]);         printf("st_mo %d \n",st_mo);
  end_yr=atoi(argv[5]);         printf("end_yr %d \n",end_yr);
  end_mo=atoi(argv[6]);         printf("end_mo %d \n",end_mo);
  strcpy(outfile,argv[7]);        printf("outfile %s \n",outfile);
  apprecs=atoi(argv[8]);         printf("apprecs %d \n",apprecs);

  if((fpinfo = fopen(infofile,"r"))==NULL){
    printf("Cannot open file %s \n",infofile);exit(0);}
  if((fpappf = fopen(appfile,"r"))==NULL){
    printf("Cannot open file %s \n",appfile);exit(0);}
  if((fpoutf = fopen(outfile,"w"))==NULL){
    printf("Cannot open file %s \n",outfile);exit(0);}
  
  fgets(str1,MAXLINE,fpinfo);
  sscanf(str1,"%d",&lines);
  printf("No. of stations in info file: %d\n",lines);
  nyrs=end_yr-st_yr+1;

  /* allocate memory */
  prec=get_3d_mem_float(nyrs+1,lines+1,366+1);
  junk=get_2d_mem_float(apprecs+1,366+1);
  apid=get_2d_mem_char(apprecs+1,6);
  apyr=get_1d_mem_int(apprecs+1);

  /***read in ".daily" preprocessed append data file into memory***/

  for(rec=1;rec<=apprecs;rec++){
    fscanf(fpappf,"%s %d", apid[rec], &apyr[rec]);
    for(k=1;k<=366;k++) fscanf(fpappf,"%f", &junk[rec][k]);
  }

  /************* begin loop for each station *******************/

  for(i=1;i<=lines;i++) {
    fgets(str1,MAXLINE,fpinfo);
    strncpy(cid,&str1[55],6);
    printf("coopid= %6s ... ",cid);

    /* begin loop for current year */

    for(year=st_yr;year<=end_yr;year++){
      idx=year-st_yr+1;
      /* search append data for current station and year */
      match=FALSE;
      for(rec=1;rec<=apprecs;rec++){
	if(! match) {
	  if ((strcmp(apid[rec],cid)==0) && apyr[rec]==year ){
	    for(k=1;k<=366;k++){
	      prec[idx][i][k]=junk[rec][k];
	    }
	    match=TRUE;
	  }
	}
      }
      if (! match) {
	for(k=1;k<=366;k++){
	  prec[idx][i][k]=-99;
	}
      }
    }
    printf("completed station %d of %d\n",i,lines);
  }

  /************* end loop for each station *******************/
  /* now to write it out in the same format as the existing .fmt file */
  /* since array always is 1-366, pass 1 instead of LP to always
     adjust julian days */

  st_day = julday(st_mo-1,1);
  end_day = julday(end_mo,1)-1;

  for(year=st_yr;year<=end_yr;year++){
    idx=year-st_yr+1;
    LP = isaleap(year);

    printf("checking data for possible bad values and writing data\n");
    for(k=1;k<=366;k++){
      for(i=1;i<=lines;i++){
	if(prec[idx][i][k] > maxprec) {
	  printf("high precip at sta %d year %d line %d\n",i,year,k);
	  printf("precip (inch/day): %.2f\n", prec[idx][i][k]);
	}
	if(prec[idx][i][k] < 0.0 && prec[idx][i][k] != -99) {
	  printf("neg. precip at sta %d year %d line %d\n",i,year,k);
	  printf("reset to -99 for missing data\n");
	  prec[idx][i][k] = -99;
	}
      }
      /* write out the daily values for all stations one day at a time
	 except for feb 29th - unless leap year */
      if(LP != 0 || k != 60) {
	if((year > st_yr || k >= st_day) &&
	   (year < end_yr || k <= end_day)) {
	  for(i=1;i<=lines;i++){
	    prec[idx][i][k] *= intomm;
	    if(prec[idx][i][k]<=-99.00) prec[idx][i][k] = -99.00;
	    fprintf(fpoutf,"%7.2f ",prec[idx][i][k]);
	  }
	  fprintf(fpoutf,"\n");
	}
      }
    }

  }
  printf("closing files\n");
  fclose(fpinfo);
  fclose(fpappf);
  fclose(fpoutf);
  return(0);
}
Пример #8
0
void		patch_daily_I(
						  struct	world_object *world,
						  struct	basin_object *basin,
						  struct 	hillslope_object *hillslope,
						  struct  zone_object *zone,
						  struct patch_object *patch,
						  struct command_line_object *command_line,
						  struct	tec_entry	*event,
						  struct	date current_date)
{
	/*--------------------------------------------------------------*/
	/*  Local Function Declarations.                                */
	/*--------------------------------------------------------------*/
	void   canopy_stratum_daily_I(
		struct	world_object *,
		struct	basin_object *,
		struct 	hillslope_object *,
		struct  zone_object *,
		struct	patch_object *,
		struct canopy_strata_object *,
		struct command_line_object *,
		struct tec_entry *,
		struct date);
	
	double	compute_layer_field_capacity(
		int,
		int,
		double,
		double,
		double,
		double,
		double,
		double,
		double,
		double,
		double);
	
	
	double	compute_delta_water(
		int,
		double,
		double,
		double,
		double,
		double);

	double	compute_z_final(
		int,
		double,
		double,
		double,
		double,
		double);

	int	update_rootzone_moist(
		struct patch_object	*,
		struct	rooting_zone_object	*,
		struct command_line_object *);
	
	double	compute_capillary_rise(
		int,
		double,
		double,
		double,
		double,
		double);


	double  compute_potential_exfiltration(
		int,
		double,
		double,
		double,
		double,
		double,
		double,
		double,
		double);
	
	double  compute_soil_water_potential(
		int,
		int,
		double,
		double,
		double,
		double,
		double,
		double,
		double,
		double,
		double,
		double);
	
	int  compute_potential_decomp(
		double,
		double,
		double,
		double,
		double,
		struct  soil_c_object   *,
		struct  soil_n_object   *,
		struct  litter_c_object *,
		struct  litter_n_object *,
		struct  cdayflux_patch_struct *,
		struct  ndayflux_patch_struct *);
	
	void    sort_patch_layers(struct patch_object *);

		
	void	update_litter_interception_capacity (double, 
		double,
		struct litter_c_object *,
		struct litter_object *);

	int	zero_patch_daily_flux(
		struct	patch_object *,
		struct  cdayflux_patch_struct *,
		struct  ndayflux_patch_struct *);
	
	
	long julday( struct date);
	/*--------------------------------------------------------------*/
	/*  Local variable definition.                                  */
	/*--------------------------------------------------------------*/
	int	layer, inx;
	int	stratum;
	double	cnt, count, theta;
	
	double  edible_leafc, grazing_mean_nc, grazing_Closs;
	struct  canopy_strata_object *strata;
	struct  dated_sequence	clim_event;

	/*--------------------------------------------------------------*/
	/*	zero out daily fluxes					*/
	/*--------------------------------------------------------------*/
	if (zero_patch_daily_flux(patch, &(patch[0].cdf), &(patch[0].ndf))){
		fprintf(stderr,
			"Error in zero_patch_daily_flux() from patch_daily_I.c... Exiting\n");
		exit(EXIT_FAILURE);
	}


	
	/*-----------------------------------------------------*/
	/*  Compute potential saturation for rootzone layer   */
	/*-----------------------------------------------------*/			
	if (patch[0].rootzone.depth > ZERO)  {
	patch[0].rootzone.potential_sat = compute_delta_water(
		command_line[0].verbose_flag,
		patch[0].soil_defaults[0][0].porosity_0,
		patch[0].soil_defaults[0][0].porosity_decay,
		patch[0].soil_defaults[0][0].soil_depth,
		patch[0].rootzone.depth, 0.0);			
	 if (patch[0].rootzone.potential_sat > ZERO)
		if (patch[0].sat_deficit_z > patch[0].rootzone.depth)	
		patch[0].rootzone.S = patch[0].rz_storage/patch[0].rootzone.potential_sat;
		else
		patch[0].rootzone.S = min((patch[0].rz_storage + patch[0].rootzone.potential_sat - patch[0].sat_deficit)/patch[0].rootzone.potential_sat,1.0);
	else
		patch[0].rootzone.S = 0.0;
	}
	else  {
		patch[0].rootzone.potential_sat = 0.0;
		patch[0].rootzone.S = 0.0;
		}

	if (patch[0].sat_deficit < ZERO) 
		patch[0].S = 1.0;
	else
		patch[0].S = (patch[0].rz_storage+patch[0].unsat_storage)/patch[0].sat_deficit;
	
	/*--------------------------------------------------------------*/
	/*  compute standard deviation of theta based on soil parameters */
	/* assume no decay of porosity here 				*/
	/*--------------------------------------------------------------*/
	theta = patch[0].S * patch[0].soil_defaults[0][0].porosity_0;
	patch[0].theta_std = (patch[0].soil_defaults[0][0].theta_mean_std_p2*theta*theta + 
				patch[0].soil_defaults[0][0].theta_mean_std_p1*theta);

	/*--------------------------------------------------------------*/
	/*	compute new field capacity				*/
	/*--------------------------------------------------------------*/

	if (patch[0].sat_deficit_z < patch[0].rootzone.depth)  {
		patch[0].rootzone.field_capacity = compute_layer_field_capacity(
			command_line[0].verbose_flag,
			patch[0].soil_defaults[0][0].theta_psi_curve,
			patch[0].soil_defaults[0][0].psi_air_entry,
			patch[0].soil_defaults[0][0].pore_size_index,
			patch[0].soil_defaults[0][0].p3,
			patch[0].soil_defaults[0][0].p4,
			patch[0].soil_defaults[0][0].porosity_0,
			patch[0].soil_defaults[0][0].porosity_decay,
			patch[0].sat_deficit_z,
			patch[0].rootzone.depth, 0.0);				
			
		patch[0].field_capacity = 0.0;
	}
	else  {
		patch[0].rootzone.field_capacity = compute_layer_field_capacity(
			command_line[0].verbose_flag,
			patch[0].soil_defaults[0][0].theta_psi_curve,
			patch[0].soil_defaults[0][0].psi_air_entry,
			patch[0].soil_defaults[0][0].pore_size_index,
			patch[0].soil_defaults[0][0].p3,
			patch[0].soil_defaults[0][0].p4,
			patch[0].soil_defaults[0][0].porosity_0,
			patch[0].soil_defaults[0][0].porosity_decay,
			patch[0].sat_deficit_z,
			patch[0].rootzone.depth, 0.0);	

		patch[0].field_capacity = compute_layer_field_capacity(
			command_line[0].verbose_flag,
			patch[0].soil_defaults[0][0].theta_psi_curve,
			patch[0].soil_defaults[0][0].psi_air_entry,
			patch[0].soil_defaults[0][0].pore_size_index,
			patch[0].soil_defaults[0][0].p3,
			patch[0].soil_defaults[0][0].p4,
			patch[0].soil_defaults[0][0].porosity_0,
			patch[0].soil_defaults[0][0].porosity_decay,
			patch[0].sat_deficit_z,
			patch[0].sat_deficit_z, 0.0) - patch[0].rootzone.depth;
	}



	/*--------------------------------------------------------------*/
	/*	Estimate potential cap rise.				*/
	/*	limited to water in sat zone.				*/
	/*--------------------------------------------------------------*/
	patch[0].potential_cap_rise =	compute_capillary_rise(
		command_line[0].verbose_flag,
		patch[0].sat_deficit_z,
		patch[0].soil_defaults[0][0].psi_air_entry,
		patch[0].soil_defaults[0][0].pore_size_index,
		patch[0].soil_defaults[0][0].mz_v,
		patch[0].soil_defaults[0][0].Ksat_0_v );
	if (patch[0].potential_cap_rise < ZERO)
		patch[0].potential_cap_rise = 0.0;
	patch[0].cap_rise=0.0;



	/*--------------------------------------------------------------*/
	/*	Compute the max exfiltration rate.			*/
	/*								*/
	/*	First check if we are saturated.  If so the 		*/
	/*	potential exfiltration rate is the capillary rise rate.	*/
	/*								*/
	/*	If we are within the active unsat zone then we assume	*/
	/*	that the potential exfiltration rate is the minimum of	*/
	/*	the computed exfiltration rate and the potential cap	*/
	/*	rise - i.e. hydrologic connectivity between surface and	*/
	/*	water table.						*/
	/*								*/
	/*--------------------------------------------------------------*/
	if ( patch[0].sat_deficit_z <= patch[0].soil_defaults[0][0].psi_air_entry ){
		patch[0].potential_exfiltration = patch[0].potential_cap_rise;
	}
	else{
		if ( patch[0].soil_defaults[0][0].active_zone_z < patch[0].sat_deficit_z ){
			/*--------------------------------------------------------------*/
			/*	Estimate potential exfiltration from active zone 	*/
			/*--------------------------------------------------------------*/
			patch[0].potential_exfiltration = compute_potential_exfiltration(
				command_line[0].verbose_flag,
				patch[0].rootzone.S,
				patch[0].soil_defaults[0][0].active_zone_z,
				patch[0].soil_defaults[0][0].Ksat_0_v,
				patch[0].soil_defaults[0][0].mz_v,
				patch[0].soil_defaults[0][0].psi_air_entry,
				patch[0].soil_defaults[0][0].pore_size_index,
				patch[0].soil_defaults[0][0].porosity_decay,
				patch[0].soil_defaults[0][0].porosity_0);
		}
		else {
			/*--------------------------------------------------------------*/
			/*	Estimate potential exfiltration from active zone 	*/
			/*--------------------------------------------------------------*/
			patch[0].potential_exfiltration = compute_potential_exfiltration(
				command_line[0].verbose_flag,
				patch[0].rootzone.S,
				patch[0].sat_deficit_z,
				patch[0].soil_defaults[0][0].Ksat_0_v,
				patch[0].soil_defaults[0][0].mz_v,
				patch[0].soil_defaults[0][0].psi_air_entry,
				patch[0].soil_defaults[0][0].pore_size_index,
				patch[0].soil_defaults[0][0].porosity_decay,
				patch[0].soil_defaults[0][0].porosity_0);
		}
	}



	/*-----------------------------------------------------*/
	/* 	Check for any grazing activity from a land use default file			*/
	/*-----------------------------------------------------*/
	if (patch[0].base_stations != NULL) {
		inx = patch[0].base_stations[0][0].dated_input[0].grazing_Closs.inx;
		if (inx > -999) {
			clim_event = patch[0].base_stations[0][0].dated_input[0].grazing_Closs.seq[inx];
			while (julday(clim_event.edate) < julday(current_date)) {
				patch[0].base_stations[0][0].dated_input[0].grazing_Closs.inx += 1;
				inx = patch[0].base_stations[0][0].dated_input[0].grazing_Closs.inx;
				clim_event = patch[0].base_stations[0][0].dated_input[0].grazing_Closs.seq[inx];
				}
			if ((clim_event.edate.year != 0) && ( julday(clim_event.edate) == julday(current_date)) ) {
				grazing_Closs = clim_event.value;
				}
			else grazing_Closs = 0.0;
			} 
		else grazing_Closs = patch[0].landuse_defaults[0][0].grazing_Closs;
		}
	else grazing_Closs = patch[0].landuse_defaults[0][0].grazing_Closs;
	patch[0].grazing_Closs = grazing_Closs;

	/*--------------------------------------------------------------*/
	/*	Cycle through the canopy layers.			*/
	/*--------------------------------------------------------------*/
	edible_leafc = 0.0;
	grazing_mean_nc = 0.0;
	cnt = 0;
	for ( layer=0 ; layer<patch[0].num_layers; layer++ ){
		/*--------------------------------------------------------------*/
		/*	Cycle through the canopy strata				*/
		/*--------------------------------------------------------------*/
		for ( stratum=0 ; stratum<patch[0].layers[layer].count; stratum++ ){

			strata = patch[0].canopy_strata[(patch[0].layers[layer].strata[stratum])];
			patch[0].preday_rain_stored += strata->cover_fraction * strata->rain_stored;
			patch[0].preday_snow_stored += strata->cover_fraction * strata->snow_stored;
			if ((strata[0].defaults[0][0].epc.edible == 1) && (strata[0].cs.leafc > ZERO)) {
				edible_leafc += strata->cs.leafc * strata->cover_fraction;
				cnt += 1;
				grazing_mean_nc += strata->ns.leafn/strata->cs.leafc * strata->cover_fraction;
				}
			canopy_stratum_daily_I(
				world,
				basin,
				hillslope,
				zone,
				patch,
				patch[0].canopy_strata[(patch[0].layers[layer].strata[stratum])],
				command_line,
				event,
				current_date );
		}
	}
	patch[0].grazing_Closs = min(edible_leafc, patch[0].grazing_Closs);
	if (cnt > 0)
		patch[0].grazing_mean_nc = grazing_mean_nc / cnt;

	/*--------------------------------------------------------------*/
	/*	Calculate effective patch lai from stratum					*/
	/*	- for later use by zone_daily_F								*/
	/*      Accumulate root biomass for patch soil -
	/*      required for N updake from soil                         */
	/*	also determine total plant carbon			*/
	/*	- if grow option is specified				*/
	/*--------------------------------------------------------------*/
	patch[0].effective_lai = 0.0;
	patch[0].soil_cs.frootc = 0.0;
	patch[0].rootzone.depth = 0.0;
	count = 0.0;
	for ( stratum=0 ; stratum<patch[0].num_canopy_strata; stratum++){
		patch[0].effective_lai += patch[0].canopy_strata[stratum][0].epv.proj_lai;
		if (command_line[0].grow_flag > 0) {
			patch[0].soil_cs.frootc
				+= patch[0].canopy_strata[stratum][0].cover_fraction
				* patch[0].canopy_strata[stratum][0].cs.frootc;
			patch[0].preday_totalc
				+= patch[0].canopy_strata[stratum][0].cover_fraction
				* patch[0].canopy_strata[stratum][0].cs.preday_totalc;
			patch[0].preday_totaln
				+= patch[0].canopy_strata[stratum][0].cover_fraction
				* patch[0].canopy_strata[stratum][0].ns.preday_totaln;
				
				
		}
		patch[0].rootzone.depth = max(patch[0].rootzone.depth, 
			 patch[0].canopy_strata[stratum][0].rootzone.depth);
	}
	patch[0].effective_lai = patch[0].effective_lai / patch[0].num_canopy_strata;
	/*--------------------------------------------------------------*/
	/*	re-sort patch layers to account for any changes in 	*/
	/*	height							*/
	/*------------------------------------------------------------------------*/
	sort_patch_layers(patch);


	/*------------------------------------------------------------------------*/
	/*	compute current soil moisture potential					*/
	/*	do this before nitrogen updake occurs later in the day			*/
	/*------------------------------------------------------------------------*/
	patch[0].psi = compute_soil_water_potential(
		command_line[0].verbose_flag,
		patch[0].soil_defaults[0][0].theta_psi_curve,
		patch[0].Tsoil,
		-1.0*patch[0].soil_defaults[0][0].psi_max,
		-10.0,
		patch[0].soil_defaults[0][0].psi_air_entry,
		patch[0].soil_defaults[0][0].pore_size_index,
		patch[0].soil_defaults[0][0].p3,
		patch[0].soil_defaults[0][0].p4,
		patch[0].soil_defaults[0][0].porosity_0,
		patch[0].soil_defaults[0][0].porosity_decay,
		patch[0].S);


	if (command_line[0].grow_flag > 0) {

		/*--------------------------------------------------------------*/
		/*	update litter interception capacity			*/
		/*--------------------------------------------------------------*/
		update_litter_interception_capacity(
			patch[0].litter.moist_coef,
			patch[0].litter.density,
			&(patch[0].litter_cs),
			&(patch[0].litter));

	
		if (compute_potential_decomp(
			patch[0].Tsoil,
			patch[0].soil_defaults[0][0].psi_max,
			patch[0].soil_defaults[0][0].psi_air_entry,
			patch[0].rootzone.S,
			patch[0].theta_std,
			&(patch[0].soil_cs),
			&(patch[0].soil_ns),
			&(patch[0].litter_cs),
			&(patch[0].litter_ns),
			&(patch[0].cdf),
			&(patch[0].ndf)
			) != 0){
			fprintf(stderr,"fATAL ERROR: in compute_potential_decomp() ... Exiting\n");
			exit(EXIT_FAILURE);
		}
	}



	return;
}/*end patch_daily_I.c*/
Пример #9
0
/*--------------------------------------------------------------------*\
 | FUNCTION     : djulian
 | COMMENT		:
 | PARAMETERS   :
 | RETURN VALUE : 
 | RESTRICTIONS :
\*--------------------------------------------------------------------*/
double djulian (char *when, char *type) {

  DATETIME *time, reftime;

  /*
   * set time according to when argument
   */

  if (!strcmp(when, "start"))
    time = Mstrttime;
  else if(!strcmp(when, "end"))
    time = Mendtime;
  else if (!strcmp(when, "now"))
    time = Mnowtime;
  else {
    (void)fprintf(stderr,
	    "ERROR - julian - illegal argument '%s'.\n", when);
    exit(1);
  }

  /*
   * set reftime depending on type arg
   */

  if (!strcmp(type, "calendar")) {
    reftime.year = time->year - 1;
    reftime.month = 12;
    reftime.day = 31;
  } else if(!strcmp(type, "solar")) {
    if ((time->month == 12) && (time->day > 21))
      reftime.year = time->year;
    else
      reftime.year = time->year - 1;
    reftime.month = 12;
    reftime.day = 21;
  } else if (!strcmp(type, "water")) {
    if (time->month > 9)
      reftime.year = time->year;
    else
      reftime.year = time->year - 1;
    reftime.month = 9;
    reftime.day = 30;
  } else if(!strcmp(type, "absolute")) {
    julday(time);
    return (time->jt);
  } else {
    (void)fprintf(stderr,
	    "ERROR - julian - illegal argument '%s'.\n", type);
    exit(1);
  }

  reftime.hour = 0;
  reftime.min = 0;
  reftime.sec = 0;

  /*
   * compute the julian dates
   */

  julday(time);
  julday(&reftime);

  return (time->jt - reftime.jt);

}
Пример #10
0
void union_date_init(struct world_object * world,
		      struct base_station_object * base_station){
  /*-----------------------------------------------------------------------------
   *  Local function definition
   *-----------------------------------------------------------------------------*/  
   void *alloc(size_t,char *, char *);
   long julday(struct date);
  /*-----------------------------------------------------------------------------
   *  Local variable definition
   *-----------------------------------------------------------------------------*/
  int i,inx,num_d;
  int year, month, day;
  int num_base_stations;
  int start_inx;
  struct hourly_clim_object *hourly;
  struct date start_date;
  struct date end_date;
  struct date prev_date;
  /*-----------------------------------------------------------------------------
   *  Initiliaze the local variables
   *-----------------------------------------------------------------------------*/

  i=0;
  inx=0;
  num_d=0; //inx store the number of days which has hourly precipitation in this station
  year=0;
  month=0;
  day=0;
  hourly = base_station[0].hourly_clim;
  start_date = world[0].start_date;
  end_date = world[0].end_date;
  start_inx =0;
  /*-----------------------------------------------------------------------------
   *  1. Total number of days which has hourly record (even it is 0)
   *-----------------------------------------------------------------------------*/

   /* if there no hourly data in that base station, use the first day in the daily data*/
  if(hourly[0].rain.inx ==-999){ // no hourly precipitation record
    num_d = 0;
  }else if(julday(end_date)<julday(hourly[0].rain.seq[0].edate)){  
  /*during this period, there is no hourly record*/
    num_d = 0;
  }else if(julday(start_date)<=julday(hourly[0].rain.seq[0].edate)){ 
     /*the date of first hourly record is earlier than the end date*/
    /* need to find out whether is any hourly record between start_date and end_date */
    prev_date = hourly[0].rain.seq[0].edate;
    start_inx = 0;
    num_d = 1;
    i=1;
    while(hourly[0].rain.seq[i].edate.year !=0 && (julday(hourly[0].rain.seq[i].edate)<=julday(end_date))){
	if (julday(prev_date)<julday(hourly[0].rain.seq[i].edate)){
	  // it is a new day
	  num_d = num_d + 1;
	  prev_date=hourly[0].rain.seq[i].edate;
	}
	  i = i+1;
    }
      
  }
  else{  
  /* the date of the first hourly record is ealier than the start date */
    i=1;
    prev_date=hourly[0].rain.seq[0].edate;
    while(hourly[0].rain.seq[i].edate.year!=0 && (julday(hourly[0].rain.seq[i].edate)<julday(start_date))){
	prev_date=hourly[0].rain.seq[i].edate;
	i=i+1;
    }
    if (hourly[0].rain.seq[i].edate.year ==0){
      /* the date of the latest hourly date is earlier than the start_date */
      num_d=0;
    }
    else{
      num_d=0;
      
      while(hourly[0].rain.seq[i].edate.year!=0 && (julday(hourly[0].rain.seq[i].edate)<=julday(end_date))){
	if (julday(prev_date)<julday(hourly[0].rain.seq[i].edate)){
	  /* if start a new day */
	  num_d = num_d + 1;
	  if(num_d==1) start_inx=i;
	  prev_date=hourly[0].rain.seq[i].edate;
	}
	i=i+1;
      }
    }

  }



  /*-----------------------------------------------------------------------------
   *  2. Create space for the num_d date 
   *  3. use master_hourly_date to store these dates
   *-----------------------------------------------------------------------------*/
    num_base_stations=world[0].num_base_stations;
    world[0].master_hourly_date = (struct date **)alloc( 1 * sizeof(struct date *),
					"master_hourly_date","union_date_init");
    
 
    if(num_d==0){

	world[0].master_hourly_date[0] = (struct date *)alloc( 1 * sizeof(struct date),
					 "master_hourly_date_[i]","union_date_init");
	world[0].master_hourly_date[0][0].year = start_date.year;
	world[0].master_hourly_date[0][0].month = start_date.month;
	world[0].master_hourly_date[0][0].day = start_date.day;
    }
    else{
	world[0].master_hourly_date[0] = (struct date *)alloc( num_d * sizeof(struct date),
					 "master_hourly_date_[i]","union_date_init");
	for(i=0;i<num_d;i++){
	    world[0].master_hourly_date[0][i].year = hourly[0].rain.seq[i*24+start_inx].edate.year;
	    world[0].master_hourly_date[0][i].month = hourly[0].rain.seq[i*24+start_inx].edate.month;
	    world[0].master_hourly_date[0][i].day = hourly[0].rain.seq[i*24+start_inx].edate.day;

	    printf("\n i = %d, date =%d %d %d\n",i, world[0].master_hourly_date[0][i].year,
	    world[0].master_hourly_date[0][i].month,world[0].master_hourly_date[0][i].day);
	}

    }
  
  //printf("\nyear = %d, month = %d, day = %d\n",year, month, day);
  printf("\n num_day = %d,start_inx=%d\n",num_d,start_inx);

}
Пример #11
0
void	canopy_stratum_daily_F(
							   struct	world_object		*world,
							   struct	basin_object		*basin,
							   struct	hillslope_object	*hillslope, 
							   struct	zone_object		*zone,
							   struct	patch_object		*patch,
							   struct  layer_object		*layer,
							   struct 	canopy_strata_object 	*stratum,
							   struct 	command_line_object	*command_line,
							   struct	tec_entry		*event,
							   struct 	date 			current_date)
{
	/*--------------------------------------------------------------*/
	/*	Local function declaration				*/
	/*--------------------------------------------------------------*/
	long	julday(struct date calendar_date);
	
	double	compute_diffuse_radiative_fluxes(
		int,
		double *,
		double,
		double,
		double,
		double,
		double,
		double);
	
	double	compute_diffuse_radiative_PAR_fluxes(
		int	,
		double	*,
		double	,
		double	,
		double	,
		double	,
		double	,
		double	);
	
	double	compute_direct_radiative_fluxes(
		int	,
		double	*,
		double	,
		double	,
		double	,
		double	,
		double	,
		double	);
	
	
	int	compute_maint_resp(	double,
		double,
		struct  cstate_struct *,
		struct  nstate_struct *,
		struct epconst_struct *,
		struct  metvar_struct *,
		struct cdayflux_struct *);
	
	double	 compute_snow_stored(
		int	,
		double	,
		double	,
		double	*,
		double	*,
		struct	canopy_strata_object *);
	
	double	 compute_rain_stored(
		int	,
		double	*,
		struct	canopy_strata_object *);
	
	double  compute_ra_overstory(
		int     ,
		double  ,
		double *,
		double  ,
		double  ,
		double	,
		double *);
	
	double  compute_ra_understory(
		int     ,
		double  ,
		double *,
		double  ,
		double  ,
		double  *);
	
	double  compute_ra_surface(
		int     ,
		double  ,
		double *,
		double  ,
		double  ,
		double  *);
	
	double	compute_vascular_stratum_conductance(
		int	,
		int	,
		double	,
		double	,
		double	,
		double	,
		double	,
		double	,
		double	,
		double	,
		double	,
		double	,
		double	,
		double	,
		double	,
		double	,
		double	,
		double	,
		double	,
		double	,
		double	,
		double	,
		double	,
		double, int,
		struct canopy_strata_object *,
		struct patch_object *);
	
	double	compute_nonvascular_stratum_conductance(
		int	,
		double	,
		double	,
		double	,
		double	,
		double	);
	
	double	compute_surface_heat_flux(
		int	,
		double	,
		double	,
		double	,
		double	,
		double	,
		double	,
		double	,
		double	,
		double	);
	
	double	penman_monteith(
		int	,
		double	,
		double	,
		double	,
		double	,
		double	,
		double	,
		int	);
	
	int	compute_farq_psn(
		struct psnin_struct * ,
		struct psnout_struct * ,
		int);
	
	double	compute_potential_N_uptake_Dickenson(
		struct	epconst_struct,
		struct	epvar_struct *,
		struct cstate_struct *cs,
		struct nstate_struct *ns,
		struct cdayflux_struct *);

	double	compute_potential_N_uptake_Waring(
		struct	epconst_struct,
		struct	epvar_struct *,
		struct cstate_struct *cs,
		struct nstate_struct *ns,
		struct cdayflux_struct *);

	double	compute_potential_N_uptake(
		struct	epconst_struct,
		struct	epvar_struct *,
		struct cstate_struct *cs,
		struct nstate_struct *ns,
		struct cdayflux_struct *);

	void	update_mortality(
		struct epconst_struct,
		struct cstate_struct *,
		struct cdayflux_struct *,
		struct cdayflux_patch_struct *,
		struct nstate_struct *,
		struct ndayflux_struct *,
		struct ndayflux_patch_struct *,
		struct litter_c_object *,
		struct litter_n_object *,
		int,
		struct mortality_struct);
	/*--------------------------------------------------------------*/
	/*  Local variable definition.                                  */
	/*--------------------------------------------------------------*/
	double tmid;
	double  assim_sunlit;
	double  assim_shade;
	double	dC13_sunlit, dC13_shade;
	double  APAR_direct_sunlit;
	double	dry_evaporation;
	double	ga;
	double	Kdown_direct;
	double	Kdown_diffuse;
	double	PAR_diffuse;
	double	PAR_direct;
	double  total_incoming_PAR;
	double	perc_sunlit;
	double	potential_evaporation_rate;
	double	potential_rainy_evaporation_rate;
	double	rainy_evaporation;
	double	rain_throughfall;
	double	rnet_evap;
	double	rnet_trans, rnet_trans_sunlit, rnet_trans_shade;
	double	snow_throughfall;
	double	transpiration;
	double	transpiration_rate;
	double	transpiration_rate_sunlit;
	double	transpiration_rate_shade;
	double	potential_transpiration;
	double	potential_transpiration_rate;
	double	potential_transpiration_rate_sunlit;
	double	potential_transpiration_rate_shade;
	double  wind;
	double leafcloss_perc;

	double m_APAR_sunlit;
	double m_tavg_sunlit;
	double m_LWP_sunlit;
	double m_CO2_sunlit;
	double m_tmin_sunlit;
	double m_vpd_sunlit;
	double m_APAR_shade;
	double m_tavg_shade;
	double m_LWP_shade;
	double m_CO2_shade;
	double m_tmin_shade;
	double m_vpd_shade;


	struct	psnin_struct	psnin;
	struct	psnout_struct	psnout;
	struct mortality_struct mort;


	if ( command_line[0].verbose_flag > 1 )
		printf("\n%8d -444.1 ",julday(current_date)-2449000);
	if ( command_line[0].verbose_flag > 1 )
		printf("%8.2f %8.2f %8.2f %8.2f ",
		patch[0].Kdown_direct,
		patch[0].Kdown_diffuse,
		patch[0].PAR_direct/1000,
		patch[0].PAR_diffuse/1000);
	/*--------------------------------------------------------------*/
	/*	Initialize stratum variables.				*/
	/*--------------------------------------------------------------*/
	stratum[0].Kstar_diffuse = 0.0;
	stratum[0].APAR_diffuse = 0.0;
	stratum[0].Kstar_direct = 0.0;
	stratum[0].APAR_direct = 0.0;
	stratum[0].potential_evaporation = 0.0;
	 m_APAR_sunlit=0.0;
	 m_tavg_sunlit=0.0;
	 m_LWP_sunlit=0.0;
	 m_CO2_sunlit=0.0;
	 m_tmin_sunlit=0.0;
	 m_vpd_sunlit=0.0;
	 m_APAR_shade=0.0;
	 m_tavg_shade=0.0;
	 m_LWP_shade=0.0;
	 m_CO2_shade=0.0;
	 m_tmin_shade=0.0;
	 m_vpd_shade=0.0;
	stratum[0].mult_conductance.vpd = 0.0;
	stratum[0].mult_conductance.tmin = 0.0;
	stratum[0].mult_conductance.tavg = 0.0;
	stratum[0].mult_conductance.CO2 = 0.0;
	stratum[0].mult_conductance.LWP = 0.0;
	stratum[0].mult_conductance.APAR = 0.0;

	/*--------------------------------------------------------------*/
	/*	Initialize temporary variables for transmitted fluxes.	*/
	/*--------------------------------------------------------------*/
	Kdown_diffuse = patch[0].Kdown_diffuse ;
	PAR_diffuse = patch[0].PAR_diffuse;
	Kdown_direct = patch[0].Kdown_direct;
	PAR_direct = patch[0].PAR_direct;
	rain_throughfall = patch[0].rain_throughfall;
	snow_throughfall = patch[0].snow_throughfall;
	ga = patch[0].ga;
	wind  = patch[0].wind;
	transpiration = 0.0;
	potential_transpiration = 0.0;
	rainy_evaporation = 0;
	dry_evaporation = 0;
	total_incoming_PAR = PAR_diffuse + PAR_direct;


	
	/*--------------------------------------------------------------*/
	/*	perform plant grazing losses				*/
	/*	(if grow flag is on)					*/
	/*--------------------------------------------------------------*/
	if ((stratum[0].cs.leafc > ZERO) && (patch[0].grazing_Closs > ZERO) && command_line[0].grow_flag == 1 ) {
			leafcloss_perc  = patch[0].grazing_Closs * (stratum[0].ns.leafn/stratum[0].cs.leafc)
						 / patch[0].grazing_mean_nc / stratum[0].cs.leafc;
			mort.mort_leafc  = leafcloss_perc;
			mort.mort_cpool = 0.0;
			mort.mort_deadleafc = 0.0;
			mort.mort_livestemc = 0.0;
			mort.mort_deadstemc = 0.0;
			mort.mort_livecrootc = 0.0;
			mort.mort_deadcrootc = 0.0;
			mort.mort_frootc = 0.0;
			update_mortality(stratum[0].defaults[0][0].epc,
				&(stratum[0].cs),
				&(stratum[0].cdf),
				&(patch[0].cdf),
				&(stratum[0].ns),
				&(stratum[0].ndf),
				&(patch[0].ndf),
				&(patch[0].litter_cs),
				&(patch[0].litter_ns),
				2,
				mort);
			printf("\n completed %lf from %lf", leafcloss_perc, stratum[0].cs.leafc);
		
	}

	/*	NEW CHECK TO SEE IF STRATUM IS VEGETATED, OTHERWISE SKIP	*/
	/*	TO END TO UPDATE RADIATION BY COVER FRACTION				*/
	
	if (stratum[0].defaults[0][0].epc.veg_type != NON_VEG) {
	
	/*--------------------------------------------------------------*/
	/*  Intercept diffuse radiation.                                */
	/*  We assume that the zone slope == patch slope.               */
	/*  We also assume that radiation reflected into the upper      */
	/*      hemisphere is lost.                                     */
	/*  We do not make adjustements for chaanging gap fraction over */
	/*      the diurnal cycle - using a suitable mean gap fraction  */
	/*      instead.                                                */
	/*  We do take into account the patch level horizon which will  */
	/*      allow simulation of clear-cuts/clearings with low sza's */
	/*  Note that for zone level temperature and radiation          */
	/*      computation we took into account only zone level horizon*/
	/*      since we figured that climate above the zone was well   */
	/*      mixed.                                                  */
	/*--------------------------------------------------------------*/
	if ( command_line[0].verbose_flag > 2 ){
		printf("\n%4d %4d %4d -444.4 \n",
			current_date.day, current_date.month, current_date.year);
		printf("\n %f %f %f %f %f %f %f",
			Kdown_diffuse,
			Kdown_direct,
			-1*stratum[0].defaults[0][0].epc.ext_coef,
			stratum[0].gap_fraction,
			stratum[0].epv.proj_pai,
			basin[0].theta_noon,
			stratum[0].defaults[0][0].K_reflectance);
		printf("\n%4d %4d %4d -444.4b \n",
			current_date.day, current_date.month, current_date.year);
	}
	stratum[0].Kstar_diffuse = compute_diffuse_radiative_fluxes(
		command_line[0].verbose_flag,
		&(Kdown_diffuse),
		Kdown_direct,
		-1*stratum[0].defaults[0][0].epc.ext_coef,
		stratum[0].gap_fraction,
		stratum[0].epv.proj_pai,
		basin[0].theta_noon,
		stratum[0].defaults[0][0].K_reflectance);
	if ( command_line[0].verbose_flag > 2 )
		printf("\n%8d -444.5 ",julday(current_date)-2449000);
	stratum[0].APAR_diffuse = compute_diffuse_radiative_PAR_fluxes(
		command_line[0].verbose_flag,
		&(PAR_diffuse),
		PAR_direct,
		-1*stratum[0].defaults[0][0].epc.ext_coef,
		stratum[0].gap_fraction,
		stratum[0].epv.proj_lai,
		basin[0].theta_noon,
		stratum[0].defaults[0][0].PAR_reflectance);
	/*--------------------------------------------------------------*/
	/*  Intercept direct radiation.                                 */
	/*      hard to measure for each strata.  We could use top      */
	/*      of canopy albedo but this integrates the effect of the  */
	/*      entire canopy.  Furthermore, it requires in general     */
	/*      knowledge of the canopy BRDF - which we want to avoid.  */
	/*      Instead we assume a certain reflectance and             */
	/*      transmittance for each strata's canopy elements.        */
	/*  We assume that the zone slope == patch slope.               */
	/*  We also assume that radiation reflected into the upper      */
	/*      hemisphere is lost.                                     */
	/*  We do not make adjustements for chaanging gap fraction over */
	/*      the diurnal cycle - using a suitable mean gap fraction  */
	/*      instead.                                                */
	/*  We do take into account the patch level horizon which will  */
	/*      allow simulation of clear-cuts/clearings with low sza's */
	/*  Note that for zone level temperature and radiation          */
	/*      computation we took into account only zone level horizon*/
	/*      since we figured that climate above the zone was well   */
	/*      mixed.                                                  */
	/*--------------------------------------------------------------*/
	if ( command_line[0].verbose_flag > 2 )
		printf("\n%8d -444.2 ",julday(current_date)-2449000);
	stratum[0].Kstar_direct = compute_direct_radiative_fluxes(
		command_line[0].verbose_flag,
		&(Kdown_direct),
		-1*stratum[0].defaults[0][0].epc.ext_coef,
		stratum[0].gap_fraction,
		stratum[0].epv.proj_pai,
		basin[0].theta_noon,
		stratum[0].defaults[0][0].K_reflectance,
		stratum[0].defaults[0][0].K_reflectance);


	if ( command_line[0].verbose_flag >2  )
		printf("\n%d %d %d  -444.3 ",
		current_date.year, current_date.month, current_date.day);
	stratum[0].APAR_direct = compute_direct_radiative_fluxes(
		command_line[0].verbose_flag,
		&(PAR_direct),
		-1*stratum[0].defaults[0][0].epc.ext_coef,
		stratum[0].gap_fraction,
		stratum[0].epv.proj_pai,
		basin[0].theta_noon,
		stratum[0].defaults[0][0].PAR_reflectance,
		stratum[0].defaults[0][0].PAR_reflectance);



	/*--------------------------------------------------------------*/
	/*	record fraction of PAR absorption 			*/
	/*	and seasonal low water content				*/
	/*	(for use in dynamic version to limit allocation)	*/
	/*--------------------------------------------------------------*/
	stratum[0].epv.min_vwc = min((patch[0].unsat_storage / patch[0].sat_deficit),
		stratum[0].epv.min_vwc);
	if ( command_line[0].verbose_flag >2  )
		printf("\n fparabs %f min_vwc %f",stratum[0].epv.max_fparabs,
		stratum[0].epv.min_vwc);
	if ( command_line[0].verbose_flag > 1 )
		printf("\n%8d -444.6 ",julday(current_date)-2449000);
	/*--------------------------------------------------------------*/
	/*	Compute conductance aerodynamic.			*/
	/*--------------------------------------------------------------*/
	if ( patch[0].snowpack.height <= stratum[0].epv.height ){
		/*--------------------------------------------------------------*/
		/*		Compute by brute force if usrat_overu given.	*/
		/*--------------------------------------------------------------*/
		if ( stratum[0].defaults[0][0].ustar_overu == -999.9 ){
			/*--------------------------------------------------------------*/
			/*		Highest layer in patch.				*/
			/*--------------------------------------------------------------*/
			if ( stratum[0].epv.height == patch[0].layers[0].height ){
				stratum[0].ga = 1.0 / compute_ra_overstory(
					command_line[0].verbose_flag,
					stratum[0].defaults[0][0].wind_attenuation_coeff,
					&(wind),
					zone[0].base_stations[0][0].screen_height,
					stratum[0].epv.height,
					layer[0].base,
					&(ga));
			}
			/*--------------------------------------------------------------*/
			/*		Layer is not the highest and is >0.1highest ht.	*/
			/*--------------------------------------------------------------*/
			else if (stratum[0].epv.height > (patch[0].layers[0].height * 0.1) ){
				stratum[0].ga = 1.0 / compute_ra_understory(
					command_line[0].verbose_flag,
					stratum[0].defaults[0][0].wind_attenuation_coeff,
					&(wind),
					stratum[0].epv.height,
					layer[0].base,
					&(ga));
			}
			/*--------------------------------------------------------------*/
			/*		Layer is <0.1highest ht. in height.		*/
			/*--------------------------------------------------------------*/
			else{
				stratum[0].ga = 1.0 /
					compute_ra_surface(
					command_line[0].verbose_flag,
					stratum[0].defaults[0][0].wind_attenuation_coeff,
					&(wind),
					stratum[0].epv.height,
					layer[0].base,
					&(ga));
			}
		}
		else{

			stratum[0].ga =
				pow(zone[0].wind * stratum[0].defaults[0][0].ustar_overu,2.0);
			ga = stratum[0].ga;
		}
	}
	else{
		stratum[0].ga = 0.0;
	}
	/*--------------------------------------------------------------*/
	/*	Factor in stability correction.				*/
	/*--------------------------------------------------------------*/
	stratum[0].ga = stratum[0].ga * patch[0].stability_correction ;
	if ( command_line[0].verbose_flag > 1 )
		printf("%8.6f ",stratum[0].ga);
	if ( command_line[0].verbose_flag > 1 )
		printf("\n%8d -444.8 ",julday(current_date)-2449000);

	/*--------------------------------------------------------------*/
	/*	Determine non-vascular condductance to evaporation.		*/
	/*	This conductance represnets the inverse of an additional 	*/
	/*	resistance to vapour flux from the stratum rian storage		*/
	/*	surface over and above aerodynamic resistances that also	*/
	/*	affect turbulent heat transfer.  						 	*/
	/*	                            								*/
	/*	A linear relationship is currently assumed with the amount	*/
	/*	of relative rain stored - or with the patch unsat zone storage  */
	/*	relative to water equiv depth top water table if roots are present */
	/*	.  Parameters for the relationship	*/
	/*	are supplied via the stratum default file.					*/
	/*--------------------------------------------------------------*/
	if ( stratum[0].epv.all_pai > 0 ){
		stratum[0].gsurf = compute_nonvascular_stratum_conductance(
			command_line[0].verbose_flag,
			stratum[0].rain_stored+rain_throughfall,
			stratum[0].epv.all_pai
			* stratum[0].defaults[0][0].specific_rain_capacity,
			stratum[0].defaults[0][0].epc.gl_c,
			stratum[0].defaults[0][0].gsurf_slope,
			stratum[0].defaults[0][0].gsurf_intercept);
	}
	else{
		stratum[0].gsurf = compute_nonvascular_stratum_conductance(
			command_line[0].verbose_flag,
			patch[0].unsat_storage+rain_throughfall,
			patch[0].sat_deficit,
			stratum[0].defaults[0][0].epc.gl_c,
			stratum[0].defaults[0][0].gsurf_slope,
			stratum[0].defaults[0][0].gsurf_intercept);
	}

	if ( command_line[0].verbose_flag > 1 )
		printf("%8.6f ",stratum[0].gs);
	if ( command_line[0].verbose_flag > 1 )
		printf("\n%4d %4d %4d -444.9 \n ",
		current_date.day, current_date.month, current_date.year);
	if ( command_line[0].verbose_flag > 1 )
		printf("%8.4f %8.4f %8.4f %8.4f \n ",
		stratum[0].Kstar_direct,stratum[0].Kstar_diffuse,
		stratum[0].APAR_direct,stratum[0].APAR_diffuse);
	if ( command_line[0].verbose_flag > 1 ) {
		printf("\n%4d %4d %4d -444.9.1 \n ",current_date.day, current_date.month,
			current_date.year);
		printf(" %f\n", stratum[0].snow_stored);
	}
	/*--------------------------------------------------------------*/
	/*	Update snow storage ( this also updates the patch level	*/
	/*	snow throughfall and the stratum level Kstar )	 	*/
	/*	Snow on the canopy is first sublimated before any ET	*/
	/*	can take place.  This may seem like we are hobbling	*/
	/*	the energy budget since the sublimation reduces the	*/
	/*	energy used for stomatal conductance etc. however we	*/
	/*	suggest that when it snows it is likely ET is small.	*/
	/*--------------------------------------------------------------*/
	stratum[0].snow_stored = compute_snow_stored(
		command_line[0].verbose_flag,
		zone[0].metv.tday,
		1000.0,
		&(snow_throughfall),
		&(rain_throughfall),
		stratum);
	if ( command_line[0].verbose_flag > 1 )
		printf("\n%8.4f %f ",stratum[0].snow_stored, stratum[0].sublimation);
	if ( command_line[0].verbose_flag > 1 )
		printf("\n%8d -444.10 ",julday(current_date)-2449000);
	if ( command_line[0].verbose_flag > 1 )
		printf("%8.4f %8.4f %8.4f %8.4f ",stratum[0].Kstar_direct,
		stratum[0].Kstar_diffuse,stratum[0].APAR_direct,
		stratum[0].APAR_diffuse);


	if (stratum[0].epv.proj_lai > ZERO)
		perc_sunlit = (stratum[0].epv.proj_lai_sunlit)/(stratum[0].epv.proj_lai);
	else
		perc_sunlit = 1.0;

	if (stratum[0].epv.proj_lai_shade > ZERO && zone[0].metv.dayl > ZERO)
		stratum[0].ppfd_shade = (stratum[0].APAR_diffuse * (1-perc_sunlit)) / 
					zone[0].metv.dayl /stratum[0].epv.proj_lai_shade;
	else
		stratum[0].ppfd_shade = 0.0;

	if (stratum[0].epv.proj_lai_sunlit > ZERO && zone[0].metv.dayl > ZERO)
		stratum[0].ppfd_sunlit = (stratum[0].APAR_direct + stratum[0].APAR_diffuse * perc_sunlit) / 
					zone[0].metv.dayl /stratum[0].epv.proj_lai_sunlit;
	else
		stratum[0].ppfd_sunlit = 0.0;

	/*--------------------------------------------------------------*/
	/*	Compute stratum conductance	m/s			*/
	/*								*/
	/*								*/
	/*	Note that the APAR supplied reduces to the rate of	*/
	/*	APAR (kJ/sec) absorbed during the daytime.  We do this	*/
	/*	since:							*/
	/*								*/
	/*	gs is only meaningful in the day			*/
	/*	gs responds to the instantaneous rather than daily	*/
	/*		averaged APAR.  				*/
	/*								*/
	/*	Also note that we will not void a shorwtwave energy	*/
	/*	budget since stratum conductance is used to scale 	*/
	/*	potnetial_evaporation; which we make sure is limited	*/
	/*	by the available energy. 				*/
	/*								*/
	/*	Note: PAR values are converted fro umol photon/m2*day to*/
	/*		umol photon/m2*sec				*/
	/*--------------------------------------------------------------*/
	/*
	if ( command_line[0].verbose_flag > 1 )
		printf("%f ",stratum[0].APAR_direct/zone[0].metv.dayl+
		stratum[0].APAR_diffuse/zone[0].metv.dayl);
	/*--------------------------------------------------------------*/
	/*								*/
	/*	if there is still snow sitting on the canopy gs should be zero */
	/*								*/
	/*--------------------------------------------------------------*/

	if (stratum[0].snow_stored < ZERO)  {

	stratum[0].gs_sunlit = compute_vascular_stratum_conductance(
		command_line[0].verbose_flag,
		stratum[0].defaults[0][0].epc.psi_curve,
		stratum[0].defaults[0][0].epc.ppfd_coef,
		stratum[0].defaults[0][0].epc.gl_c,
		stratum[0].defaults[0][0].lai_stomatal_fraction,
		stratum[0].defaults[0][0].epc.psi_open,
		stratum[0].defaults[0][0].epc.psi_close,
		stratum[0].defaults[0][0].epc.psi_threshold,
		stratum[0].defaults[0][0].epc.psi_slp,
		stratum[0].defaults[0][0].epc.psi_intercpt,
		stratum[0].defaults[0][0].epc.gl_smax,
		stratum[0].defaults[0][0].epc.topt,
		stratum[0].defaults[0][0].epc.tcoef,
		stratum[0].defaults[0][0].epc.tmax,
		stratum[0].defaults[0][0].epc.vpd_open,
		stratum[0].defaults[0][0].epc.vpd_close,
		stratum[0].ppfd_sunlit,
		stratum[0].epv.proj_lai_sunlit,
		stratum[0].epv.psi,
		zone[0].metv.tsoil,
		zone[0].metv.tday,
		zone[0].metv.vpd, zone[0].CO2,
		stratum[0].defaults[0][0].epc.coef_CO2,
		stratum[0].ID,
		stratum, patch);

	m_APAR_sunlit = stratum[0].mult_conductance.APAR;
	m_tavg_sunlit = stratum[0].mult_conductance.tavg;
	m_LWP_sunlit = stratum[0].mult_conductance.LWP;
	m_CO2_sunlit = stratum[0].mult_conductance.CO2;
	m_tmin_sunlit = stratum[0].mult_conductance.tmin;
	m_vpd_sunlit = stratum[0].mult_conductance.vpd;


	stratum[0].potential_gs_sunlit = compute_vascular_stratum_conductance(
		command_line[0].verbose_flag,
		stratum[0].defaults[0][0].epc.psi_curve,
		stratum[0].defaults[0][0].epc.ppfd_coef,
		stratum[0].defaults[0][0].epc.gl_c,
		stratum[0].defaults[0][0].lai_stomatal_fraction,
		stratum[0].defaults[0][0].epc.psi_open,
		stratum[0].defaults[0][0].epc.psi_close,
		stratum[0].defaults[0][0].epc.psi_threshold,
		stratum[0].defaults[0][0].epc.psi_slp,
		stratum[0].defaults[0][0].epc.psi_intercpt,
		stratum[0].defaults[0][0].epc.gl_smax,
		stratum[0].defaults[0][0].epc.topt,
		stratum[0].defaults[0][0].epc.tcoef,
		stratum[0].defaults[0][0].epc.tmax,
		stratum[0].defaults[0][0].epc.vpd_open,
		stratum[0].defaults[0][0].epc.vpd_close,
		stratum[0].ppfd_sunlit,
		stratum[0].epv.proj_lai_sunlit,
		9999.0,
		zone[0].metv.tsoil,
		stratum[0].defaults[0][0].epc.topt,
		stratum[0].defaults[0][0].epc.vpd_open-1.0, zone[0].CO2,
		stratum[0].defaults[0][0].epc.coef_CO2,
		stratum[0].ID,
		stratum, patch);

	stratum[0].gs_shade = compute_vascular_stratum_conductance(
		command_line[0].verbose_flag,
		stratum[0].defaults[0][0].epc.psi_curve,
		stratum[0].defaults[0][0].epc.ppfd_coef,
		stratum[0].defaults[0][0].epc.gl_c,
		stratum[0].defaults[0][0].lai_stomatal_fraction,
		stratum[0].defaults[0][0].epc.psi_open,
		stratum[0].defaults[0][0].epc.psi_close,
		stratum[0].defaults[0][0].epc.psi_threshold,
		stratum[0].defaults[0][0].epc.psi_slp,
		stratum[0].defaults[0][0].epc.psi_intercpt,
		stratum[0].defaults[0][0].epc.gl_smax,
		stratum[0].defaults[0][0].epc.topt,
		stratum[0].defaults[0][0].epc.tcoef,
		stratum[0].defaults[0][0].epc.tmax,
		stratum[0].defaults[0][0].epc.vpd_open,
		stratum[0].defaults[0][0].epc.vpd_close,
		stratum[0].ppfd_shade,
		stratum[0].epv.proj_lai_shade,
		stratum[0].epv.psi,
		zone[0].metv.tsoil,
		zone[0].metv.tday,
		zone[0].metv.vpd, zone[0].CO2,
		stratum[0].defaults[0][0].epc.coef_CO2,
		stratum[0].ID,
		stratum, patch);

	m_APAR_shade = stratum[0].mult_conductance.APAR;
	m_tavg_shade = stratum[0].mult_conductance.tavg;
	m_LWP_shade = stratum[0].mult_conductance.LWP;
	m_CO2_shade = stratum[0].mult_conductance.CO2;
	m_tmin_shade = stratum[0].mult_conductance.tmin;
	m_vpd_shade = stratum[0].mult_conductance.vpd;




	stratum[0].potential_gs_shade = compute_vascular_stratum_conductance(
		command_line[0].verbose_flag,
		stratum[0].defaults[0][0].epc.psi_curve,
		stratum[0].defaults[0][0].epc.ppfd_coef,
		stratum[0].defaults[0][0].epc.gl_c,
		stratum[0].defaults[0][0].lai_stomatal_fraction,
		stratum[0].defaults[0][0].epc.psi_open,
		stratum[0].defaults[0][0].epc.psi_close,
		stratum[0].defaults[0][0].epc.psi_threshold,
		stratum[0].defaults[0][0].epc.psi_slp,
		stratum[0].defaults[0][0].epc.psi_intercpt,
		stratum[0].defaults[0][0].epc.gl_smax,
		stratum[0].defaults[0][0].epc.topt,
		stratum[0].defaults[0][0].epc.tcoef,
		stratum[0].defaults[0][0].epc.tmax,
		stratum[0].defaults[0][0].epc.vpd_open,
		stratum[0].defaults[0][0].epc.vpd_close,
		stratum[0].ppfd_shade,
		stratum[0].epv.proj_lai_shade,
		9999.0,
		zone[0].metv.tsoil,
		stratum[0].defaults[0][0].epc.topt,
		stratum[0].defaults[0][0].epc.vpd_open-1.0, zone[0].CO2,
		stratum[0].defaults[0][0].epc.coef_CO2,
		stratum[0].ID,
		stratum, patch);


	/* keep track of conductance multipliers actually used an indication of stress */
	stratum[0].mult_conductance.APAR = (m_APAR_shade*stratum[0].epv.proj_lai_shade + 
		m_APAR_sunlit * stratum[0].epv.proj_lai_sunlit)
		/ (stratum[0].epv.proj_lai_shade+stratum[0].epv.proj_lai_sunlit);

	stratum[0].mult_conductance.tavg = (m_tavg_shade*stratum[0].epv.proj_lai_shade + 
		m_tavg_sunlit * stratum[0].epv.proj_lai_sunlit)
		/ (stratum[0].epv.proj_lai_shade+stratum[0].epv.proj_lai_sunlit);

	stratum[0].mult_conductance.LWP = (m_LWP_shade*stratum[0].epv.proj_lai_shade + 
		m_LWP_sunlit * stratum[0].epv.proj_lai_sunlit)
		/ (stratum[0].epv.proj_lai_shade+stratum[0].epv.proj_lai_sunlit);

	stratum[0].mult_conductance.CO2 = (m_CO2_shade*stratum[0].epv.proj_lai_shade + 
		m_CO2_sunlit * stratum[0].epv.proj_lai_sunlit)
		/ (stratum[0].epv.proj_lai_shade+stratum[0].epv.proj_lai_sunlit);

	stratum[0].mult_conductance.tmin = (m_tmin_shade*stratum[0].epv.proj_lai_shade + 
		m_tmin_sunlit * stratum[0].epv.proj_lai_sunlit)
		/ (stratum[0].epv.proj_lai_shade+stratum[0].epv.proj_lai_sunlit);

	stratum[0].mult_conductance.vpd = (m_vpd_shade*stratum[0].epv.proj_lai_shade + 
		m_vpd_sunlit * stratum[0].epv.proj_lai_sunlit)
		/ (stratum[0].epv.proj_lai_shade+stratum[0].epv.proj_lai_sunlit);


	}
	else {
		stratum[0].gs_sunlit = 0.0;
		stratum[0].gs_shade = 0.0;
		stratum[0].potential_gs_sunlit = 0.0;
		stratum[0].potential_gs_shade = 0.0;
		}


	stratum[0].gs = stratum[0].gs_sunlit + stratum[0].gs_shade;


	/*--------------------------------------------------------------*/
	/*	Determine heat flux between stratum and surface.			*/
	/*	representative of the surface temperature.  Obviously   */
	/*	for strata NOT at the surface one would have 0 heat cap */
	/*	kJ/day							*/
	/*	We had the current input of rain as well.		*/
	/*--------------------------------------------------------------*/
	if (stratum[0].epv.height == 0) {
		stratum[0].surface_heat_flux =
			-1 * compute_surface_heat_flux(
			command_line[0].verbose_flag,
			stratum[0].snow_stored,
			stratum[0].rain_stored+patch[0].rain_throughfall,
			stratum[0].epv.all_pai *
			stratum[0].defaults[0][0].specific_rain_capacity,
			zone[0].metv.tmin,
			zone[0].metv.tnightmax,
			zone[0].metv.tsoil,
			patch[0].soil_defaults[0][0].deltaz,
			stratum[0].defaults[0][0].min_heat_capacity,
			stratum[0].defaults[0][0].max_heat_capacity);
		
	}
	if ( command_line[0].verbose_flag > 2 )
		printf("\n%8d -444.11 ",julday(current_date)-2449000);
	/*--------------------------------------------------------------*/
	/*	COmpute evaporation and transpiration RATES (m/s)	*/
	/*	for daylight period .					*/
	/*	The rainy rate assumes a vpd of 10Pa.			*/
	/*	Note if surface heat flux makes evap negative we	*/
	/*	have condensation.  					*/
	/*--------------------------------------------------------------*/
	if (zone[0].metv.dayl > ZERO)
		rnet_evap = 1000 * (stratum[0].Kstar_direct + stratum[0].Kstar_diffuse
		+ stratum[0].Lstar + stratum[0].surface_heat_flux) / zone[0].metv.dayl;
	else
		rnet_evap = 0.0;

	/*--------------------------------------------------------------*/
	/*	Estimate potential evap rates.				*/
	/*--------------------------------------------------------------*/
	if ((stratum[0].gsurf > ZERO) && (stratum[0].ga > ZERO) && (rnet_evap > ZERO)) {
	potential_evaporation_rate = penman_monteith(
		command_line[0].verbose_flag,
		zone[0].metv.tday,
		zone[0].metv.pa,
		zone[0].metv.vpd,
		rnet_evap,
		1/stratum[0].gsurf,
		1/stratum[0].ga,
		2) ;
	potential_rainy_evaporation_rate = penman_monteith(
		command_line[0].verbose_flag,
		zone[0].metv.tday,
		zone[0].metv.pa,
		0,
		rnet_evap,
		1/stratum[0].gsurf,
		1/stratum[0].ga,
		2) ;
	}
	else {
		potential_evaporation_rate = 0.0;
		potential_rainy_evaporation_rate = 0.0;
	}

	potential_evaporation_rate = max(0,potential_evaporation_rate);
	potential_rainy_evaporation_rate = max(0,potential_rainy_evaporation_rate);


	/*--------------------------------------------------------------*/
	/*	Do not allow negative potential evap if it raining	*/
	/*	since condensation/dew dep is the same as rain		*/
	/*--------------------------------------------------------------*/
	if ( zone[0].rain > 0 ){
		potential_evaporation_rate = max(0,potential_evaporation_rate);
		potential_rainy_evaporation_rate= max(0,potential_rainy_evaporation_rate);
	}
	if ( command_line[0].verbose_flag > 2  )
		printf("\n%8d -444.12 ",julday(current_date)-2449000);
	/*--------------------------------------------------------------*/
	/*	Transpiration rate.					*/
	/*--------------------------------------------------------------*/
	/*--------------------------------------------------------------*/
	/*	Reduce rnet for transpiration by ratio of lai to pai	*/
	/*--------------------------------------------------------------*/

	if (zone[0].metv.dayl > ZERO) {
	rnet_trans_sunlit = 1000 * ((stratum[0].Kstar_direct + (perc_sunlit)*stratum[0].Kstar_diffuse)
		* ( stratum[0].epv.proj_lai / stratum[0].epv.proj_pai ) + 
		perc_sunlit* (stratum[0].Lstar + stratum[0].surface_heat_flux) ) / zone[0].metv.dayl;

	rnet_trans_shade = 1000 * (( (1.0-perc_sunlit)*stratum[0].Kstar_diffuse)
		* ( stratum[0].epv.proj_lai / stratum[0].epv.proj_pai ) + 
		(1.0-perc_sunlit) * (stratum[0].Lstar + stratum[0].surface_heat_flux) ) / zone[0].metv.dayl;
	}
	else {
		rnet_trans_sunlit = 0.0;
		rnet_trans_shade = 0.0;
		}
			
	rnet_trans_shade = max(rnet_trans_shade, 0.0);
	rnet_trans_sunlit = max(rnet_trans_sunlit, 0.0);

	if ( (rnet_trans_sunlit > ZERO ) &&
		(stratum[0].defaults[0][0].lai_stomatal_fraction > ZERO ) &&
		(stratum[0].gs_sunlit > ZERO) && ( stratum[0].ga > ZERO) ){
		transpiration_rate_sunlit = penman_monteith(
			command_line[0].verbose_flag,
			zone[0].metv.tday,
			zone[0].metv.pa,
			zone[0].metv.vpd,
			rnet_trans_sunlit,
			1/stratum[0].gs_sunlit,
			1/stratum[0].ga,
			2) ;
		potential_transpiration_rate_sunlit = penman_monteith(
			command_line[0].verbose_flag,
			zone[0].metv.tday,
			zone[0].metv.pa,
			zone[0].metv.vpd,
			rnet_trans_sunlit,
			1/stratum[0].potential_gs_sunlit,
			1/stratum[0].ga,
			2) ;
		}	
	else{
		transpiration_rate_sunlit = 0.0;
		potential_transpiration_rate_sunlit = 0.0;
	}
	if ( (rnet_trans_shade > ZERO ) &&
		(stratum[0].defaults[0][0].lai_stomatal_fraction > ZERO ) &&
		(stratum[0].gs_shade > ZERO) && ( stratum[0].ga > ZERO) ){
		transpiration_rate_shade = penman_monteith(
			command_line[0].verbose_flag,
			zone[0].metv.tday,
			zone[0].metv.pa,
			zone[0].metv.vpd,
			rnet_trans_shade,
			1/stratum[0].gs_shade,
			1/stratum[0].ga,
			2) ;
		potential_transpiration_rate_shade = penman_monteith(
			command_line[0].verbose_flag,
			zone[0].metv.tday,
			zone[0].metv.pa,
			zone[0].metv.vpd,
			rnet_trans_shade,
			1/stratum[0].potential_gs_shade,
			1/stratum[0].ga,
			2) ;
	}
	else{
		transpiration_rate_shade = 0.0;
		potential_transpiration_rate_shade = 0.0;
	}

	transpiration_rate = transpiration_rate_sunlit +  transpiration_rate_shade;
	potential_transpiration_rate = potential_transpiration_rate_sunlit +  potential_transpiration_rate_shade;

	/*--------------------------------------------------------------*/
	/*	Compute potential evaporation of stratum. 		*/
	/*	Weighted by rain and non rain periods of the daytime	*/
	/*	m/day = m/s * (sec/day)					*/
	/*								*/
	/*	Note that Kstar is converted from Kj/m2*day to W/m2	*/
	/*--------------------------------------------------------------*/
	stratum[0].potential_evaporation  = potential_evaporation_rate
		* (zone[0].metv.dayl - zone[0].daytime_rain_duration )
		+ potential_rainy_evaporation_rate * zone[0].daytime_rain_duration;


	/*--------------------------------------------------------------*/
	/*	If this stratum is on the surface and has a non-zero 	*/
	/*	rootin gdepth we assume it first takes water from soil. */
	/*	In this case we move some of the potential		*/
	/*	evaporation to porential transpiration.  The criteria 	*/
	/*	used to determine how much is based on the 		*/
	/*	estimated cap rise  during the day.		*/
	/*--------------------------------------------------------------*/
	if  ( (stratum[0].epv.height == 0 ) && ( stratum[0].rootzone.depth > 0 ) 
		&& (stratum[0].epv.proj_lai > ZERO) ){
		if ( stratum[0].potential_evaporation > ZERO ){
			transpiration = min(stratum[0].potential_evaporation,
				patch[0].cap_rise);
			potential_transpiration = min(stratum[0].potential_evaporation,
				patch[0].cap_rise);
			stratum[0].potential_evaporation -=	transpiration;
		}
		else{
			transpiration = 0.0;
			potential_transpiration = 0.0;
		}
	}
	if ( command_line[0].verbose_flag > 1 )
		printf("\n%8d -444.13 ",julday(current_date)-2449000);
	if ( command_line[0].verbose_flag > 1 )
		printf("%8.6f %8.6f %8.6f ",potential_evaporation_rate*1000,
		transpiration_rate*1000, stratum[0].potential_evaporation*1000 );
	if ( command_line[0].verbose_flag > 2 )
		printf("\n%4d %4d %4d -444.14 ",current_date.day, current_date.month,
		current_date.year);
	/*--------------------------------------------------------------*/
	/*	Update rain storage ( this also updates the patch level	*/
	/*	rain_throughfall and stratum[0].potential_evaporation	*/
	/*--------------------------------------------------------------*/
	stratum[0].rain_stored  = compute_rain_stored(
		command_line[0].verbose_flag,
		&(rain_throughfall),
		stratum);

	if ( command_line[0].verbose_flag > 1 )
		printf("\n%8d -444.15 ",julday(current_date)-2449000);
	if ( command_line[0].verbose_flag > 1 )
		printf("%8.4f %8.4f %8.4f %8.4f ",stratum[0].Kstar_direct,
		stratum[0].Kstar_diffuse,stratum[0].APAR_direct,
		stratum[0].APAR_diffuse);
	/*--------------------------------------------------------------*/
	/*	Separate the evaporation into rainy and dry		*/
	/*	assuming rainy happens as much as it can.		*/
	/*--------------------------------------------------------------*/
	if ( stratum[0].evaporation > ZERO ){
		rainy_evaporation =  min(zone[0].daytime_rain_duration *
			potential_rainy_evaporation_rate,
			stratum[0].evaporation );
		dry_evaporation = stratum[0].evaporation - rainy_evaporation;
	}
	else{
		rainy_evaporation = 0;
		dry_evaporation = stratum[0].evaporation ;
	}
	
	/*--------------------------------------------------------------*/
	/*	Compute Canopy transpiration.	m/day			*/
	/*								*/
	/*	We assume the potential_evaporation has been 		*/
	/*	reduced by the amount need to evaporate the storage 	*/
	/*	and incident precipitation.  				*/
	/*								*/
	/*	we  assume that part of the day				*/
	/*	which had a dry canopy which was transpiring.		*/
	/*								*/
	/*	The advantage of doing it via potentia evaporation 	*/
	/*	include:						*/
	/*								*/
	/*	1. the potential evaporation is computed once using	*/
	/*	the vpd and Rnet and ra of the WHOLE day.  We do not	*/
	/*	reduce Rnet after we evaporate water stored but		*/
	/*	reduce the potential evap. directly.			*/
	/*								*/
	/*	2. more importantly, the leaf conductance is computed	*/
	/*	on the full value average daytime Rnet and the 		*/
	/*	Rnet used in transpiration is the daily averaged value	*/
	/*	which properly reflects the balance in demand between	*/
	/*	Rnet and vpd.						*/
	/*								*/
	/*	we assume no transpiration happens during evaporation.	*/
	/*	or rain hours.						*/
	/*								*/
	/*	All of this is only done for vascular strata.		*/
	/*--------------------------------------------------------------*/
	if  (stratum[0].defaults[0][0].lai_stomatal_fraction > ZERO){
		if ( stratum[0].potential_evaporation > ZERO ){
			transpiration  = transpiration_rate *
				(zone[0].metv.dayl - zone[0].daytime_rain_duration -
				dry_evaporation / potential_evaporation_rate);
			potential_transpiration  = potential_transpiration_rate *
				(zone[0].metv.dayl - zone[0].daytime_rain_duration -
				dry_evaporation / potential_evaporation_rate);
		}
		else{
			transpiration  = 0.0;
			potential_transpiration = 0.0;
		}
	}

	stratum[0].PET = potential_transpiration;

	/*--------------------------------------------------------------*/
	/*	Separate the transpiration into unsat and sat zone	*/
	/*	transpiration demands based on the rooting depth and	*/
	/*	the patch depth to water table.				*/
	/*								*/
	/*	This transpiration may actually be reduced if there is	*/
	/*	not enough water i nthe respective zone.  But that 	*/
	/*	event should indicate that maybe the leaf water 	*/
	/*	potential control on gs or the soil moisture control on */
	/*	gsurf (for bryophytes) is not well calibrated.		*/
	/*--------------------------------------------------------------*/
	if ( stratum[0].rootzone.depth > ZERO ){
		stratum[0].transpiration_sat_zone = transpiration
			* max(0, 1 - ( patch[0].sat_deficit_z
			/ stratum[0].rootzone.depth ) );
		stratum[0].transpiration_unsat_zone = transpiration
			- stratum[0].transpiration_sat_zone;
	}
	else{
		if ( patch[0].sat_deficit_z > ZERO ){
			stratum[0].transpiration_unsat_zone = transpiration;
			stratum[0].transpiration_sat_zone = 0;
		}
		else{
			stratum[0].transpiration_unsat_zone = 0;
			stratum[0].transpiration_sat_zone = transpiration;
		}
	}



	if ( command_line[0].verbose_flag > 1 )
		printf("\n%8d -444.16 ",julday(current_date)-2449000);
	if ( command_line[0].verbose_flag > 1 )
		printf("%8.6f ", transpiration);
	/*--------------------------------------------------------------*/
	/*	Do respiration and photosynthesis only for plants	*/
	/*--------------------------------------------------------------*/
	if (stratum[0].defaults[0][0].lai_stomatal_fraction > ZERO) {
		/*--------------------------------------------------------------*/
		/*	perform maintenance respiration				*/
		/*	only fluxes are computed here; stores are updated later	*/
		/*	in canopy_stratum_daily_growth				*/
		/*--------------------------------------------------------------*/
		if (compute_maint_resp(
			stratum[0].defaults[0][0].mrc.q10,
			stratum[0].defaults[0][0].mrc.per_N,
			&(stratum[0].cs),
			&(stratum[0].ns),
			&(stratum[0].defaults[0][0].epc),
			&(zone[0].metv),
			&(stratum[0].cdf)	)){
			fprintf(stderr,"Error in compute_maint_resp() from bbgc.c... Exiting\n");
			exit(EXIT_FAILURE);
		}
		if ((stratum[0].epv.all_lai > ZERO) && (stratum[0].snow_stored < ZERO))  {
			/*--------------------------------------------------------------*/
			/*	convert maintenance resp from kg/m2*day to umol/m2*s	*/
			/*	only fluxes are computed here; stores are updated later	*/
			/*	in canopy_stratum_daily_growth				*/
			/*--------------------------------------------------------------*/
			/*--------------------------------------------------------------*/
			/*	Set up input array for stratum assimilation		*/
			/*--------------------------------------------------------------*/

			/*--------------------------------------------------------------*/
			/* this all needs to be repeated for sunlit and for shaded 	*/
			/*	and for potential and actual psn`			*/
			/* note that at present potential only takes into account	*/
			/*	water (i.e not nitrogen) limitations			*/
			/*--------------------------------------------------------------*/
			/* potential sunlit psn						*/
			/*--------------------------------------------------------------*/
			if (stratum[0].defaults[0][0].epc.veg_type == C4GRASS)
				psnin.c3 = 0;
			else 
				psnin.c3 = 1;
			if (zone[0].metv.dayl > ZERO)
				psnin.Rd = stratum[0].cdf.leaf_day_mr /
				(stratum[0].epv.proj_lai 
				* zone[0].metv.dayl*12.011e-9);
			else
				psnin.Rd = 0.0;

			psnin.pa = zone[0].metv.pa;
			psnin.co2 = zone[0].CO2;
			psnin.flnr = stratum[0].defaults[0][0].epc.flnr;
			psnin.t = zone[0].metv.tday;
			psnin.irad = stratum[0].ppfd_sunlit;
			if ((stratum[0].cs.leafc > ZERO) && (stratum[0].epv.proj_sla_sunlit > ZERO))
				psnin.lnc = stratum[0].ns.leafn / (stratum[0].cs.leafc * 1.0)
					/ stratum[0].epv.proj_sla_sunlit;
			else
				psnin.lnc = 0.0;
			/*--------------------------------------------------------------*/
			/* note multiply by 1000; accounted for in compute_farq_psn by a /1000 */
			/*	this is done for numerical precision			*/
			/*--------------------------------------------------------------*/
			psnin.g = max(stratum[0].defaults[0][0].epc.gl_smax ,
				stratum[0].defaults[0][0].epc.gl_c ) *
				stratum[0].defaults[0][0].lai_stomatal_fraction * 1000 / 1.6;
			if ((psnin.lnc > 0.0) && (psnin.irad > 0.0))
				compute_farq_psn(&psnin, &psnout, 1);
			else
				psnout.A = 0.0;
			assim_sunlit = psnout.A;

			/*--------------------------------------------------------------*/
			/* potential shade psn						*/
			/*--------------------------------------------------------------*/
			if (zone[0].metv.dayl > ZERO)
				psnin.Rd = stratum[0].cdf.leaf_day_mr  /
				(stratum[0].epv.proj_lai 
				* zone[0].metv.dayl*12.011e-9);
			else
				psnin.Rd = 0.0;

			psnin.irad = stratum[0].ppfd_shade;
			if ((stratum[0].cs.leafc > ZERO) && (stratum[0].epv.proj_sla_shade > ZERO))
				psnin.lnc = stratum[0].ns.leafn / (stratum[0].cs.leafc * 1.0)
					/ stratum[0].epv.proj_sla_shade ;
			else
				psnin.lnc = 0.0;

			if ((psnin.lnc > 0.0) && (psnin.irad > 0.0))
				compute_farq_psn(&psnin, &psnout, 1);
			else
				psnout.A = 0.0;
			assim_shade = psnout.A;

			/*--------------------------------------------------------------*/
			/* total potential psn						*/
			/*	We add the daytime leaf mr to the assim since it has	*/
			/*	been subtracted in both the farq and accounted for in	*/
			/*	total mr.						*/
			/*--------------------------------------------------------------*/
			stratum[0].cdf.potential_psn_to_cpool = (assim_sunlit*stratum[0].epv.proj_lai_sunlit
					+ assim_shade * stratum[0].epv.proj_lai_shade)	
					*zone[0].metv.dayl*12.011e-9 + stratum[0].cdf.leaf_day_mr;
			
			/*--------------------------------------------------------------*/
			/* actual sunlit psn						*/
			/*--------------------------------------------------------------*/
			/*--------------------------------------------------------------*/
			/*	convert water vapour to co2 conductance.		*/
			/*--------------------------------------------------------------*/
			if (zone[0].metv.dayl > ZERO)
				psnin.Rd = stratum[0].cdf.leaf_day_mr /
				(stratum[0].epv.proj_lai 
				* zone[0].metv.dayl*12.011e-9);
			else
				psnin.Rd = 0.0;
			/*--------------------------------------------------------------*/
			/* note multiply by 1000; accounted for in compute_farq_psn by a /1000 */
			/*	this is done for numerical precision			*/
			/*--------------------------------------------------------------*/
			if (stratum[0].epv.proj_lai_sunlit > ZERO)
				psnin.g = stratum[0].gs_sunlit * 1000 / 1.6 / stratum[0].epv.proj_lai_sunlit;
			else
				psnin.g = 0.0;
			psnin.irad = stratum[0].ppfd_sunlit;
			if ((stratum[0].cs.leafc > ZERO) && (stratum[0].epv.proj_lai_sunlit > ZERO))
				psnin.lnc = stratum[0].ns.leafn / (stratum[0].cs.leafc * 1.0)
					/ stratum[0].epv.proj_sla_sunlit;
			else
				psnin.lnc = 0.0;
			if ((psnin.lnc > 0.0) && (psnin.irad > 0.0)) {
				if ( compute_farq_psn(&psnin, &psnout, 1)){
					fprintf(stderr,
						"FATAL ERROR: in canopy_stratum_daily_F error in farquhar");
					exit(EXIT_FAILURE);
				}
			}
			else
				psnout.A = 0.0;
			assim_sunlit = psnout.A;
			dC13_sunlit = psnout.dC13;

			/*--------------------------------------------------------------*/
			/* actual shade psn						*/
			/*--------------------------------------------------------------*/
			/*--------------------------------------------------------------*/
			/*	convert water vapour to co2 conductance.		*/
			/*--------------------------------------------------------------*/
			if (zone[0].metv.dayl > ZERO)
			psnin.Rd = stratum[0].cdf.leaf_day_mr  /
				(stratum[0].epv.proj_lai 
				* zone[0].metv.dayl*12.011e-9);
			else
				psnin.Rd = 0.0;
			/*--------------------------------------------------------------*/
			/* note multiply by 1000; accounted for in compute_farq_psn by a /1000 */
			/*	this is done for numerical precision			*/
			/*--------------------------------------------------------------*/
			if (stratum[0].epv.proj_lai_shade > ZERO)
				psnin.g = stratum[0].gs_shade *1000 / 1.6 / stratum[0].epv.proj_lai_shade;
			else
				psnin.g = 0.0;
			psnin.irad = stratum[0].ppfd_shade;
			if ((stratum[0].cs.leafc > ZERO) && (stratum[0].epv.proj_lai_shade > ZERO))
				psnin.lnc = stratum[0].ns.leafn / (stratum[0].cs.leafc * 1.0)
					/ stratum[0].epv.proj_sla_shade;
			else
				psnin.lnc = 0.0;
			if ((psnin.lnc > 0.0) && (psnin.irad > 0.0)) {
				if ( compute_farq_psn(&psnin, &psnout, 1)){
					fprintf(stderr,
						"FATAL ERROR: in canopy_stratum_daily_F error in farquhar");
					exit(EXIT_FAILURE);
				}
			}
			else
				psnout.A = 0.0;
			assim_shade = psnout.A;
			dC13_shade = psnout.dC13;
			/*--------------------------------------------------------------*/
			/* total actual psn						*/
			/*--------------------------------------------------------------*/
			stratum[0].cdf.psn_to_cpool = (assim_sunlit*stratum[0].epv.proj_lai_sunlit
					+ assim_shade * stratum[0].epv.proj_lai_shade)	
					*zone[0].metv.dayl*12.011e-9 + stratum[0].cdf.leaf_day_mr;
			if ((assim_sunlit + assim_shade) > ZERO)
				stratum[0].dC13 = (assim_sunlit * dC13_sunlit + assim_shade * dC13_shade)/(assim_sunlit+assim_shade);
			else 
				stratum[0].dC13 = 0.0;
			/*--------------------------------------------------------------*/
			/*--------------------------------------------------------------*/
		} /* end if LAI > O  ** snow stored < 0*/
	} /* end if stomatal_fraction > 0 */
	else {
		stratum[0].cdf.psn_to_cpool = 0.0;
		stratum[0].cdf.potential_psn_to_cpool = 0.0;
	}

	/*--------------------------------------------------------------*/
	/*	perform growth related computations (if grow flag is on */
	/*--------------------------------------------------------------*/
	if ((command_line[0].grow_flag > 0) && (stratum[0].defaults[0][0].epc.veg_type != NON_VEG)) {
		/*--------------------------------------------------------------*/
		/*	compute N uptake from the soil 				*/
		/*--------------------------------------------------------------*/

		switch(stratum[0].defaults[0][0].epc.allocation_flag) {

		case CONSTANT: /* constant allocation */
			stratum[0].ndf.potential_N_uptake =	compute_potential_N_uptake(
				stratum[0].defaults[0][0].epc,
				&(stratum[0].epv),
				&(stratum[0].cs),
				&(stratum[0].ns),
				&(stratum[0].cdf));
			break;
		case DICKENSON:
			stratum[0].ndf.potential_N_uptake =compute_potential_N_uptake_Dickenson(
				stratum[0].defaults[0][0].epc,
				&(stratum[0].epv),
				&(stratum[0].cs),
				&(stratum[0].ns),
				&(stratum[0].cdf));
			break;
		case WARING:
			stratum[0].ndf.potential_N_uptake =compute_potential_N_uptake_Waring(
				stratum[0].defaults[0][0].epc,
				&(stratum[0].epv),
				&(stratum[0].cs),
				&(stratum[0].ns),
				&(stratum[0].cdf));
			break;
		} /* end switch */
	}
	
	}
	
	/*--------------------------------------------------------------*/
	/*	Increment the transmitted fluxes from this patch layer	*/
	/*	by weighting the fluxes in this stratum by its cover	*/
	/*	fraction - we have check cover fractions sum to 1 in 	*/
	/*	a layer when constructing the patch.			*/
	/*--------------------------------------------------------------*/
	patch[0].Kdown_direct_final += Kdown_direct * stratum[0].cover_fraction;
	patch[0].PAR_direct_final += PAR_direct * stratum[0].cover_fraction;
	patch[0].Kdown_diffuse_final += Kdown_diffuse * stratum[0].cover_fraction;
	patch[0].PAR_diffuse_final += PAR_diffuse * stratum[0].cover_fraction;
	patch[0].rain_throughfall_final += rain_throughfall
		* stratum[0].cover_fraction;
	patch[0].snow_throughfall_final += snow_throughfall
		* stratum[0].cover_fraction;
	patch[0].ga_final += ga * stratum[0].cover_fraction;
	patch[0].wind_final += wind * stratum[0].cover_fraction;
	/*--------------------------------------------------------------*/
	/*      update accumlator variables                             */
	/*--------------------------------------------------------------*/
	if((command_line[0].output_flags.monthly == 1)&&(command_line[0].c != NULL)){
		stratum[0].acc_month.psn += stratum[0].cdf.psn_to_cpool - stratum[0].cdf.total_mr;
		stratum[0].acc_month.lwp += stratum[0].epv.psi;
		stratum[0].acc_month.length += 1;
	}
	if ((command_line[0].output_flags.yearly == 1) && (command_line[0].c != NULL)){
		stratum[0].acc_year.psn += stratum[0].cdf.psn_to_cpool - stratum[0].cdf.total_mr;
		stratum[0].acc_year.lwp += stratum[0].epv.psi;
		if (stratum[0].acc_year.minNSC = -999)
			stratum[0].acc_year.minNSC = stratum[0].cs.cpool;
		else
			stratum[0].acc_year.minNSC = min(stratum[0].cs.cpool, stratum[0].acc_year.minNSC);
		stratum[0].acc_year.length += 1;
	}
	return;
} /*end canopy_stratum_daily_F.c*/
Пример #12
0
void		zone_hourly(
						struct	world_object 	*world,
						struct	basin_object	*basin,
						struct	hillslope_object	*hillslope,
						struct 	zone_object 	*zone,
						struct 	command_line_object *command_line,
						struct	tec_entry		*event,
						struct 	date 			current_date)
{
	/*--------------------------------------------------------------*/
	/*  Local Function Declarations.                                */
	/*--------------------------------------------------------------*/
	void patch_hourly (
		struct	world_object 	*,
		struct	basin_object	*,
		struct	hillslope_object	*,
		struct 	zone_object 	*,
		struct patch_object *,
		struct command_line_object *,
		struct tec_entry *,
		struct date);
	
	void	*alloc(	size_t, char *, char *);
	long  julday( struct date );
	/*--------------------------------------------------------------*/
	/*  Local variable definition.                                  */
	/*--------------------------------------------------------------*/
	int 	patch;
	int	inx;
	double	Kdown_direct_flat_toa;
	double	temp;
	struct	dated_sequence	clim_event;
	/*--------------------------------------------------------------*/
	/* 	check for hourly precipitation data			*/
	/* 	for now only assume one base station per zone		*/
	/*--------------------------------------------------------------*/
	zone[0].hourly_rain_flag = 0;
	zone[0].hourly[0].rain = 0.0;
	inx = zone[0].base_stations[0][0].hourly_clim[0].rain.inx;
	if (inx > -999)  {
		clim_event = zone[0].base_stations[0][0].hourly_clim[0].rain.seq[inx];
		while (julday(clim_event.edate) < julday(current_date)) {
			zone[0].base_stations[0][0].hourly_clim[0].rain.inx += 1;
			inx = zone[0].base_stations[0][0].hourly_clim[0].rain.inx;
			clim_event = zone[0].base_stations[0][0].hourly_clim[0].rain.seq[inx];
			}
		if ( (clim_event.edate.year != 0) &&
			(julday(clim_event.edate) == julday(current_date)) ) {
			zone[0].hourly_rain_flag = 1;
			zone[0].hourly[0].rain = clim_event.value;
			inx = zone[0].base_stations[0][0].hourly_clim[0].rain_duration.inx;
			/*--------------------------------------------------------------*/
			/* 	check for corresponding duration data			*/
			/*	if not there assume full hour				*/
			/*--------------------------------------------------------------*/
			if (inx > -999) {
				clim_event = zone[0].base_stations[0][0].hourly_clim[0].rain_duration.seq[inx];
				while (julday(clim_event.edate) < julday(current_date)) {
					zone[0].base_stations[0][0].hourly_clim[0].rain_duration.inx += 1;
					inx = zone[0].base_stations[0][0].hourly_clim[0].rain_duration.inx;
					clim_event = zone[0].base_stations[0][0].hourly_clim[0].rain_duration.seq[inx];
					}
				if (julday(clim_event.edate) == julday(current_date)) {
					zone[0].hourly[0].rain_duration = clim_event.value;
				}
				else zone[0].hourly[0].rain_duration = 3600;
			}
			else zone[0].hourly[0].rain_duration = 3600;
		}
	}
	zone[0].rain_hourly_total += zone[0].hourly[0].rain;
	/*--------------------------------------------------------------*/
	/*	Compute zone hourly radiation forcings.								*/
	/*--------------------------------------------------------------*/
	/*--------------------------------------------------------------*/
	/*	Kdown_direct or Kdown_diffuse.								*/
	/*																*/
	/*  Add to top of zone daily values for these terms if not		*/
	/*	provided.  													*/
	/*--------------------------------------------------------------*/
	if ((zone[0].Kdown_direct_flag == 0) ||
		(zone[0].Kdown_diffuse_flag == 0) ||
		(zone[0].daylength_flag == 0 )){
		/*--------------------------------------------------------------*/
		/*  Accumulate incoming Kdown if the sun is up.                 */
		/*                                                              */
		/*  We define the day length as the period where the cos_sza >0.*/
		/*  It is likely that Kdown_diffuse is non-zero even if         */
		/*  cos_sza < 0 but we ignore this for now.                     */
		/*--------------------------------------------------------------*/
		if ( basin[0].hourly[0].cos_sza  > 0 ){
			/*--------------------------------------------------------------*/
			/*		Atmospheric attenuation to direct radiation	(no units)  */
			/*--------------------------------------------------------------*/
			zone[0].hourly[0].direct_attenuation
				= pow( zone[0].atm_trans, basin[0].hourly[0].optical_air_mass);
			/*--------------------------------------------------------------*/
			/*		Downwelling total irradiance at BOA along sza			*/
			/*		W / m ** 2  = W /m ** 2  								*/
			/*--------------------------------------------------------------*/
			zone[0].hourly[0].Kdown_BOA
				= world[0].Io * zone[0].hourly[0].direct_attenuation;
			if (command_line[0].verbose_flag > 5) 
				printf("\n Io(W/m^2)= %f, Atm_trans= %f, air_mass= %f direct_att= %f Kdown_BOA(W/m^2)= %f ",
				world[0].Io,
				zone[0].atm_trans,
				basin[0].hourly[0].optical_air_mass,
				zone[0].hourly[0].direct_attenuation,
				zone[0].hourly[0].Kdown_BOA);
			/*--------------------------------------------------------------*/
			/*  Kdown_direct    (W/(m2)) 	                               */
			/*                                                              */
			/*  Eq. 5, Appendix D, "MTCLIM"                                 */
			/*                                                              */
			/*  We add in the constraint that the sun must be above the     */
			/*  horizon of the zone where the horizon is defined by        */
			/*  the eas and west horizons (assumes sun moves from east to   */
			/*  west with refernce to the zone).  Note that we define the  */
			/*  horizons as the angle from a flat surface at the zone and  */
			/*  NOT as the slope of the zone as zero.  We do this so that  */
			/*  the horizon can also be used to define a view factor.       */
			/*                                                              */
			/*  Note that we only accumulate the 24hr total Kdown_direct    */
			/*  so if you need the hourly Kdown_direct you have to make a   */
			/*  new state variable.                                         */
			/*																*/
			/*	Note that cos_sza = 1.0 if the sun is at a 90 degree angle	*/
			/*	to the flat surface at the zone.							*/
			/*																*/
			/* 	It is possible that the zone's east and west horizons do not*/
			/*	match that of the basins.  At present the basin's east and	*/
			/*	west horizons define length of daylight.  SO it is possible	*/
			/*	that, we consider that daylight is available evcen though	*/
			/*	the zone is still in shade.  We should decide if we should	*/
			/*	define daylength (and horizons) based on basin or zone.		*/
			/*--------------------------------------------------------------*/
			if ( (basin[0].hourly[0].cos_sza > zone[0].e_horizon) &&
				(basin[0].hourly[0].cos_sza > zone[0].w_horizon) ){
				/*--------------------------------------------------------------*/
				/*	Increment zone daylength				*/
				/*--------------------------------------------------------------*/
				if ( zone[0].daylength_flag == 0 ) zone[0].metv.dayl += 3600.0;
				/*--------------------------------------------------------------*/
				/*	Only do the following if we dont have direct radiation		*/
				/*--------------------------------------------------------------*/
				if ((zone[0].Kdown_direct_flag == 0) ||
					(zone[0].Kdown_diffuse_flag == 0)){
					/*------------------------------------------------------------*/
					/*     Kdown_direct_flat   (W/(m2))                            */
					/*                                                             */
					/*     Required to adjust max temp.                            */
					/*-------------------------------------------------------------*/
					zone[0].hourly[0].Kdown_direct_flat
						= basin[0].hourly[0].cos_sza * zone[0].hourly[0].Kdown_BOA;
					/*-------------------------------------------------------------*/
					/*     Cosine of beam slope angle. (no units)                  */
					/*                                                             */
					/*     Eq. 8 Appendix D of "MTCLIM"                            */
					/*-------------------------------------------------------------*/
					zone[0].hourly[0].cos_beam_slope
						= -1 * zone[0].sin_slope * zone[0].sin_aspect
						* basin[0].hourly[0].cos_declin_sin_hourangle
						+ ( -1 * zone[0].cos_aspect * zone[0].sin_slope
						* basin[0].sin_latitude + zone[0].cos_slope
						* basin[0].cos_latitude)
						* basin[0].hourly[0].cos_declin_cos_hourangle
						+( zone[0].cos_aspect * zone[0].sin_slope
						* basin[0].cos_latitude + zone[0].cos_slope
						* basin[0].sin_latitude ) * world[0].sin_declin;
					/*-------------------------------------------------------------*/
					/*	if sun angle is below the slope angle then		*/
					/*	hill is blocking sun and Kdown_direct is zero		*/
					/*-------------------------------------------------------------*/
					if (zone[0].hourly[0].cos_beam_slope < 0.0)
						zone[0].hourly[0].cos_beam_slope = 0.0;
					if (isnan(zone[0].hourly[0].cos_beam_slope))
						zone[0].hourly[0].cos_beam_slope = 0.0;

					/*----------------------------------------------------------*/
					/*		Kdown_direct	(W/(m2*day))							*/
					/*----------------------------------------------------------*/
					zone[0].hourly[0].Kdown_direct
						= zone[0].hourly[0].cos_beam_slope
						* zone[0].hourly[0].Kdown_BOA;
					/*-------------------------------------------------------------*/
					/*		Diffuse Radiation Calculations			*/
					/*		Source Daymet - Peter Thorto			*/
					/*		Further adjusts for horizon view factor.				*/
					/*------------------------------------------------------------*/
					if (zone[0].hourly[0].direct_attenuation > 0.000000001)
						Kdown_direct_flat_toa = zone[0].hourly[0].Kdown_direct_flat
						/ zone[0].hourly[0].direct_attenuation ;
					else
						Kdown_direct_flat_toa = 0.0;
					temp = sqrt( Kdown_direct_flat_toa
						* zone[0].hourly[0].Kdown_direct_flat);
					if (Kdown_direct_flat_toa < 0.0000000001)
						zone[0].hourly[0].Kdown_diffuse_flat = 0.0;
					else
						zone[0].hourly[0].Kdown_diffuse_flat
							= temp * (1.0 - temp / Kdown_direct_flat_toa);
					zone[0].hourly[0].Kdown_diffuse
						= zone[0].hourly[0].Kdown_diffuse_flat
						* pow(cos(zone[0].slope/2.0),2.0);
					if ( command_line[0].verbose_flag > 5 )
						printf("\n-111.3 cos_sza : %8.4f Kdown_dir_flat= %8.4f Kdown_dif_flat= %8.4f ",
						basin[0].hourly[0].cos_sza,
						zone[0].hourly[0].Kdown_direct_flat,
						zone[0].hourly[0].Kdown_diffuse_flat);
					if ( command_line[0].verbose_flag > 5 )
						printf(" cos_bsa= %8.4f Kdown_dir= %8.4f Kdown_dif= %8.4f Kdown_total(W/m^2)= %8.4f",
						zone[0].hourly[0].cos_beam_slope,
						zone[0].hourly[0].Kdown_diffuse,
						zone[0].hourly[0].Kdown_direct,
						zone[0].hourly[0].Kdown_direct
						+ zone[0].hourly[0].Kdown_diffuse);
					/*------------------------------------------------------------*/
					/*		Convert calculation fro W/m^2 to Kj/(m^2*hr)	*/
					/*-----------------------------------------------------------*/
					zone[0].Kdown_direct_flat
						+= zone[0].hourly[0].Kdown_direct_flat * 3600 / 1000;
					zone[0].Kdown_direct
						+= zone[0].hourly[0].Kdown_direct * 3600 / 1000;

					zone[0].Kdown_diffuse_flat
						+= zone[0].hourly[0].Kdown_diffuse_flat * 3600 / 1000;
					zone[0].Kdown_diffuse
						+= zone[0].hourly[0].Kdown_diffuse * 3600 / 1000;
				} /*end if */
			} /*end if*/
			} /*end if*/
		} /*end if*/
		/*--------------------------------------------------------------*/
		/*	Cycle through the patches 									*/
		/*--------------------------------------------------------------*/
		for ( patch=0 ; patch<zone[0].num_patches; patch++ ){
			patch_hourly(
				world,
				basin,
				hillslope,
				zone,
				zone[0].patches[patch],
				command_line,
				event,
				current_date );
		}
		return;
} /*end zone_hourly.c*/
Пример #13
0
void		zone_daily_F(
						 long	day,
						 struct	world_object	*world,
						 struct	basin_object	*basin,
						 struct	hillslope_object	*hillslope,
						 struct 	zone_object 	*zone,
						 struct 	command_line_object *command_line,
						 struct	tec_entry		*event,
						 struct 	date 			current_date)
						 
{
	/*--------------------------------------------------------------*/
	/*  Local Function Declarations.                                */
	/*--------------------------------------------------------------*/
	void    patch_daily_F(
		struct	world_object	*,
		struct	basin_object	*,
		struct	hillslope_object	*,
		struct 	zone_object 	*,
		struct patch_object *,
		struct command_line_object *,
		struct tec_entry *,
		struct date);
	long julday(struct date);
	
	/*--------------------------------------------------------------*/
	/*  Local variable definition.                                  */
	/*--------------------------------------------------------------*/
	int 	patch;
	double snow_rain_range;
	double	es;
	/*--------------------------------------------------------------*/
	/*  Update the forcing functions based on the hourly computation*/
	/*--------------------------------------------------------------*/
	/*--------------------------------------------------------------*/
	/*	Make use of more accurate basin daylength 		*/
	/*	if it is not given and the zone horizons are 0		*/
	/*	If the zone horizons are non zero we use the 		*/
	/*	daylength computed from hourly solar geometry.		*/
	/*--------------------------------------------------------------*/
	if ( (zone[0].daylength_flag == 0) &&
		(zone[0].e_horizon == 0) &&
		(zone[0].w_horizon == 0) ){
		/*--------------------------------------------------------------*/
		/*		adjust the simulated radiation for new dayl	*/
		/*--------------------------------------------------------------*/

		if (zone[0].Kdown_direct_flag == 0){
			zone[0].Kdown_direct = zone[0].Kdown_direct
				* ( basin[0].daylength / zone[0].metv.dayl );
		}
		if (zone[0].Kdown_diffuse_flag == 0){
			zone[0].Kdown_diffuse = zone[0].Kdown_diffuse
				* ( basin[0].daylength / zone[0].metv.dayl );
		}
		/*--------------------------------------------------------------*/
		/*		update the zone daylength to be the basin dayl	*/
		/*		which is likely more accurate.			*/
		/*--------------------------------------------------------------*/
		zone[0].metv.dayl = basin[0].daylength;
	}
	/*--------------------------------------------------------------*/
	/*	Deretmine if we need to adjust Kdowns or metv.tmax.			*/
	/*																*/
	/*	We assume that if either Kdown_diffuse or Kdown_direct		*/
	/*	was not supplied then themetv.tmax needs adjustment.		*/
	/*	This is because the adjustment should not be needed			*/
	/*		if we had good enough data to get Kdowns.				*/
	/*--------------------------------------------------------------*/
	if ( (zone[0].Kdown_direct_flag == 0) ||
		(zone[0].Kdown_diffuse_flag == 0) ){
		/*--------------------------------------------------------------*/
		/*	Adjust the computed Kdown's for cloud fraction if they		*/
		/*	were not read in directly.									*/
		/*	See simuilate_zone_daily_1 for the adjustment computation	*/
		/*--------------------------------------------------------------*/
		zone[0].Kdown_direct = zone[0].Kdown_direct
			* zone[0].Kdown_direct_adjustment;
		zone[0].Kdown_diffuse = zone[0].Kdown_diffuse
			* zone[0].Kdown_diffuse_adjustment;
		/*--------------------------------------------------------------*/
		/*	radrat (unitless)											*/
		/*																*/
		/*	Equation 2a & 2b , Page 5, "MTCLIM" 						*/
		/*--------------------------------------------------------------*/
		if ( (zone[0].Kdown_direct_flat + zone[0].Kdown_diffuse_flat) != 0.0 ) {
			zone[0].radrat = (zone[0].Kdown_direct + zone[0].Kdown_diffuse) /
			(zone[0].Kdown_direct_flat + zone[0].Kdown_diffuse_flat);   
		}
		else zone[0].radrat = 1.0;
		/*zone[0].radrat = 1.0;*/
		/* EG edit: when radrat equals zero, tmax= -Inf and PSN=Nan */
		if ( zone[0].radrat == 0.0) {
			zone[0].radrat = 1.0;
		}
		/*--------------------------------------------------------------*/
		/*	LAI compensation (unitless)									*/
		/*																*/
		/*	Equation 2a & 2b , Page 5, "MTCLIM" 						*/
		/*	Modified so that the base station LAI is subtracted from the*/
		/*		zone lai.												*/
		/*--------------------------------------------------------------*/
		zone[0].effective_lai = 0.0;
		for ( patch=0 ; patch<zone[0].num_patches ; patch++ ){
			zone[0].effective_lai
				+= zone[0].patches[patch][0].effective_lai
				* zone[0].patches[patch][0].area;
		}
		zone[0].effective_lai = zone[0].effective_lai / zone[0].area;
		if ( zone[0].radrat <  1.0 ){
			zone[0].LAI_temp_adjustment
				=-1 * ( 1/zone[0].radrat ) * ( 1 + (zone[0].effective_lai
				- zone[0].base_station_effective_lai )
				/ zone[0].defaults[0][0].max_effective_lai );
		}
		else{
			zone[0].LAI_temp_adjustment = ( zone[0].radrat )
				* ( 1 - (zone[0].effective_lai
				- zone[0].base_station_effective_lai )
				/ zone[0].defaults[0][0].max_effective_lai );
		}  /*end if-else*/
		/*--------------------------------------------------------------*/
		/*metv.tmax adjusted ( degrees C)								*/
		/*--------------------------------------------------------------*/
		zone[0].metv.tmax = zone[0].metv.tmax + zone[0].LAI_temp_adjustment;
	} /*end if*/
	/* EG edit: LAI temp adjustment was pushing tmax below tmin*/
	if (zone[0].metv.tmax < zone[0].metv.tmin) {
		zone[0].metv.tmax = zone[0].metv.tmin + 1.0;
	}
	/*--------------------------------------------------------------*/
	/*	If no PAR or only diffuse PAR is given get the other PAR's	*/
	/*	We assume the ratio of diffuse to direct PAR is a closed 	*/
	/*		form equation of the ratio of diffuse to direct Kdown.	*/
	/*--------------------------------------------------------------*/
	if ( (zone[0].PAR_direct == -999.0 ) && ( zone[0].PAR_diffuse == -999.0) ){
		zone[0].PAR_direct = 1000.0 * zone[0].Kdown_direct * RAD2PAR * EPAR;
		zone[0].PAR_diffuse = 1000.0 *  zone[0].Kdown_diffuse * RAD2PAR * EPAR;
	}
	else if ( zone[0].PAR_direct == -999.0 ){
		zone[0].PAR_direct = zone[0].PAR_diffuse * (zone[0].Kdown_direct
			/ zone[0].Kdown_diffuse );
	}
	else if ( zone[0].PAR_diffuse == -999.0 ){
		zone[0].PAR_diffuse = zone[0].PAR_direct * (zone[0].Kdown_diffuse
			/ zone[0].Kdown_direct );
	}
	/*--------------------------------------------------------------*/
	/*	.metv.tavg	(degrees C)									*/
	/*--------------------------------------------------------------*/
	if ( zone[0].metv.tavg == -999.0 ){
		zone[0].metv.tavg = (zone[0].metv.tmax + zone[0].metv.tmin)/2.0;
	}

	/*--------------------------------------------------------------*/
	/*	metv.tday	(degrees C)									*/
	/*																*/
	/*	Eq 1. Page 4, "MTCLIM"										*/
	/*--------------------------------------------------------------*/
	if ( zone[0].metv.tday == -999.0 ){
		zone[0].metv.tday = zone[0].defaults[0][0].temcf
			* (zone[0].metv.tmax - zone[0].metv.tavg) + zone[0].metv.tavg;
	}
	/*--------------------------------------------------------------*/
	/*	metv.tnight 	(degrees C)								*/
	/*																*/
	/*	zcomp.c C Rhessys code										*/
	/*--------------------------------------------------------------*/
	if ( zone[0].metv.tnight == -999.0 ){
		zone[0].metv.tnight = (zone[0].metv.tday + zone[0].metv.tmin)/2.0;
	}
	/*--------------------------------------------------------------*/
	/*	If we have no snow data determine if the rain should be snow*/
	/*																*/
	/*	Based on U.S Army Corps of ENgineers (1956) Snow Hydrology	*/
	/*	use a min/max to get range in which there is a mix of snow/rain */
	/*								*/
	/*--------------------------------------------------------------*/
	if (zone[0].snow == -999.0 ){
		if (zone[0].metv.tavg < zone[0].defaults[0][0].max_snow_temp ){
			if (zone[0].metv.tavg <= zone[0].defaults[0][0].min_rain_temp){
				zone[0].snow = zone[0].rain;
				zone[0].rain = 0.0;
			}
			else{
				snow_rain_range = zone[0].defaults[0][0].max_snow_temp
					- zone[0].defaults[0][0].min_rain_temp;
				if ( snow_rain_range < 0.001){
					zone[0].snow = zone[0].rain;
					zone[0].rain = 0.0;
				}
				else{
					zone[0].snow = min((zone[0].defaults[0][0].max_snow_temp
						- zone[0].metv.tavg) * zone[0].rain / snow_rain_range, zone[0].rain);
					zone[0].rain = zone[0].rain - zone[0].snow;
				}
			}
		}
		else{
			zone[0].snow = 0.0;
		}
	}
	/*--------------------------------------------------------------*/
	/*	If we have no rain duration data set it as		*/
	/*	daylength if rain 0 if not.					*/
	/*--------------------------------------------------------------*/
	if ( zone[0].daytime_rain_duration == -999.0 ){
		if ( zone[0].rain == 0 || (zone[0].snow != 0 ) ){
			zone[0].daytime_rain_duration = 0;
		}
		else{
			zone[0].daytime_rain_duration = zone[0].metv.dayl;
		}
	}
	else{
		if ( zone[0].rain == 0 ){
			zone[0].daytime_rain_duration = 0;
		}
		else{
			zone[0].daytime_rain_duration =
				min( zone[0].metv.dayl,zone[0].daytime_rain_duration);
		}
	}
	/*--------------------------------------------------------------*/
	/*	Ldown														*/
	/*--------------------------------------------------------------*/
	if ( zone[0].Ldown == -999.0){
		/*--------------------------------------------------------------*/
		/*		compute the daily downwelling long wave based on 		*/
		/*		.metv.tavg. 	(kJ/(m2*day))						*/
		/*																*/
		/*		Base on Linacre 1992 as found in C version of rhessys.	*/
		/*																*/
		/*		Also, Linacre's formula requires cloud fraction in   	*/
		/*		oktas of cloud cover; where 1 okta = 1/8 th of sky	*/
		/*		covered by clouds.					*/
		/*																*/
		/*		If we dont have cloud fraction data we assume 4.0oktas	*/
		/*		of full cloudyness if it is a rainy day or a rain or 	*/
		/*		snow day.												*/
		/*--------------------------------------------------------------*/
		if ( zone[0].cloud_fraction != -999.0 ){
			zone[0].cloud = zone[0].cloud_opacity
				* zone[0].cloud_fraction * 12.0;
		}
		else if	((zone[0].snow + zone[0].rain) > zone[0].defaults[0][0].pptmin ){
			zone[0].cloud = 4.0;
			zone[0].cloud_fraction = 1.0;
		}
		else{
			zone[0].cloud = 0;
			zone[0].cloud_fraction = 0.0;
		}
		zone[0].Ldown = (208+6*zone[0].metv.tavg) * ( 1.0
			+ 0.0034*pow(zone[0].cloud,2.0))* 86400.0 / 1000.0;
	} /*end if*/
	/*--------------------------------------------------------------*/
	/*	Saturation Vapour Pressure	(Pa)							*/
	/*																*/
	/*	Note the original rehssys code supplied es in mbar.			*/
	/*	c.f. eq. 1 Running and Coughlan , 1987, p. 133.				*/
	/*																*/
	/*	Since 1 bar = 100 kpa (approx) ; a millibar = 100 Pa approx.*/
	/*	This explains why the es from the original code was:		*/
	/*																*/
	/*	6.1078 * exp((17.269*z[0].metv.tday)/(237.3 +			*/
	/*									z[0].metv.tday))		*/
	/*																*/
	/*	Which is approx 100 times that of the es here.				*/
	/*																*/
	/*	Eq. 5.12 p. 110, Jones, "Plants and Microclimate"			*/
	/*--------------------------------------------------------------*/
	if (  zone[0].metv.vpd == -999.0  ){
		es = 613.75 * exp( (17.502 * zone[0].metv.tavg)
			/ ( 240.97 + zone[0].metv.tavg) );
		/*--------------------------------------------------------------*/
		/*	Make use of relative humidity if available.					*/
		/*--------------------------------------------------------------*/
		if ( zone[0].relative_humidity == -999.0 ){
			/*--------------------------------------------------------------*/
			/*	Dew Point Vapour Pressure (Pa)								*/
			/*																*/
			/*	Note the original rehssys code supplied es in mbar.			*/
			/*	c.f. eq. 1 Running and Coughlan , 1987, p. 133.				*/
			/*																*/
			/*	Since 1 bar = 100 kpa (approx) ; a millibar = 100 Pa approx.*/
			/*	This explains why the es from the original code was:		*/
			/*																*/
			/*	6.1078 * exp((17.269*z[0].tdewpoint)/(237.3 +			*/
			/*									z[0].tdewpoint))		*/
			/*																*/
			/*	Which is approx 100 times that of the es here.				*/
			/*																*/
			/*	Eq. 5.12 p. 110, Jones, "Plants and Microclimate"			*/
			/*	Assuming that tdewpoint is valid for the whole day.		*/
			/*								*/
			/*	We cannot make a correction for rain_duration here.	*/
			/*	Instead we hope that  the dewpoint vapour pressure is	*/
			/*	measured by a temperature value (night min)		*/
			/*--------------------------------------------------------------*/
			zone[0].e_dewpoint = 613.750 * exp( (17.502
				* zone[0].tdewpoint) / ( 240.97 + zone[0].tdewpoint));
		}
		else{
			/*--------------------------------------------------------------*/
			/*      Dew Point Vapour Pressure (Pa)                          */
			/*                                                              */
			/*      ONly for dayligh conditions with no rain.               */
			/*      Eq. 5.13 and 5.14 , p. 110, Jones, "Plants and Microclimate"*/
			/*--------------------------------------------------------------*/
			zone[0].e_dewpoint =  zone[0].relative_humidity * es;
		} /*end if-else*/
		/*--------------------------------------------------------------*/
		/*	metv.vpd	(Pa)						*/
		/*								*/
		/*	Eq. 5.14, p. 110, Jones, "Plants and Microclimate"	*/
		/*	Limited to at least 0.0 as per rhessys C code.		*/
		/*--------------------------------------------------------------*/

		zone[0].metv.vpd = max(es - zone[0].e_dewpoint,0.0);
		if (zone[0].relative_humidity == -999.0) {
			if (es > ZERO)
				zone[0].relative_humidity = zone[0].e_dewpoint / es;
			else
				zone[0].relative_humidity = -999.0;
			}
	}
	/*--------------------------------------------------------------*/
	/*	Nitrogen Deposition					*/
	/*	- if not availabe use default value			*/
	/*--------------------------------------------------------------*/
	if (zone[0].ndep_NO3 == -999.0){
		zone[0].ndep_NO3 = zone[0].defaults[0][0].ndep_NO3;
	}
	/*--------------------------------------------------------------*/
	/*	metv.tsoil - soil temperature 		(degrees C)	*/
	/*								*/
	/*	We always update a running average for metv.tsoil in		*/
	/*	case we get a missing value.						*/
	/*--------------------------------------------------------------*/
	if ( zone[0].metv.tsoil == -999.0 ){
		zone[0].metv.tsoil_sum = 0.9 * zone[0].metv.tsoil_sum +
			0.1 *	zone[0].metv.tavg;
		zone[0].metv.tsoil = zone[0].metv.tsoil_sum;
	}
	else{
		zone[0].metv.tsoil_sum = zone[0].metv.tsoil;
	}
	/*--------------------------------------------------------------*/
	/* 	set LAI scalar to 1.0 is missing 			*/
	/*--------------------------------------------------------------*/
	if ( zone[0].LAI_scalar == -999.0 ){
		zone[0].LAI_scalar = 1.0;
	}
	/*--------------------------------------------------------------*/
	/*	Atmospheric CO2 concentration (ppm)			*/
	/*--------------------------------------------------------------*/
	if ( zone[0].CO2 == -999.0 ){
		zone[0].CO2 = zone[0].defaults[0][0].atm_CO2;
	}
	/*--------------------------------------------------------------*/
	/*	Fill in the bbgc metv structure for missing variables	*/
	/*--------------------------------------------------------------*/
	/*--------------------------------------------------------------*/
	/*	compute total precip 			kg/m2		*/
	/*								*/
	/*	assumes density snow = debsity rain			*/
	/*	kg/m2 = (m / m2) *( 1000kg/m3)								*/
	/*--------------------------------------------------------------*/
	zone[0].metv.prcp = (zone[0].rain + zone[0].snow)*1000.0;
	/*--------------------------------------------------------------*/
	/*	compute total shortwave flux		(W/m2)		*/
	/*	W/m2 = Kj/(m2*day) * ( 1 day / dayl s ) * 1000 j / 1kj  */
	/*--------------------------------------------------------------*/
	zone[0].metv.swavgfd = (zone[0].Kdown_direct + zone[0].Kdown_diffuse)
		/ zone[0].metv.dayl * 1000.0  ;
	/*--------------------------------------------------------------*/
	/*	compute total ppfd		umol photon/m2*s	*/
	/*	umol photon/m2*s = u mol photon/m2*day * (1 day/dayl s)	*/
	/*--------------------------------------------------------------*/
	zone[0].metv.ppfd = (zone[0].PAR_direct + zone[0].PAR_diffuse)
		/ zone[0].metv.dayl ;
	if ( command_line[0].verbose_flag > 1 )
		printf("\n%8d -222.1 ",julday(current_date)-2449000);
	if ( command_line[0].verbose_flag > 0  )
		printf("%8.4f %8.4f %8.4f %8.4f %8.4f %8.4f %8.4f %8.4f ",
		zone[0].metv.dayl,
		zone[0].metv.tmax,
		zone[0].metv.tmin,
		zone[0].metv.tavg,
		zone[0].metv.tnight,
		zone[0].metv.tday,
		zone[0].metv.tsoil,
		zone[0].tdewpoint);
	if ( command_line[0].verbose_flag > 1 )
		printf("\n%8d -222.2 ",julday(current_date)-2449000);
	if ( command_line[0].verbose_flag > 0 )
		printf("%8.4f %8.4f %8.2f ",
		zone[0].rain,
		zone[0].snow,
		zone[0].metv.vpd);
	if ( command_line[0].verbose_flag > 1 )
		printf("%8.1f %8.1f %8.0f %8.0f %8.1f ",
		zone[0].Kdown_direct,
		zone[0].Kdown_diffuse,
		zone[0].PAR_direct,
		zone[0].PAR_diffuse,
		zone[0].Ldown);
	/*--------------------------------------------------------------*/
	/*      update met running averages variables                            */
	/*--------------------------------------------------------------*/

	zone[0].metv.tmin_ravg = 1.0/6.0*zone[0].metv.tmin + 5.0/6.0*zone[0].metv.tmin_ravg;
	zone[0].metv.vpd_ravg = 1/6.0*zone[0].metv.vpd + 5.0/6.0*zone[0].metv.vpd_ravg;
	zone[0].metv.dayl_ravg = 1/6.0*zone[0].metv.dayl + 5.0/6*zone[0].metv.dayl_ravg;
	/*--------------------------------------------------------------*/
	/*	Cycle through the patches for day end computations			*/
	/*--------------------------------------------------------------*/
	for ( patch=0 ; patch<zone[0].num_patches; patch++ ){
		patch_daily_F(
			world,
			basin,
			hillslope,
			zone,
			zone[0].patches[patch],
			command_line,
			event,
			current_date );
	}

	/*--------------------------------------------------------------*/
	/*      update accumulator variables                            */
	/*--------------------------------------------------------------*/
	if ((command_line[0].output_flags.monthly == 1) &&
		(command_line[0].z != NULL) ){
		zone[0].acc_month.precip += zone[0].rain + zone[0].snow;
		zone[0].acc_month.tmin += zone[0].metv.tmin;
		zone[0].acc_month.tmax += zone[0].metv.tmax;
		zone[0].acc_month.K_direct += zone[0].Kdown_direct;
		zone[0].acc_month.K_diffuse += zone[0].Kdown_diffuse;
		zone[0].acc_month.length += 1;
	}

	return;
} /*end zone_daily_F.c*/
Пример #14
0
struct world_object *construct_world(struct command_line_object *command_line){
	/*----------------------------------------------------*/
	/*	Local function definition.			     		  */
	/*----------------------------------------------------*/
	char	**construct_filename_list( FILE *, int);
	long	julday( struct date );
	struct basin_default *construct_basin_defaults(int, char **, struct command_line_object *);
	struct zone_default *construct_zone_defaults(int, char **, struct command_line_object *);
	struct hillslope_default *construct_hillslope_defaults(int, char **, struct command_line_object *);
	struct soil_default *construct_soil_defaults(int, char **, struct command_line_object *);
	struct fire_default *construct_fire_defaults(int, char **, struct command_line_object *);
	struct surface_energy_default *construct_surface_energy_defaults(int, char **, struct command_line_object *);
	struct landuse_default *construct_landuse_defaults(int, char **, struct command_line_object *);
	struct stratum_default *construct_stratum_defaults(int, char **, struct command_line_object *);
	struct base_station_object *construct_base_station(char *,
		struct date, struct date);
	struct basin_object *construct_basin(struct command_line_object *, FILE *, int, struct base_station_object **, struct default_object *);
	struct fire_struct **construct_fire_grid(struct world_object *, struct command_line_object *);
	struct base_station_object **construct_ascii_grid(char *, struct date, struct date);
	void *alloc(size_t, char *, char *);
/*
	void  construct_dclim(struct world_object *);
*/
	/*--------------------------------------------------------------*/
	/*	Local variable definition.									*/
	/*--------------------------------------------------------------*/
	FILE	*world_file;
	int	i;
	char	record[MAXSTR];
	struct world_object *world;
	/*--------------------------------------------------------------*/
	/*	Allocate a world array.										*/
	/*--------------------------------------------------------------*/
	world = (struct world_object *) alloc(1 * sizeof(struct world_object),
		"world", "construct_world");
	/*--------------------------------------------------------------*/
	/*	Try to open the world file in read mode.					*/
	/*--------------------------------------------------------------*/
	if ( (world_file = fopen(command_line[0].world_filename,"r")) == NULL ){
		fprintf(stderr,"FATAL ERROR:  Cannot open world file %s\n",
			command_line[0].world_filename);
		exit(EXIT_FAILURE);
	} /*end if*/
	/*--------------------------------------------------------------*/
	/*	Read in the start calendar date (year, month, day, hour )	*/
	/*--------------------------------------------------------------*/
	fscanf( world_file , "%ld", &world[0].start_date.year);
	read_record(world_file, record);
	fscanf( world_file , "%ld", &world[0].start_date.month);
	read_record(world_file, record);
	fscanf( world_file , "%ld", &world[0].start_date.day);
	read_record(world_file, record);
	fscanf( world_file , "%ld", &world[0].start_date.hour);
	read_record(world_file, record);
	/*--------------------------------------------------------------*/
	/*	Read in the end calendar date (year, month, day, hour )	*/
	/*--------------------------------------------------------------*/
	fscanf( world_file , "%ld", &world[0].end_date.year);
	read_record(world_file, record);
	fscanf( world_file , "%ld", &world[0].end_date.month);
	read_record(world_file, record);
	fscanf( world_file , "%ld", &world[0].end_date.day);
	read_record(world_file, record);
	fscanf( world_file , "%ld", &world[0].end_date.hour);
	read_record(world_file, record);
	/*--------------------------------------------------------------*/
	/* 	command line options can over-ride the worldfile start 	*/
	/*	and/or end dates					*/
	/*--------------------------------------------------------------*/
	if (command_line[0].start_flag == 1) {
		world[0].start_date = command_line[0].start_date;
	}
	if (command_line[0].end_flag == 1) {
		world[0].end_date = command_line[0].end_date;
	}
	
	/*--------------------------------------------------------------*/
	/*	Verify that the start hour was between 0 and 24.			*/
	/*--------------------------------------------------------------*/
	if ( (world[0].start_date.hour<=0) || (world[0].start_date.hour>24)){
		fprintf(stderr,"FATAL ERROR:  Start hour must be >0 and<=24.\n");
		exit(EXIT_FAILURE);
	} /*end if*/
	/*--------------------------------------------------------------*/
	/*	Verify that the end hour was between 1 and 24.				*/
	/*--------------------------------------------------------------*/
	if ( (world[0].end_date.hour<=0) || (world[0].end_date.hour>24)){
		fprintf(stderr,"FATAL ERROR:  End hour must be >0 and<=24.\n");
		exit(EXIT_FAILURE);
	} /*end if*/
	/*--------------------------------------------------------------*/
	/*	Compute the length of the worlds existance in each time step*/
	/*	Note that we use julday to compute the start and end days	*/
	/*	in absolute terms; and that we subtract the start and end	*/
	/*	days from the number of 24 hour days when finding the		*/
	/*	hours duration.												*/
	/*--------------------------------------------------------------*/
	world[0].duration.year = world[0].end_date.year - world[0].start_date.year;
	world[0].duration.month = (world[0].end_date.year
		- world[0].start_date.year)*12 + world[0].end_date.month
		- world[0].start_date.month;
	world[0].duration.day = julday( world[0].end_date)
		- julday( world[0].start_date) ;
	world[0].duration.hour = (world[0].duration.day) * 24
		+ world[0].end_date.hour - world[0].start_date.hour;
	/*--------------------------------------------------------------*/
	/*	Make sure that the world exists for 0 or more hours.		*/
	/*--------------------------------------------------------------*/
	if ( world[0].duration.hour < 0  ){
		fprintf(stderr,
			"FATAL ERROR: In construct_world, the end date given in %s world file is before the start date\n",
			command_line[0].world_filename);
		exit(EXIT_FAILURE);
	} /*end if*/
	/*--------------------------------------------------------------*/
	/*	Allocate world defaults objects.							*/
	/*--------------------------------------------------------------*/
	world[0].defaults = (struct default_object *)
		alloc( sizeof(struct default_object ),"defaults","construct_world");
	
	/*--------------------------------------------------------------*/
	/*	Read in the number of basin default files.		*/
	/*--------------------------------------------------------------*/
	fscanf(world_file,"%d",&(world[0].defaults[0].num_basin_default_files));
	read_record(world_file, record);
	
	/*--------------------------------------------------------------*/
	/*	Read in the basin default files.			*/
	/*--------------------------------------------------------------*/
	world[0].basin_default_files = construct_filename_list( world_file,
		world[0].defaults[0].num_basin_default_files);
	
	/*-----------------------------------*/
	/*	Read in the number of hillslope default files.		*/
	/*--------------------------------------------------------------*/
	fscanf(world_file,"%d",&(world[0].defaults[0].num_hillslope_default_files));
	read_record(world_file, record);
	
	/*--------------------------------------------------------------*/
	/*	Read in the hillslope default files.			*/
	/*--------------------------------------------------------------*/
	world[0].hillslope_default_files = construct_filename_list(	world_file,
		world[0].defaults[0].num_hillslope_default_files);
	
	/*--------------------------------------------------------------*/
	/*	Read in the number of zone default files.		*/
	/*--------------------------------------------------------------*/
	fscanf(world_file,"%d",&(world[0].defaults[0].num_zone_default_files));
	read_record(world_file, record);
	
	/*--------------------------------------------------------------*/
	/*	Read in the zone default files.				*/
	/*--------------------------------------------------------------*/
	world[0].zone_default_files = construct_filename_list( world_file,
		world[0].defaults[0].num_zone_default_files);
	
	/*--------------------------------------------------------------*/
	/*	Read in the number of soil default files.		*/
	/*--------------------------------------------------------------*/
	fscanf(world_file,"%d",&(world[0].defaults[0].num_soil_default_files));
	read_record(world_file, record);
	
	/*--------------------------------------------------------------*/
	/*	Read in the soil default files.				*/
	/*--------------------------------------------------------------*/
	world[0].soil_default_files = construct_filename_list( world_file,
		world[0].defaults[0].num_soil_default_files);
	
	/*--------------------------------------------------------------*/
	/*	Read in the number of land cover default files.		*/
	/*--------------------------------------------------------------*/
	fscanf(world_file,"%d",&(world[0].defaults[0].num_landuse_default_files));
	read_record(world_file, record);
	
	/*--------------------------------------------------------------*/
	/*	Read in the land cover default files.			*/
	/*--------------------------------------------------------------*/
	world[0].landuse_default_files = construct_filename_list( world_file,
		world[0].defaults[0].num_landuse_default_files);
	
	/*--------------------------------------------------------------*/
	/*	Read in the number of veg default files.		*/
	/*--------------------------------------------------------------*/
	fscanf(world_file,"%d",&(world[0].defaults[0].num_stratum_default_files));
	read_record(world_file, record);
	
	/*--------------------------------------------------------------*/
	/*	Read in the veg default files.			*/
	/*--------------------------------------------------------------*/
	world[0].stratum_default_files = construct_filename_list( world_file,
		world[0].defaults[0].num_stratum_default_files);

	
	/*--------------------------------------------------------------*/
	/*	If fire option has been set                             */
	/* Read in the number of fire default files.		*/
	/*--------------------------------------------------------------*/
	if (command_line[0].firespread_flag == 1) {
		fscanf(world_file,"%d",&(world[0].defaults[0].num_fire_default_files));
		read_record(world_file, record);
		/*--------------------------------------------------------------*/
		/*	Read in the fire default files.			*/
		/*--------------------------------------------------------------*/
		world[0].fire_default_files= construct_filename_list( world_file,
			world[0].defaults[0].num_fire_default_files);
	}
	
	/*--------------------------------------------------------------*/
	/*	If surface energy option has been set                             */
	/* Read in the number of surface energy default files.		*/
	/*--------------------------------------------------------------*/
	if (command_line[0].surface_energy_flag == 1) {
		fscanf(world_file,"%d",&(world[0].defaults[0].num_surface_energy_default_files));
		read_record(world_file, record);
		/*--------------------------------------------------------------*/
		/*	Read in the surface energy default files.			*/
		/*--------------------------------------------------------------*/
		world[0].surface_energy_default_files= construct_filename_list( world_file,
			world[0].defaults[0].num_fire_default_files);
	}
	
	/*--------------------------------------------------------------*/
	/*	Read in the number of base_station files.		*/
	/*  In the case of gridded climate input, there will only be    */
	/*  one entry in the world file, so we must get the number      */
	/*  of stations from the climate file instead of the worldfile. */
	/*--------------------------------------------------------------*/
	fscanf(world_file,"%d",&(world[0].num_base_stations));
	read_record(world_file, record);
	
	/*--------------------------------------------------------------*/
	/*	read in list of base_station files.			*/
	/*--------------------------------------------------------------*/
	world[0].base_station_files = construct_filename_list( world_file,
		world[0].num_base_stations);

	// If the file is an ascii gridded climate file, then the number
	// of base stations from the world file is wrong, and we need to
	// reset num_base_stations from the climate file
	if ( command_line[0].gridded_ascii_flag == 1) {
		printf("Opening climate grid %s\n", world[0].base_station_files[0]);
		FILE* grid_base;
		if ( (grid_base = fopen(world[0].base_station_files[0], "r")) == NULL ) {
			fprintf(stderr,
					"Unable to open climate grid file %s\n", 
					world[0].base_station_files[0]);
			exit(EXIT_FAILURE);
		}

		fscanf(grid_base, "%d", &world[0].num_base_stations);

		// Set the world.num_base_station_files to 1 for reference
		// when printing out the world
		world[0].num_base_station_files = 1;
	} else {
		// Non-gridded climate, num_base_station_files = num_base_stations
		world[0].num_base_station_files = world[0].num_base_stations;
	}

	/*--------------------------------------------------------------*/
	/*	Construct the basin_defaults objects.			*/
	/*--------------------------------------------------------------*/
	world[0].defaults[0].basin = construct_basin_defaults(
		world[0].defaults[0].num_basin_default_files,
		world[0].basin_default_files, command_line);
	
	/*--------------------------------------------------------------*/
	/*	Construct the hillslope_defaults objects.		*/
	/*--------------------------------------------------------------*/
	world[0].defaults[0].hillslope = construct_hillslope_defaults(
		world[0].defaults[0].num_hillslope_default_files,
		world[0].hillslope_default_files, command_line);
	
	/*--------------------------------------------------------------*/
	/*	Construct the zones_defaults objects.			*/
	/*--------------------------------------------------------------*/
	world[0].defaults[0].zone = construct_zone_defaults(
		world[0].defaults[0].num_zone_default_files,
		world[0].zone_default_files, command_line);
	
	/*--------------------------------------------------------------*/
	/*	Construct the soil_defaults objects.			*/
	/*--------------------------------------------------------------*/
	world[0].defaults[0].soil = construct_soil_defaults(
		world[0].defaults[0].num_soil_default_files,
		world[0].soil_default_files, command_line);
	
	/*--------------------------------------------------------------*/
	/*	Construct the land_defaults objects.			*/
	/*--------------------------------------------------------------*/
	world[0].defaults[0].landuse = construct_landuse_defaults(
		world[0].defaults[0].num_landuse_default_files,
		world[0].landuse_default_files, command_line);
	
	/*--------------------------------------------------------------*/
	/*	Construct the stratum_defaults objects.			*/
	/*--------------------------------------------------------------*/
	world[0].defaults[0].stratum = construct_stratum_defaults(
		world[0].defaults[0].num_stratum_default_files,
		world[0].stratum_default_files, command_line);

	/*--------------------------------------------------------------*/
	/* if fire spread flag is set					*/
	/*	Construct the fire default objects.			*/
	/*--------------------------------------------------------------*/
	if (command_line[0].firespread_flag == 1) {
		world[0].defaults[0].fire = construct_fire_defaults(
			world[0].defaults[0].num_fire_default_files,
			world[0].fire_default_files, command_line);
	}

	/*--------------------------------------------------------------*/
	/* if surface_energy spread flag is set					*/
	/*	Construct the fire default objects.			*/
	/*--------------------------------------------------------------*/
	if (command_line[0].surface_energy_flag == 1) {
		world[0].defaults[0].surface_energy = construct_surface_energy_defaults(
			world[0].defaults[0].num_surface_energy_default_files,
			world[0].surface_energy_default_files, command_line);
	}


	/*--------------------------------------------------------------*/
	/*	Construct the list of base stations.			*/
	/*--------------------------------------------------------------*/

	if (command_line[0].dclim_flag == 0) {
		/*--------------------------------------------------------------*/
		/*	Construct the base_stations.				*/
		/*--------------------------------------------------------------*/
		printf("\n Constructing base stations flag is %d\n", command_line[0].gridded_ascii_flag);
		
		if ( command_line[0].gridded_ascii_flag == 1) {
		   printf("\n starting construct_ascii_grid");
			world[0].base_stations = construct_ascii_grid( world[0].base_station_files[0],
								  world[0].start_date, 
								  world[0].duration);
		} else {
			
			world[0].base_stations = (struct base_station_object **)
			alloc(world[0].num_base_stations *
				  sizeof(struct base_station_object *),"base_stations","construct_world" );
		
			
			for (i=0; i<world[0].num_base_stations; i++ ) {
				world[0].base_stations[i] = construct_base_station(
					world[0].base_station_files[i],
					world[0].start_date, world[0].duration);
			} /*end for*/
		}
	} /*end if dclim_flag*/
/*
		construct_dclim(world);
*/

	/*--------------------------------------------------------------*/
	/*	Read in the world ID.							*/
	/*--------------------------------------------------------------*/

	printf("\n Finished constructing base stations\n");
	fscanf(world_file,"%d",&(world[0].ID));
	read_record(world_file, record);

	printf("\n Constructing world %d\n", world[0].ID);
	/*--------------------------------------------------------------*/
	/*	Read in the number of basin	files.							*/
	/*--------------------------------------------------------------*/
	fscanf(world_file,"%d",&(world[0].num_basin_files));
	read_record(world_file, record);

	printf("\n Constructing basins\n");
	/*--------------------------------------------------------------*/
	/*	Construct the list of basins. 								*/
	/*--------------------------------------------------------------*/
	world[0].basins = (struct basin_object **)
		alloc(world[0].num_basin_files * sizeof(struct basin_object *),
		"basins","construct_world");
	
	/*--------------------------------------------------------------*/
	/*	Construct the basins. 										*/
	/*--------------------------------------------------------------*/
	for (i=0; i<world[0].num_basin_files; i++ ){
		world[0].basins[i] = construct_basin(
			command_line, world_file, world[0].num_base_stations,
			world[0].base_stations,	world[0].defaults);
	} /*end for*/
	/*--------------------------------------------------------------*/
	/* if fire spread flag is set					*/
	/*	Construct the fire grid object.				*/
	/*--------------------------------------------------------------*/
	world[0].num_fire_grid_row = 0;
	world[0].num_fire_grid_col = 0;
	if (command_line[0].firespread_flag == 1) {
		world[0].fire_grid = construct_fire_grid(world, command_line);

	}	
	/*--------------------------------------------------------------*/
	/*	Close the world_file.										*/
	/*--------------------------------------------------------------*/
	if ( fclose(world_file) != 0 )
		exit(EXIT_FAILURE);
	
	return(world);
} /*end construct_world.c*/
Пример #15
0
struct world_object *construct_world(struct command_line_object *command_line){
	/*----------------------------------------------------*/
	/*	Local function definition.			     		  */
	/*----------------------------------------------------*/
	char	**construct_filename_list( FILE *, int);
	long	julday( struct date );
	struct basin_default *construct_basin_defaults(int, char **, struct command_line_object *);
	struct hillslope_default *construct_hillslope_defaults(int, char **, struct command_line_object *);
	struct zone_default *construct_zone_defaults(int, char **, struct command_line_object *);
	struct soil_default *construct_soil_defaults(int, char **, struct command_line_object *);
	struct landuse_default *construct_landuse_defaults(int, char **, struct command_line_object *);
	struct stratum_default *construct_stratum_defaults(int, char **, struct command_line_object *);
	struct fire_default *construct_fire_defaults(int, char **, struct command_line_object *);
	struct surface_energy_default *construct_surface_energy_defaults(int, char **, struct command_line_object *);
	struct spinup_default *construct_spinup_defaults(int, char **, struct command_line_object *); 
	struct base_station_object *construct_base_station(char *,
		struct date, struct date, int);
	struct basin_object *construct_basin(struct command_line_object *, FILE *, int *, 
		struct base_station_object **, struct default_object *, 
		struct base_station_ncheader_object *, struct world_object *);
	struct fire_patch_object **construct_patch_fire_grid(struct world_object *, struct command_line_object *,struct fire_default def);
	struct fire_object **construct_fire_grid(struct world_object *);
	struct base_station_object **construct_ascii_grid(char *, struct date, struct date);
	struct base_station_ncheader_object *construct_netcdf_header(struct world_object *, char *);
  void *construct_spinup_thresholds(char *, struct world_object *, struct command_line_object *);	
	void *alloc(size_t, char *, char *);

	void resemble_hourly_date(struct world_object *);
	/*--------------------------------------------------------------*/
	/*	Local variable definition.									*/
	/*--------------------------------------------------------------*/
	FILE	*world_file;
	FILE	*header_file;
	int 	header_file_flag = 0;
	int		legacy_worldfile = 0;
	int	i;
	char	record[MAXSTR];
	struct world_object *world;
	/*--------------------------------------------------------------*/
	/*	Allocate a world array.										*/
	/*--------------------------------------------------------------*/
	world = (struct world_object *) alloc(1 * sizeof(struct world_object),
		"world", "construct_world");
	/*--------------------------------------------------------------*/
	/*	Try to open the world file in read mode.					*/
	/*--------------------------------------------------------------*/
	if ( (world_file = fopen(command_line[0].world_filename,"r")) == NULL ){
		fprintf(stderr,"FATAL ERROR:  Cannot open world file %s\n",
			command_line[0].world_filename);
		exit(EXIT_FAILURE);
	} /*end if*/

	/* Determine where to read worldfile header information from.
	 * The three options, in order of precedence are:
		1. -whdr command line option
		2. ${WORLDFILE_NAME}.hdr
		3. From legacy world file (deprecated)
	 */
	if ( command_line->world_header_flag ) {
		// Option 1. -whdr command line option
		header_file = fopen(command_line->world_header_filename, "r");
		if ( header_file == NULL ) {
			fprintf(stderr,"FATAL ERROR:  Cannot open world header file %s\n",
					command_line->world_header_filename);
			exit(EXIT_FAILURE);
		}
		header_file_flag = 1;
		printf("Reading specified world file header %s\n", command_line->world_header_filename);
	} else {
		// Set up file name for Option 2. ${WORLDFILE_NAME}.hdr
		if ( snprintf(command_line->world_header_filename, FILEPATH_LEN, "%s.hdr", command_line->world_filename) >= FILEPATH_LEN ) {
			fprintf(stderr,
					"Couldn't read world file header as filename would have been longer than the limit of %d\n", FILEPATH_LEN);
			exit(EXIT_FAILURE);
		}

		if ( access(command_line->world_header_filename, R_OK) == 0 ) {
			// Option 2. ${WORLDFILE_NAME}.hdr
			header_file = fopen(command_line->world_header_filename, "r");
			if ( header_file == NULL ) {
				fprintf(stderr,"FATAL ERROR:  Cannot open world header file %s\n",
						command_line->world_header_filename);
				exit(EXIT_FAILURE);
			}
			header_file_flag = 1;
			printf("\nFound world file header %s\n", command_line->world_header_filename);
		} else {
			// Option 3. From legacy world file (deprecated)
			header_file = world_file;
			legacy_worldfile = 1;
			printf("\nWARNING\nReading world file header from legacy world file.\nThis feature will be removed from a future release.\nPlease re-run g2w to generate a separate world file header.\nWARNING\n\n");
		}
	}

	if ( legacy_worldfile ) {
		/* For backward compatibility read date from worldfile if it is an old-style
		 * worldfile with an in-line header.
		 * NOTE: we are throwing these values away, letting the command line values
		 * take precedence.
		*/
		/*--------------------------------------------------------------*/
		/*	Read in the start calendar date (year, month, day, hour )	*/
		/*--------------------------------------------------------------*/
		fscanf( world_file , "%ld", &world[0].start_date.year);
		read_record(world_file, record);
		fscanf( world_file , "%ld", &world[0].start_date.month);
		read_record(world_file, record);
		fscanf( world_file , "%ld", &world[0].start_date.day);
		read_record(world_file, record);
		fscanf( world_file , "%ld", &world[0].start_date.hour);
		read_record(world_file, record);
		/*--------------------------------------------------------------*/
		/*	Read in the end calendar date (year, month, day, hour )	*/
		/*--------------------------------------------------------------*/
		fscanf( world_file , "%ld", &world[0].end_date.year);
		read_record(world_file, record);
		fscanf( world_file , "%ld", &world[0].end_date.month);
		read_record(world_file, record);
		fscanf( world_file , "%ld", &world[0].end_date.day);
		read_record(world_file, record);
		fscanf( world_file , "%ld", &world[0].end_date.hour);
		read_record(world_file, record);
	}
	
	/*--------------------------------------------------------------
	 * Always use command line start and end dates
	 */
	world[0].start_date = command_line[0].start_date;
	world[0].end_date = command_line[0].end_date;

	/*--------------------------------------------------------------*/
	/*	Verify that the start hour was between 0 and 24.			*/
	/*--------------------------------------------------------------*/
	if ( (world[0].start_date.hour<=0) || (world[0].start_date.hour>24)){
		fprintf(stderr,"FATAL ERROR:  Start hour must be >0 and<=24.\n");
		exit(EXIT_FAILURE);
	} /*end if*/
	/*--------------------------------------------------------------*/
	/*	Verify that the end hour was between 1 and 24.				*/
	/*--------------------------------------------------------------*/
	if ( (world[0].end_date.hour<=0) || (world[0].end_date.hour>24)){
		fprintf(stderr,"FATAL ERROR:  End hour must be >0 and<=24.\n");
		exit(EXIT_FAILURE);
	} /*end if*/
	/*--------------------------------------------------------------*/
	/*	Compute the length of the worlds existance in each time step*/
	/*	Note that we use julday to compute the start and end days	*/
	/*	in absolute terms; and that we subtract the start and end	*/
	/*	days from the number of 24 hour days when finding the		*/
	/*	hours duration.												*/
	/*--------------------------------------------------------------*/
	world[0].duration.year = world[0].end_date.year - world[0].start_date.year;
	world[0].duration.month = (world[0].end_date.year
		- world[0].start_date.year)*12 + world[0].end_date.month
		- world[0].start_date.month;
	world[0].duration.day = julday( world[0].end_date)
		- julday( world[0].start_date) ;
	world[0].duration.hour = (world[0].duration.day) * 24
		+ world[0].end_date.hour - world[0].start_date.hour;
	/*--------------------------------------------------------------*/
	/*	Make sure that the world exists for 0 or more hours.		*/
	/*--------------------------------------------------------------*/
	if ( world[0].duration.hour < 0  ){
		fprintf(stderr,
			"FATAL ERROR: In construct_world, the end date given in %s world file is before the start date\n",
			command_line[0].world_filename);
		exit(EXIT_FAILURE);
	} /*end if*/
	/*--------------------------------------------------------------*/
	/*	Allocate world defaults objects.							*/
	/*--------------------------------------------------------------*/
	world[0].defaults = (struct default_object *)
		alloc( sizeof(struct default_object ),"defaults","construct_world");
	
	/*--------------------------------------------------------------*/
	/*	Read in the number of basin default files.		*/
	/*--------------------------------------------------------------*/
	fscanf(header_file,"%d",&(world[0].defaults[0].num_basin_default_files));
	read_record(header_file, record);
	
	/*--------------------------------------------------------------*/
	/*	Read in the basin default files.			*/
	/*--------------------------------------------------------------*/
	world[0].basin_default_files = construct_filename_list( header_file,
		world[0].defaults[0].num_basin_default_files);
	
	/*-----------------------------------*/
	/*	Read in the number of hillslope default files.		*/
	/*--------------------------------------------------------------*/
	fscanf(header_file,"%d",&(world[0].defaults[0].num_hillslope_default_files));
	read_record(header_file, record);
	
	/*--------------------------------------------------------------*/
	/*	Read in the hillslope default files.			*/
	/*--------------------------------------------------------------*/
	world[0].hillslope_default_files = construct_filename_list(	header_file,
		world[0].defaults[0].num_hillslope_default_files);
	
	/*--------------------------------------------------------------*/
	/*	Read in the number of zone default files.		*/
	/*--------------------------------------------------------------*/
	fscanf(header_file,"%d",&(world[0].defaults[0].num_zone_default_files));
	read_record(header_file, record);
	
	/*--------------------------------------------------------------*/
	/*	Read in the zone default files.				*/
	/*--------------------------------------------------------------*/
	world[0].zone_default_files = construct_filename_list( header_file,
		world[0].defaults[0].num_zone_default_files);
	
	/*--------------------------------------------------------------*/
	/*	Read in the number of soil default files.		*/
	/*--------------------------------------------------------------*/
	fscanf(header_file,"%d",&(world[0].defaults[0].num_soil_default_files));
	read_record(header_file, record);
	
	/*--------------------------------------------------------------*/
	/*	Read in the soil default files.				*/
	/*--------------------------------------------------------------*/
	world[0].soil_default_files = construct_filename_list( header_file,
		world[0].defaults[0].num_soil_default_files);
	
	/*--------------------------------------------------------------*/
	/*	Read in the number of land cover default files.		*/
	/*--------------------------------------------------------------*/
	fscanf(header_file,"%d",&(world[0].defaults[0].num_landuse_default_files));
	read_record(header_file, record);
        	
	/*--------------------------------------------------------------*/
	/*	Read in the land cover default files.			*/
	/*--------------------------------------------------------------*/
	world[0].landuse_default_files = construct_filename_list( header_file,
		world[0].defaults[0].num_landuse_default_files);
	
	/*--------------------------------------------------------------*/
	/*	Read in the number of veg default files.		*/
	/*--------------------------------------------------------------*/
	fscanf(header_file,"%d",&(world[0].defaults[0].num_stratum_default_files));
	read_record(header_file, record);
	/*--------------------------------------------------------------*/
	/*	Read in the veg default files.			*/
	/*--------------------------------------------------------------*/
	world[0].stratum_default_files = construct_filename_list( header_file,
		world[0].defaults[0].num_stratum_default_files);

	
	/*--------------------------------------------------------------*/
	/*	If fire option has been set                             */
	/* Read in the number of fire default files.		*/
	/*--------------------------------------------------------------*/
	if (command_line[0].firespread_flag == 1) {
		fscanf(header_file,"%d",&(world[0].defaults[0].num_fire_default_files));
		read_record(header_file, record);
		/*--------------------------------------------------------------*/
		/*	Read in the fire default files.			*/
		/*--------------------------------------------------------------*/
		world[0].fire_default_files= construct_filename_list( header_file,
			world[0].defaults[0].num_fire_default_files);
	}
	
	/*--------------------------------------------------------------*/
	/*	If surface energy option has been set                             */
	/* Read in the number of surface energy default files.		*/
	/*--------------------------------------------------------------*/
	if (command_line[0].surface_energy_flag == 1) {
		fscanf(header_file,"%d",&(world[0].defaults[0].num_surface_energy_default_files));
		read_record(header_file, record);
		/*--------------------------------------------------------------*/
		/*	Read in the surface energy default files.			*/
		/*--------------------------------------------------------------*/
		world[0].surface_energy_default_files= construct_filename_list( header_file,
			world[0].defaults[0].num_fire_default_files);
	}
	
	/*--------------------------------------------------------------*/
	/*	If spinup flag has been set                             */
	/*      Read in the number of spinup default files              */
	/*--------------------------------------------------------------*/
	if (command_line[0].vegspinup_flag > 0) {
		fscanf(header_file,"%d",&(world[0].defaults[0].num_spinup_default_files));
		read_record(header_file, record);
		/*--------------------------------------------------------------*/
		/*	Read in the spinup default files.			*/
		/*--------------------------------------------------------------*/
	        world[0].spinup_default_files = construct_filename_list( header_file,
		        world[0].defaults[0].num_spinup_default_files);
	}

	/*--------------------------------------------------------------*/
	/*	Read in the number of base_station files.		*/
	/*  In the case of gridded climate input, there will only be    */
	/*  one entry in the world file, so we must get the number      */
	/*  of stations from the climate file instead of the worldfile. */
	/*--------------------------------------------------------------*/
	fscanf(header_file,"%d",&(world[0].num_base_stations));
	read_record(header_file, record);
	
	/*--------------------------------------------------------------*/
	/*	read in list of base_station files.			*/
	/*--------------------------------------------------------------*/
	world[0].base_station_files = construct_filename_list( header_file,
		world[0].num_base_stations);

	// If the file is an ascii gridded climate file, then the number
	// of base stations from the world file is wrong, and we need to
	// reset num_base_stations from the climate file
	if ( command_line[0].gridded_ascii_flag == 1) {
		printf("Opening climate grid %s\n", world[0].base_station_files[0]);
		FILE* grid_base;
		if ( (grid_base = fopen(world[0].base_station_files[0], "r")) == NULL ) {
			fprintf(stderr,
					"Unable to open climate grid file %s\n", 
					world[0].base_station_files[0]);
			exit(EXIT_FAILURE);
		}

		fscanf(grid_base, "%d", &world[0].num_base_stations);

		// Set the world.num_base_station_files to 1 for reference
		// when printing out the world
		world[0].num_base_station_files = 1;
	} else if (command_line[0].gridded_netcdf_flag == 1) {
		world[0].num_base_station_files = world[0].num_base_stations;
	} else {
		// Non-gridded climate, num_base_station_files = num_base_stations
		world[0].num_base_station_files = world[0].num_base_stations;
	}

	/*--------------------------------------------------------------*/
	/*	Construct the basin_defaults objects.			*/
	/*--------------------------------------------------------------*/
	world[0].defaults[0].basin = construct_basin_defaults(
		world[0].defaults[0].num_basin_default_files,
		world[0].basin_default_files, command_line);
	
	/*--------------------------------------------------------------*/
	/*	Construct the hillslope_defaults objects.		*/
	/*--------------------------------------------------------------*/
	world[0].defaults[0].hillslope = construct_hillslope_defaults(
		world[0].defaults[0].num_hillslope_default_files,
		world[0].hillslope_default_files, command_line);
	
	/*--------------------------------------------------------------*/
	/*	Construct the zones_defaults objects.			*/
	/*--------------------------------------------------------------*/
	world[0].defaults[0].zone = construct_zone_defaults(
		world[0].defaults[0].num_zone_default_files,
		world[0].zone_default_files, command_line);
	
	/*--------------------------------------------------------------*/
	/*	Construct the soil_defaults objects.			*/
	/*--------------------------------------------------------------*/
	world[0].defaults[0].soil = construct_soil_defaults(
		world[0].defaults[0].num_soil_default_files,
		world[0].soil_default_files, command_line);
	
	/*--------------------------------------------------------------*/
	/*	Construct the land_defaults objects.			*/
	/*--------------------------------------------------------------*/
	world[0].defaults[0].landuse = construct_landuse_defaults(
		world[0].defaults[0].num_landuse_default_files,
		world[0].landuse_default_files, command_line);
	
	/*--------------------------------------------------------------*/
	/*	Construct the stratum_defaults objects.			*/
	/*--------------------------------------------------------------*/
	world[0].defaults[0].stratum = construct_stratum_defaults(
		world[0].defaults[0].num_stratum_default_files,
		world[0].stratum_default_files, command_line);

	/*--------------------------------------------------------------*/
	/* if fire spread flag is set					*/
	/*	Construct the fire default objects.			*/
	/*--------------------------------------------------------------*/
	if (command_line[0].firespread_flag == 1) {
		world[0].defaults[0].fire = construct_fire_defaults(
			world[0].defaults[0].num_fire_default_files,
			world[0].fire_default_files, command_line);
	}

	printf("\nConstructed fire defaults\n");
	/*--------------------------------------------------------------*/
	/* if surface_energy spread flag is set					*/
	/*	Construct the fire default objects.			*/
	/*--------------------------------------------------------------*/
	if (command_line[0].surface_energy_flag == 1) {
		world[0].defaults[0].surface_energy = construct_surface_energy_defaults(
			world[0].defaults[0].num_surface_energy_default_files,
			world[0].surface_energy_default_files, command_line);
	}

	/*--------------------------------------------------------------*/
	/* if spinup flag is set				                              	*/
	/*	Construct the spinup default objects.	                    	*/
	/*--------------------------------------------------------------*/
	if (command_line[0].vegspinup_flag > 0) {
	  printf("\nConstructed spinup defaults \n");
		world[0].defaults[0].spinup = construct_spinup_defaults(
			world[0].defaults[0].num_spinup_default_files,
			world[0].spinup_default_files, command_line);
	}


	/*--------------------------------------------------------------*/
	/*	Construct the list of base stations.			*/
	/*--------------------------------------------------------------*/

	if (command_line[0].dclim_flag == 0) {
		/*--------------------------------------------------------------*/
		/*	Construct the base_stations.				*/
		/*--------------------------------------------------------------*/
		if ( command_line[0].gridded_ascii_flag == 1) {
			printf("\nConstructing base stations from ASCII GRID");
			world[0].base_stations = construct_ascii_grid( world[0].base_station_files[0],
												world[0].start_date, 
												world[0].duration);
		}
		else if(command_line[0].gridded_netcdf_flag == 1){
			printf("\nConstructing base stations from NETCDF GRID");
			world[0].base_stations = (struct base_station_object **)
			alloc(1000 * sizeof(struct base_station_object *),"base_stations","construct_world" );
			world[0].base_station_ncheader = (struct base_station_ncheader_object *)	
			alloc(sizeof(struct base_station_ncheader_object),"base_station_ncheader","construct_world");
			world[0].base_station_ncheader = construct_netcdf_header(world,
												world[0].base_station_files[0]);
			/*printf("\n  file=%s firstID=%d num=%d numfiles=%d lai=%lf screenht=%lf sdist=%lf startyr=%d dayoffset=%d leapyr=%d precipmult=%lf",
				   world[0].base_station_ncheader[0].netcdf_tmax_filename,
				   world[0].ID,
				   world[0].num_base_stations,
				   world[0].num_base_station_files,
				   world[0].base_station_ncheader[0].effective_lai,
				   world[0].base_station_ncheader[0].screen_height,
				   world[0].base_station_ncheader[0].sdist,
				   world[0].base_station_ncheader[0].year_start,
				   world[0].base_station_ncheader[0].day_offset,
				   world[0].base_station_ncheader[0].leap_year,
				   world[0].base_station_ncheader[0].precip_mult);*/
		}
		else {
			printf("\nConstructing base stations");
			world[0].base_stations = (struct base_station_object **)
			alloc(world[0].num_base_stations *
				  sizeof(struct base_station_object *),"base_stations","construct_world" );
			
			
			for (i=0; i<world[0].num_base_stations; i++ ) {
				world[0].base_stations[i] = construct_base_station(
								world[0].base_station_files[i],
								world[0].start_date, world[0].duration,
								command_line[0].clim_repeat_flag);
			} /*end for*/

			/*--------------------------------------------------------------*/
			/* List the hourly record for all base station, resemble the hourly records*/
			/*--------------------------------------------------------------*/
			/*
			if(world[0].num_base_stations > 1){
			    resemble_hourly_date(world);
			}*/

		}
	} /*end if dclim_flag*/
	
        

	/*--------------------------------------------------------------*/
	/*	Read in the world ID.							*/
	/*--------------------------------------------------------------*/

	printf("\n Finished constructing base stations\n");
	fscanf(world_file,"%d",&(world[0].ID));
	read_record(world_file, record);

	printf("\n Constructing world %d\n", world[0].ID);
	/*--------------------------------------------------------------*/
	/*	Read in the number of basin	files.							*/
	/*--------------------------------------------------------------*/
	fscanf(world_file,"%d",&(world[0].num_basin_files));
	read_record(world_file, record);

	printf("\n Constructing basins\n");
	/*--------------------------------------------------------------*/
	/*	Construct the list of basins. 								*/
	/*--------------------------------------------------------------*/
	world[0].basins = (struct basin_object **)
		alloc(world[0].num_basin_files * sizeof(struct basin_object *),
		"basins","construct_world");
	
	/*--------------------------------------------------------------*/
	/*	Construct the basins. 										*/
	/*--------------------------------------------------------------*/
	for (i=0; i<world[0].num_basin_files; i++ ){
		world[0].basins[i] = construct_basin(
			command_line, world_file, &(world[0].num_base_stations),
			world[0].base_stations,	world[0].defaults, 
			world[0].base_station_ncheader, world);
	} /*end for*/

	/*--------------------------------------------------------------*/
	/*	If spinup flag is set construct the spinup thresholds object*/
	/*--------------------------------------------------------------*/
	if (command_line[0].vegspinup_flag > 0) {
    printf("\nReading spinup threshold file %s", command_line[0].vegspinup_filename);
		world[0].spinup_thresholds = construct_spinup_thresholds(command_line[0].vegspinup_filename, &world[0], command_line);
  }

	/*--------------------------------------------------------------*/
	/* if fire spread flag is set					*/
	/*	Construct the fire grid object.				*/
	/*--------------------------------------------------------------*/
	world[0].num_fire_grid_row = 0;
	world[0].num_fire_grid_col = 0;
	if (command_line[0].firespread_flag == 1) {
		world[0].patch_fire_grid = construct_patch_fire_grid(world, command_line,*(world[0].defaults[0].fire));
		world[0].fire_grid = construct_fire_grid(world);

	}	
	/*--------------------------------------------------------------*/
	/*	Close the world_file and header (if necessary)	         	*/
	/*--------------------------------------------------------------*/
	if ( fclose(world_file) != 0 ) exit(EXIT_FAILURE);
	if ( header_file_flag ) {
		fclose(header_file);
	}

	
	return(world);
} /*end construct_world.c*/
Пример #16
0
void	execute_tec(
					struct	tec_object *tecfile ,
					struct command_line_object *command_line,
					struct	world_output_file_object *outfile,
					struct	world_output_file_object *growth_outfile,
					struct world_object *world)
{
	/*--------------------------------------------------------------*/
	/*	Local Function Declarations.								*/
	/*--------------------------------------------------------------*/
	int		cal_date_lt(struct date, struct date );
	
	long	julday( struct date );
	
	struct	date	caldat( long );
	
	struct	tec_entry	*construct_tec_entry( struct date, char * );
	
	void	world_daily_I(
		long,
		struct world_object *,
		struct command_line_object *,
		struct tec_entry *,
		struct date);
	
	void	world_hourly(
		struct world_object *,
		struct command_line_object *,
		struct tec_entry *,
		struct date);
	
	void	world_daily_F(
		long,
		struct world_object *,
		struct command_line_object *,
		struct tec_entry *,
		struct date);
	
	void	handle_event(
		struct	tec_entry	*,
		struct	command_line_object	*,
		struct	date,
		struct	world_object	*);
	
	void	execute_yearly_growth_output_event(
		struct	world_object	*,
		struct	command_line_object	*,
		struct	date,
		struct	world_output_file_object *);

	void	execute_yearly_output_event(
		struct	world_object	*,
		struct	command_line_object	*,
		struct	date,
		struct	world_output_file_object *);
	
	void	execute_daily_output_event(
		struct	world_object	*,
		struct	command_line_object	*,
		struct	date,
		struct	world_output_file_object *);
	
	void	execute_daily_growth_output_event(
		struct	world_object	*,
		struct	command_line_object	*,
		struct	date,
		struct	world_output_file_object *);

	void	execute_monthly_output_event(
		struct	world_object	*,
		struct	command_line_object	*,
		struct	date,
		struct	world_output_file_object *);
	
	void	execute_hourly_output_event(
		struct	world_object	*,
		struct	command_line_object	*,
		struct	date,
		struct	world_output_file_object *);

	void	execute_firespread_event(
		struct	world_object	*,
		struct	command_line_object	*,
		struct	date);
	
	/*--------------------------------------------------------------*/
	/*	Local Variable Definition. 									*/
	/*--------------------------------------------------------------*/
	int check;
	long	day;
	long	hour;
	long	month;
	long	year;
	struct	date	current_date;
	struct	date	next_date;
	struct	tec_entry	*event;
	
	/*--------------------------------------------------------------*/
	/*	Initialize the indices into the base station clime sequences*/
	/*--------------------------------------------------------------*/
	year = 0;
	month = 0;
	day = 0;
	hour = 0;
	
	/*--------------------------------------------------------------*/
	/*	Initialize the tec event									*/
	/*--------------------------------------------------------------*/
	event =  construct_tec_entry(world[0].end_date,"none");
	
	/*--------------------------------------------------------------*/
	/*	Loop from the start of the world to the end of the world.	*/
	/*--------------------------------------------------------------*/
	current_date = world[0].start_date;
	next_date = current_date;
	while ( cal_date_lt(current_date,world[0].end_date)){
		/*--------------------------------------------------------------*/
		/*		Perform the tec event.									*/
		/*--------------------------------------------------------------*/
		handle_event(event,command_line,current_date,world);
		/*--------------------------------------------------------------*/
		/*		read the next tec file entry.							*/
		/*		if we are not at the end of the tec file.				*/
		/*--------------------------------------------------------------*/
		if ( !(feof(tecfile[0].tfile))){
			/*--------------------------------------------------------------*/
			/*			read in the next tec line.							*/
			/*--------------------------------------------------------------*/
			check = fscanf(tecfile[0].tfile,"%d %d %d %d %s\n",
				&(event[0].cal_date.year),
				&(event[0].cal_date.month),
				&(event[0].cal_date.day),
				&(event[0].cal_date.hour),
				event[0].command);
			/*--------------------------------------------------------------*/
			/*			report an error if for some reason we cant read it	*/
			/*--------------------------------------------------------------*/
			if ( !check ){
				fprintf(stderr,"\nERROR:  the tec file is corrupted.");
				fclose(tecfile[0].tfile);
				exit(EXIT_FAILURE);
			} /*end if*/
		} /*end if*/
		/*--------------------------------------------------------------*/
		/* 	if end of tec file next event is the end of the world		*/
		/*--------------------------------------------------------------*/
		else{
			event =  construct_tec_entry(world[0].end_date, "none");
		} /*end if-else*/
		/*--------------------------------------------------------------*/
		/*		If the next event's date exceeds the end_date then		*/
		/*		set the next event to nothing and at a time at the 		*/
		/*		end of the simulation.									*/
		/*--------------------------------------------------------------*/
		if ( cal_date_lt(event[0].cal_date,	world[0].end_date) == 0  ){
			event =  construct_tec_entry(world[0].end_date,	"none");
		} /*end if*/
		/*--------------------------------------------------------------*/
		/*		Do stuff until the next tec event.						*/
		/*--------------------------------------------------------------*/
		while ( cal_date_lt(current_date, event[0].cal_date)){
			/*--------------------------------------------------------------*/
			/*			Simulate the world for the start of this day e		*/
			/*--------------------------------------------------------------*/
			if ( current_date.hour == 1 ){
				world_daily_I(
					day,
					world,
					command_line,
					event,
					current_date);
			} /*end if*/
			/*--------------------------------------------------------------*/
			/*          Do hourly stuff for the day.                        */
			/*--------------------------------------------------------------*/
			world_hourly( world,
				command_line,
				event,
				current_date);
			
			/*--------------------------------------------------------------*/
			/*			Perform any requested hourly output					*/
			/*--------------------------------------------------------------*/
			if (command_line[0].output_flags.hourly == 1)
				execute_hourly_output_event(world,command_line,current_date,outfile);
			/*--------------------------------------------------------------*/
			/*			Increment to the next hour.							*/
			/*--------------------------------------------------------------*/
			current_date.hour++;
			/*--------------------------------------------------------------*/
			/*			Check if this is a day end.							*/
			/*--------------------------------------------------------------*/
			if ( current_date.hour == 25 ){
				/*--------------------------------------------------------------*/
				/*			Simulate the world for the end of this day e		*/
				/*--------------------------------------------------------------*/
				world_daily_F(
					day,
					world,
					command_line,
					event,
					current_date);
			        // printf("%s\n","finish_daily_simulation");	
				/*--------------------------------------------------------------*/
				/*			Perform any requested daily output					*/
				/*--------------------------------------------------------------*/
				if ((command_line[0].output_flags.daily_growth == 1) &&
							(command_line[0].grow_flag > 0) ) {
						execute_daily_growth_output_event(
						world,
						command_line,
						current_date,
						growth_outfile);
				}
				if (command_line[0].output_flags.daily == 1) {
                                                //printf("%s\n","before_daily_output");
						execute_daily_output_event(
						world,
						command_line,
						current_date,
						outfile);
                               }
				/*--------------------------------------------------------------*/
				/*			Perform any requested yearly output					*/
				/*--------------------------------------------------------------*/
				if ((command_line[0].output_flags.yearly == 1) &&
					(command_line[0].output_yearly_date.month==current_date.month)&&
					(command_line[0].output_yearly_date.day == current_date.day))
							execute_yearly_output_event(
							world,
							command_line,
							current_date,
							outfile);

				if ((command_line[0].output_flags.yearly_growth == 1) &&
					(command_line[0].output_yearly_date.month==current_date.month)&&
					(command_line[0].output_yearly_date.day == current_date.day) &&
					(command_line[0].grow_flag > 0) )
					execute_yearly_growth_output_event(
					world,
					command_line,
					current_date,
					growth_outfile);
				/*--------------------------------------------------------------*/
				/*				Determine the new calendar date if we add 1 day.*/
				/*				Do this by first conversting the current cal	*/
				/* 				endar date into a julian day.  Then adding one	*/
				/*				to the julian day and the converting back to	*/
				/*				get tomorrows calendar date.					*/
				/*				We assume that it starts at hour 1.				*/
				/*--------------------------------------------------------------*/
				day = day + 1;
				next_date = caldat(julday(current_date)+1);
				current_date.day = next_date.day;
				current_date.hour = next_date.hour;
				if (command_line[0].verbose_flag > 0)
					fprintf(stderr,"\n\nYEAR %d MONTH %d DAY %d\n\n",
					current_date.year,current_date.month,current_date.day);
			} /*end if*/
			/*--------------------------------------------------------------*/
			/*			Check if this is a month end.						*/
			/*--------------------------------------------------------------*/
			if ( next_date.month !=	current_date.month ){
				/*--------------------------------------------------------------*/
				/*				Do monthly stuff.								*/
				/*--------------------------------------------------------------*/

				/*--------------------------------------------------------------*/
				/* if fire spread is called - initiate fire spread routine 	*/
				/*--------------------------------------------------------------*/
				if (command_line[0].firespread_flag == 1) {
					execute_firespread_event(
						world,
						command_line,
						current_date);
				}	
				
				/*--------------------------------------------------------------*/
				/*			Perform any requested monthly output				*/
				/*--------------------------------------------------------------*/
				if (command_line[0].output_flags.monthly == 1)
						execute_monthly_output_event(
						world,
						command_line,
						current_date,
						outfile);
				/*--------------------------------------------------------------*/
				/*				increment month 								*/
				/*--------------------------------------------------------------*/
				month = month + 1;
				current_date.month = next_date.month;
			} /* end if */
			/*--------------------------------------------------------------*/
			/*			Check if this is a year end.						*/
			/*--------------------------------------------------------------*/
			if ( next_date.year != current_date.year ){
				/*--------------------------------------------------------------*/
				/*				Do yearly stuff.								*/
				/*--------------------------------------------------------------*/
				
				/*--------------------------------------------------------------*/
				/*				increment year  								*/
				/*-------------------------------------------------------------*/
				printf("Year %d\n", current_date.year);
				year = year + 1;
				current_date.year= next_date.year;
			}  /*end if*/
			} /*end while*/
		} /*end while*/
		return;
} /*end execute_tec.c*/
Пример #17
0
void		zone_daily_F(
						 long	day,
						 struct	world_object	*world,
						 struct	basin_object	*basin,
						 struct	hillslope_object	*hillslope,
						 struct 	zone_object 	*zone,
						 struct 	command_line_object *command_line,
						 struct	tec_entry		*event,
						 struct 	date 			current_date)
						 
{
	/*--------------------------------------------------------------*/
	/*  Local Function Declarations.                                */
	/*--------------------------------------------------------------*/
	void    patch_daily_F(
		struct	world_object	*,
		struct	basin_object	*,
		struct	hillslope_object	*,
		struct 	zone_object 	*,
		struct patch_object *,
		struct command_line_object *,
		struct tec_entry *,
		struct date);
	long julday(struct date);
	
	/*--------------------------------------------------------------*/
	/*  Local variable definition.                                  */
	/*--------------------------------------------------------------*/
	int 	patch;
	double snow_rain_range;
	double	es;
	double Tcloud, f8, e8z, tau8;
	/*--------------------------------------------------------------*/
	/*  Update the forcing functions based on the hourly computation*/
	/*--------------------------------------------------------------*/
	/* Set daily Kdowns to calculated if not given as inputs.		*/
	/* Transmissivity & cloud fractions carry over from zone_daily_I.	*/
	if ((zone[0].Kdown_direct_flag == 0) ||
		(zone[0].Kdown_diffuse_flag == 0)) {
			zone[0].Kdown_direct_flat = zone[0].Kdown_direct_flat_calc;
			zone[0].Kdown_direct = zone[0].Kdown_direct_calc;
			zone[0].Kdown_diffuse_flat = zone[0].Kdown_diffuse_flat_calc;
			zone[0].Kdown_diffuse = zone[0].Kdown_diffuse_calc;
		}
	/* Otherwise use input Kdowns and calculate transmissivity as	*/
	/* ratio between given and calculated, then generate cloud		*/
	/* fraction estimates for longwave calculations. */ 
	else {
			zone[0].atm_trans = (zone[0].Kdown_direct+zone[0].Kdown_diffuse) 
						/ (zone[0].Kdown_direct_calc + zone[0].Kdown_diffuse_calc);
			zone[0].cloud_fraction = 1.0 - zone[0].atm_trans
						/(zone[0].defaults[0][0].sea_level_clear_sky_trans
						+ zone[0].z * zone[0].defaults[0][0].atm_trans_lapse_rate);
			zone[0].cloud_fraction = max(zone[0].cloud_fraction,0.0);
			zone[0].cloud_fraction = min(zone[0].cloud_fraction,1.0);
			zone[0].cloud = zone[0].cloud_opacity * zone[0].cloud_fraction * 12.0;
		}
	
	
	/*--------------------------------------------------------------*/
	/*	Make use of more accurate basin daylength 		*/
	/*	if it is not given and the zone horizons are 0		*/
	/*	If the zone horizons are non zero we use the 		*/
	/*	daylength computed from hourly solar geometry.		*/
	/*--------------------------------------------------------------*/
	if ( (zone[0].daylength_flag == 0) &&
		(zone[0].e_horizon == 0) &&
		(zone[0].w_horizon == 0) ){
		/*--------------------------------------------------------------*/
		/*		adjust the simulated radiation for new dayl	*/
		/*--------------------------------------------------------------*/

		if (zone[0].Kdown_direct_flag == 0){
			zone[0].Kdown_direct = zone[0].Kdown_direct
				* ( basin[0].daylength / zone[0].metv.dayl );
		}
		if (zone[0].Kdown_diffuse_flag == 0){
			zone[0].Kdown_diffuse = zone[0].Kdown_diffuse
				* ( basin[0].daylength / zone[0].metv.dayl );
		}
		/*--------------------------------------------------------------*/
		/*		update the zone daylength to be the basin dayl	*/
		/*		which is likely more accurate.			*/
		/*--------------------------------------------------------------*/
		zone[0].metv.dayl = basin[0].daylength;
	}

	/*--------------------------------------------------------------*/
	/* MOVED TEMP AND PRECIP CALCS UP SO CAN BE USED FOR CLOUD FRAC */
	/*--------------------------------------------------------------*/
	/*  metv.tavg calc in zone_daily_I								*/
	/*--------------------------------------------------------------*/
	/*	metv.tday	(degrees C)										*/
	/*																*/
	/*	Eq 1. Page 4, "MTCLIM"										*/
	/*--------------------------------------------------------------*/
	if ( zone[0].metv.tday == -999.0 ){
		zone[0].metv.tday = zone[0].defaults[0][0].temcf
		* (zone[0].metv.tmax - zone[0].metv.tavg) + zone[0].metv.tavg;
	}
	/*--------------------------------------------------------------*/
	/*	metv.tnight 	(degrees C)								*/
	/*																*/
	/*	zcomp.c C Rhessys code										*/
	/*--------------------------------------------------------------*/
	if ( zone[0].metv.tnight == -999.0 ){
		zone[0].metv.tnight = (zone[0].metv.tday + zone[0].metv.tmin)/2.0;
	}
	/*--------------------------------------------------------------*/
	/*	If we have no snow data determine if the rain should be snow*/
	/*																*/
	/*	Based on U.S Army Corps of ENgineers (1956) Snow Hydrology	*/
	/*	use a min/max to get range in which there is a mix of snow/rain */
	/*								*/
	/*--------------------------------------------------------------*/
	if (zone[0].snow == -999.0 ){
		if (zone[0].metv.tavg < zone[0].defaults[0][0].max_snow_temp ){
			if (zone[0].metv.tavg <= zone[0].defaults[0][0].min_rain_temp){
				zone[0].snow = zone[0].rain;
				zone[0].rain = 0.0;
			}
			else{
				snow_rain_range = zone[0].defaults[0][0].max_snow_temp
				- zone[0].defaults[0][0].min_rain_temp;
				if ( snow_rain_range < 0.001){
					zone[0].snow = zone[0].rain;
					zone[0].rain = 0.0;
				}
				else{
					zone[0].snow = min((zone[0].defaults[0][0].max_snow_temp
										- zone[0].metv.tavg) * zone[0].rain 
									    / snow_rain_range, zone[0].rain);
					zone[0].rain = zone[0].rain - zone[0].snow;
				}
			}
		}
		else{
			zone[0].snow = 0.0;
		}
	}
	zone[0].snow += zone[0].snow_hourly_total;
	/*--------------------------------------------------------------*/
	/*	If we have no rain duration data set it as		*/
	/*	daylength if rain 0 if not.					*/
	/*--------------------------------------------------------------*/

	if ( zone[0].daytime_rain_duration == -999.0 ){
		if ( zone[0].rain == 0 || (zone[0].snow != 0 ) ){
			zone[0].daytime_rain_duration = 0;
		}
		else{
			/* Old code */
			/* zone[0].daytime_rain_duration = zone[0].metv.dayl;*/
			/* Since this value is used for both infiltration (intensity) and 
			 radiation, we are now defining it as # of seconds of rain over
			 ENTIRE 24-hr period. If no value is given, we assume it rains
			 over the full day. */
			zone[0].daytime_rain_duration = 86400;
		}
	}
	else{
		if ( zone[0].rain == 0 && zone[0].rain_hourly_total == 0){
			zone[0].daytime_rain_duration = 0;
		}
		else{
			/* Old code */
			/*zone[0].daytime_rain_duration =
				min( zone[0].metv.dayl,zone[0].daytime_rain_duration);*/
			/* We adjust this value in the radiation routines to split
			 into daylight vs. nighttime rain hours, so here we leave
			 it as-is and just bound to 0:86400 sec. */
			zone[0].daytime_rain_duration =
				min( 86400, max(zone[0].daytime_rain_duration,0));
		}
	}
	
	/*---------------------------------------------------------------*/
	/* MOVED CLOUD FRACTION CALCS INTO ZONE DAILY I AND EARLIER IN	 */
	/* THIS ROUTINE SO CAN BE USED FOR K ADJUSTMENTS				 */
	/*---------------------------------------------------------------*/
	
	/*--------------------------------------------------------------*/
	/*	Deretmine if we need to adjust Kdowns or metv.tmax.			*/
	/*																*/
	/*	We assume that if either Kdown_diffuse or Kdown_direct		*/
	/*	was not supplied then themetv.tmax needs adjustment.		*/
	/*	This is because the adjustment should not be needed			*/
	/*		if we had good enough data to get Kdowns.				*/
	/*--------------------------------------------------------------*/
	if ( (zone[0].Kdown_direct_flag == 0) ||
		(zone[0].Kdown_diffuse_flag == 0) ){
		/*--------------------------------------------------------------*/
		/*	Adjust the computed Kdown's for cloud fraction if they		*/
		/*	were not read in directly.									*/
		/*	See simuilate_zone_daily_1 for the adjustment computation	*/
		/*--------------------------------------------------------------*/
		zone[0].Kdown_direct = zone[0].Kdown_direct
			* zone[0].Kdown_direct_adjustment;
		zone[0].Kdown_diffuse = zone[0].Kdown_diffuse
			* zone[0].Kdown_diffuse_adjustment;
		if (command_line[0].verbose_flag == -5) {
			printf("\nZONE DAILY F: Precip=%lf cloudfrac=%lf Kdir_adj=%lf Kdif_adj=%lf Tavg=%lf", 
				   zone[0].snow + zone[0].rain, 
				   zone[0].cloud_fraction, 
				   zone[0].Kdown_direct_adjustment/86.4,
				   zone[0].Kdown_diffuse_adjustment/86.4,
				   zone[0].metv.tavg);
		}
		/*--------------------------------------------------------------*/
		/*	radrat (unitless)											*/
		/*																*/
		/*	Equation 2a & 2b , Page 5, "MTCLIM" 						*/
		/*--------------------------------------------------------------*/
		if ( (zone[0].Kdown_direct_flat + zone[0].Kdown_diffuse_flat) != 0.0 ) {
			zone[0].radrat = (zone[0].Kdown_direct + zone[0].Kdown_diffuse) /
			(zone[0].Kdown_direct_flat + zone[0].Kdown_diffuse_flat);   
		}
		else zone[0].radrat = 1.0;
		/*zone[0].radrat = 1.0;*/
		/* EG edit: when radrat equals zero, tmax= -Inf and PSN=Nan */
		if ( zone[0].radrat == 0.0) {
			zone[0].radrat = 1.0;
		}
		
		/*------------------------------------------------------------------*/
		/* REMOVING TMAX CORRECTION SINCE EQUATION IS ALWAYS ADDING 1 DEG	*/
		/* EVEN ON FLAT SURFACES WITH SAME LAI AS BASE. EQN NEEDS EDITS		*/
		/* BEFORE RE-IMPLEMENTING.											*/
		/*--------------------------------------------------------------*/
		/*	LAI compensation (unitless)									*/
		/*																*/
		/*	Equation 2a & 2b , Page 5, "MTCLIM" 						*/
		/*	Modified so that the base station LAI is subtracted from the*/
		/*		zone lai.												*/
		/*--------------------------------------------------------------*/
		//zone[0].effective_lai = 0.0;
		//for ( patch=0 ; patch<zone[0].num_patches ; patch++ ){
		//	zone[0].effective_lai
		//		+= zone[0].patches[patch][0].effective_lai
		//		* zone[0].patches[patch][0].area;
		//}
		//zone[0].effective_lai = zone[0].effective_lai / zone[0].area;
		//if ( zone[0].radrat <  1.0 ){
		//	zone[0].LAI_temp_adjustment
		//		=-1 * ( 1/zone[0].radrat ) * ( 1 + (zone[0].effective_lai
		//		- zone[0].base_station_effective_lai )
		//		/ zone[0].defaults[0][0].max_effective_lai );
		//}
		//else {
		//	zone[0].LAI_temp_adjustment = ( zone[0].radrat )
		//		* ( 1 - (zone[0].effective_lai
		//		- zone[0].base_station_effective_lai )
		//		/ zone[0].defaults[0][0].max_effective_lai );
		//}  /*end if-else*/
		/*--------------------------------------------------------------*/
		/*metv.tmax adjusted ( degrees C)								*/
		/*--------------------------------------------------------------*/
		//zone[0].metv.tmax = zone[0].metv.tmax + zone[0].LAI_temp_adjustment;
		/*-----------------------------------------------------------------*/
		
	} /*end if*/
	
	/* EG edit: LAI temp adjustment was pushing tmax below tmin*/
	if (zone[0].metv.tmax < zone[0].metv.tmin) {
		zone[0].metv.tmax = zone[0].metv.tmin + 1.0;
	}
	/*--------------------------------------------------------------*/
	/*	If no PAR or only diffuse PAR is given get the other PAR's	*/
	/*	We assume the ratio of diffuse to direct PAR is a closed 	*/
	/*		form equation of the ratio of diffuse to direct Kdown.	*/
	/*--------------------------------------------------------------*/
	if ( (zone[0].PAR_direct == -999.0 ) && ( zone[0].PAR_diffuse == -999.0) ){
		zone[0].PAR_direct = 1000.0 * zone[0].Kdown_direct * RAD2PAR * EPAR;
		zone[0].PAR_diffuse = 1000.0 *  zone[0].Kdown_diffuse * RAD2PAR * EPAR;
	}
	else if ( zone[0].PAR_direct == -999.0 ){
		zone[0].PAR_direct = zone[0].PAR_diffuse * (zone[0].Kdown_direct
			/ zone[0].Kdown_diffuse );
	}
	else if ( zone[0].PAR_diffuse == -999.0 ){
		zone[0].PAR_diffuse = zone[0].PAR_direct * (zone[0].Kdown_diffuse
			/ zone[0].Kdown_direct );
	}

	
	/*-------------------------------------------------------------------*/
	/* LDOWN MODEL REPLACED WITH NEW ONE CALCULATED AFTER VAPOR PRESSURE */
	/*-------------------------------------------------------------------*/
	
	/*--------------------------------------------------------------*/
	/*	Saturation Vapour Pressure	(Pa)							*/
	/*																*/
	/*	Note the original rehssys code supplied es in mbar.			*/
	/*	c.f. eq. 1 Running and Coughlan , 1987, p. 133.				*/
	/*																*/
	/*	Since 1 bar = 100 kpa (approx) ; a millibar = 100 Pa approx.*/
	/*	This explains why the es from the original code was:		*/
	/*																*/
	/*	6.1078 * exp((17.269*z[0].metv.tday)/(237.3 +			*/
	/*									z[0].metv.tday))		*/
	/*																*/
	/*	Which is approx 100 times that of the es here.				*/
	/*																*/
	/*	Eq. 5.12 p. 110, Jones, "Plants and Microclimate"			*/
	/*--------------------------------------------------------------*/
	if (  zone[0].metv.vpd == -999.0  ){
		es = 613.75 * exp( (17.502 * zone[0].metv.tavg)
			/ ( 240.97 + zone[0].metv.tavg) );
		/*--------------------------------------------------------------*/
		/*	Make use of relative humidity if available.					*/
		/*--------------------------------------------------------------*/
		if ( zone[0].relative_humidity == -999.0 ){
			/*--------------------------------------------------------------*/
			/*	Dew Point Vapour Pressure (Pa)								*/
			/*																*/
			/*	Note the original rehssys code supplied es in mbar.			*/
			/*	c.f. eq. 1 Running and Coughlan , 1987, p. 133.				*/
			/*																*/
			/*	Since 1 bar = 100 kpa (approx) ; a millibar = 100 Pa approx.*/
			/*	This explains why the es from the original code was:		*/
			/*																*/
			/*	6.1078 * exp((17.269*z[0].tdewpoint)/(237.3 +			*/
			/*									z[0].tdewpoint))		*/
			/*																*/
			/*	Which is approx 100 times that of the es here.				*/
			/*																*/
			/*	Eq. 5.12 p. 110, Jones, "Plants and Microclimate"			*/
			/*	Assuming that tdewpoint is valid for the whole day.		*/
			/*								*/
			/*	We cannot make a correction for rain_duration here.	*/
			/*	Instead we hope that  the dewpoint vapour pressure is	*/
			/*	measured by a temperature value (night min)		*/
			/*--------------------------------------------------------------*/
			zone[0].e_dewpoint = 613.750 * exp( (17.502
				* zone[0].tdewpoint) / ( 240.97 + zone[0].tdewpoint));
		}
		else{
			/*--------------------------------------------------------------*/
			/*      Dew Point Vapour Pressure (Pa)                          */
			/*                                                              */
			/*      ONly for dayligh conditions with no rain.               */
			/*      Eq. 5.13 and 5.14 , p. 110, Jones, "Plants and Microclimate"*/
			/*--------------------------------------------------------------*/
			zone[0].e_dewpoint =  zone[0].relative_humidity * es;
		} /*end if-else*/
		/*--------------------------------------------------------------*/
		/*	metv.vpd	(Pa)						*/
		/*								*/
		/*	Eq. 5.14, p. 110, Jones, "Plants and Microclimate"	*/
		/*	Limited to at least 0.0 as per rhessys C code.		*/
		/*--------------------------------------------------------------*/

		zone[0].metv.vpd = max(es - zone[0].e_dewpoint,0.0);
		if (zone[0].relative_humidity == -999.0) {
			if (es > ZERO)
				zone[0].relative_humidity = zone[0].e_dewpoint / es;
			else
				zone[0].relative_humidity = -999.0;
			}
	}
	/* Case where vpd is given. Still need to calculate e_dewpoint	*/
	/* for snowpack sublim and RH for output.						*/
	else {
		es = 613.75 * exp( (17.502 * zone[0].metv.tavg)
						  / ( 240.97 + zone[0].metv.tavg) );
		zone[0].e_dewpoint = es - zone[0].metv.vpd;
		zone[0].relative_humidity = zone[0].e_dewpoint / es;
	}
	
	/*--------------------------------------------------------------*/
	/* NEW ATMOSPHERIC LONGWAVE MODEL								*/
	/* Clear sky emissivity from Satterlund 1979 as applied in		*/
	/* Mahat & Tarboten 2012 UEB with cloud fraction correction.	*/
	/* After testing, best results from Diley-Crawford model but	*/
	/* leaving others in as comments in case someone else wants		*/
	/* to experiment.												*/
	/*--------------------------------------------------------------*/
	if ( zone[0].Ldown == -999.0){
		/* Satterlund-Crawford */
		/*zone[0].Ldown = (zone[0].cloud_fraction 
			+ (1.0 - zone[0].cloud_fraction) * 1.08 * (1.0 - exp(-pow(zone[0].e_dewpoint/100,(zone[0].metv.tavg+273.16)/2016)))) 
			* (SBC * 86400/1000) * pow(zone[0].metv.tavg+273.16,4);*/
		
		/* Diley-Crawford */
		zone[0].Ldown = zone[0].cloud_fraction * (SBC * 86400/1000) * pow(zone[0].metv.tavg+273.16,4)
				+ (1.0 - zone[0].cloud_fraction) * ( 59.38 + 113.7*pow((zone[0].metv.tavg+273.16)/273.16,6)
				+ 96.96 * pow(4650*(zone[0].e_dewpoint/1000)/(zone[0].metv.tavg+273.16)/25,0.5)) * 86400/1000;
		
		/* split by day/night (not sensitive) */
		/*zone[0].Ldown = ( zone[0].cloud_fraction * (SBC * (seconds_per_day-zone[0].metv.dayl)/1000) * pow(zone[0].metv.tnight+273,4)
						    + (1.0 - zone[0].cloud_fraction) * ( 59.38 + 113.7*pow((zone[0].metv.tnight+273)/273.16,6)
						    + 96.96 * pow(4650*(zone[0].e_dewpoint/1000)/(zone[0].metv.tnight+273)/25,0.5)) * (seconds_per_day-zone[0].metv.dayl)/1000 )
					+ ( zone[0].cloud_fraction * (SBC * zone[0].metv.dayl/1000) * pow(zone[0].metv.tday+273,4)
					        + (1.0 - zone[0].cloud_fraction) * ( 59.38 + 113.7*pow((zone[0].metv.tday+273)/273.16,6)
							+ 96.96 * pow(4650*(zone[0].e_dewpoint/1000)/(zone[0].metv.tday+273)/25,0.5)) * zone[0].metv.dayl/1000 );*/
		
		/* Diley with Kimball cloud correction per Flerchinger 2009 */
		/*if ( (current_date.month>=5) && (current_date.month<=10) )
			Tcloud = (zone[0].metv.tavg+273.16) - 9; /* summer adjustment for cloud temp */
		/*else 
			Tcloud = (zone[0].metv.tavg+273.16) - 13; /* winter adjustment for cloud temp */
		/*f8 = -0.6732 + (0.006240*Tcloud) - (0.9140*pow(10,-5)*pow(Tcloud,2));
		e8z = 0.24 + (2.98*pow(10,-6) * pow(zone[0].e_dewpoint/1000,2) * exp(3000.0/(zone[0].metv.tavg+273.16)));
		tau8 = 1.0 - e8z*(1.4-0.4*e8z);
		zone[0].Ldown = zone[0].cloud_fraction * f8 * tau8 * (SBC * 86400/1000) * pow(Tcloud,4)
				+ (1.0 - zone[0].cloud_fraction) * ( 59.38 + 113.7*pow((zone[0].metv.tavg+273.16)/273.16,6)
				+ 96.96 * pow(4650*(zone[0].e_dewpoint/1000)/(zone[0].metv.tavg+273.16)/25,0.5)) * 86400/1000;*/
	} /*end if*/
	/*--------------------------------------------------------------*/
	
	/*--------------------------------------------------------------*/
	/*	Nitrogen Deposition					*/
	/*	- if not availabe use default value			*/
	/*--------------------------------------------------------------*/
	if (zone[0].ndep_NO3 == -999.0){
		zone[0].ndep_NO3 = zone[0].defaults[0][0].ndep_NO3;
	}
	/*--------------------------------------------------------------*/
	/*	metv.tsoil - soil temperature 		(degrees C)	*/
	/*								*/
	/*	We always update a running average for metv.tsoil in		*/
	/*	case we get a missing value.						*/
	/*--------------------------------------------------------------*/
	if ( zone[0].metv.tsoil == -999.0 ){
		zone[0].metv.tsoil_sum = 0.9 * zone[0].metv.tsoil_sum +
			0.1 *	zone[0].metv.tavg;
		zone[0].metv.tsoil = zone[0].metv.tsoil_sum;
	}
	else{
		zone[0].metv.tsoil_sum = zone[0].metv.tsoil;
	}
	/*--------------------------------------------------------------*/
	/* 	set LAI scalar to 1.0 is missing 			*/
	/*--------------------------------------------------------------*/
	if ( zone[0].LAI_scalar == -999.0 ){
		zone[0].LAI_scalar = 1.0;
	}
	/*--------------------------------------------------------------*/
	/*	Atmospheric CO2 concentration (ppm)			*/
	/*--------------------------------------------------------------*/
	if ( zone[0].CO2 == -999.0 ){
		zone[0].CO2 = zone[0].defaults[0][0].atm_CO2;
	}
	/*--------------------------------------------------------------*/
	/*	Fill in the bbgc metv structure for missing variables	*/
	/*--------------------------------------------------------------*/
	/*--------------------------------------------------------------*/
	/*	compute total precip 			kg/m2		*/
	/*								*/
	/*	assumes density snow = debsity rain			*/
	/*	kg/m2 = (m / m2) *( 1000kg/m3)								*/
	/*--------------------------------------------------------------*/
	zone[0].metv.prcp = (zone[0].rain + zone[0].snow)*1000.0;
	/*--------------------------------------------------------------*/
	/*	compute total shortwave flux		(W/m2)		*/
	/*	W/m2 = Kj/(m2*day) * ( 1 day / dayl s ) * 1000 j / 1kj  */
	/*--------------------------------------------------------------*/
	zone[0].metv.swavgfd = (zone[0].Kdown_direct + zone[0].Kdown_diffuse)
		/ zone[0].metv.dayl * 1000.0  ;
	/*--------------------------------------------------------------*/
	/*	compute total ppfd		umol photon/m2*s	*/
	/*	umol photon/m2*s = u mol photon/m2*day * (1 day/dayl s)	*/
	/*--------------------------------------------------------------*/
	zone[0].metv.ppfd = (zone[0].PAR_direct + zone[0].PAR_diffuse)
		/ zone[0].metv.dayl ;
	if ( command_line[0].verbose_flag > 1 )
		printf("\n%8d -222.1 ",julday(current_date)-2449000);
	if ( command_line[0].verbose_flag > 0  )
		printf("%8.4f %8.4f %8.4f %8.4f %8.4f %8.4f %8.4f %8.4f ",
		zone[0].metv.dayl,
		zone[0].metv.tmax,
		zone[0].metv.tmin,
		zone[0].metv.tavg,
		zone[0].metv.tnight,
		zone[0].metv.tday,
		zone[0].metv.tsoil,
		zone[0].tdewpoint);
	if ( command_line[0].verbose_flag > 1 )
		printf("\n%8d -222.2 ",julday(current_date)-2449000);
	if ( command_line[0].verbose_flag > 0 )
		printf("%8.4f %8.4f %8.2f ",
		zone[0].rain,
		zone[0].snow,
		zone[0].metv.vpd);
	if ( command_line[0].verbose_flag > 1 )
		printf("%8.1f %8.1f %8.0f %8.0f %8.1f ",
		zone[0].Kdown_direct,
		zone[0].Kdown_diffuse,
		zone[0].PAR_direct,
		zone[0].PAR_diffuse,
		zone[0].Ldown);
	/*--------------------------------------------------------------*/
	/*      update met running averages variables                            */
	/*--------------------------------------------------------------*/

	zone[0].metv.tmin_ravg = 1.0/(zone[0].defaults[0][0].ravg_days)*zone[0].metv.tmin 
			+ (zone[0].defaults[0][0].ravg_days-1.0)/(zone[0].defaults[0][0].ravg_days)*zone[0].metv.tmin_ravg;
	zone[0].metv.vpd_ravg = 1.0/(zone[0].defaults[0][0].ravg_days)*zone[0].metv.vpd 
			+ (zone[0].defaults[0][0].ravg_days-1.0)/(zone[0].defaults[0][0].ravg_days)*zone[0].metv.vpd_ravg;
	zone[0].metv.dayl_ravg = 1.0/(zone[0].defaults[0][0].ravg_days)*zone[0].metv.dayl 
			+ (zone[0].defaults[0][0].ravg_days-1.0)/(zone[0].defaults[0][0].ravg_days)*zone[0].metv.dayl_ravg;

	
	if (command_line[0].verbose_flag == -5) {
		printf(" Kdowndir=%lf Kdowndiff=%lf Ldown=%lf", 
			   zone[0].Kdown_direct/86.4,
			   zone[0].Kdown_diffuse/86.4,
			   zone[0].Ldown/86.4);
	}
	
	/*--------------------------------------------------------------*/
	/*	Cycle through the patches for day end computations		    	*/
	/*--------------------------------------------------------------*/
	for ( patch=0 ; patch<zone[0].num_patches; patch++ ){
		patch_daily_F(
			world,
			basin,
			hillslope,
			zone,
			zone[0].patches[patch],
			command_line,
			event,
			current_date );

	  if(command_line[0].vegspinup_flag > 0){
      if (zone[0].patches[patch]->target_status == 0){
        world[0].target_status = 0;
      }
    }
	}

	/*--------------------------------------------------------------*/
	/*      update accumulator variables                            */
	/*--------------------------------------------------------------*/
	if ((command_line[0].output_flags.monthly == 1) &&
		(command_line[0].z != NULL) ){
		zone[0].acc_month.precip += zone[0].rain + zone[0].snow;
		zone[0].acc_month.tmin += zone[0].metv.tmin;
		zone[0].acc_month.tmax += zone[0].metv.tmax;
		zone[0].acc_month.K_direct += zone[0].Kdown_direct;
		zone[0].acc_month.K_diffuse += zone[0].Kdown_diffuse;
		zone[0].acc_month.length += 1;
	}

	return;
} /*end zone_daily_F.c*/