Khuyến nghị về phương pháp khác biệt hữu hạn trong Python khoa học


20

Đối với một dự án tôi đang thực hiện (trong các PDE hyperbol) tôi muốn có một số xử lý thô đối với hành vi bằng cách xem xét một số số. Tôi, tuy nhiên, không phải là một lập trình viên rất tốt.

Bạn có thể giới thiệu một số tài nguyên cho việc học cách mã hóa hiệu quả các sơ đồ sai phân hữu hạn trong Khoa học Python (các ngôn ngữ khác có đường cong học tập nhỏ cũng được chào đón) không?

Để cung cấp cho bạn ý tưởng của khán giả (tôi) cho đề xuất này:

  • Tôi là một nhà toán học thuần túy được đào tạo, và có phần quen thuộc với các khía cạnh lý thuyết của các sơ đồ sai phân hữu hạn
  • Điều tôi cần giúp đỡ là làm thế nào để máy tính tính toán những gì tôi muốn nó tính toán, đặc biệt là theo cách mà tôi không sao chép quá nhiều nỗ lực đã được người khác bỏ ra (để không phát minh lại bánh xe khi một gói đã có sẵn). (Một điều khác tôi muốn tránh là ngu ngốc mã hóa thứ gì đó bằng tay khi có các cấu trúc dữ liệu được thiết lập phù hợp với mục đích.)
  • Tôi đã có một số kinh nghiệm mã hóa; nhưng tôi không có gì trong Python (do đó tôi không phiền nếu có tài nguyên tốt để học một ngôn ngữ khác [ví dụ, ví dụ như Octave]).
  • Sách, tài liệu đều hữu ích, cũng như các bộ sưu tập mã ví dụ.

Vấn đề chính là tôi thậm chí không biết bắt đầu tìm kiếm ở đâu: vì vậy ngay cả những gợi ý cơ bản cũng sẽ hữu ích.
Willie Wong

Hạn chế chỉ là tôi chưa (chưa) quen thuộc với các phương pháp thể tích hữu hạn; vì vậy tôi sẽ phải học phương pháp kết hợp. Tôi sẽ không phản đối một câu trả lời như vậy, tất nhiên.
Willie Wong

PyClaw có thể xử lý các thuật ngữ nguồn phi tuyến, nhưng việc viết bộ giải Riemann của riêng bạn sẽ rất phức tạp, đặc biệt là ở kích thước thứ 2 trở lên. Nếu bạn muốn thử một sơ đồ phân biệt hữu hạn đơn giản với các lưới có cấu trúc, tùy chọn tiếp theo của bạn sẽ là thử một cái gì đó trong petc4py , (Tiết lộ: Tôi cũng liên kết với dự án này), đó là mục đích chung hơn và cũng không tốt- tài liệu.
Aron Ahmadia


Xin chào Willie (và đối với những độc giả chưa xem cuộc trò chuyện), tôi nghĩ bạn đã biết điều này, nhưng vì bạn đã đề cập đến các PDE hyperbol có lẽ bạn sẽ tốt hơn với phương pháp âm lượng hữu hạn.
Matthew Emmett

Câu trả lời:


10

Dưới đây là một ví dụ 97 dòng về việc giải quyết PDE đa biến đơn giản bằng các phương pháp sai phân hữu hạn, được đóng góp bởi Giáo sư David Ketcheson , từ kho lưu trữ py4sci tôi duy trì. Đối với các vấn đề phức tạp hơn mà bạn cần xử lý các cú sốc hoặc bảo tồn trong sự rời rạc khối lượng hữu hạn, tôi khuyên bạn nên xem pyclaw , một gói phần mềm mà tôi giúp phát triển.

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

Bạn có thể có một cái nhìn về Fenics , đó là một framwork python / C cho phép giải các phương trình khá chung bằng một ngôn ngữ đánh dấu đặc biệt. Nó chủ yếu sử dụng các yếu tố hữu hạn mặc dù, nhưng đáng xem. Các hướng dẫn nên cung cấp cho bạn một ấn tượng về cách dễ dàng có thể để giải quyết vấn đề.


3

Tài liệu tham khảo này có thể rất hữu ích cho bạn. Đây là một cuốn sách mở trên internet. Tôi đã học (vẫn đang học), python từ cuốn sách này. Tôi tìm thấy nó thực sự rất tốt tài nguyên.

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

Để tính toán bằng số, người ta chắc chắn nên sử dụng 'numpy'. (chỉ cần đảm bảo rằng bạn đã hiểu đúng về 'mảng' và 'ma trận' và 'danh sách') (tham khảo tài liệu numpy cho điều đó)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.