landlab

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Landlab - Surface Process Modelling

Landlab - 地表过程建模

Quick Reference

快速参考

python
from landlab import RasterModelGrid
from landlab.components import FlowAccumulator, StreamPowerEroder
import numpy as np
python
from landlab import RasterModelGrid
from landlab.components import FlowAccumulator, StreamPowerEroder
import numpy as np

Create grid

Create grid

grid = 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
grid = 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)

Set boundaries (open bottom edge)

grid.set_closed_boundaries_at_grid_edges(True, True, True, False)
grid.set_closed_boundaries_at_grid_edges(True, True, True, False)

Create and run components

Create and run components

fa = 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 # Uplift
grid.imshow('topographic__elevation', cmap='terrain')
undefined
fa = 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 # Uplift
grid.imshow('topographic__elevation', cmap='terrain')
undefined

Grid Types

网格类型

GridUse Case
RasterModelGrid
Regular rectangular grids (most common)
HexModelGrid
Hexagonal grids (isotropic flow)
VoronoiDelaunayGrid
Irregular point distributions
NetworkModelGrid
Channel networks only
网格类型适用场景
RasterModelGrid
规则矩形网格(最常用)
HexModelGrid
六边形网格(各向同性水流)
VoronoiDelaunayGrid
不规则点分布网格
NetworkModelGrid
仅适用于河道网络

Key Concepts

核心概念

Fields and Boundaries

字段与边界

python
undefined
python
undefined

Fields: data stored at grid elements (nodes, links, cells)

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
z = grid.add_zeros('topographic__elevation', at='node') grid.at_node['drainage_area'] # Access existing field

Boundaries: close all edges except outlet

Boundaries: close all edges except outlet

grid.set_closed_boundaries_at_grid_edges(True, True, True, False) z[grid.core_nodes] += uplift * dt # Core nodes exclude boundaries
undefined
grid.set_closed_boundaries_at_grid_edges(True, True, True, False) z[grid.core_nodes] += uplift * dt # Core nodes exclude boundaries
undefined

Essential Operations

核心操作

Flow Routing

水流路径模拟

python
from landlab.components import FlowAccumulator

fa = FlowAccumulator(grid, flow_director='D8')  # or 'Steepest', 'MFD'
fa.run_one_step()
drainage_area = grid.at_node['drainage_area']
python
from landlab.components import FlowAccumulator

fa = FlowAccumulator(grid, flow_director='D8')  # or 'Steepest', 'MFD'
fa.run_one_step()
drainage_area = grid.at_node['drainage_area']

Stream Power Erosion

河流动力侵蚀

python
from landlab.components import StreamPowerEroder

sp = StreamPowerEroder(grid, K_sp=1e-5, m_sp=0.5, n_sp=1.0)
sp.run_one_step(dt=1000)  # dt in years
python
from landlab.components import StreamPowerEroder

sp = 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

山坡扩散

python
from landlab.components import LinearDiffuser

ld = LinearDiffuser(grid, linear_diffusivity=0.01)  # m^2/yr
ld.run_one_step(dt=100)
python
from landlab.components import LinearDiffuser

ld = LinearDiffuser(grid, linear_diffusivity=0.01)  # m^2/yr
ld.run_one_step(dt=100)

Load/Save DEM Data

加载/保存DEM数据

python
from landlab.io import read_esri_ascii, write_esri_ascii
from landlab.io.netcdf import read_netcdf, write_netcdf

grid, 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
python
from landlab.io import read_esri_ascii, write_esri_ascii
from landlab.io.netcdf import read_netcdf, write_netcdf

grid, 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

多组件模型

python
from landlab import RasterModelGrid
from landlab.components import FlowAccumulator, StreamPowerEroder, LinearDiffuser

grid = 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.1
grid.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.001
for _ in range(500):
    fa.run_one_step()
    sp.run_one_step(dt)
    ld.run_one_step(dt)
    z[grid.core_nodes] += uplift_rate * dt
python
from landlab import RasterModelGrid
from landlab.components import FlowAccumulator, StreamPowerEroder, LinearDiffuser

grid = 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.1
grid.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.001
for _ 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 CaseToolWhy
Landscape evolution modellingLandlabModular components, Python-native
Basin-scale stratigraphyBadlandsFocus on sediment deposition and basin fill
Topographic analysis (MATLAB)TopoToolboxMature MATLAB toolkit for DEM analysis
Simple diffusion/erosionCustom numpyFewer dependencies for basic models
Coupled surface-subsurfaceLandlabComponents for hydrology + geomorphology
Channel network extractionLandlab or pyshedsBoth handle flow routing well
Soil production and transportLandlabDedicated weathering and soil components
Teaching geomorphologyLandlabClear 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.
适用场景工具原因
地形演化建模Landlab模块化组件,原生支持Python
盆地尺度地层学Badlands专注于沉积物沉积与盆地填充
地形分析(MATLAB)TopoToolbox成熟的MATLAB地形分析工具包
简单扩散/侵蚀模拟自定义numpy实现基础模型依赖更少
地表-地下耦合模拟Landlab包含水文与地貌学组件
河道网络提取Landlabpysheds两者均能很好处理水流路径模拟
土壤生成与搬运Landlab有专门的风化与土壤组件
地貌学教学Landlab组件API清晰,教程完善
选择Landlab的场景:你需要一个模块化、基于组件的框架,用于整合多种地表过程(侵蚀、扩散、水流路径、风化)的地形演化模拟。
选择Badlands的场景:你的研究重点是盆地尺度的地形演化,且强调沉积物搬运与地层结构。
选择自定义numpy实现的场景:你只需要简单的二维扩散或河流动力模型,无需完整组件框架的开销。

Common Workflows

常见工作流

Landscape Evolution Model with Erosion and Uplift

包含侵蚀与抬升的地形演化模型

  • Create
    RasterModelGrid
    with appropriate dimensions and spacing
  • Initialize
    topographic__elevation
    field (flat + noise, or load DEM)
  • Set boundary conditions (open one edge as outlet, close others)
  • Create
    FlowAccumulator
    with chosen flow director (D8 or MFD)
  • Create
    StreamPowerEroder
    with erosion coefficient K_sp
  • Create
    LinearDiffuser
    for hillslope processes
  • Define time step
    dt
    and total runtime; choose uplift rate
  • Run time loop: flow routing, erosion, diffusion, then uplift
  • Save snapshots at intervals with
    write_netcdf()
    or
    write_esri_ascii()
  • Visualize final topography with
    grid.imshow()
  • Analyze drainage area and channel profiles
  • Extract river long profiles for steepness analysis
  • 创建合适尺寸与间距的
    RasterModelGrid
  • 初始化
    topographic__elevation
    字段(平坦地形加噪声,或加载DEM)
  • 设置边界条件(开放一个边缘作为出口,关闭其他边缘)
  • 创建带有指定流向算法(D8或MFD)的
    FlowAccumulator
  • 创建带有侵蚀系数K_sp的
    StreamPowerEroder
  • 创建用于山坡过程的
    LinearDiffuser
  • 定义时间步长
    dt
    与总运行时长,选择抬升速率
  • 运行时间循环:水流路径模拟、侵蚀、扩散,然后抬升
  • 定期使用
    write_netcdf()
    write_esri_ascii()
    保存快照
  • 使用
    grid.imshow()
    可视化最终地形
  • 分析流域面积与河道剖面
  • 提取河流纵剖面进行陡峭度分析

Common Issues

常见问题

IssueSolution
Flat areas block flowAdd small random noise to initial topography
Boundary effectsEnsure at least one open boundary edge for drainage
Unstable erosionReduce
dt
or
K_sp
; check Courant condition
Wrong field nameUse exact Landlab names:
'topographic__elevation'
,
'drainage_area'
Memory with large gridsReduce grid resolution or use
NetworkModelGrid
for channels only
问题解决方案
平坦区域阻塞水流为初始地形添加少量随机噪声
边界效应确保至少有一个开放边界用于排水
侵蚀模拟不稳定减小
dt
K_sp
;检查Courant条件
字段名称错误使用Landlab规定的准确名称:
'topographic__elevation'
'drainage_area'
大型网格内存不足降低网格分辨率,或针对河道使用
NetworkModelGrid

Tips

小贴士

  1. Set boundaries first - before adding components
  2. Use core_nodes - excludes boundary nodes for operations
  3. Check field names - components expect specific names (e.g., 'topographic__elevation')
  4. Start simple - add components incrementally and verify each
  1. 先设置边界 - 在添加组件之前完成边界设置
  2. 使用core_nodes - 排除边界节点进行操作
  3. 检查字段名称 - 组件需要特定名称(例如'topographic__elevation')
  4. 从简单开始 - 逐步添加组件并验证每个步骤

References

参考资料

  • Components Reference - Available components by category
  • Grids Reference - Grid types and configuration
  • 组件参考 - 按分类列出可用组件
  • 网格参考 - 网格类型与配置说明

Scripts

脚本

  • scripts/erosion_model.py - Basic erosion model template
  • scripts/erosion_model.py - 基础侵蚀模型模板