射击法模拟器 返回
数值分析

射击法模拟器

在区间两端处有条件的边界值问题求解工具。用「射击(射击)法」求解问题。假设左端的初始斜率,向右端积分,观察目标值的偏离量,然后重新射击——大炮瞄准目标的过程实时可视化。

参数设置
微分方程系数 c(y'' = c·y)
c>0 时为双曲线型(指数型),c<0 时为振荡型解
区间长度 L
求解边界值问题的区间 [0, L]
左端边界值 y(0)
区间左端固定的解的值 A
右端边界值 y(L)
区间右端固定的目标值 B(射击的目标)
最大迭代次数
射击重复的上限。线性问题在2次收敛
计算结果
所需的初始斜率 y'(0)
到达的右端值 y(L)
端点误差
迭代(射击)次数
中点值 y(L/2)
收敛判定
射击过程 — 轨迹动画

从左端边界点发射,通过改变初始斜率多次射击。欠射(橙色)、过射(红色)、收敛的解(蓝色、粗线)被绘制,只有蓝色轨迹准确穿过右端的目标。

收敛的解 y(x)
逐次射击的轨迹
理论·主要公式

$$y''=c\,y,\quad y(0)=A,\ y(L)=B$$

需要求解的边界值问题。在区间 [0, L] 两端指定解的值 A、B。将其转换为一阶连立系统 $y'=v,\ v'=c\,y$ 进行积分。

$$s^\star=s_0+\frac{B-y_{end}(s_0)}{y_{end}(s_1)-y_{end}(s_0)}\,(s_1-s_0)$$

初始斜率的割线更新式。$y_{end}(s)$ 是用初始斜率 s 到达右端的值,$s_0,s_1$ 是试行斜率。对于线性常微分方程,$y_{end}(s)$ 对 s 是一次函数,因此只需两次射击和一次插值就能精确命中边界条件。

什么是射击法

🙋
「边界值问题」是微分方程的一种,对吧?求解方式和通常的初值问题有什么区别吗?
🎓
简单说,区别在于条件的给定位置。像投掷球的轨迹那样,在一点同时给定「初始位置和速度」的是初值问题。而边界值问题是「左端点的 y 是这个值,右端点的 y 是那个值」,条件分别给在区间的两端。例如两端被墙固定的梁的挠度,或两端温度固定的杆的稳定热传导,都是边界值问题。两端都被约束是关键。
🙋
如果两端都确定了,那从左端用龙格-库塔法直接积分不就行了吗?
🎓
这就是陷阱所在。像龙格-库塔法这样的推进型求解器,需要在出发点同时给定「值」和「斜率」才能迈出第一步。但在边界值问题中,虽然左端知道 y(0),却不知道 y'(0),代替的是右端的条件。也就是说,单端的信息不足以开始积分。右端的条件对从左端出发是没用的。
🙋
那么缺失的 y'(0) 怎么处理呢?
🎓
这就是射击法的思想。想法很简单,缺失的 y'(0) 就「随便猜测」一下。设定一个任意的斜率 s,这样左端就同时有值和斜率,变成了普通的初值问题。用龙格-库塔法一直积分到右端。然后右端会到达某个 y 值,看它与目标值 B 相差多少——这就是「偏离量(失误)」。就像用大炮射向远处的目标,看偏了多少,再调整后重新射击。这就是「射击(shooting)法」的名字由来。
🙋
说要反复射击听起来很麻烦,但左边的工具里迭代次数一直是「2」,为什么呢?
🎓
好问题。这个工具处理的 y''=c·y 对 s 是「线性」的。线性方程的话,右端到达值 y_end(s) 就是 s 的一次函数。一次函数由两点唯一确定,对吧。所以 s=0 时射一次,s=1 时再射一次,测得端点的两个值,然后用这两点连线来求过目标 B 的斜率 s*——这就是割线插值。不需要第三次。端点误差基本为零,机器精度就能的中。所以迭代是2次。
🙋
那如果是非线性问题,就要射很多次吧?
🎓
完全同意。非线性的话 y_end(s) 会变成弯曲的函数,两点的直线对不了。这时就「把偏离量 F(s)=y_end(s)−B 看成一个非线性方程要求其为零」,对它反复应用割线法或牛顿法。每次迭代各积一次,直到偏离量足够小。这个工具处理的是线性方程,所以两次收敛,但最大迭代次数的滑块是想体现非线性情况下的一般步骤。

常见问题

射击法是一种数值方法,用于求解在区间两端指定条件的边界值问题(BVP)。它通过「猜测」单端缺失的信息,将其转换为初值问题(IVP),然后通过反复迭代求解。对于边界值问题 y''=c·y, y(0)=A, y(L)=B,左端的初始斜率 y'(0) 是未知的。我们假设它为 s,用龙格-库塔法积分到右端,观察所得的 y(L) 与目标值 B 相差多少,然后修改 s。就像用大炮瞄准远处的目标,根据偏离程度调整角度重新射击,因此称为「射击法」。
对于像 y''=c·y 这样关于初始斜率 s 的线性方程,右端到达的值 y_end(s) 是 s 的仿射函数(一次函数)。一次函数由两点唯一确定,因此只需在 s0=0 和 s1=1 处各射击一次,测得 y_end 的两个值,然后用线性插值(割线步长)就能精确求得满足目标值 B 的初始斜率 s*。不需要第三次及以后的迭代,端点误差会减小到机器精度(约 1e-12 以下)。
在非线性问题中,y_end(s) 不再是 s 的一次函数,因此两次射击无法命中目标。此时,我们将端点的「偏离量」F(s)=y_end(s)−B 视为一个非线性方程,对其反复应用割线法或牛顿法。每次迭代进行一次积分,直到偏离量小于容差。本工具处理的是线性方程,因此两次收敛,但最大迭代次数的滑块反映了非线性情况下的一般过程。
龙格-库塔法之类的时间推进型求解器需要在某一点同时给定「值」和「斜率」才能开始积分。但在边界值问题中,虽然左端已知 y(0),却不知道 y'(0),而是由右端的条件 y(L) 代替。这意味着单端的信息不足以启动积分。射击法通过假设缺失的 y'(0) 来弥补这一不足,将边界值问题转化为标准初值问题的积分。

实际应用

结构力学中的梁、杆的挠度:两端支持的梁的弯曲问题是关于挠度 w(x) 的边界值问题。两端的挠度或斜率受到约束,初值问题求解器无法直接求解。使用射击法,可以「猜测」单端未知的反力矩或剪力,调整到另一端的边界条件满足为止,这样可以数值求解难以解析求解的变断面梁或弹性支持梁等。

定常热传导和化学反应扩散:两端温度固定的杆的定常热传导,催化剂颗粒内的反应扩散方程等是典型的边界值问题。包含发热项或温度相关物性时会变成非线性,无法得到解析解。使用射击法,可以假设单端未知的热流量进行积分,调整到另一端的温度条件满足,从而求得温度分布或反应速率分布。

流体力学的边界层方程:平板上的层流边界层由 Blasius 方程 f'''+f·f''/2=0 描述,这是在壁面和无穷远处都有条件的非线性边界值问题。用射击法假设壁面处未知的剪应力 f''(0),反复探索满足无穷远条件 f'→1 的值。这对航空飞行器和涡轮叶片周围摩擦阻力、传热的估算有直接影响,是经典应用例。

量子力学的本征值问题:一维薛定谔方程中求束缚态的能量本征值的计算也是边界值问题,其中波函数在两端衰减为零。以能量为参数从单端积分波函数,通过射击法搜索使另一端波函数为零的能量。本征值搜索和射击法的组合是代表性的应用情况。

常见误解和注意事项

最大的陷阱是「线性问题两次就命中了,所以非线性问题也会快速收敛」的误解。本工具处理的 y''=c·y 对初始斜率 s 是线性的,所以端点到达值 y_end(s) 是 s 的一次函数,两次射击和一次插值就能精确命中。但非线性边界值问题中,y_end(s) 会变成弯曲函数,两点的直线无法命中。初期推测不好会导致迭代振荡,甚至完全不收敛。必须认识到线性和非线性的区别,非线性时需要让割线法、牛顿法完整迭代到最后。

其次是「初值问题的积分在不稳定的方程中会发散,这样的方程射击法也不能用」的疏忽。系数 c 很大的正双曲线型方程会包含指数增长的解分量。从单端积分时,初始斜率的微小误差会被这个增长成分放大,导致端点出现巨大数值或溢出。区间越长问题越严重。实务中为了避免这个问题,常用「多重射击法(multiple shooting)」,即把区间分成多个子区间,分别射击每个子区间,在边界处拼接。简单射击法不是万能的。

最后,「射击的精度只由补间算法决定」的错误认识。射击法最终解的精度不只由补间(割线法等)决定,还依赖内部使用的初值问题求解器的精度。本工具使用4阶龙格-库塔法,约400步积分,线性问题的端点误差可达机器精度。但如果步数太少或用低阶欧拉法,即使补间完美,积分本身的离散化误差也会保留,解的精度也就不会更好。射击法是「补间」和「积分」的两层结构,两者精度都要确保才能得到可信的解。

使用指南

  1. 在「模拟条件」中设置区间长度L、常微分方程的系数。例如热传导方程 d²T/dx² + c·T = 0 的情况,输入系数c
  2. 在「左端值」「右端值」中指定左端y(0)和右端y(L)的边界条件。初始斜率y'(0)未知,由模拟器自动探索
  3. 点击「执行模拟」,模拟器会用不同的初始斜率反复积分,不断「射击」直到右端值与目标一致。可以在图表中确认迭代过程和误差的减少

具体计算例

梁的挠度方程 d²y/dx² = M(x)/EI 为例:区间长L=2m,左端y(0)=0,右端y(2)=0(两端固定),系数c=0.5。射击法用初始斜率y'(0)=−0.8 rad/m试行→右端到达值y(2)=−0.05m→与目标0m偏离→改用y'(0)=−0.6重试这样的过程重复3~5次,最后收敛到y'(0)=−0.707 rad/m,中点值y(1.0)=−0.25m

实务中的注意点