Beispiel #1
0
    def setUp(self):
        UTGroundStateSetup.setUp(self)

        for virtvar in ['timesteps', 'propagator']:
            assert getattr(self,virtvar) is not None, 'Virtual "%s"!' % virtvar

        self.tdname = 'ut_tddft_td_' + self.propagator.lower()
        self.tdcalc = TDDFT(self.gsname + '.gpw', propagator=self.propagator,
                            txt=self.tdname + '.txt')
Beispiel #2
0
 def time_propagation(self,
                      filename,
                      kick_strength,
                      time_step,
                      iterations,
                      dipole_moment_file=None,
                      restart_file=None,
                      dump_interval=100,
                      **kwargs):
     self.td_calc = TDDFT(filename, **kwargs)
     if kick_strength is not None:
         self.td_calc.absorption_kick(kick_strength)
         self.td_calc.hamiltonian.poisson.set_kick(kick_strength)
     self.td_calc.propagate(time_step, iterations, dipole_moment_file,
                            restart_file, dump_interval)
    def setUp(self):
        UTGroundStateSetup.setUp(self)

        for virtvar in ["timesteps", "propagator"]:
            assert getattr(self, virtvar) is not None, 'Virtual "%s"!' % virtvar

        self.tdname = "ut_tddft_td_" + self.propagator.lower()
        self.tdcalc = TDDFT(self.gsname + ".gpw", propagator=self.propagator, txt=self.tdname + ".txt")
Beispiel #4
0
    def setUp(self):
        UTGroundStateSetup.setUp(self)

        for virtvar in ['timesteps', 'propagator']:
            assert getattr(self,virtvar) is not None, 'Virtual "%s"!' % virtvar

        self.tdname = 'ut_tddft_td_' + self.propagator.lower()
        self.tdcalc = TDDFT(self.gsname + '.gpw', propagator=self.propagator,
                            txt=self.tdname + '.txt')
 def time_propagation(self,
                        filename,
                        kick_strength,
                        time_step,
                        iterations,
                        dipole_moment_file=None,
                        restart_file=None,
                        dump_interval=100,
                        **kwargs):
     self.td_calc = TDDFT(filename, **kwargs)
     if kick_strength is not None:
         self.td_calc.absorption_kick(kick_strength)
         self.td_calc.hamiltonian.poisson.set_kick(kick_strength)
     self.td_calc.propagate(time_step, iterations, dipole_moment_file, restart_file, dump_interval)
Beispiel #6
0
atoms = molecule('SiH4')
atoms.center(vacuum=4.0)

# Ground-state calculation
calc = GPAW(nbands=7,
            h=0.4,
            poissonsolver=PoissonSolver(eps=1e-16),
            convergence={'density': 1e-8},
            xc='GLLBSC',
            txt='gs.out')
atoms.set_calculator(calc)
energy = atoms.get_potential_energy()
calc.write('gs.gpw', mode='all')

# Time-propagation calculation
td_calc = TDDFT('gs.gpw', txt='td.out')
td_calc.absorption_kick(np.ones(3) * 1e-5)
td_calc.propagate(20, 3, 'dm.dat')

# Write a restart point
td_calc.write('td.gpw', mode='all')

# Keep propagating
td_calc.propagate(20, 3, 'dm.dat')

# Restart from the restart point
td_calc = TDDFT('td.gpw', txt='td2.out')
td_calc.propagate(20, 3, 'dm.dat')
world.barrier()

# Check dipole moment file
Beispiel #7
0
              positions=[(0, 0, 0), (3.0, 0, 0)],
              pbc=False)
atoms.center(vacuum=3.0)

# Standard ground state calculation
calc = GPAW(nbands=2, h=0.6, setups={'Na': '1'}, poissonsolver=poissonsolver,
            convergence={'density': density_eps})
atoms.set_calculator(calc)
energy = atoms.get_potential_energy()
calc.write('na2_gs.gpw', mode='all')

# Standard time-propagation initialization
time_step = 10.0
iterations = 20
kick_strength = [1.0e-3, 1.0e-3, 0.0]
td_calc = TDDFT('na2_gs.gpw')
td_calc.absorption_kick(kick_strength=kick_strength)

# Create and attach InducedField object
frequencies = [1.0, 2.08]     # Frequencies of interest in eV
folding = 'Gauss'             # Folding function
width = 0.1                   # Line width for folding in eV
ind = TDDFTInducedField(paw=td_calc,
                        frequencies=frequencies,
                        folding=folding,
                        width=width,
                        restart_file='na2_td.ind')

# Propagate as usual
td_calc.propagate(time_step, iterations // 2, 'na2_td_dm.dat', 'na2_td.gpw')
        cell_c = np.sum(atoms.get_cell()**2, axis=1)**0.5
        N_c = 8 * np.round(cell_c / (0.2 * 8))
        calc = GPAW(gpts=N_c, nbands=5, basis='dzp', txt=name + '_gs.txt',
                    eigensolver='rmm-diis')
        atoms.set_calculator(calc)
        atoms.get_potential_energy()
        calc.write(name + '_gs.gpw', mode='all')
        del atoms, calc
        time.sleep(10)

    while not os.path.isfile(name + '_gs.gpw'):
        print('Node %d waiting for file...' % world.rank)
        time.sleep(10)
    world.barrier()

    tdcalc = TDDFT(name + '_gs.gpw', txt=name + '_td.txt', propagator='EFSICN')
    ehrenfest = EhrenfestVelocityVerlet(tdcalc)
    traj = PickleTrajectory(name + '_td.traj', 'w', tdcalc.get_atoms())

    t0 = time.time()
    f = paropen(name + '_td.log', 'w')
    for i in range(1, niter+1):
        ehrenfest.propagate(timestep)

        if i % ndiv == 0:
            rate = 60 * ndiv / (time.time()-t0)
            ekin = tdcalc.atoms.get_kinetic_energy()
            epot = tdcalc.get_td_energy() * Hartree
            F_av = ehrenfest.F * Hartree / Bohr
            print('i=%06d (%6.2f min^-1), ekin=%13.9f, epot=%13.9f, etot=%13.9f' % (i, rate, ekin, epot, ekin+epot), file=f)
            t0 = time.time()
Beispiel #9
0
atoms.center(vacuum=6.0)
# Larger grid spacing, LDA is ok
gs_calc = GPAW(nbands=1, h=0.35, xc='LDA')
atoms.set_calculator(gs_calc)
e = atoms.get_potential_energy()
niter = gs_calc.get_number_of_iterations()
gs_calc.write('na2_gs.gpw', 'all')

# 16 fs run with 8.0 attosec time step
time_step = 8.0 # 8.0 as (1 as = 0.041341 autime)5D
iters =  10     # 2000 x 8 as => 16 fs
# Weak delta kick to z-direction
kick = [0,0,1e-3]

# TDDFT calculator
td_calc = TDDFT('na2_gs.gpw')
# Kick
td_calc.absorption_kick(kick)
# Propagate
td_calc.propagate(time_step, iters, 'na2_dmz.dat', 'na2_td.gpw')
# Linear absorption spectrum
photoabsorption_spectrum('na2_dmz.dat', 'na2_spectrum_z.dat', width=0.3)


iters = 3

# test restart
td_rest = TDDFT('na2_td.gpw')
td_rest.propagate(time_step, iters, 'na2_dmz2.dat', 'na2_td2.gpw')

# test restart
class QSFDTD:
    def __init__(self, classical_material,
                        atoms,
                        cells,
                        spacings,
                        communicator=serial_comm,
                        remove_moments=(1, 1)):
                
        self.td_calc = None
        
        # Define classical cell in one of these ways:
        # 1. [cx, cy, cz]   -> vacuum for the quantum grid = 4.0
        # 2. ([cx, cy, cz]) -> vacuum = 4.0
        # 3. ([cx, cy, cz], vacuum)
        # 4. ([cx, cy, cz], ([p1x, p1y, p1z], [p2x, p2y, p2z])) where p1 and p2 are corners of the quantum grid
        if len(cells)==1: # (cell)
            assert(len(cells[0])==3)
            cell=np.array(cells[0])
            vacuum=4.0
        elif len(cells)==3: # [cell.x, cell.y, cell.z]
            cell=np.array(cells)
            vacuum=4.0
        elif len(cells)==2: # cell + vacuum/corners
            cell=np.array(cells[0])
            if np.array(cells[1]).size==1:
                vacuum=cells[1]
                corners=None
            else:
                vacuum=None
                corners=cells[1]
        else:
            raise Exception, 'QSFDTD: cells defined incorrectly'
        
        # Define spacings in in one of these ways:
        # 1. (clh, qmh)
        # 2. clh -> qmh=clh/4
        if np.array(spacings).size==1: # clh
            cl_spacing = spacings
            qm_spacing = 0.25*cl_spacing
        elif len(spacings)==2: # (clh, qmh)
            cl_spacing = spacings[0]
            qm_spacing = spacings[1]
        else:
            raise Exception, 'QSFDTD: spacings defined incorrectly'
            
        self.poissonsolver = FDTDPoissonSolver(classical_material  = classical_material,
                                          cl_spacing          = cl_spacing,
                                          qm_spacing          = qm_spacing,
                                          remove_moments      = remove_moments,
                                          communicator        = communicator,
                                          cell                = cell)
        self.poissonsolver.set_calculation_mode('iterate')
        
        # Quantum system
        if atoms is not None:
            assert(len(cells)==2)
            assert(len(spacings)==2)
            assert(len(remove_moments)==2)
            self.atoms = atoms
            self.atoms.set_cell(cell)
            if vacuum is not None: # vacuum
                self.atoms, self.qm_spacing, self.gpts = self.poissonsolver.cut_cell(self.atoms, vacuum=vacuum)
            else: # corners
                self.atoms, self.qm_spacing, self.gpts = self.poissonsolver.cut_cell(self.atoms, corners=corners)
        else: # Dummy quantum system
            self.atoms = Atoms("H", [0.5*cell], cell=cell)
            if vacuum is not None: # vacuum
                self.atoms, self.qm_spacing, self.gpts = self.poissonsolver.cut_cell(self.atoms, vacuum=vacuum)
            else: # corners
                self.atoms, self.qm_spacing, self.gpts = self.poissonsolver.cut_cell(self.atoms, corners=corners)
            del self.atoms[:]
            
            

    def ground_state(self, filename, **kwargs):
        # GPAW calculator for the ground state
        self.gs_calc = GPAW(gpts          = self.gpts,
                            poissonsolver = self.poissonsolver,
                            **kwargs
                            )
        self.atoms.set_calculator(self.gs_calc)
        self.energy = self.atoms.get_potential_energy()
        self.write(filename, mode='all')
    
    def write(self, filename, **kwargs):
        if self.td_calc is None:
            self.gs_calc.write(filename, **kwargs)
        else:
            self.td_calc.write(filename, **kwargs)
                    
    def time_propagation(self,
                           filename,
                           kick_strength,
                           time_step,
                           iterations,
                           dipole_moment_file=None,
                           restart_file=None,
                           dump_interval=100,
                           **kwargs):
        self.td_calc = TDDFT(filename, **kwargs)
        if kick_strength is not None:
            self.td_calc.absorption_kick(kick_strength)
            self.td_calc.hamiltonian.poisson.set_kick(kick_strength)
        self.td_calc.propagate(time_step, iterations, dipole_moment_file, restart_file, dump_interval)
Beispiel #11
0
from gpaw.tddft import TDDFT
from gpaw.inducedfield.inducedfield_fdtd import (FDTDInducedField,
                                                 calculate_hybrid_induced_field
                                                 )
from gpaw.inducedfield.inducedfield_tddft import TDDFTInducedField

td_calc = TDDFT('td.gpw')

# Classical subsystem
cl_ind = FDTDInducedField(filename='cl.ind', paw=td_calc)
cl_ind.calculate_induced_field(gridrefinement=2)
cl_ind.write('cl_field.ind', mode='all')

# Quantum subsystem
qm_ind = TDDFTInducedField(filename='qm.ind', paw=td_calc)
qm_ind.calculate_induced_field(gridrefinement=2)
qm_ind.write('qm_field.ind', mode='all')

# Total system, interpolate/extrapolate to a grid with spacing h
tot_ind = calculate_hybrid_induced_field(cl_ind, qm_ind, h=1.0)
tot_ind.write('tot_field.ind', mode='all')
Beispiel #12
0
                    basis='dzp',
                    txt=name + '_gs.txt',
                    eigensolver='rmm-diis')
        atoms.set_calculator(calc)
        atoms.get_potential_energy()
        calc.write(name + '_gs.gpw', mode='all')
        del atoms, calc
        time.sleep(10)

    while not os.path.isfile(name + '_gs.gpw'):
        print('Node %d waiting for file...' % world.rank)
        time.sleep(10)
    world.barrier()

    tdcalc = TDDFT(name + '_gs.gpw',
                   txt=name + '_td.txt',
                   parallel={'band': 5},
                   propagator='EFSICN')
    ehrenfest = EhrenfestVelocityVerlet(tdcalc)
    traj = Trajectory(name + '_td.traj', 'w', tdcalc.get_atoms())

    t0 = time.time()
    f = paropen(name + '_td.log', 'w')
    for i in range(1, niter + 1):
        ehrenfest.propagate(timestep)

        if i % ndiv == 0:
            rate = 60 * ndiv / (time.time() - t0)
            ekin = tdcalc.atoms.get_kinetic_energy()
            epot = tdcalc.get_td_energy() * Hartree
            F_av = ehrenfest.F * Hartree / Bohr
            s = 'i=%06d (%6.2f min^-1), ekin=%13.9f, epot=%13.9f, etot=%13.9f'
from gpaw.tddft import TDDFT
from matplotlib import use, patches
from matplotlib.pyplot import *
from ase.units import Bohr
import numpy as np
import sys

# Initialize TDDFT and QSFDTD
td_calc = TDDFT('gs.gpw')


def generate_xygrid(d, g, box):

    vslice = 2  # yx

    # Determine the array lengths in each dimension
    ng = d.shape

    X = None
    Y = None
    U = None
    V = None

    # Slice data
    d_slice = np.rollaxis(d, vslice)[g[vslice], :, :]
    d_proj = np.zeros(d_slice.shape)
    for ind, val in np.ndenumerate(d_slice):
        d_proj[ind] = np.where(
            np.append(np.rollaxis(d, vslice)[:, ind[0],
                                             ind[1]], 1.0) != 0)[0][0]
            sigma = tar['Width']
        except KeyError:
            timestep = 1
            sigma = None
        omega_w = tar.get('Frequency')
        gamma_w = tar.get('PhaseFactor')
        Fnt_wsG = tar.get('FourierTransform')
        Ant_sG = tar.get('Average')
        atoms = None
        del tar

        gpw_filename = sys.argv[2]
        assert gpw_filename.endswith('.gpw'), 'Invalid GPW tarfile.'
        assert os.path.isfile(gpw_filename), 'GPW tarfile not found.'

        calc = TDDFT(gpw_filename, txt=None)
        obs = DensityFourierTransform(timestep * autime_to_attosec,
                                      omega_w * aufrequency_to_eV,
                                      (sigma is not None and sigma \
                                       * aufrequency_to_eV or None))
        obs.initialize(calc)
        atoms = calc.get_atoms()
        del calc
        obs.read(ftd_filename, idiotproof=False)
        try:
            sys.stdout.write('Select grid refinement [1*/2]: ')
            gdref = int(sys.stdin.readline().strip())
        except:
            gdref = 1
        getall = slice(None) #hack to obtain all frequencies/spins
        Fnt_wsG = obs.get_fourier_transform(getall, getall, gdref)
atoms = Atoms(symbols='Na2', 
              positions=[(0, 0, 0), (3.0, 0, 0)],
              pbc=False)
atoms.center(vacuum=6.0)

# Standard ground state calculation
calc = GPAW(nbands=2, h=0.4, setups={'Na': '1'})
atoms.set_calculator(calc)
energy = atoms.get_potential_energy()
calc.write('na2_gs.gpw', mode='all')

# Standard time-propagation initialization
time_step = 10.0
iterations = 3000
kick_strength = [1.0e-3, 0.0, 0.0]
td_calc = TDDFT('na2_gs.gpw')
td_calc.absorption_kick(kick_strength=kick_strength)

# Create and attach InducedField object
frequencies = [1.0, 2.08]     # Frequencies of interest in eV
folding = 'Gauss'             # Folding function
width = 0.1                   # Line width for folding in eV
ind = TDDFTInducedField(paw=td_calc,
                        frequencies=frequencies,
                        folding=folding,
                        width=width,
                        restart_file='na2_td.ind')

# Propagate as usual
td_calc.propagate(time_step, iterations, 'na2_td_dm.dat', 'na2_td.gpw')
Beispiel #16
0
from ase import Atoms
from gpaw import GPAW
from gpaw.tddft import TDDFT
from gpaw.tddft.abc import LinearAbsorbingBoundary
from gpaw.tddft.laser import CWField

atoms = Atoms('Be',[(0,0,0)], pbc=False)
atoms.center(vacuum=6)
calc = GPAW(h=0.35)
atoms.set_calculator(calc)
atoms.get_potential_energy()

calc.write('be_gs.gpw', 'all')


td_calc = TDDFT('be_gs.gpw',
                td_potential = CWField(1e-3, 2.0*np.pi/50.0, 150.0))
td_calc.set_absorbing_boundary(LinearAbsorbingBoundary(5.0, 0.01,
                                                       atoms.positions.copy()))
td_calc.propagate(8.0, 5,
                  'be_nl_dmz_ipabs_1e-3.dat',
                  'be_nl_td.gpw')

td_rest = TDDFT('be_nl_td.gpw',
                td_potential = CWField(1e-3, 2.0*np.pi/50.0, 150.0))
td_rest.set_absorbing_boundary(LinearAbsorbingBoundary(5.0, 0.01,
                                                       atoms.positions.copy()))
td_rest.propagate(8.0, 5,
                  'be_nl_dmz_ipabs_1e-3.dat',
                  'be_nl_td.gpw')
Beispiel #17
0
from gpaw.tddft import TDDFT
from gpaw.tddft.ehrenfest import EhrenfestVelocityVerlet
import sys

d = 4.5
atoms = Atoms('NaCl', [(0,0,0),(0,0,d)])
atoms.center(vacuum=4.5)
d = 4.0
atoms.set_positions([(0,0,0),(0,0,d)])
atoms.center()

gs_calc = GPAW(nbands=4, gpts=(64,64,96), xc='LDA', setups='hgh')
atoms.set_calculator(gs_calc)
atoms.get_potential_energy()

gs_calc.write('nacl_hgh_gs.gpw', 'all')

td_calc = TDDFT('nacl_hgh_gs.gpw', propagator='ETRSCN')
evv = EhrenfestVelocityVerlet(td_calc, 0.001)

i=0
evv.get_energy()
r = evv.x[1][2] - evv.x[0][2]
print 'E = ', [i, r, evv.Etot, evv.Ekin, evv.Epot]
    
for i in range(10000):
    evv.propagate(1.0)
    evv.get_energy()
    r = evv.x[1][2] - evv.x[0][2]
    print 'E = ', [i+1, r, evv.Etot, evv.Ekin, evv.Epot]
from gpaw.tddft import TDDFT, photoabsorption_spectrum
from gpaw.inducedfield.inducedfield_tddft import TDDFTInducedField

# Calculate photoabsorption spectrum as usual
folding = 'Gauss'
width = 0.1
e_min = 0.0
e_max = 4.0
photoabsorption_spectrum('na2_td_dm.dat',
                         'na2_td_spectrum_x.dat',
                         folding=folding,
                         width=width,
                         e_min=e_min,
                         e_max=e_max,
                         delta_e=1e-2)

# Load TDDFT object
td_calc = TDDFT('na2_td.gpw')

# Load InducedField object
ind = TDDFTInducedField(filename='na2_td.ind', paw=td_calc)

# Calculate induced electric field
ind.calculate_induced_field(gridrefinement=2, from_density='comp')

# Save induced electric field
ind.write('na2_td_field.ind', mode='all')
input_file = name + '_run' + str(run) + '.gpw'
traj_file = strbody + '.traj'
filename = strbody + '.txt'
f = open(filename, "w")
Natoms = 106
Nkord = 3
p_bands = 2
print(en, run)
#number of iterations and integer divisor to update states every 0.02 fs
#ndiv = int(np.ceil(0.01e3 / timestep))
niter = ndiv * int(np.ceil(duration / (ndiv * timestep)))
#parallel = { 'band' : p_bands, 'domain' : None, 'sl_auto' : True}
#parallel = { 'band' : p_bands, 'domain' : None, 'sl_default' : (4, 4, 64)}
parallel = {'band': p_bands, 'domain': None}
tdcalc = TDDFT(input_file,
               solver='CSCG',
               propagator='EFSICN',
               parallel=parallel)

##Projectile part
proj_idx = Natoms - 1
v = np.zeros((Natoms, 3))  #set all velocity to zero
Mproj = tdcalc.atoms.get_masses()[proj_idx]

#Mat = []
#vat = np.zeros([12, 3])
#for i in range(0,12):
#    Mat.append(tdcalc.atoms.get_masses()[i]*amu_to_aumass)

#ekin projectile
Ekin *= Mproj
Ekin = Ekin / Hartree
Beispiel #20
0
d = 4.0
atoms = Atoms('NaCl', [(0, 0, 0), (0, 0, d)])
atoms.center(vacuum=4.5)

gs_calc = GPAW(nbands=4,
               eigensolver='cg',
               gpts=(32, 32, 44),
               xc='LDA',
               setups={'Na': '1'})
atoms.set_calculator(gs_calc)
atoms.get_potential_energy()

gs_calc.write('nacl_gs.gpw', 'all')

td_calc = TDDFT('nacl_gs.gpw', propagator='EFSICN')
evv = EhrenfestVelocityVerlet(td_calc, 0.001)

i = 0
evv.get_energy()
r = evv.x[1][2] - evv.x[0][2]
# print 'E = ', [i, r, evv.Etot, evv.Ekin, evv.e_coulomb]

for i in range(5):
    evv.propagate(1.0)
    evv.get_energy()
    r = evv.x[1][2] - evv.x[0][2]
    print('E = ', [i + 1, r, evv.Etot, evv.Ekin, evv.e_coulomb])

equal(r, 7.558883144, 1e-6)
equal(evv.Etot, -0.1036763317, 1e-7)
Beispiel #21
0
atoms.center(vacuum=4.0)

# Ground-state calculation
calc = GPAW(nbands=7,
            h=0.4,
            poissonsolver=PoissonSolver(eps=1e-16),
            convergence={'density': 1e-8},
            xc='GLLBSC',
            txt='gs.out')
atoms.set_calculator(calc)
energy = atoms.get_potential_energy()
calc.write('gs.gpw', mode='all')

fxc = 'LDA'
# Time-propagation calculation with linearize_to_fxc()
td_calc = TDDFT('gs.gpw', txt='td.out')
td_calc.linearize_to_xc(fxc)
td_calc.absorption_kick(np.ones(3) * 1e-5)
td_calc.propagate(20, 4, 'dm.dat')
world.barrier()

# Test the absolute values
data = np.loadtxt('dm.dat').ravel()
if 0:
    from gpaw.test import print_reference
    print_reference(data, 'ref', '%.12le')

ref = [
    0.0, 1.46915686e-15, -3.289312570937e-14, -2.273046460905e-14,
    -3.201827522804e-15, 0.82682747, 1.41057108e-15, 6.113786981692e-05,
    6.113754003915e-05, 6.113827654045e-05, 1.65365493, 1.69317502e-16,
Beispiel #22
0
class UTStaticPropagatorSetup(UTGroundStateSetup):
    __doc__ = UTGroundStateSetup.__doc__ + """
    Propagate electrons with fixed nuclei and verify results.""" #TODO

    duration = 10.0 #24.0

    timesteps = None
    propagator = None

    def setUp(self):
        UTGroundStateSetup.setUp(self)

        for virtvar in ['timesteps', 'propagator']:
            assert getattr(self,virtvar) is not None, 'Virtual "%s"!' % virtvar

        self.tdname = 'ut_tddft_td_' + self.propagator.lower()
        self.tdcalc = TDDFT(self.gsname + '.gpw', propagator=self.propagator,
                            txt=self.tdname + '.txt')

    def tearDown(self):
        del self.tdcalc

    # =================================

    def _test_timestepping(self, t):
        #XXX DEBUG START
        if debug and os.path.isfile('%s_%d.gpw' % (self.tdname, t)):
            return
        #XXX DEBUG END

        timestep = self.timesteps[t]
        self.assertAlmostEqual(self.duration % timestep, 0.0, 12)
        niter = int(self.duration / timestep)
        ndiv = 1 #XXX

        traj = PickleTrajectory('%s_%d.traj' % (self.tdname, t),
                                'w', self.tdcalc.get_atoms())

        t0 = time.time()
        f = paropen('%s_%d.log' % (self.tdname, t), 'w')
        print >>f, 'propagator: %s, duration: %6.1f as, timestep: %5.2f as, ' \
            'niter: %d' % (self.propagator, self.duration, timestep, niter)

        for i in range(1, niter+1):
            # XXX bare bones propagation without all the nonsense
            self.tdcalc.propagator.propagate(self.tdcalc.time,
                                             timestep * attosec_to_autime)
            self.tdcalc.time += timestep * attosec_to_autime
            self.tdcalc.niter += 1

            if i % ndiv == 0:
                rate = 60 * ndiv / (time.time()-t0)
                ekin = self.tdcalc.atoms.get_kinetic_energy()
                epot = self.tdcalc.get_td_energy() * Hartree
                F_av = np.zeros((len(self.tdcalc.atoms), 3))
                print >>f, 'i=%06d, time=%6.1f as, rate=%6.2f min^-1, ' \
                    'ekin=%13.9f eV, epot=%13.9f eV, etot=%13.9f eV' \
                    % (i, timestep * i, rate, ekin, epot, ekin + epot)
                t0 = time.time()

                # Hack to prevent calls to GPAW::get_potential_energy when saving
                spa = self.tdcalc.get_atoms()
                spc = SinglePointCalculator(epot, F_av, None, None, spa)
                spa.set_calculator(spc)
                traj.write(spa)
        f.close()
        traj.close()
        self.tdcalc.write('%s_%d.gpw' % (self.tdname, t), mode='all')

        # Save density and wavefunctions to binary
        gd, finegd = self.tdcalc.wfs.gd, self.tdcalc.density.finegd
        if world.rank == 0:
            big_nt_g = finegd.collect(self.tdcalc.density.nt_g)
            np.save('%s_%d_nt.npy' % (self.tdname, t), big_nt_g)
            del big_nt_g

            big_psit_nG = gd.collect(self.tdcalc.wfs.kpt_u[0].psit_nG)
            np.save('%s_%d_psit.npy' % (self.tdname, t), big_psit_nG)
            del big_psit_nG
        else:
            finegd.collect(self.tdcalc.density.nt_g)
            gd.collect(self.tdcalc.wfs.kpt_u[0].psit_nG)
        world.barrier()

    def test_timestepping_ref(self):
        # Reference values for density and wavefunctions (assumed stationary)
        nt0_g = self.tdcalc.density.nt_g
        phases_n = self.tdcalc.wfs.kpt_u[0].eps_n * self.duration * attosec_to_autime
        psit0_nG = np.exp(-1j * phases_n) * self.tdcalc.wfs.kpt_u[0].psit_nG

        f = paropen('%s_ref.log' % self.tdname, 'w')
        niters = np.round(self.duration / self.timesteps).astype(int)
        print >>f, 'propagator: %s, duration: %6.1f as, niters: %s, ' \
            % (self.propagator, self.duration, niters.tolist())

        for t,timestep in enumerate(self.timesteps):
            self.assertTrue(os.path.isfile('%s_%d.gpw' % (self.tdname, t)))

            # Load density and wavefunctions from binary
            gd, finegd = self.tdcalc.wfs.gd, self.tdcalc.density.finegd
            nt_g, psit_nG = finegd.empty(), gd.empty(self.nbands, dtype=complex)
            if world.rank == 0:
                big_nt_g = np.load('%s_%d_nt.npy' % (self.tdname, t))
                finegd.distribute(big_nt_g, nt_g)
                del big_nt_g

                big_psit_nG = np.load('%s_%d_psit.npy' % (self.tdname, t))
                gd.distribute(big_psit_nG, psit_nG)
                del big_psit_nG
            else:
                finegd.distribute(None, nt_g)
                gd.distribute(None, psit_nG)

            # Check loaded density and wavefunctions against reference values
            dnt = finegd.comm.max(np.abs(nt_g - nt0_g).max())
            dpsit = gd.comm.max(np.abs(psit_nG - psit0_nG).max())
            print >>f, 't=%d, timestep: %5.2f as, dnt: %16.13f, ' \
                'dpsit: %16.13f' % (t, timestep, dnt, dpsit)
            snt, spsit = {'SITE': (5,4)}.get(self.propagator, (7,5))
            #self.assertAlmostEqual(dnt, 0, snt, 't=%d, timestep: ' \
            #    '%5.2f as, dnt: %g, digits: %d' % (t, timestep, dnt, snt))
            #self.assertAlmostEqual(dpsit, 0, spsit, 't=%d, timestep: ' \
            #    '%5.2f as, dpsit=%g, digits: %d' % (t, timestep, dpsit, spsit))
        f.close()
Beispiel #23
0
import numpy as np
from ase import Atoms
from gpaw import GPAW
from gpaw.tddft import TDDFT
from gpaw.tddft.abc import LinearAbsorbingBoundary
from gpaw.tddft.laser import CWField

atoms = Atoms('Be', [(0, 0, 0)], pbc=False)
atoms.center(vacuum=6)
calc = GPAW(h=0.35)
atoms.set_calculator(calc)
atoms.get_potential_energy()

calc.write('be_gs.gpw', 'all')

td_calc = TDDFT('be_gs.gpw',
                td_potential=CWField(1e-3, 2.0 * np.pi / 50.0, 150.0))
td_calc.set_absorbing_boundary(
    LinearAbsorbingBoundary(5.0, 0.01, atoms.positions.copy()))
td_calc.propagate(8.0, 5, 'be_nl_dmz_ipabs_1e-3.dat', 'be_nl_td.gpw')

td_rest = TDDFT('be_nl_td.gpw',
                td_potential=CWField(1e-3, 2.0 * np.pi / 50.0, 150.0))
td_rest.set_absorbing_boundary(
    LinearAbsorbingBoundary(5.0, 0.01, atoms.positions.copy()))
td_rest.propagate(8.0, 5, 'be_nl_dmz_ipabs_1e-3.dat', 'be_nl_td.gpw')
Beispiel #24
0
            sigma = tar['Width']
        except KeyError:
            timestep = 1
            sigma = None
        omega_w = tar.get('Frequency')
        gamma_w = tar.get('PhaseFactor')
        Fnt_wsG = tar.get('FourierTransform')
        Ant_sG = tar.get('Average')
        atoms = None
        del tar

        gpw_filename = sys.argv[2]
        assert gpw_filename.endswith('.gpw'), 'Invalid GPW tarfile.'
        assert os.path.isfile(gpw_filename), 'GPW tarfile not found.'

        calc = TDDFT(gpw_filename, txt=None)
        obs = DensityFourierTransform(timestep * autime_to_attosec,
                                      omega_w * aufrequency_to_eV,
                                      (sigma is not None and sigma \
                                       * aufrequency_to_eV or None))
        obs.initialize(calc)
        atoms = calc.get_atoms()
        del calc
        obs.read(ftd_filename, idiotproof=False)
        try:
            sys.stdout.write('Select grid refinement [1*/2]: ')
            gdref = int(sys.stdin.readline().strip())
        except:
            gdref = 1
        getall = slice(None)  #hack to obtain all frequencies/spins
        Fnt_wsG = obs.get_fourier_transform(getall, getall, gdref)
from gpaw.tddft import TDDFT
from gpaw.inducedfield.inducedfield_tddft import TDDFTInducedField

# Load TDDFT object
td_calc = TDDFT('na2_td.gpw')

# Load and attach InducedField object
ind = TDDFTInducedField(filename='na2_td.ind',
                        paw=td_calc,
                        restart_file='na2_td.ind')

# Continue propagation as usual
time_step = 20.0
iterations = 250
td_calc.propagate(time_step, iterations, 'na2_td_dm.dat', 'na2_td.gpw')

# Save TDDFT and InducedField objects
td_calc.write('na2_td.gpw', mode='all')
ind.write('na2_td.ind')
Beispiel #26
0
        calc = GPAW(name + '_es.gpw',
                    txt=name + '_esx.txt',
                    parallel={'band': 1})
        calc.set_positions()
        dscf_collapse_orbitals(calc)
        calc.write(name + '_esx.gpw', mode='all')
        del calc
        time.sleep(10)

    while not os.path.isfile(name + '_esx.gpw'):
        print('Node %d waiting for %s...' % (world.rank, name + '_esx.gpw'))
        time.sleep(10)
    world.barrier()

    tdcalc = TDDFT(name + '_esx.gpw',
                   txt=name + '_td.txt',
                   propagator='EFSICN')
    ehrenfest = EhrenfestVelocityVerlet(tdcalc)
    traj = PickleTrajectory(name + '_td.traj', 'w', tdcalc.get_atoms())

    t0 = time.time()
    f = paropen(name + '_td.log', 'w')
    for i in range(1, niter + 1):
        ehrenfest.propagate(timestep)

        if i % ndiv == 0:
            rate = 60 * ndiv / (time.time() - t0)
            ekin = tdcalc.atoms.get_kinetic_energy()
            epot = tdcalc.get_td_energy() * Hartree
            F_av = ehrenfest.F * Hartree / Bohr
            print(
Beispiel #27
0
# Test floating point arithmetic errors
equal(gs_calc.hamiltonian.poisson.shift_indices_1, [4, 4, 10], 0)
equal(gs_calc.hamiltonian.poisson.shift_indices_2, [8, 8, 16], 0)

# Save state
gs_calc.write('gs.gpw', 'all')
classical_material = None
gs_calc = None

# Initialize TDDFT and FDTD
kick = [0.0, 0.0, 1.0e-3]
time_step = 10.0
iterations = 10

td_calc = TDDFT('gs.gpw')
td_calc.absorption_kick(kick_strength=kick)
td_calc.hamiltonian.poisson.set_kick(kick)

# Attach InducedFields to the calculation
frequencies = [2.05, 4.0]
width = 0.15
cl_ind = FDTDInducedField(paw=td_calc, frequencies=frequencies, width=width)
qm_ind = TDDFTInducedField(paw=td_calc, frequencies=frequencies, width=width)

# Propagate TDDFT and FDTD
td_calc.propagate(time_step, iterations // 2, 'dm.dat', 'td.gpw')
td_calc.write('td.gpw', 'all')
cl_ind.write('cl.ind')
qm_ind.write('qm.ind')
td_calc = None
Beispiel #28
0
class QSFDTD:
    def __init__(self,
                 classical_material,
                 atoms,
                 cells,
                 spacings,
                 communicator=serial_comm,
                 remove_moments=(1, 1)):

        self.td_calc = None

        # Define classical cell in one of these ways:
        # 1. [cx, cy, cz]   -> vacuum for the quantum grid = 4.0
        # 2. ([cx, cy, cz]) -> vacuum = 4.0
        # 3. ([cx, cy, cz], vacuum)
        # 4. ([cx, cy, cz], ([p1x, p1y, p1z], [p2x, p2y, p2z]))
        #    where p1 and p2 are corners of the quantum grid
        if len(cells) == 1:  # (cell)
            assert (len(cells[0]) == 3)
            cell = np.array(cells[0])
            vacuum = 4.0
        elif len(cells) == 3:  # [cell.x, cell.y, cell.z]
            cell = np.array(cells)
            vacuum = 4.0
        elif len(cells) == 2:  # cell + vacuum/corners
            cell = np.array(cells[0])
            if np.array(cells[1]).size == 1:
                vacuum = cells[1]
                corners = None
            else:
                vacuum = None
                corners = cells[1]
        else:
            raise Exception('QSFDTD: cells defined incorrectly')

        # Define spacings in in one of these ways:
        # 1. (clh, qmh)
        # 2. clh -> qmh=clh/4
        if np.array(spacings).size == 1:  # clh
            cl_spacing = spacings
            qm_spacing = 0.25 * cl_spacing
        elif len(spacings) == 2:  # (clh, qmh)
            cl_spacing = spacings[0]
            qm_spacing = spacings[1]
        else:
            raise Exception('QSFDTD: spacings defined incorrectly')

        self.poissonsolver = FDTDPoissonSolver(
            classical_material=classical_material,
            cl_spacing=cl_spacing,
            qm_spacing=qm_spacing,
            remove_moments=remove_moments,
            communicator=communicator,
            cell=cell)
        self.poissonsolver.set_calculation_mode('iterate')

        # Quantum system
        if atoms is not None:
            assert (len(cells) == 2)
            assert (len(spacings) == 2)
            assert (len(remove_moments) == 2)
            self.atoms = atoms
            self.atoms.set_cell(cell)
            if vacuum is not None:  # vacuum
                self.atoms, self.qm_spacing, self.gpts = \
                    self.poissonsolver.cut_cell(self.atoms, vacuum=vacuum)
            else:  # corners
                self.atoms, self.qm_spacing, self.gpts = \
                    self.poissonsolver.cut_cell(self.atoms, corners=corners)
        else:  # Dummy quantum system
            self.atoms = Atoms('H', [0.5 * cell], cell=cell)
            if vacuum is not None:  # vacuum
                self.atoms, self.qm_spacing, self.gpts = \
                    self.poissonsolver.cut_cell(self.atoms, vacuum=vacuum)
            else:  # corners
                self.atoms, self.qm_spacing, self.gpts = \
                    self.poissonsolver.cut_cell(self.atoms, corners=corners)
            del self.atoms[:]

    def ground_state(self, filename, **kwargs):
        # GPAW calculator for the ground state
        self.gs_calc = GPAW(gpts=self.gpts,
                            poissonsolver=self.poissonsolver,
                            **kwargs)
        self.atoms.set_calculator(self.gs_calc)
        self.energy = self.atoms.get_potential_energy()
        self.write(filename, mode='all')

    def write(self, filename, **kwargs):
        if self.td_calc is None:
            self.gs_calc.write(filename, **kwargs)
        else:
            self.td_calc.write(filename, **kwargs)

    def time_propagation(self,
                         filename,
                         kick_strength,
                         time_step,
                         iterations,
                         dipole_moment_file=None,
                         restart_file=None,
                         dump_interval=100,
                         **kwargs):
        self.td_calc = TDDFT(filename, **kwargs)
        if kick_strength is not None:
            self.td_calc.absorption_kick(kick_strength)
            self.td_calc.hamiltonian.poisson.set_kick(kick_strength)
        self.td_calc.propagate(time_step, iterations, dipole_moment_file,
                               restart_file, dump_interval)
Beispiel #29
0
# Initialize GPAW
gs_calc = GPAW(gpts=gpts,
               eigensolver='cg',
               nbands=-2,
               poissonsolver=poissonsolver)
atoms.set_calculator(gs_calc)

# Ground state
energy = atoms.get_potential_energy()

# Save state
gs_calc.write('gs.%s.gpw' % tag, 'all')

# Initialize TDDFT and FDTD
td_calc = TDDFT('gs.%s.gpw' % tag)
td_calc.absorption_kick(kick_strength=kick)
td_calc.hamiltonian.poisson.set_kick(kick)

# Propagate TDDFT and FDTD
td_calc.propagate(time_step, 50, 'dm.%s.dat' % tag, 'td.%s.gpw' % tag)

# Test
ref_cl_dipole_moment = [2.72623607e-02, 1.98393701e-09, -1.98271199e-09]
ref_qm_dipole_moment = [1.44266213e-02, 1.04985435e-09, -1.04920610e-09]

tol = 0.0001
equal(td_calc.get_dipole_moment(), ref_qm_dipole_moment, tol)
equal(td_calc.hamiltonian.poisson.get_dipole_moment(), ref_cl_dipole_moment,
      tol)
Beispiel #30
0
# Test floating point arithmetic errors
equal(gs_calc.hamiltonian.poisson.shift_indices_1, [4, 4, 10], 0)
equal(gs_calc.hamiltonian.poisson.shift_indices_2, [8, 8, 16], 0)

# Save state
gs_calc.write('gs.gpw', 'all')
classical_material = None
gs_calc = None

# Initialize TDDFT and FDTD
kick = [0.0, 0.0, 1.0e-3]
time_step = 10.0
max_time = 100  # 0.1 fs

td_calc = TDDFT('gs.gpw')
td_calc.absorption_kick(kick_strength=kick)
td_calc.hamiltonian.poisson.set_kick(kick)

# Propagate TDDFT and FDTD
td_calc.propagate(time_step, max_time / time_step / 2, 'dm.dat', 'td.gpw')

td_calc2 = TDDFT('td.gpw')
td_calc2.propagate(time_step, max_time / time_step / 2, 'dm.dat', 'td.gpw')

# Test
ref_cl_dipole_moment = [5.25374117e-14, 5.75811267e-14, 3.08349334e-02]
ref_qm_dipole_moment = [1.78620337e-11, -1.57782578e-11, 5.21368300e-01]
#print("ref_cl_dipole_moment = %s" % td_calc2.hamiltonian.poisson.get_classical_dipole_moment())
#print("ref_qm_dipole_moment = %s" % td_calc2.hamiltonian.poisson.get_quantum_dipole_moment())
Beispiel #31
0
class UTStaticPropagatorSetup(UTGroundStateSetup):
    __doc__ = UTGroundStateSetup.__doc__ + """
    Propagate electrons with fixed nuclei and verify results.""" #TODO

    duration = 10.0  #24.0

    timesteps = None
    propagator = None

    def setUp(self):
        UTGroundStateSetup.setUp(self)

        for virtvar in ['timesteps', 'propagator']:
            assert getattr(self,
                           virtvar) is not None, 'Virtual "%s"!' % virtvar

        self.tdname = 'ut_tddft_td_' + self.propagator.lower()
        self.tdcalc = TDDFT(self.gsname + '.gpw',
                            propagator=self.propagator,
                            txt=self.tdname + '.txt')

    def tearDown(self):
        del self.tdcalc

    # =================================

    def _test_timestepping(self, t):
        #XXX DEBUG START
        if debug and os.path.isfile('%s_%d.gpw' % (self.tdname, t)):
            return
        #XXX DEBUG END

        timestep = self.timesteps[t]
        self.assertAlmostEqual(self.duration % timestep, 0.0, 12)
        niter = int(self.duration / timestep)
        ndiv = 1  #XXX

        traj = PickleTrajectory('%s_%d.traj' % (self.tdname, t), 'w',
                                self.tdcalc.get_atoms())

        t0 = time.time()
        f = paropen('%s_%d.log' % (self.tdname, t), 'w')
        print('propagator: %s, duration: %6.1f as, timestep: %5.2f as, ' \
            'niter: %d' % (self.propagator, self.duration, timestep, niter), file=f)

        for i in range(1, niter + 1):
            # XXX bare bones propagation without all the nonsense
            self.tdcalc.propagator.propagate(self.tdcalc.time,
                                             timestep * attosec_to_autime)
            self.tdcalc.time += timestep * attosec_to_autime
            self.tdcalc.niter += 1

            if i % ndiv == 0:
                rate = 60 * ndiv / (time.time() - t0)
                ekin = self.tdcalc.atoms.get_kinetic_energy()
                epot = self.tdcalc.get_td_energy() * Hartree
                F_av = np.zeros((len(self.tdcalc.atoms), 3))
                print('i=%06d, time=%6.1f as, rate=%6.2f min^-1, ' \
                    'ekin=%13.9f eV, epot=%13.9f eV, etot=%13.9f eV' \
                    % (i, timestep * i, rate, ekin, epot, ekin + epot), file=f)
                t0 = time.time()

                # Hack to prevent calls to GPAW::get_potential_energy when saving
                spa = self.tdcalc.get_atoms()
                spc = SinglePointCalculator(epot, F_av, None, None, spa)
                spa.set_calculator(spc)
                traj.write(spa)
        f.close()
        traj.close()
        self.tdcalc.write('%s_%d.gpw' % (self.tdname, t), mode='all')

        # Save density and wavefunctions to binary
        gd, finegd = self.tdcalc.wfs.gd, self.tdcalc.density.finegd
        if world.rank == 0:
            big_nt_g = finegd.collect(self.tdcalc.density.nt_g)
            np.save('%s_%d_nt.npy' % (self.tdname, t), big_nt_g)
            del big_nt_g

            big_psit_nG = gd.collect(self.tdcalc.wfs.kpt_u[0].psit_nG)
            np.save('%s_%d_psit.npy' % (self.tdname, t), big_psit_nG)
            del big_psit_nG
        else:
            finegd.collect(self.tdcalc.density.nt_g)
            gd.collect(self.tdcalc.wfs.kpt_u[0].psit_nG)
        world.barrier()

    def test_timestepping_ref(self):
        # Reference values for density and wavefunctions (assumed stationary)
        nt0_g = self.tdcalc.density.nt_g
        phases_n = self.tdcalc.wfs.kpt_u[
            0].eps_n * self.duration * attosec_to_autime
        psit0_nG = np.exp(-1j * phases_n) * self.tdcalc.wfs.kpt_u[0].psit_nG

        f = paropen('%s_ref.log' % self.tdname, 'w')
        niters = np.round(self.duration / self.timesteps).astype(int)
        print('propagator: %s, duration: %6.1f as, niters: %s, ' \
            % (self.propagator, self.duration, niters.tolist()), file=f)

        for t, timestep in enumerate(self.timesteps):
            self.assertTrue(os.path.isfile('%s_%d.gpw' % (self.tdname, t)))

            # Load density and wavefunctions from binary
            gd, finegd = self.tdcalc.wfs.gd, self.tdcalc.density.finegd
            nt_g, psit_nG = finegd.empty(), gd.empty(self.nbands,
                                                     dtype=complex)
            if world.rank == 0:
                big_nt_g = np.load('%s_%d_nt.npy' % (self.tdname, t))
                finegd.distribute(big_nt_g, nt_g)
                del big_nt_g

                big_psit_nG = np.load('%s_%d_psit.npy' % (self.tdname, t))
                gd.distribute(big_psit_nG, psit_nG)
                del big_psit_nG
            else:
                finegd.distribute(None, nt_g)
                gd.distribute(None, psit_nG)

            # Check loaded density and wavefunctions against reference values
            dnt = finegd.comm.max(np.abs(nt_g - nt0_g).max())
            dpsit = gd.comm.max(np.abs(psit_nG - psit0_nG).max())
            print('t=%d, timestep: %5.2f as, dnt: %16.13f, ' \
                'dpsit: %16.13f' % (t, timestep, dnt, dpsit), file=f)
            snt, spsit = {'SITE': (5, 4)}.get(self.propagator, (7, 5))
            #self.assertAlmostEqual(dnt, 0, snt, 't=%d, timestep: ' \
            #    '%5.2f as, dnt: %g, digits: %d' % (t, timestep, dnt, snt))
            #self.assertAlmostEqual(dpsit, 0, spsit, 't=%d, timestep: ' \
            #    '%5.2f as, dpsit=%g, digits: %d' % (t, timestep, dpsit, spsit))
        f.close()
Beispiel #32
0
Ekin = 40e3  # kinetic energy of the ion (in eV)

# Adapted to the ion energy; here 4 as (probably too large!)
timestep = 16.0 * np.sqrt(10e3 / Ekin)
ekin_str = '_ek' + str(int(Ekin / 1000)) + 'k'
strbody = name + ekin_str
traj_file = strbody + '.traj'

# The parallelization options should match the number of cores, here 8.
p_bands = 2  # number of bands to parallelise over
dom_dc = (2, 2, 4)  # domain decomposition for parallelization
parallel = {'band': p_bands, 'domain': dom_dc}

tdcalc = TDDFT(name + '.gpw',
               propagator='EFSICN',
               solver='BiCGStab',
               txt=strbody + '_td.txt',
               parallel=parallel)

proj_idx = 50  # atomic index of the projectile
delta_stop = 5.0 / Bohr  # stop condition when ion is within 5 A of boundary.

# Setting the initial velocity according to the kinetic energy.
amu_to_aumass = _amu / _me
Mproj = tdcalc.atoms.get_masses()[proj_idx] * amu_to_aumass
Ekin *= 1 / Hartree
v = np.zeros((proj_idx + 1, 3))
v[proj_idx, 2] = -np.sqrt((2 * Ekin) / Mproj) * Bohr / AUT
tdcalc.atoms.set_velocities(v)

evv = EhrenfestVelocityVerlet(tdcalc)
Beispiel #33
0
from ase.io import Trajectory
from ase.parallel import parprint

name = 'h2_diss'

# Ehrenfest simulation parameters
timestep = 10.0  # timestep given in attoseconds
ndiv = 10  # write trajectory every 10 timesteps
niter = 500  # run for 500 timesteps

# TDDFT calculator with an external potential emulating an intense
# harmonic laser field aligned (CWField uses by default the z axis)
# along the H2 molecular axis.
tdcalc = TDDFT(name + '_gs.gpw',
               txt=name + '_td.txt',
               propagator='EFSICN',
               solver='BiCGStab',
               td_potential=CWField(1000 * Hartree, 1 * AUT, 10))

# For Ehrenfest dynamics, we use this object for the Velocity Verlet dynamics.
ehrenfest = EhrenfestVelocityVerlet(tdcalc)

# Trajectory to save the dynamics.
traj = Trajectory(name + '_td.traj', 'w', tdcalc.get_atoms())

# Propagates the dynamics for niter timesteps.
for i in range(1, niter + 1):
    ehrenfest.propagate(timestep)

    if tdcalc.atoms.get_distance(0, 1) > 2.0:
        # Stop simulation if H-H distance is greater than 2 A
Beispiel #34
0
atoms.center(vacuum=6.0)
# Larger grid spacing, LDA is ok
gs_calc = GPAW(nbands=1, h=0.35, xc='LDA', setups={'Na': '1'})
atoms.set_calculator(gs_calc)
e = atoms.get_potential_energy()
niter = gs_calc.get_number_of_iterations()
gs_calc.write('na2_gs.gpw', 'all')

# 16 fs run with 8.0 attosec time step
time_step = 8.0  # 8.0 as (1 as = 0.041341 autime)5D
iters = 10  # 2000 x 8 as => 16 fs
# Weak delta kick to z-direction
kick = [0, 0, 1e-3]

# TDDFT calculator
td_calc = TDDFT('na2_gs.gpw')
# Kick
td_calc.absorption_kick(kick)
# Propagate
td_calc.propagate(time_step, iters, 'na2_dmz.dat', 'na2_td.gpw')
# Linear absorption spectrum
photoabsorption_spectrum('na2_dmz.dat', 'na2_spectrum_z.dat', width=0.3)

iters = 3

# test restart
td_rest = TDDFT('na2_td.gpw')
td_rest.propagate(time_step, iters, 'na2_dmz2.dat', 'na2_td2.gpw')

# test restart
td_rest = TDDFT('na2_td.gpw', solver='BiCGStab')
# Initialize GPAW
gs_calc = GPAW(gpts          = gpts,
               eigensolver   = 'cg',
               nbands        = -2,
               poissonsolver = poissonsolver)
atoms.set_calculator(gs_calc)

# Ground state
energy = atoms.get_potential_energy()

# Save state
gs_calc.write('gs.%s.gpw' % tag, 'all')

# Initialize TDDFT and FDTD
td_calc = TDDFT('gs.%s.gpw' % tag)
td_calc.absorption_kick(kick_strength=kick)
td_calc.hamiltonian.poisson.set_kick(kick)

# Propagate TDDFT and FDTD
td_calc.propagate(time_step,
                  50,
                  'dm.%s.dat' % tag,
                  'td.%s.gpw' % tag)

# Test
ref_cl_dipole_moment = [ 2.72623607e-02,  1.98393701e-09, -1.98271199e-09 ]
ref_qm_dipole_moment = [ 1.44266213e-02,  1.04985435e-09, -1.04920610e-09 ]

tol = 0.0001
equal(td_calc.get_dipole_moment(), ref_qm_dipole_moment, tol)