Skip to content

Commit 8ff893e

Browse files
authored
Merge pull request #25 from PecanProject/ORG78_Finish_sipnet_wiring
ORG78 Finish event wiring in SIPNET
2 parents c0ca273 + 20cf9b1 commit 8ff893e

File tree

2 files changed

+111
-32
lines changed

2 files changed

+111
-32
lines changed

exitCodes.h

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#ifndef EXITCODES_H
2+
#define EXITCODES_H
3+
4+
// Exit codes for SIPNET; most of the current uses of exit(1) should
5+
// get better codes, which will appear here.
6+
//
7+
// Note for future: some codes typically have other meanings and should not be
8+
// used here (except for 0 and 1, for which our meaning is the usual meaning).
9+
// Some somewhat-standard codes in use:
10+
// - 0-2, 126-165, and 255; see, e.g., https://tldp.org/LDP/abs/html/exitcodes.html
11+
// - 64-78, see https://man7.org/linux/man-pages/man3/sysexits.h.3head.html
12+
//
13+
// The upshot here is that we should be a little sparing in our list of error codes.
14+
typedef enum {
15+
EXIT_CODE_SUCCESS = 0,
16+
EXIT_CODE_FAILURE = 1, // generic failure
17+
// code 2 typically has a special meaning, see above
18+
EXIT_CODE_UNKNOWN_EVENT = 3
19+
} exit_code_t;
20+
21+
#endif

sipnet.c

+90-32
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "outputItems.h"
2121
#include "modelStructures.h"
2222
#include "events.h"
23+
#include "exitCodes.h"
2324

2425
// begin definitions for choosing different model structures
2526
// (1 -> true, 0 -> false)
@@ -491,6 +492,7 @@ static double *outputPtrs[MAX_DATA_TYPES]; // pointers to different possible out
491492

492493
#if EVENT_HANDLER
493494
static EventNode **events;
495+
static EventNode *locEvent; // current location event list
494496
#endif
495497

496498
/* Read climate file into linked lists,
@@ -2275,54 +2277,103 @@ void updateTrackers(double oldSoilWater) {
22752277
// mean of soil wetness at start of time step at soil wetness at end of time step - assume linear
22762278
}
22772279

2280+
// This should be in events.h/c, but with all the global state defined in this file,
2281+
// let's leave it here for now. Maybe someday we will factor that out.
2282+
//
2283+
// Process events for current location/year/day
2284+
#if EVENT_HANDLER
2285+
void processEvents() {
2286+
// If locEvent starts off NULL, this function will just fall through, as it should.
2287+
const int year = climate->year;
2288+
const int day = climate->day;
2289+
2290+
// The events file has been tested on read, so we know this event list should be in chrono
2291+
// order. However, we need to check to make sure the current event is not in the past, as
2292+
// that would indicate an event that did not have a corresponding climate file record.
2293+
while (locEvent != NULL && locEvent->year <= year && locEvent->day <= day) {
2294+
if (locEvent->year < year || locEvent->day < day) {
2295+
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);
2296+
exit(1);
2297+
}
2298+
switch (locEvent->type) {
2299+
// Implementation TBD, as we enable the various event types
2300+
case IRRIGATION:
2301+
// TBD
2302+
printf("Irrigation events not yet implemented\n");
2303+
break;
2304+
case PLANTING:
2305+
// TBD
2306+
printf("Planting events not yet implemented\n");
2307+
break;
2308+
case HARVEST:
2309+
// TBD
2310+
printf("Harvest events not yet implemented\n");
2311+
break;
2312+
case TILLAGE:
2313+
// TBD
2314+
printf("Tillage events not yet implemented\n");
2315+
break;
2316+
case FERTILIZATION:
2317+
// TBD
2318+
printf("Fertilization events not yet implemented\n");
2319+
break;
2320+
default:
2321+
printf("Unknown event type (%d) in processEvents()\n", locEvent->type);
2322+
exit(EXIT_CODE_UNKNOWN_EVENT);
2323+
}
22782324

2279-
// !!! main runner function !!!
2325+
locEvent = locEvent->nextEvent;
2326+
}
2327+
}
2328+
#endif
22802329

22812330

2331+
// !!! main runner function !!!
22822332

22832333
// calculate all fluxes and update state for this time step
22842334
// we calculate all fluxes before updating state in case flux calculations depend on the old state
22852335
void updateState() {
2286-
double npp; // net primary productivity, g C * m^-2 ground area * day^-1
2287-
double oldSoilWater; // how much soil water was there before we updated it? Used in trackers
2288-
int err;
2289-
oldSoilWater = envi.soilWater;
2290-
2291-
calculateFluxes();
2292-
2293-
// update the stocks, with fluxes adjusted for length of time step:
2294-
envi.plantWoodC += (fluxes.photosynthesis + fluxes.woodCreation - fluxes.leafCreation - fluxes.woodLitter
2295-
- fluxes.rVeg-fluxes.coarseRootCreation-fluxes.fineRootCreation)* climate->length;
2296-
envi.plantLeafC += (fluxes.leafCreation - fluxes.leafLitter) * climate->length;
2297-
2298-
2336+
double npp; // net primary productivity, g C * m^-2 ground area * day^-1
2337+
double oldSoilWater; // how much soil water was there before we updated it? Used in trackers
2338+
int err;
2339+
oldSoilWater = envi.soilWater;
22992340

2341+
calculateFluxes();
23002342

2301-
soilDegradation(); // This updates all the soil functions
2343+
// update the stocks, with fluxes adjusted for length of time step:
2344+
envi.plantWoodC += (fluxes.photosynthesis + fluxes.woodCreation - fluxes.leafCreation - fluxes.woodLitter
2345+
- fluxes.rVeg-fluxes.coarseRootCreation-fluxes.fineRootCreation)* climate->length;
2346+
envi.plantLeafC += (fluxes.leafCreation - fluxes.leafLitter) * climate->length;
23022347

2348+
soilDegradation(); // This updates all the soil functions
23032349

2350+
#if MODEL_WATER // water pool updating happens here:
23042351

2305-
#if MODEL_WATER // water pool updating happens here:
2352+
#if LITTER_WATER // (2 soil water layers; litter water will only be on if complex water is also on)
2353+
envi.litterWater += (fluxes.rain + fluxes.snowMelt - fluxes.immedEvap - fluxes.fastFlow
2354+
- fluxes.evaporation - fluxes.topDrainage) * climate->length;
2355+
envi.soilWater += (fluxes.topDrainage - fluxes.transpiration - fluxes.bottomDrainage)
2356+
* climate->length;
23062357

2307-
#if LITTER_WATER // (2 soil water layers; litter water will only be on if complex water is also on)
2308-
envi.litterWater += (fluxes.rain + fluxes.snowMelt - fluxes.immedEvap - fluxes.fastFlow
2309-
- fluxes.evaporation - fluxes.topDrainage) * climate->length;
2310-
envi.soilWater += (fluxes.topDrainage - fluxes.transpiration - fluxes.bottomDrainage)
2311-
* climate->length;
2358+
#else // LITTER_WATER = 0 (only one soil water layer)
2359+
// note: some of these fluxes will always be 0 if complex water is off
2360+
envi.soilWater += (fluxes.rain + fluxes.snowMelt - fluxes.immedEvap - fluxes.fastFlow
2361+
- fluxes.evaporation - fluxes.transpiration - fluxes.bottomDrainage) * climate->length;
2362+
#endif // LITTER_WATER
23122363

2313-
#else // LITTER_WATER = 0 (only one soil water layer)
2314-
// note: some of these fluxes will always be 0 if complex water is off
2315-
envi.soilWater += (fluxes.rain + fluxes.snowMelt - fluxes.immedEvap - fluxes.fastFlow
2316-
- fluxes.evaporation - fluxes.transpiration - fluxes.bottomDrainage) * climate->length;
2317-
#endif // LITTER_WATER
2364+
// if COMPLEX_WATER = 0 or SNOW = 0, some or all of these fluxes will always be 0
2365+
envi.snow += (fluxes.snowFall - fluxes.snowMelt - fluxes.sublimation) * climate->length;
23182366

2319-
// if COMPLEX_WATER = 0 or SNOW = 0, some or all of these fluxes will always be 0
2320-
envi.snow += (fluxes.snowFall - fluxes.snowMelt - fluxes.sublimation) * climate->length;
2321-
2322-
#endif // MODEL_WATER
2367+
#endif // MODEL_WATER
23232368

23242369
ensureNonNegativeStocks();
23252370

2371+
#if EVENT_HANDLER
2372+
// Process events for this location/year/day, AFTER updates are made to fluxes and state
2373+
// variables above. Events are (currently, Jan 25, 2025) handled as instantaneous deltas to
2374+
// relevant state (envi and fluxes fields),
2375+
processEvents();
2376+
#endif
23262377

23272378
npp = fluxes.photosynthesis - fluxes.rVeg-fluxes.rCoarseRoot-fluxes.rFineRoot;
23282379

@@ -2343,7 +2394,6 @@ void updateState() {
23432394
}
23442395

23452396
updateTrackers(oldSoilWater);
2346-
23472397
}
23482398

23492399

@@ -2484,9 +2534,11 @@ void setupModel(SpatialParams *spatialParams, int loc) {
24842534

24852535

24862536
// Setup events at given location
2537+
#if EVENT_HANDLER
24872538
void setupEvents(int currLoc) {
2488-
// Implementation TBD
2539+
locEvent = events[currLoc];
24892540
}
2541+
#endif
24902542

24912543

24922544
/* Do one run of the model using parameter values in spatialParams
@@ -2554,6 +2606,12 @@ void runModelNoOut(double **outArray, int numDataTypes, int dataTypeIndices[], S
25542606

25552607
setupModel(spatialParams, loc);
25562608

2609+
#if EVENT_HANDLER
2610+
// Implementation TBD
2611+
printf("Event handler not yet implemented for running model with no output\n");
2612+
exit(1);
2613+
#endif
2614+
25572615
// loop through every step of the model:
25582616
while (climate != NULL) {
25592617
updateState();

0 commit comments

Comments
 (0)