Raccomandazione per il metodo delle differenze finite in Pitone scientifico


20

Per un progetto a cui sto lavorando (in PDE iperbolici), vorrei ottenere una visione approssimativa del comportamento osservando alcuni numeri. Non sono tuttavia un ottimo programmatore.

Puoi consigliare alcune risorse per imparare a codificare in modo efficace schemi di differenze finite in Scientific Python (sono benvenute anche altre lingue con una piccola curva di apprendimento)?

Per darti un'idea del pubblico (io) per questa raccomandazione:

  • Sono un puro matematico di formazione e ho una certa familiarità con gli aspetti teorici degli schemi delle differenze finite
  • Ciò di cui ho bisogno di aiuto è come fare calcolare il computer ciò che voglio che calcoli, specialmente in modo da non duplicare troppo lo sforzo già fatto da altri (in modo da non reinventare la ruota quando un pacchetto è già disponibile). (Un'altra cosa che vorrei evitare è codificare stupidamente qualcosa a mano quando ci sono strutture di dati stabilite adatte allo scopo.)
  • Ho avuto qualche esperienza di programmazione; ma non ne ho avuti in Python (quindi non mi dispiace se ci sono buone risorse per imparare una lingua diversa [diciamo Octave per esempio]).
  • Libri, documentazione sarebbero entrambi utili, così come raccolte di esempio di codice.

Il problema principale è che non so nemmeno da dove cominciare a cercare: quindi anche i suggerimenti di base sarebbero utili.
Willie Wong,

La restrizione è solo che non ho (ancora) familiarità con i metodi a volume finito; quindi dovrò imparare il metodo insieme. Non vorrei obiettare a tale risposta, ovviamente.
Willie Wong,

PyClaw è in grado di gestire termini di origine non lineari, ma scrivere il proprio solutore Riemann sarebbe complicato, in particolare in seconda o superiore dimensione. Se vuoi provare un semplice schema di differenziazione finita con griglie strutturate, la tua prossima opzione sarebbe quella di provare qualcosa in petsc4py , (Disclosure: sono affiliato anche a questo progetto), che è più generico e non altrettanto- documentata.
Aron Ahmadia,


Ciao Willie (e per i lettori che non hanno guardato la chat), penso che tu lo sappia già, ma dato che hai menzionato i PDE iperbolici probabilmente staresti meglio con un metodo a volume finito.
Matthew Emmett,

Risposte:


10

Ecco un esempio di 97 righe per risolvere un semplice PDE multivariato utilizzando metodi a differenza finita, fornito dal Prof. David Ketcheson , dal repository py4sci che mantengo. Per problemi più complicati in cui è necessario gestire shock o conservazione in una discretizzazione a volume finito, consiglio di guardare pyclaw , un pacchetto software che aiuto a sviluppare.

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

Puoi dare un'occhiata a Fenics , che è un framwork in pitone / C che consente di risolvere equazioni abbastanza generali usando un linguaggio di markup speciale. Tuttavia utilizza principalmente elementi finiti, ma vale la pena dare un'occhiata. Il tutorial dovrebbe darti un'idea di quanto sia facile risolvere i problemi.


3

Questo riferimento potrebbe essere molto utile per te. Questo è un libro aperto su internet. Ho imparato (sto ancora imparando), python da questo libro. L'ho trovato davvero un'ottima risorsa.

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

Per il calcolo numerico, si dovrebbe assolutamente scegliere 'numpy'. (assicurati di aver compreso correttamente 'array' e 'matrix' e 'list') (per questo fai riferimento alla documentazione numpy)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.