Bilimsel Python'da Sonlu Farklar Yöntemi için Tavsiye


20

Üzerinde çalıştığım bir proje için (hiperbolik PDE'lerde) bazı nümeriklere bakarak davranış üzerinde kaba bir tutum elde etmek istiyorum. Ancak ben çok iyi bir programcı değilim.

Scientific Python'da sonlu fark şemalarını etkili bir şekilde kodlamayı öğrenmek için bazı kaynaklar önerebilir misiniz (küçük öğrenme eğrisine sahip diğer diller de hoş geldiniz)?

Bu öneri için size kitle hakkında bir fikir vermek için:

  • Eğitimle saf bir matematikçiyim ve sonlu fark şemalarının teorik yönlerine biraz aşinayım
  • Yardıma ihtiyacım olan şey, özellikle başkaları tarafından zaten harcanan çabanın çoğunu çoğaltmayacağım şekilde, bilgisayarın hesaplamasını istediğim şeyi nasıl hesaplayacağıdır (tekerleği ne zaman yeniden icat etmemek için) bir paket zaten mevcut). (Kaçınmak istediğim başka bir şey, amaca uygun yerleşik veri yapıları olduğunda aptalca bir şeyi elle kodlamaktır.)
  • Bazı kodlama deneyimim oldu; ama Python'da hiç bir şeyim yoktu (bu nedenle farklı bir dil öğrenmek için iyi kaynaklar olup olmadığına aldırmıyorum [örneğin Octave]).
  • Kitaplar, dokümantasyon ve örnek kod koleksiyonları yararlı olacaktır.

Asıl sorun, nereden bakmaya başlayacağımı bile bilmememdir: bu nedenle temel öneriler bile yardımcı olacaktır.
Willie Wong

Kısıtlama sadece (henüz) sınırlı hacim yöntemlerine aşina olmadığımdır; bu yüzden yöntemi birlikte öğrenmem gerekecek. Elbette böyle bir cevaba itiraz etmem.
Willie Wong

PyClaw doğrusal olmayan kaynak terimlerini işleyebilir, ancak kendi Riemann çözücünüzü yazmak özellikle 2. veya daha yüksek boyutlarda karmaşık olacaktır. Yapılandırılmış ızgaralarla basit bir sonlu farklar şeması denemek istiyorsanız, bir sonraki seçeneğiniz petsc4py'de (Açıklama: Bu projeye de bağlıyım) bir şey denemek olacaktır. belgelenmiş.
Aron Ahmadia


Merhaba Willie (ve sohbete bakmayan okuyucular için), bunu zaten biliyorsunuz, ancak hiperbolik PDE'lerden bahsettiğinizden beri muhtemelen sonlu bir hacim yöntemiyle daha iyi olacaksınız.
Matthew Emmett

Yanıtlar:


10

İşte katkıda sonlu farklar yöntemleri kullanarak basit değişkenli PDE çözme bir 97-çizgi örneğidir Prof David Ketcheson gelen py4sci depo ı korumak. Sonlu hacimli bir takdir yetkisinde şok veya korumayı ele almanız gereken daha karmaşık sorunlar için , geliştirmeye yardımcı olduğum bir yazılım paketi olan pyclaw'a bakmanızı tavsiye ederim .

"""Pattern formation code

    Solves the pair of PDEs:
       u_t = D_1 \nabla^2 u + f(u,v)
       v_t = D_2 \nabla^2 v + g(u,v)
"""

import matplotlib
matplotlib.use('TkAgg')
import numpy as np
import matplotlib.pyplot as plt
from scipy.sparse import spdiags,linalg,eye
from time import sleep

#Parameter values
Du=0.500; Dv=1;
delta=0.0045; tau1=0.02; tau2=0.2; alpha=0.899; beta=-0.91; gamma=-alpha;
#delta=0.0045; tau1=0.02; tau2=0.2; alpha=1.9; beta=-0.91; gamma=-alpha;
#delta=0.0045; tau1=2.02; tau2=0.; alpha=2.0; beta=-0.91; gamma=-alpha;
#delta=0.0021; tau1=3.5; tau2=0; alpha=0.899; beta=-0.91; gamma=-alpha;
#delta=0.0045; tau1=0.02; tau2=0.2; alpha=1.9; beta=-0.85; gamma=-alpha;
#delta=0.0001; tau1=0.02; tau2=0.2; alpha=0.899; beta=-0.91; gamma=-alpha;
#delta=0.0005; tau1=2.02; tau2=0.; alpha=2.0; beta=-0.91; gamma=-alpha; nx=150;

#Define the reaction functions
def f(u,v):
    return alpha*u*(1-tau1*v**2) + v*(1-tau2*u);

def g(u,v):
    return beta*v*(1+alpha*tau1/beta*u*v) + u*(gamma+tau2*v);


def five_pt_laplacian(m,a,b):
    """Construct a matrix that applies the 5-point laplacian discretization"""
    e=np.ones(m**2)
    e2=([0]+[1]*(m-1))*m
    h=(b-a)/(m+1)
    A=np.diag(-4*e,0)+np.diag(e2[1:],-1)+np.diag(e2[1:],1)+np.diag(e[m:],m)+np.diag(e[m:],-m)
    A/=h**2
    return A

def five_pt_laplacian_sparse(m,a,b):
    """Construct a sparse matrix that applies the 5-point laplacian discretization"""
    e=np.ones(m**2)
    e2=([1]*(m-1)+[0])*m
    e3=([0]+[1]*(m-1))*m
    h=(b-a)/(m+1)
    A=spdiags([-4*e,e2,e3,e,e],[0,-1,1,-m,m],m**2,m**2)
    A/=h**2
    return A

# Set up the grid
a=-1.; b=1.
m=100; h=(b-a)/m; 
x = np.linspace(-1,1,m)
y = np.linspace(-1,1,m)
Y,X = np.meshgrid(y,x)

# Initial data
u=np.random.randn(m,m)/2.;
v=np.random.randn(m,m)/2.;
plt.hold(False)
plt.pcolormesh(x,y,u)
plt.colorbar; plt.axis('image'); 
plt.draw()
u=u.reshape(-1)
v=v.reshape(-1)

A=five_pt_laplacian_sparse(m,-1.,1.);
II=eye(m*m,m*m)

t=0.
dt=h/delta/5.;
plt.ion()

#Now step forward in time
for k in range(120):
    #Simple (1st-order) operator splitting:
    u = linalg.spsolve(II-dt*delta*Du*A,u)
    v = linalg.spsolve(II-dt*delta*Dv*A,v)

    unew=u+dt*f(u,v);
    v   =v+dt*g(u,v);
    u=unew;
    t=t+dt;

    #Plot every 3rd frame
    if k/3==float(k)/3:
        U=u.reshape((m,m))
        plt.pcolormesh(x,y,U)
        plt.colorbar
        plt.axis('image')
        plt.title(str(t))
        plt.draw()

plt.ioff()

8

Özel bir biçimlendirme dili kullanılarak oldukça genel denklemlerin çözülmesini sağlayan bir python / C çerçevesi olan Fenics'e bakabilirsiniz . Yine de çoğunlukla sonlu elemanlar kullanır, ancak bir göz atmaya değer. Öğretici size o sorunları çözmek için ne kadar kolay olabileceğini bir izlenim vermelidir.


3

Bu referans sizin için çok yararlı olabilir. Bu internette açık bir kitap. Bu kitaptan python öğrendim (hala öğreniyorum). Gerçekten çok iyi bir kaynak buldum.

http://www.openbookproject.net/thinkcs/python/english2e/

Sayısal hesaplama için, Kesinlikle “numpy” ye gitmek gerekir. ('dizi' ve 'matris' ve 'liste' yi doğru anladığınızdan emin olun) (bunun için numpy belgelerine bakın)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.