Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Math 周期边界条件-有限差分_Math_Fortran_Fortran90_Numerical Methods_Pde - Fatal编程技术网

Math 周期边界条件-有限差分

Math 周期边界条件-有限差分,math,fortran,fortran90,numerical-methods,pde,Math,Fortran,Fortran90,Numerical Methods,Pde,嗨,我下面有一个解决非线性耦合偏微分方程的代码。但是,我需要实现周期性边界条件。周期性边界条件困扰着我,我应该在代码中添加什么来强制执行周期性边界条件?根据以下模块化算术建议进行更新 注意,t>=0,x在区间[0,1]内。下面是我提供代码的耦合方程 其中a,b>0 这些是初始条件,但现在我需要施加周期性边界条件。它们可以用数学的形式表示为u(0,t)=u(1,t)和du(0,t)/dx=du(1,t)/dx,对于f(x,t)也是如此。边界条件的du/dx实际上是偏导数 我的代码在下面 prog

嗨,我下面有一个解决非线性耦合偏微分方程的代码。但是,我需要实现周期性边界条件。周期性边界条件困扰着我,我应该在代码中添加什么来强制执行周期性边界条件?根据以下模块化算术建议进行更新

注意,t>=0,x在区间[0,1]内。下面是我提供代码的耦合方程

其中a,b>0

这些是初始条件,但现在我需要施加周期性边界条件。它们可以用数学的形式表示为u(0,t)=u(1,t)和du(0,t)/dx=du(1,t)/dx,对于f(x,t)也是如此。边界条件的du/dx实际上是偏导数

我的代码在下面

program coupledPDE 

integer, parameter :: n = 10, A = 20 
real, parameter :: h = 0.1, k = 0.05 
real, dimension(0:n-1) :: u,v,w,f,g,d 
integer:: i,m 
real:: t, R, x,c1,c2,c3,aa,b 

R=(k/h)**2.
aa=2.0
b=1.0
c1=(2.+aa*k**2.-2.0*R)/(1+k/2.)
c2=R/(1.+k/2.)
c3=(1.0-k/2.)/(1.0+k/2.)
c4=b*k**2./(1+k/2.)


do i = 0,n-1 !loop over all space points except 0 and n
  x = real(i)*h    
  w(i) = z(x)  !u(x,0)
  d(i) = z(x)  !f(x,0)
end do


do i=0,n-1
  ip=mod(i+1,n)
  il=modulo(i-1,n)
  v(i) = (c1/(1.+c3))*w(i) + (c2/(1.+c3))*(w(ip)+w(il)) -(c4/(1.+c3))*w(i)*((w(i))**2.+(d(i))**2.)    !\partial_t u(x,0)=0
  g(i) = (c1/(1.+c3))*d(i) + (c2/(1.+c3))*(d(ip)+d(il)) -(c4/(1.+c3))*d(i)*((w(i))**2.+(d(i))**2.)    !\partial_t f(x,0)=0
end do

do m=1,A 

   do i=0,n-1
       ip=mod(i+1,n)
       il=modulo(i-1,n)
       u(i)=c1*v(i)+c2*(v(ip)+v(il))-c3*w(i)-c4*v(i)*((v(i))**2.+(g(i))**2.) 
       f(i)=c1*g(i)+c2*(g(ip)+g(il))-c3*d(i)-c4*g(i)*((v(i))**2.+(g(i))**2.) 
   end do 
     print*, "the values of u(x,t+k) for all m=",m
   print "(//3x,i5,//(3(3x,e22.14)))",m,u   

  do i=0,n-1
   w(i)=v(i)
   v(i)=u(i)
   d(i)=g(i)
   t=real(m)*k
   x=real(i)*k
  end do

end do


end program coupledPDE

function z(x)
real, intent(in) :: x
real :: pi
pi=4.0*atan(1.0)
z = sin(pi*x)
end function z

感谢阅读,如果我需要以更恰当的方式重新编排我的问题,请让我知道

PDE离散化中边界条件的一种选择是使用重影(光晕)单元(网格点)。对于周期边界条件,它可能不是最聪明的方法,但它可以用于所有其他边界条件类型

因此,将数组声明为

real, dimension(-1:n) :: u,v,w,f,g,d
但你只能在点0..n-1(点n与点0相同)中求解偏微分方程。您也可以从1..n开始,并从0..n+1声明数组

然后你开始

 u(-1) = u(n-1)

所有其他阵列也是如此

在每个时间步骤中,您都会为
u
f
或在解决方案期间修改的所有其他字段再次设置此选项:

do m=1,A 
   u(-1) = u(n-1)
   u(n) = u(0)
   f(-1) = f(n-1)
   f(n) = f(0)

   do i=0,n-1 !Discretization equation for all times after the 1st step
       u(i)=...
       f(i)=...
   end do 
end do

以上假设了显式时间离散化和有限差分空间离散化,并假设
x(0)=0
x(n)=1
是您的边界点。

PDE离散化中边界条件的一个选项是使用重影(光晕)单元(网格点)。对于周期边界条件,它可能不是最聪明的方法,但它可以用于所有其他边界条件类型

因此,将数组声明为

real, dimension(-1:n) :: u,v,w,f,g,d
但你只能在点0..n-1(点n与点0相同)中求解偏微分方程。您也可以从1..n开始,并从0..n+1声明数组

然后你开始

 u(-1) = u(n-1)

所有其他阵列也是如此

在每个时间步骤中,您都会为
u
f
或在解决方案期间修改的所有其他字段再次设置此选项:

do m=1,A 
   u(-1) = u(n-1)
   u(n) = u(0)
   f(-1) = f(n-1)
   f(n) = f(0)

   do i=0,n-1 !Discretization equation for all times after the 1st step
       u(i)=...
       f(i)=...
   end do 
end do

以上假设了显式时间离散化和有限差分空间离散化,并假设
x(0)=0
x(n)=1
是您的边界点。

只需在每个时间步中复制从n到0和从1到n+1的值。仅此而已。只声明网格
0,h,2h,…,1-h
上的所有内容,然后使用一些简单的模运算来移动索引,肯定会更干净。周期性边界将自动处理。更好的方法是使用整个阵列和
CSHIFT
功能。@VladimirF感谢您的帮助,但我不明白您的意思。我在哪里复制这些值,你指的是什么值?我会在开始时间循环时添加代码,还是?(我理解这是一个非常简单的想法来实现,很抱歉我这边的混乱)。再次感谢@俄罗斯科学基金会也感谢您的回复。我如何在网格上声明它?我真的很难理解如何做到这一点。感谢您的帮助,只需将所有数组声明为
v[0:n-1]
等。在循环中计算
ip=mod(i+1,n)
并将对
i+1
的引用替换为
ip
。类似于
i-1
。如果将循环定义为
doi=0,则n-1
一切都会自然处理。如果您确实需要x=1处的值,则只需在执行
i
循环后从x=0处复制该值。只需在每个时间步中将值从n复制到0,从1复制到n+1即可。仅此而已。只声明网格
0,h,2h,…,1-h
上的所有内容,然后使用一些简单的模运算来移动索引,肯定会更干净。周期性边界将自动处理。更好的方法是使用整个阵列和
CSHIFT
功能。@VladimirF感谢您的帮助,但我不明白您的意思。我在哪里复制这些值,你指的是什么值?我会在开始时间循环时添加代码,还是?(我理解这是一个非常简单的想法来实现,很抱歉我这边的混乱)。再次感谢@俄罗斯科学基金会也感谢您的回复。我如何在网格上声明它?我真的很难理解如何做到这一点。感谢您的帮助,只需将所有数组声明为
v[0:n-1]
等。在循环中计算
ip=mod(i+1,n)
并将对
i+1
的引用替换为
ip
。类似于
i-1
。如果将循环定义为
doi=0,则n-1
一切都会自然处理。如果你真的需要x=1的值,那么在你
i
循环之后从x=0复制这个值就行了。非常感谢你的帮助!在我进一步发表评论之前,我需要仔细考虑所有这些问题,并加以实施。我稍后会回来。我画了一张网格图,现在我明白你的意思了,为什么u(-1)=u(n-1)和u(n)=u(0),所以我知道你为什么改变数组的维数。这很有帮助!对于两个离散化循环,我在所有变量u、f、v、g上实现了这些条件。最后,当我在每个时间步打印出我的解决方案时,现在我看到第1个和第11个值实际上是相同的!谢谢你的详细解释,如果我做错了什么,请告诉我。我有一个问题,这种方法在更高的空间维度上仍然稳定/推荐吗?谢谢@积分我个人在3D CFD计算中使用这种方法。优点是您的计算语句更简单,而且在任何地方都是相同的。缺点是您必须经常复制边界,而隐式方法会更加复杂。另一个o