Skill v1.0.0
currentAutomated scan100/100version: "1.0.0" name: landlab description: | Landscape evolution and surface process modelling in Python. Build 2D numerical models for erosion, hydrology, soil transport, and geomorphology. Use when the agent needs to: (1) Model landscape evolution over time, (2) Simulate river/stream erosion, (3) Route water flow across terrain, (4) Model hillslope diffusion processes, (5) Simulate weathering and soil production, (6) Analyze drainage networks, (7) Combine multiple geomorphic processes, (8) Load/save DEM data for modeling. license: MIT metadata: version: 1.0.1 author: Geoscience Skills tags: '["Landscape Evolution", "Geomorphology", "Erosion", "Surface Processes", "Flow Routing"]' dependencies: '["landlab>=2.6.0", "numpy", "matplotlib"]' complements: '["pyvista"]' workflow_role: analysis skill_type: domain
Landlab - Surface Process Modelling
Quick Reference
from landlab import RasterModelGridfrom landlab.components import FlowAccumulator, StreamPowerEroderimport numpy as np# Create gridgrid = RasterModelGrid((100, 100), xy_spacing=10.0)z = grid.add_zeros('topographic__elevation', at='node')z += np.random.rand(grid.number_of_nodes) * 0.1# Set boundaries (open bottom edge)grid.set_closed_boundaries_at_grid_edges(True, True, True, False)# Create and run componentsfa = FlowAccumulator(grid, flow_director='D8')sp = StreamPowerEroder(grid, K_sp=1e-5)for _ in range(100):fa.run_one_step()sp.run_one_step(dt=1000)z[grid.core_nodes] += 0.001 * 1000 # Upliftgrid.imshow('topographic__elevation', cmap='terrain')
Grid Types
| Grid | Use Case | |
|---|---|---|
RasterModelGrid | Regular rectangular grids (most common) | |
HexModelGrid | Hexagonal grids (isotropic flow) | |
VoronoiDelaunayGrid | Irregular point distributions | |
NetworkModelGrid | Channel networks only |
Key Concepts
Fields and Boundaries
# Fields: data stored at grid elements (nodes, links, cells)z = grid.add_zeros('topographic__elevation', at='node')grid.at_node['drainage_area'] # Access existing field# Boundaries: close all edges except outletgrid.set_closed_boundaries_at_grid_edges(True, True, True, False)z[grid.core_nodes] += uplift * dt # Core nodes exclude boundaries
Essential Operations
Flow Routing
from landlab.components import FlowAccumulatorfa = FlowAccumulator(grid, flow_director='D8') # or 'Steepest', 'MFD'fa.run_one_step()drainage_area = grid.at_node['drainage_area']
Stream Power Erosion
from landlab.components import StreamPowerErodersp = StreamPowerEroder(grid, K_sp=1e-5, m_sp=0.5, n_sp=1.0)sp.run_one_step(dt=1000) # dt in years
Hillslope Diffusion
from landlab.components import LinearDiffuserld = LinearDiffuser(grid, linear_diffusivity=0.01) # m^2/yrld.run_one_step(dt=100)
Load/Save DEM Data
from landlab.io import read_esri_ascii, write_esri_asciifrom landlab.io.netcdf import read_netcdf, write_netcdfgrid, z = read_esri_ascii('dem.asc', name='topographic__elevation')write_esri_ascii('output.asc', grid, names='topographic__elevation')write_netcdf('output.nc', grid) # Save all fields
Multi-Component Model
from landlab import RasterModelGridfrom landlab.components import FlowAccumulator, StreamPowerEroder, LinearDiffusergrid = RasterModelGrid((100, 100), xy_spacing=100.0)z = grid.add_zeros('topographic__elevation', at='node')z += grid.node_y / 1000 + np.random.rand(grid.number_of_nodes) * 0.1grid.set_closed_boundaries_at_grid_edges(True, True, True, False)fa = FlowAccumulator(grid, flow_director='D8')sp = StreamPowerEroder(grid, K_sp=1e-5)ld = LinearDiffuser(grid, linear_diffusivity=0.01)dt, uplift_rate = 1000, 0.001for _ in range(500):fa.run_one_step()sp.run_one_step(dt)ld.run_one_step(dt)z[grid.core_nodes] += uplift_rate * dt
When to Use vs Alternatives
| Use Case | Tool | Why | |
|---|---|---|---|
| Landscape evolution modelling | Landlab | Modular components, Python-native | |
| Basin-scale stratigraphy | Badlands | Focus on sediment deposition and basin fill | |
| Topographic analysis (MATLAB) | TopoToolbox | Mature MATLAB toolkit for DEM analysis | |
| Simple diffusion/erosion | Custom numpy | Fewer dependencies for basic models | |
| Coupled surface-subsurface | Landlab | Components for hydrology + geomorphology | |
| Channel network extraction | Landlab or pysheds | Both handle flow routing well | |
| Soil production and transport | Landlab | Dedicated weathering and soil components | |
| Teaching geomorphology | Landlab | Clear component API, good tutorials |
Choose Landlab when: You need a modular, component-based framework for landscape evolution modelling that combines multiple surface processes (erosion, diffusion, flow routing, weathering) in a single simulation.
Choose Badlands when: Your focus is on basin-scale landscape evolution with emphasis on sediment transport and stratigraphic architecture.
Choose custom numpy when: You only need a simple 2D diffusion or stream power model without the overhead of a full component framework.
Common Workflows
Landscape Evolution Model with Erosion and Uplift
- [ ] Create
RasterModelGridwith appropriate dimensions and spacing - [ ] Initialize
topographic__elevationfield (flat + noise, or load DEM) - [ ] Set boundary conditions (open one edge as outlet, close others)
- [ ] Create
FlowAccumulatorwith chosen flow director (D8 or MFD) - [ ] Create
StreamPowerEroderwith erosion coefficient K_sp - [ ] Create
LinearDiffuserfor hillslope processes - [ ] Define time step
dtand total runtime; choose uplift rate - [ ] Run time loop: flow routing, erosion, diffusion, then uplift
- [ ] Save snapshots at intervals with
write_netcdf()orwrite_esri_ascii() - [ ] Visualize final topography with
grid.imshow() - [ ] Analyze drainage area and channel profiles
- [ ] Extract river long profiles for steepness analysis
Common Issues
| Issue | Solution | |
|---|---|---|
| Flat areas block flow | Add small random noise to initial topography | |
| Boundary effects | Ensure at least one open boundary edge for drainage | |
| Unstable erosion | Reduce dt or K_sp; check Courant condition | |
| Wrong field name | Use exact Landlab names: 'topographic__elevation', 'drainage_area' | |
| Memory with large grids | Reduce grid resolution or use NetworkModelGrid for channels only |
Tips
- Set boundaries first - before adding components
- Use core_nodes - excludes boundary nodes for operations
- Check field names - components expect specific names (e.g., 'topographic__elevation')
- Start simple - add components incrementally and verify each
References
- [Components Reference](references/components.md) - Available components by category
- [Grids Reference](references/grids.md) - Grid types and configuration
Scripts
- [scripts/erosion_model.py](scripts/erosion_model.py) - Basic erosion model template