2016-03-09 2 views
0

Привет У меня есть код ниже, который решает нелинейные связанные PDE. Однако мне нужно реализовать периодические граничные условия. Периодические граничные условия беспокоят меня, что я должен добавить в свой код для обеспечения периодических граничных условий? Обновлено на основе модульных арифметических предложений ниже.Периодические граничные условия - конечные разности

Примечание: t> = 0 и x находится в интервале [0,1]. Вот спаренные уравнения, ниже я приведу мой код

equations

где а, Ь> 0.

Таковы начальные условия, но теперь мне нужно наложить периодические граничные условия. Они могут быть математически записаны как u (0, t) = u (1, t) и du (0, t)/dx = du (1, t)/dx, то же самое верно для f (x, t). Действительно, du/dx I для граничных условий являются частными производными.

Мой код ниже

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 

Спасибо за чтение, если я переформатировать мой вопрос в более правильном пути, пожалуйста, дайте мне знать.

+2

Просто скопируйте значения от n до 0 и от 1 до n + 1 за каждый шаг времени. Это все. –

+0

Наверняка, это чистое объявление, чтобы объявить все на сетке '0, h, 2h, ..., 1-h', а затем использовать некоторую простую по модулю арифметику для смещения индексов. Периодические границы заботятся автоматически. Еще лучше было бы использовать целые массивы и функцию «CSHIFT». – RussF

+0

@ VladimirF Спасибо за помощь, однако я не понимаю, что вы подразумеваете под этим. Где я копирую эти значения и какие значения вы имеете в виду? Могу ли я добавить код, когда я начну свой цикл времени, или? (Я понимаю, что это действительно простая идея для реализации, извините за путаницу на моем конце). Еще раз спасибо! –

ответ

1

Одним из вариантов граничных условий в дискретизации PDE является использование призрачных (гало) ячеек (точек сетки). Он может быть не самым умным для периодического ВС, но он может использоваться для всех других типов граничных условий.

Таким образом, вы объявлять массивы

real, dimension(-1:n) :: u,v,w,f,g,d 

но решить PDE только в точках 0..n-1 (точка п совпадает с точкой 0). Вы также можете сделать из 1..n и объявить массивы формы 0..n + 1.

Затем вы устанавливаете

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

и

u(n) = u(0) 

и то же самое для всех других массивов.

На каждом временном шаге вы установите снова 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 - ваши граничные точки.

+0

Большое спасибо за помощь! Прежде чем я могу прокомментировать дальше, мне нужно пройти все это и подумать об этом, а также реализовать его. Я вернусь позже. –

+0

Я вытащил изображение сетки, и теперь я понимаю, что вы имеете в виду, почему u (-1) = u (n-1) и u (n) = u (0), поэтому я понимаю, почему вы изменили размеры массива. Это очень полезно! Для двух циклов дискретизации я выполнил эти условия для всех переменных u, f, v, g. Наконец, когда я печатаю свое решение на каждом шаге, теперь я вижу, что действительно первое и 11-е значение одинаковы! Спасибо за подробное объяснение, пожалуйста, дайте мне знать, если я неправильно что-то сделал. У меня есть один вопрос: этот метод все еще стабилен/рекомендуется в более высоких пространственных измерениях? Благодаря! –

+1

@Integrals Я лично использую этот метод в 3D вычислениях CFD. Преимущество заключается в том, что ваши расчетные утверждения проще и одинаковы везде. Недостатком является то, что вам приходится часто копировать границы, и он становится немного более привлекательным для неявных методов. Возможна и другая опция с 'modulo'. Я нахожу, что призрачные клетки более общие. –