Modeling Conservation Agriculture
CropForge v0.7.0 introduces Topographical Physics, enabling the simulation of land preparation effects on water dynamics, soil erosion, and plant growth in a true 3D spatial context.
This tutorial walks through the conservation_ag_trial.py example script, demonstrating how to set up a comparison between Conventional Tillage and Conservation Agriculture (Contour Bunding) on a sloped terrain.
The Goal
We want to quantitatively demonstrate how contour bunds (a conservation agriculture technique) reduce soil erosion compared to conventional tillage on an undulating, sloped field under heavy rainfall.
Step 1: Terrain Generation
First, we generate a procedural undulating terrain. This provides the slope necessary to drive runoff and erosion.
from cropforge.terrain import Terrain
# The terrain has a built-in slope/undulation to drive runoff and erosion
terrain = Terrain.procedural(generator="undulating", rows=30, cols=30, resolution_m=1.0)
Step 2: Weather Setup
We simulate 60 days with frequent heavy rainfall events to stress test the erosion mechanics.
import pandas as pd
from cropforge.loaders import Weather
weather_df = pd.DataFrame({
"day": range(1, 61),
"doy": range(150, 210),
"temp_max_c": 32.0,
"temp_min_c": 22.0,
"temp_mean_c": 27.0,
"radiation_mj_m2": 20.0,
# Heavy rain every 5 days
"rainfall_mm": [30.0 if i % 5 == 0 else 2.0 for i in range(1, 61)],
"et0_mm": 5.0,
"wind_speed_ms": 3.5,
"humidity_pct": 75.0,
"co2_ppm": 415.0
})
weather = Weather(weather_df.set_index("day"))
Step 3: Setting Up the Fields
We create two fields side-by-side using the identical terrain and weather, but differing LandPrep configurations.
Field A: Conventional Tillage
Conventional tillage starts with a high surface roughness, but it decays quickly under heavy rain. It offers no physical barriers to lateral flow.
from cropforge.farm import Field
from cropforge.land_prep import ConventionalTill
field_a = Field(name="Conventional Till", rows=30, cols=30)
field_a.set_terrain(terrain)
field_a.set_weather(weather)
field_a.set_crop(maize)
field_a.set_land_prep(ConventionalTill())
farm.add_field(field_a)
Field B: Contour Bunds
Contour bunds are physical barriers placed along the contour lines of the slope. They trap water, reducing runoff velocity and minimizing erosion.
from cropforge.land_prep import ContourBund
field_b = Field(name="Contour Bunds", rows=30, cols=30)
field_b.set_terrain(terrain)
field_b.set_weather(weather)
field_b.set_crop(maize)
# Bunds trap water, reducing runoff velocity and erosion
field_b.set_land_prep(ContourBund(bund_height_m=0.3, interval_m=1.0))
farm.add_field(field_b)
Step 4: Enabling Topographical Physics
To activate the 3D physics engines, we must explicitly enable them before running the simulation.
farm.use_physics(
et0=True,
water_balance=True, # Required for runoff
lateral_flow=True, # D8 runoff routing
clod_dynamics=True, # Rain melts the clods over time
erosion=True, # RUSLE-based erosion index
slope_radiation_correction=True, # Solar incidence adjusted by slope/aspect
terrain_wind=True, # Topographical wind field
root_clamping=True, # Topographical root constraints
wind_direction_deg=270.0 # Wind coming from the West
)
Step 5: Run and Visualize
Run the simulation:
Then, launch the CropForge Dashboard:
Open your browser to http://localhost:8050.
1. Select "Field: Conventional Till".
2. Scrub to Day 60.
3. Click "Open 3D Terrain View".
4. In the Surface Overlay Variable dropdown, select Cumulative Erosion Index.
5. Observe the high erosion channels forming on the steep sections of the terrain.
6. Switch to "Field: Contour Bunds" and observe how the bunds physically block the flow paths, significantly lowering the overall erosion index.