สมการชโรดิงเงอร์ที่มีเงื่อนไขขอบเขตเป็นระยะ


9

ฉันมีคำถามสองสามข้อเกี่ยวกับสิ่งต่อไปนี้:

ฉันกำลังพยายามที่จะแก้สมการชโรดิงเงอร์ใน 1D โดยใช้ข้อเหวี่ยงนิโคลสันข้อเหวี่ยงตามด้วยการแปลงเมทริกซ์กลับด้านที่เกิดขึ้น ขณะนี้ปัญหาของฉันได้รับการพัฒนาเป็นปัญหาเกี่ยวกับเงื่อนไขขอบเขตเป็นระยะดังนั้นฉันจึงแก้ไขโค้ดของฉันเพื่อใช้อัลกอริทึม Sherman Morrison

สมมติว่าvเป็น RHS ของฉันในแต่ละขั้นตอนเมื่อฉันต้องการกลับเมทริกซ์ไตรภาคี ขนาดของvคือจำนวนจุดกริดที่ฉันมีมากกว่าพื้นที่ เมื่อฉันตั้งค่าv[0]และv[-1]ในแง่ของกันและกันตามที่จำเป็นในสถานการณ์ของฉันเป็นระยะสมการของฉันระเบิดขึ้น ฉันไม่สามารถบอกได้ว่าทำไมสิ่งนี้จึงเกิดขึ้น ฉันใช้ python2.7 และ inbuilt ของ scipy เพื่อแก้ไขสมการ

สิ่งนี้ทำให้ฉันถึงคำถามที่สองของฉัน: ฉันใช้หลามเพราะเป็นภาษาที่ฉันรู้จักดีที่สุด แต่ฉันคิดว่ามันค่อนข้างช้า (แม้จะมีการเพิ่มประสิทธิภาพที่เสนอโดย numpy และ scipy) ฉันได้ลองใช้ C ++ เพราะฉันคุ้นเคยกับมันอย่างสมเหตุสมผล ฉันคิดว่าฉันใช้ GSL ซึ่งจะเป็นการเพิ่มประสิทธิภาพ BLAS แต่ไม่พบเอกสารประกอบในการสร้างเวกเตอร์ที่ซับซ้อนหรือแก้เมทริกซ์ tridiagonal ด้วยเวกเตอร์ที่มีค่าที่ซับซ้อนเช่นนั้น

ฉันต้องการวัตถุในโปรแกรมของฉันเนื่องจากฉันรู้สึกว่ามันเป็นวิธีที่ง่ายที่สุดสำหรับฉันที่จะพูดคุยในภายหลังเพื่อรวมการมีเพศสัมพันธ์ระหว่าง wavefunctions ดังนั้นฉันจึงติดกับภาษาเชิงวัตถุ

ฉันลองเขียนตัวแก้เมทริกซ์ tridiagonal matrix ด้วยมือ แต่ฉันพบปัญหาเมื่อฉันทำเช่นนั้นในไพ ธ อน ในขณะที่ฉันมีการพัฒนาในช่วงเวลาที่มากขึ้นด้วยขั้นตอนที่ดีกว่าและดีกว่าข้อผิดพลาดที่สะสมและทำให้ฉันไร้สาระ เมื่อคำนึงถึงสิ่งนี้ฉันตัดสินใจใช้วิธีการที่สร้างขึ้น

คำแนะนำใด ๆ ที่ชื่นชมมาก

แก้ไข: นี่คือตัวอย่างรหัสที่เกี่ยวข้อง สัญกรณ์ถูกยืมมาจากหน้าของ Wikipedia บนสมการเมทริกซ์ tridiagonal (TDM) v คือ RHS ของอัลกอริธึมข้อเหวี่ยงนิโคลสันในแต่ละขั้นตอน เวกเตอร์ a, b และ c เป็นเส้นทแยงมุมของ TDM ขั้นตอนวิธีการแก้ไขสำหรับกรณีที่ระยะห่างจากCFD วิกิพีเดีย ฉันได้ทำการเปลี่ยนชื่อเล็กน้อย สิ่งที่พวกเขาเรียกว่า u, v ฉันได้เรียกว่า U, V (พิมพ์ใหญ่) ฉันเรียกว่าส่วนประกอบเสริม, y คือทางออกชั่วคราวและโซลูชันจริง self.currentState การมอบหมายของ v [0] และ v [-1] เป็นสิ่งที่ทำให้เกิดปัญหาที่นี่และได้รับการแสดงความคิดเห็น คุณอาจเพิกเฉยต่อปัจจัยของแกมม่า พวกเขาเป็นปัจจัยที่ไม่ใช่เชิงเส้นที่ใช้ในการสร้างแบบจำลอง Bose Einstein Condensates

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
มันฟังดู (เหมือนตอนแรก) เหมือนบั๊กในเงื่อนไขขอบเขตของคุณ สนใจโพสต์โค้ดหรือไม่
David Ketcheson

2
ยินดีต้อนรับสู่ Stack Exchange! ในอนาคตหากคุณมีคำถามหลายข้อคุณอาจต้องถามแยกต่างหาก
Dan

นอกจากนี้: คุณหมายถึงอะไร "set v [0] และ v [-1] ในแง่ของกันและกัน"? คุณตั้งค่าองค์ประกอบแบบเวกเตอร์ให้เท่ากันหลังจากแก้ปัญหาหรือคุณใช้องค์ประกอบนอกเส้นสามเหลี่ยมเพื่อจับคู่พวกเขาหรือไม่?
Dan

ฉันได้เพิ่มรหัสของฉันข้างต้น หากมีสิ่งใดไม่ชัดเจนโปรดแจ้งให้เราทราบ ฉันจะจำโพสต์คำถามแยกต่างหากในครั้งต่อไป
WiFO215

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

คำตอบ:


2

คำถามที่สอง

รหัสที่เรียกว่า Scipy / Numpy นั้นมักจะรวดเร็วหากสามารถทำให้เป็น vectorized ได้ คุณไม่ควรมีอะไร "ช้า" ภายในห่วงหลาม ถึงอย่างนั้นมันก็หลีกเลี่ยงไม่ได้ที่จะช้ากว่าที่ใช้ไลบรารีที่คล้ายกันในภาษาที่คอมไพล์

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] + ...

นี่คือสิ่งที่ฉันหมายถึงโดย "ช้าในหลามหลาม" Python forนั้นช้ามากสำหรับแอปพลิเคชั่นตัวเลขส่วนใหญ่และ Scipy / Numpy ไม่ส่งผลกระทบใด ๆ เลย ถ้าคุณจะใช้ python วงในนี้ควรถูกแสดงเป็นหนึ่งหรือสองฟังก์ชั่นของ Numpy / Scipy ซึ่งไลบรารีเหล่านั้นอาจมีหรือไม่มีก็ได้ หากพวกเขาไม่ได้จัดเตรียมสิ่งที่ช่วยให้คุณสามารถทำซ้ำมากกว่าอาร์เรย์เช่นนี้และเข้าถึงองค์ประกอบที่อยู่ติดกันหลามเป็นเครื่องมือที่ผิดสำหรับสิ่งที่คุณต้องการทำ

นอกจากนี้คุณกำลังทำการผกผันมากกว่าเมทริกซ์เวกเตอร์ ผกผันเมทริกซ์ตามด้วยเมทริกซ์เวกเตอร์คูณเป็นมากช้ากว่าเมทริกซ์เวกเตอร์แก้ นี่เป็นสิ่งที่ทำให้โค้ดของคุณช้าลงกว่าสิ่งอื่นใด

ถ้าคุณต้องการใช้ C / C ++, GSL เป็นชนิดที่ขาดเมื่อมันมาถึงพีชคณิตเชิงเส้นที่ซับซ้อน ฉันขอแนะนำให้ใช้ BLAS หรือ LAPACK โดยตรงหรือใช้ห้องสมุดอย่าง PETSc หรือ Trilinos หากคุณติดตั้ง MKL ไว้คุณสามารถใช้มันได้เช่นกัน คุณอาจต้องการตรวจสอบ Fortran 2008 ซึ่งเป็นเชิงวัตถุ

เมทริกซ์ของคุณกระจัดกระจายดังนั้นคุณต้องแน่ใจว่าคุณใช้ไลบรารี่เบาบาง

ฉันก็จะบอกว่าสิ่งที่คุณกำลังทำอยู่ที่นี่ดูเหมือนว่าอยู่ในระดับต่ำพอที่การวางแนววัตถุอาจไม่ควรเป็นปัญหาหลักของคุณ อาเรย์ Fortran 90+ นั้นน่าจะเหมาะกับสิ่งที่คุณต้องการและคอมไพเลอร์ของ F90 สามารถทำการลูปขนานกันได้อัตโนมัติ

นอกจากนี้คุณอาจต้องการตรวจสอบ Octave หรือ Matlab ซึ่งมีsparse()ฟังก์ชั่น หากใช้อย่างถูกต้องสิ่งเหล่านี้จะสามารถทำงานได้อย่างรวดเร็ว


แน่นอนฉันจะดูใน Fortran 2008 ฉันได้รับเมทริกซ์ 'เกือบสามเหลี่ยม' แล้ว ฉันพูดถึงข้างต้นว่าฉันใช้อัลกอริทึมของเชอร์แมนมอร์ริสัน
WiFO215

UPDATE: ฉันพยายามอ่าน ScaLAPACK เพราะมันดูน่าสนใจมาก มันช่วยให้คนหนึ่งกลับด้านเมทริกซ์โดยใช้คำพูดปากต่อปากที่ฉันได้ยินมามาก "ขนาน" ทั้งหมดที่ฉันรู้คือมันใช้โปรเซสเซอร์ทั้งหมดของฉันและมันจึงทำงานได้เร็วขึ้น แต่นอกเหนือจากนั้นฉันไม่เข้าใจว่ามันเกี่ยวกับอะไร มาจากพื้นหลังของฟิสิกส์การสัมผัสเพียงอย่างเดียวกับการคำนวณที่ฉันมีคือกับ 101 หลักสูตรใน Python และ C การเรียนรู้วิธีใช้สิ่งนี้จะต้องใช้เวลา เอกสารเองไม่ได้ยืมเพื่อทำความสะอาดการอ่าน
WiFO215

อัพเดท 2: ผู้ชาย! ScaLAPACK สิ่งนี้ดูซับซ้อนจริงๆ ฉันไม่เข้าใจส่วนหัวหรือส่วนท้ายของสิ่งที่อยู่บนเว็บไซต์ ฉันแค่ว่ายน้ำในข้อมูลทั้งหมด
WiFO215

ปรับปรุง 3: เอาล่ะฉันได้ทำตามคำแนะนำอื่น ๆ PETSc และ Trilinos การโทรครั้งสุดท้ายของฉันคือฉันไม่คิดว่าฉันจะใช้สิ่งเหล่านี้ในขณะนี้เนื่องจากมันดูซับซ้อนมาก ไม่ได้หมายความว่าฉันจะไม่อ่าน ฉันจะเริ่มอ่านพวกเขาตอนนี้ แต่เมื่อถึงเวลาที่ฉันเข้าใจและสามารถนำไปใช้ได้หลายเดือนก็ผ่านไปแล้ว ฉันจะเปิดเธรดแยกต่างหากสำหรับคำถามของฉันด้านบนเนื่องจากฉันมีปัญหากับมัน แต่สำหรับในภายหลัง ตอนนี้ฉันกลับไปที่การแก้ปัญหาเฉพาะคำถามที่ 1
WiFO215

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