前置知识-边值问题、打靶法、bvp 系列函数的用法

本文介绍了微分方程边值问题(BVP)的重要性,包括其在工程学和物理学中的应用。讲解了打靶法作为解决二阶常微分方程边值问题的一种方法,以及如何通过线性插值法修正初始值来逐步逼近解。此外,还阐述了Matlab中的bvp系列函数,如bvp4c和bvp5c,用于数值求解边值问题的流程和示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.2 边值问题

微分方程边值问题(Boundary Value Problem,简称BVP)是微分方程求解中的一个重要问题。与初值问题(Initial Value Problem,简称IVP)不同,BVP是在某个区间内寻求微分方程解的特定边界条件下的解。

在实际问题中,许多微分方程的解必须满足一些特定的边界条件,例如固定的温度或者压力等。这时就需要使用BVP求解微分方程的解。BVP的解通常比IVP更加复杂,因为它需要同时满足微分方程和一组特定的边界条件。

BVP的解决方法通常需要使用一些数值方法,例如有限差分法、有限元法和谱方法等。这些方法的主要思想是将微分方程转化为一个线性代数方程组,然后使用矩阵运算求解。这些方法的优点是可以处理一般的非线性和非均匀微分方程,但是它们需要大量的计算和数值处理,并且需要选择合适的数值方法和参数。

BVP的应用范围非常广泛,例如在工程学中可以用于处理热传导、流体力学、结构力学等问题,在物理学中可以用于处理量子力学、电动力学等问题。因此,了解和掌握BVP求解方法对于理解和应用微分方程有着重要的意义。

本小节讨论典型的二阶常微分方程的边值问题:
d 2 u   d x 2 = f ( x , u , d u   d x ) , a < x < b (1-65) \frac{\mathrm{d}^2 u}{\mathrm{~d} x^2}=f\left(x, u, \frac{\mathrm{d} u}{\mathrm{~d} x}\right), \quad a<x<b\tag{1-65}  dx2d2u=f(x,u, dxdu),a<x<b(1-65)
其边界条件为 ( α 1 、 β 1 、 γ 1 、 α 2 、 β 2 、 γ 2 \left(\alpha_1 、 \beta_1 、 \gamma_1 、 \alpha_2 、 \beta_2 、 \gamma_2\right. (α1β1γ1α2β2γ2 均为常数 ) ) ) :
{ α 1 u ( a ) + β 1 u ′ ( a ) = γ 1 α 2 u ( b ) + β 2 u ′ ( b ) = γ 2 (1-66) \left\{\begin{array}{l} \alpha_1 u(a)+\beta_1 u^{\prime}(a)=\gamma_1 \\ \alpha_2 u(b)+\beta_2 u^{\prime}(b)=\gamma_2 \end{array}\right.\tag{1-66} {α1u(a)+β1u(a)=γ1α2u(b)+β2u(b)=γ2(1-66)
上式具有很强的一般性, 这里先从一种简单的边界条件开始分析 ( α 、 β \alpha 、 \beta αβ 为常数):
u ( a ) = α , u ( b ) = β (1-67) u(a)=\alpha, \quad u(b)=\beta\tag{1-67} u(a)=α,u(b)=β(1-67)

1.2.1 打靶法.

对于二阶常微分方程(1-65)及边界条件(1-67), 利用代换 u 1 = u 、 u 2 = u ′ u_1=u 、 u_2=u^{\prime} u1=uu2=u, 可将其写为等价的方程组形式:
{ u 1 ′ = u 2 , u 1 ( a ) = α u 2 ′ = f ( x , u 1 , u 2 ) , u 1 ( b ) = β (1-68) \begin{cases}u_1^{\prime}=u_2, & u_1(a)=\alpha \\ u_2^{\prime}=f\left(x, u_1, u_2\right), & u_1(b)=\beta\end{cases}\tag{1-68} {u1=u2,u2=f(x,u1,u2),u1(a)=αu1(b)=β(1-68)
它与初值问题的不同之处在于, u 2 ( a ) u_2(a) u2(a) 的值是末知的, 已知条件中取而代之的是 u 1 ( b ) u_1(b) u1(b) 的值, 否则就可以直接通过 odesolver 数值求解了。假如可以确定一个值 m m m, 使初值问题 (1-69) 的解 u 1 ( x ) u_1(x) u1(x) 满足 ∣ u 1 ( b ) − β ∣ < ε \mid u_1(b)-\beta\mid <\varepsilon u1(b)β∣<ε, 其中 ε \varepsilon ε 为可允许的误差, 那么边值问题 (1-68) 和初值问题(1-69) 的解就是近似相等的, 也就相当于把边值问题转化成了初值问题。
{ u 1 ′ = u 2 , u 1 ( a ) = α u 2 ′ = f ( x , u 1 , u 2 ) , u 2 ( a ) = m (1-69) \begin{cases}u_1^{\prime}=u_2, & u_1(a)=\alpha \\ u_2^{\prime}=f\left(x, u_1, u_2\right), & u_2(a)=m\end{cases}\tag{1-69} {u1=u2,u2=f(x,u1,u2),u1(a)=αu2(a)=m(1-69)
打靶法就是用来确定 m m m 值的, 大致思路如下:

(1) 随意选取 m m m 的起始值。

(2) 求出初值问题 (1-69) 的解 u 1 ( x ) u_1(x) u1(x)

(3)若不符合 ∣ u 1 ( b ) − β ∣ < ε \mid u_1(b)-\beta\mid <\varepsilon u1(b)β∣<ε, 就修正 m m m 的值。

(4) 重复前面两项, 直到符合 ∣ u 1 ( b ) − β ∣ < ε \mid u_1(b)-\beta\mid <\varepsilon u1(b)β∣<ε, 此时的 u 1 ( x ) u_1(x) u1(x) 就是数值解。

修正 m m m 取值的方法可以是线性插值法、牛顿法等, 这里使用比较简单的线性插值法。 设 m = m n m=m_n m=mn 时初值问题(1-69) 的解 u 1 ( x ) u_1(x) u1(x) x = b x=b x=b 处有 u 1 ( b ) = β n u_1(b)=\beta_n u1(b)=βn, 其中 n = 1 , 2 , … n=1,2, \ldots n=1,2, 。若假设 m n m_n mn β n \beta_n βn 是线性关系, 为了让 m m m 取最新修正值 m n + 2 m_{n+2} mn+2 时有 β n + 2 = β \beta_{n+2}=\beta βn+2=β, 则 m n + 2 m_{n+2} mn+2 需要满足 ( m n + 2 − m n ) / ( β − β n ) = ( m n + 1 − m n ) / ( β n + 1 − β n ) \left(m_{n+2}-m_n\right) /\left(\beta-\beta_n\right)=\left(m_{n+1}-m_n\right) /\left(\beta_{n+1}-\beta_n\right) (mn+2mn)/(ββn)=(mn+1mn)/(βn+1βn), 即:
m n + 2 = m n + m n + 1 − m n β n + 1 − β n ( β − β n ) (1-70) m_{n+2}=m_n+\frac{m_{n+1}-m_n}{\beta_{n+1}-\beta_n}\left(\beta-\beta_n\right)\tag{1-70} mn+2=mn+βn+1βnmn+1mn(ββn)(1-70)
其中的 m n 、 β n 、 m n + 1 、 β n + 1 m_n 、 \beta_n 、 m_{n+1} 、 \beta_{n+1} mnβnmn+1βn+1 为已知, 这就是说如果使用线性插值法修正 m m m 的取值, 在打靶法开始时需要先随意选取 2 个 m m m 的起始值 m 1 、 m 2 m_1 、 m_2 m1m2, 计算出相应的 β 1 、 β 2 \beta_1 、 \beta_2 β1β2, 才可以根据上式得到修正值 m 3 m_3 m3, 进而得到 β 3 \beta_3 β3, 然后得到修正值 m 4 ⋯ ⋯ m_4 \cdots \cdots m4⋯⋯ 直到找到满足 ∣ β n − β ∣ < ε \mid \beta_n-\beta\mid <\varepsilon βnβ∣<ε m m m 值。此时初值问题 (1-69) 的解即近似为边值问题(1-68)的解, 而初值问题是容易数值求解的。

虽然 m m m m 1 、 m 2 m_1 、 m_2 m1m2 时, 最终结果在 x = b x=b x=b 处的取值与应有的边界条件相差甚远, 但通过一次一次地修正, 逐渐缩小距离目标的差距, 最终总会得到在一定误差内满足 x = b x=b x=b 处边界条件的解。

对于更复杂的边界条件 (1-66), 照样可以用打靶法解决。尽管 u ( a ) u(a) u(a) u ′ ( a ) u^{\prime}(a) u(a) 的值都是末知的, 但只要猜测它们其中一个的取值, 就可以通过关系 α 1 u ( a ) + β 1 u ′ ( a ) = γ 1 \alpha_1 u(a)+\beta_1 u^{\prime}(a)=\gamma_1 α1u(a)+β1u(a)=γ1 得到另外一 个的值。有了 u ( a ) u(a) u(a) u ′ ( a ) u^{\prime}(a) u(a) 的值, 再通过 odesolver 求解式 (1-65) 得到 u ( b ) u(b) u(b) u ′ ( b ) u^{\prime}(b) u(b) 的值(当然需要变量代换 u 1 = u 、 u 2 = u ′ u_1=u 、 u_2=u^{\prime} u1=uu2=u ), 然后使用 ∣ α 2 u ( b ) + β 2 u ′ ( b ) − γ 2 ∣ < ε \mid \alpha_2 u(b)+\beta_2 u^{\prime}(b)-\gamma_2\mid<\varepsilon α2u(b)+β2u(b)γ2∣<ε 判断猜测的初始值是否符合 要求, 如失败就修正猜测值后继续尝试, 直到符合要求。这样一来, 同样可以将边界条件 (1-66)下的边值问题当做初值问题处理。

下面举一个例子, 考虑如下二阶常微分方程:
u ′ ′ + ∣ u ∣ = 0 , 0 < x < 4 (1-71) u^{\prime \prime}+|u|=0, \quad 0<x<4\tag{1-71} u′′+u=0,0<x<4(1-71)
其边界条件为:
u ( 0 ) = 0 , u ( 4 ) = − 2 (1-72) u(0)=0, \quad u(4)=-2\tag{1-72} u(0)=0,u(4)=2(1-72)
做代换 u 1 = u 、 u 2 = u ′ u_1=u 、 u_2=u^{\prime} u1=uu2=u, 写为一阶常微分方程组形式:
{ u 1 ′ = u 2 , u 1 ( 0 ) = 0 u 2 ′ = − ∣ u 1 ∣ , u 1 ( 4 ) = − 2 (1-73) \begin{cases}u_1^{\prime}=u_2, & u_1(0)=0 \\ u_2^{\prime}=-\left|u_1\right|, & u_1(4)=-2\end{cases}\tag{1-73} {u1=u2,u2=u1,u1(0)=0u1(4)=2(1-73)
将此问题转化为初值问题, 就需要找到一个 m = m n m=m_n m=mn, 使式 (1-74) 的解 u 1 ( x ) u_1(x) u1(x) x = 4 x=4 x=4 处 的值 u 1 ( 4 ) = β n u_1(4)=\beta_n u1(4)=βn 满足 ∣ β n + 2 ∣ < 1 0 − 6 \mid \beta_n+2\mid<10^{-6} βn+2∣<106
{ u 1 ′ = u 2 , u 1 ( 0 ) = 0 u 2 ′ = − ∣ u 1 ∣ , u 2 ( 0 ) = m (1-74) \begin{cases}u_1^{\prime}=u_2, & u_1(0)=0 \\ u_2^{\prime}=-\left|u_1\right|, & u_2(0)=m\end{cases}\tag{1-74} {u1=u2,u2=u1,u1(0)=0u2(0)=m(1-74)
根据打靶法思想, 确定 m m m 取值的流程如下所示

开始
任意选取m=m_1并计算β_1
β_1与β差的绝对值是否小于ε
End
任意选取m=m_2并计算β_2
β_2与β差的绝对值是否小于ε
任意选取m=m_2并计算β_2

相应代码如下:

主程序代码如下

clear ; close all;
n=0; m(1)=1; alpha=0; beta0=-2;
while n==0||abs(beta(n)-beta0)>=1e-6
    n=n+1;
    %在猜测的初始条件下求解初值问题
    [x,usol]=ode45('shoot',[0 4],[alpha m(n)]);
    beta(n)=usol(end,1);
    if n==1
        m(2)=m(1)-0.1;
    else
        %线性插值法修正m的取值
        m(n+1)=m(n-1)+(m(n)-m(n-1))*(beta0-beta(n-1))/(beta(n)-beta(n-1));
    end
end
plot(x,usol(:,1),'LineWidth',1.5), xlabel x, ylabel u

文件 shoot.m 代码如下

function du=shoot(x,u)
du=[u(2); -abs(u(1))];

代码中使用的 m m m 的前两个猜测值为 1 和 0.9 0.9 0.9, 程序仅经过了 5 次循环, 就满足条件 ∣ β 5 + 2 ∣ < 1 0 − 6 \mid \beta_5+2\mid<10^{-6} β5+2∣<106, 得到结果如下图所示。如选取 m m m 的前两个猜测值为-1 和-1.1, 还会得到另 外一个截然不同的解。因为边值问题的解往往不是唯一的, 所求得的解与猜测值的选取有关, 这是边值问题与初值问题的一个很大不同。
边值问题的解

查看程序运行后 m n m_n mn β n \beta_n βn 的前 5 个值, 可发现线性插值法的修正效率还比较令人满意。

>> m(1:5)

ans =

    1.0000    0.9000    2.0480    2.0640    2.0641

>> beta(1:5)

ans =

   -0.9699   -0.8716   -1.9845   -1.9999   -2.0000

1.2.2 bvp 系列函数的用法

与专门针对初值问题的 ode 系列函数类似, Matlab 中还有专门用于解决边值问题的 bvp 系列函数, 其调用语法为:

sol = bvpsolver(odefun, bcfun,solinit,options)

下面对每一项进行说明:

(1) “bvpsolver” 是 bvp 系列函数的名称, 可以是 bvp4c 或 bvp5c, 后者比前者的精度高一些。

(2) “odefun" 是包含常微分方程组的函数句柄, 这与 ode 系列函数中的 odefun 是一样的。

(3) “bcfun" 是包含边界条件的函数句柄。

(4) “solinit”是包含初始网格结点、初始猜测值的结构体, 由 bvpinit 函数生成。

(5) “options”用于改变 bvpsolver 的默认设置, 由 bvpset 函数生成, 为可选项。

(6) “sol"为包含计算结果的结构体。

如不需要用到 options, 则 bvp 系列函数的调用形式为:

sol = bvpsolver(odefun,bcfun,solinit)

用于生成结构体 solinit 的 bvpinit 函数的调用语法为:

solinit=bvpinit(x,uinit,params)

其中:

(1) “ x ”为计算区间内的初始网格结点, 起止点即为边界条件所在的两处位置, 这些结点需要按大小单调排列。

(2) “uinit" 是解的初始猜测值, 也可以是每个结点处的解的猜测值。

(3) “params" 是边值问题中的末知参数 (如果有的话) 的猜测值, 为可选项。

下面举例说明 bvp4c 的用法, 边值问题如下:
{ u ′ ′ = − u + 2 ( x − 1 ) e − x , 0 < x < π u ( 0 ) = 1 , u ( π ) = π / e π − 1 (1-75) \left\{\begin{array}{l} u^{\prime \prime}=-u+2(x-1) \mathrm{e}^{-x}, \quad 0<x<\pi \\ u(0)=1, \quad u(\pi)=\pi / \mathrm{e}^\pi-1 \end{array}\right.\tag{1-75} {u′′=u+2(x1)ex,0<x<πu(0)=1,u(π)=π/eπ1(1-75)
先利用代换 u 1 = u 、 u 2 = u ′ u_1=u 、 u_2=u^{\prime} u1=uu2=u, 化为一阶常微分方程组形式:
{ u 1 ′ = u 2 , u 1 ( 0 ) = 1 u 2 ′ = − u 1 + 2 ( x − 1 ) e − x , u 1 ( π ) = π / e π − 1 (1-76) \begin{cases}u_1^{\prime}=u_2, & u_1(0)=1 \\ u_2^{\prime}=-u_1+2(x-1) \mathrm{e}^{-x}, & u_1(\pi)=\pi / \mathrm{e}^\pi-1\end{cases}\tag{1-76} {u1=u2,u2=u1+2(x1)ex,u1(0)=1u1(π)=π/eπ1(1-76)
将此常微分方程组和边界条件分别写进 shoot 2. m 2 . \mathrm{m} 2.m 和 bc.m 中, 用 bvp4c 求解, 代码如下:

主程序代码如下

clear; close all;
x=linspace(0,pi,20);
solinit=bvpinit(x,[2 2]);
%bvp4c解边值问题
sol=bvp4c(@shoot2,@bc,solinit);
%从结构体sol获取指定位置的数值结果
u=deval(sol,x);
%解析解
u_exact=cos(x)+x.*exp(-x);
%画图
plot(x,u(1,:),'+k',x,u_exact,'MarkerSize',10,'LineWidth',1.5)
set(gca,'Fontsize',16), xlabel x, ylabel u
legend('bvp4c','解析解'), axis([0 pi -1 1.5])

文件 bc.m 代码如下

function res=bc(ua,ub)
%边界条件boundary condition
res=[ua(1)-1; ub(1)+1-pi/exp(pi)];

这里重点说明一下包含边界条件的文件 bc.m, 其中定义了一个同名函数 bc, 参数 uaub 分别代表左边界和右边界的情况。其中, ua(1)ua(2) 为函数在左边界的取值和一阶导数, ub(1)ub(2) 为函数在右边界的取值和一阶导数。代码中的 ua(1)-1 就是 u a ( 1 ) − 1 = 0 u a(1)-1=0 ua(1)1=0 的简写, 代表边界条件 u ( 0 ) = 1 u(0)=1 u(0)=1, 同理, ub(1)+1-pi/exp(pi)表示 u ( π ) = π / e π − 1 u(\pi)=\pi / \mathrm{e}^\pi-1 u(π)=π/eπ1

代码中的初始猜测值为 u 1 = 2 、 u 2 = 2 u_1=2 、 u_2=2 u1=2u2=2, 假如边值问题的解是唯一的, 初始猜测值的选取是不会影响结果的。下图同时显示了 bvp4c 得到的数值解和式 (1-75) 的解析解 u = cos ⁡ ( x ) + x e − x u=\cos (x)+x \mathrm{e}^{-x} u=cos(x)+xex, 二者相当吻合。值得一提的是, 如果在 bvpinit 函数中选取的初始网格结点数量偏少的话, 会造成数值解和解析解存在一定的差异, 在这一点上, bvp4c 比打靶法更难使用。
边值问题的数值解与解析解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

图灵猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值