-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
1 parent
75b1359
commit 6d4c7e9
Showing
10 changed files
with
8,392 additions
and
8,007 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,155 +1,178 @@ | ||
/** | ||
* @file SW_Carbon.c | ||
* @author Zachary Kramer | ||
* @brief Contains functions, constants, and variables that deal with the | ||
* effect of CO2 on transpiration and biomass. | ||
* | ||
* @date 7 February 2017 | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <math.h> | ||
#include <string.h> | ||
#include "generic.h" | ||
#include "filefuncs.h" | ||
#include "SW_Defines.h" | ||
#include "SW_Times.h" | ||
#include "SW_Files.h" | ||
#include "SW_Carbon.h" | ||
#include "SW_Site.h" | ||
#include "SW_VegProd.h" | ||
|
||
/* =================================================== */ | ||
/* Global Variables */ | ||
/* --------------------------------------------------- */ | ||
|
||
|
||
/* =================================================== */ | ||
/* Module-Level Variables */ | ||
/* --------------------------------------------------- */ | ||
|
||
static char *MyFileName; | ||
SW_CARBON SW_Carbon; // Declared here, externed elsewhere | ||
SW_VEGPROD SW_VegProd; // Declared here, externed elsewhere | ||
|
||
|
||
/* =================================================== */ | ||
/* =================================================== */ | ||
/* Private Function Definitions */ | ||
/* --------------------------------------------------- */ | ||
|
||
/* =================================================== */ | ||
/* =================================================== */ | ||
/* Public Function Definitions */ | ||
/* --------------------------------------------------- */ | ||
|
||
/** | ||
* Initializes the multiplier values in the SW_CARBON structure | ||
* @note The spin-up year has been known to have the multipliers equal | ||
* to 0 without this constructor | ||
*/ | ||
void SW_CBN_construct(void) | ||
{ | ||
memset(&SW_Carbon, 0, sizeof(SW_Carbon)); | ||
|
||
SW_CARBON *c = &SW_Carbon; | ||
int year; | ||
|
||
for (year = 0; year < MAX_CO2_YEAR; year++) | ||
{ | ||
c->co2_multipliers[BIO_INDEX][year] = 1.0; | ||
c->co2_multipliers[WUE_INDEX][year] = 1.0; | ||
} | ||
|
||
c->co2_bio_mult = 1.0; | ||
c->co2_wue_mult = 1.0; | ||
} | ||
|
||
/* A description on how these 'onGet' and 'onSet' functions work... | ||
* Summary: onGet instantiates the 'swCarbon' class and returns the object, and is only used once | ||
* onSet extracts the value of the given object, and is used on both calls to SOILWAT2 | ||
* 1) An S4 class is described and generated in rSOILWAT2/R | ||
* 2) This class needs to be instantiatied, which is done here | ||
* 3) The object that gets returned here eventually gets inserted into swRunScenariosData[[1]] | ||
* 4) Data of the object is then modified with class functions in R (e.g. rSOILWAT2::swCarbon_Scenario(swRUnScenariosData[[1]]) <- "RCP85") | ||
* 5) The 'onSet' function is used to extract the latest data of the object (e.g. when SOILWAT2 begins modeling the real years) | ||
*/ | ||
#ifdef RSOILWAT | ||
SEXP onGet_SW_CARBON(void) { | ||
// Create access variables | ||
SEXP class, object; | ||
|
||
// Grab our S4 carbon class as an object | ||
PROTECT(class = MAKE_CLASS("swCarbon")); | ||
PROTECT(object = NEW_OBJECT(class)); | ||
|
||
// Extract the values to our global structure | ||
onSet_swCarbon(object); | ||
|
||
UNPROTECT(2); | ||
|
||
return object; | ||
} | ||
|
||
void onSet_swCarbon(SEXP object) { | ||
SW_CARBON *c = &SW_Carbon; | ||
|
||
// Extract the slots from our object into our structure | ||
c->use_bio_mult = INTEGER(GET_SLOT(object, install("CarbonUseBio")))[0]; | ||
c->use_wue_mult = INTEGER(GET_SLOT(object, install("CarbonUseWUE")))[0]; | ||
c->addtl_yr = INTEGER(GET_SLOT(object, install("DeltaYear")))[0]; | ||
strcpy(c->scenario, CHAR(STRING_ELT(GET_SLOT(object, install("Scenario")), 0))); // e.g. c->scenario = "RCP85" | ||
} | ||
#endif | ||
|
||
/** | ||
* Calculates the multipliers for biomass and Water-use efficiency. | ||
* If a multiplier is disabled, its value is set to 1. All the years | ||
* in carbon.in are calculated. rSOILWAT2 will pass in the settings directly. | ||
* SOILWAT2 will read siteparam.in for settings. | ||
*/ | ||
void calculate_CO2_multipliers(void) { | ||
FILE *f; | ||
char scenario[64]; | ||
double ppm; | ||
int year; | ||
|
||
SW_CARBON *c = &SW_Carbon; | ||
SW_VEGPROD *v = &SW_VegProd; | ||
MyFileName = SW_F_name(eCarbon); | ||
f = OpenFile(MyFileName, "r"); | ||
|
||
/* Calculate multipliers by reading carbon.in */ | ||
while (GetALine(f, inbuf)) { | ||
// Read the year standalone because if it's 0 it marks a change in the scenario, | ||
// in which case we'll need to read in a string instead of an int | ||
sscanf(inbuf, "%d", &year); | ||
|
||
// Find scenario | ||
if (year == 0) | ||
{ | ||
sscanf(inbuf, "%d %63s", &year, scenario); | ||
continue; // Skip to the PPM values | ||
} | ||
if (strcmp(scenario, c->scenario) != 0) | ||
continue; // Keep searching for the right scenario | ||
|
||
sscanf(inbuf, "%d %lf", &year, &ppm); | ||
if (c->use_bio_mult) c->co2_multipliers[BIO_INDEX][year] = v->co2_bio_coeff1 * pow(ppm, v->co2_bio_coeff2); | ||
if (c->use_wue_mult) c->co2_multipliers[WUE_INDEX][year] = v->co2_wue_coeff1 * pow(ppm, v->co2_wue_coeff2); | ||
} | ||
} | ||
|
||
/** | ||
* Applies CO2 effects to supplied biomass data. Two parameters are needed so that | ||
* we do not have a compound effect on the biomass. | ||
* @param new_biomass the resulting biomass after CO2 effects calculated | ||
* @param biomass the biomass to be modified | ||
*/ | ||
void apply_CO2(double new_biomass[], double biomass[]) { | ||
int i; | ||
SW_CARBON *c = &SW_Carbon; | ||
|
||
for (i = 0; i < 12; i++) new_biomass[i] = (biomass[i] * c->co2_bio_mult); | ||
} | ||
/** | ||
* @file SW_Carbon.c | ||
* @author Zachary Kramer | ||
* @brief Contains functions, constants, and variables that deal with the | ||
* effect of CO2 on transpiration and biomass. | ||
* | ||
* @date 7 February 2017 | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <math.h> | ||
#include <string.h> | ||
#include "generic.h" | ||
#include "filefuncs.h" | ||
#include "SW_Defines.h" | ||
#include "SW_Times.h" | ||
#include "SW_Files.h" | ||
#include "SW_Carbon.h" | ||
#include "SW_Site.h" | ||
#include "SW_VegProd.h" | ||
|
||
/* =================================================== */ | ||
/* Global Variables */ | ||
/* --------------------------------------------------- */ | ||
|
||
|
||
/* =================================================== */ | ||
/* Module-Level Variables */ | ||
/* --------------------------------------------------- */ | ||
|
||
static char *MyFileName; | ||
SW_CARBON SW_Carbon; // Declared here, externed elsewhere | ||
SW_VEGPROD SW_VegProd; // Declared here, externed elsewhere | ||
|
||
|
||
/* =================================================== */ | ||
/* =================================================== */ | ||
/* Private Function Definitions */ | ||
/* --------------------------------------------------- */ | ||
|
||
/* =================================================== */ | ||
/* =================================================== */ | ||
/* Public Function Definitions */ | ||
/* --------------------------------------------------- */ | ||
|
||
/** | ||
* Initializes the multiplier values in the SW_CARBON structure | ||
* @note The spin-up year has been known to have the multipliers equal | ||
* to 0 without this constructor | ||
*/ | ||
void SW_CBN_construct(void) | ||
{ | ||
memset(&SW_Carbon, 0, sizeof(SW_Carbon)); | ||
|
||
SW_CARBON *c = &SW_Carbon; | ||
int year; | ||
|
||
PFTs default_values; | ||
default_values.grass = default_values.shrub = default_values.tree = default_values.forb = 1.0; | ||
|
||
for (year = 0; year < MAX_CO2_YEAR; year++) | ||
{ | ||
c->co2_multipliers[BIO_INDEX][year] = default_values; | ||
c->co2_multipliers[WUE_INDEX][year] = default_values; | ||
} | ||
|
||
c->co2_bio_mult = default_values; | ||
c->co2_wue_mult = default_values; | ||
} | ||
|
||
/* A description on how these 'onGet' and 'onSet' functions work... | ||
* Summary: onGet instantiates the 'swCarbon' class and returns the object, and is only used once | ||
* onSet extracts the value of the given object, and is used on both calls to SOILWAT2 | ||
* 1) An S4 class is described and generated in rSOILWAT2/R | ||
* 2) This class needs to be instantiatied, which is done here | ||
* 3) The object that gets returned here eventually gets inserted into swRunScenariosData[[1]] | ||
* 4) Data of the object is then modified with class functions in R (e.g. rSOILWAT2::swCarbon_Scenario(swRUnScenariosData[[1]]) <- "RCP85") | ||
* 5) The 'onSet' function is used to extract the latest data of the object (e.g. when SOILWAT2 begins modeling the real years) | ||
*/ | ||
#ifdef RSOILWAT | ||
SEXP onGet_SW_CARBON(void) { | ||
// Create access variables | ||
SEXP class, object; | ||
|
||
// Grab our S4 carbon class as an object | ||
PROTECT(class = MAKE_CLASS("swCarbon")); | ||
PROTECT(object = NEW_OBJECT(class)); | ||
|
||
// Extract the values to our global structure | ||
onSet_swCarbon(object); | ||
|
||
UNPROTECT(2); | ||
|
||
return object; | ||
} | ||
|
||
void onSet_swCarbon(SEXP object) { | ||
SW_CARBON *c = &SW_Carbon; | ||
|
||
// Extract the slots from our object into our structure | ||
c->use_bio_mult = INTEGER(GET_SLOT(object, install("CarbonUseBio")))[0]; | ||
c->use_wue_mult = INTEGER(GET_SLOT(object, install("CarbonUseWUE")))[0]; | ||
c->addtl_yr = INTEGER(GET_SLOT(object, install("DeltaYear")))[0]; | ||
strcpy(c->scenario, CHAR(STRING_ELT(GET_SLOT(object, install("Scenario")), 0))); // e.g. c->scenario = "RCP85" | ||
} | ||
#endif | ||
|
||
/** | ||
* Calculates the multipliers for biomass and Water-use efficiency. | ||
* If a multiplier is disabled, its value is set to 1. All the years | ||
* in carbon.in are calculated. rSOILWAT2 will pass in the settings directly. | ||
* SOILWAT2 will read siteparam.in for settings. | ||
*/ | ||
void calculate_CO2_multipliers(void) { | ||
FILE *f; | ||
char scenario[64]; | ||
double ppm; | ||
int year; | ||
|
||
SW_CARBON *c = &SW_Carbon; | ||
SW_VEGPROD *v = &SW_VegProd; | ||
MyFileName = SW_F_name(eCarbon); | ||
f = OpenFile(MyFileName, "r"); | ||
|
||
// For efficiency, don't read carbon.in if neither multiplier is being used | ||
// We can do this because SW_CBN_CONSTRUCT already populated the multipliers with default values | ||
if (!c->use_bio_mult && !c->use_wue_mult) | ||
{ | ||
return; | ||
} | ||
|
||
/* Calculate multipliers by reading carbon.in */ | ||
while (GetALine(f, inbuf)) { | ||
// Read the year standalone because if it's 0 it marks a change in the scenario, | ||
// in which case we'll need to read in a string instead of an int | ||
sscanf(inbuf, "%d", &year); | ||
|
||
// Find scenario | ||
if (year == 0) | ||
{ | ||
sscanf(inbuf, "%d %63s", &year, scenario); | ||
continue; // Skip to the PPM values | ||
} | ||
if (strcmp(scenario, c->scenario) != 0) | ||
continue; // Keep searching for the right scenario | ||
|
||
sscanf(inbuf, "%d %lf", &year, &ppm); | ||
|
||
// Per PFT | ||
if (c->use_bio_mult) | ||
{ | ||
c->co2_multipliers[BIO_INDEX][year].grass = v->co2_bio_coeff1.grass * pow(ppm, v->co2_bio_coeff2.grass); | ||
c->co2_multipliers[BIO_INDEX][year].shrub = v->co2_bio_coeff1.shrub * pow(ppm, v->co2_bio_coeff2.shrub); | ||
c->co2_multipliers[BIO_INDEX][year].tree = v->co2_bio_coeff1.tree * pow(ppm, v->co2_bio_coeff2.tree); | ||
c->co2_multipliers[BIO_INDEX][year].forb = v->co2_bio_coeff1.forb * pow(ppm, v->co2_bio_coeff2.forb); | ||
} | ||
if (c->use_wue_mult) | ||
{ | ||
c->co2_multipliers[WUE_INDEX][year].grass = v->co2_wue_coeff1.grass * pow(ppm, v->co2_wue_coeff2.grass); | ||
c->co2_multipliers[WUE_INDEX][year].shrub = v->co2_wue_coeff1.shrub * pow(ppm, v->co2_wue_coeff2.shrub); | ||
c->co2_multipliers[WUE_INDEX][year].tree = v->co2_wue_coeff1.tree * pow(ppm, v->co2_wue_coeff2.tree); | ||
c->co2_multipliers[WUE_INDEX][year].forb = v->co2_wue_coeff1.forb * pow(ppm, v->co2_wue_coeff2.forb); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Applies CO2 effects to supplied biomass data. Two parameters are needed so that | ||
* we do not have a compound effect on the biomass. | ||
* @param new_biomass the resulting biomass after CO2 effects calculated | ||
* @param biomass the biomass to be modified | ||
* @param multiplier the biomass multiplier for this PFT | ||
*/ | ||
void apply_CO2(double new_biomass[], double biomass[], double multiplier) { | ||
int i; | ||
for (i = 0; i < 12; i++) new_biomass[i] = (biomass[i] * multiplier); | ||
} |
Oops, something went wrong.
6d4c7e9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Zachary-Kramer Can you please pay attention that you only commit diffs and don't commit entirely new copies of existing files. New copies makes tracking changes unnecessarily tricky, compare, e.g., this blame against this. The whole idea of version control relies on using diffs -- despite git not being a delta-based VCS; maybe this chapter helps clarify some of the concepts we use.
@CaitlinA Could you please enforce this and write it up very prominently in our guidelines? Thanks!
For instance, this commit used both
6d4c7e9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I acknowledged this in an issue I created #78. My git configuration was committing my line endings and I didn't notice it because upon diffing I had Ignore Whitespace turned on.