Skip to content

Commit

Permalink
Merge pull request #338 from DrylandEcology/bugfix_336_vegtypeindex_v2
Browse files Browse the repository at this point in the history
Consistent SOILWAT2 vegetation type indices:
- STEPWAT2 uses a different system for inputs than SOILWAT2 does to index SOILWAT2 vegetation types
--> this commit adds the function `get_SW2_veg_index` to systematically convert the inputs to the corresponding SOILWAT2 value immediately after reading values from input files, i.e., `veg_prod_type` are now SOILWAT2 indices (unlike before)
  • Loading branch information
dschlaep committed Jul 18, 2019
2 parents 2492718 + 97e3b35 commit 21fd1db
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 135 deletions.
7 changes: 6 additions & 1 deletion ST_grid.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,9 @@ struct _grid_disturb_st
killfreq_startyr,/* start year for kill frequency*/
killfrq, /* kill group at this frequency: <1=prob, >1=# years */
extirp, /* year in which group is extirpated (0==ignore) */
veg_prod_type, /* type of VegProd. 1 for tree, 2 for shrub, 3 for grass, 4 for forb */
veg_prod_type, /* type of SOILWAT2 vegetation type:
STEPWAT2 inputs via "rgroup.in" are defined as: 1 for tree, 2 for shrub, 3 for grass, 4 for forb;
however, the inputs get translated by get_SW2_veg_index() to SOILWAT2 values immediately upon reading the inputs (see SW_Defines.h) */
grazingfreq_startyr,/* start year for grazing frequency*/
grazing_frq; /* grazing effect on group at this frequency: <1=prob, >1=# years */

Expand Down Expand Up @@ -1998,6 +2000,9 @@ static void _read_disturbances_in(void)
&grid_Disturb[i].killfreq_startyr,&grid_Disturb[i].xgrow,&grid_Disturb[i].veg_prod_type,
&grid_Disturb[i].grazing_frq,&grid_Disturb[i].grazingfreq_startyr);

// Convert to SOILWAT2 vegetation index
grid_Disturb[i].veg_prod_type = get_SW2_veg_index(grid_Disturb[i].veg_prod_type);

// printf("values : cell=%d ,choices[0]=%d ,choices[1]=%d ,choices[2]=%d ,kill_yr=%d ,killfrq=%d ,extirp=%d ,killfreq_startyr=%d ,xgrow=%f ,veg_prod_type=%d ,grazing_frq=%d ,grazingfrd_start_year=%d \n", cell,
// grid_Disturb[i].choices[0], grid_Disturb[i].choices[1],
// grid_Disturb[i].choices[2], grid_Disturb[i].kill_yr,
Expand Down
5 changes: 5 additions & 0 deletions ST_params.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
#include "filefuncs.h"
#include "myMemory.h"
#include "rands.h"
#include "sxw_funcs.h"


/************ External Variable Declarations ***************/
/***********************************************************/
Expand Down Expand Up @@ -811,6 +813,9 @@ static void _rgroup_init( void) {
MyFileName);
}

// Convert to SOILWAT2 vegetation index
veg_prod_type = get_SW2_veg_index(veg_prod_type);

_rgroup_add1( name, space, density, estab,
slow, stretch, xres, estann,
turnon, styr, xgro, veg_prod_type, mort);
Expand Down
4 changes: 3 additions & 1 deletion ST_structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,9 @@ struct resourcegroup_st {

extirp, /* year in which group is extirpated (0==ignore) */
grp_num, /* index number of this group */
veg_prod_type, /* type of VegProd. 1 for tree, 2 for shrub, 3 for grass, 4 for forb */
veg_prod_type, /* type of SOILWAT2 vegetation type:
STEPWAT2 inputs via "rgroup.in" are defined as: 1 for tree, 2 for shrub, 3 for grass, 4 for forb;
however, the inputs get translated by get_SW2_veg_index() to SOILWAT2 values immediately upon reading the inputs (see SW_Defines.h) */
grazingfrq, /* grazing effect on group at this frequency: <1=prob, >1=# years */
grazingfreq_startyr;/* start year for grazing frequency*/
SppIndex *species; /*list of spp belonging to this grp*/
Expand Down
59 changes: 39 additions & 20 deletions sxw.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,8 +299,10 @@ void SXW_Run_SOILWAT (void) {
sizes = (RealF *)Mem_Calloc(Globals.max_rgroups, sizeof(RealF), "SXW_Run_SOILWAT");

/* compute production values for transp based on current plant sizes */
ForEachGroup(g)
sizes[g] = RGroup_GetBiomass(g);
ForEachGroup(g) {
sizes[g] = RGroup_GetBiomass(g);
}

_sxw_sw_setup(sizes);

// Initialize `SXW` values for current year's run:
Expand Down Expand Up @@ -868,11 +870,11 @@ void _print_debuginfo(void) {
RealF sum2 = 0.;
RealF sum3 = 0.;
static Bool beenhere = FALSE;
char vegProdNames[4][7];
strcpy(vegProdNames[0], "TREE");
strcpy(vegProdNames[1], "SHRUB");
strcpy(vegProdNames[2], "GRASS");
strcpy(vegProdNames[3], "FORB");
char vegProdNames[NVEGTYPES][7];
strcpy(vegProdNames[SW_TREES], "TREE");
strcpy(vegProdNames[SW_SHRUB], "SHRUB");
strcpy(vegProdNames[SW_GRASS], "GRASS");
strcpy(vegProdNames[SW_FORBS], "FORB");
char name[256] = {0};
strcat(name, _debugout);
f = OpenFile(strcat(name, ".output.out"), "a");
Expand Down Expand Up @@ -976,7 +978,7 @@ void _print_debuginfo(void) {
pct_live, lai_live, bLAI_total, total_agb);
}

for (t = 0; t < 4; t++) {
ForEachVegType(t) {
fprintf(f, "\n------ Active Roots (sum) %s -------\n", vegProdNames[t]);
fprintf(f, "Layer:");
ForEachTrPeriod(p)
Expand Down Expand Up @@ -1074,18 +1076,35 @@ void SXW_SetMemoryRefs( void) {

#endif

/** Convert STEPWAT2 indices of SOILWAT2's vegetation type into a
SOILWAT2 index
@param veg_prod_type 1 for tree, 2 for shrub, 3 for grass, 4 for forb
(see comments for "veg_prod_type" in `rgroup.in`).
@return One of the SOILWAT2 defined values `SW_TREES`, `SW_SHRUB`,
`SW_FORBS`, `SW_GRASS` or -1 if no match.
See `SW_Defines.h` for definitions.
*/
int get_SW2_veg_index(int veg_prod_type) {
if (veg_prod_type == 1)
return SW_TREES;
else if (veg_prod_type == 2)
return SW_SHRUB;
else if (veg_prod_type == 3)
return SW_GRASS;
else if (veg_prod_type == 4)
return SW_FORBS;

return -1;
}



/***********************************************************/
//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[0];
else if(veg_prod_type == 2)
return SW_Site.n_transp_lyrs[1];
else if(veg_prod_type == 3)
return SW_Site.n_transp_lyrs[3];
else if(veg_prod_type == 4)
return SW_Site.n_transp_lyrs[2];
return -1;
return SW_Site.n_transp_lyrs[veg_prod_type];
}

/***********************************************************/
Expand Down Expand Up @@ -1130,7 +1149,7 @@ void load_sxw_memory( RealD* grid_roots_max, RealD* grid_rootsXphen, RealD* grid
_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()");
_roots_active_sum = Mem_Calloc(NVEGTYPES * 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()");
Expand All @@ -1139,7 +1158,7 @@ void load_sxw_memory( RealD* grid_roots_max, RealD* grid_rootsXphen, RealD* grid
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(_roots_active_sum, grid_roots_active_sum, NVEGTYPES * 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));
Expand All @@ -1152,7 +1171,7 @@ void save_sxw_memory( RealD * grid_roots_max, RealD* grid_rootsXphen, RealD* gri
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_roots_active_sum, _roots_active_sum, NVEGTYPES * 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));
Expand Down
1 change: 1 addition & 0 deletions sxw_funcs.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "sxw.h"

RealF SXW_GetTranspiration( GrpIndex rg);
int get_SW2_veg_index(int veg_prod_type);

void SXW_Init( Bool init_SW, char *f_roots );
void SXW_Reset(void);
Expand Down
39 changes: 8 additions & 31 deletions sxw_resource.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,6 @@ void _sxw_update_resource(void) {

ForEachGroup(g)
{
//RGroup[g]->veg_prod_type
sizes[g] = 0.;
//printf("_sxw_update_resource()RGroup Name= %s, RGroup[g]->regen_ok=%d \n ", RGroup[g]->name, RGroup[g]->regen_ok);
if (!RGroup[g]->regen_ok)
Expand Down Expand Up @@ -173,26 +172,24 @@ void _sxw_update_root_tables( RealF sizes[] ) {
* (resources) to each STEPPE functional group. */

GrpIndex g;
LyrIndex l;
LyrIndex l, nLyrs;
TimeInt p;
RealD x;
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(_roots_active_sum, 0, NVEGTYPES * 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 */
ForEachGroup(g)
{
t = RGroup[g]->veg_prod_type-1;
nLyrs = getNTranspLayers(RGroup[g]->veg_prod_type);
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;
_roots_active_sum[Itlp(RGroup[g]->veg_prod_type, l, p)] += x;
}
}
}
Expand All @@ -201,16 +198,14 @@ void _sxw_update_root_tables( RealF sizes[] ) {
* STEPPE group's roots in a given layer in a given month */
ForEachGroup(g)
{
int t = RGroup[g]->veg_prod_type-1;
int nLyrs = getNTranspLayers(RGroup[g]->veg_prod_type);
nLyrs = getNTranspLayers(RGroup[g]->veg_prod_type);
for (l = 0; l < nLyrs; l++) {
ForEachTrPeriod(p)
{
_roots_active_rel[Iglp(g, l, p)] =
ZRO(_roots_active_sum[Itlp(t,l,p)]) ?
ZRO(_roots_active_sum[Itlp(RGroup[g]->veg_prod_type, l, p)]) ?
0. :
_roots_active[Iglp(g, l, p)]
/ _roots_active_sum[Itlp(t,l, p)];
_roots_active[Iglp(g, l, p)] / _roots_active_sum[Itlp(RGroup[g]->veg_prod_type, l, p)];
}
}
}
Expand Down Expand Up @@ -257,25 +252,7 @@ static void _transp_contribution_by_group(RealF use_by_group[]) {
ForEachGroup(g) //Steppe functional group
{
use_by_group[g] = 0.;
t = RGroup[g]->veg_prod_type - 1;

switch (t) {
case 0://Tree
transp = SXW.transpVeg[SW_TREES];
break;
case 1://Shrub
transp = SXW.transpVeg[SW_SHRUB];
break;
case 2://Grass
transp = SXW.transpVeg[SW_GRASS];
break;
case 3://Forb
transp = SXW.transpVeg[SW_FORBS];
break;
default:
transp = SXW.transpTotal;
break;
}
transp = SXW.transpVeg[RGroup[g]->veg_prod_type];

//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
Expand Down
Loading

0 comments on commit 21fd1db

Please sign in to comment.