struct basin_object *construct_basin( 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) { /*--------------------------------------------------------------*/ /* Local function definition. */ /*--------------------------------------------------------------*/ struct base_station_object *assign_base_station( int, int, struct base_station_object **); struct hillslope_object *construct_hillslope( struct command_line_object *, FILE *, int , struct base_station_object **, struct default_object *); void *alloc( size_t, char *, char *); void sort_by_elevation( struct basin_object *); // struct routing_list_object construct_ddn_routing_topology( // char *, // struct basin_object *); // struct routing_list_object construct_routing_topology( // char *, // struct basin_object *, // struct command_line_object *); struct stream_list_object construct_stream_routing_topology( char *, struct basin_object *, struct command_line_object *); /*--------------------------------------------------------------*/ /* Local variable definition. */ /*--------------------------------------------------------------*/ int base_stationID; int i,j,z; int default_object_ID; double check_snow_scale; double n_routing_timesteps; char record[MAXSTR]; struct basin_object *basin; /*--------------------------------------------------------------*/ /* Allocate a basin object. */ /*--------------------------------------------------------------*/ basin = (struct basin_object *) alloc( 1 * sizeof( struct basin_object ),"basin","construct_basin"); /*--------------------------------------------------------------*/ /* Read in the basinID. */ /*--------------------------------------------------------------*/ fscanf(world_file,"%d",&(basin[0].ID)); read_record(world_file, record); fscanf(world_file,"%lf",&(basin[0].x)); read_record(world_file, record); fscanf(world_file,"%lf",&(basin[0].y)); read_record(world_file, record); fscanf(world_file,"%lf",&(basin[0].z)); read_record(world_file, record); fscanf(world_file,"%d",&(default_object_ID)); read_record(world_file, record); fscanf(world_file,"%lf",&(basin[0].latitude)); read_record(world_file, record); fscanf(world_file,"%d",&(basin[0].num_base_stations)); read_record(world_file, record); /*--------------------------------------------------------------*/ /* Create cosine of latitude to save future computations. */ /*--------------------------------------------------------------*/ basin[0].cos_latitude = cos(basin[0].latitude*DtoR); basin[0].sin_latitude = sin(basin[0].latitude*DtoR); /*--------------------------------------------------------------*/ /* Allocate a list of base stations for this basin. */ /*--------------------------------------------------------------*/ basin[0].base_stations = (struct base_station_object **) alloc(basin[0].num_base_stations * sizeof(struct base_station_object *),"base_stations","construct_basin"); /*--------------------------------------------------------------*/ /* Read each base_station ID and then point to that base_statio*/ /*--------------------------------------------------------------*/ for (i=0 ; i<basin[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. */ /*--------------------------------------------------------------*/ basin[0].base_stations[i] = assign_base_station( base_stationID, num_world_base_stations, world_base_stations); } /*end for*/ /*--------------------------------------------------------------*/ /* Create the grow subobject if needed. */ /*--------------------------------------------------------------*/ if ( command_line[0].grow_flag == 1 ){ /*--------------------------------------------------------------*/ /* Allocate memory for the grow subobject. */ /*--------------------------------------------------------------*/ basin[0].grow = (struct grow_basin_object *) alloc(1 * sizeof(struct grow_basin_object), "grow","construct_basin"); /*--------------------------------------------------------------*/ /* NOTE: PUT READS FOR GROW SUBOBJECT HERE. */ /*--------------------------------------------------------------*/ } /*end if*/ /*--------------------------------------------------------------*/ /* Assign defaults for this basin */ /*--------------------------------------------------------------*/ basin[0].defaults = (struct basin_default **) alloc( sizeof(struct basin_default *),"defaults","construct_basin" ); i = 0; while (defaults[0].basin[i].ID != default_object_ID) { i++; /*--------------------------------------------------------------*/ /* Report an error if no match was found. Otherwise assign */ /* the default to point to this basin. */ /*--------------------------------------------------------------*/ if ( i>= defaults[0].num_basin_default_files ){ fprintf(stderr, "\nFATAL ERROR: in construct_basin,basin default ID %d not found.\n", default_object_ID); exit(EXIT_FAILURE); } } /* end-while */ basin[0].defaults[0] = &defaults[0].basin[i]; /*--------------------------------------------------------------*/ /* Read in the number of hillslopes. */ /*--------------------------------------------------------------*/ fscanf(world_file,"%d",&(basin[0].num_hillslopes)); read_record(world_file, record); /*--------------------------------------------------------------*/ /* Allocate a list of pointers to hillslope objects. */ /*--------------------------------------------------------------*/ basin[0].hillslopes = (struct hillslope_object **) alloc(basin[0].num_hillslopes * sizeof(struct hillslope_object *), "hillslopes","construct_basin"); basin[0].area = 0.0; basin[0].max_slope = 0.0; n_routing_timesteps = 0.0; check_snow_scale = 0.0; /*--------------------------------------------------------------*/ /* Construct the hillslopes for this basin. */ /*--------------------------------------------------------------*/ for (i=0; i<basin[0].num_hillslopes; i++){ basin[0].hillslopes[i] = construct_hillslope( command_line, world_file, num_world_base_stations, world_base_stations,defaults); basin[0].area += basin[0].hillslopes[i][0].area; n_routing_timesteps += basin[0].hillslopes[i][0].area * basin[0].hillslopes[i][0].defaults[0][0].n_routing_timesteps; if (basin[0].max_slope < basin[0].hillslopes[i][0].slope) basin[0].max_slope = basin[0].hillslopes[i][0].slope; if (command_line[0].snow_scale_flag == 1) { for (z = 0; z < basin[0].hillslopes[i][0].num_zones; z++) { for (j=0; j < basin[0].hillslopes[i][0].zones[z][0].num_patches; j++) { check_snow_scale += basin[0].hillslopes[i][0].zones[z][0].patches[j][0].snow_redist_scale * basin[0].hillslopes[i][0].zones[z][0].patches[j][0].area; } } } }; basin[0].defaults[0][0].n_routing_timesteps = (int) (n_routing_timesteps / basin[0].area); if (basin[0].defaults[0][0].n_routing_timesteps < 1) basin[0].defaults[0][0].n_routing_timesteps = 1; if (command_line[0].snow_scale_flag == 1) { check_snow_scale /= basin[0].area; if (fabs(check_snow_scale - 1.0) > ZERO ) { printf("\n ******* WARNING ********** "); printf("\n Basin-wide average snow scale is %lf", check_snow_scale); printf("\n Snow rescaling will alter net precip input by this scale factor\n\n"); } if (command_line[0].snow_scale_tol > ZERO) { if ((check_snow_scale > command_line[0].snow_scale_tol) || (check_snow_scale < 1/command_line[0].snow_scale_tol)) { printf("Basin-wide average snow scale %lf is outside tolerance %lf", check_snow_scale, command_line[0].snow_scale_tol); printf("\n Exiting\n"); exit(EXIT_FAILURE); } } } /*--------------------------------------------------------------*/ /* initialize accumulator variables for this patch */ /*--------------------------------------------------------------*/ basin[0].acc_month.et = 0.0; basin[0].acc_month.snowpack = 0.0; basin[0].acc_month.theta = 0.0; basin[0].acc_month.streamflow = 0.0; basin[0].acc_month.length = 0; basin[0].acc_month.denitrif = 0.0; basin[0].acc_month.nitrif = 0.0; basin[0].acc_month.mineralized = 0.0; basin[0].acc_month.uptake = 0.0; basin[0].acc_month.lai = 0.0; basin[0].acc_month.leach = 0.0; basin[0].acc_month.DOC_loss = 0.0; basin[0].acc_month.DON_loss = 0.0; basin[0].acc_month.stream_NO3 = 0.0; basin[0].acc_month.stream_NH4 = 0.0; basin[0].acc_month.stream_DON = 0.0; basin[0].acc_month.stream_DOC = 0.0; basin[0].acc_month.PET = 0.0; basin[0].acc_month.psn = 0.0; basin[0].acc_month.num_threshold = 0; basin[0].acc_year.et = 0.0; basin[0].acc_year.snowpack = 0.0; basin[0].acc_year.theta = 0.0; basin[0].acc_year.streamflow = 0.0; basin[0].acc_year.length = 0; basin[0].acc_year.denitrif = 0.0; basin[0].acc_year.nitrif = 0.0; basin[0].acc_year.mineralized = 0.0; basin[0].acc_year.uptake = 0.0; basin[0].acc_year.lai = 0.0; basin[0].acc_year.leach = 0.0; basin[0].acc_year.DOC_loss = 0.0; basin[0].acc_year.DON_loss = 0.0; basin[0].acc_year.stream_NO3 = 0.0; basin[0].acc_year.stream_NH4 = 0.0; basin[0].acc_year.stream_DON = 0.0; basin[0].acc_year.stream_DOC = 0.0; basin[0].acc_year.PET = 0.0; basin[0].acc_year.psn = 0.0; basin[0].acc_year.num_threshold = 0; /*--------------------------------------------------------------*/ /* Sort sub-hierarchy in the basin by elevation */ /*--------------------------------------------------------------*/ sort_by_elevation(basin); /*--------------------------------------------------------------*/ /* Read in flow routing topology for routing option */ /*--------------------------------------------------------------*/ if ( command_line[0].routing_flag == 1 ) { basin[0].outside_region = (struct patch_object *) alloc (1 * sizeof(struct patch_object) , "patch", "construct_basin"); basin[0].outside_region[0].sat_deficit = 0.0; basin[0].outside_region[0].ID = 0; if ( command_line[0].ddn_routing_flag == 1 ) { basin->route_list = construct_ddn_routing_topology( command_line[0].routing_filename, basin); } else { basin->route_list = construct_routing_topology( command_line[0].routing_filename, basin, command_line, false); if ( command_line->surface_routing_flag ) { printf("\tReading surface routing table\n"); basin->surface_route_list = construct_routing_topology( command_line->surface_routing_filename, basin, command_line, true); if ( basin->surface_route_list->num_patches != basin->route_list->num_patches ) { fprintf(stderr, "\nFATAL ERROR: in construct_basin, surface routing table has %d patches, but subsurface routing table has %d patches. The number of patches must be identical.\n", basin->surface_route_list->num_patches, basin->route_list->num_patches); exit(EXIT_FAILURE); } } else { // No surface routing table specified, use sub-surface for surface basin->surface_route_list = construct_routing_topology( command_line->routing_filename, basin, command_line, true); } } } else { // command_line[0].routing_flag != 1 // For TOPMODEL mode, make a dummy route list consisting of all patches // in the basin, in no particular order. basin->route_list = construct_topmodel_patchlist(basin); } /*--------------------------------------------------------------*/ /* Read in stream routing topology if needed */ /*--------------------------------------------------------------*/ if ( command_line[0].stream_routing_flag == 1) { basin[0].stream_list = construct_stream_routing_topology( command_line[0].stream_routing_filename, basin, command_line); } else { basin[0].stream_list.stream_network = NULL; basin[0].stream_list.streamflow = 0.0; } return(basin); } /*end construct_basin.c*/
void input_new_hillslope_mult( 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 hillslope_object *hillslope) { /*--------------------------------------------------------------*/ /* Local function definition. */ /*--------------------------------------------------------------*/ struct base_station_object *assign_base_station( int , int , struct base_station_object **); void *alloc( size_t, char *, char *); /*--------------------------------------------------------------*/ /* Local variable definition. */ /*--------------------------------------------------------------*/ int i,j, dtmp; int base_stationID; int default_object_ID; char record[MAXSTR]; double ltmp; /*--------------------------------------------------------------*/ /* Read in the hillslope record from the world file. */ /*--------------------------------------------------------------*/ fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ZERO) hillslope[0].x = ltmp * hillslope[0].x; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ZERO) hillslope[0].y = ltmp * hillslope[0].y; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ZERO) hillslope[0].z = ltmp * hillslope[0].z; fscanf(world_file,"%d",&(default_object_ID)); read_record(world_file, record); fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ZERO) hillslope[0].gw.storage = ltmp * hillslope[0].gw.storage; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ZERO) hillslope[0].gw.NO3 = ltmp * hillslope[0].gw.NO3; /*--------------------------------------------------------------*/ /* Assign defaults for this hillslope */ /*--------------------------------------------------------------*/ if (default_object_ID > 0) { i = 0; while (defaults[0].hillslope[i].ID != default_object_ID) { i++; /*--------------------------------------------------------------*/ /* Report an error if no match was found. Otherwise assign */ /* the default to point to this hillslope. */ /*--------------------------------------------------------------*/ if ( i>= defaults[0].num_hillslope_default_files ){ fprintf(stderr, "\nFATAL ERROR: in input_new_hillslope,hillslope default ID %d not found.\n", default_object_ID); exit(EXIT_FAILURE); } } /* end-while */ hillslope[0].defaults[0] = &defaults[0].hillslope[i]; } /*--------------------------------------------------------------*/ /* Allocate a list of base stations for this hillslope. */ /*--------------------------------------------------------------*/ fscanf(world_file,"%d",&(dtmp)); read_record(world_file, record); if (dtmp > 0) { hillslope[0].num_base_stations = dtmp * hillslope[0].num_base_stations; hillslope[0].base_stations = (struct base_station_object **) alloc(hillslope[0].num_base_stations * sizeof(struct base_station_object *),"base_stations", "input_new_hillslopes" ); /*--------------------------------------------------------------*/ /* Read each base_station ID and then point to that base_statio*/ /*--------------------------------------------------------------*/ for (i=0 ; i<hillslope[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. */ /* */ /*--------------------------------------------------------------*/ hillslope[0].base_stations[i] = assign_base_station( base_stationID, num_world_base_stations, world_base_stations); } /*end for*/ } return; } /*end input_new_hillslope.c*/
void input_new_zone( 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 zone_object *zone) { /*--------------------------------------------------------------*/ /* Local function definition. */ /*--------------------------------------------------------------*/ struct base_station_object *assign_base_station( int , int , struct base_station_object **); void *alloc(size_t, char *, char *); double atm_pres( double ); /*--------------------------------------------------------------*/ /* Local variable definition. */ /*--------------------------------------------------------------*/ int base_stationID; int i,dtmp; int default_object_ID; char record[MAXSTR]; double ltmp; /*--------------------------------------------------------------*/ /* Read in the next zone record for this hillslope. */ /*--------------------------------------------------------------*/ fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ZERO) zone[0].x = ltmp; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ZERO) zone[0].y = ltmp; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ZERO) { zone[0].z = ltmp; zone[0].metv.pa = atm_pres( zone[0].z ); } fscanf(world_file,"%d",&(default_object_ID)); read_record(world_file, record); fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ZERO) zone[0].area = ltmp; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ZERO) { zone[0].slope = ltmp * DtoR; zone[0].cos_slope = cos(zone[0].slope); zone[0].sin_slope = sin(zone[0].slope); } fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ZERO) { zone[0].aspect = ltmp * DtoR; zone[0].cos_aspect = cos(zone[0].aspect); zone[0].sin_aspect = sin(zone[0].aspect); } fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ZERO) zone[0].precip_lapse_rate = ltmp; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ZERO) zone[0].e_horizon = ltmp; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ZERO) zone[0].w_horizon = ltmp; /*--------------------------------------------------------------*/ /* Assign defaults for this zone */ /*--------------------------------------------------------------*/ if (default_object_ID > 0) { i = 0; while (defaults[0].zone[i].ID != default_object_ID) { i++; /*--------------------------------------------------------------*/ /* Report an error if no match was found. Otherwise assign */ /* the default to point to this zone. */ /*--------------------------------------------------------------*/ if ( i>= defaults[0].num_zone_default_files ){ fprintf(stderr, "\nFATAL ERROR: in input_new_zone, zone default ID %d not found.\n", default_object_ID); exit(EXIT_FAILURE); } } /* end-while */ zone[0].defaults[0] = &defaults[0].zone[i]; } /*--------------------------------------------------------------*/ /* Allocate a list of base stations for this zone. */ /*--------------------------------------------------------------*/ fscanf(world_file,"%d",&(dtmp)); read_record(world_file, record); if (dtmp > 0) { zone[0].num_base_stations = dtmp; zone[0].base_stations = (struct base_station_object **) alloc(zone[0].num_base_stations * sizeof(struct base_station_object *), "base_stations","input_new_zone" ); /*--------------------------------------------------------------*/ /* Read each base_station ID and then point to that base station */ /*--------------------------------------------------------------*/ for (i=0 ; i<zone[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. */ /* */ /*--------------------------------------------------------------*/ zone[0].base_stations[i] = assign_base_station( base_stationID, num_world_base_stations, world_base_stations); } /*end for*/ } else { fscanf(world_file,"%d",&(dtmp)); read_record(world_file, record); } /*--------------------------------------------------------------*/ /* Initialize any variables that should be initialized at */ /* the start of a simulation run for the zone. */ /*--------------------------------------------------------------*/ return; } /*end input_new_zone.c*/
struct zone_object *construct_zone( 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 base_station_ncheader_object *base_station_ncheader, struct world_object *world) { /*--------------------------------------------------------------*/ /* Local function definition. */ /*--------------------------------------------------------------*/ struct base_station_object *assign_base_station( int , int , struct base_station_object **); struct base_station_object *assign_base_station_xy( float , float , int , int *, struct base_station_object **); struct patch_object *construct_patch( struct command_line_object *, FILE *, int num_world_base_stations, struct base_station_object **world_base_stations, struct default_object *defaults); struct base_station_object *construct_netcdf_grid( struct base_station_ncheader_object *, int *, float, float, float, struct date, struct date); int get_netcdf_xy(char *, char *, char *, float, float, float, float *, float *); void *alloc(size_t, char *, char *); double atm_pres( double ); /*--------------------------------------------------------------*/ /* Local variable definition. */ /*--------------------------------------------------------------*/ int base_stationID; int i, k, j; int default_object_ID; int notfound; int *dum; float base_x, base_y; char record[MAXSTR]; struct zone_object *zone; notfound = 0; base_x = 0.0; base_y = 0.0; j = 0; k = 0; /*--------------------------------------------------------------*/ /* Allocate a zone object. */ /*--------------------------------------------------------------*/ zone = (struct zone_object *) alloc( 1 * sizeof( struct zone_object ),"zone","construct_zone" ); /*--------------------------------------------------------------*/ /* Read in the next zone record for this hillslope. */ /*--------------------------------------------------------------*/ fscanf(world_file,"%d",&(zone[0].ID)); read_record(world_file, record); fscanf(world_file,"%lf",&(zone[0].x)); read_record(world_file, record); fscanf(world_file,"%lf",&(zone[0].y)); read_record(world_file, record); fscanf(world_file,"%lf",&(zone[0].z)); read_record(world_file, record); fscanf(world_file,"%d",&(default_object_ID)); read_record(world_file, record); fscanf(world_file,"%lf",&(zone[0].area)); read_record(world_file, record); fscanf(world_file,"%lf",&(zone[0].slope)); read_record(world_file, record); fscanf(world_file,"%lf",&(zone[0].aspect)); read_record(world_file, record); fscanf(world_file,"%lf",&(zone[0].precip_lapse_rate)); read_record(world_file, record); fscanf(world_file,"%lf",&(zone[0].e_horizon)); read_record(world_file, record); fscanf(world_file,"%lf",&(zone[0].w_horizon)); read_record(world_file, record); fscanf(world_file,"%d",&(zone[0].num_base_stations)); read_record(world_file, record); /*--------------------------------------------------------------*/ /* convert from degrees to radians for slope and aspects */ /*--------------------------------------------------------------*/ zone[0].aspect = zone[0].aspect * DtoR; zone[0].slope = zone[0].slope * DtoR; /*--------------------------------------------------------------*/ /* Define cos and sine of slopes and aspects. */ /*--------------------------------------------------------------*/ zone[0].cos_aspect = cos(zone[0].aspect); zone[0].cos_slope = cos(zone[0].slope); zone[0].sin_aspect = sin(zone[0].aspect); zone[0].sin_slope = sin(zone[0].slope); /*--------------------------------------------------------------*/ /* Initialize accumulator variables */ /*--------------------------------------------------------------*/ zone[0].acc_month.K_direct = 0.0; zone[0].acc_month.K_diffuse = 0.0; zone[0].acc_month.tmax = 0.0; zone[0].acc_month.tmin = 0.0; zone[0].acc_month.precip = 0.0; zone[0].acc_month.length = 0; /*--------------------------------------------------------------*/ /* Define hourly array zone */ /*--------------------------------------------------------------*/ zone[0].hourly = (struct zone_hourly_object *) alloc( sizeof( struct zone_hourly_object ), "hourly","zone_hourly"); /*--------------------------------------------------------------*/ /* Assign defaults for this zone */ /*--------------------------------------------------------------*/ zone[0].defaults = (struct zone_default **) alloc( sizeof(struct zone_default *),"defaults", "construct_zone" ); i = 0; while (defaults[0].zone[i].ID != default_object_ID) { i++; /*--------------------------------------------------------------*/ /* Report an error if no match was found. Otherwise assign */ /* the default to point to this zone. */ /*--------------------------------------------------------------*/ if ( i>= defaults[0].num_zone_default_files ){ fprintf(stderr, "\nFATAL ERROR: in construct_zone, zone default ID %d not found.\n", default_object_ID); exit(EXIT_FAILURE); } } /* end-while */ zone[0].defaults[0] = &defaults[0].zone[i]; if ( command_line[0].verbose_flag == -3 ){ printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); printf("Constructing zone base stations %d \n", zone[0].ID); } /*--------------------------------------------------------------*/ /* Allocate a list of base stations for this zone. */ /*--------------------------------------------------------------*/ zone[0].base_stations = (struct base_station_object **) alloc(zone[0].num_base_stations * sizeof(struct base_station_object *), "base_stations","construct_zone" ); /*--------------------------------------------------------------*/ /* NON NETCDF BASE STATIONS */ /*--------------------------------------------------------------*/ /* Read each base_station ID and then point to that base station */ /*--------------------------------------------------------------*/ if (command_line[0].gridded_netcdf_flag == 0){ for (i = 0; i < zone[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. */ /* */ /*--------------------------------------------------------------*/ zone[0].base_stations[i] = assign_base_station( base_stationID, *num_world_base_stations, world_base_stations); } /*end for*/ } else { fscanf(world_file, "%d", &(dum)); read_record(world_file, record); } /*--------------------------------------------------------------*/ /* NETCDF BASE STATIONS */ /*--------------------------------------------------------------*/ /* Construct the list of base stations. */ /*--------------------------------------------------------------*/ if (command_line[0].dclim_flag == 0) { if(command_line[0].gridded_netcdf_flag == 1){ /*--------------------------------------------------------------*/ /* Construct the base_stations. */ /*--------------------------------------------------------------*/ if ( command_line[0].verbose_flag == -3 ){ printf("Constructing base stations from %s: zoney=%lf zonex=%lf num=%d sdist=%lf base_y=%lf base_x=%lf \n", base_station_ncheader[0].netcdf_tmax_filename, zone[0].y, zone[0].x, *num_world_base_stations, base_station_ncheader[0].sdist, base_y, base_x); printf("STARTING CLOSEST CELL: y=%lf x=%lf \n",base_y,base_x); } /* Identify centerpoint coords for closest netcdf cell to zone x, y */ k = get_netcdf_xy(base_station_ncheader[0].netcdf_tmax_filename, base_station_ncheader[0].netcdf_y_varname, base_station_ncheader[0].netcdf_x_varname, zone[0].y, zone[0].x, base_station_ncheader[0].sdist, &(base_y), &(base_x)); if ( command_line[0].verbose_flag == -3 ){ printf("CLOSEST CELL: y=%lf x=%lf num=%d \n",base_y,base_x,*num_world_base_stations); } if(k == -1){ fprintf(stderr,"Can't locate station data in netcdf for var tmax\n"); exit(0); } /* Assign base station based on closest found coordinates */ if (*num_world_base_stations > 0) { zone[0].base_stations[0] = assign_base_station_xy( base_x, base_y, *num_world_base_stations, &(notfound), world_base_stations); } else notfound = 1; /* If station is not already in list, add it */ if (notfound == 1) { if ( command_line[0].verbose_flag == -3 ){ printf("Starting construct_netcdf_grid: file=%s num=%d \n", world[0].base_station_files[0], *num_world_base_stations); } j = *num_world_base_stations; world_base_stations[j] = construct_netcdf_grid( base_station_ncheader, num_world_base_stations, base_x, base_y, zone[0].z, world[0].start_date, world[0].duration); world[0].num_base_stations = *num_world_base_stations; if ( command_line[0].verbose_flag == -3 ){ printf("Assigning base station: file=%s num=%d lai=%lf notfound=%d lastid=%d numworld=%d ID=%d LAI=%lf \n", world[0].base_station_files[0], *num_world_base_stations, (*(world_base_stations[j])).effective_lai, notfound, base_station_ncheader[0].lastID, world[0].num_base_stations, (*(world_base_stations[j])).ID, (*(world_base_stations[j])).effective_lai); } /* Now link the zone to the newly added base station */ zone[0].base_stations[0] = world_base_stations[j]; if ( command_line[0].verbose_flag == -3 ){ printf("Zone base station: lai=%lf tmin=%lf tmax=%lf rain=%lf wind=%lf \n", (*(zone[0].base_stations[0])).effective_lai, (*(zone[0].base_stations[0])).daily_clim[0].tmin[0], (*(zone[0].base_stations[0])).daily_clim[0].tmax[0], (*(zone[0].base_stations[0])).daily_clim[0].rain[0] //(*(zone[0].base_stations[0])).daily_clim[0].wind[0] ); // T.N } } } } if ( command_line[0].verbose_flag == -3 ){ printf("Ending zone base station: num=%d worldnum=%d \n", *num_world_base_stations, world[0].num_base_stations); printf("------------------------------\n"); } /*--------------------------------------------------------------*/ /* Read in number of patches in this zone. */ /*--------------------------------------------------------------*/ fscanf(world_file,"%d",&(zone[0].num_patches)); read_record(world_file, record); /*--------------------------------------------------------------*/ /* Allocate list of pointers to patch objects . */ /*--------------------------------------------------------------*/ zone[0].patches = ( struct patch_object ** ) alloc( zone[0].num_patches * sizeof( struct patch_object *), "patches","construct_zone"); /*--------------------------------------------------------------*/ /* Initialize any variables that should be initialized at */ /* the start of a simulation run for the zone. */ /* for temperaturature we initialize to 999 so that they will be set on the first day based */ /* on air temperatures on that day - which we don't know at this point */ /*--------------------------------------------------------------*/ zone[0].metv.pa = atm_pres( zone[0].z ); zone[0].metv.tsoil_sum = 0.0; zone[0].metv.tsoil = 0.0; zone[0].metv.tmin_ravg = 3.0; zone[0].metv.vpd_ravg = 900; zone[0].metv.dayl_ravg = 38000; /*--------------------------------------------------------------*/ /* Construct the intervals in this zone. */ /*--------------------------------------------------------------*/ for ( i=0 ; i<zone[0].num_patches ; i++ ){ zone[0].patches[i] = construct_patch( command_line, world_file, *num_world_base_stations, world_base_stations, defaults); zone[0].patches[i][0].zone = zone; } /*end for*/ return(zone); } /*end construct_zone.c*/
void input_new_strata_mult( 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); void *alloc( size_t, char *, char *); /*--------------------------------------------------------------*/ /* Local variable definition. */ /*--------------------------------------------------------------*/ int base_stationID; int i, dtmp, num_lines; int default_object_ID; char record[MAXSTR]; double rootc, ltmp; /*--------------------------------------------------------------*/ /* Read in the next canopy strata record for this patch. */ /*--------------------------------------------------------------*/ fscanf(world_file,"%d",&(default_object_ID)); read_record(world_file, record); fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cover_fraction = ltmp * canopy_strata[0].cover_fraction; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].gap_fraction = ltmp * canopy_strata[0].gap_fraction; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].rootzone.depth = ltmp * canopy_strata[0].rootzone.depth; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].snow_stored = ltmp * canopy_strata[0].snow_stored; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].rain_stored = ltmp * canopy_strata[0].rain_stored; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.cpool = ltmp * canopy_strata[0].cs.cpool; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.leafc = ltmp * canopy_strata[0].cs.leafc; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.dead_leafc = ltmp * canopy_strata[0].cs.dead_leafc; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.leafc_store = ltmp * canopy_strata[0].cs.leafc_store; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.leafc_transfer = ltmp * canopy_strata[0].cs.leafc_transfer; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.live_stemc = ltmp * canopy_strata[0].cs.live_stemc; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.livestemc_store = ltmp * canopy_strata[0].cs.livestemc_store; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.livestemc_transfer = ltmp * canopy_strata[0].cs.livestemc_transfer; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.dead_stemc = ltmp * canopy_strata[0].cs.dead_stemc; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.deadstemc_store = ltmp * canopy_strata[0].cs.deadstemc_store; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.deadstemc_transfer = ltmp * canopy_strata[0].cs.deadstemc_transfer; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.live_crootc = ltmp * canopy_strata[0].cs.live_crootc; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.livecrootc_store = ltmp * canopy_strata[0].cs.livecrootc_store; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.livecrootc_transfer = ltmp * canopy_strata[0].cs.livecrootc_transfer; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.dead_crootc = ltmp * canopy_strata[0].cs.dead_crootc; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.deadcrootc_store = ltmp * canopy_strata[0].cs.deadcrootc_store; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.deadcrootc_transfer = ltmp * canopy_strata[0].cs.deadcrootc_transfer; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.frootc = ltmp * canopy_strata[0].cs.frootc; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.frootc_store = ltmp * canopy_strata[0].cs.frootc_store; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.frootc_transfer = ltmp * canopy_strata[0].cs.frootc_transfer; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].cs.cwdc = ltmp * canopy_strata[0].cs.cwdc; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].epv.prev_leafcalloc = ltmp * canopy_strata[0].epv.prev_leafcalloc; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.npool = ltmp * canopy_strata[0].ns.npool; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.leafn = ltmp * canopy_strata[0].ns.leafn; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.dead_leafn = ltmp * canopy_strata[0].ns.dead_leafn; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.leafn_store = ltmp * canopy_strata[0].ns.leafn_store; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.leafn_transfer = ltmp * canopy_strata[0].ns.leafn_transfer; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.live_stemn = ltmp * canopy_strata[0].ns.live_stemn; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.livestemn_store = ltmp * canopy_strata[0].ns.livestemn_store; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.livestemn_transfer = ltmp * canopy_strata[0].ns.livestemn_transfer; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.dead_stemn = ltmp * canopy_strata[0].ns.dead_stemn; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.deadstemn_store = ltmp * canopy_strata[0].ns.deadstemn_store; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.deadstemn_transfer = ltmp * canopy_strata[0].ns.deadstemn_transfer; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.live_crootn = ltmp * canopy_strata[0].ns.live_crootn; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.livecrootn_store = ltmp * canopy_strata[0].ns.livecrootn_store; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.livecrootn_transfer = ltmp * canopy_strata[0].ns.livecrootn_transfer; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.dead_crootn = ltmp * canopy_strata[0].ns.dead_crootn; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.deadcrootn_store = ltmp * canopy_strata[0].ns.deadcrootn_store; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.deadcrootn_transfer = ltmp * canopy_strata[0].ns.deadcrootn_transfer; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.frootn = ltmp * canopy_strata[0].ns.frootn; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.frootn_store = ltmp * canopy_strata[0].ns.frootn_store; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.frootn_transfer = ltmp * canopy_strata[0].ns.frootn_transfer; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.cwdn = ltmp * canopy_strata[0].ns.cwdn; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].ns.retransn = ltmp * canopy_strata[0].ns.retransn; /*--------------------------------------------------------------*/ /* intialized annual flux variables */ /*--------------------------------------------------------------*/ fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].epv.wstress_days = ltmp * canopy_strata[0].epv.wstress_days; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].epv.max_fparabs = ltmp * canopy_strata[0].epv.max_fparabs; fscanf(world_file,"%lf",&(ltmp)); read_record(world_file, record); if (fabs(ltmp - NULLVAL) >= ONE) canopy_strata[0].epv.min_vwc = ltmp * canopy_strata[0].epv.min_vwc; /*--------------------------------------------------------------*/ /* Assign defaults for this canopy_strata */ /*--------------------------------------------------------------*/ if (default_object_ID > 0) { i=0; while (defaults[0].stratum[i].ID != default_object_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" , default_object_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; /*--------------------------------------------------------------*/ /* 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 { 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); } /*--------------------------------------------------------------*/ /* 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 * canopy_strata[0].num_base_stations; /*--------------------------------------------------------------*/ /* 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*/ } return; } /*end input_new_strata.c*/
struct zone_object *construct_zone( 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) { /*--------------------------------------------------------------*/ /* Local function definition. */ /*--------------------------------------------------------------*/ struct base_station_object *assign_base_station( int , int , struct base_station_object **); struct patch_object *construct_patch( struct command_line_object *, FILE *, int num_world_base_stations, struct base_station_object **world_base_stations, struct default_object *defaults); void *alloc(size_t, char *, char *); double atm_pres( double ); /*--------------------------------------------------------------*/ /* Local variable definition. */ /*--------------------------------------------------------------*/ int base_stationID; int i; int default_object_ID; char record[MAXSTR]; struct zone_object *zone; /*--------------------------------------------------------------*/ /* Allocate a zone object. */ /*--------------------------------------------------------------*/ zone = (struct zone_object *) alloc( 1 * sizeof( struct zone_object ),"zone","construct_zone" ); /*--------------------------------------------------------------*/ /* Read in the next zone record for this hillslope. */ /*--------------------------------------------------------------*/ fscanf(world_file,"%d",&(zone[0].ID)); read_record(world_file, record); fscanf(world_file,"%lf",&(zone[0].x)); read_record(world_file, record); fscanf(world_file,"%lf",&(zone[0].y)); read_record(world_file, record); fscanf(world_file,"%lf",&(zone[0].z)); read_record(world_file, record); fscanf(world_file,"%d",&(default_object_ID)); read_record(world_file, record); fscanf(world_file,"%lf",&(zone[0].area)); read_record(world_file, record); fscanf(world_file,"%lf",&(zone[0].slope)); read_record(world_file, record); fscanf(world_file,"%lf",&(zone[0].aspect)); read_record(world_file, record); fscanf(world_file,"%lf",&(zone[0].precip_lapse_rate)); read_record(world_file, record); fscanf(world_file,"%lf",&(zone[0].e_horizon)); read_record(world_file, record); fscanf(world_file,"%lf",&(zone[0].w_horizon)); read_record(world_file, record); fscanf(world_file,"%d",&(zone[0].num_base_stations)); read_record(world_file, record); /*--------------------------------------------------------------*/ /* convert from degrees to radians for slope and aspects */ /*--------------------------------------------------------------*/ zone[0].aspect = zone[0].aspect * DtoR; zone[0].slope = zone[0].slope * DtoR; /*--------------------------------------------------------------*/ /* Define cos and sine of slopes and aspects. */ /*--------------------------------------------------------------*/ zone[0].cos_aspect = cos(zone[0].aspect); zone[0].cos_slope = cos(zone[0].slope); zone[0].sin_aspect = sin(zone[0].aspect); zone[0].sin_slope = sin(zone[0].slope); /*--------------------------------------------------------------*/ /* Initialize accumulator variables */ /*--------------------------------------------------------------*/ zone[0].acc_month.K_direct = 0.0; zone[0].acc_month.K_diffuse = 0.0; zone[0].acc_month.tmax = 0.0; zone[0].acc_month.tmin = 0.0; zone[0].acc_month.precip = 0.0; zone[0].acc_month.length = 0; /*--------------------------------------------------------------*/ /* Define hourly array zone */ /*--------------------------------------------------------------*/ zone[0].hourly = (struct zone_hourly_object *) alloc( sizeof( struct zone_hourly_object ), "hourly","zone_hourly"); /*--------------------------------------------------------------*/ /* Assign defaults for this zone */ /*--------------------------------------------------------------*/ zone[0].defaults = (struct zone_default **) alloc( sizeof(struct zone_default *),"defaults", "construct_zone" ); i = 0; while (defaults[0].zone[i].ID != default_object_ID) { i++; /*--------------------------------------------------------------*/ /* Report an error if no match was found. Otherwise assign */ /* the default to point to this zone. */ /*--------------------------------------------------------------*/ if ( i>= defaults[0].num_zone_default_files ){ fprintf(stderr, "\nFATAL ERROR: in construct_zone, zone default ID %d not found.\n", default_object_ID); exit(EXIT_FAILURE); } } /* end-while */ zone[0].defaults[0] = &defaults[0].zone[i]; /*--------------------------------------------------------------*/ /* Allocate a list of base stations for this zone. */ /*--------------------------------------------------------------*/ zone[0].base_stations = (struct base_station_object **) alloc(zone[0].num_base_stations * sizeof(struct base_station_object *), "base_stations","construct_zone" ); /*--------------------------------------------------------------*/ /* Read each base_station ID and then point to that base station */ /*--------------------------------------------------------------*/ for (i=0 ; i<zone[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. */ /* */ /*--------------------------------------------------------------*/ zone[0].base_stations[i] = assign_base_station( base_stationID, num_world_base_stations, world_base_stations); } /*end for*/ /*--------------------------------------------------------------*/ /* Read in number of patches in this zone. */ /*--------------------------------------------------------------*/ fscanf(world_file,"%d",&(zone[0].num_patches)); read_record(world_file, record); /*--------------------------------------------------------------*/ /* Allocate list of pointers to patch objects . */ /*--------------------------------------------------------------*/ zone[0].patches = ( struct patch_object ** ) alloc( zone[0].num_patches * sizeof( struct patch_object *), "patches","construct_zone"); /*--------------------------------------------------------------*/ /* Initialize any variables that should be initialized at */ /* the start of a simulation run for the zone. */ /* for temperaturature we initialize to 999 so that they will be set on the first day based */ /* on air temperatures on that day - which we don't know at this point */ /*--------------------------------------------------------------*/ zone[0].metv.pa = atm_pres( zone[0].z ); zone[0].metv.tsoil_sum = 0.0; zone[0].metv.tsoil = 0.0; zone[0].metv.tmin_ravg = 3.0; zone[0].metv.vpd_ravg = 900; zone[0].metv.dayl_ravg = 38000; /*--------------------------------------------------------------*/ /* Construct the intervals in this zone. */ /*--------------------------------------------------------------*/ for ( i=0 ; i<zone[0].num_patches ; i++ ){ zone[0].patches[i] = construct_patch( command_line, world_file, num_world_base_stations, world_base_stations, defaults); zone[0].patches[i][0].zone = zone; } /*end for*/ return(zone); } /*end construct_zone.c*/
struct canopy_strata_object *construct_canopy_strata( struct command_line_object *command_line, FILE *world_file, struct patch_object *patch, int num_world_base_stations, struct base_station_object **world_base_stations, struct default_object *defaults) { /*--------------------------------------------------------------*/ /* 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); void *alloc(size_t, char *, char *); /*--------------------------------------------------------------*/ /* Local variable definition. */ /*--------------------------------------------------------------*/ int base_stationID; int i; double sai, rootc; int default_object_ID; int spinup_default_object_ID; char record[MAXSTR]; struct canopy_strata_object *canopy_strata; /*--------------------------------------------------------------*/ /* Allocate a canopy_strata object. */ /*--------------------------------------------------------------*/ canopy_strata = (struct canopy_strata_object *) alloc( 1 * sizeof( struct canopy_strata_object ),"canopy_strata", "construct_canopy_strata" ); /*--------------------------------------------------------------*/ /* Read in the next canopy strata record for this patch. */ /*--------------------------------------------------------------*/ fscanf(world_file,"%d",&(canopy_strata[0].ID)); read_record(world_file, record); fscanf(world_file,"%d",&(default_object_ID)); read_record(world_file, record); if (command_line[0].vegspinup_flag > 0){ fscanf(world_file,"%d",&(spinup_default_object_ID)); read_record(world_file, record); } fscanf(world_file,"%lf",&(canopy_strata[0].cover_fraction)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].gap_fraction)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].rootzone.depth)); read_record(world_file, record); if (command_line[0].tmp_value > ZERO) canopy_strata[0].rootzone.depth *= command_line[0].tmp_value; fscanf(world_file,"%lf",&(canopy_strata[0].snow_stored)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].rain_stored)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].cs.cpool)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].cs.leafc)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].cs.dead_leafc)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].cs.leafc_store)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].cs.leafc_transfer)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].cs.live_stemc)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].cs.livestemc_store)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].cs.livestemc_transfer)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].cs.dead_stemc)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].cs.deadstemc_store)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].cs.deadstemc_transfer)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].cs.live_crootc)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].cs.livecrootc_store)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].cs.livecrootc_transfer)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].cs.dead_crootc)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].cs.deadcrootc_store)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].cs.deadcrootc_transfer)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].cs.frootc)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].cs.frootc_store)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].cs.frootc_transfer)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].cs.cwdc)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].epv.prev_leafcalloc)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].ns.npool)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].ns.leafn)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].ns.dead_leafn)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].ns.leafn_store)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].ns.leafn_transfer)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].ns.live_stemn)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].ns.livestemn_store)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].ns.livestemn_transfer)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].ns.dead_stemn)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].ns.deadstemn_store)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].ns.deadstemn_transfer)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].ns.live_crootn)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].ns.livecrootn_store)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].ns.livecrootn_transfer)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].ns.dead_crootn)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].ns.deadcrootn_store)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].ns.deadcrootn_transfer)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].ns.frootn)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].ns.frootn_store)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].ns.frootn_transfer)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].ns.cwdn)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].ns.retransn)); read_record(world_file, record); if (command_line[0].vegspinup_flag > 0){ canopy_strata[0].target.lai = NULLVAL; canopy_strata[0].target.total_stemc = NULLVAL; canopy_strata[0].target.met = 2; } /*--------------------------------------------------------------*/ /* intialized annual flux variables */ /*--------------------------------------------------------------*/ fscanf(world_file,"%d",&(canopy_strata[0].epv.wstress_days)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].epv.max_fparabs)); read_record(world_file, record); fscanf(world_file,"%lf",&(canopy_strata[0].epv.min_vwc)); read_record(world_file, record); /*--------------------------------------------------------------*/ /* Assign defaults for this canopy_strata */ /*--------------------------------------------------------------*/ canopy_strata[0].defaults = (struct stratum_default **) alloc( sizeof(struct stratum_default *),"defaults", "construct_canopy_strata" ); i = 0; while (defaults[0].stratum[i].ID != default_object_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" , default_object_ID); exit(EXIT_FAILURE); } } /* end-while */ canopy_strata[0].defaults[0] = &defaults[0].stratum[i]; /*--------------------------------------------------------------*/ /* if spinup module is called assign spinup defaults */ /*--------------------------------------------------------------*/ if (command_line[0].vegspinup_flag > 0) { canopy_strata[0].spinup_defaults = (struct spinup_default **) alloc( sizeof(struct spinup_default *),"defaults", "construct_stratum" ); i = 0; while (defaults[0].spinup[i].ID != spinup_default_object_ID) { i++; /*--------------------------------------------------------------*/ /* Report an error if no match was found. Otherwise assign */ /* the default to point to this patch. */ /*--------------------------------------------------------------*/ if ( i>= defaults[0].num_spinup_default_files ){ fprintf(stderr, "\nFATAL ERROR: in construct_stratum, spinup default ID %d not found for patch %d\n" , spinup_default_object_ID, patch[0].ID); exit(EXIT_FAILURE); } } /* end-while */ canopy_strata[0].spinup_defaults[0] = &defaults[0].spinup[i]; } /*--------------------------------------------------------------*/ /* zero all non tree stem and wood variables */ /*--------------------------------------------------------------*/ if (canopy_strata[0].defaults[0][0].epc.veg_type != TREE) { canopy_strata[0].cs.live_stemc = 0.0; canopy_strata[0].cs.dead_stemc = 0.0; canopy_strata[0].cs.live_crootc = 0.0; canopy_strata[0].cs.dead_crootc = 0.0; canopy_strata[0].cs.livestemc_store = 0.0; canopy_strata[0].cs.deadstemc_store = 0.0; canopy_strata[0].cs.livestemc_transfer = 0.0; canopy_strata[0].cs.deadstemc_transfer = 0.0; canopy_strata[0].cs.livecrootc_store = 0.0; canopy_strata[0].cs.deadcrootc_store = 0.0; canopy_strata[0].cs.livecrootc_transfer = 0.0; canopy_strata[0].cs.deadcrootc_transfer = 0.0; canopy_strata[0].cs.cwdc = 0.0; canopy_strata[0].ns.live_stemn = 0.0; canopy_strata[0].ns.dead_stemn = 0.0; canopy_strata[0].ns.live_crootn = 0.0; canopy_strata[0].ns.dead_crootn = 0.0; canopy_strata[0].ns.livestemn_store = 0.0; canopy_strata[0].ns.deadstemn_store = 0.0; canopy_strata[0].ns.livestemn_transfer = 0.0; canopy_strata[0].ns.deadstemn_transfer = 0.0; canopy_strata[0].ns.livecrootn_store = 0.0; canopy_strata[0].ns.deadcrootn_store = 0.0; canopy_strata[0].ns.livecrootn_transfer = 0.0; canopy_strata[0].ns.deadcrootn_transfer = 0.0; canopy_strata[0].ns.cwdn = 0.0; } /*--------------------------------------------------------------*/ /* zero other carbon stores for non veg */ /*--------------------------------------------------------------*/ if (canopy_strata[0].defaults[0][0].epc.veg_type == NON_VEG) { canopy_strata[0].cs.cpool = 0.0; canopy_strata[0].cs.leafc = 0.0; canopy_strata[0].cs.dead_leafc = 0.0; canopy_strata[0].cs.leafc_store = 0.0; canopy_strata[0].cs.leafc_transfer = 0.0; canopy_strata[0].cs.frootc = 0.0; canopy_strata[0].cs.frootc_store = 0.0; canopy_strata[0].cs.frootc_transfer = 0.0; canopy_strata[0].ns.npool = 0.0; canopy_strata[0].ns.leafn = 0.0; canopy_strata[0].ns.dead_leafn = 0.0; canopy_strata[0].ns.leafn_store = 0.0; canopy_strata[0].ns.leafn_transfer = 0.0; canopy_strata[0].ns.frootn = 0.0; canopy_strata[0].ns.frootn_store = 0.0; canopy_strata[0].ns.frootn_transfer = 0.0; } /*--------------------------------------------------------------*/ /* 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].NO3_stored = 0.0; // this is for the NO3 deposition on leaves /*--------------------------------------------------------------*/ /* initialize accumulator variables */ /*--------------------------------------------------------------*/ canopy_strata[0].acc_year.lai = 0.0; canopy_strata[0].acc_year.psn = 0.0; canopy_strata[0].acc_year.lwp = 0.0; canopy_strata[0].acc_year.minNSC = -999; canopy_strata[0].acc_year.length = 0; canopy_strata[0].acc_month.lai = 0.0; canopy_strata[0].acc_month.psn = 0.0; canopy_strata[0].acc_month.lwp = 0.0; canopy_strata[0].acc_month.length = 0; canopy_strata[0].cs.Tacc = 20.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) { sai = 0.55*(1.0-exp(-0.175*(canopy_strata[0].cs.live_stemc+canopy_strata[0].cs.dead_stemc))); canopy_strata[0].epv.proj_pai = max(canopy_strata[0].epv.proj_lai + sai, 0.0); canopy_strata[0].epv.all_pai = max(canopy_strata[0].epv.all_lai + sai, 0.0); } 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 */ /* for static non-grow version use the worldfile rooting depth */ /* as read in above */ /*--------------------------------------------------------------*/ 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); } } } /*--------------------------------------------------------------*/ /* initialize leaf out for non-grow version */ /*--------------------------------------------------------------*/ if (( command_line[0].grow_flag == 0) && (canopy_strata[0].defaults[0][0].epc.veg_type != NON_VEG) ){ /* canopy_strata[0].cs.leafc_transfer = canopy_strata[0].phen.leaflitfallc; canopy_strata[0].ns.leafn_transfer = canopy_strata[0].phen.leaflitfallc * canopy_strata[0].ns.leafn / canopy_strata[0].cs.leafc; canopy_strata[0].cs.leafc_store = 0.0; canopy_strata[0].ns.leafn_store = 0.0; */ } /*--------------------------------------------------------------*/ /* set phenology timing if static allocation */ /* and initialize for dynamic runs */ /*--------------------------------------------------------------*/ 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; /*--------------------------------------------------------------*/ /* set critical soil moisture (at stomatal closure) */ /* psi_close is converted to m water tension from MPa using */ /* 1m water tension = 10000 Pa */ /* = 0.01 Mpa */ /*--------------------------------------------------------------*/ canopy_strata[0].epv.crit_vwc = pow( ((-1.0 * 100.0 * 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 ); /*--------------------------------------------------------------*/ /* initialize runnning average of psi **** should actually calc */ /* current day psi */ /*--------------------------------------------------------------*/ canopy_strata[0].epv.psi_ravg = canopy_strata[0].defaults[0][0].epc.psi_open; /*--------------------------------------------------------------*/ /* for now initialize these accumuling variables */ /* note that age really should be a state variable */ /* and initialized in the worldfile */ /*--------------------------------------------------------------*/ canopy_strata[0].cs.num_resprout = 0; canopy_strata[0].cs.age = 0; canopy_strata[0].epv.wstress_days = 0; canopy_strata[0].epv.max_fparabs = 0.0; canopy_strata[0].epv.min_vwc = 1.0; /*--------------------------------------------------------------*/ /* Read in the number of strata base stations */ /*--------------------------------------------------------------*/ fscanf(world_file,"%d",&(canopy_strata[0].num_base_stations)); read_record(world_file, record); /*--------------------------------------------------------------*/ /* 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_station*/ /*--------------------------------------------------------------*/ 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*/ return(canopy_strata); } /*end construct_canopy_strata.c*/