Exemple #1
0
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()
Exemple #2
0
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()