예제 #1
0
void		surface_daily_F(
							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 declaration				*/
	/*--------------------------------------------------------------*/
	
	double	compute_diffuse_radiative_fluxes(
		int,
		double *,
		double,
		double,
		double,
		double,
		double,
		double);


	
	double	compute_direct_radiative_fluxes(
		int,
		double *,
		double,
		double,
		double,
		double,
		double,
		double);
	
	
	double	compute_direct_radiative_PAR_fluxes(
		int,
		double *,
		double,
		double,
		double,
		double,
		double,
		double,
		double,
		double);

	
	double	compute_nonvascular_stratum_conductance(
		int	,
		double	,
		double	,
		double	,
		double	,
		double	);

	double	compute_litter_rain_stored(
		int,
		struct	patch_object *);
	
	double	penman_monteith(
		int,
		double,
		double,
		double,
		double,
		double,
		double,
		int);


	double  compute_subsurface_temperature_profile(
		struct	surface_energy_object *,
		struct surface_energy_default *,
		double,
		double,
		double *);
	
	/*--------------------------------------------------------------*/
	/*  Local variable definition.                                  */
	/*--------------------------------------------------------------*/
	double  detention_store_evaporation;
	double  detention_store_potential_evaporation;
	double  detention_store_potential_dry_evaporation_rate;
	double  detention_store_potential_rainy_evaporation_rate;
	double  albedo;
	double	dry_evaporation;
	double	Kstar_direct;
	double	Kstar_diffuse;
	double	APAR_diffuse;
	double	APAR_direct;
	double	potential_evaporation_rate;
	double	potential_rainy_evaporation_rate;
	double	rainy_evaporation;
	double	rnet_evap, rnet_evap_pond, rnet_evap_litter, rnet_evap_soil;
	double  rnet;
	double	PE_rate, PE_rainy_rate;
	double	soil_potential_evaporation;
	double	soil_potential_dry_evaporation_rate;
	double	soil_potential_rainy_evaporation_rate;
	double	exfiltration;
	double	K_used;
	double	K_initial;
	double	hv;			/* latent heat of vaporization for water (KJ/kg) */
	double	water_density;		/* density of water in kg/m^3 */
	double 	fraction_direct_K;
	double	fraction_diffuse_K;
	double	fraction_Lstar_soil;
	double	fraction_surface_heat_flux;
	struct	litter_object	*litter;
	
	
	/*--------------------------------------------------------------*/
	/*	Initialize litter variables.				*/
	/*--------------------------------------------------------------*/
	Kstar_diffuse = 0.0;
	APAR_diffuse = 0.0;
	Kstar_direct = 0.0;
	APAR_direct = 0.0;
	exfiltration = 0;
	rainy_evaporation = 0;
	dry_evaporation = 0;
	rnet = 0.0;
	
	litter = &(patch[0].litter);
	hv = 2.495 * 1e3;	/* latent heat of vaporization for water (KJ/kg) */
	water_density = 1000;	/* density of water in kg/m^3 */

	/*--------------------------------------------------------------*/
	/*	DETENTION STORE EVAPORATION:								*/
	/*	Check to see if detention store is greater than current		*/
	/*	litter holding capacity.  If so, run water surface evap		*/
	/*	first.														*/
	/* but only do this if there is actually a detention_store capacity to hold water */
	/*--------------------------------------------------------------*/
	
    	if ( (patch[0].detention_store > (max(litter[0].rain_capacity - litter[0].rain_stored, 0.0)))
                                        && (patch[0].soil_defaults[0][0].detention_store_size > 0.0)) {
	
			/*** Calculate available energy at surface. Assumes Kdowns are partially ***/
			/*** reflected by water surface based on water albedo. ***/
		
			if (zone[0].metv.dayl > ZERO) {
				rnet_evap_pond = 1000 * ( (1-WATER_ALBEDO) * (patch[0].Kdown_direct + patch[0].Kdown_diffuse) - 
						patch[0].Lstar_soil + patch[0].surface_heat_flux) / zone[0].metv.dayl;
				if (rnet_evap_pond <= ZERO) {
					rnet_evap_pond = 0.0;
				}
			}
			else rnet_evap_pond = 0.0;
	
			/*** Use Penman with rsurface=0 for open water evaporation. ***/
	
			patch[0].ga = max((patch[0].ga * patch[0].stability_correction),0.0001);
		
			detention_store_potential_dry_evaporation_rate = penman_monteith(
				command_line[0].verbose_flag,
				zone[0].metv.tday,
				zone[0].metv.pa,
				zone[0].metv.vpd,
				rnet_evap_pond,
				0.0,
				1/(patch[0].ga),
				2) ;
			detention_store_potential_rainy_evaporation_rate = penman_monteith(
				command_line[0].verbose_flag,
				zone[0].metv.tday,
				zone[0].metv.pa,
				10,
				rnet_evap_pond,
				0.0,
				1/(patch[0].ga),
				2) ;
	
			detention_store_potential_evaporation  = detention_store_potential_dry_evaporation_rate
					* (zone[0].metv.dayl - zone[0].daytime_rain_duration )
					+ detention_store_potential_rainy_evaporation_rate
					* zone[0].daytime_rain_duration;

			// Avoid over-estimating ET from surfaces with no detention store size 
			//   (e.g. impervious surface) by gating ET by detention_store_size
			detention_store_evaporation = min(detention_store_potential_evaporation,
							  min(patch[0].detention_store, 
							      patch[0].soil_defaults[0][0].detention_store_size) );
	
	}
	
	else detention_store_evaporation = 0.0;
	
	patch[0].detention_store -= detention_store_evaporation;
	
	/*** If snowpack is over detention store, then add evaporated water to snowpack. ***/
	
	if (patch[0].snowpack.water_equivalent_depth > ZERO) {
		patch[0].snowpack.water_equivalent_depth += detention_store_evaporation;
		detention_store_evaporation = 0.0;
	}
	
	patch[0].evaporation_surf += detention_store_evaporation;
	
	
	/*** Update patch radiation to remove any radiation used to evaporate pond. ***/
	/*** Assume same proportions as original 4 energy sources. ***/
	
	K_used =  detention_store_evaporation * hv * water_density;
	K_initial = (1-WATER_ALBEDO) * (patch[0].Kdown_direct + patch[0].Kdown_diffuse)
					- patch[0].Lstar_soil + patch[0].surface_heat_flux;
	if ( K_used > 0 ){
		if ( K_initial > 0 ){
			fraction_direct_K = (1-WATER_ALBEDO) * patch[0].Kdown_direct / K_initial;
			fraction_diffuse_K = (1-WATER_ALBEDO) * patch[0].Kdown_diffuse / K_initial;
			fraction_Lstar_soil = patch[0].Lstar_soil / K_initial;
			fraction_surface_heat_flux = patch[0].surface_heat_flux / K_initial;
		}
		else {
			fraction_direct_K = 0.0;
			fraction_diffuse_K = 0.0;
			fraction_Lstar_soil = 0.0;
			fraction_surface_heat_flux = 0.0;
		}
		patch[0].Kdown_direct = ((1-WATER_ALBEDO) * patch[0].Kdown_direct) - (fraction_direct_K * K_used);
		patch[0].Kdown_diffuse = ((1-WATER_ALBEDO) * patch[0].Kdown_diffuse) - (fraction_diffuse_K * K_used);
		patch[0].Lstar_soil = patch[0].Lstar_soil - (fraction_Lstar_soil * K_used);
		patch[0].surface_heat_flux = patch[0].surface_heat_flux - (fraction_surface_heat_flux * K_used);
	}
	
	
	/*--------------------------------------------------------------*/
	/*	LITTER STORE EVAPORATION:									*/
	/*	Now move to litter and then bare soil evaporation if the 	*/
	/*	remaining surface water can be held by the litter.			*/
	/*--------------------------------------------------------------*/
	
	if ( patch[0].detention_store <= (litter[0].rain_capacity - litter[0].rain_stored) ) {
		
		/*--------------------------------------------------------------*/
		/*	calculate surface albedo as a function of amount of	*/
		/*		litter vs soil					*/
		/*--------------------------------------------------------------*/
		if (litter->proj_pai >= 1.0)
			albedo = LITTER_ALBEDO;
		else {
			albedo = LITTER_ALBEDO * litter->proj_pai
				+ patch[0].soil_defaults[0][0].albedo * (1-litter->proj_pai);
		}

		/*--------------------------------------------------------------*/
		/*  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.                                                  */
		/*--------------------------------------------------------------*/
		Kstar_diffuse = compute_diffuse_radiative_fluxes(
			command_line[0].verbose_flag,
			&(patch[0].Kdown_diffuse),
			patch[0].Kdown_direct,
			-10000.0,
			0.0,
			1.0,
			basin[0].theta_noon,
			albedo);
	
		APAR_diffuse = compute_diffuse_radiative_fluxes(
			command_line[0].verbose_flag,
			&(patch[0].PAR_diffuse),
			patch[0].PAR_direct,
			-10000.0,
			0.0,
			1.0,
			basin[0].theta_noon,
			albedo);
		/*--------------------------------------------------------------*/
		/*  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.                                                  */
		/*--------------------------------------------------------------*/
		Kstar_direct = compute_direct_radiative_fluxes(
			command_line[0].verbose_flag,
			&(patch[0].Kdown_direct),
			-10000,
			0.0,
			1.0,
			basin[0].theta_noon,
			albedo,
			albedo);
		APAR_direct = compute_direct_radiative_fluxes(
			command_line[0].verbose_flag,
			&(patch[0].PAR_direct),
			-10000,
			0.0,
			1.0,
			basin[0].theta_noon,
			albedo,
			albedo);
									
		/*--------------------------------------------------------------*/
		/*	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.					*/
		/*--------------------------------------------------------------*/
		litter[0].gsurf = compute_nonvascular_stratum_conductance(
				command_line[0].verbose_flag,
				litter[0].rain_stored + patch[0].detention_store,
				litter[0].rain_capacity,
				litter[0].gl_c,	
				litter[0].gsurf_slope,
				litter[0].gsurf_intercept);
		
		if (patch[0].rootzone.depth > ZERO) {
			patch[0].gsurf = compute_nonvascular_stratum_conductance(
				command_line[0].verbose_flag,
				patch[0].rz_storage + patch[0].detention_store,
				patch[0].sat_deficit,
				patch[0].soil_defaults[0][0].gl_c,	
				patch[0].soil_defaults[0][0].gsurf_slope,
				patch[0].soil_defaults[0][0].gsurf_intercept);
		}

		else {
			patch[0].gsurf = compute_nonvascular_stratum_conductance(
				command_line[0].verbose_flag,
				patch[0].unsat_storage + patch[0].detention_store,
				patch[0].sat_deficit,
				patch[0].soil_defaults[0][0].gl_c,	
				patch[0].soil_defaults[0][0].gsurf_slope,
				patch[0].soil_defaults[0][0].gsurf_intercept);
		}
		/*--------------------------------------------------------------*/
		/*	COmpute evaporation and exfiltration 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 * (Kstar_direct + Kstar_diffuse - patch[0].Lstar_soil
			+ patch[0].surface_heat_flux) / zone[0].metv.dayl;
			if (rnet_evap <= ZERO) {
					rnet_evap_pond = 0.0;
			}
		}

		else rnet_evap = 0.0;

		rnet_evap_litter = min(litter->proj_pai,1)*rnet_evap;
		rnet_evap_soil = max(0.0, rnet_evap-rnet_evap_litter);

		if (rnet_evap < 0.0) rnet_evap = 0.0;
		/*--------------------------------------------------------------*/
		/*	Make sure ga and gsurf are non-zero.			*/
		/*--------------------------------------------------------------*/
		patch[0].ga = max((patch[0].ga * patch[0].stability_correction),0.0001);
		/*--------------------------------------------------------------*/
		/*	Estimate potential evap rates.				*/
		/*--------------------------------------------------------------*/
			
		potential_evaporation_rate = penman_monteith(
			command_line[0].verbose_flag,
			zone[0].metv.tday,
			zone[0].metv.pa,
			zone[0].metv.vpd,
			rnet_evap_litter,
			1/patch[0].litter.gsurf,
			1/(patch[0].ga),
			2) ;
		potential_rainy_evaporation_rate = penman_monteith(
			command_line[0].verbose_flag,
			zone[0].metv.tday,
			zone[0].metv.pa,
			10,
			rnet_evap_litter,
			1/patch[0].litter.gsurf,
			1/(patch[0].ga),
			2) ;
		PE_rate = penman_monteith(
			command_line[0].verbose_flag,
			zone[0].metv.tday,
			zone[0].metv.pa,
			zone[0].metv.vpd,
			rnet_evap_litter,
			0.0,
			1/(patch[0].ga),
			2) ;
		PE_rainy_rate = penman_monteith(
			command_line[0].verbose_flag,
			zone[0].metv.tday,
			zone[0].metv.pa,
			10,
			rnet_evap_litter,
			0.0,
			1/(patch[0].ga),
			2) ;
		
		PE_rainy_rate = max(0, PE_rainy_rate);
		PE_rate = max(0, PE_rate);

		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);
		}
		/*--------------------------------------------------------------*/
		/*	Compute potential evaporation of litter. 		*/
		/*	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	*/
		/*--------------------------------------------------------------*/
		patch[0].potential_evaporation  = potential_evaporation_rate
			* (zone[0].metv.dayl - zone[0].daytime_rain_duration )
			+ potential_rainy_evaporation_rate * zone[0].daytime_rain_duration;
		patch[0].PE  = PE_rate 
			* (zone[0].metv.dayl - zone[0].daytime_rain_duration )
			+ PE_rainy_rate * zone[0].daytime_rain_duration;

		/*--------------------------------------------------------------*/
		/*	Update rain storage ( this also updates the patch level	*/
		/*	detention store and potential_evaporation	*/
		/*--------------------------------------------------------------*/
		litter[0].rain_stored  = compute_litter_rain_stored(
			command_line[0].verbose_flag,
			patch);
		/*--------------------------------------------------------------*/
		/*	if litter is empty then we have bare soil		*/
		/*								*/
		/*	We assume that the exfiltration rate is limited to 	*/
		/*	the minimum of the potential evap rate for the 		*/
		/*	soil and the max exfiltration rate.			*/
		/*	The potential evap rate is estimated using P-M with 	*/
		/*	the same aero cond as the litter but with a 		*/
		/*	surface cond estimated based on vapour conductance in 	*/
		/*	soil column.						*/
		/*								*/
		/*	The surface heat flux of the soil column is estimated	*/
		/*	aasuming no litter covering the surface (0 m height).	*/
		/*--------------------------------------------------------------*/
		
			soil_potential_rainy_evaporation_rate = penman_monteith(
				command_line[0].verbose_flag,
				zone[0].metv.tday,
				zone[0].metv.pa,
				10.0,
				rnet_evap_soil,
				1.0/patch[0].gsurf,
				1.0/patch[0].ga,
				2);
			soil_potential_dry_evaporation_rate = penman_monteith(
				command_line[0].verbose_flag,
				zone[0].metv.tday,
				zone[0].metv.pa,
				zone[0].metv.vpd,
				rnet_evap_soil,
				1.0/patch[0].gsurf,
				1.0/patch[0].ga,
				2);
			soil_potential_evaporation  = soil_potential_dry_evaporation_rate
				* (zone[0].metv.dayl - zone[0].daytime_rain_duration )
				+ soil_potential_rainy_evaporation_rate
				* zone[0].daytime_rain_duration;

			/*--------------------------------------------------------------*/
			/*	BARE SOIL EVAPORATION:									*/
			/*	base soil evapotration/ exfiltration will only occur 	*/
			/*	on exposed soil layers					*/
			/*--------------------------------------------------------------*/
			exfiltration =	min(soil_potential_evaporation,
				patch[0].potential_exfiltration);
		
			
		if ( patch[0].sat_deficit_z > 0 ){
			patch[0].exfiltration_unsat_zone = exfiltration;
			patch[0].exfiltration_sat_zone = 0;
		}
		else{
			patch[0].exfiltration_unsat_zone = 0;
			patch[0].exfiltration_sat_zone = exfiltration;
		}
		
	}

	/*--------------------------------------------------------------*/
	/* if we want to solve surface temperature profile, determine 	*/
	/* moistures and depths to send to solver			*/
	/*	then call solver compute_subsurface_temperature_profile */
	/* will also determine % of soil water that is frozen		*/
	/* note that depth for layer 3 is always the soil depth so 	*/
	/* this is set only once in construct_patch			*/
	/*--------------------------------------------------------------*/
	
	if (command_line[0].surface_energy_flag == 1) {
		patch[0].surface_energy_profile[0].depth = patch[0].litter.depth;
		patch[0].surface_energy_profile[0].moisture = patch[0].litter.rain_stored;

	if (patch[0].sat_deficit > patch[0].rootzone.potential_sat) {
		patch[0].surface_energy_profile[1].depth = 
			patch[0].surface_energy_profile[0].depth + patch[0].rootzone.depth;
		patch[0].surface_energy_profile[1].moisture = patch[0].rz_storage;
		patch[0].surface_energy_profile[2].depth = 
			patch[0].surface_energy_profile[0].depth + patch[0].sat_deficit_z;
		patch[0].surface_energy_profile[2].moisture = patch[0].unsat_storage;
		patch[0].surface_energy_profile[3].moisture = patch[0].soil_defaults[0][0].soil_water_cap - patch[0].sat_deficit;	
		}
	else {
		patch[0].surface_energy_profile[1].depth = 
			patch[0].surface_energy_profile[0].depth + patch[0].sat_deficit_z;
		patch[0].surface_energy_profile[1].moisture = patch[0].rz_storage;
		
		patch[0].surface_energy_profile[2].depth = 
			patch[0].surface_energy_profile[0].depth + patch[0].rootzone.depth;
		patch[0].surface_energy_profile[2].moisture = patch[0].rootzone.potential_sat - patch[0].sat_deficit;
		patch[0].surface_energy_profile[3].moisture = patch[0].soil_defaults[0][0].soil_water_cap - patch[0].rootzone.potential_sat;	
		}

	compute_subsurface_temperature_profile(
				patch[0].surface_energy_profile,
				patch[0].surface_energy_defaults[0],
				zone[0].metv.tavg,
				rnet,
				&(patch[0].percent_soil_water_unfrozen));

	/*--------------------------------------------------------------*/
	/* map iterative temperatures back to soil and litter, for now  */
	/* we don't differentiate between unsat, rootzone and sat for temperature */
	/*--------------------------------------------------------------*/

	patch[0].litter.T = patch[0].surface_energy_profile[0].T;
	if (patch[0].sat_deficit > patch[0].rootzone.potential_sat) 
		patch[0].rootzone.T = patch[0].surface_energy_profile[1].T;
	else
		patch[0].rootzone.T = (patch[0].surface_energy_profile[1].T * (patch[0].sat_deficit) + 
					patch[0].surface_energy_profile[2].T * (patch[0].rootzone.potential_sat - patch[0].sat_deficit)) 
					/ (patch[0].rootzone.potential_sat);

	patch[0].Tsoil = (patch[0].surface_energy_profile[1].T * 
			(patch[0].surface_energy_profile[1].depth - patch[0].surface_energy_profile[0].depth) +
			patch[0].surface_energy_profile[2].T *
			(patch[0].surface_energy_profile[2].depth - patch[0].surface_energy_profile[1].depth) +
			patch[0].surface_energy_profile[3].T *
			(patch[0].surface_energy_profile[3].depth - patch[0].surface_energy_profile[2].depth)) /
			patch[0].surface_energy_profile[3].depth;
		
	}
	
	return;
}/*end surface_daily_F.c*/
예제 #2
0
void penman_canopy_wrapper(params *p, state *s, double press, double vpd,
                           double tair, double wind, double rnet, double ca,
                           double gpp, double *ga, double *gsv,
                           double *transpiration, double *LE, double *omega) {
    /*
        Calculates transpiration at the canopy scale (or big leaf) using the
        Penman-Monteith

        Parameters:
        ----------
        parms : structure
            parameters
        state : structure
            state variables
        press : float
            atmospheric pressure (Pa)
        vpd : float
            vapour pressure deficit of air (Pa)
        tair : float
            air temperature (deg C)
        wind : float
            wind speed (m s-1)
        rnet : float
            net radiation (J m-2 s-1)
        ca : float
            ambient CO2 concentration (umol mol-1)
        gpp : float
            gross primary productivity (umol m-2 s-1)
        ga : float
            canopy scale boundary layer conductance (mol m-2 s-1; returned)
        gsv : float
            stomatal conductance to H20 (mol m-2 s-1; returned)
        transpiration : float
            transpiration (mol H2O m-2 s-1; returned)
        LE : float
            latent heat flux (W m-2; returned)


    */
    double gb, gv, gsc, epsilon, arg1, arg2, slope, gamma, lambda;

    /* stomtal conductance to CO2 */
    gsc = calc_stomatal_conductance(p, s, vpd, ca, gpp);

    /* stomtal conductance to H2O */
    *gsv = GSVGSC * gsc;

    *ga = canopy_boundary_layer_conduct(p, s->canht, wind, press, tair);

    /* Total leaf conductance to water vapour */
    gv = 1.0 / (1.0 / *gsv + 1.0 / *ga);

    lambda = calc_latent_heat_of_vapourisation(tair);
    gamma = calc_pyschrometric_constant(press, lambda);
    slope = calc_slope_of_sat_vapour_pressure_curve(tair);

    penman_monteith(press, vpd, rnet, slope, lambda, gamma, ga, &gv,
                    transpiration, LE);

    /* Calculate decoupling coefficient (McNaughton and Jarvis 1986) */
    epsilon = slope / gamma;
    *omega = (1.0 + epsilon) / (1.0 + epsilon + *ga / *gsv);

    return;
}
예제 #3
0
void penman_leaf_wrapper(met *m, params *p, state *s, double tleaf, double rnet,
                         double gsc, double *transpiration, double *LE,
                         double *gbc, double *gh, double *gv, double *omega) {
    /*
        Calculates transpiration by leaves using the Penman-Monteith

        Parameters:
        ----------
        press : float
            atmospheric pressure (Pa)
        rnet : float
            net radiation (J m-2 s-1)
        vpd : float
            vapour pressure deficit of air (Pa)
        tair : float
            air temperature (deg C)
        transpiration : float
            transpiration (mol H2O m-2 s-1) (returned)
        LE : float
            latent heat flux, W m-2 (returned)


    */
    double slope, epsilon, lambda, arg1, arg2, gradn, gbhu, gbhf, gbh,
           gbv, gsv, gamma, Tdiff, sensible_heat, ema, Tk;

    /* Radiation conductance (mol m-2 s-1) */
    gradn = calc_radiation_conductance(m->tair);

    /* Boundary layer conductance for heat - single sided, forced
       convection (mol m-2 s-1) */
    gbhu = calc_bdn_layer_forced_conduct(m->tair, m->press, m->wind,
                                         p->leaf_width);

    /* Boundary layer conductance for heat - single sided, free convection */
    gbhf = calc_bdn_layer_free_conduct(m->tair, tleaf, m->press, p->leaf_width);

    /* Total boundary layer conductance for heat */
    gbh = gbhu + gbhf;

    /* Total conductance for heat - two-sided */
    *gh = 2.0 * (gbh + gradn);

    gbv = GBVGBH * gbh;
    gsv = GSVGSC * gsc;

    /* Total leaf conductance to water vapour */
    *gv = (gbv * gsv) / (gbv + gsv);
    *gbc = gbh / GBHGBC;

    lambda = calc_latent_heat_of_vapourisation(m->tair);
    gamma = calc_pyschrometric_constant(m->press, lambda);
    slope = calc_slope_of_sat_vapour_pressure_curve(m->tair);

    penman_monteith(m->press, m->vpd, rnet, slope, lambda, gamma, gh, gv,
                    transpiration, LE);

    /* Calculate decoupling coefficient (McNaughton and Jarvis 1986) */
    epsilon = slope / gamma;
    *omega = (1.0 + epsilon) / (1.0 + epsilon + gbv / gsv);

    return;
}
예제 #4
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*/