def rotate_atoms(individual, max_natoms=0.20): """Randomly rotates a number of random atoms within the individual (in place). Args: individual (Individual): an individual max_natoms (float or int): if float, the maximum number of atoms that will be rotated is max_natoms*len(individual) if int, the maximum number of atoms that will be rotated is max_natoms default: 0.20 """ if len(individual): if isinstance(max_natoms, float): max_natoms = int(len(individual)*max_natoms) max_natoms = max(max_natoms, 1) natoms_to_rotate = random.randint(1, max_natoms) atom_indices = list(range(len(individual))) random.shuffle(atom_indices) # Using random.shuffle on the indices guarantees no duplicates atom_indices = atom_indices[:natoms_to_rotate] # Extract out the atoms to be rotated atom_indices.sort(reverse=True) atoms = Atoms() for ind in atom_indices: atoms.append(individual.pop(ind)) axis = random.choice(['x', '-x', 'y', '-y', 'z', '-z']) angle = random.uniform(30, 180) atoms.rotate(axis, a=angle, center='COM', rotate_cell=False) individual.extend(atoms) return None
def compareForces(): d = 0.9575 t = np.pi / 180 * 104.51 water = Atoms("H2O", positions=[(d, 0, 0), (d * np.cos(t), d * np.sin(t), 0), (0, 0, 0)], cell=np.eye(3) * 5.0) water.calc = ElectronicMinimize(atoms=water, log=False) print(water.get_forces()) print(water.calc.calculate_numerical_forces(water))
def die(): d = 0.9575 t = np.pi / 180 * 104.51 water = Atoms("H2O", positions=[(d, 0, 0), (d * np.cos(t), d * np.sin(t), 0), (0, 0, 0)]) water.calc = ElectronicMinimize(atoms=water, log=True) dyn = LBFGS(water) dyn.run(fmax=0.05)
def adjust_positions(self, atoms: Atoms, newpositions): """ :param atoms: structure to be adjusted :param newpositions: positions from dft code :return: """ # get Normal Vector atoms.wrap(atoms.get_scaled_positions()[self.diffusing_i]) p1 = newpositions[self.plane_i[0]] # type: np.array p2 = newpositions[self.plane_i[1]] # type: np.array p3 = newpositions[self.plane_i[2]] # type: np.array v1 = p2 - p1 v2 = p3 - p1 # Get equation of plane ax+by+cz+d = 0 normal = np.cross(v1, v2) / np.linalg.norm(np.cross(v1,v2)) d = np.dot(normal, p1) a=normal[0] b=normal[1] c=normal[2] # Get closest point on plane p = newpositions[self.diffusing_i] k = (a*p[0] + b*p[1] + c*p[2] - d) / (a**2 + b**2 + c**2) # distance between point and plane position = [p[0] - k*a, p[1] - k*b, p[2] - k*c] newpositions[self.diffusing_i] = position
def test_s22(): fragTest = Fragmentation(s22.s22) minimize = False #minimize = True print 'Relaxed:', minimize fragTest.molecules = [] fragTest.fragments = [] for moleculeName in s22.s22: data = s22.data[moleculeName] atoms = Atoms(data['symbols'], data['positions']) dimer1End = data['dimer atoms'][0] frag1Atoms = atoms.copy()[:dimer1End] frag2Atoms = atoms.copy()[dimer1End:] fragment1 = ReaxFFSystem(moleculeName + '_f1', frag1Atoms, minimize = minimize) fragment2 = ReaxFFSystem(moleculeName + '_f2', frag2Atoms, minimize = minimize) system = ReaxFFSystem(moleculeName, atoms, minimize = minimize, fragment_list = [fragment1.name, fragment2.name]) fragTest.molecules.append(system) fragTest.fragments += [fragment1, fragment2] fragTest.fill_data_reference(data_type='s22') fragTest.run(write=True)
def testSingle(molecule): #TEST fragmentation print "Test fragmentation with s22 set" fragment_names = [molecule+'_f1',molecule+'_f2'] test_f = Fragmentation([molecule]) minimize = False #minimize = True print 'Relaxed:', minimize sys = Atoms(s22_sim_data[molecule]['symbols'], s22_sim_data[molecule]['positions']) test_f.molecules = [ReaxFFSystem(molecule,atoms=sys, fragment_list=fragment_names, minimize=minimize)] n = s22_sim_data[molecule]['dimer atoms'] atom_fragments = [ sys.copy()[range(n[0])], sys.copy()[range(n[0],n[0]+n[1])] ] test_f.fragments = [ ReaxFFSystem(name,atoms=a, minimize = minimize) for name,a in zip(fragment_names,atom_fragments)] test_f.fill_data_reference(data_type='s22') test_f.run(write=True) print test_f.data
def extract_calc(inp_file): """Constructs an ase atoms object with an attached Gaussian calculator from a gaussian input file assumes the input file has format Route.... \n\nTitle...\n\ncoord_sect...\n\nconnect_sect""" with open(inp_file, 'r') as fl: data = fl.read() section_names = ['route', 'title', 'coords', 'connects'] sections = data.split('\n\n') no_sections = len(sections) data_dict = dict(zip(section_names[:no_sections], sections)) label = data_dict.get('title') route = data_dict.get('route') coords = data_dict.get('coords') #connects = data_dict.get('connects') if coords: charge, mult = coords.split('\n')[0].split() coords = '\n'.join(coords.split('\n')[1:]) atoms = Atoms() if coords: for line in coords.split('\n'): info = line.split() is_bq = re.match('bq', info[0], re.I) # H -> H, H(ISO=2) -> H symbol = info[0].split('(')[0] position = [float(info[1]), float(info[2]), float(info[3])] #ignoring ghost atoms if not is_bq: atoms += Atom(symbol.split('(')[0], position=position) if not label: label = 'Default Gaussian Label' route_args = route.split()[1:] if 'oniom' in route_args[0]: method = route_args[0] basis = 'oniom' route_args = route_args[1:] else: method, basis = route_args[0:2] route_args = route_args[2:] route_kwargs = {'method':method, 'basis':basis} for route_arg in route_args: if re.match('IOP', route_arg, re.I): route_kwargs.update({'ioplist': route_arg[4:-1].split(',')}) elif '=' in route_arg: route_arg_nm, route_arg_vl = route_arg.split('=') route_kwargs.update({route_arg_nm: route_arg_vl}) else: route_kwargs.update({route_arg:route_arg}) atoms.set_calculator(Gaussian(label=label, multiplicity=mult, **route_kwargs)) return atoms
def bcc100(symbol, a, layers, L): """Build a bcc(100) surface symbol: chemical symbol ('H', 'Li', ...) a : lattice constant layers: number of layers L : height of unit cell""" a = float(a) # Distance between layers: z = a / 2 assert L > layers * z, 'Unit cell too small!' # Start with an empty Atoms object with an orthorhombic unit cell: atoms = Atoms(pbc=(True, True, False), cell=(a, a, L)) # Fill in the atoms: for n in range(layers): position = [a / 2 * (n % 2), a / 2 * (n % 2), n * z] atoms.append(Atom(symbol, position)) atoms.center(axis=2) return atoms
def structure(self): latysmall,latExtend,latxsmall,latxbig,bond=[int(self.latysmall),int(self.latExtend),int(self.latxsmall),int(self.latxbig),float(self.bond)] if(latxsmall%2==0):latxsmall+=1; if(latxbig%2==1):latxbig+=1; atoms=self.agnr(latysmall,latxsmall+1,0); unit=self.agnr(latysmall-1+2*latExtend,latxbig,0) unit.translate([latxsmall*1.5,-(latExtend-0.5)*sqrt(3),0]) atoms.extend(unit) unit=self.agnr(latysmall,latxsmall+1,0); unit.translate([(latxsmall+latxbig-1)*1.5,0,0]) atoms.extend(unit) temp=Atoms() for i in range(self.seg): unit=atoms.copy() unit.translate([(latxsmall+latxbig-1)*1.5*i,0,0]) temp.extend(unit) atoms.extend(temp) atoms=get_unique_atoms(atoms) lx,ly=self.extent(atoms) atoms.set_cell([lx,ly,100]) atoms.set_cell([lx*bond,ly*bond,100],scale_atoms=True) atoms.set_pbc([1,1,1]) atoms.center(vacuum=10*bond) self.atoms=atoms self.write() print 'read_data structure'
def testSingle(moleculeName = "Methane_dimer"): #TEST fragmentation print "Test fragmentation with s22 set" minimize = False minimize = True print 'Relaxed:', minimize fragTest = Fragmentation([moleculeName]) #atoms = s22.create_s22_system(moleculeName) data = s22.data[moleculeName] atoms = Atoms(data['symbols'], data['positions']) dimer1End = s22.data[moleculeName]['dimer atoms'][0] frag1Atoms = atoms.copy()[:dimer1End] frag2Atoms = atoms.copy()[dimer1End:] calculate_charges(frag1Atoms) calculate_charges(frag2Atoms) atoms.set_charges(np.append(frag1Atoms.get_charges(), frag2Atoms.get_charges())) fragment1 = CHARMMSystem(moleculeName + '_f1', frag1Atoms, minimize = minimize) fragment2 = CHARMMSystem(moleculeName + '_f2', frag2Atoms, minimize = minimize) system = CHARMMSystem(moleculeName, atoms, minimize = minimize, fragment_list = [fragment1.name, fragment2.name]) fragTest.molecules = [system] fragTest.fragments = [fragment1, fragment2] fragTest.fill_data_reference(data_type='s22') fragTest.run(write=True) import ase.io ase.io.write('molecule.xyz', atoms) print fragTest.data
def initialize_subsystem(self, info): """Initializes a SubsystemInternal from the given Subsystem. Parameters: info: SubSystem """ name = info.name real_indices = self.generate_subsystem_indices(name) # Create a copy of the subsystem temp_atoms = Atoms() index_map = {} reverse_index_map = {} counter = 0 for index in real_indices: atom = self.atoms[index] temp_atoms.append(atom) index_map[index] = counter reverse_index_map[counter] = index counter += 1 atoms = temp_atoms.copy() atoms.set_pbc(self.atoms.get_pbc()) atoms.set_cell(self.atoms.get_cell()) # Create the SubSystem subsystem = SubSystemInternal( atoms, info, index_map, reverse_index_map, len(self.atoms)) self.subsystems[name] = subsystem
def CCP_Oct_Tet(ind1, ind2, Optimizer): """CX Function underdevelopment for preferentially exchanging octahedral and tetrahedral defect sites Non-Functional """ if 'CX' in Optimizer.debug: debug = True else: debug = False uc = numpy.maximum.reduce(Optimizer.solidbulk.get_cell()/Optimizer.supercell)[0] interstitials = [[0.0,0.5,0.0],[0.5,0.0,0.0],[0.0,0.0,0.5],[0.5,0.5,0.5], [0.25,0.25,0.25],[0.25,0.75,0.25],[0.75,0.25,0.25],[0.75,0.75,0.25], [0.25,0.25,0.75],[0.25,0.75,0.75],[0.75,0.25,0.75],[0.75,0.75,0.75]] sites=[] for one in interstitials: pos = [uc*p for p in one] npos = [0,0,0] for i in range(Optimizer.supercell[0]): npos[0]=pos[0]+i*uc for j in range(Optimizer.supercell[1]): npos[1]=pos[1]+j*uc for k in range(Optimizer.supercell[2]): npos[2]=pos[2]+k*uc sites.append(copy.copy(npos)) solidsites = Atoms() for one in sites: solidsites.append(Atom(position=one)) return ind1, ind2
def test_axis_layout(): system = Atoms('H') a = 3. system.cell = (a, a, a) system.pbc = 1 for axis in range(3): system.center() system.positions[0, axis] = 0.0 calc = Octopus(**getkwargs(label='ink-%s' % 'xyz'[axis], Output='density + potential + wfs')) system.set_calculator(calc) system.get_potential_energy() rho = calc.get_pseudo_density(pad=False) #for dim in rho.shape: # assert dim % 2 == 1, rho.shape maxpoint = np.unravel_index(rho.argmax(), rho.shape) print('axis=%d: %s/%s' % (axis, maxpoint, rho.shape)) expected_max = [dim // 2 for dim in rho.shape] expected_max[axis] = 0 assert maxpoint == tuple(expected_max), '%s vs %s' % (maxpoint, expected_max) errs = check_interface(calc) for err in errs: if err.code == 'not implemented': continue if err.methname == 'get_dipole_moment': assert isinstance(err.error, OctopusIOError) else: raise AssertionError(err.error)
def build_sheet(nx, nz, symmetry=0): nx=nx+1 nz=(nz+1)/2 basic_cell= Atoms('C4', positions=[[3.11488, 2.50000, 0.71000], [4.34463, 2.50000, 1.42000], [4.34463, 2.50000, 2.84000], [3.11488, 2.50000, 3.55000]], cell=[[2.45951, 0, 0], [0, 1, 0], [0, 0, 4.26]]) atoms=basic_cell.repeat((nx,1,nz)) atoms.pop(basic_cell.get_number_of_atoms()*nz-1) atoms.pop(0) if symmetry == 1: print "Making graphene sheet symmetric" global to_be_removed to_be_removed = [] sym_fix_int = nz-1 for i in xrange(2, nz+sym_fix_int, 2): to_be_removed.append(2*i-2) to_be_removed.append(2*i-1) to_be_removed = to_be_removed[::-1] for entry in to_be_removed: atoms.pop(entry) else: print "Molecule was not made symmetric" return atoms
def get_OH(rotate=0): height = 1.8 atoms = Atoms([Atom('O', (-0.15, 0, 0), magmom=0), Atom('H', (0.655, 0, 0.564), magmom=0)]) rad = rotate * pi/180 atoms.rotate('z', rad) return atoms, height
def lmp_structure(self): pos=np.array([ [ 0.0000000000000000, 0.0000000000000000, 0.0000000000000000], [ 0.0000000000000000, 0.5000000000000000, 0.5000000000000000], [ 0.5000000000000000, 0.0000000000000000, 0.5000000000000000], [ 0.5000000000000000, 0.5000000000000000, 0.0000000000000000], [ 0.5000000000000000, 0.5000000000000000, 0.5000000000000000], [ 0.5000000000000000, 0.0000000000000000, 0.0000000000000000], [ 0.0000000000000000, 0.5000000000000000, 0.0000000000000000], [ 0.0000000000000000, 0.0000000000000000, 0.5000000000000000] ]) if self.modulation: pos=np.array([ [ 0.0028042995364173 , 0.9974037352530641 , 0.0077352314347739], [ 0.9976620421445513 , 0.4989145351814259 , 0.5063342423839297], [ 0.4945930839448565 , 0.9984163204751321 , 0.5059643310587607], [ 0.5058732577361121 , 0.4969055205467704 , 0.0045633420079164], [ 0.5023379578554488 , 0.5015836795248679 , 0.4954366579920836], [ 0.4971957004635827 , 0.0030944794532296 , 0.9940356689412393], [ 0.9941267422638879 , 0.5025962647469360 , 0.9936657576160703], [ 0.0054069160551436 , 0.0010854648185742 , 0.4922647685652261] ]) cell=4.8874939611242816*np.eye(3) atoms = Atoms('P8',scaled_positions=pos, cell=cell) atoms=atoms.repeat([self.latx,self.laty,self.latz]) atoms.set_pbc([self.xp,self.yp,self.zp]) return atoms
def get_OOH(rotate=0): height = 1.8 atoms = Atoms([Atom('O', (-0.433, 0 , 0), magmom=0), Atom('O', (0.648, 0, 0.964), magmom=0), Atom('H', (0.112, 0, 1.79), magmom=0)]) rad = rotate * pi/180 atoms.rotate('z', rad) return atoms, height
def __delitem__(self, i): Atoms.__delitem__(self, i) #Subtract one from all neighbor references that is greater than "index" if self.has('neighbors'): neighbors = self.get_neighbors() neighbors = neighbors - (neighbors > i).astype(int) self.set_neighbors(neighbors)
def create_random_atoms(gd, nmolecules=10, name='NH2', mindist=4.5 / Bohr): """Create gas-like collection of atoms from randomly placed molecules. Applies rigid motions to molecules, translating the COM and/or rotating by a given angle around an axis of rotation through the new COM. These atomic positions obey the minimum distance requirement to zero-boundaries. Warning: This is only intended for testing parallel grid/LFC consistency. """ atoms = Atoms(cell=gd.cell_cv * Bohr, pbc=gd.pbc_c) # Store the original state of the random number generator randstate = np.random.get_state() seed = np.array([md5_array(data, numeric=True) for data in [nmolecules, gd.cell_cv, gd.pbc_c, gd.N_c]]).astype(int) np.random.seed(seed % 4294967296) for m in range(nmolecules): amol = molecule(name) amol.set_cell(gd.cell_cv * Bohr) # Rotate the molecule around COM according to three random angles # The rotation axis is given by spherical angles phi and theta v,phi,theta = np.random.uniform(0.0, 2*np.pi, 3) # theta [0,pi[ really axis = np.array([cos(phi)*sin(theta), sin(phi)*sin(theta), cos(theta)]) amol.rotate(axis, v) # Find the scaled length we must transverse along the given axes such # that the resulting displacement vector is `mindist` from the cell # face corresponding to that direction (plane with unit normal n_v). sdist_c = np.empty(3) if not gd.orthogonal: for c in range(3): n_v = gd.xxxiucell_cv[c] / np.linalg.norm(gd.xxxiucell_cv[c]) sdist_c[c] = mindist / np.dot(gd.cell_cv[c], n_v) else: sdist_c[:] = mindist / gd.cell_cv.diagonal() assert np.all(sdist_c > 0), 'Displacment vectors must be inside cell.' # Scaled dimensions of the smallest possible box centered on the COM spos_ac = amol.get_scaled_positions() # NB! must not do a "% 1.0" scom_c = np.dot(gd.icell_cv, amol.get_center_of_mass()) sbox_c = np.abs(spos_ac-scom_c[np.newaxis,:]).max(axis=0) sdelta_c = (1-np.array(gd.pbc_c)) * (sbox_c + sdist_c) assert (sdelta_c < 1.0-sdelta_c).all(), 'Box is too tight to fit atoms.' scenter_c = [np.random.uniform(d,1-d) for d in sdelta_c] center_v = np.dot(scenter_c, gd.cell_cv) # Translate the molecule such that COM is located at random center offset_av = (center_v-amol.get_center_of_mass()/Bohr)[np.newaxis,:] amol.set_positions(amol.get_positions()+offset_av*Bohr) assert np.linalg.norm(center_v-amol.get_center_of_mass()/Bohr) < 1e-9 atoms.extend(amol) # Restore the original state of the random number generator np.random.set_state(randstate) assert compare_atoms(atoms) return atoms
def read_vasp_xdatcar(filename, index=-1): """Import XDATCAR file Reads all positions from the XDATCAR and returns a list of Atoms objects. Useful for viewing optimizations runs from VASP5.x Constraints ARE NOT stored in the XDATCAR, and as such, Atoms objects retrieved from the XDATCAR will not have constraints set. """ import numpy as np from ase import Atoms images = list() with open(filename, 'r') as xdatcar: xdatcar.readline() xdatcar.readline() xx = [float(x) for x in xdatcar.readline().split()] yy = [float(y) for y in xdatcar.readline().split()] zz = [float(z) for z in xdatcar.readline().split()] cell = np.array([xx, yy, zz]) symbols = xdatcar.readline().split() numbers = [int(n) for n in xdatcar.readline().split()] total = sum(numbers) atomic_formula = str() for n, sym in enumerate(symbols): atomic_formula += '%s%s' % (sym, numbers[n]) count = 0 nimage = 0 coords = list() for line in xdatcar: if 'Direct configuration=' in line: nimage += 1 else: coord = [float(x) for x in line.split()] coords.append(coord) count += 1 if count == total: image = Atoms(atomic_formula, cell=cell, pbc=True) image.set_scaled_positions(coords) images.append(image) count = 0 coords = list() if not index: return images else: return images[index]
def build_system(self, name): if name in extra: mol = Atoms(*extra[name]) mol.cell = self.unit_cell mol.center() else: self.bond_length = bondlengths.get(name, None) mol = MoleculeTask.build_system(self, name) return mol
def zhexian(self,n,p,type): m=n*2+1; atoms=Atoms() for i in range(m): y=i*sqrt(3)/2 x=0.5*(1+(type*2-1)*(i%2)-type)+p*1.5 atoms.append(Atom('C',(x,y,0.0))) return atoms
def read_from_pickle(file, ts_est, geo_dict): from pts.tools.pathtools import unpickle_path, PathTools from ase import Atoms from ase.io import write from pts.ui.read_COS import set_atoms from pts.searcher import new_abscissa from numpy import savetxt coord_b, energy_b, gradients_b, __, __, symbols, funcart = unpickle_path(file) # v2 mt.setup_metric(funcart) startx = new_abscissa(coord_b, mt.metric) pt2 = PathTools(coord_b, energy_b, gradients_b, startx) if ts_est == "spline": ts_int = pt2.ts_spl() if len(ts_int) == 0: print >> stderr, "Transition state estimate did not provide any results" print >> stderr, "Aborting!" exit() est = ts_int[-1] elif ts_est == "spl_avg": ts_int = pt2.ts_splavg() if len(ts_int) == 0: print >> stderr, "Transition state estimate did not provide any results" print >> stderr, "Aborting!" exit() est = ts_int[-1] elif ts_est == "cubic": ts_int = pt2.ts_splcub() if len(ts_int) == 0: print >> stderr, "Transition state estimate did not provide any results" print >> stderr, "Aborting!" exit() est = ts_int[-1] elif ts_est == "highest": est = pt2.ts_highest()[-1] elif ts_est == "bell": ts_int = pt2.ts_bell() if len(ts_int) == 0: print >> stderr, "Transition state estimate did not provide any results" print >> stderr, "Aborting!" exit() est = ts_int[-1] else: print >> stderr, "Transition state estimate not found", ts_est print >> stderr, "Make sure that the name is written correctly" exit() energy, start_geo, __, __,s_ts, __, __ = est init_mode = pt2.xs.fprime(s_ts) atoms = Atoms(symbols) atoms.set_positions(funcart(start_geo)) atoms = set_atoms(atoms, geo_dict) write("start.xyz", atoms) savetxt("mode.start", init_mode) return start_geo, init_mode, funcart, atoms
def adjust_positions(self, atoms : Atoms, newpositions): # get plane atoms.wrap(atoms.get_scaled_positions()[self.diffusing_i]) (a, b, c, d) = self.get_plane(atoms) # ax + by + cz = d # Get closest point on plane p = atoms.positions[self.diffusing_i] k = (a*p[0] + b*p[1] + c*p[2] - d) / (a**2 + b**2 + c**2) # distance between point and plane position = [p[0] - k*a, p[1] - k*b, p[2] - k*c] newpositions[self.diffusing_i] = position
def atomsfromlist(atomslist): """Takes in a list of atomic symbols and coordinates, as in [atom1, atom2, ...] where atomX = (symbol, (x,y,z)), and symbol is the atomic symbol (e.g. "Na") and x,y,z is the position, in Angstroms, of the atom. Returns an ASE atoms object.""" atoms = Atoms() for atom in atomslist: atoms.append(Atom(atom[0], atom[1])) return atoms
def mutate(self, atoms): """ Does the actual mutation. """ tbm = random.choice(range(len(atoms))) indi = Atoms() for a in atoms: if a.index == tbm: a.position += self.random_vector(self.length) indi.append(a) return indi
def lmp_structure(self): ribbon=graphene(dict(latx=self.latx,laty=self.laty,latz=1,gnrtype=self.gnrtype)).lmp_structure() for atom in ribbon: atom.position=self.trans(atom.position) atoms=Atoms() atoms.extend(ribbon) atoms.center(vacuum=10) return atoms
def color(gui): a = Atoms('C10', magmoms=np.linspace(1, -1, 10)) a.positions[:] = np.linspace(0, 9, 10)[:, None] a.calc = SinglePointCalculator(a, forces=a.positions) gui.new_atoms(a) c = gui.colors_window() c.toggle('force') text = c.toggle('magmom') assert [button.active for button in c.radio.buttons] == [1, 0, 1, 0, 0, 1] assert text.rsplit('[', 1)[1].startswith('-1.000000,1.000000]')
def get_density(self, atom_indicees=None, gridrefinement=2): """Get sum of atomic densities from the given atom list. All atoms are taken if the list is not given.""" all_atoms = self.calculator.get_atoms() if atom_indicees is None: atom_indicees = range(len(all_atoms)) density = self.calculator.density spos_ac = all_atoms.get_scaled_positions() rank_a = self.finegd.get_ranks_from_positions(spos_ac) density.set_positions(all_atoms.get_scaled_positions(), rank_a ) # select atoms atoms = [] D_asp = {} rank_a = [] all_D_asp = self.calculator.density.D_asp all_rank_a = self.calculator.density.rank_a for a in atom_indicees: if a in all_D_asp: D_asp[len(atoms)] = all_D_asp.get(a) atoms.append(all_atoms[a]) rank_a.append(all_rank_a[a]) atoms = Atoms(atoms, cell=all_atoms.get_cell(), pbc=all_atoms.get_pbc()) spos_ac = atoms.get_scaled_positions() Z_a = atoms.get_atomic_numbers() par = self.calculator.input_parameters setups = Setups(Z_a, par.setups, par.basis, par.lmax, XC(par.xc), self.calculator.wfs.world) self.D_asp = D_asp # initialize self.initialize(setups, self.calculator.timer, np.zeros((len(atoms), 3)), False) self.set_mixer(None) # FIXME nparray causes partitionong.py test to fail self.set_positions(spos_ac, np.array(rank_a)) basis_functions = BasisFunctions(self.gd, [setup.phit_j for setup in self.setups], cut=True) basis_functions.set_positions(spos_ac) self.initialize_from_atomic_densities(basis_functions) aed_sg, gd = self.get_all_electron_density(atoms, gridrefinement) return aed_sg[0], gd
def read_vasp_xdatcar(filename, index=-1): """Import XDATCAR file Reads all positions from the XDATCAR and returns a list of Atoms objects. Useful for viewing optimizations runs from VASP5.x Constraints ARE NOT stored in the XDATCAR, and as such, Atoms objects retrieved from the XDATCAR will not have constraints set. """ import numpy as np from ase import Atoms images = list() cell = np.eye(3) atomic_formula = str() with open(filename, 'r') as xdatcar: while True: comment_line = xdatcar.readline() if "Direct configuration=" not in comment_line: try: lattice_constant = float(xdatcar.readline()) except: break xx = [float(x) for x in xdatcar.readline().split()] yy = [float(y) for y in xdatcar.readline().split()] zz = [float(z) for z in xdatcar.readline().split()] cell = np.array([xx, yy, zz]) * lattice_constant symbols = xdatcar.readline().split() numbers = [int(n) for n in xdatcar.readline().split()] total = sum(numbers) atomic_formula = str() for n, sym in enumerate(symbols): atomic_formula += '%s%s' % (sym, numbers[n]) xdatcar.readline() coords = [np.array(xdatcar.readline().split(), np.float) for ii in range(total)] image = Atoms(atomic_formula, cell=cell, pbc=True) image.set_scaled_positions(np.array(coords)) images.append(image) if not index: return images else: return images[index]
from ase import Atoms from ase.calculators.emt import EMT from ase.calculators.test import numeric_forces h2 = Atoms('H2', positions=[(0, 0, 0), (0, 0, 1.1)], calculator=EMT()) f1 = numeric_forces(h2, d=0.0001) f2 = h2.get_forces() assert abs(f1 - f2).max() < 1e-6 assert (f1 == h2.calc.calculate_numerical_forces(h2, 0.0001)).all()
def co(netCDF4): return Atoms( [Atom('C', (0, 0, 0)), Atom('O', (0, 0, 1.2))], cell=[3, 3, 3], pbc=True)
#=============================================================================== # Creating Cu (111) surface with 4 layers 2x2 supercell in orthogonal cell # through Atomic Simulation Envirnoment https://wiki.fysik.dtu.dk/ase/ build. # Total amount of vacuum between the slabs is 10 Ang. CO molecule is added # on-top of one of the top-most copper atoms.Later the atoms are ordered, so # the top-most goes as first. Finally the two bottom layers of the slab are # constrained, so they cannot relax. slab = fcc111('Cu', size=(2, 2, 4), a=3.62, vacuum=5, orthogonal=True, periodic=True) CO = Atoms('CO', positions=[ slab.positions[-1] + [0, 0, 1.85], slab.positions[-1] + [0, 0, 3.00] ]) slab += CO slab = slab[np.argsort(-1 * slab.positions[:, 2])] mask = [atom.tag > 2 for atom in slab] slab.set_constraint(FixAtoms(mask=mask)) #=============================================================================== # If you want to directly visualize the created slab uncomment following lines: #from ase.visualize import view #view(slab) #=============================================================================== # If you want to print important information about the created slab uncomment # following lines:
OPTIONS = np.linspace(0.98, 1.02, 9) volumes = [] energies = [] cr = 0.15 ni = 0.15 fe = 1.0 - cr - ni for opt in OPTIONS: l = 3.602 * opt atoms = Atoms('Fe4', scaled_positions=[(0, 0, 0), (0.5, 0.5, 0), (0.5, 0, 0.5), (0, 0.5, 0.5)], cell=[l, l, l], pbc=(1, 1, 1)) atoms.set_tags([1, 1, 1, 1]) # view(atoms) atoms = atoms + Atom('C', position=(0, 0, 0.5 * l), tag=2) alloys = [] alloys.append(Alloy(1, 'Fe', 0.5, 1.0)) alloys.append(Alloy(1, 'Fe', 0.5, -1.0)) alloys.append(Alloy(2, 'N', 1.0, 0.0)) calc = EMTO()
import numpy as np from ase import Atoms, Atom from ase.parallel import barrier, rank, size from gpaw.cluster import Cluster from gpaw.test import equal from ase.data.molecules import molecule from math import pi, sqrt R = 2.0 CO = Atoms([Atom('C', (1, 0, 0)), Atom('O', (1, 0, R))]) CO.rotate('y', pi/2) equal(CO.positions[1, 0], R, 1e-10) # translate CO.translate(-CO.get_center_of_mass()) p = CO.positions.copy() for i in range(2): equal(p[i, 1], 0, 1e-10) equal(p[i, 2], 0, 1e-10) # rotate the nuclear axis to the direction (1,1,1) CO.rotate(p[1] - p[0], (1, 1, 1)) q = CO.positions.copy() for c in range(3): equal(q[0, c], p[0, 0] / sqrt(3), 1e-10) equal(q[1, c], p[1, 0] / sqrt(3), 1e-10) # minimal box b=4.0
import os from ase import Atoms from ase.io import read, write from ase.calculators.exciting import Exciting from ase.units import Bohr, Hartree a = Atoms('N3O', [(0, 0, 0), (1, 0, 0), (0, 0, 1), (0.5, 0.5, 0.5)], pbc=True) write('geo.exi', a) b = read('geo.exi') print a print a.get_positions() print b print b.get_positions() calculator = Exciting( dir='excitingtestfiles', kpts=(4, 4, 3), maxscl=3, #bin='/fshome/chm/git/exciting/bin/excitingser' )
def test_external_force(): """Tests for class ExternalForce in ase/constraints.py""" f_ext = 0.2 atom1 = 0 atom2 = 1 atom3 = 2 atoms = Atoms('H3', positions=[(0, 0, 0), (0.751, 0, 0), (0, 1., 0)]) atoms.calc = EMT() # Without external force optimize(atoms) dist1 = atoms.get_distance(atom1, atom2) # With external force con1 = ExternalForce(atom1, atom2, f_ext) atoms.set_constraint(con1) optimize(atoms) dist2 = atoms.get_distance(atom1, atom2) # Distance should increase due to the external force assert dist2 > dist1 # Combine ExternalForce with FixBondLength # Fix the bond on which the force acts con2 = FixBondLength(atom1, atom2) # ExternalForce constraint at the beginning of the list!!! atoms.set_constraint([con1, con2]) optimize(atoms) f_con = con2.constraint_forces # It was already optimized with this external force, therefore # the constraint force should be almost zero assert norm(f_con[0]) <= fmax # To get the complete constraint force (with external force), # use only the FixBondLength constraint, after the optimization with # ExternalForce atoms.set_constraint(con2) optimize(atoms) f_con = con2.constraint_forces[0] assert round(norm(f_con), 2) == round(abs(f_ext), 2) # Fix another bond and incrase the external force f_ext *= 2 con1 = ExternalForce(atom1, atom2, f_ext) d1 = atoms.get_distance(atom1, atom3) con2 = FixBondLength(atom1, atom3) # ExternalForce constraint at the beginning of the list!!! atoms.set_constraint([con1, con2]) optimize(atoms) d2 = atoms.get_distance(atom1, atom3) # Fixed distance should not change assert round(d1, 5) == round(d2, 5)
from gpaw.xas import * #XAS, RecursionMethod import numpy as np from gpaw import setup_paths #setup_paths.insert(0, '.') # Generate setup for oxygen with half a core-hole: gen('Si', name='hch1s', corehole=(1, 0, 0.5)) a = 5.43095 b = a / 2 c = b / 2 d = b + c si_nonortho = Atoms( [Atom('Si', (0, 0, 0)), Atom('Si', (a / 4, a / 4, a / 4))], cell=[(a / 2, a / 2, 0), (a / 2, 0, a / 2), (0, a / 2, a / 2)], pbc=True) # calculation with full symmetry calc = GPAW(nbands=-10, h=0.25, kpts=(2, 2, 2), occupations=FermiDirac(width=0.05), setups={0: 'hch1s'}) si_nonortho.set_calculator(calc) e = si_nonortho.get_potential_energy() niter = calc.get_number_of_iterations() calc.write('si_nonortho_xas_sym.gpw')
Power12Potential, LinearDielectric, KB51Volume, GradientSurface, VolumeInteraction, SurfaceInteraction, LeakedDensityInteraction) import numpy as np SKIP_ENERGY_CALCULATION = True F_max_err = 0.005 h = 0.2 u0 = 0.180 epsinf = 80. T = 298.15 atomic_radii = lambda atoms: [vdw_radii[n] for n in atoms.numbers] atoms = Atoms('NaCl', positions=((5.6, 5.6, 6.8), (5.6, 5.6, 8.8))) atoms.set_cell((11.2, 11.2, 14.4)) atoms.calc = SolvationGPAW( mixer=Mixer(0.5, 7, 50.0), xc='oldPBE', h=h, setups={'Na': '1'}, cavity=EffectivePotentialCavity(effective_potential=Power12Potential( atomic_radii, u0), temperature=T, volume_calculator=KB51Volume(), surface_calculator=GradientSurface()), dielectric=LinearDielectric(epsinf=epsinf), # parameters chosen to give ~ 1eV for each interaction interactions=[
def make_system_at_shift(global_prefix, subdir, db, syms, c_sep, vacuum_dist, AB_stacking, interlayer_relax, soc, xc, pp, Ds, extra_bands_factor, layer_shifts=None): latvecs, at_syms, cartpos = make_cell(db, syms, c_sep, vacuum_dist, AB_stacking, layer_shifts) system = Atoms(symbols=at_syms, positions=cartpos, cell=latvecs, pbc=True) system.center(axis=2) wann_valence, num_wann = get_wann_valence(system.get_chemical_symbols(), soc) num_bands = get_num_bands(num_wann, extra_bands_factor) prefixes = [] for D in Ds: qe_config = make_qe_config(system, D, interlayer_relax, soc, num_bands, xc, pp) if D is None: D_str = "0.0000" else: D_str = "{:.4f}".format(D) if layer_shifts is not None: da2, db2 = layer_shifts[1] prefix = "{}_D_{}_da2_{:.4f}_db2_{:.4f}".format( global_prefix, D_str, da2, db2) else: prefix = "{}_{}".format(global_prefix, D_str) prefixes.append(prefix) work = _get_work(subdir, prefix) wannier_dir = os.path.join(work, "wannier") if not os.path.exists(wannier_dir): os.makedirs(wannier_dir) bands_dir = os.path.join(work, "bands") if not os.path.exists(bands_dir): os.makedirs(bands_dir) dirs = { 'relax': wannier_dir, 'scf': wannier_dir, 'nscf': wannier_dir, 'bands': bands_dir } qe_input = {} if interlayer_relax: calc_types = ['relax', 'scf', 'nscf', 'bands'] else: calc_types = ['scf', 'nscf', 'bands'] for calc_type in calc_types: # Turn off SOC for relaxation. if calc_type == 'relax': relax_soc = False qe_config_no_soc = make_qe_config(system, D, interlayer_relax, relax_soc, num_bands, xc, pp) qe_input[calc_type] = build_qe(system, prefix, calc_type, qe_config_no_soc) else: qe_input[calc_type] = build_qe(system, prefix, calc_type, qe_config) _write_qe_input(prefix, dirs[calc_type], qe_input, calc_type) pw2wan_input = build_pw2wan(prefix, soc) pw2wan_path = os.path.join(wannier_dir, "{}.pw2wan.in".format(prefix)) with open(pw2wan_path, 'w') as fp: fp.write(pw2wan_input) bands_post_input = build_bands(prefix) bands_post_path = os.path.join(bands_dir, "{}.bands_post.in".format(prefix)) with open(bands_post_path, 'w') as fp: fp.write(bands_post_input) wannier_input = Winfile(system, qe_config, wann_valence, num_wann) win_path = os.path.join(wannier_dir, "{}.win".format(prefix)) with open(win_path, 'w') as fp: fp.write(wannier_input) return prefixes
from ase import Atoms, Atom import numpy as np from gpaw import GPAW, FermiDirac from gpaw.test import equal h = .4 q = 3 spin = True s = Atoms([Atom('Fe')]) s.center(vacuum=2.5) convergence = {'eigenstates': 0.01, 'density': 0.1, 'energy': 0.1} # use Hunds rules c = GPAW(charge=q, h=h, nbands=5, hund=True, eigensolver='rmm-diis', occupations=FermiDirac(width=0.1), convergence=convergence) c.calculate(s) equal(c.get_magnetic_moment(0), 5, 0.1) # set magnetic moment mm = [5] s.set_initial_magnetic_moments(mm) c = GPAW(charge=q,
from __future__ import print_function from ase import Atoms from gpaw import GPAW from gpaw.test import equal # ??? g = Generator('H', 'TPSS', scalarrel=True, nofiles=True) atoms = Atoms('H', magmoms=[1], pbc=True) atoms.center(vacuum=3) calc = GPAW(gpts=(32, 32, 32), nbands=1, xc='PBE', txt='Hnsc.txt') atoms.set_calculator(calc) e1 = atoms.get_potential_energy() niter1 = calc.get_number_of_iterations() e1ref = calc.get_reference_energy() de12t = calc.get_xc_difference('TPSS') de12m = calc.get_xc_difference('M06-L') de12r = calc.get_xc_difference('revTPSS') print('================') print('e1 = ', e1) print('de12t = ', de12t) print('de12m = ', de12m) print('de12r = ', de12r) print('tpss = ', e1 + de12t) print('m06l = ', e1 + de12m) print('revtpss = ', e1 + de12r) print('================') equal(e1 + de12t, -1.11723235592, 0.005) equal(e1 + de12m, -1.18207312133, 0.005) equal(e1 + de12r, -1.10093196353, 0.005)
def read_abinit_out(fd): results = {} def skipto(string): for line in fd: if string in line: return line raise RuntimeError('Not found: {}'.format(string)) line = skipto('Version') m = re.match(r'\.*?Version\s+(\S+)\s+of ABINIT', line) assert m is not None results['version'] = m.group(1) shape_vars = {} skipto('echo values of preprocessed input variables') for line in fd: if '===============' in line: break tokens = line.split() if not tokens: continue for key in ['natom', 'nkpt', 'nband', 'ntypat']: if tokens[0] == key: shape_vars[key] = int(tokens[1]) if line.lstrip().startswith('typat'): # Avoid matching ntypat types = consume_multiline(fd, line, shape_vars['natom'], int) if 'znucl' in line: znucl = consume_multiline(fd, line, shape_vars['ntypat'], float) if 'rprim' in line: cell = consume_multiline(fd, line, 9, float) cell = cell.reshape(3, 3) natoms = shape_vars['natom'] # Skip ahead to results: for line in fd: if 'was not enough scf cycles to converge' in line: raise RuntimeError(line) if 'iterations are completed or convergence reached' in line: break else: raise RuntimeError('Cannot find results section') def read_array(fd, nlines): arr = [] for i in range(nlines): line = next(fd) arr.append(line.split()[1:]) arr = np.array(arr).astype(float) return arr for line in fd: if 'cartesian coordinates (angstrom) at end' in line: positions = read_array(fd, natoms) if 'cartesian forces (eV/Angstrom) at end' in line: results['forces'] = read_array(fd, natoms) if 'Cartesian components of stress tensor (hartree/bohr^3)' in line: results['stress'] = read_stress(fd) if 'Components of total free energy (in Hartree)' in line: for line in fd: if 'Etotal' in line: energy = float(line.rsplit('=', 2)[1]) * Hartree results['energy'] = results['free_energy'] = energy break # Which of the listed energies do we take ?? if 'END DATASET(S)' in line: break znucl_int = znucl.astype(int) znucl_int[znucl_int != znucl] = 0 # (Fractional Z) numbers = znucl_int[types - 1] atoms = Atoms(numbers=numbers, positions=positions, cell=cell, pbc=True) results['atoms'] = atoms return results
def generate_hybrid_structure(ani_input: dict, tautomer_transformation: dict, ANI1_force_and_energy: ANI1_force_and_energy): """ Generates a hybrid structure between two tautomers. The heavy atom frame is kept but a hydrogen is added to the tautomer acceptor heavy atom. Keys are added to the ani_input dict and tautomer_transformation dict: ani_input['hybrid_atoms'] = ani_input['ligand_atoms'] + 'H' ani_input['hybrid_coords'] = hybrid_coord ani_input['min_e'] = min_e ani_input['hybrid_topolog'] = hybrid_top tautomer_transformation['donor_hydrogen_idx'] = tautomer_transformation['hydrogen_idx'] tautomer_transformation['acceptor_hydrogen_idx'] = len(ani_input['hybrid_atoms']) -1 Parameters ---------- ani_input : dict tautomer_transformation : traj ANI1_force_and_energy : ANI1_force_and_energy """ platform = 'cpu' device = torch.device(platform) model = LinearAlchemicalANI(alchemical_atoms=[], ani_input={}, device=device, pbc=False) model = model.to(device) torch.set_num_threads(2) ani_input['hybrid_atoms'] = ani_input['ligand_atoms'] + 'H' energy_function = ANI1_force_and_energy( device=device, model=model, atom_list=ani_input['hybrid_atoms'], platform=platform, tautomer_transformation=None) # TODO: check type consistency: here tautomer_transformation=None, but default is {} hydrogen_mover = MC_Mover(tautomer_transformation['donor_idx'], tautomer_transformation['hydrogen_idx'], tautomer_transformation['acceptor_idx'], ani_input['ligand_atoms']) hybrid_top = copy.deepcopy(ani_input['ligand_topology']) dummy_atom = hybrid_top.add_atom('H', md.element.hydrogen, hybrid_top.residue(-1)) hybrid_top.add_bond( hybrid_top.atom(tautomer_transformation['acceptor_idx']), dummy_atom) min_e = 100 * unit.kilocalorie_per_mole min_coordinates = None for _ in range(1000): hybrid_coord = hydrogen_mover._move_hydrogen_to_acceptor_idx( ani_input['ligand_coords'], override=False) e = energy_function.calculate_energy(hybrid_coord) if e < min_e: min_e = e min_coordinates = hybrid_coord tautomer_transformation['donor_hydrogen_idx'] = tautomer_transformation[ 'hydrogen_idx'] tautomer_transformation['acceptor_hydrogen_idx'] = len( ani_input['hybrid_atoms']) - 1 ani_input['hybrid_coords'] = min_coordinates ani_input['min_e'] = min_e ani_input['hybrid_topology'] = hybrid_top atom_list = [] for e, c in zip(ani_input['hybrid_atoms'], ani_input['hybrid_coords']): c_list = (c[0].value_in_unit(unit.angstrom), c[1].value_in_unit(unit.angstrom), c[2].value_in_unit(unit.angstrom)) atom_list.append(Atom(e, c_list)) mol = Atoms(atom_list) ani_input['ase_hybrid_mol'] = mol
def getUnitCell(self): sideLen = self.sideLen edge = Atoms() nAtom = 2 * sideLen + 1 for i in range(nAtom): if i % 2 == 0: label = 'C' y = 0.5 else: label = 'N' if len(self.elements) == 1: label = 'C' y = 1.0 x = (-sideLen + i) * 0.5 * sqrt(3) y -= (sideLen + 1) * 1.5 atom = Atom(label, (x, y, 0.0)) edge.append(atom) unitCell = Atoms() for i in range(6): newEdge = edge.copy() newEdge.rotate('z', i * 2 * pi / 6.0) unitCell.extend(newEdge) #get cell dist = (self.sideLen + 1) * 3.0 #the distance between 2 hole center if self.cubic: newAtoms = unitCell.copy() newAtoms.translate([dist * sqrt(3) / 2, dist / 2.0, 0]) unitCell.extend(newAtoms) unitCell.set_cell([dist * sqrt(3), dist, 10.0]) else: cell = np.diag([dist * sqrt(3) / 2, dist, 10]) cell[0, 1] = dist / 2.0 unitCell.set_cell(cell) return unitCell
voxel_gaussian = norm.pdf(r) # put e density in voxel ed = voxel_gaussian * atom.number return ed if __name__ == '__main__': import matplotlib.pyplot as plt from ase import Atoms from ase.visualize import view from ase.cluster import FaceCenteredCubic import ase.io as aseio # atoms = Atoms('Pt', [(0, 0, 0)]) atoms = Atoms( FaceCenteredCubic('Pt', [[1, 0, 0], [1, 1, 0], [1, 1, 1]], (2, 3, 2))) # atoms = atoms[[atom.index for atom in atoms if atom.position[2]< 1.5]] view(atoms) atoms.set_cell(atoms.get_cell() * 1.2) atoms.center() cell = atoms.get_cell() print(cell, len(atoms)) resolution = .3 * np.ones(3) c = np.diagonal(cell) v = tuple(np.int32(np.ceil(c / resolution))) voxels = np.zeros(v) ed = np.zeros(v) i = 0 for atom in atoms: print(i) ed += get_atomic_electron_density(atom, voxels, resolution)
def newclus(ind1, ind2, Optimizer): """Select a box in the cluster configuration""" if 'CX' in Optimizer.debug: debug = True else: debug = False Optimizer.output.write('Box Cluster Cx between individual ' + repr(ind1.index) + ' and individual ' + repr(ind2.index) + '\n') #Perserve starting conditions of individual solid1 = ind1[0].copy() solid2 = ind2[0].copy() cello1 = ind1[0].get_cell() cello2 = ind2[0].get_cell() cell1 = numpy.maximum.reduce(solid1.get_positions()) cell1m = numpy.minimum.reduce(solid1.get_positions()) cell2 = numpy.maximum.reduce(solid2.get_positions()) cell2m = numpy.minimum.reduce(solid2.get_positions()) cell = numpy.minimum(cell1, cell2) pbc1 = solid1.get_pbc() pbc2 = solid2.get_pbc() #Get starting concentrations and number of atoms nat1 = len(solid1) nat2 = len(solid2) # Pick a origin point for box in the cell pt1 = random.choice(solid1) pt1f = [(pt1.position[i] - cell1m[i]) / cell1[i] for i in range(3)] pt2 = [pt1f[i] * cell2[i] + cell2m[i] for i in range(3)] solid2.append(Atom(position=pt2)) pt2 = solid2[len(solid2) - 1] #Find max neighborsize of circle cut r = random.uniform(0, min(nat1, nat2) / 5.0) if debug: print 'DEBUG CX: Point one =', pt1.position print 'DEBUG CX: Point two =', pt2.position #Find atoms within sphere of neighborsize r for both individuals #Make sure that crossover is only selection of atoms not all while True: ctoff = [r for on in solid1] nl = NeighborList(ctoff, bothways=True, self_interaction=False) nl.update(solid1) indices1, offsets = nl.get_neighbors(pt1.index) if len(indices1) == 0: r = r * 1.2 elif len(indices1) < nat1 * .75: break else: r = r * 0.8 if debug: print 'Neighborsize of box = ' + repr( r) + '\nPosition in solid1 = ' + repr( pt1.position) + '\nPosition in solid2 = ' + repr(pt2.position) group1 = Atoms(cell=solid1.get_cell(), pbc=solid1.get_pbc()) group1.append(pt1) indices1a = [pt1.index] for index, d in zip(indices1, offsets): if index not in indices1a: index = int(index) pos = solid1[index].position + numpy.dot(d, solid1.get_cell()) group1.append(Atom(symbol=solid1[index].symbol, position=pos)) indices1a.append(index) indices1 = indices1a ctoff = [r for on in solid2] nl = NeighborList(ctoff, bothways=True, self_interaction=False) nl.update(solid2) indices2, offsets = nl.get_neighbors(pt2.index) group2 = Atoms(cell=solid2.get_cell(), pbc=solid2.get_pbc()) indices2a = [] for index, d in zip(indices2, offsets): if index not in indices2a: index = int(index) pos = solid2[index].position + numpy.dot(d, solid2.get_cell()) group2.append(Atom(symbol=solid2[index].symbol, position=pos)) indices2a.append(index) indices2 = indices2a if len(indices2) == 0: for one in group1: while True: sel = random.choice(solid2) if sel.symbol == one.symbol: if sel.index not in indices2: group2.append(sel) indices2.append(sel.index) break if Optimizer.forcing == 'Concentration': symlist = list(set(group1.get_chemical_symbols())) seplist = [[atm for atm in group2 if atm.symbol == sym] for sym in symlist] group2n = Atoms(cell=group2.get_cell(), pbc=group2.get_pbc()) indices2n = [] dellist = [] for one in group1: sym1 = one.symbol listpos = [i for i, s in enumerate(symlist) if s == sym1][0] if len(seplist[listpos]) > 0: pos = random.choice(range(len(seplist[listpos]))) group2n.append(seplist[listpos][pos]) indices2n.append(indices2[seplist[listpos][pos].index]) del seplist[listpos][pos] else: dellist.append(one.index) if len(dellist) != 0: dellist.sort(reverse=True) for one in dellist: del group1[one] del indices1[one] indices2n.append(pt2.index) indices2 = indices2n group2 = group2n.copy() else: dellist = [] while len(group2) < len(group1) - len(dellist): #Too many atoms in group 1 dellist.append(random.choice(group1).index) if len(dellist) != 0: dellist.sort(reverse=True) for one in dellist: del group1[one] del indices1[one] dellist = [] while len(group1) < len(group2) - len(dellist): #Too many atoms in group 2 dellist.append(random.choice(group2).index) if len(dellist) != 0: dellist.sort(reverse=True) for one in dellist: del group2[one] del indices2[one] other2 = Atoms(cell=solid2.get_cell(), pbc=solid2.get_pbc()) for one in solid2: if one.index not in indices2: other2.append(one) other1 = Atoms(cell=solid1.get_cell(), pbc=solid1.get_pbc()) for one in solid1: if one.index not in indices1: other1.append(one) #Exchange atoms in sphere and build new solids nsolid1 = other1.copy() nsolid1.extend(group2.copy()) nsolid2 = other2.copy() nsolid2.extend(group1.copy()) #DEBUG: Write crossover to file if debug: write_xyz(Optimizer.debugfile, nsolid1, 'CX(randalloybx):nsolid1') write_xyz(Optimizer.debugfile, nsolid2, 'CX(randalloybx):nsolid2') #DEBUG: Check structure of atoms exchanged for sym, c, m, u in Optimizer.atomlist: if Optimizer.structure == 'Defect': nc = len([atm for atm in nsolid1 if atm.symbol == sym]) nc += len([atm for atm in ind1.bulki if atm.symbol == sym]) oc = len([atm for atm in solid1 if atm.symbol == sym]) oc += len([atm for atm in ind1.bulki if atm.symbol == sym]) else: nc = len([atm for atm in nsolid1 if atm.symbol == sym]) oc = len([atm for atm in solid1 if atm.symbol == sym]) Optimizer.output.write('CX(clustbx):New solid1 contains ' + repr(nc) + ' ' + repr(sym) + ' atoms\n') if debug: print 'DEBUG CX: New solid1 contains ' + repr(nc) + ' ' + repr( sym) + ' atoms' if oc != nc: #pdb.set_trace() print 'CX: Issue in maintaining atom concentration\n Dropping new individual' Optimizer.output.write( 'CX: Issue in maintaining atom concentration\n Dropping new individual 1\n' ) nsolid1 = solid1 for sym, c, m, u in Optimizer.atomlist: if Optimizer.structure == 'Defect': nc = len([atm for atm in nsolid2 if atm.symbol == sym]) nc += len([atm for atm in ind2.bulki if atm.symbol == sym]) oc = len([atm for atm in solid2 if atm.symbol == sym]) oc += len([atm for atm in ind2.bulki if atm.symbol == sym]) else: nc = len([atm for atm in nsolid2 if atm.symbol == sym]) oc = len([atm for atm in solid2 if atm.symbol == sym]) Optimizer.output.write('CX(clustbx):New solid2 contains ' + repr(nc) + ' ' + repr(sym) + ' atoms\n') if debug: print 'DEBUG CX: New solid2 contains ' + repr(nc) + ' ' + repr( sym) + ' atoms' if oc != nc: #pdb.set_trace() print 'CX: Issue in maintaining atom concentration\n Dropping new individual' Optimizer.output.write( 'CX: Issue in maintaining atom concentration\n Dropping new individual 2\n' ) solid2.pop() nsolid2 = solid2 if Optimizer.forcing != 'Concentration': for i in range(len(Optimizer.atomlist)): atms1 = [ inds for inds in nsolid1 if inds.symbol == Optimizer.atomlist[i][0] ] atms2 = [ inds for inds in nsolid2 if inds.symbol == Optimizer.atomlist[i][0] ] if len(atms1) == 0: if len(atms2) == 0: nsolid1[random.randint( 0, len(indi1) - 1)].symbol == Optimizer.atomlist[i][0] nsolid2[random.randint( 0, len(indi2) - 1)].symbol == Optimizer.atomlist[i][0] else: nsolid1.append(atms2[random.randint(0, len(atms2) - 1)]) nsolid1.pop(random.randint(0, len(nsolid1) - 2)) else: if len(atms2) == 0: nsolid2.append(atms1[random.randint(0, len(atms1) - 1)]) nsolid2.pop(random.randint(0, len(nsolid2) - 2)) nsolid1.set_cell(cello1) nsolid2.set_cell(cello2) nsolid1.set_pbc(pbc1) nsolid2.set_pbc(pbc2) ind1[0] = nsolid1.copy() ind2[0] = nsolid2.copy() return ind1, ind2
lambda_coeff = 1.0 name = 'lambda_{0}'.format(lambda_coeff) filename = 'atoms_' + name + '.dat' f = paropen(filename, 'w') elements = ['N'] for symbol in elements: mixer = Mixer() eigensolver = CG(tw_coeff=lambda_coeff) poissonsolver = PoissonSolver() molecule = Atoms(symbol, positions=[(c, c, c)], cell=(a, a, a)) calc = GPAW(h=h, xc=xcname, maxiter=240, eigensolver=eigensolver, mixer=mixer, setups=name, poissonsolver=poissonsolver) molecule.set_calculator(calc) E = molecule.get_total_energy() f.write('{0}\t{1}\n'.format(symbol, E))
def do_calculation(calculator): 'function to run a calculation through multiprocessing' with calculator as calc: atoms = calc.get_atoms() e = atoms.get_potential_energy() v = atoms.get_volume() return v, e # this only runs in the main script, not in processes on other cores if __name__ == '__main__': NCORES = 6 # number of cores to run processes on # setup an atoms object a = 3.6 atoms = Atoms( [Atom('Cu', (0, 0, 0))], cell=0.5 * a * np.array([[1.0, 1.0, 0.0], [0.0, 1.0, 1.0], [1.0, 0.0, 1.0]])) v0 = atoms.get_volume() # Step 1 COUNTER = 0 calculators = [] # list of calculators to be run factors = [-0.1, 0.05, 0.0, 0.05, 0.1] for f in factors: newatoms = atoms.copy() newatoms.set_volume(v0 * (1 + f)) label = 'bulk/cu-mp/step1-{0}'.format(COUNTER) COUNTER += 1 calc = jasp(label, xc='PBE', encut=350, kpts=(6, 6, 6),
def read_abinit_in(fd): """Import ABINIT input file. Reads cell, atom positions, etc. from abinit input file """ tokens = [] for line in fd: meat = line.split('#', 1)[0] tokens += meat.lower().split() # note that the file can not be scanned sequentially index = tokens.index("acell") unit = 1.0 if (tokens[index + 4].lower()[:3] != 'ang'): unit = Bohr acell = [ unit * float(tokens[index + 1]), unit * float(tokens[index + 2]), unit * float(tokens[index + 3]) ] index = tokens.index("natom") natom = int(tokens[index + 1]) index = tokens.index("ntypat") ntypat = int(tokens[index + 1]) index = tokens.index("typat") typat = [] while len(typat) < natom: token = tokens[index + 1] if '*' in token: # e.g. typat 4*1 3*2 ... nrepeat, typenum = token.split('*') typat += [int(typenum)] * int(nrepeat) else: typat.append(int(token)) index += 1 assert natom == len(typat) index = tokens.index("znucl") znucl = [] for i in range(ntypat): znucl.append(int(tokens[index + 1 + i])) index = tokens.index("rprim") rprim = [] for i in range(3): rprim.append([ acell[i] * float(tokens[index + 3 * i + 1]), acell[i] * float(tokens[index + 3 * i + 2]), acell[i] * float(tokens[index + 3 * i + 3]) ]) # create a list with the atomic numbers numbers = [] for i in range(natom): ii = typat[i] - 1 numbers.append(znucl[ii]) # now the positions of the atoms if "xred" in tokens: index = tokens.index("xred") xred = [] for i in range(natom): xred.append([ float(tokens[index + 3 * i + 1]), float(tokens[index + 3 * i + 2]), float(tokens[index + 3 * i + 3]) ]) atoms = Atoms(cell=rprim, scaled_positions=xred, numbers=numbers, pbc=True) else: if "xcart" in tokens: index = tokens.index("xcart") unit = Bohr elif "xangst" in tokens: unit = 1.0 index = tokens.index("xangst") else: raise IOError( "No xred, xcart, or xangs keyword in abinit input file") xangs = [] for i in range(natom): xangs.append([ unit * float(tokens[index + 3 * i + 1]), unit * float(tokens[index + 3 * i + 2]), unit * float(tokens[index + 3 * i + 3]) ]) atoms = Atoms(cell=rprim, positions=xangs, numbers=numbers, pbc=True) try: ii = tokens.index('nsppol') except ValueError: nsppol = None else: nsppol = int(tokens[ii + 1]) if nsppol == 2: index = tokens.index('spinat') magmoms = [float(tokens[index + 3 * i + 3]) for i in range(natom)] atoms.set_initial_magnetic_moments(magmoms) assert len(atoms) == natom return atoms
atoms.get_potential_energy() calc.write('Al1.gpw','all') # Excited state calculation q = np.array([1./4.,0.,0.]) w = np.linspace(0, 24, 241) df = DF(calc='Al1.gpw', q=q, w=w, eta=0.2, ecut=50) #df.write('Al.pckl') df.get_EELS_spectrum(filename='EELS_Al_1') atoms = Atoms('Al8',scaled_positions=[(0,0,0), (0.5,0,0), (0,0.5,0), (0,0,0.5), (0.5,0.5,0), (0.5,0,0.5), (0.,0.5,0.5), (0.5,0.5,0.5)], cell=[(0,a,a),(a,0,a),(a,a,0)], pbc=True) calc = GPAW(gpts=(24,24,24), eigensolver=RMM_DIIS(), mixer=Mixer(0.1,3), kpts=(2,2,2), xc='LDA') atoms.set_calculator(calc) atoms.get_potential_energy() calc.write('Al2.gpw','all')
from distutils.version import LooseVersion from ase.phonons import Phonons from ase import Atoms, __version__ import numpy as np from gpaw import GPAW from gpaw.elph.electronphonon import ElectronPhononCoupling if LooseVersion(__version__) < '3.18': from unittest import SkipTest raise SkipTest a = 0.90 atoms = Atoms('H', cell=np.diag([a, 2.1, 2.1]), positions=[[0, 0, 0]], pbc=(1, 0, 0)) atoms.center() supercell = (2, 1, 1) parameters = { 'mode': 'lcao', 'kpts': { 'size': (2, 1, 1), 'gamma': True }, 'txt': None, 'basis': 'dzp', 'symmetry': { 'point_group': False },
import numpy as np from ase import Atoms from ase.calculators.test import FreeElectrons from ase.geometry import crystal_structure_from_cell, cell_to_cellpar, cellpar_to_cell from ase.dft.kpoints import get_special_points mc1 = [[1, 0, 0], [0, 1, 0], [0, 0.2, 1]] par = cell_to_cellpar(mc1) mc2 = cellpar_to_cell(par) mc3 = [[1, 0, 0], [0, 1, 0], [-0.2, 0, 1]] mc4 = [[1, 0, 0], [-0.2, 1, 0], [0, 0, 1]] path = 'GYHCEM1AXH1' firsttime = True for cell in [mc1, mc2, mc3, mc4]: a = Atoms(cell=cell, pbc=True) a.cell *= 3 a.calc = FreeElectrons(nvalence=1, kpts={'path': path}) cs = crystal_structure_from_cell(a.cell) assert cs == 'monoclinic' r = a.get_reciprocal_cell() k = get_special_points(a.cell)['H'] print(np.dot(k, r)) a.get_potential_energy() bs = a.calc.band_structure() coords, labelcoords, labels = bs.get_labels() assert ''.join(labels) == path e_skn = bs.energies # bs.plot() if firsttime: coords1 = coords
"""Check that we can read old version 1 PickleTrajectories.""" import cPickle as pickle from StringIO import StringIO import numpy as np from ase.io.trajectory import PickleTrajectory from ase.constraints import FixAtoms from ase import Atoms a = Atoms('FOO') def v1(a): """Create old version-1 trajectory.""" fd = StringIO() fd.write('PickleTrajectory') d = {'pbc': a.pbc, 'numbers': a.numbers, 'tags': None, 'masses': None, 'constraints': a.constraints} pickle.dump(d, fd, protocol=-1) d = {'positions': a.positions, 'cell': a.cell, 'momenta': None} pickle.dump(d, fd, protocol=-1) return StringIO(fd.getvalue()) def v2(a):
import numpy as np a1 = [2, 0, 0] a2 = [1, 1, 0] a3 = [0, 0, 10] uc = np.array([a1, a2, a3]) print('V = {0} ang^3 from dot/cross'.format(np.dot(np.cross(a1, a2), a3))) print('V = {0} ang^3 from det'.format(np.linalg.det(uc))) from ase import Atoms atoms = Atoms([], cell=uc) #empty list of atoms print('V = {0} ang^3 from get_volume'.format(atoms.get_volume()))
def test_dynamic_neb(): # Global counter of force evaluations: force_evaluations = [0] class EMT(OrigEMT): def calculate(self, *args, **kwargs): force_evaluations[0] += 1 OrigEMT.calculate(self, *args, **kwargs) # Build Pt(111) slab with six surface atoms and add oxygen adsorbate initial = fcc111('Pt', size=(3, 2, 3), orthogonal=True) initial.center(axis=2, vacuum=10) oxygen = Atoms('O') oxygen.translate(initial[7].position + (0., 0., 3.5)) initial.extend(oxygen) # EMT potential initial.calc = EMT() # Optimize initial state opt = BFGS(initial) opt.run(fmax=0.03) # Move oxygen adsorbate to neighboring hollow site final = initial.copy() final[18].x += 2.8 final[18].y += 1.8 final.calc = EMT() opt = BFGS(final) opt.run(fmax=0.03) # NEB with seven interior images images = [initial] for i in range(7): images.append(initial.copy()) images.append(final) fmax = 0.03 # Same for NEB and optimizer for i in range(1, len(images) - 1): calc = EMT() images[i].calc = calc def run_NEB(): if method == 'dyn': neb = NEB(images, fmax=fmax, dynamic_relaxation=True) neb.interpolate() elif method == 'dyn_scale': neb = NEB(images, fmax=fmax, dynamic_relaxation=True, scale_fmax=6.) neb.interpolate() else: # Default NEB neb = NEB(images) neb.interpolate() # Optimize and check number of calculations. # We use a hack with a global counter to count the force evaluations: force_evaluations[0] = 0 opt = BFGS(neb) opt.run(fmax=fmax) force_calls.append(force_evaluations[0]) # Get potential energy of transition state. Emax.append( np.sort([image.get_potential_energy() for image in images[1:-1]])[-1]) force_calls, Emax = [], [] for method in ['def', 'dyn', 'dyn_scale']: run_NEB() # Check force calculation count for default and dynamic NEB implementations print('\n# Force calls with default NEB: {}'.format(force_calls[0])) print('# Force calls with dynamic NEB: {}'.format(force_calls[1])) print('# Force calls with dynamic and scaled NEB: {}\n'.format( force_calls[2])) assert force_calls[2] < force_calls[1] < force_calls[0] # Assert reaction barriers are within 1 meV of default NEB assert (abs(Emax[1] - Emax[0]) < 1e-3) assert (abs(Emax[2] - Emax[0]) < 1e-3)
def write(self, filename, **settings): # Determine canvas width and height ratio = float(self.w) / self.h if self.canvas_width is None: if self.canvas_height is None: self.canvas_width = min(self.w * 15, 640) else: self.canvas_width = self.canvas_height * ratio elif self.canvas_height is not None: raise RuntimeError("Can't set *both* width and height!") # Distance to image plane from camera if self.image_plane is None: if self.camera_type == 'orthographic': self.image_plane = 1 - self.camera_dist else: self.image_plane = 0 self.image_plane += self.camera_dist # Produce the .ini file if filename.endswith('.pov'): ini = open(filename[:-4] + '.ini', 'w').write else: ini = open(filename + '.ini', 'w').write ini('Input_File_Name=%s\n' % filename) ini('Output_to_File=True\n') ini('Output_File_Type=N\n') if self.transparent: ini('Output_Alpha=on\n') else: ini('Output_Alpha=off\n') ini('; if you adjust Height, and width, you must preserve the ratio\n') ini('; Width / Height = %f\n' % ratio) ini('Width=%s\n' % self.canvas_width) ini('Height=%s\n' % (self.canvas_width / ratio)) ini('Antialias=True\n') ini('Antialias_Threshold=0.1\n') ini('Display=%s\n' % self.display) ini('Pause_When_Done=%s\n' % self.pause) ini('Verbose=False\n') del ini # Produce the .pov file pov_fid = open(filename, 'w') w = pov_fid.write w('#include "colors.inc"\n') w('#include "finish.inc"\n') w('\n') w('global_settings {assumed_gamma 1 max_trace_level 6}\n') # The background must be transparent for a transparent image if self.transparent: w('background {%s transmit 1.0}\n' % pc(self.background)) else: w('background {%s}\n' % pc(self.background)) w('camera {%s\n' % self.camera_type) w(' right -%.2f*x up %.2f*y\n' % (self.w, self.h)) w(' direction %.2f*z\n' % self.image_plane) w(' location <0,0,%.2f> look_at <0,0,0>}\n' % self.camera_dist) for loc, rgb in self.point_lights: w('light_source {%s %s}\n' % (pa(loc), pc(rgb))) if self.area_light is not None: loc, color, width, height, nx, ny = self.area_light w('light_source {%s %s\n' % (pa(loc), pc(color))) w(' area_light <%.2f, 0, 0>, <0, %.2f, 0>, %i, %i\n' % (width, height, nx, ny)) w(' adaptive 1 jitter}\n') # the depth cueing if self.depth_cueing and (self.cue_density >= 1e-4): # same way vmd does it if self.cue_density > 1e4: # larger does not make any sense dist = 1e-4 else: dist = 1. / self.cue_density w('fog {fog_type 1 distance %.4f color %s}' % (dist, pc(self.background))) w('\n') for key in self.material_styles_dict.keys(): w('#declare %s = %s\n' % (key, self.material_styles_dict[key])) w('#declare Rcell = %.3f;\n' % self.celllinewidth) w('#declare Rbond = %.3f;\n' % self.bondlinewidth) w('\n') w('#macro atom(LOC, R, COL, TRANS, FIN)\n') w(' sphere{LOC, R texture{pigment{color COL transmit TRANS} ' 'finish{FIN}}}\n') w('#end\n') w('#macro constrain(LOC, R, COL, TRANS FIN)\n') w('union{torus{R, Rcell rotate 45*z ' 'texture{pigment{color COL transmit TRANS} finish{FIN}}}\n') w(' torus{R, Rcell rotate -45*z ' 'texture{pigment{color COL transmit TRANS} finish{FIN}}}\n') w(' translate LOC}\n') w('#end\n') w('\n') z0 = self.positions[:, 2].max() self.positions -= (self.w / 2, self.h / 2, z0) # Draw unit cell if self.cell_vertices is not None: self.cell_vertices -= (self.w / 2, self.h / 2, z0) self.cell_vertices.shape = (2, 2, 2, 3) for c in range(3): for j in ([0, 0], [1, 0], [1, 1], [0, 1]): parts = [] for i in range(2): j.insert(c, i) parts.append(self.cell_vertices[tuple(j)]) del j[c] distance = np.linalg.norm(parts[1] - parts[0]) if distance < 1e-12: continue w('cylinder {') for i in range(2): w(pa(parts[i]) + ', ') w('Rcell pigment {Black}}\n') # Draw atoms a = 0 for loc, dia, color in zip(self.positions, self.d, self.colors): tex = 'ase3' trans = 0. if self.textures is not None: tex = self.textures[a] if self.transmittances is not None: trans = self.transmittances[a] w('atom(%s, %.2f, %s, %s, %s) // #%i \n' % (pa(loc), dia / 2., pc(color), trans, tex, a)) a += 1 # Draw atom bonds for pair in self.bondatoms: # Make sure that each pair has 4 componets: a, b, offset, # bond_order, bond_offset # a, b: atom index to draw bond # offset: original meaning to make offset for mid-point. # bond_oder: if not supplied, set it to 1 (single bond). # It can be 1, 2, 3, corresponding to single, # double, triple bond # bond_offset: displacement from original bond position. # Default is (bondlinewidth, bondlinewidth, 0) # for bond_order > 1. if len(pair) == 2: a, b = pair offset = (0, 0, 0) bond_order = 1 bond_offset = (0, 0, 0) elif len(pair) == 3: a, b, offset = pair bond_order = 1 bond_offset = (0, 0, 0) elif len(pair) == 4: a, b, offset, bond_order = pair bond_offset = (self.bondlinewidth, self.bondlinewidth, 0) elif len(pair) > 4: a, b, offset, bond_order, bond_offset = pair else: raise RuntimeError('Each list in bondatom must have at least ' '2 entries. Error at %s' % pair) if len(offset) != 3: raise ValueError('offset must have 3 elements. ' 'Error at %s' % pair) if len(bond_offset) != 3: raise ValueError('bond_offset must have 3 elements. ' 'Error at %s' % pair) if bond_order not in [0, 1, 2, 3]: raise ValueError('bond_order must be either 0, 1, 2, or 3. ' 'Error at %s' % pair) # Up to here, we should have all a, b, offset, bond_order, # bond_offset for all bonds. # Rotate bond_offset so that its direction is 90 degree off the bond # Utilize Atoms object to rotate if bond_order > 1 and np.linalg.norm(bond_offset) > 1.e-9: tmp_atoms = Atoms('H3') tmp_atoms.set_cell(self.cell) tmp_atoms.set_positions([ self.positions[a], self.positions[b], self.positions[b] + np.array(bond_offset), ]) tmp_atoms.center() tmp_atoms.set_angle(0, 1, 2, 90) bond_offset = tmp_atoms[2].position - tmp_atoms[1].position R = np.dot(offset, self.cell) mida = 0.5 * (self.positions[a] + self.positions[b] + R) midb = 0.5 * (self.positions[a] + self.positions[b] - R) if self.textures is not None: texa = self.textures[a] texb = self.textures[b] else: texa = texb = 'ase3' if self.transmittances is not None: transa = self.transmittances[a] transb = self.transmittances[b] else: transa = transb = 0. fmt = ('cylinder {%s, %s, Rbond texture{pigment ' '{color %s transmit %s} finish{%s}}}\n') # draw bond, according to its bond_order. # bond_order == 0: No bond is plotted # bond_order == 1: use original code # bond_order == 2: draw two bonds, one is shifted by bond_offset/2, # and another is shifted by -bond_offset/2. # bond_order == 3: draw two bonds, one is shifted by bond_offset, # and one is shifted by -bond_offset, and the # other has no shift. # To shift the bond, add the shift to the first two coordinate in # write statement. if bond_order == 1: w(fmt % (pa(self.positions[a]), pa(mida), pc( self.colors[a]), transa, texa)) w(fmt % (pa(self.positions[b]), pa(midb), pc( self.colors[b]), transb, texb)) elif bond_order == 2: bondOffSetDB = [x / 2 for x in bond_offset] w(fmt % (pa(self.positions[a] - bondOffSetDB), pa(mida - bondOffSetDB), pc(self.colors[a]), transa, texa)) w(fmt % (pa(self.positions[b] - bondOffSetDB), pa(midb - bondOffSetDB), pc(self.colors[b]), transb, texb)) w(fmt % (pa(self.positions[a] + bondOffSetDB), pa(mida + bondOffSetDB), pc(self.colors[a]), transa, texa)) w(fmt % (pa(self.positions[b] + bondOffSetDB), pa(midb + bondOffSetDB), pc(self.colors[b]), transb, texb)) elif bond_order == 3: w(fmt % (pa(self.positions[a]), pa(mida), pc( self.colors[a]), transa, texa)) w(fmt % (pa(self.positions[b]), pa(midb), pc( self.colors[b]), transb, texb)) w(fmt % (pa(self.positions[a] + bond_offset), pa(mida + bond_offset), pc(self.colors[a]), transa, texa)) w(fmt % (pa(self.positions[b] + bond_offset), pa(midb + bond_offset), pc(self.colors[b]), transb, texb)) w(fmt % (pa(self.positions[a] - bond_offset), pa(mida - bond_offset), pc(self.colors[a]), transa, texa)) w(fmt % (pa(self.positions[b] - bond_offset), pa(midb - bond_offset), pc(self.colors[b]), transb, texb)) # Draw constraints if requested if self.exportconstraints: for a in self.constrainatoms: dia = self.d[a] loc = self.positions[a] trans = 0.0 if self.transmittances is not None: trans = self.transmittances[a] w('constrain(%s, %.2f, Black, %s, %s) // #%i \n' % (pa(loc), dia / 2., trans, tex, a)) return pov_fid
from vasp import Vasp from ase import Atom, Atoms atoms = Atoms([Atom('Cu', [0.000, 0.000, 0.000])], cell=[[1.818, 0.000, 1.818], [1.818, 1.818, 0.000], [0.000, 1.818, 1.818]]) calc = Vasp('bulk/alloy/cu', xc='PBE', encut=350, kpts=[13, 13, 13], ibrion=2, isif=4, nsw=10, atoms=atoms) calc.set_nbands(f=7) calc.write_input() # you have to write out the input for it to take effect print calc
import numpy as np import torch from ase import Atoms from ase.calculators.emt import EMT from amptorch.trainer import AtomsTrainer ### Construct test data distances = np.linspace(2, 5, 100) images = [] for dist in distances: image = Atoms( "CuCO", [ (-dist * np.sin(0.65), dist * np.cos(0.65), 0), (0, 0, 0), (dist * np.sin(0.65), dist * np.cos(0.65), 0), ], ) image.set_cell([10, 10, 10]) image.wrap(pbc=True) image.set_calculator(EMT()) images.append(image) ### Construct parameters Gs = { "default": { "G2": { "etas": np.logspace(np.log10(0.05), np.log10(5.0), num=4), "rs_s": [0], },
def test_qmmm(testdir): r = rOH a = angleHOH * pi / 180 # From https://doi.org/10.1063/1.445869 eexp = 6.50 * units.kcal / units.mol dexp = 2.74 aexp = 27 D = np.linspace(2.5, 3.5, 30) i = LJInteractions({('O', 'O'): (epsilon0, sigma0)}) # General LJ interaction object sigma_mm = np.array([0, 0, sigma0]) epsilon_mm = np.array([0, 0, epsilon0]) sigma_qm = np.array([0, 0, sigma0]) epsilon_qm = np.array([0, 0, epsilon0]) ig = LJInteractionsGeneral(sigma_qm, epsilon_qm, sigma_mm, epsilon_mm, 3) for calc in [ TIP3P(), SimpleQMMM([0, 1, 2], TIP3P(), TIP3P(), TIP3P()), SimpleQMMM([0, 1, 2], TIP3P(), TIP3P(), TIP3P(), vacuum=3.0), EIQMMM([0, 1, 2], TIP3P(), TIP3P(), i), EIQMMM([3, 4, 5], TIP3P(), TIP3P(), i, vacuum=3.0), EIQMMM([0, 1, 2], TIP3P(), TIP3P(), i, vacuum=3.0), EIQMMM([0, 1, 2], TIP3P(), TIP3P(), ig), EIQMMM([3, 4, 5], TIP3P(), TIP3P(), ig, vacuum=3.0), EIQMMM([0, 1, 2], TIP3P(), TIP3P(), ig, vacuum=3.0) ]: dimer = Atoms('H2OH2O', [(r * cos(a), 0, r * sin(a)), (r, 0, 0), (0, 0, 0), (r * cos(a / 2), r * sin(a / 2), 0), (r * cos(a / 2), -r * sin(a / 2), 0), (0, 0, 0)]) dimer.calc = calc E = [] F = [] for d in D: dimer.positions[3:, 0] += d - dimer.positions[5, 0] E.append(dimer.get_potential_energy()) F.append(dimer.get_forces()) F = np.array(F) F1 = np.polyval(np.polyder(np.polyfit(D, E, 7)), D) F2 = F[:, :3, 0].sum(1) error = abs(F1 - F2).max() assert error < 0.01 dimer.constraints = FixInternals(bonds=[(r, (0, 2)), (r, (1, 2)), (r, (3, 5)), (r, (4, 5))], angles_deg=[ (np.degrees(a), (0, 2, 1)), (np.degrees(a), (3, 5, 4)) ]) with GPMin(dimer, trajectory=calc.name + '.traj', logfile=calc.name + 'd.log') as opt: opt.run(0.01) e0 = dimer.get_potential_energy() d0 = dimer.get_distance(2, 5) R = dimer.positions v1 = R[1] - R[5] v2 = R[5] - (R[3] + R[4]) / 2 a0 = np.arccos( np.dot(v1, v2) / (np.dot(v1, v1) * np.dot(v2, v2))**0.5) / np.pi * 180 fmt = '{0:>20}: {1:.3f} {2:.3f} {3:.3f} {4:.1f}' print(fmt.format(calc.name, -min(E), -e0, d0, a0)) assert abs(e0 + eexp) < 0.002 assert abs(d0 - dexp) < 0.01 assert abs(a0 - aexp) < 4 print(fmt.format('reference', 9.999, eexp, dexp, aexp))