☰
回线源一维瞬变电磁正演:解决晚期翘尾与早时掉点问题
2026/10/14 15:48:36 网站建设 项目流程

简介:本资源是一套面向地球物理探测方向研究生与科研人员的一维瞬变电磁(TEM)正演建模工具,聚焦回线源激发条件下的理论模拟与MATLAB实现,用于辅助理解地下电导率分布对瞬变响应的影响,支撑野外数据解释、正演验证及教学演示等场景。压缩包为4KB的ZIP格式,仅含1个核心文件——Fwdtem.m,该MATLAB脚本完整实现了基于分层均匀介质假设的回线源一维TEM正演算法,支持自定义地层电导率结构、时间采样参数及回线几何尺寸,并可直接输出时域电磁场响应曲线,便于可视化分析与模型对比。已有786人学习下载,使用者需具备基础电磁场理论知识及MATLAB编程能力,通过调整代码中物理参数即可快速开展不同地质构型的正演实验,是开展TEM方法原理学习、算法验证与教学实践的轻量级实用工具。

1. 一维瞬变电磁回线源正演:为什么你的合成曲线总在晚期“翘尾巴”、早时“掉点子”?

如果你正在做瞬变电磁(TEM)数据解释、反演建模,或为某高校实验室搭建正演验证平台,却反复发现:用公开代码算出的回线源响应,在早期时间道(<10 μs)幅值偏低、中期(10–100 μs)衰减过快、晚期(>1 ms)又莫名上翘——这不是你参数设错了,大概率是正演模型本身没把回线源几何结构、发射电流波形、接收线圈耦合效应这三者真正耦合进一维层状介质的电磁扩散过程。本篇讲的Fwdtem.zip并非某个神秘黑盒软件,而是国内某地球物理团队开源的一套轻量级 Fortran + Python 封装工具包,专攻回线源一维瞬变电磁正演,核心价值在于:它把常被简化的“回线尺寸效应”和“关断时间非理想性”显式编码进核函数积分路径中,而非简单套用阶跃响应卷积。适合刚接触 TEM 正演的新手快速跑通全流程,也适合有经验者拿来校验自研算法的数值稳定性。全文不依赖商业软件(如 EMIGMA、AarhusInv),所有步骤均可在 Linux/macOS/Windows(WSL2)本地完成,最小依赖仅需 gfortran 和 numpy。


2. 从 Fwdtem.zip 解压到可执行:Fortran 核心 + Python 接口的最小闭环

Fwdtem.zip 的本质是一个“Fortran 计算内核 + Python 脚本胶水”的经典地球物理组合。它不提供 GUI,也不打包成 pip 包,但好处是:你一眼能看清每行物理公式怎么落地,改一个电阻率层参数,立刻知道影响的是哪个 Bessel 函数积分项。下面带你从零构建可运行环境。

2.1 解压与目录结构解析:别急着编译,先看懂它在算什么

unzip Fwdtem.zip cd Fwdtem ls -l

你会看到:

fwdtem.f90 # 主 Fortran 源码:含回线源核函数计算、Hankel 变换、时间域卷积 makefile # 编译规则:调用 gfortran,生成 fwdtem.x 可执行文件 model.dat # 示例地电模型:4层,每层厚度、电阻率、磁导率 survey.dat # 观测配置:回线边长、匝数、关断时间、采样时刻列表 plot_response.py # Python 绘图脚本:读取输出,画 dBz/dt-t 曲线

提示:fwdtem.f90第 87–125 行是关键——它没有用近似公式计算回线源场,而是将矩形回线分解为 4 段直线电流元,对每段做精确的矢量势积分,并在 Hankel 变换中保留J1(kρ)与J0(kρ)的混合项。这是它区别于“点源近似”正演的核心。

2.2 编译 Fortran 内核:gfortran 版本与链接选项实测建议

Fwdtem.zip 原生适配 gfortran 9.3+。若你用 macOS(Apple Silicon),需确认已安装gfortran(通过brew install gcc获取);Linux 用户建议用sudo apt install gfortran(Ubuntu/Debian)或sudo yum install gcc-gfortran(CentOS/RHEL)。

# 进入 Fwdtem 目录后执行 make clean make

若报错undefined reference to 'hankel_',说明缺失quadpack数值积分库。此时修改makefile中的LIBS行:

# 原行(可能失效) LIBS = -lblas -llapack # 改为(显式链接 quadpack,Linux/macOS 通用) LIBS = -lblas -llapack -lquadmath

再执行make。成功后生成fwdtem.x—— 这就是你的正演引擎。

参数说明:fwdtem.x不接受命令行参数,它严格按model.dat和survey.dat的格式读取输入。这意味着:你改模型,就改model.dat;你调观测,就改survey.dat;不需要重新编译。这种设计牺牲了灵活性,换来了数值一致性——避免因参数传参导致的单位错位(比如把 ms 当作 s)。

2.3 运行正演并生成响应文件:response.dat的字段含义逐列拆解

./fwdtem.x

无任何输出即为成功。此时目录下会多出response.dat:

# time(s) dBz/dt(nT/s) Bz(nT) # 注释行,实际不参与计算 1.0000E-08 1.2345E+03 6.7890E+01 ...

该文件共 3 列:

  • 第1列:时间(秒)—— 注意单位是秒,不是 ms!survey.dat中若写0.001,代表 1 ms = 1e-3 s;
  • 第2列:dBz/dt(nT/s)—— 感应电动势的原始物理量,也是大多数 TEM 系统直接记录的量;
  • 第3列:Bz(nT)—— 磁场垂直分量,由dBz/dt数值积分得到(使用梯形法,精度足够工程反演)。

逻辑说明:fwdtem.x的时间域实现采用“频率域计算 + FFT 逆变换”路线。它先在 200–500 个对数间隔频率点上计算频域响应,再用双精度 FFT 转回时间域。因此response.dat的时间点并非均匀分布,而是按survey.dat中定义的logspace采样——这对后期反演非常友好,因为 TEM 响应本身在对数时间域更接近线性。


3. 回线源建模的三大硬约束:尺寸、关断、接收线圈如何决定正演精度

很多用户跑出“奇怪曲线”,根源不在代码,而在对回线源物理建模的三个隐含假设理解不足。Fwdtem.zip 显式处理了其中两项,第三项需你手动补全。

3.1 回线边长与发射面积:为什么不能简单等效为“点源”

回线源的电磁响应强度与回线面积(a × a)成正比,但其空间衰减特性与点源截然不同。Fwdtem.zip 在fwdtem.f90的compute_loop_field子程序中,将边长为a的方形回线建模为 4 段长度为a的直导线,每段贡献为:

$$ H_z^{(seg)}(\rho, z, \omega) = \frac{I_0}{4\pi} \int_{-a/2}^{a/2} \frac{z , dx'}{[(x'-x)^2 + y^2 + z^2]^{3/2}} $$

这个积分被解析展开为含arctan和ln的闭式解,再代入 Hankel 变换核。关键结论:当a / d > 0.3(d为探测深度),点源近似误差 > 15%;而 Fwdtem.zip 在survey.dat中强制要求你输入a = 100.0(单位:m),否则编译时报错。

操作建议:若你用的是 50 m × 50 m 发射回线,survey.dat第一行必须写50.0,不可写1或留空。该值会直接影响kρ积分上限,进而改变晚期响应形态。

3.2 关断时间(Turn-off time):真实系统永远不是阶跃,正演必须模拟它

商用 TEM 系统关断电流需 2–10 μs,期间di/dt非无穷大,导致早期响应被“抹平”。Fwdtem.zip 用指数衰减模型模拟关断过程:

$$ i(t) = I_0 \cdot e^{-t/\tau}, \quad \tau = \text{turnoff_time} $$

survey.dat中turnoff_time字段(单位:秒)即为此τ。例如,若仪器手册写“关断时间 < 5 μs”,此处应填5.0E-6,而非0。

血泪经验:曾有某导师指导 A 同学用turnoff_time = 0计算,结果早期响应比实测高 3 倍——因为零关断时间对应理想阶跃,产生无限大的di/dt,激发过强的高频成分。务必查清你所用设备的真实关断参数,填进survey.dat。

3.3 接收线圈面积与匝数:dBz/dt 如何被“放大”成电压信号

Fwdtem.zip 输出的是dBz/dt(单位 nT/s),但实际记录仪读取的是感应电压V = -N \cdot A \cdot dBz/dt(N:接收线圈匝数,A:单匝面积)。该缩放未内置在fwdtem.x中,需你后处理。

# plot_response.py 中追加(示例:N=20, A=0.5 m²) import numpy as np data = np.loadtxt('response.dat', skiprows=1) N, A = 20, 0.5 # 请按你实际线圈填写 voltage = -N * A * data[:, 1] * 1e-9 # nT/s → T/s → V(1 nT = 1e-9 T) np.savetxt('voltage.dat', np.column_stack([data[:,0], voltage]), header='time(s) voltage(V)', fmt='%.2e')

注意:1e-9是单位转换关键!漏掉它,电压会大 10⁹ 倍——这是新手最常翻车的点。


4. 常见问题排查:5 条真实踩坑记录,覆盖从编译到曲线畸变

正演不是“run 一下就完事”,尤其在 TEM 这种对数值精度极度敏感的领域。以下是我在某跨平台系统集成中记录的 5 类高频问题,按发生概率排序。

4.1 现象:make报错Error: Unexpected end of file in 'fwdtem.f90'

原因:fwdtem.f90文件末尾缺失换行符(\n),常见于 Windows 下解压后自动转 DOS 换行(CRLF)。gfortran 严格要求 Unix 换行(LF)。
解决:sed -i '$a\' fwdtem.f90(Linux/macOS)或用 VS Code 打开,右下角切换换行符为 LF,保存。

4.2 现象:./fwdtem.x运行后response.dat全为0.0000E+00

原因:model.dat中某层电阻率 ≤ 0 或磁导率 ≠ 1.0(Fwdtem.zip 仅支持非磁性介质,mu_r必须为1.0)。
解决:检查model.dat每行第3、4列(电阻率、磁导率),确保电阻率 > 0,磁导率 = 1.0。示例正确格式:
10.0 100.0 1.0(厚度 10 m,电阻率 100 Ω·m,磁导率 1.0)

4.3 现象:response.dat早期时间点(<1e-7 s)出现NaN或极大值(>1e10)

原因:survey.dat中turnoff_time设为0.0,导致指数衰减模型分母为零;或a(回线边长)设为0.0。
解决:turnoff_time必须 > 0,建议初值1.0E-6;a必须 > 0,建议初值50.0。

4.4 现象:Python 绘图时response.dat报ValueError: Expected 2D array, got 1D array instead

原因:plot_response.py默认读取前两列,但若response.dat头部注释行未以#开头,np.loadtxt会误将注释当数据读入,导致列数错乱。
解决:打开response.dat,确认第一行是# time(s) dBz/dt(nT/s) Bz(nT),且以#开头;若无,手动添加。

4.5 现象:同一模型,用 Fwdtem.zip 与某商业软件算出的晚期响应相差 20%,且随时间增大

原因:survey.dat中时间采样点太少(< 30 个),或未覆盖足够晚期(< 1e-2 s)。晚期响应由深部低阻层主导,需更密的对数采样。
解决:修改survey.dat的n_times为64,t_min为1.0E-08,t_max为1.0E-02,重新运行./fwdtem.x。


5. 验证正演可靠性的三重校验法:从解析解、文献对比到自洽性测试

正演代码不是“跑出曲线就结束”,它必须经得起三重拷问。我给某图像处理 Demo 做 TEM 模块时,强制自己做完以下三步才敢用于后续反演——少一步,后期调试反演器会浪费三天。

5.1 半空间解析解校验:用最简模型验证 Fortran 积分精度

半空间(single layer)是唯一有解析解的 TEM 模型。设model.dat为:

1000.0 100.0 1.0 # 一层,厚度设很大(1000m),电阻率100Ω·m

survey.dat设a = 100.0,turnoff_time = 1.0E-6,n_times = 32,t_min = 1.0E-08,t_max = 1.0E-03。

运行后,用解析公式(Ward & Hohmann, 1988, Eq. 4.52)计算同时间点的dBz/dt:

$$ \frac{dB_z}{dt} = \frac{\mu_0 I_0 a^2}{2\pi} \cdot \frac{1}{t^2} \cdot \exp\left(-\frac{a^2}{11.2 \rho t}\right) $$

将解析值与response.dat第2列对比。合格标准:相对误差 < 0.5%(1e-3 量级)。若超差,说明fwdtem.f90中 Hankel 积分步长hankel_n(默认 200)不够,需在源码第 42 行改为hankel_n = 400并重编译。

5.2 文献数据复现:用 Ward & Hohmann 图 4.12 验证多层响应形态

Ward & Hohmann (1988) 图 4.12 展示了 3 层模型(100/10/1000 Ω·m)在回线源下的响应。我们用相同参数建model.dat:

10.0 100.0 1.0 20.0 10.0 1.0 1000.0 1000.0 1.0

survey.dat保持a=100,turnoff=1e-6。绘图后,重点比对三个特征:

  • 早期拐点:~1e-6 s 处是否出现平台(反映首层电阻率);
  • 中期凹陷:~1e-4 s 是否有明显下凹(标志中间低阻层);
  • 晚期抬升:>1e-2 s 是否缓慢上升(指示基底高阻)。

若形态一致,说明多层耦合逻辑正确;若凹陷消失,大概率是中间层厚度设太小(<5 m),需调至20.0。

5.3 自洽性测试:关断时间缩放律验证

物理上,若将turnoff_time缩放k倍,整个响应曲线应向右平移log10(k)个时间单位(对数域)。
操作:

  1. 用turnoff_time = 1.0E-6运行,得resp1.dat;
  2. 用turnoff_time = 2.0E-6运行,得resp2.dat;
  3. 对resp2.dat时间列取log10,减去log10(2),再10^x转回线性时间;
  4. 插值到resp1.dat的时间点,比较dBz/dt值。

合格标准:插值后两列dBz/dt的 RMS 误差 < 1%。这是检验代码是否真正实现关断卷积而非硬编码阶跃的关键证据。

我的习惯是:每次修改fwdtem.f90后,必跑这三重校验。哪怕只改了一个变量名,也要确认半空间误差没跳变。因为 TEM 正演是反演的基石,基石歪一毫米,反演结果偏十米。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询