Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions tests/models/abiotic_simple/test_abiotic_simple_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,10 @@ def test_abiotic_simple_model_initialization(


@pytest.mark.parametrize(
"cfg_string,satvap1,raises,expected_log_entries",
"cfg_string,raises,expected_log_entries",
[
pytest.param(
"[core.timing]\nupdate_interval = '1 week'\n[abiotic_simple]\n",
[0.61078, 7.5, 237.3],
does_not_raise(),
tuple(
[
Expand All @@ -94,8 +93,7 @@ def test_abiotic_simple_model_initialization(
pytest.param(
"[core.timing]\nupdate_interval = '1 week'\n"
"[abiotic_simple.constants]\n"
"saturation_vapour_pressure_factors = [1.0, 2.0, 3.0]\n",
[1.0, 2.0, 3.0],
"initial_net_radiation = 20\n",
does_not_raise(),
tuple(
[
Expand All @@ -115,7 +113,6 @@ def test_generate_abiotic_simple_model(
caplog,
dummy_climate_data_varying_canopy,
cfg_string,
satvap1,
raises,
expected_log_entries,
):
Expand Down
4 changes: 1 addition & 3 deletions tests/models/abiotic_simple/test_microclimate_simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ def test_varying_canopy_calculate_vapour_pressure_deficit(
def test_run_microclimate_varying_canopy(
dummy_climate_data_varying_canopy,
fixture_core_components,
fixture_abiotic_constants,
fixture_core_constants,
fixture_abiotic_simple_configuration,
):
Expand All @@ -89,8 +88,7 @@ def test_run_microclimate_varying_canopy(
data=data,
layer_structure=lyr_strct,
time_index=0,
simple_constants=fixture_abiotic_simple_configuration.constants,
abiotic_constants=fixture_abiotic_constants,
constants=fixture_abiotic_simple_configuration.constants,
core_constants=fixture_core_constants,
bounds=fixture_abiotic_simple_configuration.bounds,
)
Expand Down
34 changes: 13 additions & 21 deletions virtual_ecosystem/models/abiotic/abiotic_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,7 @@ class as a child of the :class:`~virtual_ecosystem.core.base_model.BaseModel` cl
calculate_vapour_pressure_deficit,
run_simple_microclimate,
)
from virtual_ecosystem.models.abiotic_simple.model_config import (
AbioticSimpleBounds,
AbioticSimpleConfiguration,
AbioticSimpleConstants,
)
from virtual_ecosystem.models.abiotic_simple.model_config import AbioticSimpleBounds


class AbioticModel(
Expand Down Expand Up @@ -120,10 +116,9 @@ def __init__(

self.model_constants: AbioticConstants
"""Set of constants for the abiotic model."""
self.simple_constants: AbioticSimpleConstants
"""Set of constants for simple abiotic model."""
self.simple_bounds: AbioticSimpleBounds
"""Set of bound for simple abiotic model."""
self.bounds: AbioticSimpleBounds
"""A set of bounds on microclimates variables, used with both the simple model
of the initial state and the full energy balance calculations."""
self.pyrealm_constants: PyrealmConst
"""Pyrealm constants."""

Expand Down Expand Up @@ -152,8 +147,7 @@ def from_config(
"abiotic", AbioticConfiguration
)

# Hard coding these here until we figure out how to resolve config issues
abiotic_simple_configuration = AbioticSimpleConfiguration()
# Hard coding this until we figure out how to pass in.
pyrealm_consts = PyrealmConst()

LOGGER.info(
Expand All @@ -164,15 +158,15 @@ def from_config(
data=data,
core_components=core_components,
static=model_configuration.static,
model_constants=model_configuration.constants,
simple_config=abiotic_simple_configuration,
constants=model_configuration.constants,
bounds=model_configuration.bounds,
pyrealm_consts=pyrealm_consts,
)

def _setup(
self,
model_constants: AbioticConstants = AbioticConstants(),
simple_config: AbioticSimpleConfiguration = AbioticSimpleConfiguration(),
bounds: AbioticSimpleBounds = AbioticSimpleBounds(),
pyrealm_constants: PyrealmConst = PyrealmConst(),
**kwargs,
) -> None:
Expand All @@ -185,14 +179,13 @@ def _setup(

Args:
model_constants: Set of constants for the abiotic model.
simple_config: Configuration options for the abiotic simple model.
bounds: A set of bounds to be applied to abiotic variables.
pyrealm_constants: Additional configuration options to the pyrealm package.
**kwargs: Further arguments to the setup method.
"""

self.model_constants = model_constants
self.simple_constants = simple_config.constants
self.simple_bounds = simple_config.bounds
self.bounds = bounds
self.pyrealm_constants = pyrealm_constants

# create soil temperature array
Expand All @@ -219,10 +212,9 @@ def _setup(
data=self.data,
layer_structure=self.layer_structure,
time_index=0,
simple_constants=self.simple_constants,
abiotic_constants=self.model_constants,
constants=self.model_constants,
core_constants=self.core_constants,
bounds=self.simple_bounds,
bounds=self.bounds,
)

# Generate initial profiles of canopy temperature and heat fluxes from soil and
Expand Down Expand Up @@ -260,7 +252,7 @@ def _update(self, time_index: int, **kwargs: Any) -> None:
abiotic_constants=self.model_constants,
core_constants=self.core_constants,
pyrealm_const=self.pyrealm_constants,
abiotic_bounds=self.simple_bounds,
abiotic_bounds=self.bounds,
)

self.data.add_from_dict(output_dict=update_dict)
Expand Down
32 changes: 14 additions & 18 deletions virtual_ecosystem/models/abiotic/model_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,17 @@
simulation.
""" # noqa: D205

from virtual_ecosystem.core.configuration import Configuration, ModelConfigurationRoot
from virtual_ecosystem.core.configuration import ModelConfigurationRoot
from virtual_ecosystem.models.abiotic_simple.model_config import (
AbioticSharedConstants,
AbioticSimpleBounds,
AbioticSimpleConstants,
)


class AbioticConstants(Configuration):
class AbioticConstants(AbioticSharedConstants):
"""Dataclass to store all constants for the `abiotic` model."""

leaf_emissivity: float = 0.98
"""Leaf emissivity, unitless.

Leaf emissivity is a measure of how efficiently a leaf emits thermal radiation
compared to a perfect blackbody, typically ranging from 0.95 to 0.99. Value for
tropical vegetation is taken from :cite:t:`ma_an_2019`.
"""

leaf_albedo: float = 0.15
"""Leaf albedo, unitless.

Expand Down Expand Up @@ -142,14 +139,6 @@ class AbioticConstants(Configuration):
The value is takes from a study that compares changes in surface albedo before and
after deforestation in South East Asia :cite:p:`wilson_role_2020`."""

soil_emissivity: float = 0.95
"""Soil emissivity, dimensionless.

Soil emissivity is a measure of how efficiently the soil surface emits thermal
radiation compared to a perfect blackbody, with values typically ranging from 0.90
to 0.98 depending on soil texture, moisture, and surface roughness. Value taken
from :cite:t:`molders_plant_2005`."""

saturated_pressure_slope_parameters: tuple[float, float, float, float] = (
4098.0,
0.6108,
Expand All @@ -174,3 +163,10 @@ class AbioticConfiguration(ModelConfigurationRoot):

constants: AbioticConstants = AbioticConstants()
"""Constants for the abiotic model"""

bounds: AbioticSimpleBounds = AbioticSimpleBounds()
"""Bounds for abiotic variables."""

simple_constants: AbioticSimpleConstants = AbioticSimpleConstants()
"""Constants used for the simple abiotic model, used to set up initial
conditions."""
12 changes: 1 addition & 11 deletions virtual_ecosystem/models/abiotic_simple/abiotic_simple_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ class as a child of the :class:`~virtual_ecosystem.core.base_model.BaseModel` cl
from virtual_ecosystem.core.core_components import CoreComponents
from virtual_ecosystem.core.data import Data
from virtual_ecosystem.core.logger import LOGGER
from virtual_ecosystem.models.abiotic.model_config import AbioticConstants
from virtual_ecosystem.models.abiotic_simple.microclimate_simple import (
calculate_vapour_pressure_deficit,
run_simple_microclimate,
Expand Down Expand Up @@ -101,8 +100,6 @@ def __init__(
"""Set of constants for the abiotic simple model"""
self.bounds: AbioticSimpleBounds
"""Upper and lower bounds for abiotic variables."""
self.abiotic_constants: AbioticConstants
"""Abiotic constants required for some calculations"""

@classmethod
def from_config(
Expand Down Expand Up @@ -131,9 +128,6 @@ def from_config(
)
)

# Hard coding abiotic constants here until we resolve the config setup
abiotic_constants: AbioticConstants = AbioticConstants()

LOGGER.info(
"Information required to initialise the abiotic simple model successfully "
"extracted."
Expand All @@ -143,13 +137,11 @@ def from_config(
core_components=core_components,
static=model_configuration.static,
model_configuration=model_configuration,
abiotic_constants=abiotic_constants,
)

def _setup(
self,
model_configuration: AbioticSimpleConfiguration,
abiotic_constants: AbioticConstants,
**kwargs,
) -> None:
"""Function to set up the abiotic simple model.
Expand All @@ -166,7 +158,6 @@ def _setup(
# Populate model attributes
self.model_constants = model_configuration.constants
self.bounds = model_configuration.bounds
self.abiotic_constants = abiotic_constants

# create soil temperature array
self.data["soil_temperature"] = self.layer_structure.from_template()
Expand Down Expand Up @@ -207,8 +198,7 @@ def _update(self, time_index: int, **kwargs: Any) -> None:
data=self.data,
layer_structure=self.layer_structure,
time_index=time_index,
simple_constants=self.model_constants,
abiotic_constants=self.abiotic_constants,
constants=self.model_constants,
core_constants=self.core_constants,
bounds=self.bounds,
)
Expand Down
10 changes: 4 additions & 6 deletions virtual_ecosystem/models/abiotic_simple/microclimate_simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ def run_simple_microclimate(
data: Data,
layer_structure: LayerStructure,
time_index: int, # could be datetime?
simple_constants: AbioticSimpleConstants,
abiotic_constants: AbioticConstants,
constants: AbioticSimpleConstants | AbioticConstants,
core_constants: CoreConstants,
bounds: AbioticSimpleBounds,
) -> dict[str, DataArray]:
Expand Down Expand Up @@ -88,8 +87,7 @@ def run_simple_microclimate(
data: Data object
layer_structure: The LayerStructure instance for the simulation.
time_index: Time index, integer
simple_constants: Set of constants for the abiotic simple model
abiotic_constants: Set of constants for the abiotic model
constants: Set of constants for the abiotic simple model
core_constants: Set of constants shared across all models
bounds: Upper and lower allowed values for vertical profiles, used to constrain
log interpolation. Note that currently no conservation of water and energy!
Expand Down Expand Up @@ -160,14 +158,14 @@ def run_simple_microclimate(
# Calculate net radiation, [W m-2].
canopy_longwave_emission = energy_balance.calculate_longwave_emission(
temperature=canopy_temperature.to_numpy(),
emissivity=abiotic_constants.leaf_emissivity,
emissivity=constants.leaf_emissivity,
stefan_boltzmann=core_constants.stefan_boltzmann_constant,
)
soil_longwave_emission = energy_balance.calculate_longwave_emission(
temperature=output["soil_temperature"][
layer_structure.index_topsoil_scalar
].to_numpy(),
emissivity=abiotic_constants.soil_emissivity,
emissivity=constants.soil_emissivity,
stefan_boltzmann=core_constants.stefan_boltzmann_constant,
)

Expand Down
33 changes: 25 additions & 8 deletions virtual_ecosystem/models/abiotic_simple/model_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,32 @@
from virtual_ecosystem.core.configuration import Configuration, ModelConfigurationRoot


class AbioticSimpleConstants(Configuration):
"""Dataclass to store all constants for the `abiotic_simple` model."""
class AbioticSharedConstants(Configuration):
"""Shared abiotic constants.

This is a pydantic basemodel to hold constants shared between the `abiotic` and
`abiotic_simple` models.
"""

leaf_emissivity: float = 0.98
"""Leaf emissivity, unitless.

Leaf emissivity is a measure of how efficiently a leaf emits thermal radiation
compared to a perfect blackbody, typically ranging from 0.95 to 0.99. Value for
tropical vegetation is taken from :cite:t:`ma_an_2019`.
"""

soil_emissivity: float = 0.95
"""Soil emissivity, dimensionless.

Soil emissivity is a measure of how efficiently the soil surface emits thermal
radiation compared to a perfect blackbody, with values typically ranging from 0.90
to 0.98 depending on soil texture, moisture, and surface roughness. Value taken
from :cite:t:`molders_plant_2005`."""

saturation_vapour_pressure_factors: tuple[float, float, float] = (
0.61078,
7.5,
237.3,
)
"""Factors for saturation vapour pressure calculation."""

class AbioticSimpleConstants(AbioticSharedConstants):
"""Dataclass to store all constants for the `abiotic_simple` model."""

initial_net_radiation: float = 10.0
"""Initial value for net radiation per layer, W m-2.
Expand Down