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() # Hack to prevent calls to GPAW::get_potential_energy when saving
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) traj = Trajectory(traj_file, 'w', tdcalc.get_atoms()) trajdiv = 1 # number of timesteps between trajectory images densdiv = 10 # number of timesteps between saved electron densities niters = 100 # total number of timesteps to propagate for i in range(niters): # Stopping condition when projectile z coordinate passes threshold if evv.x[proj_idx, 2] < delta_stop: tdcalc.write(strbody + '_end.gpw', mode='all') break # Saving trajectory file every trajdiv timesteps if i % trajdiv == 0: F_av = evv.F * Hartree / Bohr # forces converted from atomic units v_av = evv.v * Bohr / AUT # velocities converted from atomic units
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) Ant_sG = obs.get_average(getall, gdref) del obs # Save modulus and phase as .cube files for all frequencies/spins for w, Fnt_sG in enumerate(Fnt_wsG): for s, Fnt_G in enumerate(Fnt_sG):
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( 'i=%06d (%6.2f min^-1), ekin=%13.9f, epot=%13.9f, etot=%13.9f' % (i, rate, ekin, epot, ekin + epot), file=f)
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()
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 parprint('Dissociated!') break # Every ndiv timesteps, save an image in the trajectory file. if i % ndiv == 0: # Currently needed with Ehrenfest dynamics to save energy, # forces and velocitites. epot = tdcalc.get_td_energy() * Hartree
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()
#for i in range(0,12): # for j in range(0,3): # vat[i,j] = rd.uniform (0,1) / (3* Mat[i])**0.5 # v[i,j] = vat[i,j] # #world.broadcast(vat, 0) #ekint = 0.5 * np.dot(Mat, np.sum(vat**2, axis=1)) #vat *= (Ekint/ekint)**0.5 #for i in range(0,12): # for j in range(0,3): # v[i,j] = vat[i,j] tdcalc.atoms.set_velocities(v) evv = EhrenfestVelocityVerlet(tdcalc) traj = Trajectory(traj_file, 'w', tdcalc.get_atoms()) t0 = time.time() m = 0 epow = np.zeros(niter) xproj = np.zeros(niter) sp = 0 for i in range(niter): Ekin_p = 0.5 *evv.M[proj_idx] * (evv.v[proj_idx, 0]**2 \ + evv.v[proj_idx, 1]**2 \ + evv.v[proj_idx, 2]**2 ) if i % ndiv == 0: spa = tdcalc.get_atoms() F_av = evv.F * Hartree / Bohr epot = tdcalc.get_td_energy() * Hartree