diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6b11c81fc..39e37b621 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,6 +10,7 @@ on: - 'docs/**' jobs: + # Build and Integration Test build: strategy: diff --git a/.github/workflows/debug.yml b/.github/workflows/debug.yml new file mode 100644 index 000000000..f2558f12b --- /dev/null +++ b/.github/workflows/debug.yml @@ -0,0 +1,24 @@ +name: Setup Linux Debug Session + +on: + workflow_dispatch: + inputs: + debug_enabled: + type: boolean + description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)' + required: false + default: false + +jobs: + # Debug environment + debug: + runs-on: ubuntu-latest + environment: debug + steps: + - uses: actions/checkout@v4 + - name: Install gdb + if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled }} + run: sudo apt install gdb + - name: Setup tmate session + if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled }} + uses: mxschmitt/action-tmate@v3 diff --git a/src/sipnet/events.c b/src/sipnet/events.c index ef32be1a2..1d828cf1f 100644 --- a/src/sipnet/events.c +++ b/src/sipnet/events.c @@ -303,13 +303,19 @@ void doWriteEventOut(int year, int day, const char *type, int numParams, // Standard prefix for all fprintf(eventOutFile, "%4d %3d %-7s ", year, day, type); + // For debugging on linux + char *param; + double val; // Variable output per oneEvent type for (ind = 0; ind < numParams - 1; ind++) { - fprintf(eventOutFile, "%s=%-.2f,", va_arg(args, char *), - va_arg(args, double)); + // For debugging on linux + param = va_arg(args, char *); + val = va_arg(args, double); + fprintf(eventOutFile, "%s=%-.2f,", param, val); } - fprintf(eventOutFile, "%s=%-.2f\n", va_arg(args, char *), - va_arg(args, double)); + param = va_arg(args, char *); + val = va_arg(args, double); + fprintf(eventOutFile, "%s=%-.2f\n", param, val); } void writeEventOut(EventNode *oneEvent, int numParams, ...) { @@ -350,9 +356,12 @@ void resetEventFluxes(void) { fluxes.eventCoarseRootC = 0.0; fluxes.eventEvap = 0.0; fluxes.eventSoilWater = 0.0; + fluxes.eventSoilC = 0.0; fluxes.eventLitterC = 0.0; fluxes.eventMinN = 0.0; + fluxes.eventSoilOrgN = 0.0; fluxes.eventLitterN = 0.0; + // mass balance fluxes.eventInputC = 0.0; fluxes.eventOutputC = 0.0; @@ -448,7 +457,8 @@ void processEvents(void) { "fluxes.eventInputN", inputN / climLen); } break; case HARVEST: { - // Harvest can both remove biomass and move biomass to the litter pool + // Harvest can both remove biomass and move biomass to the soil/litter + // pools const HarvestParams *harvParams = gEvent->eventParams; const double fracRA = harvParams->fractionRemovedAbove; const double fracTA = harvParams->fractionTransferredAbove; @@ -457,8 +467,9 @@ void processEvents(void) { const double woodC = envi.plantWoodC + envi.plantWoodCStorageDelta; // Litter increase - const double litterAdd = fracTA * (envi.plantLeafC + woodC) + - fracTB * (envi.fineRootC + envi.coarseRootC); + double litterAdd = fracTA * (envi.plantLeafC + woodC); + double soilAdd = fracTB * (envi.fineRootC + envi.coarseRootC); + // Pool reductions, counting both mass moved to litter and removed by // the harvest itself. Above-ground changes: const double leafDelta = -envi.plantLeafC * (fracRA + fracTA); @@ -468,24 +479,35 @@ void processEvents(void) { const double coarseDelta = -envi.coarseRootC * (fracRB + fracTB); // Pool updates: + if (!ctx.litterPool) { + // send it all to the soil + soilAdd += litterAdd; + litterAdd = 0.0; + } fluxes.eventLitterC += litterAdd / climLen; + fluxes.eventSoilC += soilAdd / climLen; fluxes.eventLeafC += leafDelta / climLen; fluxes.eventWoodC += woodDelta / climLen; fluxes.eventFineRootC += fineDelta / climLen; fluxes.eventCoarseRootC += coarseDelta / climLen; // No need to allocate to biomass N pools, we don't track that N - // explicitly. We do need to handle litter N, though. + // explicitly. We do need to handle soil and litter N, though. + // Note: ctx.nitrogenCycle implies ctx.litterPool // Litter N increase double litterNAdd = 0.0; + double soilNAdd = 0.0; if (ctx.nitrogenCycle) { const double totalAbove = (envi.plantLeafC / params.leafCN) + (envi.plantWoodC / params.woodCN); const double totalBelow = (envi.fineRootC / params.fineRootCN) + (envi.coarseRootC / params.woodCN); - litterNAdd = (fracTA * totalAbove) + (fracTB * totalBelow); + litterNAdd = fracTA * totalAbove; + soilNAdd = fracTB * totalBelow; + fluxes.eventSoilOrgN += soilNAdd / climLen; fluxes.eventLitterN += litterNAdd / climLen; } + // MASS BALANCE: removed fractions are system outputs const double outputC = ((woodC + envi.plantLeafC) * fracRA + (envi.fineRootC + envi.coarseRootC) * fracRB); @@ -501,14 +523,15 @@ void processEvents(void) { fracRB); fluxes.eventOutputN += outputN / climLen; } - writeEventOut( - gEvent, 8, "fluxes.eventLitterC", litterAdd / climLen, - "fluxes.eventLeafC", leafDelta / climLen, "fluxes.eventWoodC", - woodDelta / climLen, "fluxes.eventFineRootC", fineDelta / climLen, + gEvent, 10, "fluxes.eventSoilC", soilAdd / climLen, + "fluxes.eventLitterC", litterAdd / climLen, "fluxes.eventLeafC", + leafDelta / climLen, "fluxes.eventWoodC", woodDelta / climLen, + "fluxes.eventFineRootC", fineDelta / climLen, "fluxes.eventCoarseRootC", coarseDelta / climLen, - "fluxes.eventLitterN", litterNAdd / climLen, "fluxes.eventOutputC", - outputC / climLen, "fluxes.eventOutputN", outputN / climLen); + "fluxes.eventSoilOrgN", soilNAdd / climLen, "fluxes.eventLitterN", + litterNAdd / climLen, "fluxes.eventOutputC", outputC / climLen, + "fluxes.eventOutputN", outputN / climLen); } break; case TILLAGE: { // BIG NOTE: this is the one event type that is NOT modeled as a flux; @@ -526,19 +549,25 @@ void processEvents(void) { const double orgC = fertParams->orgC; double orgN = fertParams->orgN; double minN = fertParams->minN; - if (!ctx.nitrogenCycle) { + if (ctx.litterPool) { + fluxes.eventLitterC += orgC / climLen; + } else { + fluxes.eventSoilC += orgC / climLen; + } + + if (ctx.nitrogenCycle) { // As the warning says in readEventData(), we ignore N when the // nitrogen cycle model is off - orgN = 0.0; - minN = 0.0; + // Implies ctx.litterPool + fluxes.eventLitterN += orgN / climLen; + fluxes.eventMinN += minN / climLen; } - fluxes.eventLitterC += orgC / climLen; - fluxes.eventLitterN += orgN / climLen; - fluxes.eventMinN += minN / climLen; // MASS BALANCE: this is a system input fluxes.eventInputC += orgC / climLen; - fluxes.eventInputN += (orgN + minN) / climLen; + if (ctx.nitrogenCycle) { + fluxes.eventInputN += (orgN + minN) / climLen; + } writeEventOut(gEvent, 5, "fluxes.eventOrgN", orgN / climLen, "fluxes.eventLitterC", orgC / climLen, "fluxes.eventMinN", @@ -561,10 +590,9 @@ void updatePoolsForEvents(void) { envi.plantLeafC += fluxes.eventLeafC * climate->length; // Harvest and fertilization events + envi.soilC += fluxes.eventSoilC * climate->length; if (ctx.litterPool) { envi.litterC += fluxes.eventLitterC * climate->length; - } else { - envi.soilC += fluxes.eventLitterC * climate->length; } // Harvest and planting events @@ -576,11 +604,12 @@ void updatePoolsForEvents(void) { envi.soilWater += fluxes.eventSoilWater * climate->length; // NITROGEN - // Fertilization events - // (Harvest and planting events TBD) - // Note: litter_pool is required for nitrogen_cycle + // Harvest and fertilization events + // (Planting events don't explicitly handle N) + // Note: nitrogen_cycle implies litter_pool if (ctx.nitrogenCycle) { envi.minN += fluxes.eventMinN * climate->length; + envi.soilOrgN += fluxes.eventSoilOrgN * climate->length; envi.litterN += fluxes.eventLitterN * climate->length; } } diff --git a/src/sipnet/state.h b/src/sipnet/state.h index a0239635f..f07a550c9 100644 --- a/src/sipnet/state.h +++ b/src/sipnet/state.h @@ -565,10 +565,14 @@ typedef struct FluxVars { double eventEvap; // irrigation water that goes to the soil double eventSoilWater; - // carbon added to litter pool (if used) or soil pool (if not) + // carbon added to soil pool + double eventSoilC; + // carbon added to litter pool double eventLitterC; // nitrogen added to soil mineral N pool double eventMinN; + // nitrogen added to soil org N pool + double eventSoilOrgN; // nitrogen added to litter N pool double eventLitterN; // MASS BALANCE HELPERS diff --git a/tests/sipnet/test_events_infrastructure/events_output_header.out b/tests/sipnet/test_events_infrastructure/events_output_header.out index a0d04dc52..5cb70a77b 100644 --- a/tests/sipnet/test_events_infrastructure/events_output_header.out +++ b/tests/sipnet/test_events_infrastructure/events_output_header.out @@ -1,7 +1,7 @@ year day type param_name=delta[,param_name=delta,...] 2023 65 plant fluxes.eventLeafC=6.00,fluxes.eventWoodC=8.00,fluxes.eventFineRootC=10.00,fluxes.eventCoarseRootC=12.00,fluxes.eventInputC=36.00,fluxes.eventInputN=0.00 2023 70 irrig fluxes.eventSoilWater=10.00,fluxes.eventEvap=0.00 -2023 200 harv fluxes.eventLitterC=10.93,fluxes.eventLeafC=-11.86,fluxes.eventWoodC=-9.50,fluxes.eventFineRootC=-7.46,fluxes.eventCoarseRootC=-7.78,fluxes.eventLitterN=0.00,fluxes.eventOutputC=25.66,fluxes.eventOutputN=0.00 +2023 200 harv fluxes.eventSoilC=3.81,fluxes.eventLitterC=7.12,fluxes.eventLeafC=-11.86,fluxes.eventWoodC=-9.50,fluxes.eventFineRootC=-7.46,fluxes.eventCoarseRootC=-7.78,fluxes.eventSoilOrgN=0.00,fluxes.eventLitterN=0.00,fluxes.eventOutputC=25.66,fluxes.eventOutputN=0.00 2024 65 plant fluxes.eventLeafC=6.00,fluxes.eventWoodC=10.00,fluxes.eventFineRootC=14.00,fluxes.eventCoarseRootC=18.00,fluxes.eventInputC=48.00,fluxes.eventInputN=0.00 2024 70 irrig fluxes.eventSoilWater=5.00,fluxes.eventEvap=5.00 -2024 200 harv fluxes.eventLitterC=8.51,fluxes.eventLeafC=-2.78,fluxes.eventWoodC=-3.27,fluxes.eventFineRootC=-5.04,fluxes.eventCoarseRootC=-5.93,fluxes.eventLitterN=0.00,fluxes.eventOutputC=8.51,fluxes.eventOutputN=0.00 +2024 200 harv fluxes.eventSoilC=5.48,fluxes.eventLitterC=3.02,fluxes.eventLeafC=-2.78,fluxes.eventWoodC=-3.27,fluxes.eventFineRootC=-5.04,fluxes.eventCoarseRootC=-5.93,fluxes.eventSoilOrgN=0.00,fluxes.eventLitterN=0.00,fluxes.eventOutputC=8.51,fluxes.eventOutputN=0.00 diff --git a/tests/sipnet/test_events_infrastructure/events_output_no_header.out b/tests/sipnet/test_events_infrastructure/events_output_no_header.out index bbeb85df4..574b1113e 100644 --- a/tests/sipnet/test_events_infrastructure/events_output_no_header.out +++ b/tests/sipnet/test_events_infrastructure/events_output_no_header.out @@ -1,6 +1,6 @@ 2023 65 plant fluxes.eventLeafC=20.00,fluxes.eventWoodC=10.00,fluxes.eventFineRootC=8.00,fluxes.eventCoarseRootC=6.00,fluxes.eventInputC=44.00,fluxes.eventInputN=0.00 2023 70 irrig fluxes.eventSoilWater=10.00,fluxes.eventEvap=0.00 -2023 200 harv fluxes.eventLitterC=24.80,fluxes.eventLeafC=-9.60,fluxes.eventWoodC=-6.40,fluxes.eventFineRootC=-9.60,fluxes.eventCoarseRootC=-9.60,fluxes.eventLitterN=0.00,fluxes.eventOutputC=10.40,fluxes.eventOutputN=0.00 +2023 200 harv fluxes.eventSoilC=24.80,fluxes.eventLitterC=0.00,fluxes.eventLeafC=-9.60,fluxes.eventWoodC=-6.40,fluxes.eventFineRootC=-9.60,fluxes.eventCoarseRootC=-9.60,fluxes.eventSoilOrgN=0.00,fluxes.eventLitterN=0.00,fluxes.eventOutputC=10.40,fluxes.eventOutputN=0.00 2024 65 plant fluxes.eventLeafC=20.00,fluxes.eventWoodC=10.00,fluxes.eventFineRootC=8.00,fluxes.eventCoarseRootC=6.00,fluxes.eventInputC=44.00,fluxes.eventInputN=0.00 2024 70 irrig fluxes.eventSoilWater=5.00,fluxes.eventEvap=5.00 -2024 200 harv fluxes.eventLitterC=24.28,fluxes.eventLeafC=-20.64,fluxes.eventWoodC=-11.76,fluxes.eventFineRootC=-5.76,fluxes.eventCoarseRootC=-4.96,fluxes.eventLitterN=0.00,fluxes.eventOutputC=18.84,fluxes.eventOutputN=0.00 +2024 200 harv fluxes.eventSoilC=24.28,fluxes.eventLitterC=0.00,fluxes.eventLeafC=-20.64,fluxes.eventWoodC=-11.76,fluxes.eventFineRootC=-5.76,fluxes.eventCoarseRootC=-4.96,fluxes.eventSoilOrgN=0.00,fluxes.eventLitterN=0.00,fluxes.eventOutputC=18.84,fluxes.eventOutputN=0.00 diff --git a/tests/sipnet/test_events_types/events_two_harvest.in b/tests/sipnet/test_events_types/events_two_harvest.in index 3e0464c23..30f83c95d 100644 --- a/tests/sipnet/test_events_types/events_two_harvest.in +++ b/tests/sipnet/test_events_types/events_two_harvest.in @@ -1,2 +1,2 @@ 2024 70 harv 0.1 0.2 0.3 0.4 -2024 70 harv 0.25 0.25 0.25 0.25 +2024 70 harv 0.2 0.1 0.2 0.1 diff --git a/tests/sipnet/test_events_types/testEventFertilization.c b/tests/sipnet/test_events_types/testEventFertilization.c index 5c89452fa..7c0d346dc 100644 --- a/tests/sipnet/test_events_types/testEventFertilization.c +++ b/tests/sipnet/test_events_types/testEventFertilization.c @@ -61,6 +61,7 @@ int run(void) { initEvents("events_one_fert.in", 0); setupEvents(); procEvents(); + closeEventOutFile(); // First fert: (15-5-10) expOrgN = 0; // nitrogen cycle is off @@ -78,6 +79,7 @@ int run(void) { initEvents("events_two_fert.in", 1); setupEvents(); procEvents(); + closeEventOutFile(); // First event same as above (15-5-10) expOrgN = 3 + 15; diff --git a/tests/sipnet/test_events_types/testEventHarvest.c b/tests/sipnet/test_events_types/testEventHarvest.c index 80912a79b..db92e0c63 100644 --- a/tests/sipnet/test_events_types/testEventHarvest.c +++ b/tests/sipnet/test_events_types/testEventHarvest.c @@ -5,22 +5,8 @@ #include "typesUtils.h" -int checkOutput(double litter, double leafC, double woodC, double fineC, - double coarseC) { +int checkBioOutput(double leafC, double woodC, double fineC, double coarseC) { int status = 0; - double curLitter = 0; - if (ctx.litterPool) { - logTest("Checking litter pool\n"); - curLitter = envi.litterC; - } else { - logTest("Checking soil pool\n"); - curLitter = envi.soilC; - litter += 0.5; // We bumped init soil C to distinguish - } - if (!compareDoubles(litter, curLitter)) { - logTest("Litter/soil C is %f, expected %f\n", curLitter, litter); - status = 1; - } if (!compareDoubles(leafC, envi.plantLeafC)) { logTest("Plant leaf C is %f, expected %f\n", envi.plantLeafC, leafC); status = 1; @@ -40,18 +26,61 @@ int checkOutput(double litter, double leafC, double woodC, double fineC, return status; } +int checkSoilOutput(double soilC, double litterC, double soilOrgN, + double litterN) { + int status = 0; + if (!compareDoubles(soilC, envi.soilC)) { + logTest("Soil C is %f, expected %f\n", envi.soilC, soilC); + status = 1; + } + if (!compareDoubles(litterC, envi.litterC)) { + logTest("Litter C is %f, expected %f\n", envi.litterC, litterC); + status = 1; + } + if (!compareDoubles(soilOrgN, envi.soilOrgN)) { + logTest("Soil Org N is %f, expected %f\n", envi.soilOrgN, soilOrgN); + status = 1; + } + if (!compareDoubles(litterN, envi.litterN)) { + logTest("Litter N is %f, expected %f\n", envi.litterN, litterN); + status = 1; + } + return status; +} + void initEnv(void) { - envi.soilC = 1.5; - envi.litterC = 1; + envi.soilC = 10; + envi.litterC = 0; envi.plantLeafC = 2; envi.plantWoodC = 3; envi.fineRootC = 4; envi.coarseRootC = 5; + envi.soilOrgN = 0; + envi.litterN = 0; + + if (ctx.litterPool) { + envi.litterC = 15; + } + if (ctx.nitrogenCycle) { + envi.soilOrgN = 2.0; + envi.litterN = 3.0; + params.woodCN = 10; + params.leafCN = 20; + params.fineRootCN = 30; + } + + // not used here, but accessed + envi.plantWoodCStorageDelta = 0.0; + envi.soilWater = 10.0; + envi.minN = 10.0; } int run(void) { int status = 0; - double expLitter, expLeafC, expWoodC, expFineC, expCoarseC; + double expSoilC, expLitterC; + double expLeafC, expWoodC, expFineC, expCoarseC; + double expSoilOrgN = 0.0; + double expLitterN = 0.0; // We will need to switch back and forth between litter pool and soil manually prepTypesTest(); @@ -59,38 +88,55 @@ int run(void) { // init values initEnv(); - //// ONE PLANTING EVENT + //// ONE HARVEST EVENT + logTest("Testing one event\n"); updateIntContext("litterPool", 0, CTX_TEST); - logTest("Litter pool is %s\n", ctx.litterPool ? "on" : "off"); + updateIntContext("nitrogenCycle", 0, CTX_TEST); + logTest("Litter pool is %s, nitrogen cycle is %s\n", + ctx.litterPool ? "on" : "off", ctx.nitrogenCycle ? "on" : "off"); initEvents("events_one_harvest.in", 0); setupEvents(); procEvents(); - + closeEventOutFile(); // fracRA = 0.1, fracRB = 0.2, frac TA = 0.3, fracTB = 0.4 - expLitter = 1 + 0.3 * (2 + 3) + 0.4 * (4 + 5); // 1 + 1.5 + 3.6 = 6.1 + expSoilC = 10 + 0.3 * (2 + 3) + 0.4 * (4 + 5); // 10 + 1.5 + 3.6 = 15.1 + expLitterC = 0.0; // litter pool off expLeafC = 2 * (1 - 0.1 - 0.3); // 1.2 expWoodC = 3 * (1 - 0.1 - 0.3); // 1.8 expFineC = 4 * (1 - 0.2 - 0.4); // 1.6 expCoarseC = 5 * (1 - 0.2 - 0.4); // 2.0 - status |= checkOutput(expLitter, expLeafC, expWoodC, expFineC, expCoarseC); + status |= checkBioOutput(expLeafC, expWoodC, expFineC, expCoarseC); + status |= checkSoilOutput(expSoilC, expLitterC, expSoilOrgN, expLitterN); - //// TWO HARVEST + //// TWO HARVEST EVENTS // Ok, so, two harvest events on the same day shouldn't happen (seriously, // model it as one harvest) - but we can test the arithmetic here + // fracRA = 0.1, fracRB = 0.2, frac TA = 0.3, fracTB = 0.4 + // fracRA = 0.2, fracRB = 0.1, frac TA = 0.2, fracTB = 0.1 + logTest("Testing two events\n"); updateIntContext("litterPool", 1, CTX_TEST); - logTest("Litter pool is %s\n", ctx.litterPool ? "on" : "off"); + updateIntContext("nitrogenCycle", 1, CTX_TEST); + logTest("Litter pool is %s, nitrogen cycle is %s\n", + ctx.litterPool ? "on" : "off", ctx.nitrogenCycle ? "on" : "off"); initEnv(); initEvents("events_two_harvest.in", 1); setupEvents(); procEvents(); + closeEventOutFile(); // Two events are additive - expLitter = 1 + (0.3 + 0.25) * (2 + 3) + (0.4 + 0.25) * (4 + 5); // 9.6 - expLeafC = 2 * (1 - 0.1 - 0.3 - 0.25 - 0.25); // 0.2 - expWoodC = 3 * (1 - 0.1 - 0.3 - 0.25 - 0.25); // 0.3 - expFineC = 4 * (1 - 0.2 - 0.4 - 0.25 - 0.25); // -0.4 - expCoarseC = 5 * (1 - 0.2 - 0.4 - 0.25 - 0.25); // -0.5 + expSoilC = 10 + (0.4 + 0.1) * (4 + 5); + expLitterC = 15 + (0.3 + 0.2) * (2 + 3); + expLeafC = 2 * (1 - 0.1 - 0.3 - 0.2 - 0.2); + expWoodC = 3 * (1 - 0.1 - 0.3 - 0.2 - 0.2); + expFineC = 4 * (1 - 0.2 - 0.4 - 0.1 - 0.1); + expCoarseC = 5 * (1 - 0.2 - 0.4 - 0.1 - 0.1); + expSoilOrgN = 2 + (4 * (0.4 + 0.1)) / params.fineRootCN + + (5 * (0.4 + 0.1)) / params.woodCN; + expLitterN = + 3 + (3 * (0.3 + 0.2)) / params.woodCN + (2 * (0.3 + 0.2)) / params.leafCN; - status |= checkOutput(expLitter, expLeafC, expWoodC, expFineC, expCoarseC); + status |= checkBioOutput(expLeafC, expWoodC, expFineC, expCoarseC); + status |= checkSoilOutput(expSoilC, expLitterC, expSoilOrgN, expLitterN); return status; } diff --git a/tests/sipnet/test_events_types/testEventIrrigation.c b/tests/sipnet/test_events_types/testEventIrrigation.c index f0cf35366..2ee9a4c0e 100644 --- a/tests/sipnet/test_events_types/testEventIrrigation.c +++ b/tests/sipnet/test_events_types/testEventIrrigation.c @@ -35,6 +35,7 @@ int run(void) { initEvents("events_one_irrig.in", 0); setupEvents(); procEvents(); + closeEventOutFile(); // should have 5 going to the soil status |= checkOutput(5, 0); @@ -44,6 +45,7 @@ int run(void) { initEvents("events_two_irrig.in", 1); setupEvents(); procEvents(); + closeEventOutFile(); // event 1: 3 to soil // event 2: 2=4*0.5 to evap, the rest (2) to soil // (plus the five from the test above) diff --git a/tests/sipnet/test_events_types/testEventPlanting.c b/tests/sipnet/test_events_types/testEventPlanting.c index 48c282f49..42f8e90b6 100644 --- a/tests/sipnet/test_events_types/testEventPlanting.c +++ b/tests/sipnet/test_events_types/testEventPlanting.c @@ -45,6 +45,7 @@ int run(void) { initEvents("events_one_planting.in", 0); setupEvents(); procEvents(); + closeEventOutFile(); // added: leaf 10, wood 5, fine root 4, coarse root 3 status |= checkOutput(1 + 10, 2 + 5, 3 + 4, 4 + 3); @@ -53,6 +54,7 @@ int run(void) { initEvents("events_two_planting.in", 1); setupEvents(); procEvents(); + closeEventOutFile(); // leaf 10+9, wood 5+6, fine root 4+8, coarse root 3+4 status |= checkOutput(1 + 19, 2 + 11, 3 + 12, 4 + 7); diff --git a/tests/sipnet/test_events_types/testEventTillage.c b/tests/sipnet/test_events_types/testEventTillage.c index 2f5ef4181..8d6f5c44f 100644 --- a/tests/sipnet/test_events_types/testEventTillage.c +++ b/tests/sipnet/test_events_types/testEventTillage.c @@ -34,6 +34,7 @@ int run(void) { initEvents("events_one_tillage.in", 0); setupEvents(); procEvents(); + closeEventOutFile(); // First tillage: expTillMod = 0.5; @@ -64,6 +65,7 @@ int run(void) { status |= checkOutput("post-update", expTillMod); climate = climate->nextClim; } + closeEventOutFile(); return status; }