コード例 #1
0
ファイル: ut_invops.py プロジェクト: thonmaker/gpaw
    def setUp(self):
        for virtvar in ['boundaries']:
            assert getattr(self,virtvar) is not None, 'Virtual "%s"!' % virtvar

        parsize_domain, parsize_bands = create_parsize_minbands(self.nbands, world.size)
        assert self.nbands % np.prod(parsize_bands) == 0
        comms = distribute_cpus(parsize_domain,
                                parsize_bands, self.nspins, self.nibzkpts)
        domain_comm, kpt_comm, band_comm, block_comm = \
            [comms[name] for name in 'dkbK']

        self.block_comm = block_comm

        # Set up band descriptor:
        self.bd = BandDescriptor(self.nbands, band_comm)

        # Set up grid descriptor:
        res, ngpts = shapeopt(300, self.G**3, 3, 0.2)
        cell_c = self.h * np.array(ngpts)
        pbc_c = {'zero'    : False, \
                 'periodic': True, \
                 'mixed'   : (True, False, True)}[self.boundaries]
        self.gd = GridDescriptor(ngpts, cell_c, pbc_c, domain_comm, parsize_domain)

        # What to do about kpoints?
        self.kpt_comm = kpt_comm
コード例 #2
0
ファイル: ut_hsops.py プロジェクト: yihsuanliu/gpaw
    def setUp(self):
        for virtvar in ['dtype', 'parstride_bands']:
            assert getattr(self,
                           virtvar) is not None, 'Virtual "%s"!' % virtvar

        parsize, parsize_bands = create_parsize_maxbands(
            self.nbands, world.size)
        assert self.nbands % np.prod(parsize_bands) == 0
        domain_comm, kpt_comm, band_comm = distribute_cpus(
            parsize, parsize_bands, self.nspins, self.nibzkpts)

        # Set up band descriptor:
        self.bd = BandDescriptor(self.nbands, band_comm, self.parstride_bands)

        # Set up grid descriptor:
        res, ngpts = shapeopt(100, self.G**3, 3, 0.2)
        cell_c = self.h * np.array(ngpts)
        pbc_c = (True, False, True)
        self.gd = GridDescriptor(ngpts, cell_c, pbc_c, domain_comm, parsize)

        # Create Kohn-Sham layouts for these band and grid descriptors:
        self.ksl = self.create_kohn_sham_layouts()

        # What to do about kpoints?
        self.kpt_comm = kpt_comm
コード例 #3
0
    def setUp(self):
        for virtvar in ['boundaries']:
            assert getattr(self,virtvar) is not None, 'Virtual "%s"!' % virtvar

        parsize_domain, parsize_bands = create_parsize_minbands(self.nbands, world.size)
        assert self.nbands % np.prod(parsize_bands) == 0
        comms = distribute_cpus(parsize_domain,
                                parsize_bands, self.nspins, self.nibzkpts)
        domain_comm, kpt_comm, band_comm, block_comm = \
            [comms[name] for name in 'dkbK']

        self.block_comm = block_comm

        # Set up band descriptor:
        self.bd = BandDescriptor(self.nbands, band_comm)

        # Set up grid descriptor:
        res, ngpts = shapeopt(300, self.G**3, 3, 0.2)
        cell_c = self.h * np.array(ngpts)
        pbc_c = {'zero'    : False, \
                 'periodic': True, \
                 'mixed'   : (True, False, True)}[self.boundaries]
        self.gd = GridDescriptor(ngpts, cell_c, pbc_c, domain_comm, parsize_domain)

        # What to do about kpoints?
        self.kpt_comm = kpt_comm
コード例 #4
0
    def setUp(self):
        for virtvar in ['dtype','parstride_bands']:
            assert getattr(self,virtvar) is not None, 'Virtual "%s"!' % virtvar

        parsize_domain, parsize_bands = create_parsize_maxbands(self.nbands, world.size)
        assert self.nbands % parsize_bands == 0
        comms = distribute_cpus(parsize_domain,
                                parsize_bands, self.nspins, self.nibzkpts)
        domain_comm, kpt_comm, band_comm, block_comm = \
            [comms[name] for name in 'dkbK']
        self.block_comm = block_comm

        # Set up band descriptor:
        self.bd = BandDescriptor(self.nbands, band_comm, self.parstride_bands)

        # Set up grid descriptor:
        res, ngpts = shapeopt(100, self.G**3, 3, 0.2)
        cell_c = self.h * np.array(ngpts)
        pbc_c = (True, False, True)
        self.gd = GridDescriptor(ngpts, cell_c, pbc_c, domain_comm, parsize_domain)

        # Create Kohn-Sham layouts for these band and grid descriptors:
        self.ksl = self.create_kohn_sham_layouts()

        # What to do about kpoints?
        self.kpt_comm = kpt_comm
コード例 #5
0
    def setUp(self):
        for virtvar in ['boundaries']:
            assert getattr(self,
                           virtvar) is not None, 'Virtual "%s"!' % virtvar

        # Basic unit cell information:
        res, N_c = shapeopt(100, self.G**3, 3, 0.2)
        #N_c = 4*np.round(np.array(N_c)/4) # makes domain decomposition easier
        cell_cv = self.h * np.diag(N_c)
        pbc_c = {'zero'    : (False,False,False), \
                 'periodic': (True,True,True), \
                 'mixed'   : (True, False, True)}[self.boundaries]

        # Create randomized gas-like atomic configuration on interim grid
        tmpgd = GridDescriptor(N_c, cell_cv, pbc_c)
        self.atoms = create_random_atoms(tmpgd)

        # Create setups
        Z_a = self.atoms.get_atomic_numbers()
        assert 1 == self.nspins
        self.setups = Setups(Z_a, p.setups, p.basis, p.lmax, xc)
        self.natoms = len(self.setups)

        # Decide how many kpoints to sample from the 1st Brillouin Zone
        kpts_c = np.ceil(
            (10 / Bohr) / np.sum(cell_cv**2, axis=1)**0.5).astype(int)
        kpts_c = tuple(kpts_c * pbc_c + 1 - pbc_c)
        self.bzk_kc = kpts2ndarray(kpts_c)

        # Set up k-point descriptor
        self.kd = KPointDescriptor(self.bzk_kc, self.nspins)
        self.kd.set_symmetry(self.atoms, self.setups, p.usesymm)

        # Set the dtype
        if self.kd.gamma:
            self.dtype = float
        else:
            self.dtype = complex

        # Create communicators
        parsize, parsize_bands = self.get_parsizes()
        assert self.nbands % np.prod(parsize_bands) == 0
        domain_comm, kpt_comm, band_comm = distribute_cpus(
            parsize, parsize_bands, self.nspins, self.kd.nibzkpts)

        self.kd.set_communicator(kpt_comm)

        # Set up band descriptor:
        self.bd = BandDescriptor(self.nbands, band_comm)

        # Set up grid descriptor:
        self.gd = GridDescriptor(N_c, cell_cv, pbc_c, domain_comm, parsize)

        # Set up kpoint/spin descriptor (to be removed):
        self.kd_old = KPointDescriptorOld(self.nspins, self.kd.nibzkpts,
                                          kpt_comm, self.kd.gamma, self.dtype)
コード例 #6
0
ファイル: ut_gucops.py プロジェクト: robwarm/gpaw-symm
    def setUp(self):
        for virtvar in ['boundaries', 'celltype']:
            assert getattr(self,virtvar) is not None, 'Virtual "%s"!' % virtvar

        # Basic unit cell information:
        pbc_c = {'zero'    : (False,False,False), \
                 'periodic': (True,True,True), \
                 'mixed'   : (True, False, True)}[self.boundaries]
        a, b = self.a, 2**0.5*self.a
        cell_cv = {'general'   : np.array([[0,a,a],[a/2,0,a/2],[a/2,a/2,0]]),
                   'rotated'   : np.array([[0,0,b],[b/2,0,0],[0,b/2,0]]),
                   'inverted'   : np.array([[0,0,b],[0,b/2,0],[b/2,0,0]]),
                   'orthogonal': np.diag([b, b/2, b/2])}[self.celltype]
        cell_cv = np.array([(4-3*pbc)*c_v for pbc,c_v in zip(pbc_c, cell_cv)])

        # Decide how many kpoints to sample from the 1st Brillouin Zone
        kpts_c = np.ceil((10/Bohr)/np.sum(cell_cv**2,axis=1)**0.5).astype(int)
        kpts_c = tuple(kpts_c*pbc_c + 1-pbc_c)
        bzk_kc = kpts2ndarray(kpts_c)
        self.gamma = len(bzk_kc) == 1 and not bzk_kc[0].any()

        #p = InputParameters()
        #Z_a = self.atoms.get_atomic_numbers()
        #xcfunc = XC(p.xc)
        #setups = Setups(Z_a, p.setups, p.basis, p.lmax, xcfunc)
        #symmetry, weight_k, self.ibzk_kc = reduce_kpoints(self.atoms, bzk_kc,
        #                                                  setups, p.usesymm)

        self.ibzk_kc = bzk_kc.copy() # don't use symmetry reduction of kpoints
        self.nibzkpts = len(self.ibzk_kc)
        self.ibzk_kv = kpoint_convert(cell_cv, skpts_kc=self.ibzk_kc)

        # Parse parallelization parameters and create suitable communicators.
        #parsize_domain, parsize_bands = create_parsize_minbands(self.nbands, world.size)
        parsize_domain, parsize_bands = world.size//gcd(world.size, self.nibzkpts), 1
        assert self.nbands % np.prod(parsize_bands) == 0
        domain_comm, kpt_comm, band_comm = distribute_cpus(parsize_domain,
            parsize_bands, self.nspins, self.nibzkpts)

        # Set up band descriptor:
        self.bd = BandDescriptor(self.nbands, band_comm)

        # Set up grid descriptor:
        N_c = np.round(np.sum(cell_cv**2, axis=1)**0.5 / self.h)
        N_c += 4-N_c % 4 # makes domain decomposition easier
        self.gd = GridDescriptor(N_c, cell_cv, pbc_c, domain_comm, parsize_domain)
        self.assertEqual(self.gamma, np.all(~self.gd.pbc_c))

        # What to do about kpoints?
        self.kpt_comm = kpt_comm

        if debug and world.rank == 0:
            comm_sizes = tuple([comm.size for comm in [world, self.bd.comm, \
                                                   self.gd.comm, self.kpt_comm]])
            print '%d world, %d band, %d domain, %d kpt' % comm_sizes
コード例 #7
0
ファイル: ut_gucops.py プロジェクト: yihsuanliu/gpaw
    def setUp(self):
        for virtvar in ['boundaries', 'celltype']:
            assert getattr(self,virtvar) is not None, 'Virtual "%s"!' % virtvar

        # Basic unit cell information:
        pbc_c = {'zero'    : (False,False,False), \
                 'periodic': (True,True,True), \
                 'mixed'   : (True, False, True)}[self.boundaries]
        a, b = self.a, 2**0.5*self.a
        cell_cv = {'general'   : np.array([[0,a,a],[a/2,0,a/2],[a/2,a/2,0]]),
                   'rotated'   : np.array([[0,0,b],[b/2,0,0],[0,b/2,0]]),
                   'inverted'   : np.array([[0,0,b],[0,b/2,0],[b/2,0,0]]),
                   'orthogonal': np.diag([b, b/2, b/2])}[self.celltype]
        cell_cv = np.array([(4-3*pbc)*c_v for pbc,c_v in zip(pbc_c, cell_cv)])

        # Decide how many kpoints to sample from the 1st Brillouin Zone
        kpts_c = np.ceil((10/Bohr)/np.sum(cell_cv**2,axis=1)**0.5).astype(int)
        kpts_c = tuple(kpts_c*pbc_c + 1-pbc_c)
        bzk_kc = kpts2ndarray(kpts_c)
        self.gamma = len(bzk_kc) == 1 and not bzk_kc[0].any()

        #p = InputParameters()
        #Z_a = self.atoms.get_atomic_numbers()
        #xcfunc = XC(p.xc)
        #setups = Setups(Z_a, p.setups, p.basis, p.lmax, xcfunc)
        #symmetry, weight_k, self.ibzk_kc = reduce_kpoints(self.atoms, bzk_kc,
        #                                                  setups, p.usesymm)

        self.ibzk_kc = bzk_kc.copy() # don't use symmetry reduction of kpoints
        self.nibzkpts = len(self.ibzk_kc)
        self.ibzk_kv = kpoint_convert(cell_cv, skpts_kc=self.ibzk_kc)

        # Parse parallelization parameters and create suitable communicators.
        #parsize, parsize_bands = create_parsize_minbands(self.nbands, world.size)
        parsize, parsize_bands = world.size//gcd(world.size, self.nibzkpts), 1
        assert self.nbands % np.prod(parsize_bands) == 0
        domain_comm, kpt_comm, band_comm = distribute_cpus(parsize,
            parsize_bands, self.nspins, self.nibzkpts)

        # Set up band descriptor:
        self.bd = BandDescriptor(self.nbands, band_comm)

        # Set up grid descriptor:
        N_c = np.round(np.sum(cell_cv**2, axis=1)**0.5 / self.h)
        N_c += 4-N_c % 4 # makes domain decomposition easier
        self.gd = GridDescriptor(N_c, cell_cv, pbc_c, domain_comm, parsize)
        self.assertEqual(self.gamma, np.all(~self.gd.pbc_c))

        # What to do about kpoints?
        self.kpt_comm = kpt_comm

        if debug and world.rank == 0:
            comm_sizes = tuple([comm.size for comm in [world, self.bd.comm, \
                                                   self.gd.comm, self.kpt_comm]])
            print '%d world, %d band, %d domain, %d kpt' % comm_sizes
コード例 #8
0
ファイル: ut_redist.py プロジェクト: qsnake/gpaw
    def setUp(self):
        for virtvar in ['boundaries']:
            assert getattr(self,virtvar) is not None, 'Virtual "%s"!' % virtvar

        # Basic unit cell information:
        res, N_c = shapeopt(100, self.G**3, 3, 0.2)
        #N_c = 4*np.round(np.array(N_c)/4) # makes domain decomposition easier
        cell_cv = self.h * np.diag(N_c)
        pbc_c = {'zero'    : (False,False,False), \
                 'periodic': (True,True,True), \
                 'mixed'   : (True, False, True)}[self.boundaries]

        # Create randomized gas-like atomic configuration on interim grid
        tmpgd = GridDescriptor(N_c, cell_cv, pbc_c)
        self.atoms = create_random_atoms(tmpgd)

        # Create setups
        Z_a = self.atoms.get_atomic_numbers()
        assert 1 == self.nspins
        self.setups = Setups(Z_a, p.setups, p.basis, p.lmax, xc)
        self.natoms = len(self.setups)

        # Decide how many kpoints to sample from the 1st Brillouin Zone
        kpts_c = np.ceil((10/Bohr)/np.sum(cell_cv**2,axis=1)**0.5).astype(int)
        kpts_c = tuple(kpts_c * pbc_c + 1 - pbc_c)
        self.bzk_kc = kpts2ndarray(kpts_c)

        # Set up k-point descriptor
        self.kd = KPointDescriptor(self.bzk_kc, self.nspins)
        self.kd.set_symmetry(self.atoms, self.setups, p.usesymm)

        # Set the dtype
        if self.kd.gamma:
            self.dtype = float
        else:
            self.dtype = complex
            
        # Create communicators
        parsize, parsize_bands = self.get_parsizes()
        assert self.nbands % np.prod(parsize_bands) == 0
        domain_comm, kpt_comm, band_comm = distribute_cpus(parsize,
            parsize_bands, self.nspins, self.kd.nibzkpts)

        self.kd.set_communicator(kpt_comm)
        
        # Set up band descriptor:
        self.bd = BandDescriptor(self.nbands, band_comm)

        # Set up grid descriptor:
        self.gd = GridDescriptor(N_c, cell_cv, pbc_c, domain_comm, parsize)

        # Set up kpoint/spin descriptor (to be removed):
        self.kd_old = KPointDescriptorOld(self.nspins, self.kd.nibzkpts,
                                          kpt_comm, self.kd.gamma, self.dtype)
コード例 #9
0
ファイル: ut_kptops.py プロジェクト: robwarm/gpaw-symm
    def setUp(self):
        for virtvar in ['equipartition']:
            assert getattr(self,virtvar) is not None, 'Virtual "%s"!' % virtvar

        kpts = {'even' : (12,1,2), \
                'prime': (23,1,1)}[self.equipartition]

        #primes = [i for i in xrange(50,1,-1) if ~np.any(i%np.arange(2,i)==0)]
        bzk_kc = kpts2ndarray(kpts)
        assert p.usesymm == None
        self.nibzkpts = len(bzk_kc)

        #parsize_domain, parsize_bands = create_parsize_minbands(self.nbands, world.size)
        parsize_domain, parsize_bands = 1, 1 #XXX
        assert self.nbands % np.prod(parsize_bands) == 0
        domain_comm, kpt_comm, band_comm = distribute_cpus(parsize_domain,
            parsize_bands, self.nspins, self.nibzkpts)

        # Set up band descriptor:
        self.bd = BandDescriptor(self.nbands, band_comm, p.parallel['stridebands'])

        # Set up grid descriptor:
        res, ngpts = shapeopt(300, self.G**3, 3, 0.2)
        cell_c = self.h * np.array(ngpts)
        pbc_c = (True, False, True)
        self.gd = GridDescriptor(ngpts, cell_c, pbc_c, domain_comm, parsize_domain)

        # Create randomized gas-like atomic configuration
        self.atoms = create_random_atoms(self.gd)

        # Create setups
        Z_a = self.atoms.get_atomic_numbers()
        self.setups = Setups(Z_a, p.setups, p.basis, p.lmax, xc)
        self.natoms = len(self.setups)

        # Set up kpoint descriptor:
        self.kd = KPointDescriptor(bzk_kc, self.nspins)
        self.kd.set_symmetry(self.atoms, self.setups, usesymm=p.usesymm)
        self.kd.set_communicator(kpt_comm)
コード例 #10
0
    def setUp(self):
        for virtvar in ['equipartition']:
            assert getattr(self,virtvar) is not None, 'Virtual "%s"!' % virtvar

        kpts = {'even' : (12,1,2), \
                'prime': (23,1,1)}[self.equipartition]

        #primes = [i for i in xrange(50,1,-1) if ~np.any(i%np.arange(2,i)==0)]
        bzk_kc = kpts2ndarray(kpts)
        assert p.usesymm == None
        self.nibzkpts = len(bzk_kc)

        #parsize, parsize_bands = create_parsize_minbands(self.nbands, world.size)
        parsize, parsize_bands = 1, 1 #XXX
        assert self.nbands % np.prod(parsize_bands) == 0
        domain_comm, kpt_comm, band_comm = distribute_cpus(parsize,
            parsize_bands, self.nspins, self.nibzkpts)

        # Set up band descriptor:
        self.bd = BandDescriptor(self.nbands, band_comm, p.parallel['stridebands'])

        # Set up grid descriptor:
        res, ngpts = shapeopt(300, self.G**3, 3, 0.2)
        cell_c = self.h * np.array(ngpts)
        pbc_c = (True, False, True)
        self.gd = GridDescriptor(ngpts, cell_c, pbc_c, domain_comm, parsize)

        # Create randomized gas-like atomic configuration
        self.atoms = create_random_atoms(self.gd)

        # Create setups
        Z_a = self.atoms.get_atomic_numbers()
        self.setups = Setups(Z_a, p.setups, p.basis, p.lmax, xc)
        self.natoms = len(self.setups)

        # Set up kpoint descriptor:
        self.kd = KPointDescriptor(bzk_kc, self.nspins)
        self.kd.set_symmetry(self.atoms, self.setups, p.usesymm)
        self.kd.set_communicator(kpt_comm)
コード例 #11
0
        B = world.size // np.prod(parsize_domain)
        D = parsize_domain
else:
    B = parsize_bands
    D = world.size // B

M = N // B     # number of bands per group
assert M * B == N, 'M=%d, B=%d, N=%d' % (M,B,N)

h = 0.2        # grid spacing
a = h * G      # side length of box
assert np.prod(D) * B == world.size, 'D=%s, B=%d, W=%d' % (D,B,world.size)

# Set up communicators:
comms = distribute_cpus(parsize_domain=D,
                        parsize_bands=B,
                        nspins=1, nibzkpts=1)
domain_comm, kpt_comm, band_comm, block_comm = \
    [comms[name] for name in ['d', 'k', 'b', 'K']]

assert kpt_comm.size == 1
if world.rank == 0:
    print('MPI: %d domains, %d band groups' % (domain_comm.size, band_comm.size))

# Set up band and grid descriptors:
bd = BandDescriptor(N, band_comm, False)
gd = GridDescriptor((G, G, G), (a, a, a), True, domain_comm, parsize=D)
ksl = BandLayouts(gd, bd, block_comm, float)

# Random wave functions:
psit_mG = gd.empty(M)
コード例 #12
0
ファイル: realspace_blacs.py プロジェクト: thonmaker/gpaw
N = 10  # number of bands

# B: number of band groups
# D: number of domains
B = 2
D = 2

n = N // B  # number of bands per group
assert n * B == N, 'n=%d, B=%d, N=%d' % (n, B, N)

h = 0.2  # grid spacing
a = h * G  # side length of box

# Set up communicators:
comms = distribute_cpus(parsize_domain=D,
                        parsize_bands=B,
                        nspins=1,
                        nibzkpts=2)
domain_comm, kpt_comm, band_comm, block_comm = \
    [comms[name] for name in ['d', 'k', 'b', 'K']]
assert world.size == D * B * kpt_comm.size

if world.rank == 0:
    print('MPI: %d domains, %d band groups, %d kpts' %
          (domain_comm.size, band_comm.size, kpt_comm.size))

# Set up band and grid descriptors:
bd = BandDescriptor(N, band_comm, False)
gd = GridDescriptor((G, G, G), (a, a, a), True, domain_comm, parsize_c=D)

mcpus, ncpus, blocksize = 2, 2, 6
コード例 #13
0
ファイル: realspace_blacs.py プロジェクト: qsnake/gpaw
G = 120  # number of grid points (G x G x G)
N = 10  # number of bands

# B: number of band groups
# D: number of domains
B = 2
D = 2

n = N // B     # number of bands per group
assert n * B == N, 'n=%d, B=%d, N=%d' % (n, B, N)

h = 0.2        # grid spacing
a = h * G      # side length of box

# Set up communicators:
domain_comm, kpt_comm, band_comm = distribute_cpus(parsize=D, parsize_bands=B, \
                                                   nspins=1, nibzkpts=2)
assert world.size == D*B*kpt_comm.size

if world.rank == 0:
    print 'MPI: %d domains, %d band groups, %d kpts' % (domain_comm.size, band_comm.size, kpt_comm.size)

# Set up band and grid descriptors:
bd = BandDescriptor(N, band_comm, False)
gd = GridDescriptor((G, G, G), (a, a, a), True, domain_comm, parsize=D)

mcpus, ncpus, blocksize = 2, 2, 6

def blacs_diagonalize(ksl, H_Nn, U_nN, eps_n):
    # H_Nn must be lower triangular or symmetric, 
    # but not upper triangular.
    # U_nN will be symmetric
コード例 #14
0
ファイル: hamiltonian.py プロジェクト: yihsuanliu/gpaw
    else:
        B = world.size // np.prod(parsize)
        D = parsize
else:
    B = parsize_bands
    D = world.size // B

M = N // B  # number of bands per group
assert M * B == N, 'M=%d, B=%d, N=%d' % (M, B, N)

h = 0.2  # grid spacing
a = h * G  # side length of box
assert np.prod(D) * B == world.size, 'D=%s, B=%d, W=%d' % (D, B, world.size)

# Set up communicators:
domain_comm, kpt_comm, band_comm = distribute_cpus(parsize=D, parsize_bands=B, \
                                                   nspins=1, nibzkpts=1)
assert kpt_comm.size == 1
if world.rank == 0:
    print 'MPI: %d domains, %d band groups' % (domain_comm.size,
                                               band_comm.size)

# Set up band and grid descriptors:
bd = BandDescriptor(N, band_comm, False)
gd = GridDescriptor((G, G, G), (a, a, a), True, domain_comm, parsize=D)
ksl = BandLayouts(gd, bd, float)

# Random wave functions:
psit_mG = gd.empty(M)
for m in range(M):
    np.random.seed(world.rank * M + m)
    psit_mG[m] = np.random.uniform(-0.5, 0.5, tuple(gd.n_c))
コード例 #15
0
ファイル: paw.py プロジェクト: qsnake/gpaw
    def initialize(self, atoms=None):
        """Inexpensive initialization."""

        if atoms is None:
            atoms = self.atoms
        else:
            # Save the state of the atoms:
            self.atoms = atoms.copy()

        par = self.input_parameters

        world = par.communicator
        if world is None:
            world = mpi.world
        elif hasattr(world, 'new_communicator'):
            # Check for whether object has correct type already
            #
            # Using isinstance() is complicated because of all the
            # combinations, serial/parallel/debug...
            pass
        else:
            # world should be a list of ranks:
            world = mpi.world.new_communicator(np.asarray(world))
        self.wfs.world = world

        self.set_text(par.txt, par.verbose)

        natoms = len(atoms)

        pos_av = atoms.get_positions() / Bohr
        cell_cv = atoms.get_cell()
        pbc_c = atoms.get_pbc()
        Z_a = atoms.get_atomic_numbers()
        magmom_a = atoms.get_initial_magnetic_moments()

        magnetic = magmom_a.any()

        spinpol = par.spinpol
        if par.hund:
            if natoms != 1:
                raise ValueError('hund=True arg only valid for single atoms!')
            spinpol = True

        if spinpol is None:
            spinpol = magnetic
        elif magnetic and not spinpol:
            raise ValueError('Non-zero initial magnetic moment for a '
                             'spin-paired calculation!')

        nspins = 1 + int(spinpol)
        
        if isinstance(par.xc, str):
            xc = XC(par.xc)
        else:
            xc = par.xc

        setups = Setups(Z_a, par.setups, par.basis, par.lmax, xc, world)

        # K-point descriptor
        kd = KPointDescriptor(par.kpts, nspins)

        width = par.width
        if width is None:
            if kd.gamma:
                width = 0.0
            else:
                width = 0.1  # eV
        else:
            assert par.occupations is None
      
        if par.gpts is not None and par.h is None:
            N_c = np.array(par.gpts)
        else:
            if par.h is None:
                self.text('Using default value for grid spacing.')
                h = 0.2 
            else:
                h = par.h
            N_c = h2gpts(h, cell_cv)

        cell_cv /= Bohr


        if hasattr(self, 'time') or par.dtype==complex:
            dtype = complex
        else:
            if kd.gamma:
                dtype = float
            else:
                dtype = complex

        kd.set_symmetry(atoms, setups, par.usesymm, N_c)

        nao = setups.nao
        nvalence = setups.nvalence - par.charge

        nbands = par.nbands
        if nbands is None:
            nbands = nao
        elif nbands > nao and par.mode == 'lcao':
            raise ValueError('Too many bands for LCAO calculation: ' +
                             '%d bands and only %d atomic orbitals!' %
                             (nbands, nao))

        if nvalence < 0:
            raise ValueError(
                'Charge %f is not possible - not enough valence electrons' %
                par.charge)

        M = magmom_a.sum()
        if par.hund:
            f_si = setups[0].calculate_initial_occupation_numbers(
                magmom=0, hund=True, charge=par.charge, nspins=nspins)
            Mh = f_si[0].sum() - f_si[1].sum()
            if magnetic and M != Mh:
                raise RuntimeError('You specified a magmom that does not'
                                   'agree with hunds rule!')
            else:
                M = Mh

        if nbands <= 0:
            nbands = int(nvalence + M + 0.5) // 2 + (-nbands)

        if nvalence > 2 * nbands:
            raise ValueError('Too few bands!  Electrons: %d, bands: %d'
                             % (nvalence, nbands))

        if par.width is not None:
            self.text('**NOTE**: please start using '
                      'occupations=FermiDirac(width).')
        if par.fixmom:
            self.text('**NOTE**: please start using '
                      'occupations=FermiDirac(width, fixmagmom=True).')

        if self.occupations is None:
            if par.occupations is None:
                # Create object for occupation numbers:
                self.occupations = occupations.FermiDirac(width, par.fixmom)
            else:
                self.occupations = par.occupations

        self.occupations.magmom = M

        cc = par.convergence

        if par.mode == 'lcao':
            niter_fixdensity = 0
        else:
            niter_fixdensity = None

        if self.scf is None:
            self.scf = SCFLoop(
                cc['eigenstates'] * nvalence,
                cc['energy'] / Hartree * max(nvalence, 1),
                cc['density'] * nvalence,
                par.maxiter, par.fixdensity,
                niter_fixdensity)

        parsize, parsize_bands = par.parallel['domain'], par.parallel['band']

        if parsize_bands is None:
            parsize_bands = 1

        # TODO delete/restructure so all checks are in BandDescriptor
        if nbands % parsize_bands != 0:
            raise RuntimeError('Cannot distribute %d bands to %d processors' %
                               (nbands, parsize_bands))

        if not self.wfs:
            if parsize == 'domain only': #XXX this was silly!
                parsize = world.size

            domain_comm, kpt_comm, band_comm = mpi.distribute_cpus(parsize,
                parsize_bands, nspins, kd.nibzkpts, world, par.idiotproof)

            kd.set_communicator(kpt_comm)

            parstride_bands = par.parallel['stridebands']
            bd = BandDescriptor(nbands, band_comm, parstride_bands)

            if (self.density is not None and
                self.density.gd.comm.size != domain_comm.size):
                # Domain decomposition has changed, so we need to
                # reinitialize density and hamiltonian:
                if par.fixdensity:
                    raise RuntimeError("I'm confused - please specify parsize."
                                       )
                self.density = None
                self.hamiltonian = None

            # Construct grid descriptor for coarse grids for wave functions:
            gd = self.grid_descriptor_class(N_c, cell_cv, pbc_c,
                                            domain_comm, parsize)

            # do k-point analysis here? XXX
            args = (gd, nvalence, setups, bd, dtype, world, kd, self.timer)

            if par.mode == 'lcao':
                # Layouts used for general diagonalizer
                sl_lcao = par.parallel['sl_lcao']
                if sl_lcao is None:
                    sl_lcao = par.parallel['sl_default']
                lcaoksl = get_KohnSham_layouts(sl_lcao, 'lcao',
                                               gd, bd, dtype,
                                               nao=nao, timer=self.timer)

                self.wfs = LCAOWaveFunctions(lcaoksl, *args)
            elif par.mode == 'fd' or isinstance(par.mode, PW):
                # buffer_size keyword only relevant for fdpw
                buffer_size = par.parallel['buffer_size']
                # Layouts used for diagonalizer
                sl_diagonalize = par.parallel['sl_diagonalize']
                if sl_diagonalize is None:
                    sl_diagonalize = par.parallel['sl_default']
                diagksl = get_KohnSham_layouts(sl_diagonalize, 'fd',
                                               gd, bd, dtype,
                                               buffer_size=buffer_size,
                                               timer=self.timer)

                # Layouts used for orthonormalizer
                sl_inverse_cholesky = par.parallel['sl_inverse_cholesky']
                if sl_inverse_cholesky is None:
                    sl_inverse_cholesky = par.parallel['sl_default']
                if sl_inverse_cholesky != sl_diagonalize:
                    message = 'sl_inverse_cholesky != sl_diagonalize ' \
                        'is not implemented.'
                    raise NotImplementedError(message)
                orthoksl = get_KohnSham_layouts(sl_inverse_cholesky, 'fd',
                                                gd, bd, dtype,
                                                buffer_size=buffer_size,
                                                timer=self.timer)

                # Use (at most) all available LCAO for initialization
                lcaonbands = min(nbands, nao)
                lcaobd = BandDescriptor(lcaonbands, band_comm, parstride_bands)
                assert nbands <= nao or bd.comm.size == 1
                assert lcaobd.mynbands == min(bd.mynbands, nao) #XXX

                # Layouts used for general diagonalizer (LCAO initialization)
                sl_lcao = par.parallel['sl_lcao']
                if sl_lcao is None:
                    sl_lcao = par.parallel['sl_default']
                initksl = get_KohnSham_layouts(sl_lcao, 'lcao',
                                               gd, lcaobd, dtype, 
                                               nao=nao,
                                               timer=self.timer)

                if par.mode == 'fd':
                    self.wfs = FDWaveFunctions(par.stencils[0], diagksl,
                                               orthoksl, initksl, *args)
                else:
                    # Planewave basis:
                    self.wfs = par.mode(diagksl, orthoksl, initksl,
                                        gd, nvalence, setups, bd,
                                        world, kd, self.timer)
            else:
                self.wfs = par.mode(self, *args)
        else:
            self.wfs.set_setups(setups)

        if not self.wfs.eigensolver:
            # Number of bands to converge:
            nbands_converge = cc['bands']
            if nbands_converge == 'all':
                nbands_converge = nbands
            elif nbands_converge != 'occupied':
                assert isinstance(nbands_converge, int)
                if nbands_converge < 0:
                    nbands_converge += nbands
            eigensolver = get_eigensolver(par.eigensolver, par.mode,
                                          par.convergence)
            eigensolver.nbands_converge = nbands_converge
            # XXX Eigensolver class doesn't define an nbands_converge property
            self.wfs.set_eigensolver(eigensolver)

        if self.density is None:
            gd = self.wfs.gd
            if par.stencils[1] != 9:
                # Construct grid descriptor for fine grids for densities
                # and potentials:
                finegd = gd.refine()
            else:
                # Special case (use only coarse grid):
                finegd = gd
            self.density = Density(gd, finegd, nspins,
                                   par.charge + setups.core_charge)

        self.density.initialize(setups, par.stencils[1], self.timer,
                                magmom_a, par.hund)
        self.density.set_mixer(par.mixer)

        if self.hamiltonian is None:
            gd, finegd = self.density.gd, self.density.finegd
            self.hamiltonian = Hamiltonian(gd, finegd, nspins,
                                           setups, par.stencils[1], self.timer,
                                           xc, par.poissonsolver,
                                           par.external)

        xc.initialize(self.density, self.hamiltonian, self.wfs,
                      self.occupations)

        self.text()
        self.print_memory_estimate(self.txt, maxdepth=memory_estimate_depth)
        self.txt.flush()

        if dry_run:
            self.dry_run()

        self.initialized = True