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

Adding organic phosphorus flows #653

Merged
merged 10 commits into from
Jan 8, 2025
5 changes: 5 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,11 +265,16 @@ def dummy_carbon_data(fixture_core_components):
"soil_n_pool_particulate": [0.00714285, 0.00071425, 0.00285714, 0.01428571],
"soil_n_pool_necromass": [0.00288462, 0.01788462, 0.02019231, 0.01115385],
"soil_n_pool_maom": [0.86538462, 0.48076923, 0.32692308, 0.09615385],
"soil_p_pool_dop": [5.714e-6, 2.2857120e-5, 5.7142800e-5, 1.1428568e-4],
"soil_p_pool_particulate": [2.857e-5, 2.85714e-4, 1.142856e-4, 5.714284e-4],
"soil_p_pool_necromass": [0.00080769, 0.00011538, 0.00071538, 0.00044615],
"soil_p_pool_maom": [0.01307692, 0.03461538, 0.01923077, 0.00384615],
"pH": [3.0, 7.5, 9.0, 5.7],
"bulk_density": [1350.0, 1800.0, 1000.0, 1500.0],
"clay_fraction": [0.8, 0.3, 0.1, 0.9],
"litter_C_mineralisation_rate": [0.00212106, 0.00106053, 0.00049000, 0.0055],
"litter_N_mineralisation_rate": [3.5351e-5, 7.0702e-5, 0.000183, 1.63333e-5],
"litter_P_mineralisation_rate": [7.32e-6, 1.41404e-6, 2.82808e-6, 6.53332e-7],
"vertical_flow": [0.1, 0.5, 2.5, 1.59],
}

Expand Down
4 changes: 4 additions & 0 deletions tests/core/test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -978,6 +978,10 @@ def test_output_current_state(mocker, dummy_carbon_data, time_index):
"soil_n_pool_particulate",
"soil_n_pool_necromass",
"soil_n_pool_maom",
"soil_p_pool_dop",
"soil_p_pool_particulate",
"soil_p_pool_necromass",
"soil_p_pool_maom",
],
time_index,
)
Expand Down
1 change: 1 addition & 0 deletions tests/models/soil/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ def microbial_changes(
return calculate_microbial_changes(
soil_c_pool_lmwc=dummy_carbon_data["soil_c_pool_lmwc"],
soil_n_pool_don=dummy_carbon_data["soil_n_pool_don"],
soil_p_pool_dop=dummy_carbon_data["soil_p_pool_dop"],
soil_c_pool_microbe=dummy_carbon_data["soil_c_pool_microbe"],
soil_enzyme_pom=dummy_carbon_data["soil_enzyme_pom"],
soil_enzyme_maom=dummy_carbon_data["soil_enzyme_maom"],
Expand Down
115 changes: 75 additions & 40 deletions tests/models/soil/test_pools.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,21 @@ def test_calculate_all_pool_updates(dummy_carbon_data, fixture_core_components):
soil_pools = SoilPools(data=dummy_carbon_data, pools=pools, constants=SoilConsts)

change_in_pools = {
"soil_c_pool_lmwc": [0.0129365, 0.0060499, 0.03697928, 0.02425546],
"soil_c_pool_lmwc": [0.01510858, 0.01400719, 0.03697928, 0.02426899],
"soil_c_pool_maom": [0.038767651, 0.00829848, 0.05982197, 0.07277182],
"soil_c_pool_microbe": [-0.05362396, -0.02020101, -0.11965575, -0.00719517],
"soil_c_pool_microbe": [-0.0544059, -0.02282691, -0.11965575, -0.00720166],
"soil_c_pool_pom": [0.00177803841, -0.007860960795, -0.012016245, 0.00545032],
"soil_c_pool_necromass": [0.001137474, 0.009172067, 0.033573266, -0.08978050],
"soil_enzyme_pom": [1.18e-8, 1.67e-8, 1.8e-9, -1.12e-8],
"soil_enzyme_maom": [-0.00031009, -5.09593e-5, 0.0005990658, -3.72112e-5],
"soil_n_pool_don": [0.00104884, 0.00419763, 0.00496839, 0.00251317],
"soil_n_pool_don": [0.00119921, 0.00470261, 0.00496839, 0.00251442],
"soil_n_pool_particulate": [1.102338e-5, 6.422491e-5, 0.000131687, 1.461799e-5],
"soil_n_pool_necromass": [0.00786114, -0.01209909, 0.00432363, -0.00891218],
"soil_n_pool_maom": [0.00148604, 0.01179891, 0.01365197, 0.0077315],
"soil_p_pool_dop": [1.92918032e-4, 6.24454858e-5, 1.57222238e-4, 9.94118894e-5],
"soil_p_pool_particulate": [7.22218e-6, -1.13464e-6, 7.86083e-7, 5.85634364e-7],
"soil_p_pool_necromass": [2.674836e-3, 1.333056e-3, 6.8090685e-3, 4.1429847e-5],
"soil_p_pool_maom": [5.52086672e-4, 3.68566732e-5, 4.7566130e-4, 3.09257058e-4],
}

# Make order of pools object
Expand All @@ -72,16 +76,18 @@ def test_calculate_microbial_changes(

from virtual_ecosystem.models.soil.pools import calculate_microbial_changes

expected_lmwc_uptake = [2.241176e-3, 8.433524e-3, 1.556094e-3, 5.7736357e-5]
expected_don_uptake = [1.5515837e-4, 5.3520443e-4, 8.97746776e-5, 5.3295099e-6]
expected_microbe = [-0.05362396, -0.02020101, -0.11965575, -0.00719517]
expected_lmwc_uptake = [6.90989514e-5, 4.76229800e-4, 1.55609440e-3, 4.42097002e-5]
expected_don_uptake = [4.78377356e-6, 3.02222758e-5, 8.97746767e-5, 4.08089540e-6]
expected_dop_uptake = [1.55472641e-6, 9.82223962e-6, 2.91767699e-5, 1.32629101e-6]
expected_microbe = [-0.0544059, -0.02282691, -0.11965575, -0.00720166]
expected_pom_enzyme = [1.17571917e-8, 1.67442231e-8, 1.83311362e-9, -1.11675865e-8]
expected_maom_enzyme = [-3.1009224e-4, -5.0959256e-5, 5.9906583e-4, -3.7211168e-5]
expected_necromass = [0.05474086, 0.02303502, 0.11952352, 0.00726011]

mic_changes = calculate_microbial_changes(
soil_c_pool_lmwc=dummy_carbon_data["soil_c_pool_lmwc"],
soil_n_pool_don=dummy_carbon_data["soil_n_pool_don"],
soil_p_pool_dop=dummy_carbon_data["soil_p_pool_dop"],
soil_c_pool_microbe=dummy_carbon_data["soil_c_pool_microbe"],
soil_enzyme_pom=dummy_carbon_data["soil_enzyme_pom"],
soil_enzyme_maom=dummy_carbon_data["soil_enzyme_maom"],
Expand All @@ -95,6 +101,7 @@ def test_calculate_microbial_changes(
# Check that each rate matches expectation
assert np.allclose(mic_changes.lmwc_uptake, expected_lmwc_uptake)
assert np.allclose(mic_changes.don_uptake, expected_don_uptake)
assert np.allclose(mic_changes.dop_uptake, expected_dop_uptake)
assert np.allclose(mic_changes.microbe_change, expected_microbe)
assert np.allclose(mic_changes.pom_enzyme_change, expected_pom_enzyme)
assert np.allclose(mic_changes.maom_enzyme_change, expected_maom_enzyme)
Expand Down Expand Up @@ -225,27 +232,36 @@ def test_calculate_nutrient_uptake_rates(
calculate_nutrient_uptake_rates,
)

expected_carbon_gain = [8.06823526e-4, 2.78306304e-3, 4.66828324e-4, 2.77134516e-5]
expected_nitrogen_gain = [1.5515837e-4, 5.3520443e-4, 8.97746776e-5, 5.3295099e-6]
expected_carbon_consumption = [2.241176e-3, 8.433524e-3, 1.556094e-3, 5.7736357e-5]

actual_carbon_gain, actual_carbon_consumption, actual_nitrogen_gain = (
calculate_nutrient_uptake_rates(
soil_c_pool_lmwc=dummy_carbon_data["soil_c_pool_lmwc"],
soil_n_pool_don=dummy_carbon_data["soil_n_pool_don"],
soil_c_pool_microbe=dummy_carbon_data["soil_c_pool_microbe"],
water_factor=environmental_factors.water,
pH_factor=environmental_factors.pH,
soil_temp=dummy_carbon_data["soil_temperature"][
fixture_core_components.layer_structure.index_topsoil_scalar
].to_numpy(),
constants=SoilConsts,
)
expected_carbon_gain = [2.48756225e-5, 1.57155834e-4, 4.66828319e-4, 2.12206561e-5]
expected_consumption_rates = {
"nitrogen": [4.78377356e-6, 3.02222758e-5, 8.97746767e-5, 4.08089540e-6],
"phosphorus": [1.55472641e-6, 9.82223962e-6, 2.91767699e-5, 1.32629101e-6],
"carbon": [6.90989514e-5, 4.76229800e-4, 1.55609440e-3, 4.42097002e-5],
}

actual_carbon_gain, actual_consumption_rates = calculate_nutrient_uptake_rates(
soil_c_pool_lmwc=dummy_carbon_data["soil_c_pool_lmwc"],
soil_n_pool_don=dummy_carbon_data["soil_n_pool_don"],
soil_p_pool_dop=dummy_carbon_data["soil_p_pool_dop"],
soil_c_pool_microbe=dummy_carbon_data["soil_c_pool_microbe"],
water_factor=environmental_factors.water,
pH_factor=environmental_factors.pH,
soil_temp=dummy_carbon_data["soil_temperature"][
fixture_core_components.layer_structure.index_topsoil_scalar
].to_numpy(),
constants=SoilConsts,
)

assert np.allclose(actual_carbon_gain, expected_carbon_gain)
assert np.allclose(actual_nitrogen_gain, expected_nitrogen_gain)
assert np.allclose(actual_carbon_consumption, expected_carbon_consumption)

assert set(expected_consumption_rates.keys()) == set(
actual_consumption_rates.keys()
)

for key in expected_consumption_rates.keys():
assert np.allclose(
expected_consumption_rates[key], actual_consumption_rates[key]
)


def test_calculate_highest_achievable_nutrient_uptake(
Expand Down Expand Up @@ -409,52 +425,71 @@ def test_calculate_nutrient_flows_to_necromass(microbial_changes):
)

expected_n_flow_to_necromass = [0.01052709, 0.00442981, 0.02298529, 0.00139617]
expected_p_flow_to_necromass = [0.0034213, 0.00143969, 0.00747022, 0.00045376]

actual_n_flow_to_necromass = calculate_nutrient_flows_to_necromass(
microbial_changes=microbial_changes, constants=SoilConsts
actual_n_flow_to_necromass, actual_p_flow_to_necromass = (
calculate_nutrient_flows_to_necromass(
microbial_changes=microbial_changes, constants=SoilConsts
)
)

assert np.allclose(actual_n_flow_to_necromass, expected_n_flow_to_necromass)
assert np.allclose(actual_p_flow_to_necromass, expected_p_flow_to_necromass)


def test_find_necromass_nitrogen_outflows(
def test_find_necromass_nutrient_outflows(
dummy_carbon_data, necromass_breakdown, necromass_sorption
):
"""Test that function to find necromass nitrogen losses works correctly."""
from virtual_ecosystem.models.soil.pools import find_necromass_nitrogen_outflows

expected_decay = [0.00066649, 0.00413222, 0.00466541, 0.00257709]
expected_sorption = [0.00199947, 0.01239667, 0.01399624, 0.00773126]
"""Test that function to find necromass nutrient losses works correctly."""
from virtual_ecosystem.models.soil.pools import find_necromass_nutrient_outflows

expected_rates = {
"decay_nitrogen": [0.00066649, 0.00413222, 0.00466541, 0.00257709],
"sorption_nitrogen": [0.00199947, 0.01239667, 0.01399624, 0.00773126],
"decay_phosphorus": [1.86616016e-4, 2.6658441e-5, 1.65287877e-4, 1.03082538e-4],
"sorption_phosphorus": [5.5984805e-4, 7.9975322e-5, 4.958636e-4, 3.0924762e-4],
}

actual_decay, actual_sorption = find_necromass_nitrogen_outflows(
actual_rates = find_necromass_nutrient_outflows(
necromass_carbon=dummy_carbon_data["soil_c_pool_necromass"],
necromass_nitrogen=dummy_carbon_data["soil_n_pool_necromass"],
necromass_phosphorus=dummy_carbon_data["soil_p_pool_necromass"],
necromass_decay=necromass_breakdown,
necromass_sorption=necromass_sorption,
)

assert np.allclose(actual_decay, expected_decay)
assert np.allclose(actual_sorption, expected_sorption)
assert set(expected_rates.keys()) == set(actual_rates.keys())

for key in expected_rates.keys():
assert np.allclose(expected_rates[key], actual_rates[key])

def test_calculate_net_nitrogen_transfer_from_maom_to_don(

def test_calculate_net_nutrient_transfers_from_maom_to_lmwc(
dummy_carbon_data, enzyme_mediated_rates, lmwc_sorption, maom_desorption
):
"""Test function to find net exchange of nitrogen between maom and don."""
from virtual_ecosystem.models.soil.pools import (
calculate_net_nitrogen_transfer_from_maom_to_don,
calculate_net_nutrient_transfers_from_maom_to_lmwc,
)

expected_transfer = [5.13427177e-4, 5.97759087e-4, 3.44268148e-4, -2.36081562e-7]
expected_transfers = {
"nitrogen": [5.13427177e-4, 5.97759087e-4, 3.44268148e-4, -2.36081562e-7],
"phosphorus": [7.76137416e-6, 4.31186485e-5, 2.02023283e-5, -9.44337153e-9],
}

actual_transfer = calculate_net_nitrogen_transfer_from_maom_to_don(
actual_transfers = calculate_net_nutrient_transfers_from_maom_to_lmwc(
lmwc_carbon=dummy_carbon_data["soil_c_pool_lmwc"],
lmwc_nitrogen=dummy_carbon_data["soil_n_pool_don"],
lmwc_phosphorus=dummy_carbon_data["soil_p_pool_dop"],
maom_carbon=dummy_carbon_data["soil_c_pool_maom"],
maom_nitrogen=dummy_carbon_data["soil_n_pool_maom"],
maom_phosphorus=dummy_carbon_data["soil_p_pool_maom"],
maom_breakdown=enzyme_mediated_rates.maom_to_lmwc,
maom_desorption=maom_desorption,
lmwc_sorption=lmwc_sorption,
)

assert np.allclose(actual_transfer, expected_transfer)
assert set(expected_transfers.keys()) == set(actual_transfers.keys())

for key in expected_transfers.keys():
assert np.allclose(expected_transfers[key], actual_transfers[key])
63 changes: 49 additions & 14 deletions tests/models/soil/test_soil_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
(DEBUG, "soil model: required var 'soil_n_pool_particulate' checked"),
(DEBUG, "soil model: required var 'soil_n_pool_necromass' checked"),
(DEBUG, "soil model: required var 'soil_n_pool_maom' checked"),
(DEBUG, "soil model: required var 'soil_p_pool_dop' checked"),
(DEBUG, "soil model: required var 'soil_p_pool_particulate' checked"),
(DEBUG, "soil model: required var 'soil_p_pool_necromass' checked"),
(DEBUG, "soil model: required var 'soil_p_pool_maom' checked"),
(DEBUG, "soil model: required var 'pH' checked"),
(DEBUG, "soil model: required var 'bulk_density' checked"),
(DEBUG, "soil model: required var 'clay_fraction' checked"),
Expand Down Expand Up @@ -285,20 +289,20 @@ def test_update(mocker, fixture_soil_model, dummy_carbon_data):
Dataset(
data_vars=dict(
soil_c_pool_lmwc=DataArray(
[0.0558832, 0.02294602, 0.11309406, 0.01485682], dims="cell_id"
[0.0571695, 0.02695769, 0.11767019, 0.01488859], dims="cell_id"
),
soil_c_pool_maom=DataArray(
[2.5194618, 1.70483236, 4.53238116, 0.52968038], dims="cell_id"
),
soil_c_pool_microbe=DataArray(
[5.77347072, 2.29002259, 11.24219185, 0.99642319],
[5.77300855, 2.28870164, 11.24082106, 0.99640795],
dims="cell_id",
),
soil_c_pool_pom=DataArray(
[0.10088826, 0.99607827, 0.69401858, 0.35272508], dims="cell_id"
),
soil_c_pool_necromass=DataArray(
[0.05840173, 0.01865113, 0.10631256, 0.06904725], dims="cell_id"
[0.05840079, 0.01864821, 0.10630987, 0.06904723], dims="cell_id"
),
soil_enzyme_pom=DataArray(
[0.02267842, 0.00957576, 0.05004963, 0.00300993], dims="cell_id"
Expand All @@ -307,17 +311,31 @@ def test_update(mocker, fixture_soil_model, dummy_carbon_data):
[0.0354453, 0.01167442, 0.02538637, 0.00454144], dims="cell_id"
),
soil_n_pool_don=DataArray(
[0.00124825, 0.00320679, 0.00236633, 0.00388298], dims="cell_id"
[0.00133728, 0.00346121, 0.00262946, 0.0038859], dims="cell_id"
),
soil_n_pool_particulate=DataArray(
[0.00714836, 0.00074629, 0.00292269, 0.01429302], dims="cell_id"
),
soil_n_pool_necromass=DataArray(
[0.00602181, 0.01303618, 0.02189848, 0.00758444], dims="cell_id"
[0.00602163, 0.01303562, 0.02189796, 0.00758443], dims="cell_id"
),
soil_n_pool_maom=DataArray(
[0.86671423, 0.48576345, 0.33406677, 0.09935391], dims="cell_id"
),
soil_p_pool_dop=DataArray(
[1.59404568e-4, 8.17510225e-5, 2.73598058e-4, 1.64590927e-4],
dims="cell_id",
),
soil_p_pool_particulate=DataArray(
[3.21780215e-5, 2.85147941e-4, 1.14676885e-4, 5.71721209e-4],
dims="cell_id",
),
soil_p_pool_necromass=DataArray(
[0.00187526, 0.00064761, 0.00343342, 0.00046239], dims="cell_id"
),
soil_p_pool_maom=DataArray(
[0.01355237, 0.03473323, 0.01997613, 0.00400384], dims="cell_id"
),
)
),
(),
Expand Down Expand Up @@ -398,6 +416,7 @@ def test_order_independance(
"clay_fraction",
"litter_C_mineralisation_rate",
"litter_N_mineralisation_rate",
"litter_P_mineralisation_rate",
]
for not_pool in not_pools:
new_data[not_pool] = dummy_carbon_data[not_pool]
Expand Down Expand Up @@ -436,18 +455,18 @@ def test_construct_full_soil_model(dummy_carbon_data, fixture_core_components):
)

delta_pools = [
0.0129365,
0.0060499,
0.01510858,
0.01400719,
0.03697928,
0.02425546,
0.02426899,
0.038767651,
0.00829848,
0.05982197,
0.07277182,
-0.05362396,
-0.02020101,
-0.0544059,
-0.02282691,
-0.11965575,
-0.00719517,
-0.00720166,
0.00177803841,
-0.007860960795,
-0.012016245,
Expand All @@ -464,10 +483,10 @@ def test_construct_full_soil_model(dummy_carbon_data, fixture_core_components):
-5.09593e-5,
0.0005990658,
-3.72112e-5,
0.00104884,
0.00419763,
0.00119921,
0.00470261,
0.00496839,
0.00251317,
0.00251442,
1.102338e-5,
6.422491e-5,
0.000131687,
Expand All @@ -480,6 +499,22 @@ def test_construct_full_soil_model(dummy_carbon_data, fixture_core_components):
0.01179891,
0.01365197,
0.0077315,
1.92918032e-4,
6.24454858e-5,
1.57222238e-4,
9.94118894e-5,
7.22218e-6,
-1.13464e-6,
7.86083e-7,
5.85634364e-7,
2.674836e-3,
1.333056e-3,
6.8090685e-3,
4.1429847e-5,
5.52086672e-4,
3.68566732e-5,
4.7566130e-4,
3.09257058e-4,
]

# make pools
Expand Down
4 changes: 4 additions & 0 deletions tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
(DEBUG, "soil model: required var 'soil_n_pool_particulate' checked"),
(DEBUG, "soil model: required var 'soil_n_pool_necromass' checked"),
(DEBUG, "soil model: required var 'soil_n_pool_maom' checked"),
(DEBUG, "soil model: required var 'soil_p_pool_dop' checked"),
(DEBUG, "soil model: required var 'soil_p_pool_particulate' checked"),
(DEBUG, "soil model: required var 'soil_p_pool_necromass' checked"),
(DEBUG, "soil model: required var 'soil_p_pool_maom' checked"),
(DEBUG, "soil model: required var 'pH' checked"),
(DEBUG, "soil model: required var 'bulk_density' checked"),
(DEBUG, "soil model: required var 'clay_fraction' checked"),
Expand Down
Loading
Loading