예제 #1
0
def H(W):
    '''
    H dot W where H is Harmiton operator
    @input:
        W: Expansion coefficients for Ns unconstrained wave functions, stored as 
            an (S0 * S1 * S2, Ns) matrix
    @global variables
        Vdual: Dual potential coefficients stored as a (S0 * S1 * S2, 1) column vector.
    @return:
        matrix of shape (S0 * S1 * S2, Ns)
    '''
    f = 2
    U = np.dot(W.conj().T, op.O(W))
    U_inv = np.linalg.inv(U)
    # each col of W_real represents W's value in sampled real space
    W_real = op.cI(W)
    n = f * op.diagouter(np.dot(W_real, U_inv), W_real)
    exc = excVWN(n)
    exc_prime = excpVWN(n)
    # electrostatic potential (phi) in freqency space
    phi = op.poisson(n, real_phi=False)
    Veff = gb_Vdual \
        + op.cJdag(op.O(phi)) \
        + op.cJdag(op.O(op.cJ(exc))) \
        + op.diagprod(exc_prime, op.cJdag(op.O(op.cJ(n))))
    HW_potential = op.cIdag(op.diagprod(Veff, op.cI(W)))
    HW_kinetic = -0.5 * op.L(W)
    HW = HW_kinetic + HW_potential
    return HW
예제 #2
0
def getE(W):
    '''
    get the energy from expansion coefficients for Ns unconstrained wave function
    @input:
        W: Expansion coefficients for Ns unconstrained wave functions, stored as 
            an (S0 * S1 * S2, Ns) matrix
    @global variables
        Vdual: Dual potential coefficients stored as a (S0 * S1 * S2, 1) column vector.
    @return:
        E: Energies summed over Ns states
    '''
    f = 2
    U = np.dot(W.conj().T, op.O(W))
    U_inv = np.linalg.inv(U)
    # each col of W_real represents W's value in sampled real space
    W_real = op.cI(W)
    n = f * op.diagouter(np.dot(W_real, U_inv), W_real)
    E_potential = np.dot(gb_Vdual.T, n)
    E_kinetic = -0.5 * np.trace(np.dot(W.conj().T, op.L(np.dot(W, U_inv)))) * f
    # electrostatic potential (phi) in freqency space
    phi = op.poisson(n, real_phi=False)
    # E_hartree = 0.5 * np.dot(n.conj().T, op.cJdag(op.O(phi)))
    E_hartree = 0.5 * np.dot(op.cJ(n).conj().T, op.O(phi))
    exc = excVWN(n)
    # the Exc is negative here, which seems problematic.
    Exc = np.dot(op.cJ(n).conj().T, op.O(op.cJ(exc)))
    E = (E_potential + E_kinetic + E_hartree + Exc)[0, 0]
    E = E.real
    return E
예제 #3
0
파일: sch.py 프로젝트: liarrn/Practical_DFT
def getgrad(W):
    '''
    get gradient dE/dW
    '''
    U = np.dot(W.conj().T, op.O(W))
    U_inv = np.linalg.inv(U)
    HW = H(W)
    t1 = np.dot(op.O(W), U_inv)  # (#. sample points, Ns)
    t2 = np.dot(t1, np.dot(W.conj().T, HW))
    t3 = HW - t2
    t4 = np.dot(t3, U_inv)
    return t4
예제 #4
0
파일: sch.py 프로젝트: liarrn/Practical_DFT
def orthonormalizeW(W):
    '''
    orthonormalize W so that Wdag dot O(W) is identity matrix
    '''
    U = np.dot(W.conj().T, op.O(W))
    U_inv = np.linalg.inv(U)
    U_inv_sqrt = linalg.sqrtm(U_inv)
    W_orthonormal = np.dot(W, U_inv_sqrt)
    return W_orthonormal
예제 #5
0
def test_orthonormalizeW():
    ns = 4
    W = np.random.rand(np.prod(global_vars.S), ns) + 1j * \
        np.random.rand(np.prod(global_vars.S), ns)
    W = orthonormalizeW(W)
    # Overlap matrix should equal to identity matrix up to machine precison
    Overlap = np.dot(W.conj().T, op.O(W))
    assert np.linalg.norm(
        np.sum(Overlap - np.identity(ns))) < 1e-6, 'ERROR in orthonormalizeW'
예제 #6
0
파일: sch.py 프로젝트: liarrn/Practical_DFT
def getE(W):
    '''
    get the energy from expansion coefficients for Ns unconstrained wave function
    @input:
        W: Expansion coefficients for Ns unconstrained wave functions, stored as 
            an (S0 * S1 * S2, Ns) matrix
    @global variables
        Vdual: Dual potential coefficients stored as a (S0 * S1 * S2, 1) column vector.
    @return:
        E: Energies summed over Ns states
    '''
    U = np.dot(W.conj().T, op.O(W))
    U_inv = np.linalg.inv(U)
    W_real = op.cI(
        W)  # each col of W_real represents W's value in sampled real space
    n = op.diagouter(np.dot(W_real, U_inv), W_real)
    E_potential = np.dot(gb_Vdual.T, n)
    E_kinetic = -0.5 * np.trace(np.dot(W.conj().T, op.L(np.dot(W, U_inv))))
    E = (E_potential + E_kinetic)[0, 0]
    E = E.real
    return E
예제 #7
0
sum_over_cell = lambda x: np.sum(x) * np.linalg.det(global_vars.R) / \
    (global_vars.S[0] * global_vars.S[1] * global_vars.S[2])  # sum(xdv)
sigma1, sigma2 = 0.75, 0.5
g1 = gen_gaussian3(dr, sigma1)
g2 = gen_gaussian3(dr, sigma2)
n = g2 - g1

if global_vars.is_debug:
    print(sum_over_cell(g1))
    print(sum_over_cell(g2))

net_charge = sum_over_cell(n)
print('net charge is {:.4f}'.format(net_charge))
assert net_charge < 1e-3, 'Current charge is not zero'

phi = op.cI(op.Linv(-4 * np.pi * op.O(op.cJ(n))))
# Due to rounding, tiny imaginary parts creep into the solution. Eliminate
# by taking the real part.
phi = np.real(phi)

# Unum = (0.5 * np.real(np.dot(op.cJ(phi).conj().T, op.O(op.cJ(n)))))[0, 0]
Unum = (0.5 * np.dot(phi.T, n)[0]) * (np.linalg.det(global_vars.R) /
                                      np.prod(global_vars.S))
Uanal = ((1 / sigma1 + 1 / sigma2) / 2 -
         np.sqrt(2) / np.sqrt(sigma1**2 + sigma2**2)) / np.sqrt(np.pi)
res_deviation = np.abs(Unum - Uanal)
print('Deviation between numerical and analytical results is {:.4f}'.format(
    res_deviation))
if global_vars.is_debug:
    print(Unum)
    print(Uanal)
예제 #8
0
파일: sch.py 프로젝트: liarrn/Practical_DFT
import numpy as np
import matplotlib.pyplot as plt
import global_vars
import op
from scipy import linalg
import vis

lattice_center = np.reshape(np.sum(global_vars.R / 2, axis=1), (1, -1))
dr = np.sqrt(np.sum((global_vars.r - lattice_center)**2, axis=1))
V = 2 * (dr**2)
gb_Vdual = op.cJdag(op.O(op.cJ(V)))


def getE(W):
    '''
    get the energy from expansion coefficients for Ns unconstrained wave function
    @input:
        W: Expansion coefficients for Ns unconstrained wave functions, stored as 
            an (S0 * S1 * S2, Ns) matrix
    @global variables
        Vdual: Dual potential coefficients stored as a (S0 * S1 * S2, 1) column vector.
    @return:
        E: Energies summed over Ns states
    '''
    U = np.dot(W.conj().T, op.O(W))
    U_inv = np.linalg.inv(U)
    W_real = op.cI(
        W)  # each col of W_real represents W's value in sampled real space
    n = op.diagouter(np.dot(W_real, U_inv), W_real)
    E_potential = np.dot(gb_Vdual.T, n)
    E_kinetic = -0.5 * np.trace(np.dot(W.conj().T, op.L(np.dot(W, U_inv))))