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
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
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
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)
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
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
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)
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)
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)
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)
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
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
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))
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