def get_deformed_cell(base_cryst, axis=0, size=1): ''' Return the cell (with atoms) deformed along one cell parameter (0,1,2 = a,b,c ; 3,4,5 = alpha,beta,gamma) by size percent or size degrees (axis/angles). ''' cryst = Atoms(base_cryst) uc = base_cryst.get_cell() if axis < 3: uc[axis, :] = (1+size/100.0)*uc[axis, :] else: (a, b, c, alp, bet, gam) = get_vecang_cell(cryst) d = array([0.0, 0.0, 0.0]) d[axis-3] = pi*size/180 (alp, bet, gam) = array((alp, bet, gam))+d t = 1 - (ctg(bet)*ctg(gam)-cos(alp)*csc(bet)*csc(gam))**2 if t < 0.0: print(''' The parameters (alpha,beta,gamma)=(%f,%f,%f) are probably incorrect and lead to imaginary coordinates. This range of parameters is unsupported by this program (and is, let me say, very strange for a crystal). Cennot continue, bye.''' % (alp, bet, gam)) raise ValueError else: uc = [[a, 0.0, 0.0], [b*cos(gam), b*sin(gam), 0], [c*cos(bet), c*(cos(alp)/sin(gam) - cos(bet)*ctg(gam)), c*sin(bet)*sqrt(t)]] cryst.set_cell(uc, scale_atoms=True) # print(cryst.get_cell()) # print(uc) return cryst
def get_cart_deformed_cell(base_cryst, axis=0, size=1): '''Return the cell deformed along one of the cartesian directions Creates new deformed structure. The deformation is based on the base structure and is performed along single axis. The axis is specified as follows: 0,1,2 = x,y,z ; sheers: 3,4,5 = yz, xz, xy. The size of the deformation is in percent and degrees, respectively. :param base_cryst: structure to be deformed :param axis: direction of deformation :param size: size of the deformation :returns: new, deformed structure ''' cryst = Atoms(base_cryst) uc = base_cryst.get_cell() s = size/100.0 L = diag(ones(3)) if axis < 3: L[axis, axis] += s else: if axis == 3: L[1, 2] += s elif axis == 4: L[0, 2] += s else: L[0, 1] += s uc = dot(uc, L) cryst.set_cell(uc, scale_atoms=True) # print(cryst.get_cell()) # print(uc) return cryst
def read_dacapo(filename): from ase.io.pupynere import NetCDFFile nc = NetCDFFile(filename) dims = nc.dimensions vars = nc.variables cell = vars['UnitCell'][-1] try: magmoms = vars['InitialAtomicMagneticMoment'][:] except KeyError: magmoms = None try: tags = vars['AtomTags'][:] except KeyError: tags = None atoms = Atoms(scaled_positions=vars['DynamicAtomPositions'][-1], symbols=[(a + b).strip() for a, b in vars['DynamicAtomSpecies'][:]], cell=cell, magmoms=magmoms, tags=tags, pbc=True) try: energy = vars['TotalEnergy'][-1] force = vars['DynamicAtomForces'][-1] except KeyError: energy = None force = None calc = SinglePointCalculator(energy,force,None, None, atoms) ### Fixme magmoms atoms.set_calculator(calc) return atoms
def dict2atoms(dct, attach_calculator=False): constraint_dicts = dct.get('constraints') if constraint_dicts: constraints = [] for c in constraint_dicts: assert c.pop('__name__') == 'ase.constraints.FixAtoms' constraints.append(FixAtoms(**c)) else: constraints = None atoms = Atoms(dct['numbers'], dct['positions'], cell=dct['cell'], pbc=dct['pbc'], magmoms=dct.get('magmoms'), charges=dct.get('charges'), tags=dct.get('tags'), masses=dct.get('masses'), momenta=dct.get('momenta'), constraint=constraints) results = dct.get('results') if attach_calculator: atoms.calc = get_calculator(dct['calculator_name'])( **dct['calculator_parameters']) elif results: atoms.calc = SinglePointCalculator(atoms, **results) return atoms
def datacollection_to_atoms(self): """ Convert from ovito.data.DataCollection to ase.atoms.Atoms """ # Extract basic dat: pbc, cell, positions, particle types pbc = self.cell.pbc cell_matrix = np.array(self.cell.matrix) cell, origin = cell_matrix[:, :3], cell_matrix[:, 3] info = {'cell_origin': origin } positions = np.array(self.position) type_names = dict([(t.id, t.name) for t in self.particle_type.type_list]) symbols = [type_names[id] for id in np.array(self.particle_type)] # construct ase.Atoms object atoms = Atoms(symbols, positions, cell=cell, pbc=pbc, info=info) # Convert any other particle properties to additional arrays for name, prop in self.iteritems(): if name in ['Simulation cell', 'Position', 'Particle Type']: continue if not isinstance(prop, ParticleProperty): continue atoms.new_array(prop.name, prop.array) return atoms
def crystalAtoms(self, start_layer=0, end_layer=1, coordinates='orth_surface', sub_layers=False, minimal=True, ): atoms = self.crystal().atoms() if sub_layers: in_equal_layers = self.inequivalentLayers() repeats = int(np.ceil(end_layer/float(in_equal_layers))) atoms = atoms.repeat((1, 1, repeats + 1)) atoms.positions -= self.crystal().unitCell()*(repeats) start_layer += in_equal_layers -1 end_layer += in_equal_layers -1 atoms = orderAtoms(atoms, (2, 1, 0)) sl = slice(start_layer, end_layer) groups = groupAtoms(atoms)[::-1][sl] if len(groups) == 0: atoms = Atoms([], cell=atoms.get_cell(), pbc=atoms.get_pbc()) else: atoms, indices = groups[0] for group, indices in groups[1:]: atoms += group else: cell = atoms.unitCell() atoms = atoms.repeat((1, 1, end_layer-start_layer)) atoms.positions += cell*start_layer return atoms
def dict2atoms(dct, attach_calculator=False): constraint_dicts = dct.get('constraints') if constraint_dicts: constraints = [dict2constraint(c) for c in constraint_dicts] else: constraints = None atoms = Atoms(dct['numbers'], dct['positions'], cell=dct['cell'], pbc=dct['pbc'], magmoms=dct.get('initial_magmoms'), charges=dct.get('initial_charges'), tags=dct.get('tags'), masses=dct.get('masses'), momenta=dct.get('momenta'), constraint=constraints) if attach_calculator: atoms.calc = get_calculator(dct['calculator'])( **dct['calculator_parameters']) else: results = {} for prop in all_properties: if prop in dct: results[prop] = dct[prop] if results: atoms.calc = SinglePointCalculator(atoms, **results) return atoms
def __getitem__(self, i=-1): b = self.backend[i] atoms = Atoms(positions=b.positions, numbers=self.numbers, cell=b.cell, masses=self.masses, pbc=self.pbc, celldisp=self.celldisp, info=b.get('info'), constraint=[dict2constraint(d) for d in decode(self.constraints)], momenta=b.get('momenta'), magmoms=b.get('magmoms'), charges=b.get('charges'), tags=b.get('tags')) atoms._readTags(self.new_tags) if 'calculator' in b: results = {} c = b.calculator for prop in all_properties: if prop in c: results[prop] = c.get(prop) calc = SinglePointCalculator(atoms, **results) calc.name = b.calculator.name atoms.set_calculator(calc) return atoms
def mx2(formula='MoS2', kind='2H', a=3.18, thickness=3.19, size=(1, 1, 1), vacuum=7.5): """Create three-layer 2D materials with hexagonal structure. For metal dichalcogenites, ect. The kind argument accepts '2H', which gives a mirror plane symmetry and '1T', which gives an inversion symmetry.""" if kind == '2H': basis = [(0, 0, 0), (2 / 3, 1 / 3, 0.5 * thickness), (2 / 3, 1 / 3, -0.5 * thickness)] elif kind == '1T': basis = [(0, 0, 0), (2 / 3, 1 / 3, 0.5 * thickness), (1 / 3, 2 / 3, -0.5 * thickness)] else: raise ValueError('Structure not recognized') cell = [[a, 0, 0], [-a / 2, a * 3**0.5 / 2, 0], [0, 0, 1]] atoms = Atoms(formula, cell=cell, scaled_positions=basis, pbc=(1, 1, 0)) atoms.center(vacuum=vacuum, axis=2) return atoms
def dimer(self): dimer = Atoms([self.symbol, self.symbol], pbc=True, cell=(self.a, self.a, self.a)) self.Edimer = np.zeros((self.ng, 7)) self.Fdimer = np.zeros((self.ng, 7, 2)) q0 = self.d0 / np.sqrt(3) eigensolver = 'rmm-diis' if self.symbol in ['Ti', 'Sn', 'Te', 'Ba']: eigensolver = 'cg' for i in range(self.ng): h = self.gridspacings[i] calc = GPAW(h=h, txt='%s-dimer-%.3f.txt' % (self.symbol, h), mixer=Mixer(beta=0.1, nmaxold=5, weight=50), #mixer=Mixer(beta=0.05, nmaxold=7, weight=100), eigensolver=eigensolver, maxiter=300, nbands=-10, **self.parameters) dimer.set_calculator(calc) y = [] for j in range(-3, 4): q = q0 * (1 + j * 0.02) dimer.positions[1] = (q, q, q) try: e = calc.get_potential_energy(dimer, force_consistent=True) self.Edimer[i, j + 3] = e except ConvergenceError: raise self.Fdimer[i, j + 3] = dimer.get_forces()[:, 0]
def eggbox(self): atom = Atoms(self.symbol, pbc=True, cell=(self.a, self.a, self.a)) negg = 25 self.Eegg = np.zeros((self.ng, negg)) self.Fegg = np.zeros((self.ng, negg)) eigensolver = 'rmm-diis' if self.symbol in ['Na', 'Mg']: eigensolver = 'cg' if self.symbol in ['Sc', 'Ti', 'V', 'Mn', 'Ni', 'Zn']: eigensolver = 'cg' if self.symbol in ['Zr', 'Nb', 'Mo', 'Ru', 'Rh', 'Pd', 'Ag']: eigensolver = 'cg' if self.symbol in ['Sn', 'Sb', 'Te', 'Ba']: eigensolver = 'cg' if self.symbol in ['Hf', 'Ta', 'W', 'Re', 'Os', 'Ir', 'Pt', 'Hg', 'Pb', 'Bi']: eigensolver = 'cg' for i in range(self.ng): h = self.gridspacings[i] calc = GPAW(h=h, txt='%s-eggbox-%.3f.txt' % (self.symbol, h), mixer=Mixer(beta=0.1, nmaxold=5, weight=50), eigensolver=eigensolver, maxiter=300, nbands=-10, **self.parameters) atom.set_calculator(calc) for j in range(negg): x = h * j / (2 * negg - 2) atom[0].x = x try: e = calc.get_potential_energy(atom, force_consistent=True) self.Eegg[i, j] = e except ConvergenceError: raise self.Fegg[i, j] = atom.get_forces()[0, 0]
def read_pdb(fileobj, index=-1): """Read PDB files. The format is assumed to follow the description given in http://www.wwpdb.org/documentation/format32/sect9.html.""" if isinstance(fileobj, str): fileobj = open(fileobj) atoms = Atoms() for line in fileobj.readlines(): if line.startswith('ATOM'): try: symbol = line[12:16].strip() # we assume that the second character is a label # in case that it is upper case if len(symbol) > 1 and symbol[1].isupper(): symbol = symbol[0] words = line[30:55].split() position = np.array([float(words[0]), float(words[1]), float(words[2])]) atoms.append(Atom(symbol, position)) except: pass return atoms
def dict2atoms(dct, attach_calculator=False): constraint_dicts = dct.get("constraints") if constraint_dicts: constraints = [dict2constraint(c) for c in constraint_dicts] else: constraints = None atoms = Atoms( dct["numbers"], dct["positions"], cell=dct["cell"], pbc=dct["pbc"], magmoms=dct.get("initial_magmoms"), charges=dct.get("initial_charges"), tags=dct.get("tags"), masses=dct.get("masses"), momenta=dct.get("momenta"), constraint=constraints, ) if attach_calculator: atoms.calc = get_calculator(dct["calculator"])(**dct["calculator_parameters"]) else: results = {} for prop in all_properties: if prop in dct: results[prop] = dct[prop] if results: atoms.calc = SinglePointCalculator(atoms, **results) return atoms
def read_pdb(fileobj, index=-1): """Read PDB files. The format is assumed to follow the description given in http://www.wwpdb.org/documentation/format32/sect9.html.""" if isinstance(fileobj, str): fileobj = open(fileobj) images = [] atoms = Atoms() for line in fileobj.readlines(): if line.startswith('ATOM') or line.startswith('HETATM'): try: # Atom name is arbitrary and does not necessarily contain the element symbol. # The specification requires the element symbol to be in columns 77+78. symbol = line[76:78].strip().lower().capitalize() words = line[30:55].split() position = np.array([float(words[0]), float(words[1]), float(words[2])]) atoms.append(Atom(symbol, position)) except: pass if line.startswith('ENDMDL'): images.append(atoms) atoms = Atoms() if len(images) == 0: images.append(atoms) return images[index]
def read_gaussian_out(filename, index=-1, quantity='atoms'): """"Interface to GaussianReader and returns various quantities""" energy = 0.0 data = GR(filename)[index] formula = data['Chemical_formula'] positions = np.array(data['Positions']) method = data['Method'] version = data['Version'] if method.lower()[1:] in allowed_dft_functionals: method = 'HF' atoms = Atoms(formula, positions=positions) for key, value in data.items(): if (key in method): energy = value try: # Re-read in the log file f = open(filename, 'r') lines = f.readlines() f.close() forces = list() charges = list() for n, line in enumerate(lines): if ('Forces (Hartrees/Bohr)' in line): for j in range(len(atoms)): forces += [[float(lines[n + j + 3].split()[2]), float(lines[n + j + 3].split()[3]), float(lines[n + j + 3].split()[4])]] if ('Mulliken charges:' in line): for j in range(len(atoms)): charges += [-float(lines[n+j+2].split()[2])+int(Atoms(str(lines[n+j+2].split()[1])).get_atomic_numbers())] convert = ase.units.Hartree / ase.units.Bohr forces = np.array(forces) * convert except: forces = None energy *= ase.units.Hartree # Convert the energy from a.u. to eV calc = SinglePointCalculator(atoms, energy=energy, forces=forces) atoms.set_calculator(calc) if (quantity == 'energy'): return energy elif (quantity == 'forces'): return forces elif (quantity == 'dipole'): return data['Dipole'] elif (quantity == 'atoms'): return atoms elif (quantity == 'version'): return version elif (quantity == 'charges'): return charges
def __crystal_init__(self, *args, **kwargs): Atoms.__atoms_init__(self, *args, **kwargs) self.recalc_bulk=True self.bulk_modulus=None self.bm_eos=None self.full_min_calc=None self.cell_min_calc=None self.idof_min_calc=None
def createCH2(self): rot = xRotation(2/3*pi) mpow = np.linalg.matrix_power h_coords = array((-cos(c_angle), 0, sin(c_angle)))*ch_length pos = [zeros((3)), dot(rot, h_coords), dot(mpow(rot,2), h_coords)] atoms = Atoms('CH2', pos) atoms.info['bonds'] = Bonds(atoms, pairs=((0,1), (0,2))) return atoms
def read_xsf(fileobj, index=-1): if isinstance(fileobj, str): fileobj = open(fileobj) readline = fileobj.readline line = readline() if line.startswith('ANIMSTEPS'): nimages = int(line.split()[1]) line = readline() else: nimages = 1 if line.startswith('CRYSTAL'): pbc = True elif line.startswith('SLAB'): pbc = (True, True, Flase) elif line.startswith('POLYMER'): pbc = (True, False, Flase) else: pbc = False images = [] for n in range(nimages): cell = None if pbc: line = readline() assert line.startswith('PRIMVEC') cell = [] for i in range(3): cell.append([float(x) for x in readline().split()]) line = readline() assert line.startswith('PRIMCOORD') natoms = int(readline().split()[0]) numbers = [] positions = [] for a in range(natoms): line = readline().split() numbers.append(int(line[0])) positions.append([float(x) for x in line[1:]]) positions = np.array(positions) if len(positions[0]) == 3: forces = None else: positions = positions[:, :3] forces = positions[:, 3:] * Hartree image = Atoms(numbers, positions, cell=cell, pbc=pbc) if forces is not None: image.set_calculator(SinglePointCalculator(None, forces, None, None, image)) images.append(image) return images[index]
def read_gpaw_text(fileobj, index=-1): if isinstance(fileobj, str): fileobj = open(fileobj) lines = fileobj.readlines() images = [] while True: try: i = lines.index('Unit Cell:\n') cell = [float(line.split()[2]) for line in lines[i + 3:i + 6]] pbc = [line.split()[1] == 'yes' for line in lines[i + 3:i + 6]] except ValueError: pass try: i = lines.index('Positions:\n') except ValueError: break atoms = Atoms(cell=cell, pbc=pbc) for line in lines[i + 1:]: words = line.split() if len(words) != 5: break n, symbol, x, y, z = words symbol = symbol.split('.')[0] atoms.append(Atom(symbol, [float(x), float(y), float(z)])) lines = lines[i + 5:] try: i = lines.index('-------------------------\n') except ValueError: e = None else: line = lines[i + 9] assert line.startswith('Zero Kelvin:') e = float(line.split()[-1]) try: ii = lines.index('Forces in eV/Ang:\n') except ValueError: f = None else: f = [] for i in range(ii + 1, ii + 1 + len(atoms)): try: x, y, z = lines[i].split()[-3:] f.append((float(x), float(y), float(z))) except (ValueError, IndexError), m: raise IOError('Malformed GPAW log file: %s' % m) if len(images) > 0 and e is None: break if e is not None or f is not None: atoms.set_calculator(SinglePointCalculator(e, f, None, None, atoms)) ### Fixme magmoms images.append(atoms) lines = lines[i:]
def read_turbomole(filename='coord'): """Method to read turbomole coord file coords in bohr, atom types in lowercase, format: $coord x y z atomtype x y z atomtype f $end Above 'f' means a fixed atom. """ from ase import Atoms, Atom from ase.constraints import FixAtoms if isinstance(filename, str): f = open(filename) lines = f.readlines() atoms_pos = [] atom_symbols = [] myconstraints=[] # find $coord section; # does not necessarily have to be the first $<something> in file... for i, l in enumerate(lines): if l.strip().startswith('$coord'): start = i break for line in lines[start+1:]: if line.startswith('$'): # start of new section break else: x, y, z, symbolraw = line.split()[:4] symbolshort=symbolraw.strip() symbol=symbolshort[0].upper()+symbolshort[1:].lower() #print symbol atom_symbols.append(symbol) atoms_pos.append([float(x)*Bohr, float(y)*Bohr, float(z)*Bohr]) cols = line.split() if (len(cols) == 5): fixedstr = line.split()[4].strip() if (fixedstr == "f"): myconstraints.append(True) else: myconstraints.append(False) else: myconstraints.append(False) if type(filename) == str: f.close() atoms = Atoms(positions = atoms_pos, symbols = atom_symbols, pbc = False) c = FixAtoms(mask = myconstraints) atoms.set_constraint(c) #print c return atoms
def colored(self, elements): res = Atoms() res.set_cell(self.get_cell()) for atom in self: elem = self.types[atom.tag] if elem in elements: elem = elements[elem] res.append(Atom(elem, atom.position)) return res
def get_atoms(self, frame): atoms = Atoms(positions=self.P[frame], numbers=self.Z, cell=self.A[frame], pbc=self.pbc) atoms.set_calculator(SinglePointCalculator(self.E[frame], self.F[frame], None, None, atoms)) return atoms
def write_dftb(filename, atoms): """Method to write atom structure in DFTB+ format (gen format) """ import numpy as np #sort atoms.set_masses() masses = atoms.get_masses() indexes = np.argsort(masses) atomsnew = Atoms() for i in indexes: atomsnew = atomsnew + atoms[i] if isinstance(filename, str): myfile = open(filename, 'w') else: # Assume it's a 'file-like object' myfile = filename ispbc = atoms.get_pbc() box = atoms.get_cell() if (any(ispbc)): myfile.write('%8d %2s \n' %(len(atoms), 'S')) else: myfile.write('%8d %2s \n' %(len(atoms), 'C')) chemsym = atomsnew.get_chemical_symbols() allchem = '' for i in chemsym: if i not in allchem: allchem = allchem + i + ' ' myfile.write(allchem+' \n') coords = atomsnew.get_positions() itype = 1 for iatom, coord in enumerate(coords): if iatom > 0: if chemsym[iatom] != chemsym[iatom-1]: itype = itype+1 myfile.write('%5i%5i %19.16f %19.16f %19.16f \n' \ %(iatom+1, itype, coords[iatom][0], coords[iatom][1], coords[iatom][2])) # write box if (any(ispbc)): #dftb dummy myfile.write(' %19.16f %19.16f %19.16f \n' %(0, 0, 0)) myfile.write(' %19.16f %19.16f %19.16f \n' %( box[0][0], box[0][1], box[0][2])) myfile.write(' %19.16f %19.16f %19.16f \n' %( box[1][0], box[1][1], box[1][2])) myfile.write(' %19.16f %19.16f %19.16f \n' %( box[2][0], box[2][1], box[2][2])) if type(filename) == str: myfile.close()
def build_crystal(a,b,c,al,be,ga): from ase.atoms import Atoms if (al+be+ga > 350) : return if (al+be < 1.1*ga) : return if (al+ga < 1.1*be) : return if (be+ga < 1.1*al) : return atms=Atoms('Mg', positions=[(0,0,0)], cell=[a,b,c,al,be,ga],pbc=True) atms._test_data=[a,b,c,al*pi/180,be*pi/180,ga*pi/180] return atms
def __init__(self, *args, **kwargs): quaternions = None if "quaternions" in kwargs: quaternions = np.array(kwargs["quaternions"]) del kwargs["quaternions"] Atoms.__init__(self, *args, **kwargs) if quaternions is not None: self.set_array("quaternions", quaternions, shape=(4,)) # set default shapes self.set_shapes(np.array([[5, 3, 1]] * len(self)))
def __init__(self, filename=None, *args, **kwargs): Atoms.__init__(self, *args, **kwargs) if filename: self.read_extended_xyz(filename) else: self.types = [] for atom in self: if atom.symbol not in self.types: self.types.append(atom.symbol) atom.tag = self.types.index(atom.symbol)
def build_atoms(positions, method, cell, alat): """Creates the atoms for a quantum espresso in file.""" if method != "crystal": raise NotImplementedError("Only supported for crystal method of " "ATOMIC_POSITIONS, not %s." % method) atoms = Atoms() for el, (x, y, z) in positions: atoms.append(Atom(el, (x, y, z))) cell *= f2f(alat) * units.Bohr atoms.set_cell(cell, scale_atoms=True) return atoms
def __init__(self, *args, **kwargs): quaternions = None if 'quaternions' in kwargs: quaternions = np.array(kwargs['quaternions']) del kwargs['quaternions'] Atoms.__init__(self, *args, **kwargs) if quaternions is not None: self.set_array('quaternions', quaternions, shape=(4,)) # set default shapes self.set_shapes(np.array([[3, 2, 1]] * len(self)))
def unpack_reftraj_str_to_atoms(data): lines = data.split('\n') label = int(lines[0]) n_atoms = int(lines[1]) at = Atoms(symbols=[' ']*n_atoms, cell=np.eye(3)) at.info['label'] = label for i in range(3): at.cell[:, i] = [float(x) for x in lines[i].split()] for i, line in enumerate(lines[4:]): t = [float(x) for x in line.split()] at.positions[i, :] = np.dot(at.cell.T, t) return at
def __iadd__(self, other): shift = len(self) AseAtoms.__iadd__(self, other) if isinstance(other, Atoms): self.transfer(other, shift) for constraint in other.constraints: if isinstance(constraint, FixAtoms) and len(constraint.index) > 0: indices = np.array(constraint.index) + shift self.constraints[0].index = np.array(list(self.constraints[0].index) + list(indices)) return self
def _read_cp2k_dcd_frame(fileobj, dtype, natoms, symbols, aligned=False): arr = np.fromfile(fileobj, dtype, 1) cryst_const = np.empty(6, dtype=np.float64) cryst_const[0] = arr['x1'][0, 0] cryst_const[1] = arr['x1'][0, 2] cryst_const[2] = arr['x1'][0, 5] cryst_const[3] = arr['x1'][0, 4] cryst_const[4] = arr['x1'][0, 3] cryst_const[5] = arr['x1'][0, 1] coords = np.empty((natoms, 3), dtype=np.float32) coords[..., 0] = arr['x3'][0, ...] coords[..., 1] = arr['x5'][0, ...] coords[..., 2] = arr['x7'][0, ...] assert len(coords) == len(symbols) if aligned: # convention of the cell is (see cp2ks src/particle_methods.F): # A is in x # B lies in xy plane # luckily this is also the ASE convention for Atoms.set_cell() atoms = Atoms(symbols, coords, cell=cryst_const, pbc=True) else: atoms = Atoms(symbols, coords) return atoms
def simple_read_xyz(fileobj, index): lines = fileobj.readlines() natoms = int(lines[0]) nimages = len(lines) // (natoms + 2) for i in range(*index.indices(nimages)): symbols = [] positions = [] n = i * (natoms + 2) + 2 for line in lines[n:n + natoms]: symbol, x, y, z = line.split()[:4] symbol = symbol.lower().capitalize() symbols.append(symbol) positions.append([float(x), float(y), float(z)]) yield Atoms(symbols=symbols, positions=positions)
def write(self, id, atoms, keywords=[], key_value_pairs={}, data={}, timestamp=None, replace=True): if timestamp is None: timestamp = (time() - T0) / YEAR self.timestamp = timestamp if atoms is None: atoms = Atoms() self._write(id, atoms, keywords, key_value_pairs, data, replace)
def setUp(self): lattVects = ([6.06, 0.0, 0.0], [-3.0299495954, 5.2480557244, 0.0], [0.0, 0.0, 9.84]) fractPos = ([0.0, 0.0, 0.0], [0.33333300, 0.66666700, 0.50000000]) atomLabels = ["Mg", "Mg"] fractCoords = [ list(x) + [y] for x, y in it.zip_longest(fractPos, atomLabels) ] self.testUCell = UCell.UnitCell.fromLattVects(lattVects, fractCoords=fractCoords) self.aseCell = Atoms(pbc=True, cell=lattVects, symbols=atomLabels, scaled_positions=fractPos)
def dict_atoms(d): atoms = Atoms([ Atom(atom['symbol'], position=atom['position'], tag=atom['tag'], momentum=atom['momentum'], magmom=atom['magmom'], charge=atom['charge']) for atom in d['atoms'] ], cell=d['cell'], pbc=d['pbc'], info=d['info'], constraint=[dict2constraint(c) for c in d['constraints']]) return atoms
def _cubic_bulk(name, crystalstructure, a): if crystalstructure == 'fcc': atoms = Atoms(4 * name, cell=(a, a, a), pbc=True, scaled_positions=[(0, 0, 0), (0, 0.5, 0.5), (0.5, 0, 0.5), (0.5, 0.5, 0)]) elif crystalstructure == 'diamond': atoms = _cubic_bulk(2 * name, 'zincblende', a) elif crystalstructure == 'zincblende': atoms = Atoms(4 * name, cell=(a, a, a), pbc=True, scaled_positions=[(0, 0, 0), (0.25, 0.25, 0.25), (0, 0.5, 0.5), (0.25, 0.75, 0.75), (0.5, 0, 0.5), (0.75, 0.25, 0.75), (0.5, 0.5, 0), (0.75, 0.75, 0.25)]) elif crystalstructure == 'rocksalt': atoms = Atoms(4 * name, cell=(a, a, a), pbc=True, scaled_positions=[(0, 0, 0), (0.5, 0, 0), (0, 0.5, 0.5), (0.5, 0.5, 0.5), (0.5, 0, 0.5), (0, 0, 0.5), (0.5, 0.5, 0), (0, 0.5, 0)]) else: raise incompatible_cell(want='cubic', have=crystalstructure) return atoms
def _cubic_bulk(name, crystalstructure, a): if crystalstructure == 'fcc': atoms = Atoms(4 * name, cell=(a, a, a), pbc=True, scaled_positions=[(0, 0, 0), (0, 0.5, 0.5), (0.5, 0, 0.5), (0.5, 0.5, 0)]) elif crystalstructure == 'diamond': atoms = _cubic_bulk(2 * name, 'zincblende', a) elif crystalstructure == 'zincblende': atoms = Atoms(4 * name, cell=(a, a, a), pbc=True, scaled_positions=[(0, 0, 0), (0.25, 0.25, 0.25), (0, 0.5, 0.5), (0.25, 0.75, 0.75), (0.5, 0, 0.5), (0.75, 0.25, 0.75), (0.5, 0.5, 0), (0.75, 0.75, 0.25)]) elif crystalstructure == 'rocksalt': atoms = Atoms(4 * name, cell=(a, a, a), pbc=True, scaled_positions=[(0, 0, 0), (0.5, 0, 0), (0, 0.5, 0.5), (0.5, 0.5, 0.5), (0.5, 0, 0.5), (0, 0, 0.5), (0.5, 0.5, 0), (0, 0.5, 0)]) else: raise RuntimeError return atoms
def phonopy_atoms_to_ase(atoms_phonopy): """Convert PhonopyAtoms to Atoms.""" try: from ase.atoms import Atoms except ImportError: raise ImportError("ASE python module was not found.") ase_atoms = Atoms( cell=atoms_phonopy.cell, scaled_positions=atoms_phonopy.scaled_positions, numbers=atoms_phonopy.numbers, pbc=True, ) return ase_atoms
def read_crystal(filename): """Method to read coordinates form 'fort.34' files additionally read information about periodic boundary condition """ with open(filename, 'r') as myfile: lines = myfile.readlines() atoms_pos = [] anumber_list = [] my_pbc = [False, False, False] mycell = [] if float(lines[4]) != 1: raise ValueError('High symmetry geometry is not allowed.') if float(lines[1].split()[0]) < 500.0: cell = [float(c) for c in lines[1].split()] mycell.append(cell) my_pbc[0] = True else: mycell.append([1, 0, 0]) if float(lines[2].split()[1]) < 500.0: cell = [float(c) for c in lines[2].split()] mycell.append(cell) my_pbc[1] = True else: mycell.append([0, 1, 0]) if float(lines[3].split()[2]) < 500.0: cell = [float(c) for c in lines[3].split()] mycell.append(cell) my_pbc[2] = True else: mycell.append([0, 0, 1]) natoms = int(lines[9].split()[0]) for i in range(natoms): index = 10 + i anum = int(lines[index].split()[0]) % 100 anumber_list.append(anum) position = [float(p) for p in lines[index].split()[1:]] atoms_pos.append(position) atoms = Atoms(positions=atoms_pos, numbers=anumber_list, cell=mycell, pbc=my_pbc) return atoms
def build_supercells(self): supercells = self.phonon.get_supercells_with_displacements() # Force calculations by calculator i = 0 for scell in supercells: atoms = Atoms(symbols=scell.get_chemical_symbols(), scaled_positions=scell.get_scaled_positions(), cell=scell.get_cell(), pbc=True) self.supercells[str(i).zfill(3)] = atoms i += 1 self.nsupercells = len(self.supercells) self.log('') self.log('Number of supercells: %s'%(i))
def read_sdf(fileobj): lines = fileobj.readlines() # first three lines header del lines[:3] L1 = lines.pop(0).split() natoms = int(L1[0]) positions = [] symbols = [] for line in lines[:natoms]: x, y, z, symbol = line.split()[:4] symbols.append(symbol) positions.append([float(x), float(y), float(z)]) return Atoms(symbols=symbols, positions=positions)
def read(self, label): FileIOCalculator.read(self, label) if not os.path.isfile(self.label + '.out'): raise ReadError f = open(self.label + '.nw') for line in f: if line.startswith('geometry'): break symbols = [] positions = [] for line in f: if line.startswith('end'): break words = line.split() symbols.append(words[0]) positions.append([float(word) for word in words[1:]]) self.parameters = Parameters.read(self.label + '.ase') self.atoms = Atoms(symbols, positions, magmoms=self.parameters.pop('initial_magmoms')) self.read_results()
def build_atoms(): atoms = Atoms(symbols=symbols, cell=cell, pbc=pbc, positions=positions) if not read_arrays: return atoms info = {'occupancy': occ, 'bfactor': bfactor, 'residuenames': residuenames, 'atomtypes': atomtypes, 'residuenumbers': residuenumbers} for name, array in info.items(): if len(array) == 0: pass elif len(array) != len(atoms): warnings.warn('Length of {} array, {}, ' 'different from number of atoms {}'. format(name, len(array), len(atoms))) else: atoms.set_array(name, np.array(array)) return atoms
def unf(phonon, sc_mat, qpoints, knames=None, x=None, xpts=None): prim = phonon.get_primitive() prim = Atoms(symbols=prim.get_chemical_symbols(), cell=prim.get_cell(), positions=prim.get_positions()) #vesta_view(prim) sc_qpoints = np.array([np.dot(q, sc_mat) for q in qpoints]) phonon.set_qpoints_phonon(sc_qpoints, is_eigenvectors=True) freqs, eigvecs = phonon.get_qpoints_phonon() uf = phonon_unfolder(atoms=prim, supercell_matrix=sc_mat, eigenvectors=eigvecs, qpoints=sc_qpoints, phase=False) weights = uf.get_weights() #ax=plot_band_weight([list(x)]*freqs.shape[1],freqs.T*8065.6,weights[:,:].T*0.98+0.01,xticks=[knames,xpts],style='alpha') ax = plot_band_weight([list(x)] * freqs.shape[1], freqs.T * 33.356, weights[:, :].T * 0.99 + 0.001, xticks=[knames, xpts], style='alpha') return ax
def test_gfn2_xtb_3d(): """Test ASE interface to GFN2-xTB, should fail""" thr = 5.0e-6 atoms = Atoms( symbols='C4O8', positions=np.array([ [0.9441259872, 0.9437851680, 0.9543505632], [3.7179966528, 0.9556570368, 3.7316862240], [3.7159517376, 3.7149292800, 0.9692330016], [0.9529872864, 3.7220864832, 3.7296981120], [1.6213905408, 1.6190616096, 1.6313879040], [0.2656685664, 0.2694175776, 0.2776540416], [4.3914553920, 1.6346256864, 3.0545920000], [3.0440834880, 0.2764611744, 4.4080419264], [4.3910577696, 3.0416409504, 0.2881058304], [3.0399936576, 4.3879335936, 1.6497353376], [0.2741322432, 4.4003734944, 3.0573754368], [1.6312174944, 3.0434586528, 4.4023048032], ]), cell=np.array([5.68032, 5.68032, 5.68032]), pbc=np.array([True, True, True]), ) calc = XTB(method="GFN2-xTB") atoms.set_calculator(calc) with raises(CalculationFailed): atoms.get_potential_energy() # make structure molecular atoms.set_pbc(False) assert approx(atoms.get_potential_energy(), abs=thr) == -1121.9196707084955 with raises(InputError): atoms.positions = np.zeros((len(atoms), 3)) calc.calculate(atoms=atoms, system_changes=["positions"])
def test_gfn2xtb_velocityverlet(): """Perform molecular dynamics with GFN2-xTB and Velocity Verlet Integrator""" thr = 1.0e-5 atoms = Atoms( symbols="NHCHC2H3OC2H3ONHCH3", positions=np.array([ [1.40704587284727, -1.26605342016611, -1.93713466561923], [1.85007200612454, -0.46824072777417, -1.50918242392545], [-0.03362432532150, -1.39269245193812, -1.74003582081606], [-0.56857009928108, -1.01764444489068, -2.61263467107342], [-0.44096297340282, -2.84337808903410, -1.48899734014499], [-0.47991761226058, -0.55230954385212, -0.55520222968656], [-1.51566045903090, -2.89187354810876, -1.32273881320610], [-0.18116520746778, -3.45187805987944, -2.34920431470368], [0.06989722340461, -3.23298998903001, -0.60872832703814], [-1.56668253918793, 0.00552120970194, -0.52884675001441], [1.99245341064342, -1.73097165236442, -3.08869239114486], [3.42884244212567, -1.30660069291348, -3.28712665743189], [3.87721962540768, -0.88843123009431, -2.38921453037869], [3.46548545761151, -0.56495308290988, -4.08311788302584], [4.00253374168514, -2.16970938132208, -3.61210068365649], [1.40187968630565, -2.43826111827818, -3.89034127398078], [0.40869198386066, -0.49101709352090, 0.47992424955574], [1.15591901335007, -1.16524842262351, 0.48740266650199], [0.00723492494701, 0.11692276177442, 1.73426297572793], [0.88822128447468, 0.28499001838229, 2.34645658013686], [-0.47231557768357, 1.06737634000561, 1.52286682546986], [-0.70199987915174, -0.50485938116399, 2.28058247845421], ]), ) calc = XTB(method="GFN2-xTB", cache_api=False) atoms.set_calculator(calc) dyn = VelocityVerlet(atoms, timestep=1.0 * fs) dyn.run(20) assert approx(atoms.get_potential_energy(), thr) == -896.9772346260584 assert approx(atoms.get_kinetic_energy(), thr) == 0.022411127028842362 atoms.calc.set(cache_api=True) dyn.run(20) assert approx(atoms.get_potential_energy(), thr) == -896.9913862530841 assert approx(atoms.get_kinetic_energy(), thr) == 0.036580471363852810
def test_co_potential_curve(self): direction = np.array([1., 2., 3.]) direction /= np.linalg.norm(direction) r_train = np.linspace(0.5, 7, 11) energies_train = [] images_train = [] for ri in r_train: image = Atoms(['C', 'O'], positions=np.array( [-0.5 * ri * direction, 0.5 * ri * direction])) image.set_calculator(EMT()) energies_train.append(image.get_potential_energy()) images_train.append(image) def to_radius(x): xyzs = x.get_positions() r = np.sqrt(np.sum((xyzs[1, :] - xyzs[0, :])**2)) dr = np.zeros((1, 6)) dr[0, 0] = (xyzs[0, 0] - xyzs[1, 0]) / r dr[0, 1] = (xyzs[0, 1] - xyzs[1, 1]) / r dr[0, 2] = (xyzs[0, 2] - xyzs[1, 2]) / r dr[0, 3] = (xyzs[1, 0] - xyzs[0, 0]) / r dr[0, 4] = (xyzs[1, 1] - xyzs[0, 1]) / r dr[0, 5] = (xyzs[1, 2] - xyzs[0, 2]) / r return [r], dr kernel = RBFKernel(constant=100.0, length_scale=1e-1) calc = NCGPRCalculator(input_transform=to_radius, kernel=kernel, C1=1e8, C2=1e8, opt_restarts=0) [calc.add_data(im) for im in images_train] calc.fit() np.testing.assert_allclose( energies_train, [calc.predict(im)[0] for im in images_train])
def reserve(self, *keywords, **key_value_pairs): """Write empty row if not already present. Usage:: id = conn.reserve('keyword1', 'keyword2', ..., key1=value1, key2=value2, ...) Write an empty row with the given keywords and key-value pairs and return the integer id. If such a row already exists, don't write anything and return None. """ for dct in self._select(keywords, [(key, '=', value) for key, value in key_value_pairs.items()]): return None atoms = Atoms() calc_name = key_value_pairs.pop('calculator', None) if calc_name: # Allow use of calculator key assert calc_name.lower() == calc_name # Fake calculator class: class Fake: name = calc_name todict = lambda self: {} check_state = lambda self, atoms: ['positions'] atoms.calc = Fake() id = self._write(atoms, keywords, key_value_pairs, {}) return id
def read_dacapo_text(fd): lines = fd.readlines() i = lines.index(' Structure: A1 A2 A3\n') cell = np.array([[float(w) for w in line.split()[2:5]] for line in lines[i + 1:i + 4]]).transpose() i = lines.index(' Structure: >> Ionic positions/velocities ' + 'in cartesian coordinates <<\n') atoms = [] for line in lines[i + 4:]: words = line.split() if len(words) != 9: break Z, x, y, z = words[2:6] atoms.append(Atom(int(Z), [float(x), float(y), float(z)])) atoms = Atoms(atoms, cell=cell.tolist()) try: i = lines.index( ' DFT: CPU time Total energy\n') except ValueError: pass else: column = lines[i + 3].split().index('selfcons') - 1 try: i2 = lines.index(' ANALYSIS PART OF CODE\n', i) except ValueError: pass else: while i2 > i: if lines[i2].startswith(' DFT:'): break i2 -= 1 energy = float(lines[i2].split()[column]) atoms.calc = SinglePointCalculator(atoms, energy=energy) return atoms
def get_energy(self, atoms): """comp is the composition array (i.e. n_i), mu is the array of chemical potentials, ecomp is the array of the total energy of components (e.g. atomic) DICTIONARIES""" """If it hasn't converged after 3000 steps, it probably won't ever""" #atoms=sort(atoms) ##must be sorted for traj --- no, sorting in displacements is enough composition = Stoichiometry() if self.adsorbate is not None: ads = Atoms([atom for atom in atoms if atom.tag == self.adsorbate]) stoich = composition.get(ads) else: stoich = composition.get(atoms) #####CP make arrays with composition, free atom energies and chemical potential, sorted by atomic symbols, from dictionaries comp = [stoich[c] for c in sorted(stoich)] #ecomp=[self.ecomp[e] for e in sorted(self.ecomp)] ecomp = [self.ecomp[e] for e in sorted(stoich)] #mu=[self.mu[m] for m in sorted(self.mu)] mu = [self.mu[m] for m in sorted(stoich)] ret = None try: atoms.set_calculator(self.calc) ## CP the following fixes some back-compatibility issue with ASE; since v.3.13 the force_consistent tag was introduced in optimizers BUT not all of them try: opt = self.opt(atoms, logfile=self.optlog, force_consistent=False, trajectory='relax.traj') except: opt = self.opt(atoms, logfile=self.optlog, trajectory='relax.traj') opt.run(fmax=self.fmax, steps=3000) if opt.converged( ) and self.opt2 is not None and self.fmax2 is not None: opt = self.opt2(atoms, logfile=self.optlog, trajectory='relax.traj') opt.run(fmax=self.fmax2, steps=3000) if opt.converged(): import numpy as np #print 'fin qui tutto bene' EE = atoms.get_potential_energy() grandE = EE - np.dot(comp, ecomp) - np.dot(comp, mu) - self.eref ret = (atoms, grandE) except: """Something went wrong.""" #print 'Something went wrong.' ret = None return ret
def read_eon(fileobj): """Reads an EON reactant.con file. If *fileobj* is the name of a "states" directory created by EON, all the structures will be read.""" if isinstance(fileobj, str): if (os.path.isdir(fileobj)): return read_states(fileobj) else: f = open(fileobj) else: f = fileobj comment = f.readline().strip() f.readline() # 0.0000 TIME (??) cell_lengths = f.readline().split() cell_angles = f.readline().split() # Different order of angles in EON. cell_angles = [cell_angles[2], cell_angles[1], cell_angles[0]] cellpar = [float(x) for x in cell_lengths + cell_angles] f.readline() # 0 0 (??) f.readline() # 0 0 0 (??) ntypes = int(f.readline()) # number of atom types natoms = [int(n) for n in f.readline().split()] atommasses = [float(m) for m in f.readline().split()] symbols = [] coords = [] masses = [] fixed = [] for n in range(ntypes): symbol = f.readline().strip() symbols.extend([symbol] * natoms[n]) masses.extend([atommasses[n]] * natoms[n]) f.readline() # Coordinates of Component n for i in range(natoms[n]): row = f.readline().split() coords.append([float(x) for x in row[:3]]) fixed.append(bool(int(row[3]))) if isinstance(fileobj, str): f.close() atoms = Atoms(symbols=symbols, positions=coords, masses=masses, cell=cellpar_to_cell(cellpar), constraint=FixAtoms(mask=fixed), info=dict(comment=comment)) return atoms
def test_fix_symmetry_shuffle_indices(): atoms = Atoms('AlFeAl6', cell=[6] * 3, positions=[[0, 0, 0], [2.9, 2.9, 2.9], [0, 0, 3], [0, 3, 0], [0, 3, 3], [3, 0, 0], [3, 0, 3], [3, 3, 0]], pbc=True) atoms.set_constraint(FixSymmetry(atoms)) at_permut = atoms[[0, 2, 3, 4, 5, 6, 7, 1]] pos0 = atoms.get_positions() def perturb(atoms, pos0, at_i, dpos): positions = pos0.copy() positions[at_i] += dpos atoms.set_positions(positions) new_p = atoms.get_positions() return pos0[at_i] - new_p[at_i] dp1 = perturb(atoms, pos0, 1, (0.0, 0.1, -0.1)) dp2 = perturb(atoms, pos0, 2, (0.0, 0.1, -0.1)) pos0 = at_permut.get_positions() permut_dp1 = perturb(at_permut, pos0, 7, (0.0, 0.1, -0.1)) permut_dp2 = perturb(at_permut, pos0, 1, (0.0, 0.1, -0.1)) assert np.max(np.abs(dp1 - permut_dp1)) < 1.0e-10 assert np.max(np.abs(dp2 - permut_dp2)) < 1.0e-10
def RandomSphereAtoms(symbols, covalent=None, radius=None, vacuum=0.0): numbers = symbols2numbers(symbols) if covalent is None: covalent = 0.8 * np.mean(covalent_radii[numbers]) if radius is None: radius = covalent * float(len(numbers))**(1.0/3.0) cell = 3.0 * radius * np.ones(3, float) + vacuum positions = radius * np.ones((len(numbers), 3)) for i in range(len(numbers)): pos = radius * RandSphere(1) + 0.5 * cell while np.any(np.sum((positions - pos)**2, axis=1) < covalent**2): pos = radius * RandSphere(1) + 0.5 * cell positions[i] = pos.copy() #positions = radius * RandSphere(len(numbers)) + 0.5 * cell return Atoms(numbers, positions=positions, cell=cell)
def get_surfAtom_byXY(atoms, xypos, scale=2): radiiAll = scale * np.array( [covalRadii[i] for i in atoms.get_atomic_numbers()]) z_test = max(atoms.get_positions()[:, 2]) + 5 surfIndex = [] while len(surfIndex) == 0: testAtom = Atoms(['H'], [[xypos[0], xypos[1], z_test]]) tmpAtoms = atoms.copy() tmpAtoms.extend(testAtom) dist_test = list( tmpAtoms.get_distances(-1, list(range(len(atoms)))) - radiiAll) for i in dist_test: if i < 0: surfIndex.append(dist_test.index(i)) z_test -= 0.05 return surfIndex
def __getitem__(self, i=-1): b = self.backend[i] atoms = Atoms( positions=b.positions, numbers=self.numbers, cell=b.cell, masses=self.masses, pbc=self.pbc, info=b.get('info'), constraint=[dict2constraint(d) for d in decode(self.constraints)], momenta=b.get('momenta'), magmoms=b.get('magmoms'), charges=b.get('charges'), tags=b.get('tags')) if 'calculator' in b: results = {} c = b.calculator for prop in all_properties: if prop in c: results[prop] = c.get(prop) calc = SinglePointCalculator(atoms, **results) calc.name = b.calculator.name atoms.set_calculator(calc) return atoms
def reset(self): self.size = int(settings.simulation_size) proclist.init((self.size, ) * int(lattice.model_dimension), self.system_name, lattice.default_layer, not self.banner) self.cell_size = lattice.unit_cell_size * lattice.system_size # prepare structures for TOF evaluation self.tofs = tofs = get_tof_names() self.tof_matrix = np.zeros((len(tofs), proclist.nr_of_proc)) for process, tof_count in settings.tof_count.iteritems(): process_nr = eval('proclist.%s' % process.lower()) for tof, tof_factor in tof_count.iteritems(): self.tof_matrix[tofs.index(tof), process_nr - 1] += tof_factor # prepare procstat self.procstat = np.zeros((proclist.nr_of_proc, )) self.time = 0. self.species_representation = [] for species in sorted(settings.representations): if settings.representations[species].strip(): self.species_representation.append( eval(settings.representations[species])) else: self.species_representation.append(Atoms()) if len(settings.lattice_representation): if hasattr(settings, 'substrate_layer'): self.lattice_representation = eval( settings.lattice_representation)[lattice.substrate_layer] else: self.lattice_representation = eval( settings.lattice_representation)[lattice.default_layer] else: self.lattice_representation = Atoms() set_rate_constants(settings.parameters, self.print_rates)
def gen_basis_set(nsites, nlabels, nspin=None): """ generate basis on nlabels of basis on each of nsites. """ bset = BasisSet() atoms = Atoms(symbols=['H'] * nsites, cell=[1, 1, 1], positions=[[1, 1, 1]] * nsites) bset.set_atoms(atoms) for isite in range(nsites): for ilabel in range(nlabels): for ispin in range(nspin): bset.append( Basis(index=0, site=isite, label=ilabel, spin=ispin)) return bset
def test_molecule(testdir): with open('basis', 'w') as fd: fd.write("""6 4 0 0 6 2.0 1.0 3048.0 0.001826 456.4 0.01406 103.7 0.06876 29.23 0.2304 9.349 0.4685 3.189 0.3628 0 1 2 4.0 1.0 3.665 -0.3959 0.2365 0.7705 1.216 0.8606 0 1 1 0.0 1.0 0.26 1.0 1.0 0 3 1 0.0 1.0 0.8 1.0 """) geom = Atoms('OHH', positions=[(0, 0, 0), (1, 0, 0), (0, 1, 0)]) geom.calc = CRYSTAL(label='water', guess=True, basis='sto-3g', xc='PBE', otherkeys=[ 'scfdir', 'anderson', ['maxcycles', '500'], ['toldee', '6'], ['tolinteg', '7 7 7 7 14'], ['fmixing', '90'] ]) opt = BFGS(geom) opt.run(fmax=0.05) final_energy = geom.get_potential_energy() assert abs(final_energy + 2047.34531091) < 1.0
def sc_atoms(self, atoms): """ This function is compatible with ase.build.make_supercell. They should produce the same result. """ from ase.atoms import Atoms sc_cell = self.sc_cell(atoms.get_cell()) sc_pos = self.sc_pos(atoms.get_scaled_positions()) sc_numbers = self.sc_trans_invariant(atoms.get_atomic_numbers()) sc_magmoms = self.sc_trans_invariant( atoms.get_initial_magnetic_moments()) return Atoms(cell=sc_cell, scaled_positions=sc_pos, numbers=sc_numbers, magmoms=sc_magmoms)