diff --git a/.cproject b/.cproject index b1fb9794..9d9bb911 100644 --- a/.cproject +++ b/.cproject @@ -1,87 +1,40 @@ - - + + - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - @@ -102,14 +52,14 @@ + + + - - - - - - - + + + + diff --git a/.project b/.project index 1003b227..9a6898d1 100644 --- a/.project +++ b/.project @@ -22,5 +22,6 @@ org.eclipse.cdt.core.cnature org.eclipse.cdt.managedbuilder.core.managedBuildNature org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + org.eclipse.cdt.core.ccnature diff --git a/README.md b/README.md index a091d1b1..db6821eb 100644 --- a/README.md +++ b/README.md @@ -34,13 +34,14 @@ Other tasks: ``` ``` -> Usage: stepwat [-d startdir] [-f files.in] [-q] [-s] [-e] [-o] [-g] +> Usage: stepwat [-d startdir] [-f files.in] [-q] [-s] [-e] [-o] [-i] [-g] > -d : supply working directory (default=.) > -f : supply list of input files (default=files.in) > -q : quiet mode, don't print message to check logfile. > -s : use SOILWAT model for resource partitioning. > -e : echo initialization results to logfile -> -o : print all the soilwat output in addition to the stepwat output +> -o : write SOILWAT output to output files. Contains average over all iterations and standard deviation +> -i : write soilwat output to output files for each iteration > -g : use gridded mode ``` @@ -68,6 +69,13 @@ cd testing.sagebrush.master/Stepwat_Inputs/ ./stepwat -f files.in ``` +* Run STEPPE (get SOILWAT output for all iterations and average) + +``` +cd testing.sagebrush.master/Stepwat_Inputs/ +./stepwat -f files.in -o -i -s +``` +
@@ -79,4 +87,3 @@ Contributors are encouraged, however, to update local clones to [point to the ne ``` git remote set-url origin https://github.com/Burke-Lauenroth-Lab/STEPWAT2.git ``` - diff --git a/ST_defines.h b/ST_defines.h index 1895c7e5..e2e47f94 100644 --- a/ST_defines.h +++ b/ST_defines.h @@ -18,6 +18,11 @@ /* see #include "ST_structs.h" below */ + +// TRUE / FALSE +#define TRUE 1 +#define FALSE 0 + /*************************************************** * Basic definitions ***************************************************/ diff --git a/ST_environs.c b/ST_environs.c index ac4eca23..9bf06510 100644 --- a/ST_environs.c +++ b/ST_environs.c @@ -90,7 +90,7 @@ static void _make_ppt( void) { * but we still pass through this code to set the * Dry/Wet/Normal state. * KAP 1/26/2017 The above note by CB is not correct. Env.ppt - * is set in _sxw_set_environs, but gsppt is not, it is + * is set in _sxw_set_environs, but gsppt is not, it is * set below. When using SOILWAT or not, the gsspt, ppt.dry, * and ppt.wet is currently fixed each year and read from env.in * We should consider calculating gsspt in the _sxw_set_environs @@ -308,4 +308,3 @@ static void _make_disturbance( void) { } } - diff --git a/ST_functions.h b/ST_functions.h index 5f3d603d..c2f501a8 100644 --- a/ST_functions.h +++ b/ST_functions.h @@ -55,6 +55,9 @@ void Indiv_SortSize( const byte sorttype, int Indiv_CompSize_A( const void *key1, const void *key2); int Indiv_CompSize_D( const void *key1, const void *key2); +float get_running_avg(float old_val, float val_to_add); +float get_running_sqr(float old_val, float val_to_add, float run_avg); + #ifdef DEBUG_MEM void RGroup_SetMemoryRefs(void); diff --git a/ST_grid.c b/ST_grid.c index 1461c218..8ef16e82 100644 --- a/ST_grid.c +++ b/ST_grid.c @@ -6,8 +6,8 @@ // History: // (5/24/2013) -- INITIAL CODING - DLM // -// WARNING: This module deals with a LARGE amount of dynamic memory allocation/deallocation (there can be potentially hundreds of thousands of allocations/frees called by this code depending on settings ran). -// Be very wary when editing it as even small changes could possibly cause massive memory errors/leaks to occur. In particular be careful when copy/freeing the linked list of individuals (I would suggest just using the code I wrote for this as it works and it's pretty easy to screw it up). +// WARNING: This module deals with a LARGE amount of dynamic memory allocation/deallocation (there can be potentially hundreds of thousands of allocations/frees called by this code depending on settings ran). +// Be very wary when editing it as even small changes could possibly cause massive memory errors/leaks to occur. In particular be careful when copy/freeing the linked list of individuals (I would suggest just using the code I wrote for this as it works and it's pretty easy to screw it up). // Always keep in mind that for every time memory is allocated (every time alloc or calloc is called), a corresponding free is required. I would recommend valgrind or a similar program to debug memory errors as doing it without some kind of tool would be crazy. /********************************************************/ /* @@ -240,7 +240,7 @@ void stat_Init_Accumulators(void); //functions from sxw.c //void free_sxw_memory( void ); -void free_all_sxw_memory(void); +//void free_all_sxw_memory(void); void load_sxw_memory(RealD * grid_roots_max, RealD* grid_rootsXphen, RealD* grid_roots_active, RealD* grid_roots_active_rel, RealD* grid_roots_active_sum, RealD* grid_phen, RealD* grid_prod_bmass, @@ -353,7 +353,7 @@ static int _load_bar(char* prefix, clock_t start, int x, int n, int r, int w) int i; - printf("\r"); //we output a carriage-return character to put us back at the beginning of the line + printf("\r"); //we output a carriage-return character to put us back at the beginning of the line if (prefix != NULL) printf("%s", prefix); @@ -383,7 +383,7 @@ static int _load_bar(char* prefix, clock_t start, int x, int n, int r, int w) printf(" "); printf("]"); - fflush(stdout); //we do this to flush (ie. print) the output, since stdout typically waits for a newline character before flushing + fflush(stdout); //we do this to flush (ie. print) the output, since stdout typically waits for a newline character before flushing return result; } @@ -1464,7 +1464,7 @@ static void _free_grid_memory(void) /***********************************************************/ static void _free_spinup_memory(void) { - // frees spinup memory + // frees spinup memory GrpIndex c; SppIndex s; @@ -2307,9 +2307,9 @@ static void _init_soil_layers(int cell, int isSpinup) Mem_Free(SW_Site.lyr); SW_Site.n_layers = grid_Soils[i].num_layers; - SW_Site.n_evap_lyrs = SW_Site.n_transp_lyrs_forb = - SW_Site.n_transp_lyrs_tree = SW_Site.n_transp_lyrs_shrub = - SW_Site.n_transp_lyrs_grass = 0; + SW_Site.n_evap_lyrs = SW_Site.n_transp_lyrs[SW_FORBS] = + SW_Site.n_transp_lyrs[SW_TREES] = SW_Site.n_transp_lyrs[SW_SHRUB] = + SW_Site.n_transp_lyrs[SW_GRASS] = 0; SW_Site.lyr = Mem_Calloc(SW_Site.n_layers + SW_Site.deepdrain, sizeof(SW_LAYER_INFO *), "_init_grid_globals()"); @@ -2362,19 +2362,19 @@ static void _init_soil_layers(int cell, int isSpinup) SW_Site.lyr[j]->soilMatric_density = grid_Soils[i].lyr[j].data[0]; SW_Site.lyr[j]->fractionVolBulk_gravel = grid_Soils[i].lyr[j].data[1]; SW_Site.lyr[j]->evap_coeff = grid_Soils[i].lyr[j].data[2]; - SW_Site.lyr[j]->transp_coeff_grass = grid_Soils[i].lyr[j].data[3]; - SW_Site.lyr[j]->transp_coeff_shrub = grid_Soils[i].lyr[j].data[4]; - SW_Site.lyr[j]->transp_coeff_tree = grid_Soils[i].lyr[j].data[5]; - SW_Site.lyr[j]->transp_coeff_forb = grid_Soils[i].lyr[j].data[6]; + SW_Site.lyr[j]->transp_coeff[3] = grid_Soils[i].lyr[j].data[3]; + SW_Site.lyr[j]->transp_coeff[1] = grid_Soils[i].lyr[j].data[4]; + SW_Site.lyr[j]->transp_coeff[0] = grid_Soils[i].lyr[j].data[5]; + SW_Site.lyr[j]->transp_coeff[2] = grid_Soils[i].lyr[j].data[6]; SW_Site.lyr[j]->fractionWeightMatric_sand = grid_Soils[i].lyr[j].data[7]; SW_Site.lyr[j]->fractionWeightMatric_clay = grid_Soils[i].lyr[j].data[8]; SW_Site.lyr[j]->impermeability = grid_Soils[i].lyr[j].data[9]; - SW_Site.lyr[j]->my_transp_rgn_tree = 0; - SW_Site.lyr[j]->my_transp_rgn_forb = 0; - SW_Site.lyr[j]->my_transp_rgn_shrub = 0; - SW_Site.lyr[j]->my_transp_rgn_grass = 0; + SW_Site.lyr[j]->my_transp_rgn[0] = 0; + SW_Site.lyr[j]->my_transp_rgn[2] = 0; + SW_Site.lyr[j]->my_transp_rgn[1] = 0; + SW_Site.lyr[j]->my_transp_rgn[3] = 0; SW_Site.lyr[j]->sTemp = grid_Soils[i].lyr[j].data[10]; if (evap_ok) @@ -2386,29 +2386,29 @@ static void _init_soil_layers(int cell, int isSpinup) } if (transp_ok_tree) { - if (GT(SW_Site.lyr[j]->transp_coeff_tree, 0.0)) - SW_Site.n_transp_lyrs_tree++; + if (GT(SW_Site.lyr[j]->transp_coeff[0], 0.0)) + SW_Site.n_transp_lyrs[SW_TREES]++; else transp_ok_tree = FALSE; } if (transp_ok_shrub) { - if (GT(SW_Site.lyr[j]->transp_coeff_shrub, 0.0)) - SW_Site.n_transp_lyrs_shrub++; + if (GT(SW_Site.lyr[j]->transp_coeff[1], 0.0)) + SW_Site.n_transp_lyrs[SW_SHRUB]++; else transp_ok_shrub = FALSE; } if (transp_ok_grass) { - if (GT(SW_Site.lyr[j]->transp_coeff_grass, 0.0)) - SW_Site.n_transp_lyrs_grass++; + if (GT(SW_Site.lyr[j]->transp_coeff[3], 0.0)) + SW_Site.n_transp_lyrs[SW_GRASS]++; else transp_ok_grass = FALSE; } if (transp_ok_forb) { - if (GT(SW_Site.lyr[j]->transp_coeff_forb, 0.0)) - SW_Site.n_transp_lyrs_forb++; + if (GT(SW_Site.lyr[j]->transp_coeff[2], 0.0)) + SW_Site.n_transp_lyrs[SW_FORBS]++; else transp_ok_forb = FALSE; } @@ -2657,7 +2657,7 @@ static void _read_seed_dispersal_in(void) grid_SD[s][cell].prob[k] = pd; grid_SD[s][cell].size++; k++; - //fprintf(stderr, "cell: %d; i: %d; j: %d; dist: %f; pd: %f %d %d\n", i + ( (j-1) * grid_Cols) - 1, i, j, d, pd, row, col); + //fprintf(stderr, "cell: %d; i: %d; j: %d; dist: %f; pd: %f %d %d\n", i + ( (j-1) * grid_Cols) - 1, i, j, d, pd, row, col); } } //fprintf(stderr, "size %d index %d maxsize %d\n", grid_SD[cell].size, cell, maxCells); @@ -2790,7 +2790,7 @@ static void _do_seed_dispersal(void) float Pmin = grid_Species[s][i].sd_Pmin, Pmax = grid_Species[s][i].sd_Pmax; - //p3 = Pmin, if LYPPT < PPTdry + //p3 = Pmin, if LYPPT < PPTdry //p3 = 1 - (1-Pmin) * exp(-d * (LYPPT - PPTdry)) with d = - ln((1 - Pmax)/(1 - Pmin)) / (PPTwet - PPTdry), if PPTdry <= LYPPT <= PPTwet //p3 = Pmax, if LYPPT > PPTwet @@ -3092,7 +3092,7 @@ static void _read_init_species(void) int i, j, num, cell, do_copy, copy_cell, use_SpinUp, seeds_Avail; char buf[4096]; - //open the file/do the reading + //open the file/do the reading f = OpenFile(grid_files[5], "r"); //grid_files[5] is the grid_initSpecies.csv file GetALine2(f, buf, 4096); // gets rid of the first line (since it just defines the columns)... it's only there for user readability diff --git a/ST_indivs.c b/ST_indivs.c index e4addd91..d6ca9a42 100644 --- a/ST_indivs.c +++ b/ST_indivs.c @@ -208,7 +208,7 @@ void indiv_proportion_Kill(IndivType *ndv, int killType, RealF proportKilled) /* HISTORY */ /* Chris Bennett @ LTER-CSU 6/15/2000 * 09/23/15 -AT -Added proportionKilled - * Nov 4 2015- AT - Modified code for doing proportional kill for annual as well and not deleting species + * Nov 4 2015- AT - Modified code for doing proportional kill for annual as well and not deleting species * and indi from memory only adjusting their real size */ /*------------------------------------------------------*/ @@ -486,4 +486,3 @@ int Indiv_CompSize_D( const void *key1, const void *key2) { return r; } - diff --git a/ST_main.c b/ST_main.c index fe2a8eb5..166e1dea 100644 --- a/ST_main.c +++ b/ST_main.c @@ -23,15 +23,21 @@ #include "generic.h" #include "filefuncs.h" #include "myMemory.h" +#include "SW_VegProd.h" #ifdef STEPWAT #include "sxw_funcs.h" #include "sxw.h" + #include "sw_src/SW_Output.h" + #include "sw_src/rands.h" extern SXW_t SXW; #endif extern Bool isPartialSoilwatOutput; +extern Bool storeAllIterations; +extern SW_VEGPROD SW_VegProd; +SW_FILE_STATUS SW_File_Status; /************* External Function Declarations **************/ /***********************************************************/ @@ -40,7 +46,6 @@ extern Bool isPartialSoilwatOutput; void rgroup_Establish( void) ; void rgroup_IncrAges( void); void rgroup_PartResources( void); - //void rgroup_ResPartIndiv(void); void mort_Main( Bool *killed); void mort_EndOfYear( void); @@ -56,10 +61,12 @@ extern Bool isPartialSoilwatOutput; void stat_Collect( Int year ) ; void stat_Collect_GMort ( void ) ; void stat_Collect_SMort ( void ) ; - //void stat_Output_YrMorts( void ) ; + void stat_Output_AllMorts( void) ; void stat_Output_AllBmass(void) ; - + + void stat_Output_AllSoilwatVariables(void); + void runGrid( void ); //for the grid... declared in ST_grid.c void _kill_annuals(void); @@ -85,19 +92,19 @@ extern Bool isPartialSoilwatOutput; /*************** Local Function Declarations ***************/ /***********************************************************/ void Plot_Initialize( void); -//void Debug_AddByIter( Int iter); -//void Debug_AddByYear( Int year); -/*void chkmem(void);*/ + static void usage(void) { char *s ="STEPPE plant community dynamics (SGS-LTER Jan-04).\n" "Usage: steppe [-d startdir] [-f files.in] [-q] [-s] [-e] [-o] [-g]\n" " -d : supply working directory (default=.)\n" " -f : supply list of input files (default=files.in)\n" " -q : quiet mode, don't print message to check logfile.\n" + " -p : prints progress bar\n" " -s : use SOILWAT model for resource partitioning.\n" " -e : echo initialization results to logfile\n" - " -o : print all the soilwat output as well like standalone soilwat running\n" - " -g : use gridded mode\n"; + " -o : print all the soilwat output\n" + " -g : use gridded mode\n" + " -i : print SOILWAT output for each iteration\n"; // dont need to set -o flag to use this flag fprintf(stderr,"%s", s); exit(0); } @@ -106,7 +113,6 @@ static void check_log(void); /* a couple of debugging routines */ void check_sizes(const char *); -//static void check_sizes_final(void ); Bool QuietMode; @@ -134,42 +140,10 @@ Bool DuringSpinup; Bool EchoInits; Bool UseProgressBar; -/* Added By: AKT 06/27/2016 - * Function for printing all the SOILWAT output in the STEPWAT, - * it will work in both grid and non-grid version - * - */ -void print_soilwat_output(char* str) -{ - isPartialSoilwatOutput = FALSE; - - printf( "inside stepwat main setting files options for soilwat full output, so now isPartialSoilwatOutput=%d \n", isPartialSoilwatOutput); - - int argc_soilwat = 3; - char **array; - array = malloc(sizeof(char*) * (argc_soilwat + 1)); - - array[0] = "sw_v31"; //Just for name sake SOILWAT exe name given here, though it will never getting use - array[1] = "-f"; - array[2] = Str_Dup(str); - array[3] = NULL;/* end of array so later you can do while (array[i++]!=NULL) {...} */ - - printf( "inside stepwat main setting files options for soilwat: argc=%d array[0]=%s ,array[1]=%s,array[2]=%s \n ", - argc_soilwat, array[0], array[1], array[2]); - - main_function(argc_soilwat, array); - - isPartialSoilwatOutput = TRUE; - - printf( "Soilwat main function executed successfully and now isPartialSoilwatOutput=%d \n", isPartialSoilwatOutput); - -} - /******************** Begin Model Code *********************/ /***********************************************************/ int main(int argc, char **argv) { - IntS year, iter, incr, g, s; - IndivType *i; + IntS year, iter, incr; Bool killedany; logged = FALSE; @@ -177,11 +151,12 @@ int main(int argc, char **argv) { /* provides a way to inform user that something * was logged. see generic.h */ - init_args(argc, argv); + isPartialSoilwatOutput = TRUE; // dont want to get soilwat output unless -o flag + storeAllIterations = FALSE; // dont want to store all soilwat output iterations unless -i flag - printf("STEPWAT init_args() executed successfully \n "); + init_args(argc, argv); // read input arguments and intialize proper flags - isPartialSoilwatOutput = TRUE; + printf("STEPWAT init_args() executed successfully \n"); if (UseGrid == TRUE) { runGrid(); @@ -190,11 +165,10 @@ int main(int argc, char **argv) { parm_Initialize(0); - if (UseSoilwat) + if (UseSoilwat){ SXW_Init(TRUE, NULL); - - //Connect to ST db and insert static data - //ST_connect("Output/stdebug"); + SW_OUT_set_ncol(); // set number of columns + } incr = (IntS) ((float) Globals.runModelIterations / 10); if (incr == 0) @@ -202,7 +176,6 @@ int main(int argc, char **argv) { /* --- Begin a new iteration ------ */ for (iter = 1; iter <= Globals.runModelIterations; iter++) { - if (progfp == stderr) { if (iter % incr == 0) fprintf(progfp, "."); @@ -210,6 +183,7 @@ int main(int argc, char **argv) { fprintf(progfp, "%d\n", iter); } + if (BmassFlags.yearly || MortFlags.yearly) parm_Initialize(iter); @@ -217,17 +191,11 @@ int main(int argc, char **argv) { RandSeed(Globals.randseed); Globals.currIter = iter; - /*Debug_AddByIter( iter); */ - /* ------ Begin running the model ------ */ - for (year = 1; year <= Globals.runModelYears; year++) { - - /*Debug_AddByYear(year);*/ - - /* printf("Iter=%d, Year=%d\n", iter, year); */ + for (year = 1; year <= Globals.runModelYears; year++){ Globals.currYear = year; - rgroup_Establish(); + rgroup_Establish(); Env_Generate(); @@ -243,7 +211,7 @@ int main(int argc, char **argv) { rgroup_IncrAges(); - // Added functions for Grazing and mort_end_year as proportional killing effect before exporting biomass end of the year + // Added functions for Grazing and mort_end_year as proportional killing effect before exporting biomass end of the year grazing_EndOfYear(); mort_EndOfYear(); @@ -253,35 +221,28 @@ int main(int argc, char **argv) { if (BmassFlags.yearly) output_Bmass_Yearly(year); - // Moved kill annual and kill extra growth after we export biomass, and recovery of biomass after fire before the next year + // Moved kill annual and kill extra growth after we export biomass, and recovery of biomass after fire before the next year _kill_annuals(); proportion_Recovery(); _kill_extra_growth(); - - //ForEachGroup(g) { - // insertRGroupYearInfo(g); - //} - //ForEachSpecies(s) { - // insertSpecieYearInfo(s); - // for ((i) = Species[s]->IndvHead; (i) != NULL; (i) = (i)->Next) { - // insertIndivYearInfo(i); - // } - //} } /* end model run for this year*/ - //if (BmassFlags.yearly) //moved to output function - // CloseFile(&Globals.bmass.fp_year); if (MortFlags.summary) { stat_Collect_GMort(); stat_Collect_SMort(); } if (MortFlags.yearly) - output_Mort_Yearly(); + output_Mort_Yearly(); // writes yearly file if (UseSoilwat) - SXW_Reset(); - + { + //stat_Output_AllSoilwatVariables(); + // dont need to restart if last iteration finished + // this keeps it from re-writing the output folder and overwriting output files + if(Globals.currIter != Globals.runModelIterations) + SXW_Reset(); + } } /* end model run for this iteration*/ /*------------------------------------------------------*/ @@ -290,12 +251,15 @@ int main(int argc, char **argv) { if (BmassFlags.summary) stat_Output_AllBmass(); - //Needed to disconnect from database - //ST_disconnect(); #ifdef STEPWAT - if (!isnull(SXW.debugfile) ) SXW_PrintDebug(1); + if (!isnull(SXW.debugfile)){ + printf("entering debugfile\n"); + SXW_PrintDebug(1); + } #endif - + SW_OUT_close_files(); + free_all_sxw_memory(); + printf("\nend program\n"); fprintf(progfp, "\n"); return 0; } @@ -320,7 +284,6 @@ void Plot_Initialize(void) { if (RGroup[Species[sp]->res_grp]->extirpated) { Species[sp]->seedling_estab_prob = Species[sp]->seedling_estab_prob_old; - } /* clear estab and kills information */ @@ -366,6 +329,7 @@ void Plot_Initialize(void) { RGroup[rg]->yrs_neg_pr = 0; RGroup[rg]->extirpated = FALSE; } + memset(SXW.transp_SWA, 0, sizeof(SXW.transp_SWA)); // set transp_SWA to 0; needs to be reset each iteration if (UseSoilwat) SXW_InitPlot(); @@ -396,10 +360,13 @@ static void init_args(int argc, char **argv) { * the program to write progress info (iter) to stdout. * Without the option, progress info (dots) is written to * stderr. + * 8/16/17 - BEB Updated option for -o flag. Now if this flag is set the output files from + * files_v30.in are written to. + * 10/9/17 - BEB Added -i flag for writing SOILWAT output for every iteration */ char str[1024], - *opts[] = {"-d","-f","-q","-s","-e", "-p", "-g", "-o"}; /* valid options */ - int valopts[] = { 1, 1, 0, -1, 0, 0 , 0, 1}; /* indicates options with values */ + *opts[] = {"-d","-f","-q","-s","-e", "-p", "-g", "-o", "-i"}; /* valid options */ + int valopts[] = { 1, 1, 0, -1, 0, 0, 0, 0, 0}; /* indicates options with values */ /* 0=none, 1=required, -1=optional */ int i, /* looper through all cmdline arguments */ a, /* current valid argument-value position */ @@ -513,14 +480,15 @@ static void init_args(int argc, char **argv) { break; /* -g */ case 7: - printf("Get all the Soilwat option called, with file=%s \n", str); - if (strlen(str) > 1) - { - print_soilwat_output(str); - } - + printf("storing SOILWAT output (flag -o)\n"); + isPartialSoilwatOutput = FALSE; break; /* -o also get all the soilwat output*/ + case 8: // -i + printf("storing SOILWAT output for all iterations\n"); + storeAllIterations = TRUE; + break; + default: LogError(logfp, LOGFATAL, "Programmer: bad option in main:init_args:switch"); @@ -540,7 +508,7 @@ static void check_log(void) { if (logfp != stdout) { if (logged && !QuietMode) fprintf(progfp, "\nCheck logfile for error messages.\n"); - + CloseFile(&logfp); } @@ -589,32 +557,6 @@ void check_sizes(const char *chkpt) { } - -/*static void check_sizes_final(void) { -//=================================================== - - GrpIndex rg; - SppIndex sp; - - ForEachGroup(rg) { - if (!ZRO(RGroup[rg]->relsize) ) { - LogError(stdout, LOGWARN, "(%d) Group %s relsize != 0 (%.2f)\n", - Globals.currIter, - RGroup[rg]->name, RGroup[rg]->relsize); - } - } - - ForEachSpecies(sp) { - if (!ZRO(Species[sp]->relsize) ) { - LogError(stdout, LOGWARN, "(%d) Species %s relsize != 0 (%.2f)\n", - Globals.currIter, - Species[sp]->name, Species[sp]->relsize); - } - } - -}*/ - -/*===============================================================*/ #ifdef DEBUG_MEM void CheckMemoryIntegrity(Bool flag) { // DLM - 6/6/2013 : NOTE - The dynamically allocated variables added for the new grid option are not accounted for here. I haven't bothered to add them because it would add a ton of code and I haven't been using the code to facilitate debugging of memory. Instead I have been using the valgrind program to debug my memory, as I feel like it is a better solution. If wanting to use this code to debug memory, memory references would probably have to be set up for the dynamically allocated variables in ST_grid.c as well as the new dynamically allocated grid_Stat variable in ST_stats.c. diff --git a/ST_mortality.c b/ST_mortality.c index 2ad8af6e..29e23c26 100644 --- a/ST_mortality.c +++ b/ST_mortality.c @@ -21,6 +21,7 @@ #include #include +#include "sw_src/filefuncs.h" #include "generic.h" #include "rands.h" #include "myMemory.h" @@ -190,7 +191,7 @@ void mort_EndOfYear( void) /*======================================================*/ /* PURPOSE */ /* Implements killing of plants through fire or another event - * that would result in mortality in single year (killyr) or + * that would result in mortality in single year (killyr) or * extirpation (extirp) where plants are killed and do not return. */ //printf("inside mort_EndOfYear() \n"); @@ -281,7 +282,7 @@ void grazing_EndOfYear( void){ //rgroup grazing if (Globals.currYear == grazingyr) - { + { //printf( "currYear is equal to grazingYear so will iterate all the Species for doing grazing, RGroup[g]->est_count =%d \n",RGroup[rg]->est_count); Int i; ForEachEstSpp2( rg, i) @@ -831,4 +832,3 @@ void _kill_extra_growth( void) { } - diff --git a/ST_output.c b/ST_output.c index b2c3f78a..0df68d6a 100644 --- a/ST_output.c +++ b/ST_output.c @@ -109,7 +109,6 @@ void output_Bmass_Yearly( Int year ) { sprintf(fields[fc++],"%d", Species[sp]->est_count); } } - sprintf(filename, "%s%0*d.csv", Parm_name(F_BMassPre), Globals.bmass.suffixwidth, Globals.currIter); @@ -185,5 +184,3 @@ void output_Mort_Yearly( void ) { CloseFile(&Globals.mort.fp_year); } - - diff --git a/ST_params.c b/ST_params.c index d1fb13de..1f85910d 100644 --- a/ST_params.c +++ b/ST_params.c @@ -51,7 +51,7 @@ SppIndex species_New(void); void parm_Initialize( Int); void parm_SetFirstName( char *s); void parm_SetName( char *s, int which); - void parm_free_memory( void ); + void parm_free_memory( void ); /*********** Locally Used Function Declarations ************/ /***********************************************************/ @@ -146,7 +146,7 @@ void parm_Initialize( Int iter) { _rgroup_init(); _species_init(); _check_species(); - + // _bmasshdr_init(); // _morthdr_create(); RandSeed(Globals.randseed); @@ -900,7 +900,7 @@ static void _rgroup_init( void) { LogError(logfp, LOGFATAL, "%s: Too few columns in groups", MyFileName); } - + _rgroup_add1( name, space, density, estab, slow, stretch, xres, estann, turnon, styr, killyr,killfreq_startyr, killfreq, @@ -1187,7 +1187,7 @@ static void _species_init( void) { LogError(logfp, LOGFATAL, "%s: Incorrect/incomplete input in annual estab parms", MyFileName); } - + /* ------------------------------------------------- */ /* ------ read the vegetative propagation parameters */ @@ -1233,7 +1233,7 @@ static void _species_init( void) { continue; } - x = sscanf( inbuf, "%s %hd %f %f %f %f %f %f %f", + x = sscanf( inbuf, "%s %hd %f %f %f %f %f %f %f", name, &turnondispersal, &p1, &p2, &p3, &p4, &p5, &p6, &p7); if(x < 9) LogError(logfp, LOGFATAL, "%s: Too few columns in species seed dispersal inputs", MyFileName); @@ -1242,11 +1242,11 @@ static void _species_init( void) { sp = Species_Name2Index(name2); if( sp < 0) LogError(logfp, LOGFATAL, "%s: Mismatched name (%s) for species seed dispersal inputs", MyFileName, name2); - + Species[sp]->use_dispersal = itob(turnondispersal); Species[sp]->allow_growth = TRUE; Species[sp]->sd_sgerm = FALSE; - + Species[sp]->sd_Param1 = p1; Species[sp]->sd_PPTdry = p2; Species[sp]->sd_PPTwet = p3; @@ -1255,7 +1255,7 @@ static void _species_init( void) { Species[sp]->sd_H = p6; Species[sp]->sd_VT = p7; } - if(!sppok) + if(!sppok) LogError(logfp, LOGFATAL, "%s: Incorrect/incomplete input in species seed dispersal input", MyFileName); CloseFile(&f); @@ -1320,4 +1320,3 @@ void Parm_SetMemoryRefs( void) { } #endif - diff --git a/ST_resgroups.c b/ST_resgroups.c index 02d0fd53..f60f34f0 100644 --- a/ST_resgroups.c +++ b/ST_resgroups.c @@ -25,6 +25,7 @@ #include "rands.h" #include "generic.h" +#include "sw_src/filefuncs.h" #include "ST_functions.h" #include "sxw_funcs.h" extern Bool UseSoilwat; @@ -64,10 +65,11 @@ static RealF _add_annuals(const GrpIndex rg, const RealF g_pr, void rgroup_PartResources(void) { /*======================================================*/ + /* PURPOSE */ /* Partition resources for this year among the resource groups. The allocation happens in three steps: basic - group allocation, partitioning of extra resources in - _res_part_extra(), and further partitioning to individuals + group allocation, partitioning of extra resources in + _res_part_extra(), and further partitioning to individuals in the group _ResPartIndiv(). See COMMENT 1. at the end of this file for the algorithm.*/ /* Chris Bennett @ LTER-CSU 12/15/2000 */ @@ -78,19 +80,19 @@ void rgroup_PartResources(void) /*------------------------------------------------------*/ GrpIndex rg; - SppIndex sp; RealF resource, /* amt of "resource" == 1 when ppt is avg */ xtra_base = 0., /* pooled extra resource up to 1.0 */ xtra_obase = 0., /* pooled resource > 1.0 */ - size_base[MAX_RGROUPS], /* total res. contrib to base, all groups */ - size_obase[MAX_RGROUPS]; /* total res. contrib. if xtra_obase */ + size_base[MAX_RGROUPS] = {0}, /* total res. contrib to base, all groups */ + size_obase[MAX_RGROUPS] = {0}; /* total res. contrib. if xtra_obase */ Bool noplants = TRUE; const Bool do_base = FALSE, /* monikers for _res_part_extra() */ - do_extra = TRUE, add_seeds = TRUE, /* monikers for pass 1 & 2 _add_annuals() */ + do_extra = TRUE, /* monikers for pass 1 & 2 _add_annuals() */ no_seeds = FALSE; GroupType *g; /* shorthand for RGroup[rg] */ - int i; + + /*----------------------------------------------------*/ /* ----- distribute basic (minimum) resources */ ForEachGroup(rg) @@ -115,6 +117,11 @@ void rgroup_PartResources(void) size_base[rg] = g->relsize * g->min_res_req; size_obase[rg] = (g->use_extra_res) ? size_base[rg] : 0.; + /*these functions are not used if using SOILWAT, + extra resource partitioning does not occur when running SOILWAT*/ + _res_part_extra(do_base, xtra_base, size_base); + _res_part_extra(do_extra, xtra_obase, size_obase); + /*this is how res_required and res_avail are set if SOILWAT is running*/ #ifdef STEPWAT } @@ -139,6 +146,7 @@ void rgroup_PartResources(void) //KAP:Previously, a seperate set of code was used to determine resource availability for annual species //Now, resource paritioning for annuals occurs in the same way as for perennials, by getting the RGroup Biomass //and the resource_cur from SXW_GetTranspiration + //Annuals seem to have a artificial limit of 20. We do Annuals here differently if(g->max_age == 1) { if(!ZRO(g->res_avail) && g->res_required / g->res_avail > 20) @@ -154,7 +162,7 @@ void rgroup_PartResources(void) } } #endif - + /* If relsize>0, reset noplants from TRUE to FALSE and if noplants=TRUE, exit from the loop */ if (GT(g->relsize, 0.)) noplants = FALSE; @@ -164,12 +172,9 @@ void rgroup_PartResources(void) if (noplants) return; - /*these functions are not used if using SOILWAT, - extra resource partitioning does not occur when running SOILWAT*/ - _res_part_extra(do_base, xtra_base, size_base); - _res_part_extra(do_extra, xtra_obase, size_obase); - - //calculate PR at the rgroup level: resources required/resources available + /* reset annuals' "TRUE" relative size here */ + //KAP: formely, this call established annual species. We have moved annual establishment to the Rgroup_Establish function, + //where all other resource groups establish (e.g. perennials). This function is no longer required. ForEachGroup(rg) { g = RGroup[rg]; @@ -190,7 +195,7 @@ static RealF _add_annuals(const GrpIndex rg, const RealF g_pr, * if add_seeds==TRUE, we should have done the above and now * we really want to add to the biomass and seedbank. * - * check regen_ok flag. if true, apply establishment and + * check regen_ok flag. if TRUE, apply establishment and * add to seedbank. Otherwise, add 0 to seedbank and skip * adding plants this year. We also check probability of establishment to * account for introduction of propagules, in which case @@ -228,7 +233,7 @@ static RealF _add_annuals(const GrpIndex rg, const RealF g_pr, if (!add_seeds && RandUni() <= s->seedling_estab_prob) { /* force addition of new propagules */ - //if regen_ok is True, pass the g_pr parameter, if regen_ok is False, pass -1 + //if regen_ok is TRUE, pass the g_pr parameter, if regen_ok is False, pass -1 _add_annual_seedprod(sp, (g->regen_ok) ? g_pr : -1.); forced = TRUE; } @@ -267,7 +272,7 @@ static RealF _add_annuals(const GrpIndex rg, const RealF g_pr, static RealF _get_annual_maxestab(SppIndex sp) { /*======================================================*/ - /* Get the maximum number of viable seeds from the seedbank that can + /* Get the maximum number of viable seeds from the seedbank that can establish this year*/ IntU i; RealF sum = 0.; @@ -366,7 +371,12 @@ static void _res_part_extra(Bool isextra, RealF extra, RealF size[]) continue; space = (UseSoilwat) ? 1.0 : g->min_res_req; - req_prop = size[rg] / sum_size; + // checking so dont divide by 0 + if(sum_size == 0.) + req_prop = 0.; + else + req_prop = size[rg] / sum_size; + //printf("sum_size: %f\n", sum_size); if (isextra && g->use_extra_res && GT(g->xgrow, 0)) g->res_extra = req_prop * extra / space; @@ -386,9 +396,9 @@ void rgroup_ResPartIndiv(void) resource availability for the group is divided between individuals of the group, largest to smallest. Species distinctions within the group are ignored.The partitioning of resources - to individuals is done proportionally based on size so that individuals + to individuals is done proportionally based on size so that individuals should get more resources than their less-developed competitors. - See COMMENT 3 at the end of this file for the algorithm. Chris Bennett + See COMMENT 3 at the end of this file for the algorithm. Chris Bennett @ LTER-CSU 12/21/2000*/ /*------------------------------------------------------*/ @@ -396,7 +406,7 @@ void rgroup_ResPartIndiv(void) GrpIndex rg; GroupType *g; /* shorthand for RGroup[rg] */ SppIndex sp; - Int j; + Int j; IndivType **indivs, /* dynamic array of indivs in RGroup[rg] */ *ndv; /* shorthand for the current indiv */ IntS numindvs, n; @@ -418,10 +428,10 @@ void rgroup_ResPartIndiv(void) /* amount of extra, if any, is kept in g->res_extra */ /* base_rem = fmin(1, g->res_avail); */ base_rem = g->res_avail; - + ForEachEstSpp(sp, rg, j) { - + for (n = 0; n < numindvs; n++) { ndv = indivs[n]; @@ -438,7 +448,7 @@ void rgroup_ResPartIndiv(void) //printf("base_rem pr>1 = %f\n", base_rem); } - + else { ndv->res_avail = ndv->grp_res_prop * g->res_avail; @@ -447,7 +457,7 @@ void rgroup_ResPartIndiv(void) } } } - + base_rem += fmin(0, g->res_avail - 1.0); //printf("base_rem end = %f\n", base_rem); @@ -684,7 +694,7 @@ void rgroup_Establish(void) * * Also, there's now a parameter to define the start year * of establishment for perennials. - * + * * KAP: Annual establishment now occurs here instead of in PartResources */ /*------------------------------------------------------*/ @@ -746,7 +756,7 @@ void rgroup_Establish(void) else { num_est = 0; - } + } //printf("num_est for annuals=%d \n",num_est); // above inserted to establish individuals for annuals @@ -869,11 +879,12 @@ void RGroup_Update_Newsize(GrpIndex rg) } ///if (RGroup[rg]->max_age != 1) { + numindvs = 0; // set to 0 so no problems passing to function /* compute the contribution of each indiv to the group's size */ indivs = RGroup_GetIndivs(rg, SORT_0, &numindvs); for (n = 0; n < numindvs; n++) indivs[n]->grp_res_prop = indivs[n]->relsize / sumsize; - Mem_Free(indivs); + //Mem_Free(indivs); // dont call free on variable unless it was initialized with malloc or calloc ///} /* double check some assumptions */ @@ -1282,4 +1293,3 @@ void RGroup_SetMemoryRefs( void) creation imply that availability is not tied to relsize. */ - diff --git a/ST_species.c b/ST_species.c index b9e08a8b..3884442b 100644 --- a/ST_species.c +++ b/ST_species.c @@ -20,6 +20,7 @@ #include #include "ST_steppe.h" #include "ST_globals.h" +#include "sw_src/filefuncs.h" #include "myMemory.h" #include "rands.h" @@ -648,4 +649,3 @@ void Species_SetMemoryRefs( void) } #endif - diff --git a/ST_stats.c b/ST_stats.c index 42633934..65226cb4 100644 --- a/ST_stats.c +++ b/ST_stats.c @@ -24,7 +24,11 @@ #include "ST_steppe.h" #include "filefuncs.h" #include "myMemory.h" +#include "sw_src/SW_Site.h" #include "ST_structs.h" +#include "sxw.h" + extern SXW_t SXW; + extern SW_SITE SW_Site; /************ External Variable Declarations ***************/ /***********************************************************/ @@ -45,12 +49,16 @@ void stat_Output_YrMorts( void ) ; void stat_Output_AllMorts( void) ; void stat_Output_AllBmass(void) ; + + //adding below function for adding modified soilwat output at stepwat location + void stat_Output_AllSoilwatVariables(void); + //Adding below two functions for creating grid cells avg values output file - void stat_Output_AllBmassAvg(void) ; + void stat_Output_AllBmassAvg(void); void stat_Output_AllCellAvgBmass(const char * filename); - void stat_Output_Seed_Dispersal(const char * filename, const char sep, Bool makeHeader); - void stat_free_mem( void ) ; - + void stat_Output_Seed_Dispersal(const char * filename, const char sep, Bool makeHeader); + void stat_free_mem( void ); + void stat_Load_Accumulators( int cell, int year ); //these accumulators were added to use in the gridded option... there overall purpose is to save/load data to allow steppe to output correctly when running multiple grid cells void stat_Save_Accumulators( int cell, int year ); void stat_Free_Accumulators( void ); @@ -71,10 +79,10 @@ struct stat_st { *_Spp, *_Indv, *_Smort, *_Sestab, *_Sreceived; typedef struct { - struct accumulators_st *dist, *temp, *ppt, **grp1, **gsize, **gpr2, + struct accumulators_st *dist, *temp, *ppt, **grp1, **gsize, **gpr2, **gmort, **gestab, **spp, **indv, **smort, **sestab, **sreceived; } accumulators_grid_st; - + accumulators_grid_st *grid_Stat; @@ -118,7 +126,7 @@ static void _make_header_with_std( char *buf); } // quick macro to make life easier in the load/save accumulators functions... it just copies the data of p into v -// static void _copy_over(struct accumulators_st *p, struct accumulators_st *v) +// static void _copy_over(struct accumulators_st *p, struct accumulators_st *v) #define _copy_over(p, v) { \ (p)->sum = (v)->sum; \ (p)->sum_sq = (v)->sum_sq; \ @@ -177,7 +185,7 @@ void stat_Collect( Int year ) { RGroup[rg]->pr); } } - + if (BmassFlags.sppb) { ForEachSpecies(sp) { bmass = (double) Species_GetBiomass(sp); @@ -420,13 +428,13 @@ static void _init( void) { void stat_Init_Accumulators( void ) { //allocates memory for all of the grid accumulators grid_Stat = Mem_Calloc(Globals.nCells, sizeof(accumulators_grid_st), "stat_Init_Accumulators()"); - + int i, j; for( i = 0; i < Globals.nCells; i++) { if (BmassFlags.dist) grid_Stat[i].dist = Mem_Calloc(Globals.runModelYears, sizeof(struct accumulators_st), "stat_Init_Accumulators()"); if (BmassFlags.ppt) grid_Stat[i].ppt = Mem_Calloc(Globals.runModelYears, sizeof(struct accumulators_st), "stat_Init_Accumulators()"); if (BmassFlags.tmp) grid_Stat[i].temp = Mem_Calloc(Globals.runModelYears, sizeof(struct accumulators_st), "stat_Init_Accumulators()"); - + if (BmassFlags.grpb) { grid_Stat[i].grp1 = Mem_Calloc(Globals.runModelYears, sizeof(struct accumulators_st*), "stat_Init_Accumulators()"); // gave grp and gpr numbers attached to them so I wouldn't mix them up lol... bad (confusing) variable names on part of the original creator. if (BmassFlags.size) grid_Stat[i].gsize = Mem_Calloc(Globals.runModelYears, sizeof(struct accumulators_st), "stat_Init_Accumulators()"); @@ -455,10 +463,10 @@ void stat_Init_Accumulators( void ) { } } - if(UseSeedDispersal && UseGrid) + if(UseSeedDispersal && UseGrid) grid_Stat[i].sreceived = Mem_Calloc(Globals.runModelYears, sizeof(struct accumulators_st*), "stat_Init_Accumulators()"); - - + + for( j = 0; j < Globals.runModelYears; j++) { if (BmassFlags.grpb) { grid_Stat[i].grp1[j] = Mem_Calloc(Globals.grpCount, sizeof(struct accumulators_st), "stat_Init_Accumulators()"); @@ -486,7 +494,7 @@ void stat_Load_Accumulators(int cell, int year) { IntS age; int yr; yr = year - 1; - + if(MortFlags.species) { SppIndex sp; @@ -511,8 +519,8 @@ void stat_Load_Accumulators(int cell, int year) { if (BmassFlags.tmp) _copy_over(&_Temp.s[yr], &grid_Stat[cell].temp[yr]); if (BmassFlags.ppt) _copy_over(&_Ppt.s[yr], &grid_Stat[cell].ppt[yr]); - if (BmassFlags.dist) _copy_over(&_Dist.s[yr], &grid_Stat[cell].dist[yr]); - + if (BmassFlags.dist) _copy_over(&_Dist.s[yr], &grid_Stat[cell].dist[yr]); + if(BmassFlags.grpb) { GrpIndex c; ForEachGroup(c) { @@ -521,7 +529,7 @@ void stat_Load_Accumulators(int cell, int year) { if (BmassFlags.pr) _copy_over(&_Gpr[c].s[yr], &grid_Stat[cell].gpr2[yr][c]); } } - + if(BmassFlags.sppb) { SppIndex s; ForEachSpecies(s) { @@ -540,7 +548,7 @@ void stat_Load_Accumulators(int cell, int year) { /***********************************************************/ void stat_Save_Accumulators(int cell, int year) { //saves the accumulators for the cell at the given year - + if (firsttime) { firsttime = FALSE; _init(); @@ -548,10 +556,10 @@ void stat_Save_Accumulators(int cell, int year) { IntS age; int yr; yr = year - 1; - + if(MortFlags.species) { SppIndex sp; - + ForEachSpecies(sp) { if ( !Species[sp]->use_me) continue; _copy_over(&grid_Stat[cell].sestab[sp][0], &_Sestab[sp].s[0]); @@ -569,7 +577,7 @@ void stat_Save_Accumulators(int cell, int year) { _copy_over(&grid_Stat[cell].gmort[rg][age], &_Gmort[rg].s[age]); } } - + if (BmassFlags.tmp) _copy_over(&grid_Stat[cell].temp[yr], &_Temp.s[yr]); if (BmassFlags.ppt) _copy_over(&grid_Stat[cell].ppt[yr], &_Ppt.s[yr]); if (BmassFlags.dist) _copy_over(&grid_Stat[cell].dist[yr], &_Dist.s[yr]); @@ -582,7 +590,7 @@ void stat_Save_Accumulators(int cell, int year) { if (BmassFlags.pr) _copy_over(&grid_Stat[cell].gpr2[yr][c], &_Gpr[c].s[yr]); } } - + if(BmassFlags.sppb) { SppIndex s; ForEachSpecies(s) { @@ -599,6 +607,19 @@ void stat_Save_Accumulators(int cell, int year) { } +float get_running_avg(float old_val, float val_to_add){ + float new_avg; + new_avg = old_val + (val_to_add - old_val) / Globals.currIter; + return new_avg; +} + +float get_running_sqr(float old_val, float val_to_add, float run_avg){ + float run_sqr; + run_sqr = (val_to_add-old_val) * (val_to_add-run_avg); + + return run_sqr; +} + /***********************************************************/ void stat_Free_Accumulators( void ) { //frees all the memory allocated in stat_init_Accumulators() @@ -618,11 +639,11 @@ void stat_Free_Accumulators( void ) { if(UseSeedDispersal && UseGrid) Mem_Free(grid_Stat[i].sreceived[j]); } - + if (BmassFlags.dist) Mem_Free(grid_Stat[i].dist); - if (BmassFlags.ppt) Mem_Free(grid_Stat[i].ppt); + if (BmassFlags.ppt) Mem_Free(grid_Stat[i].ppt); if (BmassFlags.tmp) Mem_Free(grid_Stat[i].temp); - + if(BmassFlags.grpb) { Mem_Free(grid_Stat[i].grp1);// gave grp and gpr numbers attached to them so I wouldn't mix them up lol... bad (confusing) variable names on part of the original creator. if (BmassFlags.size) Mem_Free(grid_Stat[i].gsize); @@ -662,7 +683,7 @@ void stat_free_mem( void ) { //frees memory allocated in this module GrpIndex gp; SppIndex sp; - + if(BmassFlags.grpb) ForEachGroup(gp) { Mem_Free(_Grp[gp].s); @@ -674,11 +695,11 @@ void stat_free_mem( void ) { Mem_Free(_Spp[sp].s); if(BmassFlags.indv) Mem_Free(_Indv[sp].s); } - + if (BmassFlags.dist) Mem_Free(_Dist.s); - if (BmassFlags.ppt) Mem_Free(_Ppt.s); + if (BmassFlags.ppt) Mem_Free(_Ppt.s); if (BmassFlags.tmp) Mem_Free(_Temp.s); - + if(BmassFlags.grpb) { Mem_Free(_Grp); if (BmassFlags.size) Mem_Free(_Gsize); @@ -712,7 +733,7 @@ void stat_free_mem( void ) { Mem_Free(_Sreceived); } - + } /***********************************************************/ @@ -856,7 +877,7 @@ void stat_Output_AllMorts( void) { for(age=0; age < Globals.Max_Age; age++) { fprintf(f,"%d", age+1); if (MortFlags.group) { - ForEachGroup(rg) + ForEachGroup(rg) fprintf(f,"%c%5.1f", sep, ( age < GrpMaxAge(rg) ) ? _get_avg(&_Gmort[rg].s[age]) : 0.); @@ -1208,16 +1229,16 @@ void stat_Output_Seed_Dispersal(const char * filename, const char sep, Bool make for( yr=1; yr<= Globals.runModelYears; yr++) { *buf = '\0'; - + sprintf(buf, "%d%c", yr, sep); - + ForEachSpecies(sp) { sprintf(tbuf, "%f%c%f%c", _get_avg( &_Sreceived[sp].s[yr-1]), sep, _get_std( &_Sreceived[sp].s[yr-1]), sep); strcat(buf, tbuf); } fprintf(f, "%s\n", buf); - } + } CloseFile(&f); } @@ -1290,7 +1311,6 @@ static RealF _get_gridcell_std(struct accumulators_grid_cell_st *p) } - /***********************************************************/ static void _make_header_with_std( char *buf) { @@ -1410,8 +1430,6 @@ static void _make_header( char *buf) { } } - - /* Put header line in global variable */ for (i=0; i< fc-1; i++) { sprintf(tbuf,"%s%c", fields[i], BmassFlags.sep); @@ -1423,7 +1441,6 @@ static void _make_header( char *buf) { } - #ifdef DEBUG_MEM void Stat_SetMemoryRefs(void) { /* when debugging memory problems, use the bookkeeping diff --git a/makefile b/makefile index 67b6dfc8..1e660cea 100644 --- a/makefile +++ b/makefile @@ -26,7 +26,7 @@ libDirs = -Lsw_src -Lsqlite-amalgamation incDirs = -Isw_src -Isqlite-amalgamation LIBS = -C_FLAGS = -g -O0 -Wstrict-prototypes -Wmissing-prototypes -Wimplicit -Wunused -Wformat -Wredundant-decls -Wcast-align\ +C_FLAGS = -g -O0 -Wstrict-prototypes -Wmissing-prototypes -Wimplicit -Wunused -Wformat -Wredundant-decls -Wcast-align\ -DSTEPWAT -lm SRCS =\ @@ -46,7 +46,6 @@ SRCS =\ $(Src)/sw_src/SW_Files.c\ $(Src)/sw_src/SW_Model.c\ $(Src)/sw_src/SW_Output.c\ - $(Src)/sw_src/SW_Main_Function.c\ $(Src)/sw_src/SW_Site.c\ $(Src)/sw_src/SW_Sky.c\ $(Src)/sw_src/SW_VegProd.c\ @@ -85,7 +84,6 @@ EXOBJS =\ $(oDir)/sw_src/SW_Files.o\ $(oDir)/sw_src/SW_Model.o\ $(oDir)/sw_src/SW_Output.o\ - $(oDir)/sw_src/SW_Main_Function.o\ $(oDir)/sw_src/SW_Site.o\ $(oDir)/sw_src/SW_Sky.o\ $(oDir)/sw_src/SW_VegProd.o\ @@ -222,9 +220,6 @@ $(oDir)/sw_src/SW_Output.o: sw_src/SW_Output.c sw_src/generic.h \ sw_src/SW_Weather.h sw_src/SW_Carbon.h $(CC) $(C_FLAGS) $(incDirs) -c -o $@ $< -$(oDir)/sw_src/SW_Main_Function.o: sw_src/SW_Main_Function.c - $(CC) $(C_FLAGS) $(incDirs) -c -o $@ $< - $(oDir)/sw_src/SW_Site.o: sw_src/SW_Site.c sw_src/generic.h sw_src/filefuncs.h \ sw_src/myMemory.h sw_src/SW_Defines.h sw_src/SW_Files.h sw_src/SW_Site.h sw_src/SW_Carbon.h $(CC) $(C_FLAGS) $(incDirs) -c -o $@ $< @@ -271,7 +266,7 @@ $(oDir)/ST_indivs.o: ST_indivs.c ST_steppe.h ST_defines.h \ $(oDir)/ST_main.o: ST_main.c ST_steppe.h ST_defines.h sw_src/generic.h \ ST_structs.h ST_functions.h sw_src/filefuncs.h \ - sw_src/myMemory.h + sw_src/myMemory.h sw_src/SW_VegProd.h $(CC) $(C_FLAGS) $(incDirs) -c -o $@ $< $(oDir)/ST_mortality.o: ST_mortality.c ST_steppe.h ST_defines.h \ diff --git a/sw_src b/sw_src index 72f9382d..f30878e8 160000 --- a/sw_src +++ b/sw_src @@ -1 +1 @@ -Subproject commit 72f9382d106a5b7c7247065d334ff4ef394c3a3b +Subproject commit f30878e8f41fa4299e4ab006acdaba5af78082c7 diff --git a/sxw.c b/sxw.c index 38a31173..732da509 100644 --- a/sxw.c +++ b/sxw.c @@ -74,6 +74,7 @@ /*************** Global Variable Declarations ***************/ /***********************************************************/ SXW_t SXW; +SXW_avg SXW_AVG; extern SW_SITE SW_Site; extern SW_MODEL SW_Model; @@ -82,6 +83,10 @@ extern SW_WEATHER SW_Weather; extern SW_MARKOV SW_Markov; //extern SW_SOILWAT SW_Soilwat; +extern Bool isPartialSoilwatOutput; +extern Bool storeAllIterations; + + /*************** Module/Local Variable Declarations ***************/ /***********************************************************/ @@ -108,6 +113,7 @@ RealD * _roots_max, /* read from root distr. file */ /* simple vectors hold the resource information for each group */ /* curr/equ gives the available/required ratio */ RealF _resource_cur[MAX_RGROUPS], /* current resource utilization */ + _resource_cur_swa[MAX_RGROUPS], _resource_pr[MAX_RGROUPS]; /* resource convertable to PR */ #ifdef SXW_BYMAXSIZE @@ -145,11 +151,12 @@ static void _make_roots_arrays(void); static void _make_phen_arrays(void); static void _make_prod_arrays(void); static void _make_transp_arrays(void); -static void _write_sw_outin(void); +static void _make_soil_arrays(void); //static void _recover_names(void); static void _read_debugfile(void); void _print_debuginfo(void); void debugCleanUp(void); +static void _make_swa_array(void); static void _make_swc_array(void); static void SXW_SW_Setup_Echo(void); //static void SXW_SW_Output_Echo(void); @@ -158,7 +165,6 @@ static void SXW_SW_Setup_Echo(void); void load_sxw_memory( RealD * grid_roots_max, RealD* grid_rootsXphen, RealD* grid_roots_active, RealD* grid_roots_active_rel, RealD* grid_roots_active_sum, RealD* grid_phen, RealD* grid_prod_bmass, RealD* grid_prod_pctlive ); void save_sxw_memory( RealD * grid_roots_max, RealD* grid_rootsXphen, RealD* grid_roots_active, RealD* grid_roots_active_rel, RealD* grid_roots_active_sum, RealD* grid_phen, RealD* grid_prod_bmass, RealD* grid_prod_pctlive ); void free_sxw_memory( void ); -void free_all_sxw_memory( void ); /****************** Begin Function Code ********************/ /***********************************************************/ @@ -208,7 +214,6 @@ void SXW_Init( Bool init_SW, char *f_roots ) { if (SXW.debugfile) _read_debugfile(); - _write_sw_outin(); if(init_SW) { @@ -218,16 +223,20 @@ void SXW_Init( Bool init_SW, char *f_roots ) { free(temp); } - SXW.NTrLyrs = SW_Site.n_transp_lyrs_tree; - if(SW_Site.n_transp_lyrs_shrub > SXW.NTrLyrs) - SXW.NTrLyrs = SW_Site.n_transp_lyrs_shrub; - if(SW_Site.n_transp_lyrs_grass > SXW.NTrLyrs) - SXW.NTrLyrs = SW_Site.n_transp_lyrs_grass; - if(SW_Site.n_transp_lyrs_forb > SXW.NTrLyrs) - SXW.NTrLyrs = SW_Site.n_transp_lyrs_forb; + SXW.NTrLyrs = SW_Site.n_transp_lyrs[0]; + if(SW_Site.n_transp_lyrs[1] > SXW.NTrLyrs) + SXW.NTrLyrs = SW_Site.n_transp_lyrs[1]; + if(SW_Site.n_transp_lyrs[3] > SXW.NTrLyrs) + SXW.NTrLyrs = SW_Site.n_transp_lyrs[3]; + if(SW_Site.n_transp_lyrs[2] > SXW.NTrLyrs) + SXW.NTrLyrs = SW_Site.n_transp_lyrs[2]; SXW.NSoLyrs = SW_Site.n_layers; + printf("Number of layers: %d\n", SW_Site.n_layers); + printf("Number of iterations: %d\n", Globals.runModelIterations); + printf("Number of years: %d\n", Globals.runModelYears); + _make_arrays(); _read_roots_max(); @@ -320,7 +329,6 @@ void SXW_Run_SOILWAT (void) { SXW.aet = 0.; /* used to be in sw_setup() but it needs clearing each run */ //SXW_SW_Setup_Echo(); - _sxw_sw_run(); /* now compute resource availability for the given plant sizes */ @@ -337,38 +345,38 @@ void SXW_SW_Setup_Echo(void) { FILE *f = OpenFile(strcat(name, ".input.out"), "a"); int i; fprintf(f, "\n================== %d =============================\n", SW_Model.year); - fprintf(f,"Fractions Grass:%f Shrub:%f Tree:%f Forb:%f BareGround:%f\n", SW_VegProd.grass.cov.fCover, SW_VegProd.shrub.cov.fCover, SW_VegProd.tree.cov.fCover, SW_VegProd.forb.cov.fCover, SW_VegProd.bare_cov.fCover); + fprintf(f,"Fractions Grass:%f Shrub:%f Tree:%f Forb:%f BareGround:%f\n", SW_VegProd.veg[3].cov.fCover, SW_VegProd.veg[1].cov.fCover, SW_VegProd.veg[0].cov.fCover, SW_VegProd.veg[2].cov.fCover, SW_VegProd.bare_cov.fCover); fprintf(f,"Monthly Production Values\n"); fprintf(f,"Grass\n"); fprintf(f,"Month\tLitter\tBiomass\tPLive\tLAI_conv\n"); for (i = 0; i < 12; i++) { - fprintf(f,"%u\t%f\t%f\t%f\t%f\n", i + 1, SW_VegProd.grass.litter[i], - SW_VegProd.grass.biomass[i], SW_VegProd.grass.pct_live[i], - SW_VegProd.grass.lai_conv[i]); + fprintf(f,"%u\t%f\t%f\t%f\t%f\n", i + 1, SW_VegProd.veg[3].litter[i], + SW_VegProd.veg[3].biomass[i], SW_VegProd.veg[3].pct_live[i], + SW_VegProd.veg[3].lai_conv[i]); } fprintf(f,"Shrub\n"); fprintf(f,"Month\tLitter\tBiomass\tPLive\tLAI_conv\n"); for (i = 0; i < 12; i++) { - fprintf(f,"%u\t%f\t%f\t%f\t%f\n", i + 1, SW_VegProd.shrub.litter[i], - SW_VegProd.shrub.biomass[i], SW_VegProd.shrub.pct_live[i], - SW_VegProd.shrub.lai_conv[i]); + fprintf(f,"%u\t%f\t%f\t%f\t%f\n", i + 1, SW_VegProd.veg[1].litter[i], + SW_VegProd.veg[1].biomass[i], SW_VegProd.veg[1].pct_live[i], + SW_VegProd.veg[1].lai_conv[i]); } fprintf(f,"Tree\n"); fprintf(f,"Month\tLitter\tBiomass\tPLive\tLAI_conv\n"); for (i = 0; i < 12; i++) { - fprintf(f,"%u\t%f\t%f\t%f\t%f\n", i + 1, SW_VegProd.tree.litter[i], - SW_VegProd.tree.biomass[i], SW_VegProd.tree.pct_live[i], - SW_VegProd.tree.lai_conv[i]); + fprintf(f,"%u\t%f\t%f\t%f\t%f\n", i + 1, SW_VegProd.veg[0].litter[i], + SW_VegProd.veg[0].biomass[i], SW_VegProd.veg[0].pct_live[i], + SW_VegProd.veg[0].lai_conv[i]); } fprintf(f,"Forb\n"); fprintf(f,"Month\tLitter\tBiomass\tPLive\tLAI_conv\n"); for (i = 0; i < 12; i++) { - fprintf(f,"%u\t%f\t%f\t%f\t%f\n", i + 1, SW_VegProd.forb.litter[i], - SW_VegProd.forb.biomass[i], SW_VegProd.forb.pct_live[i], - SW_VegProd.forb.lai_conv[i]); + fprintf(f,"%u\t%f\t%f\t%f\t%f\n", i + 1, SW_VegProd.veg[2].litter[i], + SW_VegProd.veg[2].biomass[i], SW_VegProd.veg[2].pct_live[i], + SW_VegProd.veg[2].lai_conv[i]); } SW_SITE *s = &SW_Site; @@ -376,8 +384,16 @@ void SXW_SW_Setup_Echo(void) { fprintf(f,"Forb\tTree\tShrub\tGrass\n"); ForEachSoilLayer(i) {// %u %u %u %u s->lyr[i]->my_transp_rgn_forb, s->lyr[i]->my_transp_rgn_tree, s->lyr[i]->my_transp_rgn_shrub, s->lyr[i]->my_transp_rgn_grass - fprintf(f,"%6.2f %6.2f %6.2f %6.2f\n", s->lyr[i]->transp_coeff_forb, s->lyr[i]->transp_coeff_tree, s->lyr[i]->transp_coeff_shrub, s->lyr[i]->transp_coeff_grass); + fprintf(f,"%6.2f %6.2f %6.2f %6.2f\n", s->lyr[i]->transp_coeff[2], s->lyr[i]->transp_coeff[0], s->lyr[i]->transp_coeff[1], s->lyr[i]->transp_coeff[3]); } + + // adding values to sxw structure for use in ST_stats.c + /*SXW.grass_cover = SW_VegProd.grass.conv_stcr; + SXW.shrub_cover = SW_VegProd.shrub.conv_stcr; + SXW.tree_cover = SW_VegProd.tree.conv_stcr; + SXW.forbs_cover = SW_VegProd.forb.conv_stcr;*/ + + fprintf(f, "\n"); CloseFile(&f); } @@ -389,7 +405,7 @@ void SXW_SW_Setup_Echo(void) { RealF SXW_GetPR( GrpIndex rg) { /*======================================================*/ /* see _sxw_update_resource() for _resource_cur[] -This function is no longer utilized, SXW_GetTranspiration has replaced it +This function is no longer utilized, SXW_GetResource has replaced it _resource_pr is no longer used as a parameter. We remain the code for the time being KAP 7/20/2016 */ @@ -696,6 +712,7 @@ static void _read_watin(void) { MyFileName = SXW.f_watin; f = OpenFile(MyFileName, "r"); + while( GetALine(f, inbuf) ) { if (++lineno == (eOutput + 2)) { strcpy(_swOutDefName, DirName(SXW.f_watin)); @@ -713,41 +730,6 @@ static void _read_watin(void) { } -static void _write_sw_outin(void) { -/*======================================================*/ -/* make sure the outsetup file for soilwat contains only - * the given information */ -/* Note that there won't actually be any output. These - * keys are required to trigger the correct part of the - * output accumulation routines. Refer to the Output.c - * module of SOILWAT for more. - */ - FILE *fp; - char pd[3]; - - switch (SXW.NPds) { - case MAX_WEEKS: - strcpy(pd, "WK"); - break; - case MAX_MONTHS: - strcpy(pd, "MO"); - break; - case MAX_DAYS: - strcpy(pd, "DY"); - break; - } - fp = OpenFile(_swOutDefName, "w"); - fprintf(fp, "TRANSP SUM %s 1 end transp\n", pd); - fprintf(fp, "PRECIP SUM YR 1 end precip\n"); - fprintf(fp, "TEMP AVG YR 1 end temp\n"); - if (SXW.debugfile) { - fprintf(fp, "AET SUM YR 1 end aet\n"); - fprintf(fp, "SWCBULK FIN MO 1 end swc_bulk\n"); - } - - CloseFile(&fp); -} - static void _make_arrays(void) { /*======================================================*/ /* central point to make all dynamically allocated arrays @@ -757,8 +739,11 @@ static void _make_arrays(void) { _make_phen_arrays(); _make_prod_arrays(); _make_transp_arrays(); - if (SXW.debugfile || UseGrid) - _make_swc_array(); + _make_swa_array(); + _make_swc_array(); + // only make output storage if -o or -i flags + if(storeAllIterations || isPartialSoilwatOutput == FALSE) + _make_soil_arrays(); } static void _make_roots_arrays(void) { @@ -775,7 +760,7 @@ static void _make_roots_arrays(void) { _roots_active_rel = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); //4 - Grass,Frob,Tree,Shrub - size = 4 * SXW.NPds * SXW.NTrLyrs; + size = NVEGTYPES * SXW.NPds * SXW.NTrLyrs; _roots_active_sum = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); } @@ -805,8 +790,9 @@ static void _make_transp_arrays(void) { */ char *fstr = "_make_transp_array()"; int size; + //int avg_size; - size = SXW.NPds * SXW.NSoLyrs; + size = (SXW.NPds * SXW.NSoLyrs) * MAX_DAYS; SXW.transpTotal = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); SXW.transpTrees = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); SXW.transpShrubs = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); @@ -814,6 +800,14 @@ static void _make_transp_arrays(void) { SXW.transpGrasses = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); } +static void _make_swa_array(void){ + char *fstr = "_make_swa_array()"; + int size_sum = NVEGTYPES * MAX_DAYS * SXW.NSoLyrs; + + SXW.sum_dSWA_repartitioned = (RealF *) Mem_Calloc(size_sum, sizeof(RealF), fstr); + + Mem_Set(SXW.sum_dSWA_repartitioned, 0, size_sum * sizeof(RealF)); +} static void _make_swc_array(void) { /*======================================================*/ @@ -822,10 +816,192 @@ static void _make_swc_array(void) { * specified with debugfile */ char *fstr = "_make_swc_array()"; - int size = SXW.NPds * SXW.NSoLyrs; + int size = SXW.NPds * SXW.NSoLyrs * MAX_DAYS; + SXW.swc = (RealF *) Mem_Calloc(size, sizeof(RealF *), fstr); } +// all memory allocation for avg values are here +// to be used with -o or -i flags +// dont need to allocate memory unless storing SOILWAT output +static void _make_soil_arrays(void){ + char *fstr = "_make_soil_arrays"; + int size, layer_size, avg_size; + size = (SXW.NPds * Globals.runModelYears * 2 * NVEGTYPES) * Globals.runModelYears; + layer_size = (SXW.NPds * SXW.NSoLyrs * Globals.runModelYears * 2 * NVEGTYPES) * Globals.runModelYears; + + avg_size = (4 * SXW.NSoLyrs * Globals.runModelYears * SXW.NPds * 2) * Globals.runModelYears; + + SXW.transpTotal_avg = (RealD *) Mem_Calloc(avg_size, sizeof(RealD), fstr); + SXW.transpTrees_avg = (RealD *) Mem_Calloc(avg_size, sizeof(RealD), fstr); + SXW.transpShrubs_avg = (RealD *) Mem_Calloc(avg_size, sizeof(RealD), fstr); + SXW.transpForbs_avg = (RealD *) Mem_Calloc(avg_size, sizeof(RealD), fstr); + SXW.transpGrasses_avg = (RealD *) Mem_Calloc(avg_size, sizeof(RealD), fstr); + + // initialize values to 0 + Mem_Set(SXW.transpTotal_avg, 0, avg_size * sizeof(RealD)); + Mem_Set(SXW.transpTrees_avg, 0, avg_size * sizeof(RealD)); + Mem_Set(SXW.transpShrubs_avg, 0, avg_size * sizeof(RealD)); + Mem_Set(SXW.transpForbs_avg, 0, avg_size * sizeof(RealD)); + Mem_Set(SXW.transpGrasses_avg, 0, avg_size * sizeof(RealD)); + + SXW.SWA_grass_avg = (RealF *) Mem_Calloc(avg_size, sizeof(RealF *), fstr); + SXW.SWA_shrub_avg = (RealF *) Mem_Calloc(avg_size, sizeof(RealF *), fstr); + SXW.SWA_tree_avg = (RealF *) Mem_Calloc(avg_size, sizeof(RealF *), fstr); + SXW.SWA_forb_avg = (RealF *) Mem_Calloc(avg_size, sizeof(RealF *), fstr); + + Mem_Set(SXW.SWA_grass_avg, 0, avg_size * sizeof(RealF)); + Mem_Set(SXW.SWA_shrub_avg, 0, avg_size * sizeof(RealF)); + Mem_Set(SXW.SWA_tree_avg, 0, avg_size * sizeof(RealF)); + Mem_Set(SXW.SWA_forb_avg, 0, avg_size * sizeof(RealF)); + + SXW_AVG.swc_avg = (RealF *) Mem_Calloc(avg_size, sizeof(RealF), fstr); + Mem_Set(SXW_AVG.swc_avg, 0, avg_size * sizeof(RealF)); + + + SXW_AVG.max_temp_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + SXW_AVG.min_temp_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + SXW_AVG.avg_temp_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + SXW_AVG.surfaceTemp_avg = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); + + SXW_AVG.aet_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + + Mem_Set(SXW_AVG.aet_avg, 0, size * sizeof(RealF)); + + SXW_AVG.ppt_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + SXW_AVG.val_rain_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + SXW_AVG.val_snow_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + SXW_AVG.val_snowloss_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + SXW_AVG.val_snowmelt_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + + Mem_Set(SXW_AVG.ppt_avg, 0, size * sizeof(RealF)); + Mem_Set(SXW_AVG.val_rain_avg, 0, size * sizeof(RealF)); + Mem_Set(SXW_AVG.val_snow_avg, 0, size * sizeof(RealF)); + Mem_Set(SXW_AVG.val_snowloss_avg, 0, size * sizeof(RealF)); + Mem_Set(SXW_AVG.val_snowmelt_avg, 0, size * sizeof(RealF)); + + SXW_AVG.estab_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + SXW_AVG.vwcbulk_avg = (RealF *) Mem_Calloc(layer_size, sizeof(RealF), fstr); + SXW_AVG.vwcmatric_avg = (RealF *) Mem_Calloc(layer_size, sizeof(RealF), fstr); + SXW_AVG.swpmatric_avg = (RealF *) Mem_Calloc(layer_size, sizeof(RealF), fstr); + SXW_AVG.swabulk_avg = (RealF *) Mem_Calloc(layer_size, sizeof(RealF), fstr); + SXW_AVG.swamatric_avg = (RealF *) Mem_Calloc(layer_size, sizeof(RealF), fstr); + SXW_AVG.surfacewater_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + SXW_AVG.runoff_total_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + SXW_AVG.surface_runoff_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + SXW_AVG.surface_runon_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + SXW_AVG.runoff_snow_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + SXW_AVG.evapsoil_avg = (RealF *) Mem_Calloc(layer_size, sizeof(RealF), fstr); + SXW_AVG.evapsurface_total_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + SXW_AVG.evapsurface_tree_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + SXW_AVG.evapsurface_shrub_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + SXW_AVG.evapsurface_forb_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + SXW_AVG.evapsurface_grass_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + SXW_AVG.evapsurface_litter_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + SXW_AVG.evapsurface_water_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + + SXW_AVG.interception_total_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + SXW_AVG.interception_tree_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + SXW_AVG.interception_shrub_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + SXW_AVG.interception_forb_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + SXW_AVG.interception_grass_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + SXW_AVG.interception_litter_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + SXW_AVG.soilinfilt_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + + SXW_AVG.lyrdrain_avg = (RealF *) Mem_Calloc(layer_size, sizeof(RealF), fstr); + + SXW_AVG.hydred_total_avg = (RealF *) Mem_Calloc(layer_size, sizeof(RealF), fstr); + SXW_AVG.hydred_tree_avg = (RealF *) Mem_Calloc(layer_size, sizeof(RealF), fstr); + SXW_AVG.hydred_shrub_avg = (RealF *) Mem_Calloc(layer_size, sizeof(RealF), fstr); + SXW_AVG.hydred_forb_avg = (RealF *) Mem_Calloc(layer_size, sizeof(RealF), fstr); + SXW_AVG.hydred_grass_avg = (RealF *) Mem_Calloc(layer_size, sizeof(RealF), fstr); + + SXW_AVG.pet_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + SXW_AVG.wetday_avg = (RealF *) Mem_Calloc(layer_size, sizeof(RealF), fstr); + + SXW_AVG.snowpack_water_eqv_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + SXW_AVG.snowpack_depth_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + + SXW_AVG.deepswc_avg = (RealF *) Mem_Calloc(size, sizeof(RealF), fstr); + + SXW_AVG.soiltemp_avg = (RealF *) Mem_Calloc(layer_size, sizeof(RealF), fstr); + + // carbon variables + SXW_AVG.biomass_grass_avg = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); + SXW_AVG.biomass_shrub_avg = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); + SXW_AVG.biomass_tree_avg = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); + SXW_AVG.biomass_forb_avg = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); + SXW_AVG.biomass_total_avg = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); + + SXW_AVG.biolive_grass_avg = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); + SXW_AVG.biolive_shrub_avg = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); + SXW_AVG.biolive_tree_avg = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); + SXW_AVG.biolive_forb_avg = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); + SXW_AVG.biolive_total_avg = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); + + SXW_AVG.bio_mult_grass_avg = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); + SXW_AVG.bio_mult_shrub_avg = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); + SXW_AVG.bio_mult_tree_avg = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); + SXW_AVG.bio_mult_forb_avg = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); + + SXW_AVG.wue_mult_grass_avg = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); + SXW_AVG.wue_mult_shrub_avg = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); + SXW_AVG.wue_mult_tree_avg = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); + SXW_AVG.wue_mult_forb_avg = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); + + + Mem_Set(SXW_AVG.max_temp_avg, 0, size * sizeof(RealF)); + Mem_Set(SXW_AVG.min_temp_avg, 0, size * sizeof(RealF)); + Mem_Set(SXW_AVG.avg_temp_avg, 0, size * sizeof(RealF)); + Mem_Set(SXW_AVG.surfaceTemp_avg, 0, size * sizeof(RealD)); + + Mem_Set(SXW_AVG.estab_avg, 0, size * sizeof(RealF)); + Mem_Set(SXW_AVG.vwcbulk_avg, 0, layer_size * sizeof(RealF)); + Mem_Set(SXW_AVG.vwcmatric_avg, 0, layer_size * sizeof(RealF)); + Mem_Set(SXW_AVG.swpmatric_avg, 0, layer_size * sizeof(RealF)); + Mem_Set(SXW_AVG.swabulk_avg, 0, layer_size * sizeof(RealF)); + Mem_Set(SXW_AVG.swamatric_avg, 0, layer_size * sizeof(RealF)); + Mem_Set(SXW_AVG.surfacewater_avg, 0, size * sizeof(RealF)); + Mem_Set(SXW_AVG.runoff_total_avg, 0, size * sizeof(RealF)); + Mem_Set(SXW_AVG.surface_runoff_avg, 0, size * sizeof(RealF)); + Mem_Set(SXW_AVG.surface_runon_avg, 0, size * sizeof(RealF)); + Mem_Set(SXW_AVG.runoff_snow_avg, 0, size * sizeof(RealF)); + Mem_Set(SXW_AVG.evapsoil_avg, 0, layer_size * sizeof(RealF)); + Mem_Set(SXW_AVG.evapsurface_total_avg, 0, size * sizeof(RealF)); + Mem_Set(SXW_AVG.evapsurface_tree_avg, 0, size * sizeof(RealF)); + Mem_Set(SXW_AVG.evapsurface_shrub_avg, 0, size * sizeof(RealF)); + Mem_Set(SXW_AVG.evapsurface_forb_avg, 0, size * sizeof(RealF)); + Mem_Set(SXW_AVG.evapsurface_grass_avg, 0, size * sizeof(RealF)); + Mem_Set(SXW_AVG.evapsurface_litter_avg, 0, size * sizeof(RealF)); + Mem_Set(SXW_AVG.evapsurface_water_avg, 0, size * sizeof(RealF)); + + Mem_Set(SXW_AVG.interception_total_avg, 0, size * sizeof(RealF)); + Mem_Set(SXW_AVG.interception_tree_avg, 0, size * sizeof(RealF)); + Mem_Set(SXW_AVG.interception_shrub_avg, 0, size * sizeof(RealF)); + Mem_Set(SXW_AVG.interception_forb_avg, 0, size * sizeof(RealF)); + Mem_Set(SXW_AVG.interception_grass_avg, 0, size * sizeof(RealF)); + Mem_Set(SXW_AVG.interception_litter_avg, 0, size * sizeof(RealF)); + + Mem_Set(SXW_AVG.soilinfilt_avg, 0, size * sizeof(RealF)); + Mem_Set(SXW_AVG.lyrdrain_avg, 0, layer_size * sizeof(RealF)); + + Mem_Set(SXW_AVG.hydred_total_avg, 0, layer_size * sizeof(RealF)); + Mem_Set(SXW_AVG.hydred_tree_avg, 0, layer_size * sizeof(RealF)); + Mem_Set(SXW_AVG.hydred_shrub_avg, 0, layer_size * sizeof(RealF)); + Mem_Set(SXW_AVG.hydred_forb_avg, 0, layer_size * sizeof(RealF)); + Mem_Set(SXW_AVG.hydred_grass_avg, 0, layer_size * sizeof(RealF)); + + Mem_Set(SXW_AVG.pet_avg, 0, size * sizeof(RealF)); + Mem_Set(SXW_AVG.wetday_avg, 0, layer_size * sizeof(RealF)); + + Mem_Set(SXW_AVG.snowpack_water_eqv_avg, 0, size * sizeof(RealF)); + Mem_Set(SXW_AVG.snowpack_depth_avg, 0, size * sizeof(RealF)); + + Mem_Set(SXW_AVG.deepswc_avg, 0, size * sizeof(RealF)); + + Mem_Set(SXW_AVG.soiltemp_avg, 0, layer_size * sizeof(RealF)); +} + /*static void _recover_names(void) { ====================================================== @@ -913,6 +1089,7 @@ static void _read_debugfile(void) { } void debugCleanUp() { + printf("in debugCleanUp\n"); disconnect(); } @@ -1002,24 +1179,24 @@ void _print_debuginfo(void) { } // all the other months have 31 days for (i = doy; i < (doy + days); i++) { //accumulating the monthly values... - lai_live += (v->tree.lai_live_daily[i]) - + (v->shrub.lai_live_daily[i]) - + (v->grass.lai_live_daily[i]) - + (v->forb.lai_live_daily[i]); - vegcov += (v->tree.vegcov_daily[i]) + (v->shrub.vegcov_daily[i]) - + (v->grass.vegcov_daily[i]) + (v->forb.vegcov_daily[i]); - total_agb += (v->tree.total_agb_daily[i]) - + (v->shrub.total_agb_daily[i]) - + (v->grass.total_agb_daily[i]) - + (v->forb.total_agb_daily[i]); - pct_live += (v->tree.pct_live_daily[i]) - + (v->shrub.pct_live_daily[i]) - + (v->grass.pct_live_daily[i]) - + (v->forb.pct_live_daily[i]); - biomass += (v->tree.biomass_daily[i]) - + (v->shrub.biomass_daily[i]) - + (v->grass.biomass_daily[i]) - + (v->forb.biomass_daily[i]); + lai_live += (v->veg[0].lai_live_daily[i]) + + (v->veg[1].lai_live_daily[i]) + + (v->veg[3].lai_live_daily[i]) + + (v->veg[2].lai_live_daily[i]); + vegcov += (v->veg[0].vegcov_daily[i]) + (v->veg[1].vegcov_daily[i]) + + (v->veg[3].vegcov_daily[i]) + (v->veg[2].vegcov_daily[i]); + total_agb += (v->veg[0].total_agb_daily[i]) + + (v->veg[1].total_agb_daily[i]) + + (v->veg[3].total_agb_daily[i]) + + (v->veg[2].total_agb_daily[i]); + pct_live += (v->veg[0].pct_live_daily[i]) + + (v->veg[1].pct_live_daily[i]) + + (v->veg[3].pct_live_daily[i]) + + (v->veg[2].pct_live_daily[i]); + biomass += (v->veg[0].biomass_daily[i]) + + (v->veg[1].biomass_daily[i]) + + (v->veg[3].biomass_daily[i]) + + (v->veg[2].biomass_daily[i]); } doy += days; //updating the doy //biomass = (v->tree.biomass[p]) + (v->shrub.biomass[p]) @@ -1139,30 +1316,120 @@ void SXW_SetMemoryRefs( void) { //returns the number of transpiration layers correctly for each veg_prod_type int getNTranspLayers(int veg_prod_type) { if(veg_prod_type == 1) - return SW_Site.n_transp_lyrs_tree; + return SW_Site.n_transp_lyrs[0]; else if(veg_prod_type == 2) - return SW_Site.n_transp_lyrs_shrub; + return SW_Site.n_transp_lyrs[1]; else if(veg_prod_type == 3) - return SW_Site.n_transp_lyrs_grass; + return SW_Site.n_transp_lyrs[3]; else if(veg_prod_type == 4) - return SW_Site.n_transp_lyrs_forb; + return SW_Site.n_transp_lyrs[2]; return -1; } /***********************************************************/ void free_all_sxw_memory( void ) { - free_sxw_memory(); + free_sxw_memory(); + Mem_Free(SXW.f_files); Mem_Free(SXW.f_roots); Mem_Free(SXW.f_phen); Mem_Free(SXW.f_bvt); Mem_Free(SXW.f_prod); Mem_Free(SXW.f_watin); + Mem_Free(SXW.transpTotal); Mem_Free(SXW.transpTrees); Mem_Free(SXW.transpShrubs); Mem_Free(SXW.transpForbs); Mem_Free(SXW.transpGrasses); - if (SXW.debugfile || UseGrid) Mem_Free(SXW.swc); + Mem_Free(SXW.transpTotal_avg); + Mem_Free(SXW.transpTrees_avg); + Mem_Free(SXW.transpShrubs_avg); + Mem_Free(SXW.transpForbs_avg); + Mem_Free(SXW.transpGrasses_avg); + + Mem_Free(SXW.SWA_grass_avg); + Mem_Free(SXW.SWA_shrub_avg); + Mem_Free(SXW.SWA_tree_avg); + Mem_Free(SXW.SWA_forb_avg); + + Mem_Free(SXW.sum_dSWA_repartitioned); + + Mem_Free(SXW.swc); + Mem_Free(SXW_AVG.swc_avg); + + Mem_Free(SXW_AVG.max_temp_avg); + Mem_Free(SXW_AVG.min_temp_avg); + Mem_Free(SXW_AVG.avg_temp_avg); + Mem_Free(SXW_AVG.surfaceTemp_avg); + + Mem_Free(SXW_AVG.aet_avg); + + Mem_Free(SXW_AVG.ppt_avg); + Mem_Free(SXW_AVG.val_rain_avg); + Mem_Free(SXW_AVG.val_snow_avg); + Mem_Free(SXW_AVG.val_snowmelt_avg); + Mem_Free(SXW_AVG.val_snowloss_avg); + + Mem_Free(SXW_AVG.estab_avg); + Mem_Free(SXW_AVG.vwcbulk_avg); + Mem_Free(SXW_AVG.vwcmatric_avg); + Mem_Free(SXW_AVG.swpmatric_avg); + Mem_Free(SXW_AVG.swabulk_avg); + Mem_Free(SXW_AVG.swamatric_avg); + Mem_Free(SXW_AVG.surfacewater_avg); + Mem_Free(SXW_AVG.runoff_total_avg); + Mem_Free(SXW_AVG.surface_runoff_avg); + Mem_Free(SXW_AVG.surface_runon_avg); + Mem_Free(SXW_AVG.runoff_snow_avg); + Mem_Free(SXW_AVG.evapsoil_avg); + Mem_Free(SXW_AVG.evapsurface_total_avg); + Mem_Free(SXW_AVG.evapsurface_tree_avg); + Mem_Free(SXW_AVG.evapsurface_shrub_avg); + Mem_Free(SXW_AVG.evapsurface_forb_avg); + Mem_Free(SXW_AVG.evapsurface_grass_avg); + Mem_Free(SXW_AVG.evapsurface_litter_avg); + Mem_Free(SXW_AVG.evapsurface_water_avg); + Mem_Free(SXW_AVG.interception_total_avg); + Mem_Free(SXW_AVG.interception_tree_avg); + Mem_Free(SXW_AVG.interception_shrub_avg); + Mem_Free(SXW_AVG.interception_forb_avg); + Mem_Free(SXW_AVG.interception_grass_avg); + Mem_Free(SXW_AVG.interception_litter_avg); + Mem_Free(SXW_AVG.soilinfilt_avg); + Mem_Free(SXW_AVG.lyrdrain_avg); + Mem_Free(SXW_AVG.hydred_total_avg); + Mem_Free(SXW_AVG.hydred_tree_avg); + Mem_Free(SXW_AVG.hydred_shrub_avg); + Mem_Free(SXW_AVG.hydred_forb_avg); + Mem_Free(SXW_AVG.hydred_grass_avg); + Mem_Free(SXW_AVG.pet_avg); + Mem_Free(SXW_AVG.wetday_avg); + Mem_Free(SXW_AVG.snowpack_water_eqv_avg); + Mem_Free(SXW_AVG.snowpack_depth_avg); + Mem_Free(SXW_AVG.deepswc_avg); + Mem_Free(SXW_AVG.soiltemp_avg); + + Mem_Free(SXW_AVG.biomass_grass_avg); + Mem_Free(SXW_AVG.biomass_shrub_avg); + Mem_Free(SXW_AVG.biomass_tree_avg); + Mem_Free(SXW_AVG.biomass_forb_avg); + Mem_Free(SXW_AVG.biomass_total_avg); + + Mem_Free(SXW_AVG.biolive_grass_avg); + Mem_Free(SXW_AVG.biolive_shrub_avg); + Mem_Free(SXW_AVG.biolive_tree_avg); + Mem_Free(SXW_AVG.biolive_forb_avg); + Mem_Free(SXW_AVG.biolive_total_avg); + + Mem_Free(SXW_AVG.bio_mult_grass_avg); + Mem_Free(SXW_AVG.bio_mult_shrub_avg); + Mem_Free(SXW_AVG.bio_mult_tree_avg); + Mem_Free(SXW_AVG.bio_mult_forb_avg); + + Mem_Free(SXW_AVG.wue_mult_grass_avg); + Mem_Free(SXW_AVG.wue_mult_shrub_avg); + Mem_Free(SXW_AVG.wue_mult_tree_avg); + Mem_Free(SXW_AVG.wue_mult_forb_avg); } /***********************************************************/ diff --git a/sxw.h b/sxw.h index 1def1e4a..0dc5a33c 100644 --- a/sxw.h +++ b/sxw.h @@ -26,8 +26,10 @@ #include "generic.h" #include "SW_Times.h" +#include "ST_defines.h" int getNTranspLayers(int veg_prod_type); +void free_all_sxw_memory( void ); struct stepwat_st { RealD *transpTotal; /* points to dynamic array indexed by Ilp() */ @@ -35,6 +37,13 @@ struct stepwat_st { RealD *transpShrubs; RealD *transpForbs; RealD *transpGrasses; + + RealD *transpTotal_avg, + *transpTrees_avg, + *transpShrubs_avg, + *transpForbs_avg, + *transpGrasses_avg; + RealF temp, /* soilwat's MAT */ ppt; /* soilwat's MAP */ TimeInt NPds; /* number of transp periods= maxdays, maxweeks, maxmonths */ @@ -53,16 +62,115 @@ struct stepwat_st { /* DEBUG stuff */ char *debugfile; /* added in ST_Main(), read to get debug instructions */ RealF *swc, /* dynamic array(Ilp) of SWC from SOILWAT */ - aet; /* soilwat's evapotranspiration for the year */ + aet; + /* soilwat's evapotranspiration for the year */ RealD surfaceTemp; /* soilwat's surfaceTemp */ -}; + // PPT variables + int yearInterval, // keep track of years + curMonth; -#define SXW_NFILES 5 + RealF PPT_sum, + PPT_rain, + PPT_snow_fall, + PPT_snow_melt, + PPT_snow_loss; + RealF *SWA_grass_avg, // 2D array to store SWA vals ([days of year][number of max layers]) + *SWA_shrub_avg, + *SWA_tree_avg, + *SWA_forb_avg; + RealF *sum_dSWA_repartitioned; + + RealF transp_SWA[MAX_YEARS][11]; // store the sum of SWA and transp for each year and resource. transp_SWA[year][steppe_resource_group] +}; + +struct soilwat_average{ + RealF *soilinfilt_avg, + *runoff_total_avg, + *surface_runoff_avg, + *surface_runon_avg, + *runoff_snow_avg, + *vwcbulk_avg, + *vwcmatric_avg, + *swamatric_avg, + *swabulk_avg, + *swpmatric_avg, + *surfacewater_avg, + *evapsoil_avg, + *evapsurface_total_avg, + *evapsurface_tree_avg, + *evapsurface_shrub_avg, + *evapsurface_forb_avg, + *evapsurface_grass_avg, + *evapsurface_litter_avg, + *evapsurface_water_avg, + + *interception_total_avg, + *interception_tree_avg, + *interception_shrub_avg, + *interception_forb_avg, + *interception_grass_avg, + *interception_litter_avg, + + *lyrdrain_avg, + + *hydred_total_avg, + *hydred_tree_avg, + *hydred_shrub_avg, + *hydred_forb_avg, + *hydred_grass_avg, + + *pet_avg, + *wetday_avg, + *snowpack_water_eqv_avg, + *snowpack_depth_avg, + *deepswc_avg, + *soiltemp_avg, + *estab_avg, + *max_temp_avg, + *min_temp_avg, + *avg_temp_avg, + *aet_avg, + *ppt_avg, + *val_rain_avg, + *val_snow_avg, + *val_snowmelt_avg, + *val_snowloss_avg; + + RealD *surfaceTemp_avg; + + // Carbon Variables + RealD *biomass_grass_avg, + *biomass_shrub_avg, + *biomass_tree_avg, + *biomass_forb_avg, + *biomass_total_avg, + + *biolive_grass_avg, + *biolive_shrub_avg, + *biolive_tree_avg, + *biolive_forb_avg, + *biolive_total_avg, + + *bio_mult_grass_avg, + *bio_mult_shrub_avg, + *bio_mult_tree_avg, + *bio_mult_forb_avg, + + *wue_mult_grass_avg, + *wue_mult_shrub_avg, + *wue_mult_tree_avg, + *wue_mult_forb_avg; + + RealF *swc_avg; +}; + +#define SXW_NFILES 5 typedef struct stepwat_st SXW_t; +typedef struct soilwat_average SXW_avg; #define ForEachTrPeriod(i) for((i)=0; (i)< SXW.NPds; (i)++) @@ -76,6 +184,24 @@ typedef struct stepwat_st SXW_t; */ #define Itlp(t,l,p) (((t)*SXW.NTrLyrs*SXW.NPds) + ((l)*SXW.NPds) + (p)) +/* convert 4-d index to actual array index for + * veg-prod-type/crit-value/layer/phenology + */ + //veg_type, new_critical_value, layer, timeperiod +#define Itclp(t,c,l,p) (((t)*SXW.NTrLyrs*SXW.NPds) + ((c)*NVEGTYPES) + ((l)*SXW.NPds) + (p)) // c*4 is because there are 4 critical values + +// for use with avg values +// year, layer, timeperiod, avg/std +#define Iylp(y,l,p,pd,x) (((y)*Globals.runModelYears * SXW.NTrLyrs * 4 * SXW.NPds * 2) + ((l)*SXW.NTrLyrs * 4 * SXW.NPds * 2) + ((p) * 4 * SXW.NPds * 2) + ((pd)*4*2) + ((x) * 2)) + +// for soilwat average and standard deviation +// year, timeperiod, choice (avg or std), timeperiod (dy, wk, mo, yr) +// difference between p and b is p is current period within period (ie. for day it could be 0 to 364) and b is just timeperiod (0 to 3 where 0 is day and 3 is yr) +#define Iypc(y,p,c,b) (((y)*Globals.runModelYears * SXW.NPds * NVEGTYPES) + ((p)*SXW.NPds * NVEGTYPES) + ((c) * NVEGTYPES) + (b)) + +// veg type, layer, timeperiod +#define Ivlp(v,l,p) (((v)*NVEGTYPES * SXW.NTrLyrs * SXW.NPds) + ((l)*SXW.NTrLyrs * SXW.NPds) + ((p)*SXW.NPds)) + /* convert 2d layer by period indices to layer/phenology 1D index */ #define Ilp(l,p) ((l)*SXW.NPds + (p)) diff --git a/sxw_resource.c b/sxw_resource.c index cb2bacc5..a963ff94 100644 --- a/sxw_resource.c +++ b/sxw_resource.c @@ -49,7 +49,7 @@ /* for steppe, see ST_globals.h */ //extern SW_SITE SW_Site; -//extern SW_MODEL SW_Model; +extern SW_MODEL SW_Model; //extern SW_SOILWAT SW_Soilwat; //extern SW_VEGPROD SW_VegProd; @@ -76,7 +76,7 @@ extern extern RealF _resource_pr[MAX_RGROUPS], /* resource convertable to pr */ - _resource_cur[MAX_RGROUPS]; /* current resource utilization */ + _resource_cur[MAX_RGROUPS]; extern RealF _bvt; @@ -88,6 +88,8 @@ extern static void _transp_contribution_by_group(RealF use_by_group[]); +static void _SWA_contribution_by_group(RealF use_by_group[]); + /***********************************************************/ /****************** Begin Function Code ********************/ @@ -122,10 +124,13 @@ void _sxw_update_resource(void) { RealF sizes[MAX_RGROUPS] = {0.}; GrpIndex g; - SppIndex sp; - int i; + int currentYear; + if(SW_Model.year == 0) currentYear = 0; + else currentYear = SW_Model.year - SW_Model.startyr; #ifdef SXW_BYMAXSIZE + int i; + SppIndex sp; ForEachGroup(g) { sizes[g] = 0.; if (RGroup[g]->regen_ok) { @@ -148,11 +153,14 @@ void _sxw_update_resource(void) { _sxw_update_root_tables(sizes); _transp_contribution_by_group(_resource_cur); + _SWA_contribution_by_group(SXW.sum_dSWA_repartitioned); ForEachGroup(g) { - //_resource_pr[g] = ZRO(sizes[g]) ? 0.0 : _resource_cur[g] * _bvt / sizes[g]; + _resource_cur[g] = SXW.transp_SWA[currentYear][g]; + //printf("for groupName= %smresource_cur prior to multiplication: %f\n",RGroup[g]->name, _resource_cur[g]); _resource_cur[g] = _resource_cur[g] * _bvt; + //printf("for groupName= %s, resource_cur post multiplication: %f\n\n",Rgroup[g]->name, _resource_cur[g]); } /* _print_debuginfo(); */ } @@ -182,7 +190,7 @@ void _sxw_update_root_tables( RealF sizes[] ) { { x = _rootsXphen[Iglp(g, l, p)] * sizes[g]; _roots_active[Iglp(g, l, p)] = x; - _roots_active_sum[Itlp(t,l, p)] += x; + _roots_active_sum[Itlp(t, l, p)] += x; } } } @@ -212,61 +220,63 @@ void _sxw_update_root_tables( RealF sizes[] ) { static void _transp_contribution_by_group(RealF use_by_group[]) { /*======================================================*/ - /* - * use_by_group is the vector to be used in the resource - * availability calculation, ie, the output. - - * must call _update_root_tables() before this. - * - */ - - /* compute each group's contribution to the - * transpiration values retrieved from SOILWAT based - * on its relative size, its root distribution, and - * its phenology (activity). - */ + /* use_by_group is the amount of transpiration (cm) assigned + * to each STEPPE functional group. + * Must call _update_root_tables() before this. + * Compute each group's amount of transpiration from SOILWAT2 + * based on its biomass, root distribution, and phenological + * activity. */ GrpIndex g; - SppIndex s; TimeInt p; LyrIndex l; - int t,i; + int currentYear; + if(SW_Model.year == 0) currentYear = 0; + else currentYear = SW_Model.year - SW_Model.startyr; + int t; RealD *transp; RealF sumUsedByGroup = 0., sumTranspTotal = 0., TranspRemaining = 0.; - ForEachGroup(g) + ForEachGroup(g) //Steppe functional group { - use_by_group[g] = 0.; /* clear */ + use_by_group[g] = 0.; t = RGroup[g]->veg_prod_type-1; + switch(t) { case 0://Tree - transp = SXW.transpTotal; + transp = SXW.transpTrees; break; case 1://Shrub - transp = SXW.transpTotal; + transp = SXW.transpShrubs; break; case 2://Grass - transp = SXW.transpTotal; + transp = SXW.transpGrasses; break; case 3://Forb - transp = SXW.transpTotal; + transp = SXW.transpForbs; break; default: transp = SXW.transpTotal; break; } - ForEachTrPeriod(p) - { - int nLyrs = getNTranspLayers(RGroup[g]->veg_prod_type); - for (l = 0; l < nLyrs; l++) { - use_by_group[g] += (RealF) (_roots_active_rel[Iglp(g, l, p)] * RGroup[g]->min_res_req * transp[Ilp(l, p)]); - //printf("for groupName= %s, layerIndex: %d after sum use_by_group[g]= %f \n",RGroup[g]->name,l,use_by_group[g] ); - } - } - sumUsedByGroup += use_by_group[g]; + + //Loops through each month and calculates amount of transpiration for each steppe functional group + //according to whether that group has active living roots in each soil layer for each month + ForEachTrPeriod(p) + { + int nLyrs = getNTranspLayers(RGroup[g]->veg_prod_type); + for (l = 0; l < nLyrs; l++) { + use_by_group[g] += (RealF) (_roots_active_rel[Iglp(g, l, p)] * transp[Ilp(l, p)]); + } + } + //printf("for groupName= %s, use_by_group[g] in transp= %f \n",RGroup[g]->name,use_by_group[g] ); + + sumUsedByGroup += use_by_group[g]; + //printf(" sumUsedByGroup in transp=%f \n",sumUsedByGroup); } - //Occasionally, extra transpiration remains and if not perfectly partitioned to RGroups. - //This check makes sure any remaining transpiration is divided proportionately among Rgroups. + + //Very small amounts of transpiration remain and not perfectly partitioned to functional groups. + //This check makes sure any remaining transpiration is divided proportionately among groups. ForEachTrPeriod(p) { for (t = 0; t < SXW.NSoLyrs; t++) @@ -274,14 +284,57 @@ static void _transp_contribution_by_group(RealF use_by_group[]) { } TranspRemaining = sumTranspTotal - sumUsedByGroup; //printf(" sumTranspTotal=%f, sumUsedByGroup=%f TranspRemaining=%f \n",sumTranspTotal,sumUsedByGroup,TranspRemaining); - ForEachGroup(g) + + ForEachGroup(g) { if(!ZRO(use_by_group[g])) { use_by_group[g] += (use_by_group[g]/sumUsedByGroup) * TranspRemaining; - // printf("for groupName= %s, after sum use_by_group[g]= %f \n",RGroup[g]->name,use_by_group[g] ); - } - } + //printf("for groupName= %s, after sum use_by_group[g]= %f \n",RGroup[g]->name,use_by_group[g] ); + + SXW.transp_SWA[currentYear][g] = use_by_group[g]; + //printf("for groupName= %s, SXW.transp_SWA[g] in transp= %f \n",RGroup[g]->name,SXW.transp_SWA[currentYear][g]); + } + } } +static void _SWA_contribution_by_group(RealF use_by_group[]) { + /*======================================================*/ + /* use_by_group is the amount of plant available soil water (SWA,cm) + * assigned to each STEPPE functional group. + * Must call _update_root_tables() before this. + * Compute each group's amount of SWA from SOILWAT2 + * based on its biomass, root distribution, and phenological + * activity. */ + GrpIndex g; + TimeInt p; + LyrIndex l; + int currentYear; + if(SW_Model.year == 0) currentYear = 0; + else currentYear = SW_Model.year - SW_Model.startyr; + int t; + RealF sumUsedByGroup = 0.; + + ForEachGroup(g) //Steppe functional group + { + use_by_group[g] = 0.; + t = RGroup[g]->veg_prod_type-1; + //printf("g, t || %d, %d\n", g, t); + ForEachTrPeriod(p) + { + for (l = 0; l < SXW.NSoLyrs; l++) { + //printf("%d,%d,%d\n", t,l,p); + use_by_group[g] += (RealF) (_roots_active_rel[Iglp(g, l, p)] * SXW.sum_dSWA_repartitioned[Ivlp(t,l,p)]); + //printf("for groupName= %s, layerIndex: %d, month: %d, in swa loop use_by_group[g]= %f \n",RGroup[g]->name,l,p,use_by_group[g]); + } + } + //printf("for groupName= %s, use_by_group[g] in swa= %f \n",RGroup[g]->name,use_by_group[g]); + + sumUsedByGroup += use_by_group[g]; + //printf(" sumUsedByGroup in swa=%f \n",sumUsedByGroup); + + SXW.transp_SWA[currentYear][g] += use_by_group[g]; + //printf("SXW.transp_SWA[%d][%d]: %f\n", currentYear, g, SXW.transp_SWA[currentYear][g]); + } +} diff --git a/sxw_soilwat.c b/sxw_soilwat.c index 97041784..aff4d932 100644 --- a/sxw_soilwat.c +++ b/sxw_soilwat.c @@ -95,25 +95,25 @@ void _sxw_sw_setup (RealF sizes[]) { #ifndef SXW_BYMAXSIZE for (doy = 1; doy <= MAX_DAYS; doy++) { - v->tree.litter_daily[doy] = 0; - v->grass.litter_daily[doy] = 0; - v->shrub.litter_daily[doy] = 0; - v->forb.litter_daily[doy] = 0; - - v->tree.biomass_daily[doy] = 0; - v->grass.biomass_daily[doy] = 0; - v->shrub.biomass_daily[doy] = 0; - v->forb.biomass_daily[doy] = 0; - - v->tree.pct_live_daily[doy] = 0; - v->grass.pct_live_daily[doy] = 0; - v->shrub.pct_live_daily[doy] = 0; - v->forb.pct_live_daily[doy] = 0; - - v->tree.lai_conv_daily[doy] = 0; - v->grass.lai_conv_daily[doy] = 0; - v->shrub.lai_conv_daily[doy] = 0; - v->forb.lai_conv_daily[doy] = 0; + v->veg[0].litter_daily[doy] = 0; + v->veg[3].litter_daily[doy] = 0; + v->veg[1].litter_daily[doy] = 0; + v->veg[2].litter_daily[doy] = 0; + + v->veg[0].biomass_daily[doy] = 0; + v->veg[3].biomass_daily[doy] = 0; + v->veg[1].biomass_daily[doy] = 0; + v->veg[2].biomass_daily[doy] = 0; + + v->veg[0].pct_live_daily[doy] = 0; + v->veg[3].pct_live_daily[doy] = 0; + v->veg[1].pct_live_daily[doy] = 0; + v->veg[2].pct_live_daily[doy] = 0; + + v->veg[0].lai_conv_daily[doy] = 0; + v->veg[3].lai_conv_daily[doy] = 0; + v->veg[1].lai_conv_daily[doy] = 0; + v->veg[2].lai_conv_daily[doy] = 0; } SW_VPD_init(); @@ -153,56 +153,56 @@ static void _update_transp_coeff(RealF relsize[]) { ForEachTreeTranspLayer(t) { y = SW_Site.lyr[t]; - y->transp_coeff_tree = 0.; + y->transp_coeff[0] = 0.; ForEachGroup(g) if(RGroup[g]->veg_prod_type == 1) if (getNTranspLayers(RGroup[g]->veg_prod_type)) - y->transp_coeff_tree += (RealF) _roots_max[Ilg(t, g)] * relsize[g]; - sum1 += y->transp_coeff_tree; + y->transp_coeff[0] += (RealF) _roots_max[Ilg(t, g)] * relsize[g]; + sum1 += y->transp_coeff[0]; } ForEachShrubTranspLayer(t) { y = SW_Site.lyr[t]; - y->transp_coeff_shrub = 0.; + y->transp_coeff[1] = 0.; ForEachGroup(g) if(RGroup[g]->veg_prod_type == 2) if (getNTranspLayers(RGroup[g]->veg_prod_type)) - y->transp_coeff_shrub += (RealF) _roots_max[Ilg(t, g)] * relsize[g]; - sum2 += y->transp_coeff_shrub; + y->transp_coeff[1] += (RealF) _roots_max[Ilg(t, g)] * relsize[g]; + sum2 += y->transp_coeff[1]; } ForEachGrassTranspLayer(t) { y = SW_Site.lyr[t]; - y->transp_coeff_grass = 0.; + y->transp_coeff[3] = 0.; ForEachGroup(g) if(RGroup[g]->veg_prod_type == 3) if (getNTranspLayers(RGroup[g]->veg_prod_type)) - y->transp_coeff_grass += (RealF) _roots_max[Ilg(t, g)] * relsize[g]; - sum3 += y->transp_coeff_grass; + y->transp_coeff[3] += (RealF) _roots_max[Ilg(t, g)] * relsize[g]; + sum3 += y->transp_coeff[3]; } ForEachForbTranspLayer(t) { y = SW_Site.lyr[t]; - y->transp_coeff_forb = 0.; + y->transp_coeff[2] = 0.; ForEachGroup(g) if(RGroup[g]->veg_prod_type == 4) if (getNTranspLayers(RGroup[g]->veg_prod_type)) - y->transp_coeff_forb += (RealF) _roots_max[Ilg(t, g)] * relsize[g]; - sum4 += y->transp_coeff_forb; + y->transp_coeff[2] += (RealF) _roots_max[Ilg(t, g)] * relsize[g]; + sum4 += y->transp_coeff[2]; } /* normalize coefficients to 1.0 If sum is 0, then the transp_coeff is also 0. */ ForEachTreeTranspLayer(t) - if(!ZRO(sum1)) SW_Site.lyr[t]->transp_coeff_tree /= sum1; + if(!ZRO(sum1)) SW_Site.lyr[t]->transp_coeff[0] /= sum1; ForEachShrubTranspLayer(t) - if(!ZRO(sum2)) SW_Site.lyr[t]->transp_coeff_shrub /= sum2; + if(!ZRO(sum2)) SW_Site.lyr[t]->transp_coeff[1] /= sum2; ForEachGrassTranspLayer(t) - if(!ZRO(sum3)) SW_Site.lyr[t]->transp_coeff_grass /= sum3; + if(!ZRO(sum3)) SW_Site.lyr[t]->transp_coeff[3] /= sum3; ForEachForbTranspLayer(t) - if(!ZRO(sum4)) SW_Site.lyr[t]->transp_coeff_forb /= sum4; + if(!ZRO(sum4)) SW_Site.lyr[t]->transp_coeff[2] /= sum4; } @@ -259,60 +259,59 @@ static void _update_productivity(void) { /* compute monthly biomass, litter, and pct live per month */ ForEachMonth(m) { - v->tree.pct_live[m] = 0.; - v->tree.biomass[m] = 0.; - v->tree.litter[m] = 0.; - v->shrub.pct_live[m] = 0.; - v->shrub.biomass[m] = 0.; - v->shrub.litter[m] = 0.; - v->grass.pct_live[m] = 0.; - v->grass.biomass[m] = 0.; - v->grass.litter[m] = 0.; - v->forb.pct_live[m] = 0.; - v->forb.biomass[m] = 0.; - v->forb.litter[m] = 0.; + v->veg[0].pct_live[m] = 0.; + v->veg[0].biomass[m] = 0.; + v->veg[0].litter[m] = 0.; + v->veg[1].pct_live[m] = 0.; + v->veg[1].biomass[m] = 0.; + v->veg[1].litter[m] = 0.; + v->veg[3].pct_live[m] = 0.; + v->veg[3].biomass[m] = 0.; + v->veg[3].litter[m] = 0.; + v->veg[2].pct_live[m] = 0.; + v->veg[2].biomass[m] = 0.; + v->veg[2].litter[m] = 0.; if (GT(totbmass, 0.)) { ForEachGroup(g) { if (1 == RGroup[g]->veg_prod_type) { //tree - v->tree.pct_live[m] += _prod_pctlive[Igp(g, m)] * rgroupFractionOfVegTypeBiomass[g]; - v->tree.biomass[m] += _prod_bmass[Igp(g, m)] * bmassg[g]; + v->veg[0].pct_live[m] += _prod_pctlive[Igp(g, m)] * rgroupFractionOfVegTypeBiomass[g]; + v->veg[0].biomass[m] += _prod_bmass[Igp(g, m)] * bmassg[g]; } else if (2 == RGroup[g]->veg_prod_type) { //shrub - v->shrub.pct_live[m] += _prod_pctlive[Igp(g, m)] * rgroupFractionOfVegTypeBiomass[g]; - v->shrub.biomass[m] += _prod_bmass[Igp(g, m)] * bmassg[g]; + v->veg[1].pct_live[m] += _prod_pctlive[Igp(g, m)] * rgroupFractionOfVegTypeBiomass[g]; + v->veg[1].biomass[m] += _prod_bmass[Igp(g, m)] * bmassg[g]; } else if (3 == RGroup[g]->veg_prod_type) { //grass - v->grass.pct_live[m] += _prod_pctlive[Igp(g, m)] * rgroupFractionOfVegTypeBiomass[g]; - v->grass.biomass[m] += _prod_bmass[Igp(g, m)] * bmassg[g]; + v->veg[3].pct_live[m] += _prod_pctlive[Igp(g, m)] * rgroupFractionOfVegTypeBiomass[g]; + v->veg[3].biomass[m] += _prod_bmass[Igp(g, m)] * bmassg[g]; } else if (4 == RGroup[g]->veg_prod_type) { //forb - v->forb.pct_live[m] += _prod_pctlive[Igp(g, m)] * rgroupFractionOfVegTypeBiomass[g]; - v->forb.biomass[m] += _prod_bmass[Igp(g, m)] * bmassg[g]; + v->veg[2].pct_live[m] += _prod_pctlive[Igp(g, m)] * rgroupFractionOfVegTypeBiomass[g]; + v->veg[2].biomass[m] += _prod_bmass[Igp(g, m)] * bmassg[g]; } } - v->tree.litter[m] = (vegTypeBiomass[0] * _prod_litter[m]); - v->shrub.litter[m] = (vegTypeBiomass[1] * _prod_litter[m]); - v->grass.litter[m] = (vegTypeBiomass[2] * _prod_litter[m]); - v->forb.litter[m] = (vegTypeBiomass[3] * _prod_litter[m]); + v->veg[0].litter[m] = (vegTypeBiomass[0] * _prod_litter[m]); + v->veg[1].litter[m] = (vegTypeBiomass[1] * _prod_litter[m]); + v->veg[3].litter[m] = (vegTypeBiomass[2] * _prod_litter[m]); + v->veg[2].litter[m] = (vegTypeBiomass[3] * _prod_litter[m]); } } if (GT(totbmass, 0.)) { //if (ZRO(biomass)) // biomass = 1; - v->tree.cov.fCover = (vegTypeBiomass[0] / totbmass); - v->shrub.cov.fCover = (vegTypeBiomass[1] / totbmass); - v->grass.cov.fCover = (vegTypeBiomass[2] / totbmass); - v->forb.cov.fCover = (vegTypeBiomass[3] / totbmass); + v->veg[0].cov.fCover = (vegTypeBiomass[0] / totbmass); + v->veg[1].cov.fCover = (vegTypeBiomass[1] / totbmass); + v->veg[3].cov.fCover = (vegTypeBiomass[2] / totbmass); + v->veg[2].cov.fCover = (vegTypeBiomass[3] / totbmass); //TODO: figure how to calculate bareground fraction. v->bare_cov.fCover = 0; } else { - v->tree.cov.fCover = (0.0); - v->shrub.cov.fCover = (0.0); - v->grass.cov.fCover = (0.0); - v->forb.cov.fCover = (0.0); + v->veg[0].cov.fCover = (0.0); + v->veg[1].cov.fCover = (0.0); + v->veg[3].cov.fCover = (0.0); + v->veg[2].cov.fCover = (0.0); v->bare_cov.fCover = 1; } #undef Biomass } - diff --git a/sxw_sql.c b/sxw_sql.c index ee01f24a..ffc5ed26 100644 --- a/sxw_sql.c +++ b/sxw_sql.c @@ -221,7 +221,7 @@ void insertInputVars() { SW_VEGPROD *v = &SW_VegProd; beginTransaction(); - insertSXWinputVarsRow(Year, Iteration, v->grass.cov.fCover, v->shrub.cov.fCover, v->tree.cov.fCover, v->forb.cov.fCover, v->bare_cov.fCover); + insertSXWinputVarsRow(Year, Iteration, v->veg[3].cov.fCover, v->veg[1].cov.fCover, v->veg[0].cov.fCover, v->veg[2].cov.fCover, v->bare_cov.fCover); endTransaction(); } @@ -256,10 +256,10 @@ void insertInputProd() { beginTransaction(); ForEachTrPeriod(p) { - insertSXWinputProdRow(Year, Iteration, 1, p+1, v->tree.litter[p], v->tree.biomass[p], v->tree.pct_live[p], v->tree.lai_conv[p]); - insertSXWinputProdRow(Year, Iteration, 2, p+1, v->shrub.litter[p], v->shrub.biomass[p], v->shrub.pct_live[p], v->shrub.lai_conv[p]); - insertSXWinputProdRow(Year, Iteration, 3, p+1, v->grass.litter[p], v->grass.biomass[p], v->grass.pct_live[p], v->grass.lai_conv[p]); - insertSXWinputProdRow(Year, Iteration, 4, p+1, v->forb.litter[p], v->forb.biomass[p], v->forb.pct_live[p], v->forb.lai_conv[p]); + insertSXWinputProdRow(Year, Iteration, 1, p+1, v->veg[0].litter[p], v->veg[0].biomass[p], v->veg[0].pct_live[p], v->veg[0].lai_conv[p]); + insertSXWinputProdRow(Year, Iteration, 2, p+1, v->veg[1].litter[p], v->veg[1].biomass[p], v->veg[1].pct_live[p], v->veg[1].lai_conv[p]); + insertSXWinputProdRow(Year, Iteration, 3, p+1, v->veg[3].litter[p], v->veg[3].biomass[p], v->veg[3].pct_live[p], v->veg[3].lai_conv[p]); + insertSXWinputProdRow(Year, Iteration, 4, p+1, v->veg[2].litter[p], v->veg[2].biomass[p], v->veg[2].pct_live[p], v->veg[2].lai_conv[p]); } endTransaction(); } @@ -295,7 +295,7 @@ void insertInputSoils() { beginTransaction(); ForEachSoilLayer(l) { - insertSXWinputSoilsRow(Year, Iteration, l+1, s->lyr[l]->transp_coeff_tree, s->lyr[l]->transp_coeff_shrub, s->lyr[l]->transp_coeff_grass, s->lyr[l]->transp_coeff_forb); + insertSXWinputSoilsRow(Year, Iteration, l+1, s->lyr[l]->transp_coeff[0], s->lyr[l]->transp_coeff[1], s->lyr[l]->transp_coeff[3], s->lyr[l]->transp_coeff[2]); } endTransaction(); } @@ -417,24 +417,24 @@ void insertOutputProd(SW_VEGPROD *v) { } // all the other months have 31 days for (i = doy; i < (doy + days); i++) { //accumulating the monthly values... - lai_live += (v->tree.lai_live_daily[i]) - + (v->shrub.lai_live_daily[i]) - + (v->grass.lai_live_daily[i]) - + (v->forb.lai_live_daily[i]); - vegcov += (v->tree.vegcov_daily[i]) + (v->shrub.vegcov_daily[i]) - + (v->grass.vegcov_daily[i]) + (v->forb.vegcov_daily[i]); - total_agb += (v->tree.total_agb_daily[i]) - + (v->shrub.total_agb_daily[i]) - + (v->grass.total_agb_daily[i]) - + (v->forb.total_agb_daily[i]); - pct_live += (v->tree.pct_live_daily[i]) - + (v->shrub.pct_live_daily[i]) - + (v->grass.pct_live_daily[i]) - + (v->forb.pct_live_daily[i]); - biomass += (v->tree.biomass_daily[i]) - + (v->shrub.biomass_daily[i]) - + (v->grass.biomass_daily[i]) - + (v->forb.biomass_daily[i]); + lai_live += (v->veg[0].lai_live_daily[i]) + + (v->veg[1].lai_live_daily[i]) + + (v->veg[3].lai_live_daily[i]) + + (v->veg[2].lai_live_daily[i]); + vegcov += (v->veg[0].vegcov_daily[i]) + (v->veg[1].vegcov_daily[i]) + + (v->veg[3].vegcov_daily[i]) + (v->veg[2].vegcov_daily[i]); + total_agb += (v->veg[0].total_agb_daily[i]) + + (v->veg[1].total_agb_daily[i]) + + (v->veg[3].total_agb_daily[i]) + + (v->veg[2].total_agb_daily[i]); + pct_live += (v->veg[0].pct_live_daily[i]) + + (v->veg[1].pct_live_daily[i]) + + (v->veg[3].pct_live_daily[i]) + + (v->veg[2].pct_live_daily[i]); + biomass += (v->veg[0].biomass_daily[i]) + + (v->veg[1].biomass_daily[i]) + + (v->veg[3].biomass_daily[i]) + + (v->veg[2].biomass_daily[i]); } doy += days; //updating the doy diff --git a/testing.sagebrush.master/Stepwat_Inputs/Input/sxw/Input/outsetup_v30.in b/testing.sagebrush.master/Stepwat_Inputs/Input/sxw/Input/outsetup_v30.in index b1fb0ccc..6a383045 100644 --- a/testing.sagebrush.master/Stepwat_Inputs/Input/sxw/Input/outsetup_v30.in +++ b/testing.sagebrush.master/Stepwat_Inputs/Input/sxw/Input/outsetup_v30.in @@ -1,5 +1,64 @@ -TRANSP SUM MO 1 end transp -PRECIP SUM YR 1 end precip -TEMP AVG YR 1 end temp -AET SUM YR 1 end aet -SWCBULK FIN MO 1 end swc_bulk +# Output setup file for SOILWAT2 +# +# Notes: +# Time periods available: DY,WK,MO,YR +# eg, if DY is chosen then 100,200 would mean to use the second hundred days +# But if YR is chosen, start and end numbers are in days so only those days +# are reported for the yearly average. +# Some keys from older versions (fortran and the c versions mimicking the fortran +# version) are not currently implemented: +# ALLH20, WTHR. +# +# ESTABL only produces yearly output, namely, DOY for each species requested. +# Thus, to minimize typo errors, all flags are ignored except the filename. +# Output is simply the day of the year establishment occurred for each species +# in each year of the model run. Refer to the estabs.in file for more info. +# +# DEEPSWC produces output only if the deepdrain flag is set in siteparam.in. +# +# Filename prefixes should not have a file extension. +# Case is unimportant. +# +# SUMTYPEs are one of the following: +# OFF - no output for this variable +# SUM - sum the variable for each day in the output period +# AVG - average the variable over the output period +# FIN - output value of final day in the period; soil water variables only. +# Note that SUM and AVG are the same if timeperiod = dy. +# +# (01/17/2013) TIMESTEP key indicates which periods you want to output. +# You can output all the periods at a time, just one, or however many +# you want. To change which periods to output type 'dy' for day, +# 'wk' for week, 'mo' for month, and 'yr' for year after TIMESTEP +# in any order. For example: 'TIMESTEP mo wk' will output for month and week + +TIMESTEP dy yr # must be lowercase + +# key SUMTYPE PERIOD start end filename_prefix comment + TEMP AVG YR 1 end temp_air /* max., min, average temperature (C) */ + PRECIP SUM YR 1 end precip /* total precip = sum(rain, snow), rain, snow-fall, snowmelt, and snowloss (cm) */ + SOILINFILT SUM YR 1 end infiltration /* water to infiltrate in top soil layer (cm), runoff (cm); (not-intercepted rain)+(snowmelt-runoff) */ + RUNOFF SUM YR 1 end runoff /* runoff/runon (cm): net runoff, runoff from ponded water, runoff from snowmelt, runon of surface water from hypothetical upslope neighbor */ + VWCBULK AVG YR 1 end vwc_bulk /* bulk volumetric soilwater (cm / layer) */ + VWCMATRIC AVG YR 1 end vwc_matric /* matric volumetric soilwater (cm / layer) */ + SWCBULK AVG YR 1 end swc_bulk /* bulk soilwater content (cm / cm layer); swc.l1(today) = swc.l1(yesterday)+inf_soil-lyrdrain.l1-transp.l1-evap_soil.l1; swc.li(today) = swc.li(yesterday)+lyrdrain.l(i-1)-lyrdrain.li-transp.li-evap_soil.li; swc.llast(today) = swc.llast(yesterday)+lyrdrain.l(last-1)-deepswc-transp.llast-evap_soil.llast */ + SWA AVG YR 1 end swa /* plant available soil water (cm / layer): trees, shrubs, forbs, grasses */ + SWABULK AVG YR 1 end swa_bulk /* DEFUNCT: MAY BE REMOVED IN FUTURE VERSIONS; bulk available soil water (cm/layer) = swc - wilting point */ + SWAMATRIC AVG YR 1 end swa_matric /* DEFUNCT: MAY BE REMOVED IN FUTURE VERSIONS; matric available soil water (cm/layer) = swc - wilting point */ + SWPMATRIC AVG YR 1 end swp_matric /* matric soilwater potential (-bars) */ + SURFACEWATER AVG YR 1 end surface_water /* surface water (cm) */ + TRANSP SUM YR 1 end transp /* transpiration from each soil layer (cm): total, trees, shrubs, forbs, grasses */ + EVAPSOIL SUM YR 1 end evap_soil /* bare-soil evaporation from each soil layer (cm) */ + EVAPSURFACE SUM YR 1 end evap_surface /* evaporation (cm): total, trees, shrubs, forbs, grasses, litter, surface water */ + INTERCEPTION SUM YR 1 end interception /* intercepted rain (cm): total, trees, shrubs, forbs, grasses, and litter (cm) */ + LYRDRAIN SUM YR 1 end percolation /* water percolated from each layer (cm) */ + HYDRED SUM YR 1 end hydred /* hydraulic redistribution from each layer (cm): total, trees, shrubs, forbs, grasses */ + AET SUM YR 1 end aet /* actual evapotr. (cm) */ + PET SUM YR 1 end pet /* potential evaptr (cm) */ + WETDAY SUM YR 1 end wetdays /* days above swc_wet */ + SNOWPACK AVG YR 1 end snowpack /* snowpack water equivalent (cm), snowdepth (cm); since snowpack is already summed, use avg - sum sums the sums = nonsense */ + DEEPSWC SUM YR 1 end deep_drain /* deep drainage into lowest layer (cm) */ + SOILTEMP AVG YR 1 end temp_soil /* soil temperature from each soil layer (in celsius) */ + ESTABL OFF YR 1 end estabs /* yearly establishment results */ + CO2EFFECTS AVG YR 1 end vegetation /* vegetation biomass: biomass (g/m2) for grasses, shrubs, trees, forbs, and total; live biomass (g/m2) fgrasses, shrubs, trees, forbs, and total; biomass CO2-effect (multiplier) for grasses, shrubs, trees, and forbs; WUE CO2-effect (multiplier) for grasses, shrubs, trees, and forbs + diff --git a/testing.sagebrush.master/Stepwat_Inputs/Input/sxw/Input/years.in b/testing.sagebrush.master/Stepwat_Inputs/Input/sxw/Input/years.in index 739acd21..e6aa7400 100644 --- a/testing.sagebrush.master/Stepwat_Inputs/Input/sxw/Input/years.in +++ b/testing.sagebrush.master/Stepwat_Inputs/Input/sxw/Input/years.in @@ -2,7 +2,7 @@ # Location: P1 1980 # starting year (but see weather and swc inputs) -2280 # ending year +2020 # ending year 1 # first day of first year 365 # ending day of last year N # hemisphere (N,S) diff --git a/testing.sagebrush.master/Stepwat_Inputs/Input/sxw/files_v30.in b/testing.sagebrush.master/Stepwat_Inputs/Input/sxw/files_v30.in index c41cb3a8..705a6b92 100644 --- a/testing.sagebrush.master/Stepwat_Inputs/Input/sxw/files_v30.in +++ b/testing.sagebrush.master/Stepwat_Inputs/Input/sxw/files_v30.in @@ -27,5 +27,14 @@ Input/carbon.in Input/swcsetup.in # params for handling measured swc #Output -Output # 'relative' path for output files: / for same directory, or e.g., Output/ +Output/ # 'relative' path for output files: / for same directory, or e.g., Output/ Input/outsetup_v30.in # define output quantities +Output/sw_output/sw2_daily.csv #output +Output/sw_output/sw2_weekly.csv #output +Output/sw_output/sw2_monthly.csv #output +Output/sw_output/sw2_yearly.csv #output + +Output/sw_output/sw2_daily_slyrs.csv #output +Output/sw_output/sw2_weekly_slyrs.csv #output +Output/sw_output/sw2_monthly_slyrs.csv #output +Output/sw_output/sw2_yearly_slyrs.csv #output