void canopy_stratum_daily_I( struct world_object *world, struct basin_object *basin, struct hillslope_object *hillslope, struct zone_object *zone, struct patch_object *patch, struct canopy_strata_object *stratum, struct command_line_object *command_line, struct tec_entry *event, struct date current_date) { /*--------------------------------------------------------------*/ /* Local function declaration */ /*--------------------------------------------------------------*/ double compute_lwp_predawn( int, int, double, double, double, double, double, double, double, double, double, double); int compute_annual_turnover( struct epconst_struct, struct epvar_struct *, struct cstate_struct *); int update_rootzone_moist( struct patch_object *, struct rooting_zone_object *, struct command_line_object *); 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); void update_branch_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 *, double, double); void update_phenology( struct zone_object *, struct epvar_struct *, struct epconst_struct, struct phenology_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 *, struct litter_object *, struct soil_c_object *, struct soil_n_object *, struct rooting_zone_object *, double soil_depth, double, double, double, struct date, int); int zero_stratum_daily_flux(struct cdayflux_struct *, struct ndayflux_struct *); /*--------------------------------------------------------------*/ /* Local variable definition. */ /*--------------------------------------------------------------*/ struct cstate_struct *cs; struct nstate_struct *ns; double wilting_point; struct mortality_struct mort; /*--------------------------------------------------------------*/ /* no processing at present for non-veg types */ /*--------------------------------------------------------------*/ if (stratum[0].defaults[0][0].epc.veg_type != NON_VEG) { /*--------------------------------------------------------------*/ /* zero all of the carbon daily flux variables. */ /*--------------------------------------------------------------*/ if (zero_stratum_daily_flux(&(stratum[0].cdf), &(stratum[0].ndf) )){ fprintf(stderr,"fATAL ERROR: in zero_day_flux() ... Exiting\n"); exit(EXIT_FAILURE); } stratum[0].Kup_direct = 0.0; stratum[0].Kup_diffuse = 0.0; if (patch[0].sat_deficit < ZERO) stratum[0].rootzone.S = 1.0; else if (patch[0].sat_deficit_z > patch[0].rootzone.depth) stratum[0].rootzone.S = min(patch[0].rz_storage / patch[0].rootzone.potential_sat, 1.0); else stratum[0].rootzone.S = min((patch[0].rz_storage + patch[0].rootzone.potential_sat - patch[0].sat_deficit) / patch[0].rootzone.potential_sat, 1.0); /*--------------------------------------------------------------*/ /* Compute canopy predawn LWP */ /* Currently defaulted at non-stressed value. */ /*--------------------------------------------------------------*/ stratum[0].epv.psi = compute_lwp_predawn( command_line[0].verbose_flag, patch[0].soil_defaults[0][0].theta_psi_curve, patch[0].Tsoil, stratum[0].defaults[0][0].epc.psi_open, stratum[0].defaults[0][0].epc.psi_close, 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, stratum[0].rootzone.S); wilting_point = exp(-1.0*log(-1.0*stratum[0].defaults[0][0].epc.psi_close/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_0; if (stratum[0].rootzone.S < wilting_point) stratum[0].epv.psi = stratum[0].defaults[0][0].epc.psi_close; if ( command_line[0].verbose_flag > 1 ) printf(" %8f", stratum[0].epv.psi); /*--------------------------------------------------------------*/ /* keep track of water stress days for annual allocation */ /*--------------------------------------------------------------*/ if ( (command_line[0].grow_flag > 0) && (stratum[0].epv.psi <= stratum[0].defaults[0][0].epc.psi_close )) { if (command_line[0].verbose_flag == -2) printf("\n%4ld %4ld %4ld -111.1 ws day %lf %lf", current_date.day, current_date.month, current_date.year, stratum[0].epv.psi ,stratum[0].defaults[0][0].epc.psi_close); stratum[0].epv.wstress_days += 1; } /*--------------------------------------------------------------*/ /* compute temperature for acclimation - currently just a running mean of air temperature */ /*--------------------------------------------------------------*/ stratum[0].cs.Tacc = stratum[0].cs.Tacc*(stratum[0].defaults[0][0].epc.Tacclim_days-1.0)/(stratum[0].defaults[0][0].epc.Tacclim_days) + zone[0].metv.tavg * 1.0/stratum[0].defaults[0][0].epc.Tacclim_days; /*--------------------------------------------------------------*/ /* perform plant mortality losses */ /* (if grow flag is on) */ /*--------------------------------------------------------------*/ if (command_line[0].grow_flag > 0) { cs = &(stratum[0].cs); ns = &(stratum[0].ns); stratum[0].cs.preday_totalc = (cs->cpool + cs->cwdc + cs->leafc + cs->leafc_store + cs->leafc_transfer + cs->dead_leafc + cs->gresp_transfer + cs->gresp_store + cs->frootc + cs->frootc_store + cs->frootc_transfer + cs->live_stemc + cs->livestemc_store + cs->livestemc_transfer + cs->dead_stemc + cs->deadstemc_store + cs->deadstemc_transfer + cs->live_crootc + cs->livecrootc_store + cs->livecrootc_transfer + cs->dead_crootc + cs->deadcrootc_store + cs->deadcrootc_transfer); /* stratum[0].ns.preday_totaln = (ns->npool + ns->cwdn + ns->retransn + ns->dead_leafn + ns->leafn + ns->leafn_store + ns->leafn_transfer + ns->frootn + ns->frootn_store + ns->frootn_transfer + ns->live_stemn + ns->livestemn_store + ns->livestemn_transfer + ns->dead_stemn + ns->deadstemn_store + ns->deadstemn_transfer + ns->live_crootn + ns->livecrootn_store + ns->livecrootn_transfer + ns->dead_crootn + ns->deadcrootn_store + ns->deadcrootn_transfer); */ mort.mort_cpool = stratum[0].defaults[0][0].epc.daily_mortality_turnover; mort.mort_leafc = stratum[0].defaults[0][0].epc.daily_mortality_turnover; mort.mort_deadleafc = stratum[0].defaults[0][0].epc.daily_mortality_turnover; mort.mort_livestemc = stratum[0].defaults[0][0].epc.daily_mortality_turnover; mort.mort_deadstemc = stratum[0].defaults[0][0].epc.daily_mortality_turnover; mort.mort_livecrootc = stratum[0].defaults[0][0].epc.daily_mortality_turnover; mort.mort_deadcrootc = stratum[0].defaults[0][0].epc.daily_mortality_turnover; mort.mort_frootc = stratum[0].defaults[0][0].epc.daily_mortality_turnover; 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), 1, mort); if ((stratum[0].defaults[0][0].epc.veg_type==TREE) && (stratum[0].defaults[0][0].epc.branch_turnover > ZERO)){ update_branch_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), stratum[0].cover_fraction, stratum[0].defaults[0][0].epc.branch_turnover); } } /*--------------------------------------------------------------*/ /* perform seasonal leaf sens. and budding */ /*--------------------------------------------------------------*/ update_phenology( zone, &(stratum[0].epv), stratum[0].defaults[0][0].epc, &(stratum[0].phen), &(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), &(patch[0].litter), &(patch[0].soil_cs), &(patch[0].soil_ns), &(stratum[0].rootzone), patch[0].soil_defaults[0][0].effective_soil_depth, stratum[0].cover_fraction, stratum[0].gap_fraction, basin[0].theta_noon, current_date, command_line[0].grow_flag); /*--------------------------------------------------------------*/ /* if it is the last day of litterfall, perform carbon/nitrogen */ /* allocations */ /*--------------------------------------------------------------*/ if (command_line[0].grow_flag > 0) { if ( command_line[0].verbose_flag == -2 ) printf("\n%4ld %4ld %4ld -111.0 ", current_date.day, current_date.month, current_date.year); if ( stratum[0].phen.annual_allocation == 1) { /*--------------------------------------------------------------*/ /* livewood and leaf turnover */ /*--------------------------------------------------------------*/ if (compute_annual_turnover(stratum[0].defaults[0][0].epc, &(stratum[0].epv), &(stratum[0].cs) ) ){ fprintf(stderr, "FATAL ERROR: in compute_annual_turnover() ... Exiting\n"); exit(EXIT_FAILURE); } /*--------------------------------------------------------------*/ /* zero annual (season) accumulation variables */ /*--------------------------------------------------------------*/ stratum[0].epv.wstress_days = 0; stratum[0].epv.max_fparabs = 0.0; stratum[0].epv.min_vwc = 1.0; } /* end litterfall end of season calculations */ } /* end grow flag */ } /* end NON_VEG conditional */ return; } /*end canopy_stratum_I.c*/
void input_new_strata( struct command_line_object *command_line, FILE *world_file, int num_world_base_stations, struct base_station_object **world_base_stations, struct default_object *defaults, struct patch_object *patch, struct canopy_strata_object *canopy_strata) { /*--------------------------------------------------------------*/ /* Local function definition. */ /*--------------------------------------------------------------*/ struct base_station_object *assign_base_station( int , int , struct base_station_object **); int compute_annual_turnover(struct epconst_struct, struct epvar_struct *, struct cstate_struct *); int compute_annual_litfall( struct epconst_struct, struct phenology_struct *, struct cstate_struct *, int); int update_rooting_depth( struct rooting_zone_object *, double, double, double, double); double compute_delta_water( int, double, double, double, double, double); double compute_lwp_predawn( int, int, double, double, double, double, double, double, double, double, double, double); void *alloc( size_t, char *, char *); param *readtag_worldfile(int *, FILE *, char *); /*--------------------------------------------------------------*/ /* Local variable definition. */ /*--------------------------------------------------------------*/ int base_stationID; int i, dtmp, num_lines; char record[MAXSTR]; double rootc, ltmp; int paramCnt=0; param *paramPtr=NULL; /*--------------------------------------------------------------*/ /* Read in the next canopy strata record for this patch. */ /*--------------------------------------------------------------*/ paramPtr = readtag_worldfile(¶mCnt,world_file,"Canopy_Strata"); dtmp = getIntWorldfile(¶mCnt,¶mPtr,"veg_parm_ID","%d",canopy_strata[0].veg_parm_ID,1); if (dtmp > 0) canopy_strata[0].veg_parm_ID = dtmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"cover_fraction","%lf",canopy_strata[0].cover_fraction,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cover_fraction = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"gap_fraction","%lf",canopy_strata[0].gap_fraction,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].gap_fraction = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"rootzone.depth","%lf",canopy_strata[0].rootzone.depth,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].rootzone.depth = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"snow_stored","%lf",canopy_strata[0].snow_stored,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].snow_stored = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"rain_stored","%lf",canopy_strata[0].rain_stored,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].rain_stored = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"cs.cpool","%lf",canopy_strata[0].cs.cpool,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.cpool = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"cs.leafc","%lf",canopy_strata[0].cs.leafc,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.leafc = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"cs.dead_leafc","%lf",canopy_strata[0].cs.dead_leafc,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.dead_leafc = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"cs.leafc_store","%lf",canopy_strata[0].cs.leafc_store,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.leafc_store = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"cs.leafc_transfer","%lf",canopy_strata[0].cs.leafc_transfer,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.leafc_transfer = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"cs.live_stemc","%lf",canopy_strata[0].cs.live_stemc,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.live_stemc = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"cs.livestemc_store","%lf",canopy_strata[0].cs.livestemc_store,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.livestemc_store = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"cs.livestemc_transfer","%lf",canopy_strata[0].cs.livestemc_transfer,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.livestemc_transfer = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"cs.dead_stemc","%lf",canopy_strata[0].cs.dead_stemc,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.dead_stemc = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"cs.deadstemc_store","%lf",canopy_strata[0].cs.deadstemc_store,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.deadstemc_store = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"cs.deadstemc_transfer","%lf",canopy_strata[0].cs.deadstemc_transfer,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.deadstemc_transfer = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"cs.live_crootc","%lf",canopy_strata[0].cs.live_crootc,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.live_crootc = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"cs.livecrootc_store","%lf",canopy_strata[0].cs.livecrootc_store,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.livecrootc_store = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"cs.livecrootc_transfer","%lf",canopy_strata[0].cs.livecrootc_transfer,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.livecrootc_transfer = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"cs.dead_crootc","%lf",canopy_strata[0].cs.dead_crootc,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.dead_crootc = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"cs.deadcrootc_store","%lf",canopy_strata[0].cs.deadcrootc_store,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.deadcrootc_store = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"cs.deadcrootc_transfer","%lf",canopy_strata[0].cs.deadcrootc_transfer,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.deadcrootc_transfer = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"cs.frootc","%lf",canopy_strata[0].cs.frootc,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.frootc = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"cs.frootc_store","%lf",canopy_strata[0].cs.frootc_store,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.frootc_store = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"cs.frootc_transfer","%lf",canopy_strata[0].cs.frootc_transfer,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.frootc_transfer = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"cs.cwdc","%lf",canopy_strata[0].cs.cwdc,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.cwdc = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"epv.prev_leafcalloc","%lf",canopy_strata[0].epv.prev_leafcalloc,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].epv.prev_leafcalloc = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"ns.npool","%lf",canopy_strata[0].ns.npool,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.npool = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"ns.leafn","%lf",canopy_strata[0].ns.leafn,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.leafn = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"ns.dead_leafn","%lf",canopy_strata[0].ns.dead_leafn,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.dead_leafn = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"ns.leafn_store","%lf",canopy_strata[0].ns.leafn_store,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.leafn_store = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"ns.leafn_transfer","%lf",canopy_strata[0].ns.leafn_transfer,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.leafn_transfer = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"ns.live_stemn","%lf",canopy_strata[0].ns.live_stemn,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.live_stemn = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"ns.livestemn_store","%lf",canopy_strata[0].ns.livestemn_store,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.livestemn_store = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"ns.livestemn_transfer","%lf",canopy_strata[0].ns.livestemn_transfer,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.livestemn_transfer = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"ns.dead_stemn","%lf",canopy_strata[0].ns.dead_stemn,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.dead_stemn = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"ns.deadstemn_store","%lf",canopy_strata[0].ns.deadstemn_store,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.deadstemn_store = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"ns.deadstemn_transfer","%lf",canopy_strata[0].ns.deadstemn_transfer,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.deadstemn_transfer = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"ns.live_crootn","%lf",canopy_strata[0].ns.live_crootn,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.live_crootn = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"ns.livecrootn_store","%lf",canopy_strata[0].ns.livecrootn_store,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.livecrootn_store = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"ns.livecrootn_transfer","%lf",canopy_strata[0].ns.livecrootn_transfer,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.livecrootn_transfer = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"ns.dead_crootn","%lf",canopy_strata[0].ns.dead_crootn,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.dead_crootn = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"ns.deadcrootn_store","%lf",canopy_strata[0].ns.deadcrootn_store,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.deadcrootn_store = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"ns.deadcrootn_transfer","%lf",canopy_strata[0].ns.deadcrootn_transfer,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.deadcrootn_transfer = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"ns.frootn","%lf",canopy_strata[0].ns.frootn,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.frootn = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"ns.frootn_store","%lf",canopy_strata[0].ns.frootn_store,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.frootn_store = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"ns.frootn_transfer","%lf",canopy_strata[0].ns.frootn_transfer,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.frootn_transfer = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"ns.cwdn","%lf",canopy_strata[0].ns.cwdn,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.cwdn = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"ns.retransn","%lf",canopy_strata[0].ns.retransn,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.retransn = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"cs.age","%lf",canopy_strata[0].cs.age,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.age = ltmp; /*--------------------------------------------------------------*/ /* intialized annual flux variables */ /*--------------------------------------------------------------*/ ltmp = getIntWorldfile(¶mCnt,¶mPtr,"epv.wstress_days","%d",canopy_strata[0].epv.wstress_days,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].epv.wstress_days = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"epv.max_fparabs","%lf",canopy_strata[0].epv.max_fparabs,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].epv.max_fparabs = ltmp; ltmp = getDoubleWorldfile(¶mCnt,¶mPtr,"epv.min_vwc","%lf",canopy_strata[0].epv.min_vwc,1); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].epv.min_vwc = ltmp; dtmp = getIntWorldfile(¶mCnt,¶mPtr,"n_basestations","%d",canopy_strata[0].num_base_stations,0); /*--------------------------------------------------------------*/ /* Assign defaults for this canopy_strata */ /*--------------------------------------------------------------*/ if (canopy_strata[0].veg_parm_ID > 0) { i=0; while (defaults[0].stratum[i].ID != canopy_strata[0].veg_parm_ID) { i++; /*--------------------------------------------------------------*/ /* Report an error if no match was found. Otherwise assign */ /* the default to point to this canopy_strata. */ /*--------------------------------------------------------------*/ if ( i>= defaults[0].num_stratum_default_files ){ fprintf(stderr, "\nFATAL ERROR: in construct_canopy_strata, canopy_strata default ID %d not found.\n" , canopy_strata[0].veg_parm_ID); exit(EXIT_FAILURE); } } /* end-while */ canopy_strata[0].defaults[0] = &defaults[0].stratum[i]; } /*--------------------------------------------------------------*/ /* zero all long term sinks */ /*--------------------------------------------------------------*/ canopy_strata[0].cs.gpsn_src = 0.0; canopy_strata[0].cs.leaf_mr_snk = 0.0; canopy_strata[0].cs.leaf_gr_snk = 0.0; canopy_strata[0].cs.livestem_mr_snk = 0.0; canopy_strata[0].cs.livestem_gr_snk = 0.0; canopy_strata[0].cs.deadstem_gr_snk = 0.0; canopy_strata[0].cs.livecroot_mr_snk = 0.0; canopy_strata[0].cs.livecroot_gr_snk = 0.0; canopy_strata[0].cs.deadcroot_gr_snk = 0.0; canopy_strata[0].cs.froot_mr_snk = 0.0; canopy_strata[0].cs.froot_gr_snk = 0.0; canopy_strata[0].cs.nppcum = 0.0; /*--------------------------------------------------------------*/ /* determine current lai and height based on current leaf carbon */ /* we need to initialize the sunlit/shaded proportions of LAI here */ /* (these will later be updated in update_phenology */ /* using Chen;s method */ /*--------------------------------------------------------------*/ canopy_strata[0].epv.proj_sla_sunlit = canopy_strata[0].defaults[0][0].epc.proj_sla; canopy_strata[0].epv.proj_sla_shade = canopy_strata[0].defaults[0][0].epc.proj_sla * canopy_strata[0].defaults[0][0].epc.shade_sla_mult; if ( canopy_strata[0].cs.leafc <= 1.0/canopy_strata[0].epv.proj_sla_sunlit) { canopy_strata[0].epv.proj_lai = canopy_strata[0].cs.leafc * canopy_strata[0].epv.proj_sla_sunlit; canopy_strata[0].epv.proj_lai_sunlit = canopy_strata[0].epv.proj_lai; canopy_strata[0].epv.proj_lai_shade = 0.0; } else { canopy_strata[0].epv.proj_lai = 1.0 + ( canopy_strata[0].cs.leafc - 1.0/canopy_strata[0].epv.proj_sla_sunlit) * canopy_strata[0].epv.proj_sla_shade; canopy_strata[0].epv.proj_lai_sunlit = 1.0; canopy_strata[0].epv.proj_lai_shade = canopy_strata[0].epv.proj_lai - 1.0; } canopy_strata[0].epv.all_lai = canopy_strata[0].epv.proj_lai * canopy_strata[0].defaults[0][0].epc.lai_ratio; canopy_strata[0].epv.max_proj_lai = canopy_strata[0].epv.proj_lai; if (canopy_strata[0].defaults[0][0].epc.veg_type == TREE) canopy_strata[0].epv.height = canopy_strata[0].defaults[0][0].epc.height_to_stem_coef * pow((canopy_strata[0].cs.live_stemc+canopy_strata[0].cs.dead_stemc), canopy_strata[0].defaults[0][0].epc.height_to_stem_exp); else canopy_strata[0].epv.height = canopy_strata[0].defaults[0][0].epc.height_to_stem_coef * pow((canopy_strata[0].cs.leafc + canopy_strata[0].cs.dead_leafc), canopy_strata[0].defaults[0][0].epc.height_to_stem_exp); /*--------------------------------------------------------------*/ /* calculate all sided and project pai from max projected lai */ /*--------------------------------------------------------------*/ if (canopy_strata[0].defaults[0][0].epc.veg_type == TREE) { canopy_strata[0].epv.proj_pai = canopy_strata[0].epv.proj_lai + canopy_strata[0].defaults[0][0].epc.proj_swa * (canopy_strata[0].cs.live_stemc + canopy_strata[0].cs.dead_stemc); canopy_strata[0].epv.all_pai = canopy_strata[0].epv.all_lai + canopy_strata[0].defaults[0][0].epc.proj_swa * (canopy_strata[0].cs.live_stemc + canopy_strata[0].cs.dead_stemc); } else { canopy_strata[0].epv.proj_pai = canopy_strata[0].epv.proj_lai; canopy_strata[0].epv.all_pai = canopy_strata[0].epv.all_lai; } /*--------------------------------------------------------------*/ /* initializae turnovers and litterfall */ /*--------------------------------------------------------------*/ if (compute_annual_turnover(canopy_strata[0].defaults[0][0].epc, &(canopy_strata[0].epv), &(canopy_strata[0].cs)) ){ fprintf(stderr,"FATAL ERROR: in compute_annual_turnover() ... Exiting\n"); exit(EXIT_FAILURE); } if (compute_annual_litfall(canopy_strata[0].defaults[0][0].epc, &(canopy_strata[0].phen), &(canopy_strata[0].cs), command_line[0].grow_flag) ){ fprintf(stderr,"FATAL ERROR: in compute_annual_litfall() ... Exiting\n"); exit(EXIT_FAILURE); } /*--------------------------------------------------------------*/ /* compute new rooting depth based on current root carbon */ /*--------------------------------------------------------------*/ if ( command_line[0].grow_flag != 0) { rootc = canopy_strata[0].cs.frootc+canopy_strata[0].cs.live_crootc+canopy_strata[0].cs.dead_crootc; if (rootc > ZERO){ if (update_rooting_depth( &(canopy_strata[0].rootzone), rootc, canopy_strata[0].defaults[0][0].epc.root_growth_direction, canopy_strata[0].defaults[0][0].epc.root_distrib_parm, patch[0].soil_defaults[0][0].effective_soil_depth)){ fprintf(stderr, "FATAL ERROR: in compute_rooting_depth() from construct_canopy_strata()\n"); exit(EXIT_FAILURE); } } } patch[0].rootzone.depth = max(patch[0].rootzone.depth, canopy_strata[0].rootzone.depth); /*--------------------------------------------------------------*/ /* set phenology timing if static allocation */ /*--------------------------------------------------------------*/ if (canopy_strata[0].defaults[0][0].epc.phenology_flag == STATIC ) { canopy_strata[0].phen.expand_startday = canopy_strata[0].defaults[0][0].epc.day_leafon; canopy_strata[0].phen.expand_stopday = canopy_strata[0].phen.expand_startday + canopy_strata[0].defaults[0][0].epc.ndays_expand; canopy_strata[0].phen.litfall_startday = canopy_strata[0].defaults[0][0].epc.day_leafoff; canopy_strata[0].phen.litfall_stopday = canopy_strata[0].phen.litfall_startday + canopy_strata[0].defaults[0][0].epc.ndays_litfall; if (canopy_strata[0].phen.expand_stopday > 365) canopy_strata[0].phen.expand_stopday -= 365; if (canopy_strata[0].phen.litfall_stopday > 365) canopy_strata[0].phen.litfall_stopday -= 365; /*---------------------------------------------------------------*/ /* assume this is 365 for now since we don't know when next */ /* year's growing season will start */ /*---------------------------------------------------------------*/ canopy_strata[0].phen.nretdays = 365; } else if (canopy_strata[0].defaults[0][0].epc.phenology_flag == DROUGHT ) { canopy_strata[0].phen.expand_startday = canopy_strata[0].defaults[0][0].epc.day_leafon; canopy_strata[0].phen.expand_stopday = canopy_strata[0].phen.expand_startday + canopy_strata[0].defaults[0][0].epc.ndays_expand; canopy_strata[0].phen.litfall_startday = canopy_strata[0].defaults[0][0].epc.day_leafoff; canopy_strata[0].phen.litfall_stopday = canopy_strata[0].phen.litfall_startday + canopy_strata[0].defaults[0][0].epc.ndays_litfall; if (canopy_strata[0].phen.expand_stopday > 365) canopy_strata[0].phen.expand_stopday -= 365; if (canopy_strata[0].phen.litfall_stopday > 365) canopy_strata[0].phen.litfall_stopday -= 365; /*---------------------------------------------------------------*/ /* assume this is 365 for now since we don't know when next */ /* year's growing season will start */ /*---------------------------------------------------------------*/ canopy_strata[0].phen.nretdays = 365; canopy_strata[0].phen.gwseasonday = -1; canopy_strata[0].phen.lfseasonday = -1; canopy_strata[0].phen.pheno_flag = 0; } else { fprintf(stderr,"\nFATAL ERROR - construct_canopy_stratum.c"); fprintf(stderr,"\n phenology flag must be set to 0 for STATIC"); fprintf(stderr,"\n since dynamic phenology timing not yet implemented"); exit(EXIT_FAILURE); } /*--------------------------------------------------------------*/ /* initialize runnning average of psi using current day psi */ /*--------------------------------------------------------------*/ if (canopy_strata[0].rootzone.depth > ZERO) canopy_strata[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, canopy_strata[0].rootzone.depth, 0.0); canopy_strata[0].rootzone.S = min(patch[0].rz_storage / canopy_strata[0].rootzone.potential_sat, 1.0); canopy_strata[0].epv.psi = compute_lwp_predawn( command_line[0].verbose_flag, patch[0].soil_defaults[0][0].theta_psi_curve, patch[0].Tsoil, canopy_strata[0].defaults[0][0].epc.psi_open, canopy_strata[0].defaults[0][0].epc.psi_close, 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, canopy_strata[0].rootzone.S); canopy_strata[0].epv.psi_ravg = canopy_strata[0].epv.psi; /*--------------------------------------------------------------*/ /* for now initialize these accumuling variables */ /*--------------------------------------------------------------*/ if (fabs(ltmp - NULLVAL) >= ONE) { canopy_strata[0].epv.wstress_days = 0; canopy_strata[0].epv.max_fparabs = 0.0; canopy_strata[0].epv.min_vwc = 1.0; //canopy_strata[0].cs.age = 0; canopy_strata[0].cs.num_resprout = 0; } /*--------------------------------------------------------------*/ /* Read in the number of strata base stations */ /*--------------------------------------------------------------*/ /* fscanf(world_file,"%d",&(dtmp)); read_record(world_file, record);*/ if (dtmp > 0) { canopy_strata[0].num_base_stations = dtmp; /*--------------------------------------------------------------*/ /* Allocate a list of base stations for this strata. */ /*--------------------------------------------------------------*/ canopy_strata[0].base_stations = (struct base_station_object **) alloc(canopy_strata[0].num_base_stations * sizeof(struct base_station_object *),"base_stations", "construct_canopy_strata"); /*--------------------------------------------------------------*/ /* Read each base_station ID and then point to that base_statio*/ /*--------------------------------------------------------------*/ for (i=0 ; i<canopy_strata[0].num_base_stations; i++){ fscanf(world_file,"%d",&(base_stationID)); read_record(world_file, record); /*--------------------------------------------------------------*/ /* Point to the appropriate base station in the base */ /* station list for this world. */ /* */ /*--------------------------------------------------------------*/ canopy_strata[0].base_stations[i] = assign_base_station( base_stationID, num_world_base_stations, world_base_stations); } /*end for*/ } if(paramPtr!=NULL){ free(paramPtr); } return; } /*end input_new_strata.c*/