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') # Save TDDFT and InducedField objects
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') td_rest.propagate(time_step, iters, 'na2_dmz3.dat', 'na2_td3.gpw')
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 td_rest = TDDFT('na2_td.gpw', solver='BiCGStab') td_rest.propagate(time_step, iters, 'na2_dmz3.dat', 'na2_td3.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)
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 data_tj = np.loadtxt('dm.dat')
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') # Save TDDFT and InducedField objects
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)