Equazione di Schrodinger con condizioni al contorno periodiche


9

Ho un paio di domande su quanto segue:

Sto provando a risolvere l'equazione di Schrodinger in 1D usando la discretizzazione a pedivella nicolson seguita da invertire la matrice tridiagonale risultante. Il mio problema si è ora evoluto in un problema con condizioni al contorno periodiche e quindi ho modificato il mio codice per utilizzare l'algoritmo Sherman Morrison.

Supponiamo che vsia il mio RHS in ogni momento quando desidero invertire la matrice tridiagonale. La dimensione di vè il numero di punti della griglia che ho nello spazio. Quando ho impostato v[0]e v[-1]in termini reciproci, come richiesto dalla mia situazione periodica, la mia equazione esplode. Non so dire perché stia succedendo. Sto usando python2.7 e scipy integrato di risolto_bandato per risolvere l'equazione.

Questo mi porta alla mia seconda domanda: ho usato Python perché è la lingua che conosco meglio, ma la trovo piuttosto lenta (anche con le ottimizzazioni offerte da numpy e scipy). Ho provato ad usare il C ++ perché ne ho ragionevolmente familiarità. Ho pensato di usare la GSL che sarebbe stata ottimizzata per BLAS, ma non ho trovato documentazione per creare vettori complessi o risolvere la matrice tridiagonale con vettori così complessi.

Vorrei oggetti nel mio programma poiché ritengo che sarebbe il modo più semplice per me generalizzare in seguito per includere l'accoppiamento tra funzioni d'onda, quindi mi attengo a un linguaggio orientato agli oggetti.

Potrei provare a scrivere a mano il risolutore di matrici tridiagonali, ma ho riscontrato problemi quando l'ho fatto in Python. Man mano che mi sono evoluto in grandi periodi con fasi temporali sempre più precise, l'errore si è accumulato e mi ha dato sciocchezze. Tenendo presente questo, ho deciso di utilizzare i metodi integrati.

Qualsiasi consiglio è molto apprezzato.

EDIT: ecco lo snippet di codice pertinente. La notazione è presa in prestito dalla pagina di Wikipedia sull'equazione della matrice tridiagonale (TDM). v è l'RHS dell'algoritmo a pedale nicolson in ogni fase temporale. I vettori a, bec sono le diagonali del TDM. L'algoritmo corretto per il caso periodico proviene dal Wiki CFD . Ho fatto un piccolo cambio di nome. Quello che hanno chiamato u, v Ho chiamato U, V (in maiuscolo). Ho chiamato q il complemento y la soluzione temporanea e la soluzione effettiva self.currentState. L'assegnazione di v [0] e v [-1] è ciò che sta causando il problema qui e quindi è stato commentato. È possibile ignorare i fattori di gamma. Sono fattori non lineari utilizzati per modellare i condensati di Bose Einstein.

for T in np.arange(self.timeArraySize):
        for i in np.arange(0,self.spaceArraySize-1):
            v[i] = Y*self.currentState[i+1] + (1-2*Y)*self.currentState[i] + Y*self.currentState[i-1] - 1j*0.5*self.timeStep*potential[i]*self.currentState[i] - self.gamma*1j*0.5*self.timeStep*(abs(self.currentState[i])**2)*self.currentState[i]
            b[i] = 1+2*Y + 1j*0.5*self.timeStep*potential[i] + self.gamma*self.timeStep*1j*0.5*(abs(self.currentState[i])**2)

        #v[0] = Y*self.currentState[1] + (1-2*Y)*self.currentState[0] + Y*self.currentState[-1] - 1j*0.5*self.timeStep*potential[0]*self.currentState[0]# - self.gamma*1j*0.5*self.timeStep*(abs(self.currentState[0])**2)*self.currentState[0]
        #v[-1] = Y*self.currentState[0] + (1-2*Y)*self.currentState[-1] + Y*self.currentState[-2] - 1j*0.5*self.timeStep*potential[-1]*self.currentState[-1]# - self.gamma*1j*0.5*self.timeStep*(abs(self.currentState[-1])**2)*self.currentState[-1]
        b[0] = 1+2*Y + 1j*0.5*self.timeStep*potential[0] + self.gamma*self.timeStep*1j*0.5*(abs(self.currentState[0])**2)
        b[-1] = 1+2*Y + 1j*0.5*self.timeStep*potential[-1] + self.gamma*self.timeStep*1j*0.5*(abs(self.currentState[-1])**2)

        diagCorrection[0], diagCorrection[-1] = - b[0], - c[-1]*a[0]/b[0]

        tridiag = np.matrix([
            c,
            b - diagCorrection,
            a,
        ])

        temp = solve_banded((1,1), tridiag, v)

        U = np.zeros(self.spaceArraySize, dtype=np.complex64)
        U[0], U[-1] = -b[0], c[-1]

        V = np.zeros(self.spaceArraySize, dtype=np.complex64)
        V[0], V[-1] = 1, -a[0]/b[0]

        complement = solve_banded((1,1), tridiag, U)

        num = np.dot(V, temp)
        den = 1 + np.dot(V, complement)

        self.currentState = temp  - (num/den)*complement

3
Sembra (a prima vista) come un bug nelle tue condizioni al contorno periodiche. Vuoi pubblicare uno snippet di codice?
David Ketcheson,

2
Benvenuto in Stack Exchange! In futuro, se hai diverse domande, potresti volerle porre separatamente.
Dan

Inoltre: cosa intendi esattamente con "imposta v [0] e v [-1] l'uno rispetto all'altro"? Stai impostando gli elementi vettoriali uguali tra loro dopo la risoluzione o stai usando un elemento non tridiagonale per accoppiarli?
Dan

Ho aggiunto il mio codice sopra. Se qualcosa non è chiaro, per favore fatemi sapere. Ricorderò di porre domande separate la prossima volta.
WiFO215,

Grazie! È un po 'difficile leggere il codice a causa della formattazione (righe molto lunghe). Inoltre, commentare la parte a cui vuoi che le persone prestino attenzione è confuso. Cod scrivi le equazioni che stai risolvendo (con MathJax) usando la stessa notazione del tuo codice?
David Ketcheson,

Risposte:


2

Seconda domanda

Il codice che chiama Scipy / Numpy di solito è veloce solo se può essere vettorializzato; non dovresti avere nulla di "lento" all'interno di un loop Python. Anche allora, è praticamente inevitabile che sia almeno un po 'più lento di qualcosa che usa una libreria simile in un linguaggio compilato.

for i in np.arange(0,self.spaceArraySize-1):
            v[i] = Y*self.currentState[i+1] + (1-2*Y)*self.currentState[i]   ...
            b[i] = 1+2*Y + 1j*0.5*self.timeStep*potential[i] + ...

Questo è ciò che intendo per "lento in un ciclo Python". Python's forè inaccettabilmente lento per la maggior parte delle applicazioni numeriche e Scipy / Numpy non influisce affatto su questo. Se hai intenzione di usare Python, questo ciclo interno dovrebbe essere espresso come una o due funzioni Numpy / Scipy, che tali librerie possono o meno fornire. Se non forniscono qualcosa che ti consente di scorrere su matrici come questa e di accedere ad elementi adiacenti, Python è lo strumento sbagliato per quello che vuoi fare.

Inoltre, stai facendo un'inversione piuttosto che una risoluzione vettoriale-matrice. Un'inversione di matrice, seguita da una moltiplicazione di matrice-vettore, è molto più lenta di una soluzione di matrice-vettore. Questa è quasi sicuramente la cosa che rallenta il tuo codice più di ogni altra cosa.

Se si desidera utilizzare C / C ++, GSL è carente quando si tratta di algebra lineare complessa. Consiglio di utilizzare BLAS o LAPACK direttamente o di utilizzare una libreria come PETSc o Trilinos. Se hai installato MKL, puoi usarlo anche tu. Potresti anche voler dare un'occhiata a Fortran 2008, che è orientato agli oggetti.

Le tue matrici sono sparse, quindi ti consigliamo di utilizzare librerie sparse.

Direi anche che quello che stai facendo qui sembra abbastanza basso livello che l'orientamento agli oggetti probabilmente non dovrebbe essere la tua preoccupazione principale. Un array Fortran 90+ è probabilmente una buona corrispondenza con ciò di cui hai bisogno e i compilatori F90 possono auto-parallelizzare alcuni loop.

Inoltre, potresti voler controllare Octave o Matlab, che hanno la sparse()funzione. Se usati correttamente, dovrebbero essere in grado di funzionare abbastanza rapidamente.


Sicuramente esaminerò Fortran 2008. Ho già ottenuto la matrice "quasi tridiagonale". Ho menzionato sopra che stavo usando l'algoritmo Sherman Morrison.
WiFO215,

AGGIORNAMENTO: Ho cercato di leggere su ScaLAPACK perché sembra molto interessante. Permette di invertire le matrici usando una parola che ho sentito molto "in parallelo". Tutto quello che so è che utilizza tutti i miei processori e quindi va più veloce, ma oltre a ciò, non capisco di cosa si tratta. Proveniente da un background fisico, l'unica esposizione al computer che ho è con 101 corsi in Python e C. Imparare come usare questo richiederà del tempo. La stessa documentazione non si presta alla lettura pulita.
WiFO215,

AGGIORNAMENTO 2: Man! Questa cosa di ScaLAPACK sembra davvero complicata. Non capisco la testa o la coda di ciò che è sul sito web. Sto semplicemente nuotando in tutte le informazioni.
WiFO215,

AGGIORNAMENTO 3: Bene, ho seguito le altre raccomandazioni PETSc e Trilinos. La mia ultima chiamata è che non penso che li userò ora perché sembrano molto complicati. Ciò non significa che non li leggerò. Inizierò a leggerli ora, ma quando comprenderò e sono in grado di implementarli, sarebbero passati mesi. Aprirò un thread separato per le mie domande su quanto sopra in quanto ho difficoltà con esso, ma è per dopo. Ora, sono tornato ad affrontare solo la domanda 1.
WiFO215

Ho aggiornato la mia risposta.
Dan
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.