tests/testthat/test.cumulative_modules.R

# Helping function for checking carbon accounting for a particular growth
# calculator module using the soybean model as a base. Here we use a nonzero
# `growth_respiration_fraction` to test that it is properly accounted for.
test_soybean_carbon_accounting <- function(partitioning_calculator) {
    description <- paste0(
        'the soybean model accounts for all carbon when using `',
        partitioning_calculator,
        '` as its partitioning growth calculator module'
    )

    test_that(description, {
        soybean_res <- expect_silent(
            with(soybean, {run_biocro(
                c(initial_values, list(
                    canopy_assimilation = 0,
                    canopy_gross_assimilation = 0,
                    canopy_non_photorespiratory_CO2_release = 0,
                    canopy_photorespiration = 0,
                    canopy_transpiration = 0,
                    Grain_gr = 0,
                    Grain_mr = 0,
                    Leaf_gr = 0,
                    Leaf_mr = 0,
                    Leaf_WS_loss = 0,
                    Rhizome_gr = 0,
                    Rhizome_mr = 0,
                    Root_gr = 0,
                    Root_mr = 0,
                    Shell_gr = 0,
                    Shell_mr = 0,
                    soil_evaporation = 0,
                    Stem_gr = 0,
                    Stem_mr = 0,
                    total_precip = 0,
                    whole_plant_growth_respiration = 0
                )),
                within(parameters, {
                    growth_respiration_fraction = 0.01
                }),
                soybean_weather[['2002']],
                c(
                    list(
                        'BioCro:total_biomass',
                        'BioCro:total_growth_and_maintenance_respiration'
                    ),
                    within(direct_modules, {
                        partitioning_growth_calculator = partitioning_calculator
                    })
                ),
                c(differential_modules, list(
                    'BioCro:cumulative_carbon_dynamics',
                    'BioCro:cumulative_water_dynamics'
                ))
            )})
        )

        # Check that all the assimilated carbon (gross assimilation) is balanced
        # by the sum costs of photorespiration, non-photorespiratory CO2 release
        # by the leaf, growth respiration, maintenance respiration, tissue
        # growth, and litter formation.
        soybean_res$total_carbon_use <- with(soybean_res, {
            (total_intact_biomass - total_intact_biomass[1]) +
            (total_litter_biomass - total_litter_biomass[1]) +
            canopy_non_photorespiratory_CO2_release +
            canopy_photorespiration +
            total_growth_respiration +
            total_maintenance_respiration
        })

        expect_equal(
            soybean_res$canopy_gross_assimilation,
            soybean_res$total_carbon_use
        )

        ## Uncomment this when debugging test failures to visually check whether
        ## the difference is real
        #dev.new()
        #print(lattice::xyplot(
        #    total_carbon_use + canopy_gross_assimilation ~ fractional_doy,
        #    data = soybean_res,
        #    type = 'l',
        #    auto = TRUE,
        #    main = partitioning_calculator
        #))

        # Check that all CO2 loss rates are non-negative
        with(soybean_res, {
            expect_true(all(canopy_photorespiration_rate >= 0))
            expect_true(all(canopy_non_photorespiratory_CO2_release_rate >= 0))
            expect_true(all(Grain_gr_rate >= 0))
            expect_true(all(Grain_mr_rate >= 0))
            expect_true(all(Leaf_gr_rate >= 0))
            expect_true(all(Leaf_mr_rate >= 0))
            expect_true(all(Leaf_WS_loss_rate >= 0))
            expect_true(all(Rhizome_gr_rate >= 0))
            expect_true(all(Rhizome_mr_rate >= 0))
            expect_true(all(Root_gr_rate >= 0))
            expect_true(all(Root_mr_rate >= 0))
            expect_true(all(Shell_gr_rate >= 0))
            expect_true(all(Shell_mr_rate >= 0))
            expect_true(all(Stem_gr_rate >= 0))
            expect_true(all(Stem_mr_rate >= 0))
            expect_true(all(whole_plant_growth_respiration_rate >= 0))
        })

        # Check that gross assimilation is non-negative
        expect_true(all(soybean_res$canopy_gross_assimilation >= 0))
    })
}

# Test each possible partitioning growth calculator module
partitioning_calculator_modules <- c(
    'BioCro:partitioning_growth_calculator_leaf_costs',
    'BioCro:partitioning_growth_calculator'
)

for (pm in partitioning_calculator_modules) {
    test_soybean_carbon_accounting(pm)
}

# Make sure all partitioning growth calculators have the same inputs and outputs
test_that('all partitioning calculators have the same inputs and outputs', {
    expect_equal(
        module_info('BioCro:partitioning_growth_calculator', verbose = FALSE)$inputs,
        module_info('BioCro:partitioning_growth_calculator_leaf_costs', verbose = FALSE)$inputs
    )

    expect_equal(
        module_info('BioCro:partitioning_growth_calculator', verbose = FALSE)$outputs,
        module_info('BioCro:partitioning_growth_calculator_leaf_costs', verbose = FALSE)$outputs
    )
})

Try the BioCro package in your browser

Any scripts or data that you put into this service are public.

BioCro documentation built on Feb. 7, 2026, 1:08 a.m.