Beispiel #1
0
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')

# Save TDDFT and InducedField objects
td_calc.write('na2_td.gpw', mode='all')
ind.write('na2_td.ind')
ind.paw = None

# Restart and continue
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
Beispiel #2
0
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')
td_rest.propagate(time_step, iters, 'na2_dmz3.dat', 'na2_td3.gpw')

# test absorbing boundary conditions
Beispiel #3
0
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')
td_rest.propagate(time_step, iters, 'na2_dmz3.dat', 'na2_td3.gpw')

# test absorbing boundary conditions
Beispiel #4
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())

tol = 1e-4
equal(td_calc2.hamiltonian.poisson.get_classical_dipole_moment(),
      ref_cl_dipole_moment, tol)
equal(td_calc2.hamiltonian.poisson.get_quantum_dipole_moment(),
      ref_qm_dipole_moment, tol)
Beispiel #5
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
data_tj = np.loadtxt('dm.dat')
# Original run
Beispiel #6
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)
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 #8
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 #9
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 #10
0
# Save state
gs_calc.write('gs.gpw', 'all')

# Initialize TDDFT and FDTD
kick = [0.001, 0.000, 0.000]
time_step = 10
iterations = 1000

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

# Attach InducedField to the calculation
frequencies = [2.45]
width = 0.0
ind = FDTDInducedField(paw=td_calc, frequencies=frequencies, width=width)

# Propagate TDDFT and FDTD
td_calc.propagate(time_step, iterations, 'dm0.dat', 'td.gpw')

# Save results
td_calc.write('td.gpw', 'all')
ind.write('td.ind')

# Spectrum
photoabsorption_spectrum('dm0.dat', 'spec.dat', width=width)

# Induced field
ind.calculate_induced_field(gridrefinement=2)
ind.write('field.ind', mode='all')
Beispiel #11
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')
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)
               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)