-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ORG78 Finish event wiring in SIPNET #25
Changes from 5 commits
84fdae8
1d72152
8b03f77
a0a57a6
7b7bab1
88aa5a9
4207e80
f22f0cd
55a77e4
3646156
e1d0aa6
20cf9b1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -491,6 +491,7 @@ static double *outputPtrs[MAX_DATA_TYPES]; // pointers to different possible out | |
|
||
#if EVENT_HANDLER | ||
static EventNode **events; | ||
static EventNode *locEvent; // current location event list | ||
#endif | ||
|
||
/* Read climate file into linked lists, | ||
|
@@ -2275,54 +2276,103 @@ void updateTrackers(double oldSoilWater) { | |
// mean of soil wetness at start of time step at soil wetness at end of time step - assume linear | ||
} | ||
|
||
// This should be in events.h/c, but with all the global state defined in this file, | ||
// let's leave it here for now. Maybe someday we will factor that out. | ||
// | ||
// Process events for current location/year/day | ||
void processEvents() { | ||
#if EVENT_HANDLER | ||
// If locEvent starts off NULL, this function will just fall through, as it should. | ||
const int year = climate->year; | ||
const int day = climate->day; | ||
|
||
// The events file has been tested on read, so we know this event list should be in chrono | ||
// order. However, we need to check to make sure the current event is not in the past, as | ||
// that would indicate an event that did not have a corresponding climate file record. | ||
while (locEvent != NULL && locEvent->year <= year && locEvent->day <= day) { | ||
if (locEvent->year < year || locEvent->day < day) { | ||
printf("Agronomic event found for loc: %d year: %d day: %d that does not have a corresponding record in the climate file\n", locEvent->year, locEvent->year, locEvent->day); | ||
exit(1); | ||
} | ||
switch (locEvent->type) { | ||
// Implementation TBD, as we enable the various event types | ||
case IRRIGATION: | ||
// TBD | ||
printf("Irrigation events not yet implemented\n"); | ||
break; | ||
case PLANTING: | ||
// TBD | ||
printf("Planting events not yet implemented\n"); | ||
break; | ||
case HARVEST: | ||
// TBD | ||
printf("Harvest events not yet implemented\n"); | ||
break; | ||
case TILLAGE: | ||
// TBD | ||
printf("Tillage events not yet implemented\n"); | ||
break; | ||
case FERTILIZATION: | ||
// TBD | ||
printf("Fertilization events not yet implemented\n"); | ||
break; | ||
default: | ||
printf("Unknown event type (%d) in processEvents()\n", locEvent->type); | ||
exit(1); | ||
} | ||
|
||
// !!! main runner function !!! | ||
locEvent = locEvent->nextEvent; | ||
} | ||
#endif | ||
} | ||
|
||
|
||
// !!! main runner function !!! | ||
|
||
// calculate all fluxes and update state for this time step | ||
// we calculate all fluxes before updating state in case flux calculations depend on the old state | ||
void updateState() { | ||
double npp; // net primary productivity, g C * m^-2 ground area * day^-1 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Everything in this function above the |
||
double oldSoilWater; // how much soil water was there before we updated it? Used in trackers | ||
int err; | ||
oldSoilWater = envi.soilWater; | ||
|
||
calculateFluxes(); | ||
|
||
// update the stocks, with fluxes adjusted for length of time step: | ||
envi.plantWoodC += (fluxes.photosynthesis + fluxes.woodCreation - fluxes.leafCreation - fluxes.woodLitter | ||
- fluxes.rVeg-fluxes.coarseRootCreation-fluxes.fineRootCreation)* climate->length; | ||
envi.plantLeafC += (fluxes.leafCreation - fluxes.leafLitter) * climate->length; | ||
|
||
double npp; // net primary productivity, g C * m^-2 ground area * day^-1 | ||
double oldSoilWater; // how much soil water was there before we updated it? Used in trackers | ||
int err; | ||
oldSoilWater = envi.soilWater; | ||
|
||
calculateFluxes(); | ||
|
||
// update the stocks, with fluxes adjusted for length of time step: | ||
envi.plantWoodC += (fluxes.photosynthesis + fluxes.woodCreation - fluxes.leafCreation - fluxes.woodLitter | ||
- fluxes.rVeg-fluxes.coarseRootCreation-fluxes.fineRootCreation)* climate->length; | ||
envi.plantLeafC += (fluxes.leafCreation - fluxes.leafLitter) * climate->length; | ||
|
||
soilDegradation(); // This updates all the soil functions | ||
soilDegradation(); // This updates all the soil functions | ||
|
||
#if MODEL_WATER // water pool updating happens here: | ||
|
||
#if LITTER_WATER // (2 soil water layers; litter water will only be on if complex water is also on) | ||
envi.litterWater += (fluxes.rain + fluxes.snowMelt - fluxes.immedEvap - fluxes.fastFlow | ||
- fluxes.evaporation - fluxes.topDrainage) * climate->length; | ||
envi.soilWater += (fluxes.topDrainage - fluxes.transpiration - fluxes.bottomDrainage) | ||
* climate->length; | ||
|
||
#if MODEL_WATER // water pool updating happens here: | ||
#else // LITTER_WATER = 0 (only one soil water layer) | ||
// note: some of these fluxes will always be 0 if complex water is off | ||
envi.soilWater += (fluxes.rain + fluxes.snowMelt - fluxes.immedEvap - fluxes.fastFlow | ||
- fluxes.evaporation - fluxes.transpiration - fluxes.bottomDrainage) * climate->length; | ||
#endif // LITTER_WATER | ||
|
||
#if LITTER_WATER // (2 soil water layers; litter water will only be on if complex water is also on) | ||
envi.litterWater += (fluxes.rain + fluxes.snowMelt - fluxes.immedEvap - fluxes.fastFlow | ||
- fluxes.evaporation - fluxes.topDrainage) * climate->length; | ||
envi.soilWater += (fluxes.topDrainage - fluxes.transpiration - fluxes.bottomDrainage) | ||
* climate->length; | ||
// if COMPLEX_WATER = 0 or SNOW = 0, some or all of these fluxes will always be 0 | ||
envi.snow += (fluxes.snowFall - fluxes.snowMelt - fluxes.sublimation) * climate->length; | ||
|
||
#else // LITTER_WATER = 0 (only one soil water layer) | ||
// note: some of these fluxes will always be 0 if complex water is off | ||
envi.soilWater += (fluxes.rain + fluxes.snowMelt - fluxes.immedEvap - fluxes.fastFlow | ||
- fluxes.evaporation - fluxes.transpiration - fluxes.bottomDrainage) * climate->length; | ||
#endif // LITTER_WATER | ||
|
||
// if COMPLEX_WATER = 0 or SNOW = 0, some or all of these fluxes will always be 0 | ||
envi.snow += (fluxes.snowFall - fluxes.snowMelt - fluxes.sublimation) * climate->length; | ||
|
||
#endif // MODEL_WATER | ||
#endif // MODEL_WATER | ||
|
||
ensureNonNegativeStocks(); | ||
|
||
#if EVENT_HANDLER | ||
Alomir marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// Process events for this location/year/day, AFTER updates are made to fluxes and state | ||
// variables above. Events are (currently, Jan 25, 2025) handled as instantaneous deltas to | ||
// relevant state (envi and fluxes fields), | ||
processEvents(); | ||
#endif | ||
|
||
npp = fluxes.photosynthesis - fluxes.rVeg-fluxes.rCoarseRoot-fluxes.rFineRoot; | ||
|
||
|
@@ -2343,7 +2393,6 @@ void updateState() { | |
} | ||
|
||
updateTrackers(oldSoilWater); | ||
|
||
} | ||
|
||
|
||
|
@@ -2485,7 +2534,9 @@ void setupModel(SpatialParams *spatialParams, int loc) { | |
|
||
// Setup events at given location | ||
void setupEvents(int currLoc) { | ||
// Implementation TBD | ||
#if EVENT_HANDLER | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. probably should be consistent and have the EVENT_HANDLER around the function as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch! |
||
locEvent = events[currLoc]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. indenting looks off here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Formatting looks inconsistent throughout - what about applying a formatter in a separate PR? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I cannot get CLion on Mac to listen to its own format settings, thus some wonky things sneak in. I def. vote for adding a formatter on checkin/push/merge or some such, but I'll fix this one here for now. Thanks for pointing that out! |
||
#endif | ||
} | ||
|
||
|
||
|
@@ -2554,6 +2605,12 @@ void runModelNoOut(double **outArray, int numDataTypes, int dataTypeIndices[], S | |
|
||
setupModel(spatialParams, loc); | ||
|
||
#if EVENT_HANDLER | ||
// Implementation TBD | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. indenting looks off here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ditto |
||
printf("Event handler not yet implemented for running model with no output\n"); | ||
exit(1); | ||
#endif | ||
|
||
// loop through every step of the model: | ||
while (climate != NULL) { | ||
updateState(); | ||
|
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.
do we really want to exit and not just print error message, and continue?
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.
That's a great question, I was going with what seems to be the standard for SIPNET - that is, exit on errors that look like mistakes in inputs. Any thoughts on this @dlebauer @infotroph ?
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.
Decided via discussion: using different error codes, starting here