示例#1
0
def create_poisson_solver(name='fd', **kwargs):
    if name == 'fft':
        return FFTPoissonSolver()
    if name == 'fdtd':
        from gpaw.fdtd.poisson_fdtd import FDTDPoissonSolver
        return FDTDPoissonSolver(**kwargs)
    elif name == 'fd':
        return PoissonSolver(**kwargs)
    1 / 0
示例#2
0
def create_poisson_solver(name='fast', **kwargs):
    if isinstance(name, _PoissonSolver):
        return name
    elif isinstance(name, dict):
        kwargs.update(name)
        return create_poisson_solver(**kwargs)
    elif name == 'fft':
        return FFTPoissonSolver(**kwargs)
    elif name == 'fdtd':
        from gpaw.fdtd.poisson_fdtd import FDTDPoissonSolver
        return FDTDPoissonSolver(**kwargs)
    elif name == 'fd':
        return FDPoissonSolverWrapper(**kwargs)
    elif name == 'fast':
        return FastPoissonSolver(**kwargs)
    elif name == 'ExtraVacuumPoissonSolver':
        from gpaw.poisson_extravacuum import ExtraVacuumPoissonSolver
        return ExtraVacuumPoissonSolver(**kwargs)
    else:
        raise ValueError('Unknown poisson solver: %s' % name)
示例#3
0
文件: ed.py 项目: thonmaker/gpaw
    fo.close()
world.barrier()

# Classical subsystem
classical_material = PolarizableMaterial()
sphere_center = np.array([10.0, 10.0, 10.0])
classical_material.add_component(
    PolarizableSphere(permittivity=PermittivityPlus('ed.txt'),
                      center=sphere_center,
                      radius=5.0))

# Combined Poisson solver
poissonsolver = FDTDPoissonSolver(classical_material=classical_material,
                                  qm_spacing=0.40,
                                  cl_spacing=0.40 * 4,
                                  cell=large_cell,
                                  remove_moments=(1, 4),
                                  communicator=world,
                                  potential_coupler='Refiner')
poissonsolver.set_calculation_mode('iterate')

# Combined system
atoms.set_cell(large_cell)
atoms, qm_spacing, gpts = poissonsolver.cut_cell(atoms, vacuum=2.50)

# Initialize GPAW
gs_calc = GPAW(gpts=gpts,
               experimental={'niter_fixdensity': 2},
               eigensolver='cg',
               nbands=-1,
               poissonsolver=poissonsolver,
示例#4
0
def read(paw, reader, read_projections=True):
    r = reader
    timer = paw.timer
    timer.start('Read')

    wfs = paw.wfs
    density = paw.density
    hamiltonian = paw.hamiltonian
    natoms = len(paw.atoms)

    world = paw.wfs.world
    gd = wfs.gd
    kd = wfs.kd
    bd = wfs.bd

    master = (world.rank == 0)
    parallel = (world.size > 1)

    version = r['version']

    hdf5 = hasattr(r, 'hdf5')

    # Verify setup fingerprints and count projectors and atomic matrices:
    for setup in wfs.setups.setups.values():
        try:
            key = atomic_names[setup.Z] + 'Fingerprint'
            if setup.type != 'paw':
                key += '(%s)' % setup.type
            if setup.fingerprint != r[key]:
                str = 'Setup for %s (%s) not compatible with restart file.' \
                    % (setup.symbol, setup.filename)
                if paw.input_parameters['idiotproof']:
                    raise RuntimeError(str)
                else:
                    warnings.warn(str)
        except (AttributeError, KeyError):
            str = 'Fingerprint of setup for %s (%s) not in restart file.' \
                % (setup.symbol, setup.filename)
            if paw.input_parameters['idiotproof']:
                raise RuntimeError(str)
            else:
                warnings.warn(str)
    nproj = sum([setup.ni for setup in wfs.setups])
    nadm = sum([setup.ni * (setup.ni + 1) // 2 for setup in wfs.setups])

    # Verify dimensions for minimally required netCDF variables:
    ng = gd.get_size_of_global_array()
    shapes = {
        'ngptsx': ng[0],
        'ngptsy': ng[1],
        'ngptsz': ng[2],
        'nspins': wfs.nspins,
        'nproj': nproj,
        'nadm': nadm
    }
    for name, dim in shapes.items():
        if r.dimension(name) != dim:
            raise ValueError('shape mismatch: expected %s=%d' % (name, dim))

    timer.start('Density')
    density.read(r, parallel, wfs.kptband_comm)
    timer.stop('Density')

    timer.start('Hamiltonian')
    hamiltonian.read(r, parallel)
    timer.stop('Hamiltonian')

    from gpaw.utilities.partition import AtomPartition
    atom_partition = AtomPartition(gd.comm, np.zeros(natoms, dtype=int))
    # <sarcasm>let's set some variables directly on some objects!</sarcasm>
    wfs.atom_partition = atom_partition
    wfs.rank_a = np.zeros(natoms, int)
    density.atom_partition = atom_partition
    hamiltonian.atom_partition = atom_partition

    if version > 0.3:
        Etot = hamiltonian.Etot
        energy_error = r['EnergyError']
        if energy_error is not None:
            paw.scf.energies = [Etot, Etot + energy_error, Etot]
        wfs.eigensolver.error = r['EigenstateError']
        if version < 1:
            wfs.eigensolver.error *= gd.dv
    else:
        paw.scf.converged = r['Converged']

    if version > 0.6:
        if paw.occupations.fixmagmom:
            if 'FermiLevel' in r.get_parameters():
                paw.occupations.set_fermi_levels_mean(r['FermiLevel'])
            if 'FermiSplit' in r.get_parameters():
                paw.occupations.set_fermi_splitting(r['FermiSplit'])
        else:
            if 'FermiLevel' in r.get_parameters():
                paw.occupations.set_fermi_level(r['FermiLevel'])
    else:
        if (not paw.input_parameters.fixmom
                and 'FermiLevel' in r.get_parameters()):
            paw.occupations.set_fermi_level(r['FermiLevel'])

    # Try to read the current time and kick strength in time-propagation TDDFT:
    for attr, name in [('time', 'Time'), ('niter', 'TimeSteps'),
                       ('kick_strength', 'AbsorptionKick')]:
        if hasattr(paw, attr):
            try:
                if r.has_array(name):
                    value = r.get(name, read=master)
                else:
                    value = r[name]
                setattr(paw, attr, value)
            except KeyError:
                pass

    # Try to read FDTD-related data
    try:
        use_fdtd = r['FDTD']
    except:
        use_fdtd = False

    if use_fdtd:
        from gpaw.fdtd.poisson_fdtd import FDTDPoissonSolver
        # fdtd_poisson will overwrite the poisson at a later stage
        paw.hamiltonian.fdtd_poisson = FDTDPoissonSolver(restart_reader=r,
                                                         paw=paw)

    # Try to read the number of Delta SCF orbitals
    try:
        norbitals = r.dimension('norbitals')
        paw.occupations.norbitals = norbitals
    except (AttributeError, KeyError):
        norbitals = None

    nibzkpts = r.dimension('nibzkpts')
    nbands = r.dimension('nbands')
    nslice = bd.get_slice()

    if (nibzkpts != len(wfs.kd.ibzk_kc)
            or nbands != bd.comm.size * bd.mynbands):
        paw.scf.reset()
    else:
        # Verify that symmetries for for k-point reduction hasn't changed:
        tol = 1e-12

        if master:
            bzk_kc = r.get('BZKPoints', read=master)
            weight_k = r.get('IBZKPointWeights', read=master)
            assert np.abs(bzk_kc - kd.bzk_kc).max() < tol
            assert np.abs(weight_k - kd.weight_k).max() < tol

        for kpt in wfs.kpt_u:
            # Eigenvalues and occupation numbers:
            timer.start('Band energies')
            k = kpt.k
            s = kpt.s
            if hdf5:  # fully parallelized over spins, k-points
                do_read = (gd.comm.rank == 0)
                indices = [s, k]
                indices.append(nslice)
                kpt.eps_n = r.get('Eigenvalues',
                                  parallel=parallel,
                                  read=do_read,
                                  *indices)
                gd.comm.broadcast(kpt.eps_n, 0)
                kpt.f_n = r.get('OccupationNumbers',
                                parallel=parallel,
                                read=do_read,
                                *indices)
                gd.comm.broadcast(kpt.f_n, 0)
            else:
                eps_n = r.get('Eigenvalues', s, k, read=master)
                f_n = r.get('OccupationNumbers', s, k, read=master)
                kpt.eps_n = eps_n[nslice].copy()
                kpt.f_n = f_n[nslice].copy()
            timer.stop('Band energies')

            if norbitals is not None:  # XXX will probably fail for hdf5
                timer.start('dSCF expansions')
                kpt.ne_o = np.empty(norbitals, dtype=float)
                kpt.c_on = np.empty((norbitals, bd.mynbands), dtype=complex)
                for o in range(norbitals):
                    kpt.ne_o[o] = r.get('LinearExpansionOccupations',
                                        s,
                                        k,
                                        o,
                                        read=master)
                    c_n = r.get('LinearExpansionCoefficients',
                                s,
                                k,
                                o,
                                read=master)
                    kpt.c_on[o, :] = c_n[nslice]
                timer.stop('dSCF expansions')

        if (r.has_array('PseudoWaveFunctions')
                and paw.input_parameters.mode != 'lcao'):

            timer.start('Pseudo-wavefunctions')
            wfs.read(r, hdf5)
            timer.stop('Pseudo-wavefunctions')

        if (r.has_array('WaveFunctionCoefficients')
                and paw.input_parameters.mode == 'lcao'):
            wfs.read_coefficients(r)

        timer.start('Projections')
        if hdf5 and read_projections:
            # Domain masters read parallel over spin, kpoints and band groups
            cumproj_a = np.cumsum([0] + [setup.ni for setup in wfs.setups])
            all_P_ni = np.empty((bd.mynbands, cumproj_a[-1]), dtype=wfs.dtype)
            for kpt in wfs.kpt_u:
                kpt.P_ani = {}
                indices = [kpt.s, kpt.k]
                indices.append(bd.get_slice())
                do_read = (gd.comm.rank == 0)
                # timer.start('ProjectionsCritical(s=%d,k=%d)' % (kpt.s,kpt.k))
                r.get('Projections',
                      out=all_P_ni,
                      parallel=parallel,
                      read=do_read,
                      *indices)
                # timer.stop('ProjectionsCritical(s=%d,k=%d)' % (kpt.s,kpt.k))
                if gd.comm.rank == 0:
                    for a in range(natoms):
                        ni = wfs.setups[a].ni
                        P_ni = np.empty((bd.mynbands, ni), dtype=wfs.dtype)
                        P_ni[:] = all_P_ni[:, cumproj_a[a]:cumproj_a[a + 1]]
                        kpt.P_ani[a] = P_ni

            del all_P_ni  # delete a potentially large matrix
        elif read_projections and r.has_array('Projections'):
            wfs.read_projections(r)
        timer.stop('Projections')

    # Manage mode change:
    paw.scf.check_convergence(density, wfs.eigensolver, wfs, hamiltonian,
                              paw.forces)
    newmode = paw.input_parameters.mode
    try:
        oldmode = r['Mode']
        if oldmode == 'pw':
            from gpaw.wavefunctions.pw import PW
            oldmode = PW(ecut=r['PlaneWaveCutoff'] * Hartree)
    except (AttributeError, KeyError):
        oldmode = 'fd'  # This is an old gpw file from before lcao existed

    if newmode == 'lcao':
        spos_ac = paw.atoms.get_scaled_positions() % 1.0
        wfs.load_lazily(hamiltonian, spos_ac)

    if newmode != oldmode:
        paw.scf.reset()

    # Get the forces from the old calculation:
    if r.has_array('CartesianForces'):
        paw.forces.F_av = r.get('CartesianForces', broadcast=True)
    else:
        paw.forces.reset()

    hamiltonian.xc.read(r)

    timer.stop('Read')
示例#5
0
        [0.7603, 1.946, -40.89], [1.161, 1.396, 17.22], [2.946, 1.183, 15.76],
        [4.161, 1.964, 36.63], [5.747, 1.958, 22.55], [7.912, 1.361, 81.04]]

# Initialize classical material
classical_material = PolarizableMaterial()

# Classical nanosphere
classical_material.add_component(
    PolarizableSphere(center=0.5 * large_cell,
                      radius=radius,
                      permittivity=PermittivityPlus(data=gold)))

# Poisson solver
poissonsolver = FDTDPoissonSolver(classical_material=classical_material,
                                  cl_spacing=8.0,
                                  qm_spacing=1.0,
                                  cell=large_cell,
                                  communicator=world,
                                  remove_moments=(4, 1))
poissonsolver.set_calculation_mode('iterate')

# Dummy quantum system
atoms = Atoms('H', [0.5 * large_cell], cell=large_cell)
atoms, qm_spacing, gpts = poissonsolver.cut_cell(atoms)
del atoms[:]  # Remove atoms, quantum system is empty

# Initialize GPAW
gs_calc = GPAW(gpts=gpts, nbands=-1, poissonsolver=poissonsolver)
atoms.set_calculator(gs_calc)

# Ground state
energy = atoms.get_potential_energy()
示例#6
0
    data=[[0.2350, 0.1551, 95.62], [0.4411, 0.1480, -12.55],
          [0.7603, 1.946, -40.89], [1.161, 1.396, 17.22],
          [2.946, 1.183, 15.76], [4.161, 1.964, 36.63], [5.747, 1.958, 22.55],
          [7.912, 1.361, 81.04]])

# 3) Nanosphere + Na2
classical_material = PolarizableMaterial()
classical_material.add_component(
    PolarizableSphere(center=sphere_center,
                      radius=radius,
                      permittivity=eps_gold))

# Combined Poisson solver
poissonsolver = FDTDPoissonSolver(classical_material=classical_material,
                                  qm_spacing=0.5,
                                  cl_spacing=2.0,
                                  cell=simulation_cell,
                                  communicator=world,
                                  remove_moments=(1, 1))
poissonsolver.set_calculation_mode('iterate')

# Combined system
atoms.set_cell(simulation_cell)
atoms, qm_spacing, gpts = poissonsolver.cut_cell(atoms, vacuum=4.0)

# Initialize GPAW
gs_calc = GPAW(gpts=gpts, nbands=-1, poissonsolver=poissonsolver)
atoms.set_calculator(gs_calc)

# Ground state
energy = atoms.get_potential_energy()