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 epot = tdcalc.get_td_energy() * Hartree # energy atoms = tdcalc.get_atoms().copy() atoms.set_velocities(v_av) traj.write(atoms, energy=epot, forces=F_av) # Saving electron density every densdiv timesteps if (i != 0 and i % densdiv == 0): tdcalc.write(strbody + '_step' + str(i) + '.gpw') evv.propagate(timestep) traj.close()
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()
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 spa = tdcalc.get_atoms() spc = SinglePointCalculator(epot, F_av, None, None, spa) spa.set_calculator(spc) traj.write(spa) f.close() traj.close()
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()