RUFAS.routines.field.field.field module#

class RUFAS.routines.field.field.field.Field(field_data: FieldData | None = None, soil: Soil | None = None, plantings: List[PlantingEvent] | None = None, harvestings: List[HarvestEvent] | None = None, tillage_events: List[TillageEvent] | None = None, fertilizer_events: List[FertilizerEvent] | None = None, fertilizer_mixes: Dict[str, Dict[str, float]] | None = None, manure_events: List[ManureEvent] | None = None)#

Bases: object

This is a high-level class that represents and simulates an entire field. It is responsible for executing the daily biophysical routines which take place in soil columns and in crops planted in the field. It is also responsible for the management of schedules, executing, and reporting of farm management events, including planting and harvesting crops, adding manure and fertilizer to the soil, and tilling the soil.

Parameters#

field_dataFieldData, default=None

FieldData object that will be simulated.

soilSoil, default=None

The soil component of the field.

plantingsList[PlantingEvent], default=None

List of all planting events that will occur over the run of the simulation in this field.

harvestingsList[HarvestEvent], default=None

List of all harvesting events that will occur over the run of the simulation in the field.

custom_crop_specificationsdict[str, dict[str, Any]], default=None

Dictionary where keys are crop references and values are dictionaries containing crop specifications.

tillage_eventsList[TillageEvent], default=None

List of all tillage events that will occur over the run of the simulation in this field.

fertilizer_eventsList[FertilizerEvent], default=None

List of all fertilizer mixes available for application to this field.

fertilizer_mixesDict[str, Dict[str, float]], default=None

List of all fertilizer mixes available for application to this field.

manure_eventsList[ManureEvent], default=None

Manure application interface.

Attributes#

field_dataFieldData

Reference to the FieldData object

soilSoil

Reference to the Soil object

cropsList[Crop]

Reference to the list of Crop objects

planting_eventsList[PlantingEvent]

Reference to the list of PlantingEvent objects

harvest_eventsList[HarvestEvent]

Reference to the list of HarvestEvent objects

custom_crop_specificationsdict[str, dict[str, Any]]

Reference to the custom crop specifications dictionary.

fertilizer_applicatorFertilizerApplication(self.soil)

Provides interface for adding fertilizer to the field

fertilizer_eventsList

Reference to the list of FertilizerEvent objects

available_fertilizer_mixesDict

List of all fertilizer mixes available for application to this field. The 100_0_0 and 26_4_24 mixes will always be available as supplements to unfulfilled manure nutrient demands.

ONLY_NITROGEN_MIXstr

Constant with the name of the fertilizer mix that contains only Nitrogen.

tillerTillageApplication

Provides interface to till the field.

tillage_events: List[TillageEvent]

List of all tillage events that will occur over the run of the simulation in this field.

manure_applicator = ManureApplication

List of ManureApplication objects.

manure_events: List[ManureEvent]

List of all manure applications that will be applied to this field.

Methods#

manage_field(time, current_conditions: CurrentDayConditions) -> list[HarvestedCropStorageType]:

Main Field routine, runs all subroutines routines based on current attribute configuration.

__init__(field_data: FieldData | None = None, soil: Soil | None = None, plantings: List[PlantingEvent] | None = None, harvestings: List[HarvestEvent] | None = None, tillage_events: List[TillageEvent] | None = None, fertilizer_events: List[FertilizerEvent] | None = None, fertilizer_mixes: Dict[str, Dict[str, float]] | None = None, manure_events: List[ManureEvent] | None = None) None#
manage_field(time: RufasTime, current_conditions: CurrentDayConditions, manure_applications: list[ManureEventNutrientRequestResults]) list[HarvestedCropStorageType]#

Main Field routine, runs all subroutines routines based on current attribute configuration.

Parameters#

timeRufasTime

Contains the current year and day that the simulation is on.

current_conditionsCurrentDayConditions

Contains a collection of today’s conditions variables needed for field processes.

manure_applicationslist[ManureEventNutrientRequestResults]

List of manure events and the results of the nutrient requests for each event.

Returns#

list[HarvestedCropStorageType]

List of crops that have been harvested from the field and storage types they will go into.

Notes#

This method starts by executing any soil amendments that may be scheduled for the day. Then it executes the daily update routines for the soil profile and active crops in the field. It then plants and/or harvests crops, checks if active crops need to go into dormancy, and resets crop attributes in both the crops and in the field’s data object.

_execute_fertilizer_application(mix_name: str, requested_nitrogen: float, requested_phosphorus: float, requested_potassium: float, application_depth: float, surface_remainder_fraction: float, year: int, day: int) None#

Executes a fertilizer application based on the requested amounts of nutrients.

Parameters#

mix_namestr

The name of the mix this fertilizer application should be composed of.

requested_nitrogenfloat

Minimum amount of nitrogen to be included in this fertilizer application (kg).

requested_phosphorusfloat

Minimum amount of phosphorus to be included in this fertilizer application (kg).

requested_potassiumfloat

Minimum amount of potassium to be included in this fertilizer application (kg).

application_depthfloat

Depth at which fertilizer is injected into the soil (mm).

surface_remainder_fractionfloat

Fraction of fertilizer applied that remains on the soil surface after application (unitless).

yearint

Calendar year in which the fertilizer application is occurring.

dayint

Julian day on which this fertilizer application is occurring.

Raises#

KeyError

If the specified fertilizer mix is not defined in the list of available fertilizers to this field.

Notes#

This method is responsible for determining the exact amounts of fertilizer and nutrients added to the field, passing those amount to the FertilizerApplication module, and recording the fertilizer application to the OutputManager. Because potassium requests are still not accounted for when determining the amount of fertilizer applied, the method checks that there is at least some nitrogen or phosphorus requested, if not it returns without applying any fertilizer.

static _determine_optimal_fertilizer_mix(requested_nitrogen: float, requested_phosphorus: float, available_mixes: Dict[str, Dict[str, float]]) str#

Takes the requested nutrients of a fertilizer application and determines which fertilizer mix would fill them the most efficiently.

Parameters#

requested_nitrogenfloat

Minimum amount of nitrogen to be included in this fertilizer application.

requested_phosphorusfloat

Minimum amount of phosphorus to be included in this fertilizer application.

available_mixesDict[str, Dict[str, float]]

List of fertilizer mixes available for application to the field.

Returns#

str

Name of the fertilizer mix which requires the least mass of fertilizer to fill the nutrient requests.

Notes#

The optimal fertilizer mix is currently the one that requires the least amount of fertilizer to meet the demanded nutrients, but a more realistic definition of “optimal” may mean the mix that costs the least to fill the requested nutrients with.

static _formulate_fertilizer_required(nitrogen_fraction: float, phosphorus_fraction: float, potassium_fraction: float, requested_nitrogen: float, requested_phosphorus: float, requested_potassium: float) Dict[str, float]#

Determines the total mass of a specific fertilizer mix needed to meet the specified nutrient requirements.

Parameters#

nitrogen_fractionfloat

Fraction of fertilizer mix that is nitrogen, in range [0.0, 1.0] (unitless)

phosphorus_fractionfloat

Fraction of fertilizer mix that is phosphorus, in range [0.0, 1.0] (unitless)

potassium_fractionfloat

Fraction of fertilizer mix that is potassium, in range [0.0, 1.0] (unitless)

requested_nitrogenfloat

Minimum mass of nitrogen to be included in fertilizer application (kg)

requested_phosphorusfloat

Minimum mass of phosphorus to be included in fertilizer application (kg)

requested_potassiumfloat

Minimum mass of potassium to be included in fertilizer application (kg)

Returns#

Dict[str, float]

The total mass of fertilizer, and the masses of nitrogen, phosphorus, and potassium in the fertilizer.

_record_fertilizer_application(mix_name: str, total_mass: float, nitrogen_mass: float, phosphorus_mass: float, potassium_mass: float, ammonium_fraction: float, application_depth: float, surface_remainder_fraction: float, year: int, day: int) None#

Records a fertilizer application and saves it to the Output manager.

Parameters#

mix_namestr

The name of the mix this fertilizer application is composed of.

total_massfloat

The total mass of phosphorus applied (kg).

nitrogen_massfloat

The mass of nitrogen applied (kg).

phosphorus_massfloat

The mass of phosphorus applied (kg).

potassium_massfloat

The mass of potassium applied (kg).

ammonium_fractionfloat

Fraction of requested nitrogen which is ammonium and not nitrate (unitless).

application_depthfloat

Depth at which fertilizer is injected into the soil (mm).

surface_remainder_fractionfloat

Fraction of fertilizer applied that remains on the soil surface after application (unitless).

yearint

Calendar year in which the fertilizer application is occurring.

dayint

Julian day on which this fertilizer application is occurring.

_execute_manure_application(requested_nitrogen: float, requested_phosphorus: float, requested_manure_type: ManureType, field_coverage: float, application_depth: float, surface_remainder_fraction: float, year: int, day: int, manure_supplied: NutrientRequestResults | None, manure_supplement_method: ManureSupplementMethod) None#

Executes a manure application based on the requested amounts of nutrients.

Parameters#

requested_nitrogenfloat

Minimum amount of nitrogen to be included in this manure application (kg).

requested_phosphorusfloat

Minimum amount of phosphorus to be included in this manure application (kg).

requested_manure_typeManureType

Enum option indicating the type of manure applied.

field_coveragefloat

Fraction of the field this manure is applied to (unitless).

application_depthfloat

Depth at which fertilizer is injected into the soil (mm).

surface_remainder_fractionfloat

Fraction of fertilizer applied that remains on the soil surface after application (unitless).

yearint

Calendar year in which this manure application occurs.

dayint

Julian day on which this manure application occurs.

manure_suppliedNutrientRequestResults | None

An object containing the information that defines a manure application.

manure_supplement_methodManureSupplementMethod

Enum option indicating how to supplement the manure application.

_apply_and_record_manure_application(manure_supplied: NutrientRequestResults, manure_type: ManureType, field_coverage: float, application_depth: float, surface_remainder_fraction: float, year: int, day: int) dict[str, float]#

Applies the manure and records the application.

Parameters#

manure_suppliedNutrientRequestResults

An object containing the information that defines a manure application.

manure_typeManureType

Enum option indicating the type of manure applied.

field_coveragefloat

Fraction of the field this manure is applied to (unitless).

application_depthfloat

Depth at which fertilizer is injected into the soil (mm).

surface_remainder_fractionfloat

Fraction of fertilizer applied that remains on the soil surface after application (unitless).

yearint

Calendar year in which this manure application occurs.

dayint

Julian day on which this manure application occurs.

Returns#

tuple[float, float, float, float]

The supplied nitrogen and phosphorus amounts, application depth, and surface remainder fraction.

_validate_application_depth_and_fraction(application_depth: float, surface_remainder_fraction: float, year: int, day: int) tuple[float, float]#

Validates the application depth and surface remainder fraction for a manure application.

Parameters#

application_depthfloat

Depth at which fertilizer is injected into the soil (mm).

surface_remainder_fractionfloat

Fraction of fertilizer applied that remains on the soil surface after application (unitless).

yearint

Calendar year in which this manure application occurs.

dayint

Julian day on which this manure application occurs.

Returns#

tuple[float, float]

The validated application depth and surface remainder fraction.

Raises#

ValueError

If the soil layers are not initialized or if the bottom depth is not set for the last soil layer.

_handle_unmet_nutrients(requested_nitrogen: float, requested_phosphorus: float, supplied_nitrogen: float, supplied_phosphorus: float, application_depth: float, surface_remainder_fraction: float, method: ManureSupplementMethod, year: int, day: int) None#

Handles the situation where the manure application does not meet the requested nutrient requirements.

Parameters#

requested_nitrogenfloat

Minimum amount of nitrogen to be included in this manure application (kg).

requested_phosphorusfloat

Minimum amount of phosphorus to be included in this manure application (kg).

supplied_nitrogenfloat

Amount of nitrogen supplied by the manure application (kg).

supplied_phosphorusfloat

Amount of phosphorus supplied by the manure application (kg).

application_depthfloat

Depth at which fertilizer is injected into the soil (mm).

surface_remainder_fractionfloat

Fraction of fertilizer applied that remains on the soil surface after application (unitless).

methodManureSupplementMethod

Enum option indicating how to supplement the manure application.

yearint

Calendar year in which this manure application occurs.

dayint

Julian day on which this manure application occurs.

_record_manure_application(dry_matter_mass: float, dry_matter_fraction: float, field_coverage: float, nitrogen: float, phosphorus: float, application_depth: float, surface_remainder_fraction: float, year: int, day: int, output_name: str, potassium: float | None = None) None#

Records the amount of manure and related values for an individual manure application.

Parameters#

dry_matter_massfloat

Dry weight equivalent of this application (kg)

dry_matter_fractionfloat

Fraction of this manure application that is dry matter, in the range (0.0, 1.0] (unitless)

field_coveragefloat

Fraction of the field this manure is applied to (unitless)

nitrogenfloat

Mass of nitrogen in the manure applied (kg)

phosphorusfloat

Mass of phosphorus in the manure applied (kg)

application_depthfloat

Depth at which fertilizer is injected into the soil (mm).

surface_remainder_fractionfloat

Fraction of fertilizer applied that remains on the soil surface after application (unitless).

yearint

Calendar year in which this manure application occurs.

dayint

Julian day on which this manure application occurs.

potassiumfloat, Optional

Mass of potassium in the manure applied (kg)

_add_manure_water(manure_application: NutrientRequestResults, manure_type: ManureType) None#

Records the water from a manure application so it can be added to the soil.

Parameters#

manure_applicationNutrientRequestResults

An object containing the infomation that defines a manure application.

manure_typeManureType

Enum option indicating if the manure applied was solid or liquid.

Notes#

This method only records manure water to be applied to a field if it comes from an application of liquid manure. When extracting the amount of water applied in the manure application, the conversion from kilograms of water to liters of water is implicit.

_record_nutrient_application_error(application_depth: float, surface_remainder_fraction: float | None, error_name: str, year: int, day: int) None#

Logs errors to the OutputManager when attempting injection applications of manure or fertilizer.

Parameters#

application_depthfloat

Depth of the manure or fertilizer application (mm).

surface_remainder_fractionOptional[float]

Fraction of manure or fertilizer applied that remains on the soil surface after application (unitless).

error_namestr

Name of the error, indicating whether it occurred during manure or fertilizer application.

Notes#

There are two possible errors that this method can log. One is an invalid combination of application depth and surface remainder fraction, the other is an application depth deeper than the bottom of the soil profile. The two are differentiated by what is passed for surface_remainder_fraction. If it is a number, it is the former, and if None, then it is the latter.

_check_crop_planting_schedule(time: RufasTime) None#

Checks the list of PlantingEvents, and all that are scheduled to happen are passed on to another method to be executed.

Parameters#

timeRufasTime

RufasTime object containing the current day and year of the simulation.

_check_fertilizer_application_schedule(time: RufasTime) None#

Checks list of FertilizerEvents, and removes all that occur on the current day from the list.

Parameters#

timeRufasTime

RufasTime object containing the current year and day of the simulation.

_check_tillage_schedule(time: RufasTime) None#

Checks the list of Events, and all that are scheduled to happen are passed on to another method to be executed.

Parameters#

timeRufasTime

RufasTime object containing the current day and year of the simulation.

check_manure_application_schedule(time: RufasTime) list[ManureEventNutrientRequest]#

Checks list of ManureEvents, sends all that occur today to another method to be executed.

Parameters#

timeRufasTime

RufasTime containing the current year and day of the simulation.

Returns#

list[ManureEventNutrientRequest]

A list of the ManureEvents with their corresponding NutrientRequests that are scheduled to occur on the current day.

_create_manure_request(event: ManureEvent) NutrientRequest | None#

Creates a NutrientRequest object from the attributes of a ManureEvent.

Parameters#

eventManureEvent

ManureEvent object containing the attributes needed to create a NutrientRequest.

Returns#

NutrientRequest | None

Object containing the nutrient requests of the manure event or None if no nitrogen or phosphorus is requested.

_check_crop_harvest_schedule(time: RufasTime, current_conditions: CurrentDayConditions) list[HarvestedCropStorageType]#

Checks for all crops for potential harvests that may happen on the current day.

Parameters#

timeRufasTime

RufasTime object containing the current day and year of the simulation.

current_conditionsCurrentDayConditions

CurrentDayConditions object containing the current weather conditions of the simulated day.

Returns#

list[HarvestedCropStorageType]

Harvested crops and the storages where they will be placed.

Notes#

This method checks for scheduled harvests, i.e. checks all the remaining HarvestEvents. It calls the method that checks if crops should be harvested based on their heat fraction.

_harvest_heat_scheduled_crops(rainfall: float, time: RufasTime) list[HarvestedCropStorageType]#

Checks if any of the active plants in the field are harvested based on their heat schedule, and if so harvests them if they meet the heat threshold.

Parameters#

rainfallfloat

Amount of rainfall on the current day (mm).

timeRufasTime

RufasTime object containing the current day and year of the simulation.

Returns#

list[HarvestedCropStorageType]

Harvested crops and the storage types that they will be placed in.

References#

SWAT Theoretical documentation section 5:1.1.1 (Heat Scheduling)

static _filter_events(all_events: Sequence[BaseFieldManagementEvent], time: RufasTime) tuple[Sequence[BaseFieldManagementEvent], Sequence[BaseFieldManagementEvent]]#

Filters out all events from a list that occur on the current day, and creates a new list with all the events that were filtered out.

Parameters#

all_eventsList[BaseFieldManagementEvent]

List of all Events that will occur over the run of the simulation in this field.

timeRufasTime

RufasTime object containing the current day and year of the simulation.

Returns#

Tuple

A tuple containing the list of all Events that will occur in this field after the current day, and a list of Events that will occur on the current day.

Notes#

This method is written to work with generic Events so that it may be used on all the different child classes of Event: PlantingEvent, HarvestEvent, ManureEvent, FertilizerEvent, and TillageEvent.

_plant_crop(crop_reference: str, use_heat_scheduled_harvesting: bool, time: RufasTime) None#

Plants a crop in the field by creating a new Crop instance and adding it to the field’s list of current crops.

Parameters#

crop_referencestr

Name used to get the specifications for the crop to be planted.

use_heat_scheduled_harvestingbool

Indicates if this crop should be harvested based on the fraction of potential heat units it has accumulated.

timeRufasTime

RufasTime object containing the current year and day of the simulation.

Notes#

The crop reference may contain a reference to a supported crop that already has attributes defined for it, or a reference to a custom crop that has user-defined attributes. The harvest method is overwritten for the crop created because that is specified directly by the user, and the crop id is set so that the HarvestEvents will be able to identify the correct crop in the field’s list of active crops.

_record_planting(heat_scheduled_harvest: bool, crop_configuration: str, year: int, day: int) None#

Records a planting event to the OutputManager.

Parameters#

heat_scheduled_harvestbool

Indicates if this crop should be harvested based on the fraction of potential heat units it has accumulated.

crop_configurationstr

Name of the crop configuration being planted.

yearint

Year in which this crop planting occurs.

dayint

Julian day on which this crop planting occurs.

_harvest_crop(crop_reference: str, harvest_operation: HarvestOperation, time: RufasTime, current_conditions: CurrentDayConditions) list[HarvestedCropStorageType]#

Performs the specified crop operation on the specified crop.

Parameters#

crop_referencestr

Name used to get the specifications for the crop to be harvested.

harvest_operationHarvestOperation

Harvest operation to be performed on the referenced crop.

timeRufasTime

RufasTime object containing the current day and year of the simulation.

current_conditionsCurrentDayConditions

Object containing the conditions of the current simulated day.

Returns#

list[HarvestedCropStorageType]

Harvested crops and the storages into which they will be placed.

Notes#

This method raises two different warnings, one if multiple active crops share the same id, and one if no active crop is found with an id that matches the given crop reference. These are both raised as warnings and not errors (which would stop the simulation run) because they could both plausibly happen in a simulation run. The first scenario could happen if someone were to specify multiple plantings of the same crop in the same year and schedule them to be harvested together, and the second could happen if there was a catastrophic weather event that killed off a crop before it could be harvested.

_remove_dead_crops() None#

This method removes any crops from the field’s list of active crops if they are no longer alive.

_reset_crop_field_coverage_fractions() None#

Resets crops to have equal field coverage while in the field.

_assess_dormancy(daylength: float | None, rainfall: float) None#

Transition all crops to dormancy if they are capable of going dormant.

Parameters#

daylengthfloat

Length of time from sunup to sundown on the current day (hours).

rainfallfloat

Amount of rain that fell on the current day (mm).

_execute_daily_processes(current_conditions: CurrentDayConditions, time: RufasTime) None#

Executes all daily updates on this field’s soil and crop objects.

Parameters#

current_conditionsCurrentDayConditions

Object containing the environment conditions on this day.

timeRufasTime

RufasTime object containing the current year and day of the simulation.

Notes#

This method is designed to make it easier to change the order of process execution, which is desirable because it will allow subject-matter experts to more easily experiment with different orders.

_cycle_water(current_conditions: CurrentDayConditions, time: RufasTime) None#

Allow water to cycle through the field.

Parameters#

current_conditionsCurrentDayConditions

A CurrentDayConditions object containing a collection of today’s weather variables needed for field processes.

timeRufasTime

A RufasTime object containing the current year and day of the simulation.

Notes#

This method executes all water-related processes that occur within Crop and Soil objects. Having a separate method to handle water processes altogether is necessary because processes that affect water in the soil are dependent on processes that affect water in crops and vice versa. The most complex process that is executed in this method is evapotranspiration, which is executed in the following order:

  • Evaporation of water in canopies of crops.

  • Sublimation of water in the snowpack (not implemented in V1).

  • Evaporation from the soil profile.

  • Transpiration from crops (the amount of water taken up by plants is equal to the amount they transpirate, and this amount depends on the evapotranspirative demand after water has been removed from canopies).

It should also be noted that while this method is more messy and complex than it could be, this is a conscious design choice that will allow for SMEs to more easily and freely experiment with different orders of processes. This is necessary because there is not necessarily one correct order for processes to run in.

_determine_watering_amount(rainfall: float, manure_water: float, year: int, day: int, irrigation: float) float#

Manages watering of the field.

Parameters#

rainfallfloat

Amount of rainfall that occurs on this day (mm).

manure_waterfloat

Amount of water added to the field via manure application (mm).

yearint

Year in which this watering occurs.

dayint

Julian day on which this watering occurs.

irrigationfloat

The amount of hard-coded irrigation in the weather data (mm).

Returns#

float

Amount of water used to irrigate the field on this day (mm).

Notes#

This method drives the engine of irrigation for RuFaS. It tracks how much water has been added to the field by rainfall over a user-defined interval, and when at the end of the interval it determines how much water still needs to be added to the field based on how much watering has to occur over said interval (also defined by the user). The counter that tracks how where in the interval the simulation is and the amount of water that still needs to be applied are reset at the end of every interval. The water that is added to the field from the farm’s resources is tracked on an annual basis, so that water budgeting may be accurately predicted.

Old method of using hard-coded irrigation data will be used if there’s no user specified data. If there’s any user-specified data provided, the hard-coded irrigation will be ignored and only uses the new method.

_get_manure_water() float#

Grabs water from a manure application and records it, if any.

Returns#

float

Amount of water applied to the field via manure on the current day (mm).

_handle_water_in_crop_canopies(precipitation_total: float) float#

Adds water to canopies of all the crops in the field and removes any excess water from them.

Parameters#

precipitation_totalfloat

Total amount of precipitation that fell on the field today (mm)

Returns#

float

Amount of water that reaches the soil surface (mm)

Notes#

This method accounts for the edge case that no water was lost from the crop canopy yesterday and the capacity in the canopy went down overnight, so water is lost from the canopy to the ground before any evapotranspiration can happen. A caveat is that if there is excess water in the canopy of one crop, it cannot be transferred to the canopy of another.

_evaporate_from_crop_canopies(evapotranspirative_demand: float) float#

Evaporates water from crops’ canopies and reduces evapotranspirative demand accordingly.

Parameters#

evapotranspirative_demandfloat

Evapotranspirative demand on the field on the current day (mm)

Returns#

float

Evapotranspirative demand after evaporating water from crops’ canopies (mm)

_determine_total_above_ground_biomass() float#

Calculate the total amount of above-ground biomass still on the plant(s) in the field (kg / ha)

static _determine_potential_evapotranspiration(extraterrestrial_radiation: float, max_air_temp: float, min_air_temp: float, avg_air_temp: float) float#

Calculates the potential evapotranspiration for a given day.

Parameters#

extraterrestrial_radiationfloat

Radiation from sunlight (MJ per square meter per day).

max_air_tempfloat

Maximum air temperature (degrees C).

min_air_tempfloat

Minimum air temperature (degrees C).

avg_air_tempfloat

Average air temperature (degrees C).

Returns#

float

Potential evapotranspiration (mm).

References#

SWAT Reference: 2:2.2.24

Notes#

This method calculates the evapotranspirative demand for the entire field on any given day using the Hargreaves method. This method lower-bounds the potential evapotranspiration at 0.0 mm.

If the average temperature for the day is not specified, then the average temperature for the day is calculated as the average of the maximum and minimum temperatures of the day.

static _determine_latent_heat_vaporization(avg_air_temp: float) float#

Determine latent heat of vaporization for a given day.

Parameters#

avg_air_tempfloat

Average air temperature (degrees C)

Returns#

float

latent heat of vaporization (MJ per kg)

References#

SWAT Reference: 1:2.3.6

static _determine_soil_evaporation_and_sublimation_adjusted(above_ground_biomass: float, residue: float, snow_water_content: float, potential_evapotranspiration_adjusted: float, transpiration: float) float#

Calculate the amount of sublimation and soil evaporation for this day, adjusted for plant use.

Parameters#

above_ground_biomassfloat

Mass of plant above ground (kg per hectare)

residuefloat

Biomass separated from plant on the ground (kg per hectare)

snow_water_contentfloat

Amount of water in the snow pack (mm)

potential_evapotranspiration_adjustedfloat

Potential evapotranspiration adjusted for evaporation of free water in canopy (mm)

transpirationfloat

Maximum transpiration for a given day (mm)

Returns#

float

Soil evaporation and sublimation, adjusted for plant water use (mm)

References#

SWAT Theoretical documentation eqn. 2:2.3.7, 9

Notes#

If both the adjusted potential evapotranspiration and transpiration are 0, then it is assumed that all evapotranspirative demands have been met for the current day and no sublimation or evaporation from the soil will occur.

static _determine_maximum_soil_evaporation(soil_evaporation_adj: float, snow_water_content: float) float#

Calculates the maximum amount of evaporation from soil in a given day.

Parameters#

soil_evaporation_adjfloat

Maximum soil evaporation adjusted for plant water use on a given day (mm).

snow_water_contentfloat

Amount of water in the snow pack on a given day prior to accounting for sublimation (mm).

Returns#

float

Maximum soil water evaporation on a given day (mm).

References#

SWAT Theoretical documentation 2:2.3.3.1

static _determine_soil_cover_index(above_ground_biomass: float, residue: float, snow_water_content: float) float#

Calculate the soil cover index.

Parameters#

above_ground_biomassfloat

Mass of plant above ground (kg per hectare).

residuefloat

Biomass separated from plant on the ground (kg per hectare).

snow_water_contentfloat

Amount of water from snow (mm).

Returns#

Float

Soil cover index (unitless).

References#

SWAT Theoretical documentation eqn. 2:2.3.8

perform_annual_reset() None#

Collect all annual accumulated totals from Field, Crop, and Soil modules, write them to some sort of output file, and then reset all annual totals

_record_field_watering(year: int, day: int, watering_amount: float) None#

Record the day, year and amount of irrigation

Parameters#

yearint

Year in which this watering occurs.

dayint

Julian day on which this watering occurs.

watering_amountfloat

The amount of hard-coded irrigation in the weather data (mm)

Returns#

None