예제 #1
0
    def initialize(self, paw):
        self.timer = paw.timer
        self.timer.start('Initialize TDDFT Hamiltonian')
        self.wfs = paw.wfs
        self.density = paw.density
        self.hamiltonian = paw.hamiltonian
        self.occupations = paw.occupations
        niter = paw.niter

        # Reset the density mixer
        # XXX: density mixer is not written to the gpw file
        # XXX: so we need to set it always
        self.density.set_mixer(DummyMixer())
        self.update()

        # Initialize fxc
        self.initialize_fxc(niter)
        self.timer.stop('Initialize TDDFT Hamiltonian')
예제 #2
0
파일: __init__.py 프로젝트: thonmaker/gpaw
    def __init__(self,
                 filename,
                 td_potential=None,
                 propagator='SICN',
                 calculate_energy=True,
                 propagator_kwargs=None,
                 solver='CSCG',
                 tolerance=1e-8,
                 **kwargs):
        """Create TDDFT-object.

        Parameters:

        filename: string
            File containing ground state or time-dependent state to propagate
        td_potential: class, optional
            Function class for the time-dependent potential. Must have a method
            'strength(time)' which returns the strength of the linear potential
            to each direction as a vector of three floats.
        propagator:  {'SICN','ETRSCN','ECN','SITE','SIKE4','SIKE5','SIKE6'}
            Name of the time propagator for the Kohn-Sham wavefunctions
        solver: {'CSCG','BiCGStab'}
            Name of the iterative linear equations solver for time propagation
        tolerance: float
            Tolerance for the linear solver

        The following parameters can be used: `txt`, `parallel`, `communicator`
        `mixer` and `dtype`. The internal parameters `mixer` and `dtype` are
        strictly used to specify a dummy mixer and complex type respectively.
        """

        # Set initial time
        self.time = 0.0

        # Set initial kick strength
        self.kick_strength = np.array([0.0, 0.0, 0.0], dtype=float)

        # Set initial value of iteration counter
        self.niter = 0

        # Parallelization dictionary should default to strided bands
        self.default_parallel = GPAW.default_parallel.copy()
        self.default_parallel['stridebands'] = True

        self.default_parameters = GPAW.default_parameters.copy()
        self.default_parameters['mixer'] = DummyMixer()

        # NB: TDDFT restart files contain additional information which
        #     will override the initial settings for time/kick/niter.
        GPAW.__init__(self, filename, **kwargs)

        assert isinstance(self.wfs, TimeDependentWaveFunctions)
        assert isinstance(self.wfs.overlap, TimeDependentOverlap)

        # Prepare for dipole moment file handle
        self.dm_file = None

        # Initialize wavefunctions and density
        # (necessary after restarting from file)
        if not self.initialized:
            self.initialize()
        self.set_positions()

        # Don't be too strict
        self.density.charge_eps = 1e-5

        wfs = self.wfs
        self.rank = wfs.world.rank

        self.text = self.log
        self.text('')
        self.text('')
        self.text('------------------------------------------')
        self.text('  Time-propagation TDDFT                  ')
        self.text('------------------------------------------')
        self.text('')

        self.text('Charge epsilon: ', self.density.charge_eps)

        # Time-dependent variables and operators
        self.td_potential = td_potential
        self.td_hamiltonian = TimeDependentHamiltonian(self.wfs, self.spos_ac,
                                                       self.hamiltonian,
                                                       td_potential)
        self.td_overlap = self.wfs.overlap  # TODO remove this property
        self.td_density = TimeDependentDensity(self)

        # Solver for linear equations
        self.text('Solver: ', solver)
        if solver == 'BiCGStab':
            self.solver = BiCGStab(gd=wfs.gd,
                                   timer=self.timer,
                                   tolerance=tolerance)
        elif solver == 'CSCG':
            self.solver = CSCG(gd=wfs.gd,
                               timer=self.timer,
                               tolerance=tolerance)
        else:
            raise RuntimeError('Solver %s not supported.' % solver)

        # Preconditioner
        # No preconditioner as none good found
        self.text('Preconditioner: ', 'None')
        self.preconditioner = None  # TODO! check out SSOR preconditioning
        # self.preconditioner = InverseOverlapPreconditioner(self.overlap)
        # self.preconditioner = KineticEnergyPreconditioner(
        #    wfs.gd, self.td_hamiltonian.hamiltonian.kin, np.complex)

        # Time propagator
        self.text('Propagator: ', propagator)
        if propagator_kwargs is None:
            propagator_kwargs = {}
        if propagator == 'ECN':
            self.propagator = ExplicitCrankNicolson(
                self.td_density, self.td_hamiltonian, self.td_overlap,
                self.solver, self.preconditioner, wfs.gd, self.timer,
                **propagator_kwargs)
        elif propagator == 'SICN':
            self.propagator = SemiImplicitCrankNicolson(
                self.td_density, self.td_hamiltonian, self.td_overlap,
                self.solver, self.preconditioner, wfs.gd, self.timer,
                **propagator_kwargs)
        elif propagator == 'EFSICN':
            self.propagator = EhrenfestPAWSICN(self.td_density,
                                               self.td_hamiltonian,
                                               self.td_overlap, self.solver,
                                               self.preconditioner, wfs.gd,
                                               self.timer, **propagator_kwargs)
        elif propagator == 'EFSICN_HGH':
            self.propagator = EhrenfestHGHSICN(self.td_density,
                                               self.td_hamiltonian,
                                               self.td_overlap, self.solver,
                                               self.preconditioner, wfs.gd,
                                               self.timer, **propagator_kwargs)
        elif propagator == 'ETRSCN':
            self.propagator = EnforcedTimeReversalSymmetryCrankNicolson(
                self.td_density, self.td_hamiltonian, self.td_overlap,
                self.solver, self.preconditioner, wfs.gd, self.timer,
                **propagator_kwargs)
        elif propagator == 'SITE':
            self.propagator = SemiImplicitTaylorExponential(
                self.td_density, self.td_hamiltonian, self.td_overlap,
                self.solver, self.preconditioner, wfs.gd, self.timer,
                **propagator_kwargs)
        elif propagator == 'SIKE':
            self.propagator = SemiImplicitKrylovExponential(
                self.td_density, self.td_hamiltonian, self.td_overlap,
                self.solver, self.preconditioner, wfs.gd, self.timer,
                **propagator_kwargs)
        elif propagator.startswith('SITE') or propagator.startswith('SIKE'):
            raise DeprecationWarning(
                'Use propagator_kwargs to specify degree.')
        else:
            raise RuntimeError('Time propagator %s not supported.' %
                               propagator)

        if self.rank == 0:
            if wfs.kd.comm.size > 1:
                if wfs.nspins == 2:
                    self.text('Parallelization Over Spin')

                if wfs.gd.comm.size > 1:
                    self.text('Using Domain Decomposition: %d x %d x %d' %
                              tuple(wfs.gd.parsize_c))

                if wfs.bd.comm.size > 1:
                    self.text('Parallelization Over bands on %d Processors' %
                              wfs.bd.comm.size)
            self.text('States per processor = ', wfs.bd.mynbands)

        self.hpsit = None
        self.eps_tmp = None
        self.mblas = MultiBlas(wfs.gd)

        # Restarting an FDTD run generates hamiltonian.fdtd_poisson, which
        # now overwrites hamiltonian.poisson
        if hasattr(self.hamiltonian, 'fdtd_poisson'):
            self.hamiltonian.poisson = self.hamiltonian.fdtd_poisson
            self.hamiltonian.poisson.set_grid_descriptor(self.density.finegd)

        # For electrodynamics mode
        if self.hamiltonian.poisson.get_description() == 'FDTD+TDDFT':
            self.initialize_FDTD()
            self.hamiltonian.poisson.print_messages(self.text)
            self.log.flush()

        self.calculate_energy = calculate_energy
        if self.hamiltonian.xc.name.startswith('GLLB'):
            self.text('GLLB model potential. Not updating energy.')
            self.calculate_energy = False
예제 #3
0
파일: __init__.py 프로젝트: thonmaker/gpaw
 def initialize(self, reading=False):
     self.parameters.mixer = DummyMixer()
     self.parameters.experimental['reuse_wfs_method'] = None
     GPAW.initialize(self, reading=reading)
예제 #4
0
    def tddft_init(self):
        if self.tddft_initialized:
            return
        self.blacs = self.wfs.ksl.using_blacs
        if self.blacs:
            self.ksl = ksl = self.wfs.ksl
            nao = ksl.nao
            nbands = ksl.bd.nbands
            mynbands = ksl.bd.mynbands
            blocksize = ksl.blocksize

            from gpaw.blacs import Redistributor
            if self.wfs.world.rank == 0:
                print('BLACS Parallelization')

            # Parallel grid descriptors
            grid = ksl.blockgrid
            assert grid.nprow * grid.npcol == self.wfs.ksl.block_comm.size
            # FOR DEBUG
            self.MM_descriptor = grid.new_descriptor(nao, nao, nao, nao)
            self.mm_block_descriptor = grid.new_descriptor(
                nao, nao, blocksize, blocksize)
            self.Cnm_block_descriptor = grid.new_descriptor(
                nbands, nao, blocksize, blocksize)
            # self.CnM_descriptor = ksl.blockgrid.new_descriptor(nbands,
            #     nao, mynbands, nao)
            self.mM_column_descriptor = ksl.single_column_grid.new_descriptor(
                nao, nao, ksl.naoblocksize, nao)
            self.CnM_unique_descriptor = ksl.single_column_grid.new_descriptor(
                nbands, nao, mynbands, nao)

            # Redistributors
            self.mm2MM = Redistributor(ksl.block_comm,
                                       self.mm_block_descriptor,
                                       self.MM_descriptor)  # XXX FOR DEBUG
            self.MM2mm = Redistributor(ksl.block_comm, self.MM_descriptor,
                                       self.mm_block_descriptor)  # FOR DEBUG
            self.Cnm2nM = Redistributor(ksl.block_comm,
                                        self.Cnm_block_descriptor,
                                        self.CnM_unique_descriptor)
            self.CnM2nm = Redistributor(ksl.block_comm,
                                        self.CnM_unique_descriptor,
                                        self.Cnm_block_descriptor)
            self.mM2mm = Redistributor(ksl.block_comm,
                                       self.mM_column_descriptor,
                                       self.mm_block_descriptor)

            for kpt in self.wfs.kpt_u:
                scalapack_zero(self.mm_block_descriptor, kpt.S_MM, 'U')
                scalapack_zero(self.mm_block_descriptor, kpt.T_MM, 'U')

            # XXX to propagator class
            if self.propagator == 'taylor' and self.blacs:
                # cholS_mm = self.mm_block_descriptor.empty(dtype=complex)
                for kpt in self.wfs.kpt_u:
                    kpt.invS_MM = kpt.S_MM.copy()
                    scalapack_inverse(self.mm_block_descriptor, kpt.invS_MM,
                                      'L')
            if self.propagator == 'taylor' and not self.blacs:
                tmp = inv(self.wfs.kpt_u[0].S_MM)
                self.wfs.kpt_u[0].invS = tmp

        # Reset the density mixer
        self.density.set_mixer(DummyMixer())
        self.tddft_initialized = True
        for k, kpt in enumerate(self.wfs.kpt_u):
            kpt.C2_nM = kpt.C_nM.copy()
예제 #5
0
    def tddft_init(self):
        if not self.tddft_initialized:
            if world.rank == 0:
                print('Initializing real time LCAO TD-DFT calculation.')
                print('XXX Warning: Array use not optimal for memory.')
                print('XXX Taylor propagator probably doesn\'t work')
                print('XXX ...and no arrays are listed in memory estimate yet.')
            self.blacs = self.wfs.ksl.using_blacs
            if self.blacs:
                self.ksl = ksl = self.wfs.ksl    
                nao = ksl.nao
                nbands = ksl.bd.nbands
                mynbands = ksl.bd.mynbands
                blocksize = ksl.blocksize

                from gpaw.blacs import Redistributor
                if world.rank == 0:
                    print('BLACS Parallelization')

                # Parallel grid descriptors
                self.MM_descriptor = ksl.blockgrid.new_descriptor(nao, nao, nao, nao) # FOR DEBUG
                self.mm_block_descriptor = ksl.blockgrid.new_descriptor(nao, nao, blocksize, blocksize)
                self.Cnm_block_descriptor = ksl.blockgrid.new_descriptor(nbands, nao, blocksize, blocksize)
                #self.CnM_descriptor = ksl.blockgrid.new_descriptor(nbands, nao, mynbands, nao)
                self.mM_column_descriptor = ksl.single_column_grid.new_descriptor(nao, nao, ksl.naoblocksize, nao)
                self.CnM_unique_descriptor = ksl.single_column_grid.new_descriptor(nbands, nao, mynbands, nao)

                # Redistributors
                self.mm2MM = Redistributor(ksl.block_comm,
                                           self.mm_block_descriptor,
                                           self.MM_descriptor) # XXX FOR DEBUG
                self.MM2mm = Redistributor(ksl.block_comm,
                                           self.MM_descriptor,
                                           self.mm_block_descriptor) # XXX FOR DEBUG
                self.Cnm2nM = Redistributor(ksl.block_comm,
                                            self.Cnm_block_descriptor,
                                            self.CnM_unique_descriptor) 
                self.CnM2nm = Redistributor(ksl.block_comm,
                                            self.CnM_unique_descriptor,
                                            self.Cnm_block_descriptor) 
                self.mM2mm =  Redistributor(ksl.block_comm,
                                            self.mM_column_descriptor,
                                            self.mm_block_descriptor)

                for kpt in self.wfs.kpt_u:
                    scalapack_zero(self.mm_block_descriptor, kpt.S_MM,'U')
                    scalapack_zero(self.mm_block_descriptor, kpt.T_MM,'U')

                # XXX to propagator class
                if self.propagator == 'taylor' and self.blacs:  
                    # cholS_mm = self.mm_block_descriptor.empty(dtype=complex)
                    for kpt in self.wfs.kpt_u:
                        kpt.invS_MM = kpt.S_MM.copy()
                        scalapack_inverse(self.mm_block_descriptor,
                                          kpt.invS_MM, 'L')
                    if self.propagator_debug:
                        if world.rank == 0:
                            print('XXX Doing serial inversion of overlap matrix.')
                        self.timer.start('Invert overlap (serial)')
                        invS2_MM = self.MM_descriptor.empty(dtype=complex)
                        for kpt in self.wfs.kpt_u:
                            #kpt.S_MM[:] = 128.0*(2**world.rank)
                            self.mm2MM.redistribute(self.wfs.S_qMM[kpt.q], invS2_MM)
                            world.barrier()
                            if world.rank == 0:
                                tri2full(invS2_MM,'L')
                                invS2_MM[:] = inv(invS2_MM.copy())
                                self.invS2_MM = invS2_MM
                            kpt.invS2_MM = ksl.mmdescriptor.empty(dtype=complex)
                            self.MM2mm.redistribute(invS2_MM, kpt.invS2_MM)
                            verify(kpt.invS_MM, kpt.invS2_MM, 'overlap par. vs. serial', 'L')
                        self.timer.stop('Invert overlap (serial)')
                        if world.rank == 0:
                            print('XXX Overlap inverted.')
                if self.propagator == 'taylor' and not self.blacs:
                    tmp = inv(self.wfs.kpt_u[0].S_MM)
                    self.wfs.kpt_u[0].invS = tmp

            # Reset the density mixer
            self.density.mixer = DummyMixer()    
            self.tddft_initialized = True
            for k, kpt in enumerate(self.wfs.kpt_u):
                kpt.C2_nM = kpt.C_nM.copy()
예제 #6
0
 def initialize(self, reading=False):
     self.parameters.mixer = DummyMixer()
     GPAW.initialize(self, reading=reading)