คำแนะนำสำหรับระเบียบวิธีผลต่างอันตะใน Scientific Python


20

สำหรับโครงการที่ฉันกำลังทำงาน (เป็นไฮเพอร์โบลิก PDE) ฉันต้องการรับการจัดการคร่าวๆเกี่ยวกับพฤติกรรมโดยดูจากตัวเลข อย่างไรก็ตามฉันไม่ใช่โปรแกรมเมอร์ที่ดีมาก

คุณสามารถแนะนำทรัพยากรบางอย่างสำหรับการเรียนรู้วิธีการรหัสชุดรูปแบบความแตกต่างแน่นอนใน Scientific Python ได้อย่างมีประสิทธิภาพ(ยินดีต้อนรับภาษาอื่นที่มีกราฟการเรียนรู้ขนาดเล็ก)

เพื่อให้แนวคิดแก่ผู้ชม (ฉัน) สำหรับคำแนะนำนี้:

  • ฉันเป็นนักคณิตศาสตร์ที่บริสุทธิ์โดยการฝึกอบรมและค่อนข้างคุ้นเคยกับแง่มุมทางทฤษฎีของรูปแบบที่แตกต่างกันแน่นอน
  • สิ่งที่ฉันต้องการความช่วยเหลือคือวิธีทำให้คอมพิวเตอร์คำนวณสิ่งที่ฉันต้องการให้คอมพิวเตอร์คำนวณโดยเฉพาะอย่างยิ่งในวิธีที่ฉันไม่ได้ทำซ้ำความพยายามมากเกินไปที่ผู้อื่นใส่ไว้แล้ว (เพื่อไม่ให้ประดิษฐ์ล้อใหม่เมื่อ มีแพ็คเกจให้ใช้งานแล้ว) (อีกสิ่งหนึ่งที่ฉันต้องการหลีกเลี่ยงคือการเขียนโค้ดด้วยมืออย่างงี่เง่าเมื่อมีการสร้างโครงสร้างข้อมูลที่เหมาะสมกับวัตถุประสงค์)
  • ฉันมีประสบการณ์การเขียนโค้ดบ้าง แต่ฉันไม่มี Python (ดังนั้นฉันไม่รังเกียจหากมีแหล่งข้อมูลที่ดีสำหรับการเรียนรู้ภาษาอื่น [พูดเช่น Octave])
  • หนังสือเอกสารทั้งสองจะมีประโยชน์เช่นเดียวกับคอลเลกชันของรหัสตัวอย่าง

ปัญหาหลักคือฉันไม่รู้ด้วยซ้ำว่าจะเริ่มมองหาที่ใดดังนั้นแม้คำแนะนำพื้นฐานจะมีประโยชน์
Willie Wong

ข้อ จำกัด เป็นเพียงฉันยังไม่คุ้นเคย (กับ) วิธีการปริมาณ จำกัด ; ดังนั้นฉันจะต้องเรียนรู้วิธีการร่วม แน่นอนว่าฉันจะไม่คัดค้านคำตอบเช่นนี้
Willie Wong

PyClawสามารถจัดการคำที่ไม่เป็นเชิงเส้นได้ แต่การเขียนตัวแก้ Riemann ของคุณเองนั้นซับซ้อนโดยเฉพาะในมิติที่ 2 หรือสูงกว่า หากคุณต้องการลองรูปแบบ จำกัด ที่แตกต่างอย่างง่ายด้วยกริดที่มีโครงสร้างตัวเลือกถัดไปของคุณคือการลองใช้บางอย่างในPetsc4py (การเปิดเผย: ฉันมีส่วนเกี่ยวข้องกับโครงการนี้ด้วย) ซึ่งเป็นวัตถุประสงค์ทั่วไปที่มากกว่า เอกสาร
Aron Ahmadia


สวัสดีวิลลี่ (และสำหรับผู้อ่านที่ไม่ได้ดูการแชท) ฉันคิดว่าคุณรู้เรื่องนี้อยู่แล้ว แต่เนื่องจากคุณพูดถึงไฮเพอร์โบลิก PDE คุณน่าจะดีกว่าด้วยวิธีไฟไนต์วอลลุ่ม
Matthew Emmett

คำตอบ:


10

นี่คือตัวอย่าง 97 บรรทัดของการแก้ PDE หลายตัวแปรอย่างง่ายโดยใช้วิธีผลต่างอันตะ จำกัด โดยProf. David Ketchesonจากที่เก็บ py4sci ที่ฉันดูแล สำหรับปัญหาที่ซับซ้อนมากขึ้นซึ่งคุณต้องจัดการกับแรงกระแทกหรือการอนุรักษ์ในการแยกส่วนแบบ จำกัด ปริมาณผมขอแนะนำให้ดูpyclawซึ่งเป็นชุดซอฟต์แวร์ที่ฉันช่วยพัฒนา

"""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

คุณสามารถดูFenicsซึ่งเป็นกรอบรูปงูใหญ่ / C ซึ่งช่วยให้สมการทั่วไปค่อนข้างจะแก้ไขได้โดยใช้ภาษามาร์กอัปพิเศษ ส่วนใหญ่ใช้องค์ประกอบที่ จำกัด แม้ว่า แต่ควรดู กวดวิชาควรให้การแสดงผลของวิธีการที่ง่ายที่จะสามารถในการแก้ปัญหา


3

ข้อมูลอ้างอิงนี้อาจมีประโยชน์มากสำหรับคุณ นี่เป็นหนังสือเปิดบนอินเทอร์เน็ต ฉันได้เรียนรู้ (ยังคงเรียนรู้) หลามจากหนังสือเล่มนี้ ฉันพบว่ามันเป็นทรัพยากรที่ดีมากอย่างแน่นอน

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

สำหรับการคำนวณเชิงตัวเลขเราควรเลือก 'numpy' อย่างแน่นอน (ตรวจสอบให้แน่ใจว่าคุณเข้าใจ 'อาเรย์' และ 'เมทริกซ์' และ 'รายการ' อย่างถูกต้อง) (อ้างอิงเอกสารคู่มือ numpy สำหรับเรื่องนั้น)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.