def read_geometry(self, velocity=False, species_Z=False): """ Returns a `Geometry` object from the XV file Parameters ---------- species_Z : bool, optional if ``True`` the atomic numbers are the species indices (useful when reading the ChemicalSpeciesLabel block simultaneously). velocity : bool, optional also return the velocities in the file Returns ------- Geometry velocity : only if `velocity` is true. """ sc = self.read_supercell() # Read number of atoms na = int(self.readline()) xyz = np.empty([na, 3], np.float64) vel = np.empty([na, 3], np.float64) atms = [None] * na sp = np.empty([na], np.int32) for ia in range(na): line = list(map(float, self.readline().split()[:8])) sp[ia] = int(line[0]) if species_Z: atms[ia] = Atom(sp[ia]) else: atms[ia] = Atom(int(line[1])) xyz[ia, :] = line[2:5] vel[ia, :] = line[5:8] xyz *= Bohr2Ang vel *= Bohr2Ang # Ensure correct sorting max_s = sp.max() sp -= 1 # Ensure we can remove the atom after having aligned them atms2 = Atoms(AtomUnknown(1000), na=na) for i in range(max_s): idx = (sp[:] == i).nonzero()[0] if len(idx) == 0: # Always ensure we have "something" for the unoccupied places atms2[idx] = AtomUnknown(1000 + i) else: atms2[idx] = atms[idx[0]] geom = Geometry(xyz, atms2.reduce(), sc=sc) if velocity: return geom, vel return geom
def write_grid(self, *args, **kwargs): """ Store grid(s) data to an XSF file Examples -------- >>> g1 = Grid(0.1, sc=2.) >>> g2 = Grid(0.1, sc=2.) >>> get_sile('output.xsf', 'w').write_grid(g1, g2) Parameters ---------- *args : Grid a list of data-grids to be written to the XSF file. Each argument gets the field name ``?grid_<>`` where <> starts with the integer 0, and *?* is ``real_``/``imag_`` for complex valued grids. geometry : Geometry, optional the geometry stored in the file, defaults to ``args[0].geometry`` fmt : str, optional floating point format for data (.5e) buffersize : int, optional size of the buffer while writing the data, (6144) """ sile_raise_write(self) geom = kwargs.get('geometry', args[0].geometry) if geom is None: geom = Geometry([0, 0, 0], AtomUnknown(999), sc=args[0].sc) self.write_geometry(geom) # Buffer size for writing buffersize = kwargs.get('buffersize', min(6144, args[0].grid.size)) # Format for precision fmt = kwargs.get('fmt', '.5e') self._write('BEGIN_BLOCK_DATAGRID_3D\n') name = kwargs.get('name', 'sisl_grid_{}'.format(len(args))) # Transfer all spaces to underscores (no spaces allowed) self._write(' ' + name.replace(' ', '_') + '\n') _v3 = (('{:' + fmt + '} ') * 3).strip() + '\n' def write_cell(grid): # Now write the grid self._write(' {} {} {}\n'.format(*grid.shape)) self._write(' ' + _v3.format(*grid.origo)) self._write(' ' + _v3.format(*grid.cell[0, :])) self._write(' ' + _v3.format(*grid.cell[1, :])) self._write(' ' + _v3.format(*grid.cell[2, :])) for i, grid in enumerate(args): is_complex = np.iscomplexobj(grid.grid) name = kwargs.get('grid' + str(i), str(i)) if is_complex: self._write(f' BEGIN_DATAGRID_3D_real_{name}\n') else: self._write(f' BEGIN_DATAGRID_3D_{name}\n') write_cell(grid) # for z # for y # for x # write... _fmt = '{:' + fmt + '}\n' for x in np.nditer(np.asarray(grid.grid.real.T, order='C').reshape(-1), flags=['external_loop', 'buffered'], op_flags=[['readonly']], order='C', buffersize=buffersize): self._write((_fmt * x.shape[0]).format(*x.tolist())) self._write(' END_DATAGRID_3D\n') # Skip if not complex if not is_complex: continue self._write(f' BEGIN_DATAGRID_3D_imag_{name}\n') write_cell(grid) for x in np.nditer(np.asarray(grid.grid.imag.T, order='C').reshape(-1), flags=['external_loop', 'buffered'], op_flags=[['readonly']], order='C', buffersize=buffersize): self._write((_fmt * x.shape[0]).format(*x.tolist())) self._write(' END_DATAGRID_3D\n') self._write('END_BLOCK_DATAGRID_3D\n')