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
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
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
# 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)
# 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
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')
# 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)
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')
# 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')
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)