偏微分方程算法之二阶双曲型方程紧差分方法

2024-04-22 16:36

本文主要是介绍偏微分方程算法之二阶双曲型方程紧差分方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、研究目标

二、理论推导

三、算例实现


一、研究目标

        前面我们已经介绍了二阶双曲型方程显式、隐式差分格式,可否像抛物型方程一样,构建更高精度的差分格式。接下来我们介绍紧差分格式。这里继续以非齐次二阶双曲型偏微分方程的初边值问题为研究对象:

\left\{\begin{matrix} \frac{\partial^{2}u(x,t)}{\partial t^{2}}-a^{2}\frac{\partial^{2}u(x,t)}{\partial x^{2}}=f(x,t),0<x<1,0<t\leqslant T,\\ u(x,0)=\varphi(x),\frac{\partial u}{\partial t}(x,0)=\Psi(x),0\leqslant x\leqslant 1,\space\space(1)\\ u(0,t)=\alpha(t),u(1,t)=\beta(t),0<t\leqslant T \end{matrix}\right.

公式(1)中u表示一个与时间t和位置x有关的待求波函数,\varphi(x),\Psi(x),\alpha(t),\beta(t)及方程右端项函数f(x,t)都是已知函数,a,T是非零常数。

二、理论推导

        第一步:网格剖分。对矩形求解域0\leqslant x\leqslant 1,0\leqslant t\leqslant T进行等距剖分,即

x_{j}=jh(j=0,1,\cdot\cdot\cdot,m),t_{k}=k\tau(k=0,1,\cdot\cdot\cdot,n)

        第二步:弱化原方程。将原来的连续方程离散到网格节点上成立,得到离散方程:

\left\{\begin{matrix} \frac{\partial^{2}u}{\partial t^{2}}|_{(x_{j},t_{k})}-a^{2}\frac{\partial ^{2}u}{\partial x^{2}}|_{(x_{j},t_{k})}=f(x_{j},t_{k}),0<j<m,0<k\leqslant n,\\ u(x_{j},t_{0})=\varphi(x_{j}),\frac{\partial u}{\partial t}(x_{j},t_{0})=\Psi(x_{j}),0\leqslant j\leqslant m,\space\space(2)\\ u(x_{0},t_{k})=\alpha(t_{k}),u(x_{m},t_{k})=\beta(t_{k}),1\leqslant k\leqslant n \end{matrix}\right.

        第三步:对偏导数进行更高精度近似。由泰勒公式(固定时间t不变):

u(x_{j-1},t_{k})=(u-h\frac{\partial u}{\partial x}+\frac{h^{2}}{2}\frac{\partial ^{2}u}{\partial x^{2}}-\frac{h^{3}}{6}\frac{\partial^{3}u}{\partial x^{3}}+\frac{h^{4}}{24}\frac{\partial^{4}u}{\partial x^{4}}-\frac{h^{5}}{120}\frac{\partial^{5}u}{\partial x^{5}})|_{(x_{j},t_{k})}+O(h^{6})

u(x_{j+1},t_{k})=(u+h\frac{\partial u}{\partial x}+\frac{h^{2}}{2}\frac{\partial ^{2}u}{\partial x^{2}}+\frac{h^{3}}{6}\frac{\partial^{3}u}{\partial x^{3}}+\frac{h^{4}}{24}\frac{\partial^{4}u}{\partial x^{4}}+\frac{h^{5}}{120}\frac{\partial^{5}u}{\partial x^{5}})|_{(x_{j},t_{k})}+O(h^{6})

将上面两式相加可得

u(x_{j+1},t_{k})-2u(x_{j},t_{k})+u(x_{j-1},t_{k})=h^{2}\frac{\partial^{2}u}{\partial x^{2}}|_{(x_{j},t_{k})}+\frac{h^{4}}{12}\frac{\partial^{4}u}{\partial x^{4}}|_{(x_{j},t_{k})}+O(h^{6})

有           \frac{\partial^{2}u}{\partial x^{2}}|_{(x_{j},t_{k})}=\frac{u(x_{j+1},t_{k})-2u(x_{j},t_{k})+u(x_{j-1},t_{k})}{h^{2}}-\frac{h^{2}}{12}\frac{\partial^{4}u}{\partial x^{4}}|_{(x_{j},t_{k})}+O(h^{4})

类似的有

\frac{\partial^{2}u}{\partial x^{2}}|_{(x_{j},t_{k-1})}=\frac{u(x_{j+1},t_{k-1})-2u(x_{j},t_{k-1})+u(x_{j-1},t_{k-1})}{h^{2}}-\frac{h^{2}}{12}\frac{\partial^{4}u}{\partial x^{4}}|_{(x_{j},t_{k-1})}+O(h^{4})

\frac{\partial^{2}u}{\partial x^{2}}|_{(x_{j},t_{k+1})}=\frac{u(x_{j+1},t_{k+1})-2u(x_{j},t_{k+1})+u(x_{j-1},t_{k+1})}{h^{2}}-\frac{h^{2}}{12}\frac{\partial^{4}u}{\partial x^{4}}|_{(x_{j},t_{k+1})}+O(h^{4})

将上面两式相加后除以2得

\frac{1}{2}(\frac{\partial^{2}u}{\partial x^{2}}|_{(x_{j},t_{k-1})}+\frac{\partial^{2}u}{\partial x^{2}}|_{(x_{j},t_{k+1})})=\frac{u(x_{j+1},t_{k-1})-2u(x_{j},t_{k-1})+u(x_{j-1},t_{k+1})}{2h^{2}}+\frac{u(x_{j+1},t_{k+1})-2u(x_{j},t_{k+1})+u(x_{j-1},t_{k+1})}{2h{^{2}}}-\frac{h^{2}}{12}\frac{1}{2}(\frac{\partial^{4}u}{\partial x^{4}}|_{(x_{j},t_{k-1})}+\frac{\partial ^{4}u}{\partial x^{4}}|_{(x_{j},t_{k+1})})+O(h^{4})

从而         \frac{\partial^{2}u}{\partial x^{2}}|_{(x_{j},t_{k})}+O(\tau^{2})=\frac{u(x_{j+1},t_{k-1})-2u(x_{j},t_{k-1})+u(x_{j-1},t_{k-1})}{2h^{2}}+\frac{u(x_{j+1},t_{k+1})-2u(x_{j},t_{_{k+1}})+u(x_{j-1},t_{k+1})}{2h^{2}}-\frac{h^{2}}{12}\frac{\partial^{4}u}{\partial x^{4}}|_{(x_{j},t_{k})}+O(h^{4}+\tau^{2}h^{2}) \space\space(3)

现令

D=u(x_{j+1},t_{k-1})-2u(x_{j},t_{k-1})+u(x_{j-1},t_{k-1})+u(x_{j+1},t_{k+1})-2u(x_{j},t_{k+1})+u(x_{j-1},t_{k+1})\frac{\partial^{2}u}{\partial x^{2}}=v(x,t)

则公式(3)可写作

v(x_{j},t_{k})=\frac{D}{2h^{2}}-\frac{h^{2}}{12}\frac{\partial^{2}v}{\partial x^{2}}|_{(x_{j},t_{k})}+O(\tau^{2}h^{2}+h^{4}+\tau^{2})

=\frac{D}{2h^{2}}-\frac{h^{2}}{12}\frac{v(x_{j+1},t_{k})-2v(x_{j},t_{k})+v(x_{j-1},t_{k})}{h^{2}}+O(\tau^{2}h^{2}+h^{4}+\tau^{2})

整理可得

\frac{v(x_{j+1},t_{k})+10v(x_{j},t_{k})+v(x_{j-1},t_{k})}{12}=\frac{D}{2h^{2}}+O(\tau^{2}h^{2}+h^{4}+\tau^{2})\space\space\space\space(4)

        由于原双曲型方程为\frac{\partial^{2}u}{\partial t^{2}}-a^{2}v(x,t)=f(x,t),也即v(x,t)=\frac{1}{a^{2}}(\frac{\partial^{2}u}{\partial t^{2}}-f(x,t))

        公式(4)可改写为

\frac{1}{12a^{2}}(\frac{\partial^{2}u}{\partial t^{2}}|_{(x_{j-1},t_{k})}-f(x_{j-1},t_{k})+10\frac{\partial^{2}u}{\partial t^{2}}|_{(x_{j},t_{k})}-10f(x_{j},t_{k})+\frac{\partial^{2}u}{\partial t^{2}}|_{(x_{j+1},t_{k})}-f(x_{j+1},t_{k}))=\frac{D}{2h^{2}}+O(\tau^{2}h^{2}+h^{4}+\tau^{2})

再利用中心差商近似

\frac{1}{12a^{2}}(\frac{u(x_{j-1},t_{k+1})-2u(x_{j-1},t_{k})+u(x_{j-1},t_{k-1})}{\tau^{2}}-f(x_{j-1},t_{k})+10\frac{u(x_{j},t_{k+1})-2u(x_{j},t_{k})+u(x_{j},t_{k-1})}{\tau^{2}}-10f(x_{j},t_{k})+\frac{u(x_{j+1},t_{k+1})-2u(x_{j+1},t_{k}+u(x_{j+1},t_{k-1}))}{\tau^{2}}-f(x_{j+1},t_{k}))=\frac{D}{2h^{2}}+O(\tau^{2}h^{2}+h^{4}+\tau^{2})

        上式中用数值解代替精确解并忽略高阶项,可得

\frac{1}{12a^{2}\tau^{2}}(u^{k+1}_{j-1}-2u^{k}_{j-1}+u^{k+1}_{j-1}+10(u^{k+1}_{j}-2u^{k}_{j}+u^{k-1}_{j})+u^{k+1}_{j+1}-2u^{k}_{j+1}+u^{k-1}_{j+1})=\frac{1}{2}h^{2}(u^{k-1}_{j+1}-2u^{k-1}_{j}+u^{k-1}_{j-1}+u^{k+1}_{j-1}-2u^{k+1}_{j}+u^{k+1}_{j-1})+\frac{1}{12a^{2}}(f^{k}_{j+1}+10f^{k}_{j}+f^{k}_{j-1})

其中,f^{k}_{l}=f(x_{l},t_{k}),l=j-1,j,j+1

        联合初边值条件,可得到以下紧差分格式:

\left\{\begin{matrix} (6r-1)u^{k+1}_{j-1}+(10+12r)u^{k+1}_{j}+(1-6r)u^{k+1}_{j+1}=(6r-1)u^{k-1}_{j-1}-(12r+10)u^{k-1}_{j}+(6r-1)u^{k-1}_{j+1}+\\2(u^{k}_{j-1}+10u^{k}_{j}+u^{k}_{j+1})+\tau^{2}(f^{k}_{j-1}+10f^{k}_{j}+f^{k}_{j+1}),1\leqslant i\leqslant m-1,1\leqslant k\leqslant n-1,\\ u^{0}_{j}=\varphi(_{j}),0\leqslant j\leqslant m,\\ u^{1}_{j}=(ru^{0}_{j-1}+2(1-r)u^{0}_{j}+ru^{0}_{j+1}+\tau^{2}f(x_{j},t_{0})+2\tau\Psi(x_{j}))/2,1\leqslant j\leqslant m-1,\\ u^{k}_{0}=\alpha(t_{k}),u^{k}_{m}=\beta(t_{k}),1\leqslant k\leqslant n \end{matrix}\right.

        其中r=a^{2}\tau^{2}/h^{2}>0,局部截断误差为O(\tau^{2}+h^{4}),关于时间t是二阶的,关于空间x是四阶的。

三、算例实现

        紧差分格式计算双曲型偏微分方程初边值问题:

\left\{\begin{matrix} \frac{\partial^{2}u(x,t)}{\partial t^{2}}-\frac{\partial^{2}u(x,t)}{\partial x^{2}}=2e^{t}sinx,0<x<\pi,0<t\leqslant 1,\\ u(x,0)=sinx,\frac{\partial u}{\partial t}(x,0)=sinx,0\leqslant x\leqslant \pi,\\ u(0,t)=0,u(\pi,t)=0,0<t\leqslant 1 \end{matrix}\right.

已知其精确解为u(x,t)=e^{t}sinx。分别取步长为\tau_{1}=1/50,h_{1}=\pi/200\tau_{1}=1/100,h_{1}=\pi/400,给出节点(\frac{i\pi}{10},\frac{4}{5}),i=1,\cdot\cdot\cdot,5处的数值解和误差。

代码如下:


#include <cmath>
#include <stdlib.h>
#include <stdio.h>int main(int argc, char* argv[])
{int i,j,k,m,n;double a,h,r,tau,pi,c1,c2;double *x,*t,**u,*a1,*b,*c,*d,*ans;double phi(double x);double ddphi(double x);double psi(double x);double alpha(double t);double beta(double t);double f(double x, double t);double exact(double x, double t);double *chase_algorithm(double *a, double *b, double *c, double *d, int n);m=200;n=50;a=1.0;pi=3.14159265359;h=pi/m;tau=1.0/n;r=a*tau/h;r=r*r;printf("r=%.4f.\n",r);x=(double*)malloc(sizeof(double)*(m+1));for(i=0;i<=m;i++)x[i]=i*h;t=(double*)malloc(sizeof(double)*(n+1));for(k=0;k<=n;k++)t[k]=k*tau;u=(double **)malloc(sizeof(double*)*(m+1));for(i=0;i<=m;i++)u[i]=(double*)malloc(sizeof(double)*(n+1));for(i=0;i<=m;i++)u[i][0]=phi(x[i]);for(k=1;k<=n;k++){u[0][k]=alpha(t[k]);u[m][k]=beta(t[k]);}for(i=1;i<m;i++)u[i][1]=(r*u[i-1][0]+2*(1-r)*u[i][0]+r*u[i+1][0]+tau*tau*f(x[i],t[0])+2*tau*psi(x[i]))/2.0;a1=(double*)malloc(sizeof(double)*(m-1));b=(double*)malloc(sizeof(double)*(m-1));c=(double*)malloc(sizeof(double)*(m-1));d=(double*)malloc(sizeof(double)*(m-1));ans=(double*)malloc(sizeof(double)*(m-1));c1=1.0-6*r;c2=10.0+12*r;for(k=1;k<n;k++){for(i=1;i<m;i++){d[i-1]=(-c1)*(u[i-1][k-1]+u[i+1][k-1])-c2*u[i][k-1]+2*(u[i-1][k]+10*u[i][k]+u[i+1][k])+tau*tau*(f(x[i-1],t[k])+10*f(x[i],t[k])+f(x[i+1],t[k]));a1[i-1]=c1;b[i-1]=c2;c[i-1]=a1[i-1];}d[0]=d[0]-c1*u[0][k+1];d[m-2]=d[m-2]-c1*u[m][k+1];ans=chase_algorithm(a1,b,c,d,m-1);for(i=0;i<m-1;i++)u[i+1][k+1]=ans[i];}free(ans);k=4*n/5;j=m/10;for(i=j;i<=m/2;i=i+j)printf("(x,t)=(%.2f,%.2f),y=%f,error=%.4e.\n",x[i],t[k],u[i][k],fabs(u[i][k]-exact(x[i],t[k])));free(a1);free(b);free(c);free(d);free(x);free(t);return 0;
}double phi(double x)
{return sin(x);
}
double psi(double x)
{return sin(x);
}
double alpha(double t)
{return 0.0;
}
double beta(double t)
{return 0.0;
}
double f(double x, double t)
{return 2*sin(x)*exp(t);
}
double exact(double x, double t)
{return sin(x)*exp(t);
}
double *chase_algorithm(double *a, double *b, double *c, double *d, int n)
{int i;double *ans,*g,*w,p;ans=(double*)malloc(sizeof(double)*n);g=(double*)malloc(sizeof(double)*n);w=(double*)malloc(sizeof(double)*n);;g[0]=d[0]/b[0];w[0]=c[0]/b[0];for(i=1;i<n;i++){p=b[i]-a[i]*w[i-1];g[i]=(d[i]-a[i]*g[i-1])/p;w[i]=c[i]/p;}ans[n-1]=g[n-1];i=n-2;do{ans[i]=g[i]-w[i]*ans[i+1];i=i-1;}while(i>=0);free(g);free(w);return ans;
}

\tau_{1}=1/50,h_{1}=\pi/200时,计算结果如下:

r=1.6211.
(x,t)=(0.31,0.80),y=0.687686,error=4.3538e-05.
(x,t)=(0.63,0.80),y=1.308057,error=8.2815e-05.
(x,t)=(0.94,0.80),y=1.800386,error=1.1398e-04.
(x,t)=(1.26,0.80),y=2.116481,error=1.3400e-04.
(x,t)=(1.57,0.80),y=2.225400,error=1.4089e-04.

\tau_{1}=1/100,h_{1}=\pi/400时,计算结果如下:

r=0.4053.
(x,t)=(0.31,0.80),y=0.687727,error=2.7423e-06.
(x,t)=(0.63,0.80),y=1.308135,error=5.2162e-06.
(x,t)=(0.94,0.80),y=1.800493,error=7.1794e-06.
(x,t)=(1.26,0.80),y=2.116607,error=8.4399e-06.
(x,t)=(1.57,0.80),y=2.225532,error=8.8743e-06.

        从计算结果可知,当时间步长减小为原来的1/4、空间步长减小为原来的1/2时,误差减小为原来的1/16。

这篇关于偏微分方程算法之二阶双曲型方程紧差分方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/926292

相关文章

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

判断PyTorch是GPU版还是CPU版的方法小结

《判断PyTorch是GPU版还是CPU版的方法小结》PyTorch作为当前最流行的深度学习框架之一,支持在CPU和GPU(NVIDIACUDA)上运行,所以对于深度学习开发者来说,正确识别PyTor... 目录前言为什么需要区分GPU和CPU版本?性能差异硬件要求如何检查PyTorch版本?方法1:使用命

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义

SpringMVC 通过ajax 前后端数据交互的实现方法

《SpringMVC通过ajax前后端数据交互的实现方法》:本文主要介绍SpringMVC通过ajax前后端数据交互的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价... 在前端的开发过程中,经常在html页面通过AJAX进行前后端数据的交互,SpringMVC的controll

Java中的工具类命名方法

《Java中的工具类命名方法》:本文主要介绍Java中的工具类究竟如何命名,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Java中的工具类究竟如何命名?先来几个例子几种命名方式的比较到底如何命名 ?总结Java中的工具类究竟如何命名?先来几个例子JD

Spring Security自定义身份认证的实现方法

《SpringSecurity自定义身份认证的实现方法》:本文主要介绍SpringSecurity自定义身份认证的实现方法,下面对SpringSecurity的这三种自定义身份认证进行详细讲解,... 目录1.内存身份认证(1)创建配置类(2)验证内存身份认证2.JDBC身份认证(1)数据准备 (2)配置依

python获取网页表格的多种方法汇总

《python获取网页表格的多种方法汇总》我们在网页上看到很多的表格,如果要获取里面的数据或者转化成其他格式,就需要将表格获取下来并进行整理,在Python中,获取网页表格的方法有多种,下面就跟随小编... 目录1. 使用Pandas的read_html2. 使用BeautifulSoup和pandas3.

Spring 中的循环引用问题解决方法

《Spring中的循环引用问题解决方法》:本文主要介绍Spring中的循环引用问题解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录什么是循环引用?循环依赖三级缓存解决循环依赖二级缓存三级缓存本章来聊聊Spring 中的循环引用问题该如何解决。这里聊

Java学习手册之Filter和Listener使用方法

《Java学习手册之Filter和Listener使用方法》:本文主要介绍Java学习手册之Filter和Listener使用方法的相关资料,Filter是一种拦截器,可以在请求到达Servl... 目录一、Filter(过滤器)1. Filter 的工作原理2. Filter 的配置与使用二、Listen

Pandas统计每行数据中的空值的方法示例

《Pandas统计每行数据中的空值的方法示例》处理缺失数据(NaN值)是一个非常常见的问题,本文主要介绍了Pandas统计每行数据中的空值的方法示例,具有一定的参考价值,感兴趣的可以了解一下... 目录什么是空值?为什么要统计空值?准备工作创建示例数据统计每行空值数量进一步分析www.chinasem.cn处