From 9690c04a41b2453265757a634a1f3d63186fc53d Mon Sep 17 00:00:00 2001 From: Chandler Haukap Date: Thu, 11 Apr 2019 10:29:30 -0600 Subject: [PATCH] Compress sxw.c variables into struct. I added a new struct to sxw.h that contains all of the local variables from sxw.c This way we can instantiate these variables in each grid cell when using gridded mode. I named this struct TempType for now until we agree on a new name. The implementation of this struct in sxw.c is called SXWTemp. I am commiting these changes so that I can move on to other issues, and will change the names once we come up with something descriptive. I also added two local variables to the transp_window struct: added_transp and lastYear. These were free floating variables that need to be cell specific. --- ST_grid.c | 3 +- sxw.c | 158 +++++++++++++++++++------------------------------ sxw.h | 50 ++++++++++++---- sxw_resource.c | 80 ++++++++----------------- sxw_soilwat.c | 40 ++++++------- sxw_sql.c | 16 +++-- 6 files changed, 151 insertions(+), 196 deletions(-) diff --git a/ST_grid.c b/ST_grid.c index 5d166a85..97219d25 100644 --- a/ST_grid.c +++ b/ST_grid.c @@ -191,11 +191,12 @@ extern SW_SITE SW_Site; extern SW_VEGPROD SW_VegProd; extern SW_WEATHER SW_Weather; extern pcg32_random_t grid_rng; //this file's unique random number generator + +/* We need to seed these RNGs when using the gridded mode but do not use them in this file. */ extern pcg32_random_t environs_rng; extern pcg32_random_t mortality_rng; extern pcg32_random_t resgroups_rng; extern pcg32_random_t species_rng; -extern pcg32_random_t grid_rng; extern pcg32_random_t markov_rng; //This is Rgroup structure pointer that will read rgroup disturbance value, will be used in diff --git a/sxw.c b/sxw.c index 871bb857..075ca126 100644 --- a/sxw.c +++ b/sxw.c @@ -82,56 +82,22 @@ extern SW_MARKOV SW_Markov; extern Bool prepare_IterationSummary; extern Bool storeAllIterations; - - /*************** Module/Local Variable Declarations ***************/ /***********************************************************/ /* these are initialized and maybe populated here but are used * in sxw_resource.c so they aren't declared static. */ -/* ----- 3d arrays ------- */ -RealD * _rootsXphen, /* relative roots X phen in each lyr,grp,pd */ - * _roots_active, /* "active" in terms of size and phenology */ - * _roots_active_rel; - - -/* ----- 2D arrays ------- */ -/* malloc'ed here for consistency but only used */ -/* in sxw_resource.c and sxw_soilwat.c */ - - /* rgroup by layer, ie, group-level values */ -RealD * _roots_max, /* read from root distr. file */ - * _roots_active_sum, /* used in sxw_resource */ - - /* rgroup by period */ - * _phen; /* phenology read from file */ - -/* simple vectors hold the resource information for each group */ -/* curr/equ gives the available/required ratio */ -RealF _resource_cur[MAX_RGROUPS], /* current resource availability for each STEPPE functional type */ - _resource_pr[MAX_RGROUPS]; /* resource convertable to PR */ - // Window of transpiration used by _transp_contribution_by_group() in sxw_resource.c // "Window" refers to the number of years over which transpiration data is averaged. transp_t transp_window; - -// Amount of additional transpiration added for the current year -RealF added_transp; - pcg32_random_t resource_rng; //rng for swx_resource.c functions. +TempType SXWTemp; #ifdef SXW_BYMAXSIZE /* addition to meet changes specified at the top of the file */ RealF _Grp_BMass[MAX_RGROUPS]; #endif -/* and one vector for the production constants */ -RealD _prod_litter[MAX_MONTHS]; -RealD * _prod_bmass; -RealD * _prod_pctlive; - -RealF _bvt; /* ratio of biomass/m2 / transp/m2 */ - /* These are only used here so they are static. */ // static char inbuf[FILENAME_MAX]; /* reusable input buffer */ static char _swOutDefName[FILENAME_MAX]; @@ -411,7 +377,7 @@ 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 */ - RealF pr = ZRO(_resource_pr[rg]) ? 0.0 : 1. / _resource_pr[rg]; + RealF pr = ZRO(SXWTemp._resource_pr[rg]) ? 0.0 : 1. / SXWTemp._resource_pr[rg]; return pr; //return pr > 10 ? 10 : pr; } @@ -421,7 +387,7 @@ RealF SXW_GetTranspiration( GrpIndex rg) { /* see _sxw_update_resource() for _resource_cur[] */ //printf("SXW_GetTranspiration _resource_cur[%d] = %.5f \n", rg, _resource_cur[rg]); - return _resource_cur[rg]; + return SXWTemp._resource_cur[rg]; } void SXW_PrintDebug(Bool cleanup) { @@ -444,16 +410,16 @@ void SXW_PrintDebug(Bool cleanup) { insertInfo(); insertSXWPhen(); insertSXWProd(); - insertRootsXphen(_rootsXphen); + insertRootsXphen(SXWTemp._rootsXphen); } insertInputVars(); insertInputProd(); insertInputSoils(); - insertOutputVars(_resource_cur, added_transp); - insertRgroupInfo(_resource_cur); + insertOutputVars(SXWTemp._resource_cur, transp_window.added_transp); + insertRgroupInfo(SXWTemp._resource_cur); insertOutputProd(&SW_VegProd); - insertRootsSum(_roots_active_sum); - insertRootsRelative(_roots_active_rel); + insertRootsSum(SXWTemp._roots_active_sum); + insertRootsRelative(SXWTemp._roots_active_rel); insertTranspiration(); insertSWCBulk(); } @@ -507,7 +473,7 @@ static void _read_roots_max(void) { cnt++; lyr = 0; while ((p = strtok(NULL, " \t"))) { - _roots_max[Ilg(lyr, g)] = atof(p); + SXWTemp._roots_max[Ilg(lyr, g)] = atof(p); lyr++; } if (lyr != SXW.NTrLyrs) { @@ -552,7 +518,7 @@ static void _read_phen(void) { LogError(logfp, LOGFATAL, "%s: More than 12 months of data found.", MyFileName); } - _phen[Igp(g,m)] = atof(p); + SXWTemp._phen[Igp(g,m)] = atof(p); m++; } @@ -590,7 +556,7 @@ static void _read_bvt(void) { CloseFile(&fp); - _bvt = bmass / transp; + SXWTemp._bvt = bmass / transp; } @@ -608,7 +574,7 @@ static void _read_prod(void) { fp = OpenFile(MyFileName, "r"); while (GetALine(fp, inbuf)) { - x = sscanf(inbuf, "%lf", &_prod_litter[mon]); + x = sscanf(inbuf, "%lf", &SXWTemp._prod_litter[mon]); if (x < 1) { LogError(logfp, LOGFATAL, "%s: invalid record for litter %d.", MyFileName, mon + 1); @@ -643,7 +609,7 @@ static void _read_prod(void) { LogError(logfp, LOGFATAL, "%s: More than 12 months of data found.", MyFileName); } - _prod_bmass[Igp(g, mon)] = atof(p); + SXWTemp._prod_bmass[Igp(g, mon)] = atof(p); mon++; } cnt++; @@ -678,7 +644,7 @@ static void _read_prod(void) { LogError(logfp, LOGFATAL, "%s: More than 12 months of data found.", MyFileName); } - _prod_pctlive[Igp(g, mon)] = atof(p); + SXWTemp._prod_pctlive[Igp(g, mon)] = atof(p); mon++; } cnt++; @@ -750,16 +716,16 @@ static void _make_roots_arrays(void) { char *fstr = "_make_roots_array()"; size = SXW.NGrps * SXW.NTrLyrs; - _roots_max = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); + SXWTemp._roots_max = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); size = SXW.NGrps * SXW.NPds * SXW.NTrLyrs; - _rootsXphen = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); - _roots_active = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); - _roots_active_rel = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); + SXWTemp._rootsXphen = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); + SXWTemp._roots_active = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); + SXWTemp._roots_active_rel = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); //4 - Grass,Frob,Tree,Shrub size = NVEGTYPES * SXW.NPds * SXW.NTrLyrs; - _roots_active_sum = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); + SXWTemp._roots_active_sum = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); } static void _make_phen_arrays(void) { @@ -768,7 +734,7 @@ static void _make_phen_arrays(void) { char *fstr = "_make_phen_arrays()"; size = SXW.NGrps * MAX_MONTHS; - _phen = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); + SXWTemp._phen = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); } @@ -777,8 +743,8 @@ static void _make_prod_arrays(void) { char *fstr = "_make_phen_arrays()"; size = SXW.NGrps * MAX_MONTHS; - _prod_bmass = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); - _prod_pctlive = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); + SXWTemp._prod_bmass = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); + SXWTemp._prod_pctlive = (RealD *) Mem_Calloc(size, sizeof(RealD), fstr); } static void _make_transp_arrays(void) { @@ -928,7 +894,7 @@ void _print_debuginfo(void) { //ForEachTranspLayer(t) { fprintf(f, "%d", t + 1); ForEachTrPeriod(p) - fprintf(f, "\t%.4f", _rootsXphen[Iglp(r, t, p)]); + fprintf(f, "\t%.4f", SXWTemp._rootsXphen[Iglp(r, t, p)]); fprintf(f, "\n"); } } @@ -944,18 +910,18 @@ void _print_debuginfo(void) { } fprintf(f, "\n================== %d =============================\n", SW_Model.year); - fprintf(f, "MAP = %d(mm)\tMAT = %5.2f(C)\tAET = %5.4f(cm)\tT = %5.4f(cm)\tTADDED = %5.4f(cm)\tAT = %5.4f(cm)\n\n", Env.ppt, Env.temp, SXW.aet, sum, added_transp, sum + added_transp); + fprintf(f, "MAP = %d(mm)\tMAT = %5.2f(C)\tAET = %5.4f(cm)\tT = %5.4f(cm)\tTADDED = %5.4f(cm)\tAT = %5.4f(cm)\n\n", Env.ppt, Env.temp, SXW.aet, sum, transp_window.added_transp, sum + transp_window.added_transp); fprintf(f, "Group \tRelsize\tPR\tResource_cur\tResource_cur\n"); fprintf(f, "----- \t-------\t-----\t-no scaling-\t-with scaling-\n"); ForEachGroup(r) { sum1 += RGroup[r]->relsize; sum2 += RGroup[r]->pr; - sum3 += _resource_cur[r]; - fprintf(f, "%s\t%.4f\t%.4f\t%.4f\t\t%.4f\n", RGroup[r]->name, RGroup[r]->relsize, RGroup[r]->pr, _resource_cur[r]/_bvt, _resource_cur[r]); + sum3 += SXWTemp._resource_cur[r]; + fprintf(f, "%s\t%.4f\t%.4f\t%.4f\t\t%.4f\n", RGroup[r]->name, RGroup[r]->relsize, RGroup[r]->pr, SXWTemp._resource_cur[r]/SXWTemp._bvt, SXWTemp._resource_cur[r]); } fprintf(f, "----- \t-------\t-----\t-----\t\t-----\n"); - fprintf(f, "%s\t\t%.4f\t%.4f\t%.4f\t\t%.4f\n", "Total", sum1, sum2, sum3/_bvt, sum3); + fprintf(f, "%s\t\t%.4f\t%.4f\t%.4f\t\t%.4f\n", "Total", sum1, sum2, sum3/SXWTemp._bvt, sum3); fprintf(f, "\n------ Production Values Daily Summed Across Types Monthly Averaged -------\n"); fprintf(f, "Month\tBMass\tPctLive\tLAIlive\tVegCov\tTotAGB\n"); @@ -1020,7 +986,7 @@ void _print_debuginfo(void) { for (l = 0; l < SXW.NTrLyrs; l++) { fprintf(f, "%d", t + 1); ForEachTrPeriod(p) - fprintf(f, "\t%.4f", _roots_active_sum[Itlp(t, l, p)]); + fprintf(f, "\t%.4f", SXWTemp._roots_active_sum[Itlp(t, l, p)]); fprintf(f, "\n"); } } @@ -1039,7 +1005,7 @@ void _print_debuginfo(void) { //ForEachTranspLayer(t) { fprintf(f, "%d", t + 1); ForEachTrPeriod(p) - fprintf(f, "\t%.4f", _roots_active_rel[Iglp(r, t, p)]); + fprintf(f, "\t%.4f", SXWTemp._roots_active_rel[Iglp(r, t, p)]); fprintf(f, "\n"); } } @@ -1147,48 +1113,48 @@ void free_all_sxw_memory( void ) { /***********************************************************/ void free_sxw_memory( void ) { - Mem_Free(_roots_max); - Mem_Free(_rootsXphen); - Mem_Free(_roots_active); - Mem_Free(_roots_active_rel); - Mem_Free(_roots_active_sum); - Mem_Free(_phen); - Mem_Free(_prod_bmass); - Mem_Free(_prod_pctlive); + Mem_Free(SXWTemp._roots_max); + Mem_Free(SXWTemp._rootsXphen); + Mem_Free(SXWTemp._roots_active); + Mem_Free(SXWTemp._roots_active_rel); + Mem_Free(SXWTemp._roots_active_sum); + Mem_Free(SXWTemp._phen); + Mem_Free(SXWTemp._prod_bmass); + Mem_Free(SXWTemp._prod_pctlive); } /***********************************************************/ 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 ) { //load memory from the grid free_sxw_memory(); - _roots_max = Mem_Calloc(SXW.NGrps * SXW.NTrLyrs, sizeof(RealD), "load_sxw_memory()"); - _rootsXphen = Mem_Calloc(SXW.NGrps * SXW.NPds * SXW.NTrLyrs, sizeof(RealD), "load_sxw_memory()"); - _roots_active = Mem_Calloc(SXW.NGrps * SXW.NPds * SXW.NTrLyrs, sizeof(RealD), "load_sxw_memory()"); - _roots_active_rel = Mem_Calloc(SXW.NGrps * SXW.NPds * SXW.NTrLyrs, sizeof(RealD), "load_sxw_memory()"); - _roots_active_sum = Mem_Calloc(4 * SXW.NPds * SXW.NTrLyrs, sizeof(RealD), "load_sxw_memory()"); - _phen = Mem_Calloc(SXW.NGrps * MAX_MONTHS, sizeof(RealD), "load_sxw_memory()"); - _prod_bmass = Mem_Calloc(SXW.NGrps * MAX_MONTHS, sizeof(RealD), "load_sxw_memory()"); - _prod_pctlive = Mem_Calloc(SXW.NGrps * MAX_MONTHS, sizeof(RealD), "load_sxw_memory()"); - - memcpy(_roots_max, grid_roots_max, SXW.NGrps * SXW.NTrLyrs * sizeof(RealD)); - memcpy(_rootsXphen, grid_rootsXphen, SXW.NGrps * SXW.NPds * SXW.NTrLyrs * sizeof(RealD)); - memcpy(_roots_active, grid_roots_active, SXW.NGrps * SXW.NPds * SXW.NTrLyrs * sizeof(RealD)); - memcpy(_roots_active_rel, grid_roots_active_rel, SXW.NGrps * SXW.NPds * SXW.NTrLyrs * sizeof(RealD)); - memcpy(_roots_active_sum, grid_roots_active_sum, 4 * SXW.NPds * SXW.NTrLyrs * sizeof(RealD)); - memcpy(_phen, grid_phen, SXW.NGrps * MAX_MONTHS * sizeof(RealD)); - memcpy(_prod_bmass, grid_prod_bmass, SXW.NGrps * MAX_MONTHS * sizeof(RealD)); - memcpy(_prod_pctlive, grid_prod_pctlive, SXW.NGrps * MAX_MONTHS * sizeof(RealD)); + SXWTemp._roots_max = Mem_Calloc(SXW.NGrps * SXW.NTrLyrs, sizeof(RealD), "load_sxw_memory()"); + SXWTemp._rootsXphen = Mem_Calloc(SXW.NGrps * SXW.NPds * SXW.NTrLyrs, sizeof(RealD), "load_sxw_memory()"); + SXWTemp._roots_active = Mem_Calloc(SXW.NGrps * SXW.NPds * SXW.NTrLyrs, sizeof(RealD), "load_sxw_memory()"); + SXWTemp._roots_active_rel = Mem_Calloc(SXW.NGrps * SXW.NPds * SXW.NTrLyrs, sizeof(RealD), "load_sxw_memory()"); + SXWTemp._roots_active_sum = Mem_Calloc(4 * SXW.NPds * SXW.NTrLyrs, sizeof(RealD), "load_sxw_memory()"); + SXWTemp._phen = Mem_Calloc(SXW.NGrps * MAX_MONTHS, sizeof(RealD), "load_sxw_memory()"); + SXWTemp._prod_bmass = Mem_Calloc(SXW.NGrps * MAX_MONTHS, sizeof(RealD), "load_sxw_memory()"); + SXWTemp._prod_pctlive = Mem_Calloc(SXW.NGrps * MAX_MONTHS, sizeof(RealD), "load_sxw_memory()"); + + memcpy(SXWTemp._roots_max, grid_roots_max, SXW.NGrps * SXW.NTrLyrs * sizeof(RealD)); + memcpy(SXWTemp._rootsXphen, grid_rootsXphen, SXW.NGrps * SXW.NPds * SXW.NTrLyrs * sizeof(RealD)); + memcpy(SXWTemp._roots_active, grid_roots_active, SXW.NGrps * SXW.NPds * SXW.NTrLyrs * sizeof(RealD)); + memcpy(SXWTemp._roots_active_rel, grid_roots_active_rel, SXW.NGrps * SXW.NPds * SXW.NTrLyrs * sizeof(RealD)); + memcpy(SXWTemp._roots_active_sum, grid_roots_active_sum, 4 * SXW.NPds * SXW.NTrLyrs * sizeof(RealD)); + memcpy(SXWTemp._phen, grid_phen, SXW.NGrps * MAX_MONTHS * sizeof(RealD)); + memcpy(SXWTemp._prod_bmass, grid_prod_bmass, SXW.NGrps * MAX_MONTHS * sizeof(RealD)); + memcpy(SXWTemp._prod_pctlive, grid_prod_pctlive, SXW.NGrps * MAX_MONTHS * sizeof(RealD)); } /***********************************************************/ 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 ) { //save memory to the grid - memcpy(grid_roots_max, _roots_max, SXW.NGrps * SXW.NTrLyrs * sizeof(RealD)); - memcpy(grid_rootsXphen, _rootsXphen, SXW.NGrps * SXW.NPds * SXW.NTrLyrs * sizeof(RealD)); - memcpy(grid_roots_active, _roots_active, SXW.NGrps * SXW.NPds * SXW.NTrLyrs * sizeof(RealD)); - memcpy(grid_roots_active_rel, _roots_active_rel, SXW.NGrps * SXW.NPds * SXW.NTrLyrs * sizeof(RealD)); - memcpy(grid_roots_active_sum, _roots_active_sum, 4 * SXW.NPds * SXW.NTrLyrs * sizeof(RealD)); - memcpy(grid_phen, _phen, SXW.NGrps * MAX_MONTHS * sizeof(RealD)); - memcpy(grid_prod_bmass, _prod_bmass, SXW.NGrps * MAX_MONTHS * sizeof(RealD)); - memcpy(grid_prod_pctlive, _prod_pctlive, SXW.NGrps * MAX_MONTHS * sizeof(RealD)); + memcpy(grid_roots_max, SXWTemp._roots_max, SXW.NGrps * SXW.NTrLyrs * sizeof(RealD)); + memcpy(grid_rootsXphen, SXWTemp._rootsXphen, SXW.NGrps * SXW.NPds * SXW.NTrLyrs * sizeof(RealD)); + memcpy(grid_roots_active, SXWTemp._roots_active, SXW.NGrps * SXW.NPds * SXW.NTrLyrs * sizeof(RealD)); + memcpy(grid_roots_active_rel, SXWTemp._roots_active_rel, SXW.NGrps * SXW.NPds * SXW.NTrLyrs * sizeof(RealD)); + memcpy(grid_roots_active_sum, SXWTemp._roots_active_sum, 4 * SXW.NPds * SXW.NTrLyrs * sizeof(RealD)); + memcpy(grid_phen, SXWTemp._phen, SXW.NGrps * MAX_MONTHS * sizeof(RealD)); + memcpy(grid_prod_bmass, SXWTemp._prod_bmass, SXW.NGrps * MAX_MONTHS * sizeof(RealD)); + memcpy(grid_prod_pctlive, SXWTemp._prod_pctlive, SXW.NGrps * MAX_MONTHS * sizeof(RealD)); } diff --git a/sxw.h b/sxw.h index 8dd4e0be..cb169958 100644 --- a/sxw.h +++ b/sxw.h @@ -24,7 +24,9 @@ // A base of 4.4 C as described in Sims et al. 1978 Journal of Ecology // Additional testing required here and GROWING_BASE_TEMP should eventually be moved to env.in #define GROWING_BASE_TEMP 4.4 // base-temperature in degree Celsius - +#define SXW_NFILES 5 +// The number of transpiration values retained by transp_data +#define MAX_WINDOW 100 #include "generic.h" #include "SW_Times.h" @@ -70,10 +72,7 @@ struct stepwat_st { // ------ DEBUG stuff: char *debugfile; /* added in ST_Main(), read to get debug instructions */ -}; - -// The number of transpiration values retained by transp_data -#define MAX_WINDOW 100 +} typedef SXW_t; // transp_data stores three arrays: ratios, transp, and sum of squares. These arrays form // a moving window that stores "size" years worth of previous transpiration data. @@ -115,16 +114,46 @@ struct transp_data { //SoS_array[] stores the sum of squares values (xi - mean)^2 for the previous (size) iterations. RealF SoS_array[MAX_WINDOW]; //(xi - mean)^2 -}; -typedef struct transp_data transp_t; + // Amount of additional transpiration added for the current year + RealF added_transp; -#define SXW_NFILES 5 + // _transp_contribution_by_group() has different behavior for production years and setup years. + // this variable keeps track of what year last year was, to make sure that the year actually + // incremented. If it did NOT, then this is a setup year. + int lastYear; + +} typedef transp_t; -typedef struct stepwat_st SXW_t; +struct temp_SXW_st{ + /* ----- 3d arrays ------- */ + RealD * _rootsXphen, /* relative roots X phen in each lyr,grp,pd */ + * _roots_active, /* "active" in terms of size and phenology */ + * _roots_active_rel; -#define ForEachTrPeriod(i) for((i)=0; (i)< SXW.NPds; (i)++) + /* ----- 2D arrays ------- */ + /* rgroup by layer, ie, group-level values */ + RealD * _roots_max, /* read from root distr. file */ + * _roots_active_sum, /* used in sxw_resource */ + /* rgroup by period */ + * _phen; /* phenology read from file */ + + /* simple vectors hold the resource information for each group */ + /* curr/equ gives the available/required ratio */ + RealF _resource_cur[MAX_RGROUPS], /* current resource availability for each STEPPE functional type */ + _resource_pr[MAX_RGROUPS]; /* resource convertable to PR */ + + /* one vector for the production constants */ + RealD _prod_litter[MAX_MONTHS]; + RealD * _prod_bmass; + RealD * _prod_pctlive; + + RealF _bvt; /* ratio of biomass/m2 / transp/m2 */ + +} typedef TempType; + +#define ForEachTrPeriod(i) for((i)=0; (i)< SXW.NPds; (i)++) /* convert 3-d index to actual array index for group/layer/phenology 3d table */ @@ -135,7 +164,6 @@ typedef struct stepwat_st SXW_t; */ #define Itlp(t,l,p) (((t)*SXW.NTrLyrs*SXW.NPds) + ((l)*SXW.NPds) + (p)) - // veg type, layer, timeperiod #define Ivlp(v,l,p) (((v)*NVEGTYPES * SXW.NTrLyrs * SXW.NPds) + ((l)*SXW.NTrLyrs * SXW.NPds) + ((p)*SXW.NPds)) diff --git a/sxw_resource.c b/sxw_resource.c index be9719b1..417a8bd2 100644 --- a/sxw_resource.c +++ b/sxw_resource.c @@ -47,34 +47,7 @@ //extern SW_SOILWAT SW_Soilwat; //extern SW_VEGPROD SW_VegProd; - -/*************** Local Variable Declarations ***************/ -/***********************************************************/ -/* malloc'ed and maybe read in sxw.c but used here */ -/* ----- 3d arrays ------- */ -extern - RealD * _rootsXphen, /* relative roots X phen by layer & group */ - * _roots_active, /*relative to the total roots_phen_lyr_group */ - * _roots_active_rel; - - -/* ----- 2D arrays ------- */ - -extern - /* rgroup by layer */ - RealD * _roots_max, /* root distribution with depth for STEPPE functional groups, read from input */ - * _roots_active_sum, /* active roots in each month and soil layer for STEPPE functional groups in the current year */ - - /* rgroup by period */ - * _phen; /* phenological activity for each month for STEPPE functional groups, read from input */ - -extern - RealF _resource_pr[MAX_RGROUPS], /* resource convertable to pr */ - _resource_cur[MAX_RGROUPS]; /* resources currently available by group*/ - RealF added_transp; /* transpiration added for the current year */ - -extern - RealF _bvt; +extern TempType SXWTemp; /* ------ Running Averages ------ */ extern @@ -83,11 +56,6 @@ extern extern pcg32_random_t resource_rng; -// _transp_contribution_by_group() has different behavior for production years and setup years. -// this variable keeps track of what year last year was, to make sure that the year actually -// incremented. If it did NOT, then this is a setup year. -int lastYear; - //void _print_debuginfo(void); /*************** Local Function Declarations ***************/ @@ -110,14 +78,14 @@ void _sxw_root_phen(void) { TimeInt p; for (y = 0; y < (Globals.grpCount * SXW.NPds * SXW.NTrLyrs); y++) - _rootsXphen[y] = 0; + SXWTemp._rootsXphen[y] = 0; ForEachGroup(g) { int nLyrs = getNTranspLayers(RGroup[g]->veg_prod_type); for (y = 0; y < nLyrs; y++) { ForEachTrPeriod(p) { - _rootsXphen[Iglp(g, y, p)] = _roots_max[Ilg(y, g)] * _phen[Igp(g, p)]; + SXWTemp._rootsXphen[Iglp(g, y, p)] = SXWTemp._roots_max[Ilg(y, g)] * SXWTemp._phen[Igp(g, p)]; } } } @@ -163,14 +131,14 @@ void _sxw_update_resource(void) { _sxw_update_root_tables(sizes); /* Assign transpiration (resource availability) to each STEPPE functional group */ - _transp_contribution_by_group(_resource_cur); + _transp_contribution_by_group(SXWTemp._resource_cur); /* Scale transpiration resources by a constant, bvt, to convert resources * (cm) to biomass that can be supported by those resources (g/cm) */ ForEachGroup(g) { //printf("for groupName= %smresource_cur prior to multiplication: %f\n",RGroup[g]->name, _resource_cur[g]); - _resource_cur[g] = _resource_cur[g] * _bvt; + SXWTemp._resource_cur[g] = SXWTemp._resource_cur[g] * SXWTemp._bvt; //printf("for groupName= %s, resource_cur post multiplication: %f\n\n",Rgroup[g]->name, _resource_cur[g]); } /* _print_debuginfo(); */ @@ -189,7 +157,7 @@ void _sxw_update_root_tables( RealF sizes[] ) { int t,nLyrs; /* Set some things to zero where 4 refers to Tree, Shrub, Grass, Forb */ - Mem_Set(_roots_active_sum, 0, 4 * SXW.NPds * SXW.NTrLyrs * sizeof(RealD)); + Mem_Set(SXWTemp._roots_active_sum, 0, 4 * SXW.NPds * SXW.NTrLyrs * sizeof(RealD)); /* Calculate the active roots in each month and soil layer for each STEPPE * functional group based on the functional group biomass this year */ @@ -200,9 +168,9 @@ void _sxw_update_root_tables( RealF sizes[] ) { for (l = 0; l < nLyrs; l++) { ForEachTrPeriod(p) { - x = _rootsXphen[Iglp(g, l, p)] * sizes[g]; - _roots_active[Iglp(g, l, p)] = x; - _roots_active_sum[Itlp(t, l, p)] += x; + x = SXWTemp._rootsXphen[Iglp(g, l, p)] * sizes[g]; + SXWTemp._roots_active[Iglp(g, l, p)] = x; + SXWTemp._roots_active_sum[Itlp(t, l, p)] += x; } } } @@ -216,11 +184,11 @@ void _sxw_update_root_tables( RealF sizes[] ) { for (l = 0; l < nLyrs; l++) { ForEachTrPeriod(p) { - _roots_active_rel[Iglp(g, l, p)] = - ZRO(_roots_active_sum[Itlp(t,l,p)]) ? + SXWTemp._roots_active_rel[Iglp(g, l, p)] = + ZRO(SXWTemp._roots_active_sum[Itlp(t,l,p)]) ? 0. : - _roots_active[Iglp(g, l, p)] - / _roots_active_sum[Itlp(t,l, p)]; + SXWTemp._roots_active[Iglp(g, l, p)] + / SXWTemp._roots_active_sum[Itlp(t,l, p)]; } } } @@ -244,14 +212,14 @@ static void _transp_contribution_by_group(RealF use_by_group[]) { RealD *transp; RealF sumUsedByGroup = 0., sumTranspTotal = 0., TranspRemaining = 0.; RealF transp_ratio; - added_transp = 0; + transp_window.added_transp = 0; RealF transp_ratio_sd; // year 0 is a set up year. No need to calculate transpiration. // if there are multiple iterations the last year will run twice; // once for data and once for tear down. The second "last year" is // equivalent to year 0. - if(Globals.currYear == 0 || Globals.currYear == lastYear) { + if(Globals.currYear == 0 || Globals.currYear == transp_window.lastYear) { transp_window.average = 0; transp_window.ratio_average = 0; transp_window.sum_of_sqrs = 0; @@ -293,7 +261,7 @@ static void _transp_contribution_by_group(RealF use_by_group[]) { 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)]); + use_by_group[g] += (RealF) (SXWTemp._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] ); @@ -370,25 +338,25 @@ static void _transp_contribution_by_group(RealF use_by_group[]) { RealF max = transp_window.ratio_average + transp_ratio_sd; // This transpiration will be added - added_transp = (1 - transp_ratio / RandUniFloatRange(min, max, &resource_rng)) * transp_window.average; - if(added_transp < 0){ + transp_window.added_transp = (1 - transp_ratio / RandUniFloatRange(min, max, &resource_rng)) * transp_window.average; + if(transp_window.added_transp < 0){ LogError(logfp, LOGNOTE, "sxw_resource: Added transpiration less than 0.\n"); } //printf("Year %d:\tTranspiration to add: %f\n",Globals.currYear,add_transp); //printf("TranspRemaining: %f\tTranspRemaining+add_transp: %f\n",TranspRemaining,add_transp+TranspRemaining); /* -------------------- Recalculate the window including added_transp in the current year -------------------- */ - RealF added_transp_ratio = added_transp / SXW.ppt; + RealF added_transp_ratio = transp_window.added_transp / SXW.ppt; //add added_transp to the average. This is technically part of the current year, so no need to subtract anything. - transp_window.average += added_transp/transp_window.size; + transp_window.average += transp_window.added_transp/transp_window.size; //add added_transp ratio to the ratio average. This is technically part of the current year, so no need to subtract anything. transp_window.ratio_average += (added_transp_ratio)/transp_window.size; //put the new transpiration in the window. Note: oldest_index has not been incremented, so it points to what was just added - transp_window.transp[transp_window.oldest_index] += added_transp; + transp_window.transp[transp_window.oldest_index] += transp_window.added_transp; //put the new ratio in the window. Note: oldest_index has not been incremented, so it points to what was just added transp_window.ratios[transp_window.oldest_index] += added_transp_ratio; // calculate the new sum of squares value - RealF totalTranspRatio = (sumTranspTotal + added_transp)/SXW.ppt; + RealF totalTranspRatio = (sumTranspTotal + transp_window.added_transp)/SXW.ppt; RealF ssqr = (totalTranspRatio - transp_window.ratio_average) * (totalTranspRatio - transp_window.ratio_average); // Subtract the sum of squares calculated above, which was stored in the array. Replace it with what was just calculated. transp_window.sum_of_sqrs += ssqr - transp_window.SoS_array[transp_window.oldest_index]; @@ -400,7 +368,7 @@ static void _transp_contribution_by_group(RealF use_by_group[]) { /* Adds the additional transpiration to the remaining transpiration * so it can be distributed proportionally to the functional groups. */ - TranspRemaining += added_transp; + TranspRemaining += transp_window.added_transp; } //oldest_index++ accounting for the array bounds @@ -419,5 +387,5 @@ static void _transp_contribution_by_group(RealF use_by_group[]) { } //remember the last year. When setting up for a new iteration the same year will appear twice, and we want to skip it the second time - lastYear = Globals.currYear; + transp_window.lastYear = Globals.currYear; } diff --git a/sxw_soilwat.c b/sxw_soilwat.c index 91d6ba40..a638fae1 100644 --- a/sxw_soilwat.c +++ b/sxw_soilwat.c @@ -60,13 +60,7 @@ extern SW_SITE SW_Site; extern SW_MODEL SW_Model; extern SW_VEGPROD SW_VegProd; - -/*********** Local/Module Variable Declarations ************/ -/***********************************************************/ -extern RealD *_roots_max; -extern RealD _prod_litter[MAX_MONTHS]; -extern RealD * _prod_bmass; -extern RealD * _prod_pctlive; +extern TempType SXWTemp; #ifdef SXW_BYMAXSIZE extern RealF _Grp_BMass[]; /* added 2/28/03 */ @@ -139,7 +133,7 @@ static void _update_transp_coeff(RealF relsize[]) { ForEachGroup(g) if (RGroup[g]->veg_prod_type == 1) if (getNTranspLayers(RGroup[g]->veg_prod_type)) - y->transp_coeff[SW_TREES] += (RealF) _roots_max[Ilg(t, g)] * RGroup[g]->rgroupFractionOfVegTypeBiomass; + y->transp_coeff[SW_TREES] += (RealF) SXWTemp._roots_max[Ilg(t, g)] * RGroup[g]->rgroupFractionOfVegTypeBiomass; sum[SW_TREES] += y->transp_coeff[SW_TREES]; } @@ -149,7 +143,7 @@ static void _update_transp_coeff(RealF relsize[]) { ForEachGroup(g) if (RGroup[g]->veg_prod_type == 2) { if (getNTranspLayers(RGroup[g]->veg_prod_type)) - y->transp_coeff[SW_SHRUB] += (RealF) _roots_max[Ilg(t, g)] * RGroup[g]->rgroupFractionOfVegTypeBiomass; + y->transp_coeff[SW_SHRUB] += (RealF) SXWTemp._roots_max[Ilg(t, g)] * RGroup[g]->rgroupFractionOfVegTypeBiomass; /*printf("* lyr=%d, group=%s(%d), type=%d, tl=%d, rootmax=%f, relsize1=%f, relsize2=%f, trco=%f\n", t, RGroup[g]->name, g, RGroup[g]->veg_prod_type, getNTranspLayers(RGroup[g]->veg_prod_type), @@ -165,7 +159,7 @@ static void _update_transp_coeff(RealF relsize[]) { ForEachGroup(g) if (RGroup[g]->veg_prod_type == 3) if (getNTranspLayers(RGroup[g]->veg_prod_type)) - y->transp_coeff[SW_GRASS] += (RealF) _roots_max[Ilg(t, g)] * RGroup[g]->rgroupFractionOfVegTypeBiomass; + y->transp_coeff[SW_GRASS] += (RealF) SXWTemp._roots_max[Ilg(t, g)] * RGroup[g]->rgroupFractionOfVegTypeBiomass; sum[SW_GRASS] += y->transp_coeff[SW_GRASS]; } @@ -175,7 +169,7 @@ static void _update_transp_coeff(RealF relsize[]) { ForEachGroup(g) if (RGroup[g]->veg_prod_type == 4) if (getNTranspLayers(RGroup[g]->veg_prod_type)) - y->transp_coeff[SW_FORBS] += (RealF) _roots_max[Ilg(t, g)] * RGroup[g]->rgroupFractionOfVegTypeBiomass; + y->transp_coeff[SW_FORBS] += (RealF) SXWTemp._roots_max[Ilg(t, g)] * RGroup[g]->rgroupFractionOfVegTypeBiomass; sum[SW_FORBS] += y->transp_coeff[SW_FORBS]; } @@ -262,24 +256,24 @@ static void _update_productivity(void) { ForEachGroup(g) { if (1 == RGroup[g]->veg_prod_type) { //tree - v->veg[SW_TREES].pct_live[m] += _prod_pctlive[Igp(g, m)] * RGroup[g]->rgroupFractionOfVegTypeBiomass; - v->veg[SW_TREES].biomass[m] += _prod_bmass[Igp(g, m)] * bmassg[g]; + v->veg[SW_TREES].pct_live[m] += SXWTemp._prod_pctlive[Igp(g, m)] * RGroup[g]->rgroupFractionOfVegTypeBiomass; + v->veg[SW_TREES].biomass[m] += SXWTemp._prod_bmass[Igp(g, m)] * bmassg[g]; } else if (2 == RGroup[g]->veg_prod_type) { //shrub - v->veg[SW_SHRUB].pct_live[m] += _prod_pctlive[Igp(g, m)] * RGroup[g]->rgroupFractionOfVegTypeBiomass; - v->veg[SW_SHRUB].biomass[m] += _prod_bmass[Igp(g, m)] * bmassg[g]; + v->veg[SW_SHRUB].pct_live[m] += SXWTemp._prod_pctlive[Igp(g, m)] * RGroup[g]->rgroupFractionOfVegTypeBiomass; + v->veg[SW_SHRUB].biomass[m] += SXWTemp._prod_bmass[Igp(g, m)] * bmassg[g]; } else if (3 == RGroup[g]->veg_prod_type) { //grass - v->veg[SW_GRASS].pct_live[m] += _prod_pctlive[Igp(g, m)] * RGroup[g]->rgroupFractionOfVegTypeBiomass; - v->veg[SW_GRASS].biomass[m] += _prod_bmass[Igp(g, m)] * bmassg[g]; + v->veg[SW_GRASS].pct_live[m] += SXWTemp._prod_pctlive[Igp(g, m)] * RGroup[g]->rgroupFractionOfVegTypeBiomass; + v->veg[SW_GRASS].biomass[m] += SXWTemp._prod_bmass[Igp(g, m)] * bmassg[g]; } else if (4 == RGroup[g]->veg_prod_type) { //forb - v->veg[SW_FORBS].pct_live[m] += _prod_pctlive[Igp(g, m)] * RGroup[g]->rgroupFractionOfVegTypeBiomass; - v->veg[SW_FORBS].biomass[m] += _prod_bmass[Igp(g, m)] * bmassg[g]; + v->veg[SW_FORBS].pct_live[m] += SXWTemp._prod_pctlive[Igp(g, m)] * RGroup[g]->rgroupFractionOfVegTypeBiomass; + v->veg[SW_FORBS].biomass[m] += SXWTemp._prod_bmass[Igp(g, m)] * bmassg[g]; } } - v->veg[SW_TREES].litter[m] = (vegTypeBiomass[0] * _prod_litter[m]); - v->veg[SW_SHRUB].litter[m] = (vegTypeBiomass[1] * _prod_litter[m]); - v->veg[SW_GRASS].litter[m] = (vegTypeBiomass[2] * _prod_litter[m]); - v->veg[SW_FORBS].litter[m] = (vegTypeBiomass[3] * _prod_litter[m]); + v->veg[SW_TREES].litter[m] = (vegTypeBiomass[0] * SXWTemp._prod_litter[m]); + v->veg[SW_SHRUB].litter[m] = (vegTypeBiomass[1] * SXWTemp._prod_litter[m]); + v->veg[SW_GRASS].litter[m] = (vegTypeBiomass[2] * SXWTemp._prod_litter[m]); + v->veg[SW_FORBS].litter[m] = (vegTypeBiomass[3] * SXWTemp._prod_litter[m]); } } diff --git a/sxw_sql.c b/sxw_sql.c index eabaf143..913643dd 100644 --- a/sxw_sql.c +++ b/sxw_sql.c @@ -18,11 +18,7 @@ extern SW_MODEL SW_Model; extern SXW_t SXW; extern SW_SITE SW_Site; extern SW_VEGPROD SW_VegProd; -extern RealD *_phen; -extern RealD _prod_litter[MAX_MONTHS]; -extern RealD * _prod_bmass; -extern RealD * _prod_pctlive; -extern RealF _bvt; +extern TempType SXWTemp; static sqlite3 *db; static char sql[1024]; @@ -123,7 +119,7 @@ void insertSXWPhen(void) { { for(m=0;m<12;m++) { sql[0] = 0; - sprintf(sql, "INSERT INTO sxwphen (RGroupID, Month, GrowthPCT) VALUES (%d, %d, %f);", g+1, m+1,_phen[Igp(g,m)]); + sprintf(sql, "INSERT INTO sxwphen (RGroupID, Month, GrowthPCT) VALUES (%d, %d, %f);", g+1, m+1,SXWTemp._phen[Igp(g,m)]); rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); sqlcheck(rc, zErrMsg); } @@ -142,7 +138,8 @@ void insertSXWProd(void) { { for(m=0;m<12;m++) { sql[0] = 0; - sprintf(sql, "INSERT INTO sxwprod (RGroupID, Month, BMASS, LITTER, PCTLIVE) VALUES (%d, %d, %f, %f, %f);", g+1, m+1, _prod_bmass[Igp(g,m)], _prod_litter[m], _prod_pctlive[Igp(g,m)]); + sprintf(sql, "INSERT INTO sxwprod (RGroupID, Month, BMASS, LITTER, PCTLIVE) VALUES (%d, %d, %f, %f, %f);", + g+1, m+1, SXWTemp._prod_bmass[Igp(g,m)], SXWTemp._prod_litter[m], SXWTemp._prod_pctlive[Igp(g,m)]); rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); sqlcheck(rc, zErrMsg); } @@ -156,7 +153,8 @@ void insertInfo() { sql[0] = 0; beginTransaction(); - sprintf(sql, "INSERT INTO info (StartYear, Years, Iterations, RGroups, TranspirationLayers, SoilLayers, PlotSize, BVT) VALUES (%d, %d, %d, %d, %d, %d, %f, %f);", SW_Model.startyr, Globals.runModelYears, Globals.runModelIterations, Globals.grpCount, SXW.NTrLyrs, SXW.NSoLyrs, Globals.plotsize, _bvt); + sprintf(sql, "INSERT INTO info (StartYear, Years, Iterations, RGroups, TranspirationLayers, SoilLayers, PlotSize, BVT) VALUES (%d, %d, %d, %d, %d, %d, %f, %f);", + SW_Model.startyr, Globals.runModelYears, Globals.runModelIterations, Globals.grpCount, SXW.NTrLyrs, SXW.NSoLyrs, Globals.plotsize, SXWTemp._bvt); rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); sqlcheck(rc, zErrMsg); endTransaction(); @@ -384,7 +382,7 @@ void insertRgroupInfo(RealF * _resource_cur) { beginTransaction(); ForEachGroup(r) { - insertSXWoutputRgroupRow(Year, Iteration, r+1, RGroup_GetBiomass(r),RGroup[r]->relsize, RGroup[r]->pr, _resource_cur[r]/_bvt, _resource_cur[r]); + insertSXWoutputRgroupRow(Year, Iteration, r+1, RGroup_GetBiomass(r),RGroup[r]->relsize, RGroup[r]->pr, _resource_cur[r]/SXWTemp._bvt, _resource_cur[r]); } endTransaction(); }