def read_supercell(self): """ Reads a supercell from the Sile """ # 1st line is number of supercells nsc = _a.fromiteri(map(int, self.readline().split()[:3])) self.readline() # natoms, nspecies self.readline() # species cell = _a.fromiterd(map(float, self.readline().split()[:9])) # Typically ScaleUp uses very large unit-cells # so supercells will typically be restricted to [3, 3, 3] return SuperCell(cell * Bohr2Ang, nsc=nsc)
def read_geometry(self, primary=False, **kwargs): """ Reads a geometry from the Sile """ # 1st line is number of supercells nsc = _a.fromiteri(map(int, self.readline().split()[:3])) na, ns = map(int, self.readline().split()[:2]) # Convert species to atom objects try: species = get_sile(self.file.rsplit('REF', 1)[0] + 'orbocc').read_atom() except: species = [Atom(s) for s in self.readline().split()[:ns]] # Total number of super-cells if primary: # Only read in the primary unit-cell ns = 1 else: ns = np.prod(nsc) cell = _a.fromiterd(map(float, self.readline().split())) try: cell.shape = (3, 3) if primary: cell[0, :] /= nsc[0] cell[1, :] /= nsc[1] cell[2, :] /= nsc[2] except: c = np.empty([3, 3], np.float64) c[0, 0] = 1. + cell[0] c[0, 1] = cell[5] / 2. c[0, 2] = cell[4] / 2. c[1, 0] = cell[5] / 2. c[1, 1] = 1. + cell[1] c[1, 2] = cell[3] / 2. c[2, 0] = cell[4] / 2. c[2, 1] = cell[3] / 2. c[2, 2] = 1. + cell[2] cell = c * Ang2Bohr sc = SuperCell(cell * Bohr2Ang, nsc=nsc) # Create list of coordinates and atoms xyz = np.empty([na * ns, 3], np.float64) atoms = [None] * na * ns # Read the geometry for ia in range(na * ns): # Retrieve line # ix iy iz ia is x y z line = self.readline().split() atoms[ia] = species[int(line[4]) - 1] xyz[ia, :] = _a.fromiterd(map(float, line[5:8])) return Geometry(xyz * Bohr2Ang, atoms, sc=sc)
def Neumann(idx_bc, idx_p1): # TODO check this BC # Set all boundary equations to 0 s = array_arange(A.indptr[idx_bc], A.indptr[idx_bc+1]) A.data[s] = 0 # force the boundary cells to equal the neighbouring cell A[idx_bc, idx_bc] = -C # I am not sure this is correct, but setting it to 0 does NOT work A[idx_bc, idx_p1] = C # ensure the neighbouring cell doesn't connect to the boundary (no back propagation) A[idx_p1, idx_bc] = 0 # Ensure the sum of the source for the neighbouring cells equals 0 # To make it easy to figure out the diagonal elements we first # set it to 0, then sum off-diagonal terms, and set the diagonal # equal to the sum. A[idx_p1, idx_p1] = 0 n = A.indptr[idx_p1+1] - A.indptr[idx_p1] s = array_arange(A.indptr[idx_p1], n=n) n = np.split(A.data[s], np.cumsum(n)[:-1]) n = _a.fromiteri(map(np.sum, n)) # update diagonal A[idx_p1, idx_p1] = -n del s, n A.eliminate_zeros() b[idx_bc] = 0.