[Python] Semi-Lagrange-Methode

Ich habe es geschafft, weil es nur wenige Programme im Netz gab, um die Translokationsgleichung zu lösen, und es gab kein methodisiertes, als ich es auf Japanisch und Englisch (oder einem fehlerhaften) suchte.

#https://github.com/christian512/SemiLagPy/blob/master/advection1D.ipynb
#Ich habe darauf hingewiesen.

import numpy as np
import matplotlib.pyplot as plt

class SemiLagrangian1D:
    """
    SemiLagrangian scheme for periodic 1D problems.
    """
    def __init__(self,x,y,u,dt):
        """
        Initizalizes the SemiLagrangian object given initial configuration
        x : x positions (must be equidistant)
        y : variable at all x positions at time t
        u : speed of advection
        dt: time step
        """
        # Check dimensions
        assert x.shape[0] == y.shape[0], "x and y have different length"
        # Get the x stepsize
        dx = x[1] - x[0]
        # check if x is equidistant
        assert x[-1] == x[0] + dx*(x.shape[0]-1), "x array not equidistant"
        # Set class variables
        self.x = x
        self.y = y
        self.u = u
        self.dt = dt
        self.dx = dx

    def cubic_evolve(self,nt=1):
        """
        Propagates the variable using a cubic interpolation scheme.
        nt: number of time stepsize
        """
        # loop through time steps
        for l in range(nt):
            # temporary array
            y_temp = np.zeros(self.y.shape[0])
            # loop through array
            for i in range(self.y.shape[0]):
                # idx left to departure point
                x_dep = self.x[i]-self.u*self.dt
                j = int(np.floor(x_dep/self.dx))
                # alpha
                a = (self.x[i]-self.u*self.dt - j*self.dx)/self.dx
                # calculate next time step
                f = lambda x: x % self.y.shape[0] if x >= self.y.shape[0] else x
                y_temp[i] = - a * (1-a)*(2-a)/6 * self.y[f(j-1)]
                y_temp[i] += (1-a**2)*(2-a)/2 * self.y[f(j)]
                y_temp[i] += a*(1+a)*(2-a)/2 * self.y[f(j+1)]
                y_temp[i] -= a*(1-a**2)/6 * self.y[f(j+2)]
            self.y = np.copy(y_temp)
        return self.y

    def linear_interporation(self,nt=1):
        for l in range(nt):
            # temporary array
            y_tmp = np.zeros(self.y.shape[0])
            for i in range(1,NX-1):
                x_tmp = self.x[0]+i*self.dx
                x_tmp -= self.u*self.dt

                ib = int((x_tmp-self.x[0])/self.dx)
                if ib < 0: ib = 0
                if ib >= len(self.x): ib = NX-2
                distance = (x_tmp - ib*self.dx)/DX

                y_tmp[i] = (1-distance)*self.y[ib]+distance*self.y[ib+1]

        self.y = np.copy(y_tmp)
        return self.y





L = 5 # Domain length
NX = 1000 # Number of grid points
X = np.linspace(0,L,num=NX) # Array of grid points
DX = X[1] - X[0] # spatial grid point distance
DT = 0.01 # time step size
NT = 1000 # number of time steps
CA = (1 + 0.02*np.sqrt(130)) # advection speed
print('Courant= ' + str(CA*DT/DX))

# Sine function
F_ini2 = np.zeros(X.shape[0])
F_ini2[0:int(X.shape[0]/5)] = np.sin(np.pi*X[0:int(X.shape[0]/5)])

# Plotting
# plt.plot(X,F_ini2,label='Sine function')
# plt.legend()
# plt.show()

# Create array for storing evolution of F(x,t)
F_arr = np.zeros([NT,X.shape[0]])
F_arr[0,:] = np.copy(F_ini2)
# Create SemiLagrangian object
sl = SemiLagrangian1D(X,F_arr[0,:],CA,DT)

# Calculate the variable for all time steps using semi-lagrangian
for i in range(1,NT):
    F_arr[i,:] = sl.cubic_evolve(nt=1)
    #F_arr[i,:] = sl.linear_interporation(nt=i)
#ans = sl.linear_interporation(nt=300)

# Plot initial vs. evolution
# print(F_arr[300,:])
print("f(0.5,t_0) = {}".format(F_arr[0,int(X.shape[0]/10)]))
print("f(x1,t1) = {}".format(F_arr[300,int(X.shape[0]/10) + int(-CA*X.shape[0]/5)]))
plt.plot(X,F_arr[0,:],label='Initial')
plt.plot(X,F_arr[300,:],label='Evolved')
plt.legend()
plt.show()


Recommended Posts

[Python] Semi-Lagrange-Methode
Johnson-Methode (Python)
Python-Installationsmethode Windows
Simplex-Methode (Einzelmethode) in Python
Private Methode in Python
Python
[Python] Berechnungsmethode mit numpy
Das Unterdrücken von Methodenüberschreibungen in Python
Python Design Pattern - Template-Methode
Implementierte Methode zur Weitergabe von Etiketten in Python
Simulieren Sie die Monte-Carlo-Methode in Python
Hash-Methode (Open-Address-Methode) in Python
[Python] Unterschied zwischen Funktion und Methode
[Python] -1 Bedeutung der Umformungsmethode von Numpy
Kafka Python
Lassen Sie uns eine probabilistische Ausbreitungsmethode (Python) erstellen.
Python-Grundlagen ⑤
Python-Zusammenfassung
Eingebaute Python
Python-Einschlussnotation
Python studieren
Python 2.7 Countdown
Python-Memorandum
Python FlowFishMaster
Python-Dienst
Python-Tipps
Methode zum Erstellen einer Python-Umgebung in Xcode 6
[Einführung in die Udemy Python3 + -Anwendung] 25. Wörterbuchmethode
Python-Memo
[Einführung in die Udemy Python3 + -Anwendung] 13. Zeichenmethode
Python-Einschlussnotation
[Python] [scikit-learn] k-Einführung in das Memo der Methode des nächsten Nachbarn
Python Singleton
Python-Grundlagen ④
Python-Memorandum 2
Automatische Update-Methode von Python Pyinstaller exe
Python-Inkrement
atCoder 173 Python
[Python] -Funktion
Python-Installation
Binäre Methode
Python installieren 3.4.3.
Versuchen Sie Python
Python-Memo
Python iterativ
Python-Algorithmus
Python2 + word2vec
[Python] -Variablen
Python-Funktionen