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

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中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

MySQL数据库双机热备的配置方法详解

《MySQL数据库双机热备的配置方法详解》在企业级应用中,数据库的高可用性和数据的安全性是至关重要的,MySQL作为最流行的开源关系型数据库管理系统之一,提供了多种方式来实现高可用性,其中双机热备(M... 目录1. 环境准备1.1 安装mysql1.2 配置MySQL1.2.1 主服务器配置1.2.2 从

Python版本信息获取方法详解与实战

《Python版本信息获取方法详解与实战》在Python开发中,获取Python版本号是调试、兼容性检查和版本控制的重要基础操作,本文详细介绍了如何使用sys和platform模块获取Python的主... 目录1. python版本号获取基础2. 使用sys模块获取版本信息2.1 sys模块概述2.1.1

Python实现字典转字符串的五种方法

《Python实现字典转字符串的五种方法》本文介绍了在Python中如何将字典数据结构转换为字符串格式的多种方法,首先可以通过内置的str()函数进行简单转换;其次利用ison.dumps()函数能够... 目录1、使用json模块的dumps方法:2、使用str方法:3、使用循环和字符串拼接:4、使用字符

Python版本与package版本兼容性检查方法总结

《Python版本与package版本兼容性检查方法总结》:本文主要介绍Python版本与package版本兼容性检查方法的相关资料,文中提供四种检查方法,分别是pip查询、conda管理、PyP... 目录引言为什么会出现兼容性问题方法一:用 pip 官方命令查询可用版本方法二:conda 管理包环境方法

Linux云服务器手动配置DNS的方法步骤

《Linux云服务器手动配置DNS的方法步骤》在Linux云服务器上手动配置DNS(域名系统)是确保服务器能够正常解析域名的重要步骤,以下是详细的配置方法,包括系统文件的修改和常见问题的解决方案,需要... 目录1. 为什么需要手动配置 DNS?2. 手动配置 DNS 的方法方法 1:修改 /etc/res

深入理解Mysql OnlineDDL的算法

《深入理解MysqlOnlineDDL的算法》本文主要介绍了讲解MysqlOnlineDDL的算法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小... 目录一、Online DDL 是什么?二、Online DDL 的三种主要算法2.1COPY(复制法)

JavaScript对象转数组的三种方法实现

《JavaScript对象转数组的三种方法实现》本文介绍了在JavaScript中将对象转换为数组的三种实用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友... 目录方法1:使用Object.keys()和Array.map()方法2:使用Object.entr

SpringBoot中ResponseEntity的使用方法举例详解

《SpringBoot中ResponseEntity的使用方法举例详解》ResponseEntity是Spring的一个用于表示HTTP响应的全功能对象,它可以包含响应的状态码、头信息及响应体内容,下... 目录一、ResponseEntity概述基本特点:二、ResponseEntity的基本用法1. 创

java中判断json key是否存在的几种方法

《java中判断jsonkey是否存在的几种方法》在使用Java处理JSON数据时,如何判断某一个key是否存在?本文就来介绍三种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目http://www.chinasem.cn录第一种方法是使用 jsONObject 的 has 方法