31 - 辐射场¶
辐射场描述场景中每个叶片或地面单元吸收了多少短波辐射。它是能量平衡、光合作用和荧光计算的输入,也可以单独用来研究冠层的光分布,例如吸收的光合有效辐射(APAR)、受光叶片比例和垂直廓线。
LESS 提供两种计算方式:
RadiationFieldProcess |
ForwardRadiationFieldSensor |
|
|---|---|---|
| 方法 | 从每个场景元素向外追踪 | 从太阳和天空向场景追踪光子 |
| 结果 | 每个三角形或统计植被组件 | 每个三角形或三维体素 |
| 用途 | 后续的能量平衡、光合、荧光 | 垂直廓线、空间分布 |
每个元素的吸收¶
import numpy as np
import less
scene = less.Scene()
scene.size = 6.0
scene.terrain = less.Terrain(property=less.Lambertian(reflectance=0.15))
scene.illumination = less.Illumination(
source=less.Sun(zenith=30, azimuth=150),
atmosphere=less.SimpleSpectralAtmosphere(turbidity=2.0))
plant = less.Object("plant")
plant.add_component("leaves", less.Mesh(less.asset_path("tutorial_tree.obj"), group="leaves"))
plant.set_property("leaves", less.Prospect(cab=45))
scene.add(plant, positions=[(3, 3, 0)])
radiation = scene.simulate(less.RadiationFieldProcess(n_samples=64))
print(radiation.absorbed_top.shape) # (元素数, 波段数)
print(radiation.wavelengths)
| 结果 | 含义 |
|---|---|
absorbed_top、absorbed_bot |
正面和背面吸收的短波辐射(每单位面积,W m⁻²) |
absorbed_direct |
未被遮挡时吸收的太阳直射部分 |
sunlit_fraction |
能直接看到太阳的叶面积比例 |
wavelengths、band_widths |
波段中心和宽度(nm) |
leaf_area |
每个元素的面积 |
纯三角网格场景中,每个三角形是一个元素;含统计植被的场景中,每个放置后的统计植被组件是一个元素,结果是该组件内的叶面积加权平均。
在一个波长范围内积分:
par_absorbed = radiation.integrate((400, 700)) # 每个元素,W m⁻²
print(f"平均吸收的光合有效辐射: {par_absorbed.mean():.1f} W m⁻²")
print(radiation.summary())
波段设置¶
默认使用 24 个覆盖 415–2100 nm 的波段,其中 19 个在光合有效辐射范围内。spectral_profile 可以指定其他波段:
solar = less.SpectralProfile.solar_shortwave() # 400–2400 nm,5 nm 间隔
par = less.SpectralProfile([less.SpectralBand(float(center), 10.0, "par")
for center in range(405, 700, 10)])
fine = scene.simulate(less.RadiationFieldProcess(spectral_profile=par, n_samples=64))
计算与色素有关的吸收(例如叶绿素吸收的光合有效辐射)时,光合有效辐射范围内宜使用较窄的波段。
采样参数¶
| 参数 | 含义 |
|---|---|
n_samples |
每个三角形每一面的采样数 |
n_leaf_samples |
每个统计植被组件的叶片样本数 |
max_depth |
最多追踪的反射和透射次数 |
可以增大采样数比较结果,确认吸收已经稳定。
把辐射场交给其他过程¶
能量平衡、光合作用和荧光都可以直接使用已经算好的辐射场,避免重复计算:
plant.set_property("leaves", less.ThermalProperty(temperature="air", emissivity=0.98))
plant.set_property("leaves", less.BiophysicalProperty(leaf_width=0.05, stomata_side="bottom"))
scene.terrain.set_property(less.ThermalProperty(temperature="air", emissivity=0.95))
scene.terrain.set_property(less.BiophysicalProperty(two_sided=False, stomata_side="none",
ground_heat_fraction=0.3))
radiation = scene.simulate(less.RadiationFieldProcess(n_samples=64))
climate = less.Microclimate(air_temperature=25.0, humidity=60.0, wind_speed=2.0)
energy = scene.simulate(less.EnergyBalanceProcess(rad=radiation, quality="preview"),
microclimate=climate)
辐射场与计算它时的场景状态绑定:光照、属性或几何改变后(包括上面新设的热属性),需要重新计算辐射场。一个辐射场只交给一个过程使用。
三维体素中的吸收¶
ForwardRadiationFieldSensor 从光源出发追踪光子,按水平网格和高度分层统计吸收,可以得到冠层的垂直吸收廓线:
forest = less.Scene()
forest.size = 20.0
forest.terrain = less.Terrain(property=less.Lambertian(reflectance=0.15))
forest.illumination = less.Illumination(
source=less.Sun(zenith=30, azimuth=150), atmosphere=less.NoAtmosphere())
tree = less.Object("ash", mesh=less.asset_path("FREX.obj"))
tree.set_property("leaves", less.Prospect(cab=40))
tree.set_property("stem_branch", less.Lambertian(reflectance=0.1))
forest.add(tree, positions=less.place.random(forest, n=8, min_dist=5.0, seed=1))
field = forest.simulate(less.ForwardRadiationFieldSensor(
bands=[450, 550, 650], mode="grid", grid=(20, 20), layer_height=1.0,
photons_per_m2=4000, integration_range=(400, 700)))
print(field.absorption_grid.shape) # (层, 行, 列, 波段)
print(f"冠层吸收的光合有效辐射比例: {field.fpar:.3f}")
field.save("forest_radiation_field.npz")
mode="per_leaf"(默认)给出每个三角形的吸收,mode="grid" 给出(层, 行, 列, 波段)的体素吸收。layer_height 是每层的厚度,也可以用 layer_heights 直接给出各层的边界。