Skip to content
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

532 litter model should average abiotic quantities over relevant soil layers #534

4 changes: 3 additions & 1 deletion tests/models/litter/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,14 @@ def dummy_litter_data(fixture_core_components):

# Vertically structured variables
data["soil_temperature"] = lyr_strct.from_template()
data["soil_temperature"][lyr_strct.index_all_soil] = 20
data["soil_temperature"][lyr_strct.index_topsoil] = 20
data["soil_temperature"][lyr_strct.index_subsoil] = [19.5, 18.7, 18.7, 17.6]

# At present the soil model only uses the top soil layer, so this is the
# only one with real test values in
data["matric_potential"] = lyr_strct.from_template()
data["matric_potential"][lyr_strct.index_topsoil] = [-10.0, -25.0, -100.0, -100.0]
data["matric_potential"][lyr_strct.index_subsoil] = [-11.0, -29.5, -123.0, -154.1]

data["air_temperature"] = lyr_strct.from_template()
data["air_temperature"][lyr_strct.index_filled_atmosphere] = np.array(
Expand Down
141 changes: 136 additions & 5 deletions tests/models/litter/test_env_factors.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Test module for litter.env_factors.py."""

import numpy as np
import pytest

from virtual_ecosystem.models.litter.constants import LitterConsts

Expand All @@ -27,21 +28,151 @@ def test_calculate_temperature_effect_on_litter_decomp(
assert np.allclose(actual_factor, expected_factor)


def test_calculate_soil_water_effect_on_litter_decomp():
def test_calculate_soil_water_effect_on_litter_decomp(
dummy_litter_data, fixture_core_components
):
"""Test that soil moisture effects on decomposition are calculated correctly."""
from virtual_ecosystem.models.litter.env_factors import (
calculate_soil_water_effect_on_litter_decomp,
)

water_potentials = np.array([-10.0, -25.0, -100.0, -400.0])

expected_factor = [1.0, 0.88496823, 0.71093190, 0.53689556]
expected_factor = [1.0, 0.88496823, 0.71093190, 0.71093190]

actual_factor = calculate_soil_water_effect_on_litter_decomp(
water_potentials,
water_potential=dummy_litter_data["matric_potential"][
fixture_core_components.layer_structure.index_topsoil_scalar
],
water_potential_halt=LitterConsts.litter_decay_water_potential_halt,
water_potential_opt=LitterConsts.litter_decay_water_potential_optimum,
moisture_response_curvature=LitterConsts.moisture_response_curvature,
)

assert np.allclose(actual_factor, expected_factor)


@pytest.mark.parametrize(
"increased_depth,expected_av_temps",
[
pytest.param(
True,
[18.6319817, 18.498648, 18.498648, 18.315315],
id="increased depth",
),
pytest.param(
False,
[18.0729725, 18.0729725, 18.0729725, 18.0729725],
id="normal depth",
),
],
)
def test_average_temperature_over_microbially_active_layers(
dummy_litter_data, fixture_core_components, increased_depth, expected_av_temps
):
"""Check averaging of temperatures over soil layers works correctly."""
from virtual_ecosystem.models.litter.env_factors import (
average_temperature_over_microbially_active_layers,
)

if increased_depth:
fixture_core_components.layer_structure.soil_layer_active_thickness = np.array(
[0.5, 0.25]
)
fixture_core_components.layer_structure.max_depth_of_microbial_activity = 0.75

actual_av_temps = average_temperature_over_microbially_active_layers(
soil_temperatures=dummy_litter_data["soil_temperature"],
surface_temperature=dummy_litter_data["air_temperature"][
fixture_core_components.layer_structure.index_surface
].to_numpy(),
layer_structure=fixture_core_components.layer_structure,
)

assert np.allclose(actual_av_temps, expected_av_temps)


@pytest.mark.parametrize(
"increased_depth,expected_water_pots",
[
pytest.param(
True,
[-10.1667, -25.750, -103.8333, -109.0167],
id="increased depth",
),
pytest.param(
False,
[-10.0, -25.0, -100.0, -100.0],
id="normal depth",
),
],
)
def test_average_water_potential_over_microbially_active_layers(
dummy_litter_data, fixture_core_components, increased_depth, expected_water_pots
):
"""Check averaging of water potentials over soil layers works correctly."""
from virtual_ecosystem.models.litter.env_factors import (
average_water_potential_over_microbially_active_layers,
)

if increased_depth:
fixture_core_components.layer_structure.soil_layer_active_thickness = np.array(
[0.5, 0.25]
)
fixture_core_components.layer_structure.max_depth_of_microbial_activity = 0.75

actual_water_pots = average_water_potential_over_microbially_active_layers(
water_potentials=dummy_litter_data["matric_potential"],
layer_structure=fixture_core_components.layer_structure,
)

assert np.allclose(actual_water_pots, expected_water_pots)


@pytest.mark.parametrize(
"increased_depth,expected_factors",
[
pytest.param(
True,
{
"temp_above": [0.1878681, 0.1878681, 0.1878681, 0.1878681],
"temp_below": [0.2407699, 0.2377353, 0.2377353, 0.2335993],
"water": [0.9979245, 0.8812574, 0.7062095, 0.7000939],
},
id="increased depth",
),
pytest.param(
False,
{
"temp_above": [0.1878681, 0.1878681, 0.1878681, 0.1878681],
"temp_below": [0.2281971, 0.2281971, 0.2281971, 0.2281971],
"water": [1.0, 0.88496823, 0.71093190, 0.71093190],
},
id="normal depth",
),
],
)
def test_calculate_environmental_factors(
dummy_litter_data, fixture_core_components, increased_depth, expected_factors
):
"""Check that the calculation of the relevant environmental factors is correct."""
from virtual_ecosystem.models.litter.env_factors import (
calculate_environmental_factors,
)

if increased_depth:
fixture_core_components.layer_structure.soil_layer_active_thickness = np.array(
[0.5, 0.25]
)
fixture_core_components.layer_structure.max_depth_of_microbial_activity = 0.75

actual_factors = calculate_environmental_factors(
air_temperatures=dummy_litter_data["air_temperature"],
soil_temperatures=dummy_litter_data["soil_temperature"],
water_potentials=dummy_litter_data["matric_potential"],
layer_structure=fixture_core_components.layer_structure,
constants=LitterConsts,
)

assert set(expected_factors.keys()) == set(actual_factors.keys())

for key in actual_factors.keys():
assert np.allclose(actual_factors[key], expected_factors[key])
8 changes: 4 additions & 4 deletions tests/models/litter/test_litter_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,12 +311,12 @@ def test_update(fixture_litter_model, dummy_litter_data):
end_above_meta = [0.32072786, 0.15473132, 0.08523907, 0.08074153]
end_above_struct = [0.50470382, 0.25068224, 0.09843778, 0.11163532]
end_woody = [4.7745168, 11.89872931, 7.3614112, 7.3314112]
end_below_meta = [0.4090768, 0.37287148, 0.06883228, 0.08315412]
end_below_struct = [0.6066315, 0.31860251, 0.02010566, 0.03038382]
end_below_meta = [0.41087696, 0.37434507, 0.06905624, 0.08337808]
end_below_struct = [0.6066914, 0.31869812, 0.02010607, 0.03038423]
end_lignin_above_struct = [0.49790843, 0.10067782, 0.70495536, 0.71045831]
end_lignin_woody = [0.49580586, 0.79787834, 0.35224223, 0.35012603]
end_lignin_below_struct = [0.50313604, 0.2658639, 0.7499951, 0.82142894]
c_mineral = [0.02987233, 0.02316114, 0.00786517, 0.00786517]
end_lignin_below_struct = [0.50313573, 0.26585915, 0.7499951, 0.82142798]
c_mineral = [0.02652423, 0.02033658, 0.00746131, 0.00746131]

fixture_litter_model.update(time_index=0)

Expand Down
17 changes: 6 additions & 11 deletions tests/models/litter/test_litter_pools.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ def test_calculate_decay_rates(dummy_litter_data, fixture_core_components):
"metabolic_above": [0.00450883, 0.00225442, 0.00105206, 0.00105206],
"structural_above": [1.6742967e-4, 6.1857359e-4, 1.1086908e-5, 1.1086908e-5],
"woody": [0.0004832, 0.00027069, 0.0015888, 0.0015888],
"metabolic_below": [0.01092804, 0.00894564, 0.00135959, 0.00135959],
"structural_below": [3.6365995e-04, 5.803657e-04, 2.469074e-06, 2.469074e-06],
"metabolic_below": [0.00912788, 0.00747205, 0.00113563, 0.00113563],
"structural_below": [3.0375501e-4, 4.8476324e-4, 2.0623487e-6, 2.0623487e-6],
}

actual_decay = calculate_decay_rates(
Expand All @@ -109,15 +109,10 @@ def test_calculate_decay_rates(dummy_litter_data, fixture_core_components):
lignin_above_structural=dummy_litter_data["lignin_above_structural"].to_numpy(),
lignin_woody=dummy_litter_data["lignin_woody"].to_numpy(),
lignin_below_structural=dummy_litter_data["lignin_below_structural"].to_numpy(),
surface_temp=dummy_litter_data["air_temperature"][
fixture_core_components.layer_structure.index_surface_scalar
].to_numpy(),
topsoil_temp=dummy_litter_data["soil_temperature"][
fixture_core_components.layer_structure.index_topsoil_scalar
].to_numpy(),
water_potential=dummy_litter_data["matric_potential"][
fixture_core_components.layer_structure.index_topsoil_scalar
].to_numpy(),
air_temperatures=dummy_litter_data["air_temperature"],
soil_temperatures=dummy_litter_data["soil_temperature"],
water_potentials=dummy_litter_data["matric_potential"],
layer_structure=fixture_core_components.layer_structure,
constants=LitterConsts,
)

Expand Down
Loading
Loading