Exemplo n.º 1
0
    def set_calculator(self, config, filename):
        kwargs = {}
        kwargs.update(self.input_parameters)

        if self.write_gpw_file is not None:
            self.gpwfilename = filename[:-4] + 'gpw'

        if 'txt' not in kwargs:
            kwargs['txt'] = filename[:-4] + 'txt'
        
        if not config.pbc.any():
            # Isolated atom or molecule:
            config.center(vacuum=self.vacuum)
            if (len(config) == 1 and
                config.get_initial_magnetic_moments().any()):
                kwargs['hund'] = True

        # Use fixed number of gpts:
        if 'gpts' not in kwargs:
            h = kwargs.get('h', 0.2)
            gpts = h2gpts(h, config.cell)
            kwargs['h'] = None
            kwargs['gpts'] = gpts
        
        self.calc = GPAW(**kwargs)
        config.set_calculator(self.calc)
Exemplo n.º 2
0
class GPAWRunner(Runner):
    """GPAW implementation"""
    def set_parameters(self, vacuum=3.0, write_gpw_file=None, **kwargs):
        self.vacuum = vacuum
        self.write_gpw_file = write_gpw_file
        self.gpwfilename = None
        self.input_parameters = kwargs
        
    def set_calculator(self, config, filename):
        kwargs = {}
        kwargs.update(self.input_parameters)

        if self.write_gpw_file is not None:
            self.gpwfilename = filename[:-4] + 'gpw'

        if 'txt' not in kwargs:
            kwargs['txt'] = filename[:-4] + 'txt'
        
        if not config.pbc.any():
            # Isolated atom or molecule:
            config.center(vacuum=self.vacuum)
            if (len(config) == 1 and
                config.get_initial_magnetic_moments().any()):
                kwargs['hund'] = True

        # Use fixed number of gpts:
        if 'gpts' not in kwargs:
            h = kwargs.get('h', 0.2)
            gpts = h2gpts(h, config.cell)
            kwargs['h'] = None
            kwargs['gpts'] = gpts
        
        self.calc = GPAW(**kwargs)
        config.set_calculator(self.calc)

    def get_calculator(self):
        """Returns the calculator object - available when finished only."""
        return self.calc

    def post_process(self, config):
        if self.write_gpw_file is not None:
            self.calc.write(self.gpwfilename, mode=self.write_gpw_file)
        
    def check_occupation_numbers(self, config):
        """Check that occupation numbers are integers."""
        if config.pbc.any():
            return
        calc = config.get_calculator()
        nspins = calc.get_number_of_spins()
        for s in range(nspins):
            f = calc.get_occupation_numbers(spin=s)
            if abs(f % (2 // nspins)).max() > 0.0001:
                raise RuntimeError('Fractional occupation numbers?!')
Exemplo n.º 3
0
    def __init__(self, symbol, f_sln, h=0.05, rcut=10.0, **kwargs):
        assert len(f_sln) in [1, 2]
        self.symbol = symbol

        gd = AtomGridDescriptor(h, rcut)
        GPAW.__init__(self,
                      mode=MakeWaveFunctions(gd),
                      eigensolver=AtomEigensolver(gd, f_sln),
                      poissonsolver=AtomPoissonSolver(),
                      stencils=(1, 9),
                      nbands=sum([(2 * l + 1) * len(f_n)
                                  for l, f_n in enumerate(f_sln[0])]),
                      communicator=mpi.serial_comm,
                      **kwargs)
        self.occupations = AtomOccupations(f_sln)
        self.initialize(Atoms(symbol, calculator=self))
        self.calculate(converge=True)
Exemplo n.º 4
0
 def __init__(self, symbol, f_sln, h=0.05, rcut=10.0, **kwargs):
     assert len(f_sln) in [1, 2]
     self.symbol = symbol
     
     gd = AtomGridDescriptor(h, rcut)
     GPAW.__init__(self,
                   mode=MakeWaveFunctions(gd),
                   eigensolver=AtomEigensolver(gd, f_sln),
                   poissonsolver=AtomPoissonSolver(),
                   stencils=(1, 9),
                   nbands=sum([(2 * l + 1) * len(f_n)
                               for l, f_n in enumerate(f_sln[0])]),
                   communicator=mpi.serial_comm,
                   **kwargs)
     self.occupations = AtomOccupations(f_sln)
     self.initialize(Atoms(symbol, calculator=self))
     self.calculate(converge=True)
Exemplo n.º 5
0
    def __init__(self, filename, td_potential=None, propagator='SICN',
                 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

        # Override default `mixer` and `dtype` given in InputParameters
        kwargs.setdefault('mixer', DummyMixer())
        kwargs.setdefault('dtype', complex)

        # Parallelization dictionary should also default to strided bands
        parallel = kwargs.setdefault('parallel', {})
        parallel.setdefault('stridebands', True)

        # Initialize paw-object without density mixing
        # 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)
        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.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.atoms,
                                  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.kpt_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.band_comm.size > 1:
                    self.text('Parallelization Over bands on %d Processors' %
                              wfs.band_comm.size)
            self.text('States per processor = ', wfs.bd.mynbands)

        self.hpsit = None
        self.eps_tmp = None
        self.mblas = MultiBlas(wfs.gd)
Exemplo n.º 6
0
 def __del__(self):
     """Destructor"""
     GPAW.__del__(self)
Exemplo n.º 7
0
 def read(self, reader):
     assert reader.has_array('PseudoWaveFunctions')
     GPAW.read(self, reader)
Exemplo n.º 8
0
 def __init__(self, *args, **kwargs):
     sys.stderr.write('Please start using GPAW instead of Calculator!\n')
     GPAW.__init__(self, *args, **kwargs)
Exemplo n.º 9
0
Arquivo: pwf2.py Projeto: qsnake/gpaw
    def __init__(
        self,
        gpwfilename,
        fixedenergy=0.0,
        spin=0,
        ibl=True,
        basis="sz",
        zero_fermi=False,
        pwfbasis=None,
        lcaoatoms=None,
        projection_data=None,
    ):
        calc = GPAW(gpwfilename, txt=None, basis=basis)
        assert calc.wfs.gd.comm.size == 1
        assert calc.wfs.kpt_comm.size == 1
        assert calc.wfs.band_comm.size == 1
        if zero_fermi:
            try:
                Ef = calc.get_fermi_level()
            except NotImplementedError:
                Ef = calc.get_homo_lumo().mean()
        else:
            Ef = 0.0

        self.ibzk_kc = calc.get_ibz_k_points()
        self.nk = len(self.ibzk_kc)
        self.eps_kn = [calc.get_eigenvalues(kpt=q, spin=spin) - Ef for q in range(self.nk)]
        self.M_k = [sum(eps_n <= fixedenergy) for eps_n in self.eps_kn]
        print "Fixed states:", self.M_k
        self.calc = calc
        self.dtype = self.calc.wfs.dtype
        self.spin = spin
        self.ibl = ibl
        self.pwf_q = []
        self.norms_qn = []
        self.S_qww = []
        self.H_qww = []

        if ibl:
            if pwfbasis is not None:
                pwfmask = basis_subset2(calc.atoms.get_chemical_symbols(), basis, pwfbasis)
            if lcaoatoms is not None:
                lcaoindices = get_bfi2(calc.atoms.get_chemical_symbols(), basis, lcaoatoms)
            else:
                lcaoindices = None
            self.bfs = get_bfs(calc)
            if projection_data is None:
                V_qnM, H_qMM, S_qMM, self.P_aqMi = get_lcao_projections_HSP(
                    calc, bfs=self.bfs, spin=spin, projectionsonly=False
                )
            else:
                V_qnM, H_qMM, S_qMM, self.P_aqMi = projection_data
            H_qMM -= Ef * S_qMM
            for q, M in enumerate(self.M_k):
                if pwfbasis is None:
                    pwf = ProjectedWannierFunctionsIBL(V_qnM[q], S_qMM[q], M, lcaoindices)
                else:
                    pwf = PWFplusLCAO(V_qnM[q], S_qMM[q], M, pwfmask, lcaoindices)
                self.pwf_q.append(pwf)
                self.norms_qn.append(pwf.norms_n)
                self.S_qww.append(pwf.S_ww)
                self.H_qww.append(pwf.rotate_matrix(self.eps_kn[q][:M], H_qMM[q]))
        else:
            if projection_data is None:
                V_qnM = get_lcao_projections_HSP(calc, spin=spin)
            else:
                V_qnM = projection_data
            for q, M in enumerate(self.M_k):
                pwf = ProjectedWannierFunctionsFBL(V_qnM[q], M, ortho=False)
                self.pwf_q.append(pwf)
                self.norms_qn.append(pwf.norms_n)
                self.S_qww.append(pwf.S_ww)
                self.H_qww.append(pwf.rotate_matrix(self.eps_kn[q]))

        for S in self.S_qww:
            print "Condition number: %0.1e" % condition_number(S)
Exemplo n.º 10
0
 def read(self, reader, read_projections=True):
     assert reader.has_array('PseudoWaveFunctions')
     GPAW.read(self, reader, read_projections)
Exemplo n.º 11
0
    def __init__(self, gpwfilename, fixedenergy=0., spin=0, ibl=True,
                 basis='sz', zero_fermi=False, pwfbasis=None, lcaoatoms=None,
                 projection_data=None):
        calc = GPAW(gpwfilename, txt=None, basis=basis)
        assert calc.wfs.gd.comm.size == 1
        assert calc.wfs.kpt_comm.size == 1
        assert calc.wfs.band_comm.size == 1
        if zero_fermi:
            try:
                Ef = calc.get_fermi_level()
            except NotImplementedError:
                Ef = calc.get_homo_lumo().mean()
        else:
            Ef = 0.0

        self.ibzk_kc = calc.get_ibz_k_points()
        self.nk = len(self.ibzk_kc)
        self.eps_kn = [calc.get_eigenvalues(kpt=q, spin=spin) - Ef
                       for q in range(self.nk)]
        self.M_k = [sum(eps_n <= fixedenergy) for eps_n in self.eps_kn]
        print 'Fixed states:', self.M_k 
        self.calc = calc
        self.dtype = self.calc.wfs.dtype
        self.spin = spin
        self.ibl = ibl
        self.pwf_q = []
        self.norms_qn = []
        self.S_qww = []
        self.H_qww = []

        if ibl:
            if pwfbasis is not None:
                pwfmask = basis_subset2(calc.atoms.get_chemical_symbols(),
                                       basis, pwfbasis)
            if lcaoatoms is not None:
                lcaoindices = get_bfi2(calc.atoms.get_chemical_symbols(),
                                       basis,
                                       lcaoatoms)
            else:
                lcaoindices = None
            self.bfs = get_bfs(calc)
            if projection_data is None:
                V_qnM, H_qMM, S_qMM, self.P_aqMi = get_lcao_projections_HSP(
                    calc, bfs=self.bfs, spin=spin, projectionsonly=False)
            else:
                V_qnM, H_qMM, S_qMM, self.P_aqMi = projection_data
            H_qMM -= Ef * S_qMM
            for q, M in enumerate(self.M_k):
                if pwfbasis is None:
                    pwf = ProjectedWannierFunctionsIBL(V_qnM[q], S_qMM[q], M,
                                                       lcaoindices)
                else:
                    pwf = PWFplusLCAO(V_qnM[q], S_qMM[q], M, pwfmask,
                                      lcaoindices)
                self.pwf_q.append(pwf)
                self.norms_qn.append(pwf.norms_n)
                self.S_qww.append(pwf.S_ww)
                self.H_qww.append(pwf.rotate_matrix(self.eps_kn[q][:M],
                                                    H_qMM[q]))
        else:
            if projection_data is None:
                V_qnM = get_lcao_projections_HSP(calc, spin=spin)
            else:
                V_qnM = projection_data
            for q, M in enumerate(self.M_k):
                pwf = ProjectedWannierFunctionsFBL(V_qnM[q], M, ortho=False)
                self.pwf_q.append(pwf)
                self.norms_qn.append(pwf.norms_n)
                self.S_qww.append(pwf.S_ww)
                self.H_qww.append(pwf.rotate_matrix(self.eps_kn[q]))

        for S in self.S_qww:
            print 'Condition number: %0.1e' % condition_number(S)
Exemplo n.º 12
0
 def __init__(self, *args, **kwargs):
     sys.stderr.write('Please start using GPAW instead of Calculator!\n')
     GPAW.__init__(self, *args, **kwargs)
Exemplo n.º 13
0
    def __init__(self, ground_state_file=None, txt='-', td_potential=None,
                 propagator='SICN', solver='CSCG', tolerance=1e-8,
                 parsize=None, parsize_bands=1, parstride_bands=True,
                 communicator=None):
        """Create TDDFT-object.
        
        Parameters:
        -----------
        ground_state_file: string
            File name for the ground state data
        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

        """

        if ground_state_file is None:
            raise RuntimeError('TDDFT calculation has to start from converged '
                               'ground or excited state restart file')

        # 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

        # Initialize paw-object without density mixing
        # NB: TDDFT restart files contain additional information which
        #     will override the initial settings for time/kick/niter.
        GPAW.__init__(self, ground_state_file, txt=txt, mixer=DummyMixer(),
                      parallel={'domain': parsize, 'band': parsize_bands, 
                                'stridebands': parstride_bands},
                      communicator=communicator, dtype=complex)

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

        # Initialize wavefunctions and density 
        # (necessary after restarting from file)
        self.set_positions()

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

        wfs = self.wfs
        self.rank = wfs.world.rank
        
        # Convert PAW-object to complex
        if wfs.dtype == float:
            raise DeprecationWarning('This should not happen.')

            wfs.dtype = complex
            from gpaw.fd_operators import Laplace
            nn = self.input_parameters.stencils[0]
            wfs.kin = Laplace(wfs.gd, -0.5, nn, complex)
            wfs.pt = LFC(wfs.gd, [setup.pt_j for setup in wfs.setups],
                         self.kpt_comm, dtype=complex)

            for kpt in wfs.kpt_u:
                for a,P_ni in kpt.P_ani.items():
                    assert not np.isnan(P_ni).any()
                    kpt.P_ani[a] = np.array(P_ni, complex)

            self.set_positions()

            # Wave functions
            for kpt in wfs.kpt_u:
                kpt.psit_nG = np.array(kpt.psit_nG[:], complex)

        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.atoms,
                                  self.hamiltonian, td_potential)
        self.td_overlap = TimeDependentOverlap(self.wfs)
        self.td_density = TimeDependentDensity(self)

        # Solver for linear equations
        self.text('Solver: ', solver)
        if solver is 'BiCGStab':
            self.solver = BiCGStab(gd=wfs.gd, timer=self.timer,
                                   tolerance=tolerance)
        elif solver is '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 is 'ECN':
            self.propagator = ExplicitCrankNicolson(self.td_density,
                self.td_hamiltonian, self.td_overlap, self.solver,
                self.preconditioner, wfs.gd, self.timer)
        elif propagator is 'SICN':
            self.propagator = SemiImplicitCrankNicolson(self.td_density,
                self.td_hamiltonian, self.td_overlap, self.solver,
                self.preconditioner, wfs.gd, self.timer)
        elif propagator is 'ETRSCN':
            self.propagator = EnforcedTimeReversalSymmetryCrankNicolson(
                self.td_density,
                self.td_hamiltonian, self.td_overlap, self.solver,
                self.preconditioner, wfs.gd, self.timer)
        elif propagator in ['SITE4', 'SITE']:
            self.propagator = SemiImplicitTaylorExponential(self.td_density,
                self.td_hamiltonian, self.td_overlap, self.solver,
                self.preconditioner, wfs.gd, self.timer, degree = 4)
        elif propagator in ['SIKE4', 'SIKE']:
            self.propagator = SemiImplicitKrylovExponential(self.td_density,
                self.td_hamiltonian, self.td_overlap, self.solver,
                self.preconditioner, wfs.gd, self.timer, degree = 4)
        elif propagator is 'SIKE5':
            self.propagator = SemiImplicitKrylovExponential(self.td_density,
                self.td_hamiltonian, self.td_overlap, self.solver,
                self.preconditioner, wfs.gd, self.timer, degree = 5)
        elif propagator is 'SIKE6':
            self.propagator = SemiImplicitKrylovExponential(self.td_density,
                self.td_hamiltonian, self.td_overlap, self.solver, 
                self.preconditioner, wfs.gd, self.timer, degree = 6)
        else:
            raise RuntimeError('Time propagator %s not supported.' % propagator)

        if self.rank == 0:
            if wfs.kpt_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.band_comm.size > 1:
                    self.text('Parallelization Over bands on %d Processors' %
                              wfs.band_comm.size)
            self.text('States per processor = ', wfs.mynbands)

        self.hpsit = None
        self.eps_tmp = None
        self.mblas = MultiBlas(wfs.gd)
Exemplo n.º 14
0
    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

        # Override default `mixer` and `dtype` given in InputParameters
        kwargs.setdefault('mixer', DummyMixer())
        kwargs.setdefault('dtype', complex)

        # Parallelization dictionary should also default to strided bands
        parallel = kwargs.setdefault('parallel', {})
        parallel.setdefault('stridebands', True)

        # Initialize paw-object without density mixing
        # 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)
        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.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.atoms,
                                                       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.band_comm.size > 1:
                    self.text('Parallelization Over bands on %d Processors' %
                              wfs.band_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.txt.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
Exemplo n.º 15
0
 def __del__(self):
     """Destructor"""
     GPAW.__del__(self)
Exemplo n.º 16
0
 def read(self, reader, read_projections=True):
     assert reader.has_array('PseudoWaveFunctions')
     GPAW.read(self, reader, read_projections)