def _test_timestepping(self, t): #XXX DEBUG START if debug and os.path.isfile('%s_%d.gpw' % (self.tdname, t)): return #XXX DEBUG END timestep = self.timesteps[t] self.assertAlmostEqual(self.duration % timestep, 0.0, 12) niter = int(self.duration / timestep) ndiv = 1 #XXX traj = Trajectory('%s_%d.traj' % (self.tdname, t), 'w', self.tdcalc.get_atoms()) t0 = time.time() f = paropen('%s_%d.log' % (self.tdname, t), 'w') print('propagator: %s, duration: %6.1f as, timestep: %5.2f as, ' \ 'niter: %d' % (self.propagator, self.duration, timestep, niter), file=f) for i in range(1, niter + 1): # XXX bare bones propagation without all the nonsense self.tdcalc.propagator.propagate(self.tdcalc.time, timestep * attosec_to_autime) self.tdcalc.time += timestep * attosec_to_autime self.tdcalc.niter += 1 if i % ndiv == 0: rate = 60 * ndiv / (time.time() - t0) ekin = self.tdcalc.atoms.get_kinetic_energy() epot = self.tdcalc.get_td_energy() * Hartree F_av = np.zeros((len(self.tdcalc.atoms), 3)) print('i=%06d, time=%6.1f as, rate=%6.2f min^-1, ' \ 'ekin=%13.9f eV, epot=%13.9f eV, etot=%13.9f eV' \ % (i, timestep * i, rate, ekin, epot, ekin + epot), file=f) t0 = time.time() # Hack to prevent calls to GPAW::get_potential_energy when saving spa = self.tdcalc.get_atoms() spc = SinglePointCalculator(spa, energy=epot, forces=F_av) spa.set_calculator(spc) traj.write(spa) f.close() traj.close() self.tdcalc.write('%s_%d.gpw' % (self.tdname, t), mode='all') # Save density and wavefunctions to binary gd, finegd = self.tdcalc.wfs.gd, self.tdcalc.density.finegd if world.rank == 0: big_nt_g = finegd.collect(self.tdcalc.density.nt_g) np.save('%s_%d_nt.npy' % (self.tdname, t), big_nt_g) del big_nt_g big_psit_nG = gd.collect(self.tdcalc.wfs.kpt_u[0].psit_nG) np.save('%s_%d_psit.npy' % (self.tdname, t), big_psit_nG) del big_psit_nG else: finegd.collect(self.tdcalc.density.nt_g) gd.collect(self.tdcalc.wfs.kpt_u[0].psit_nG) world.barrier()
def read_castep_geom(fd, index=None, units=units_CODATA2002): """Reads a .geom file produced by the CASTEP GeometryOptimization task and returns an atoms object. The information about total free energy and forces of each atom for every relaxation step will be stored for further analysis especially in a single-point calculator. Note that everything in the .geom file is in atomic units, which has been conversed to commonly used unit angstrom(length) and eV (energy). Note that the index argument has no effect as of now. Contribution by Wei-Bing Zhang. Thanks! Routine now accepts a filedescriptor in order to out-source the gz and bz2 handling to formats.py. Note that there is a fallback routine read_geom() that behaves like previous versions did. """ from ase.calculators.singlepoint import SinglePointCalculator # fd is closed by embracing read() routine txt = fd.readlines() traj = [] Hartree = units['Eh'] Bohr = units['a0'] # Yeah, we know that... # print('N.B.: Energy in .geom file is not 0K extrapolated.') for i, line in enumerate(txt): if line.find('<-- E') > 0: start_found = True energy = float(line.split()[0]) * Hartree cell = [x.split()[0:3] for x in txt[i + 1:i + 4]] cell = np.array([[float(col) * Bohr for col in row] for row in cell]) if line.find('<-- R') > 0 and start_found: start_found = False geom_start = i for i, line in enumerate(txt[geom_start:]): if line.find('<-- F') > 0: geom_stop = i + geom_start break species = [line.split()[0] for line in txt[geom_start:geom_stop]] geom = np.array([[float(col) * Bohr for col in line.split()[2:5]] for line in txt[geom_start:geom_stop]]) forces = np.array([[ float(col) * Hartree / Bohr for col in line.split()[2:5] ] for line in txt[geom_stop:geom_stop + (geom_stop - geom_start)]]) image = ase.Atoms(species, geom, cell=cell, pbc=True) image.calc = SinglePointCalculator(atoms=image, energy=energy, forces=forces) traj.append(image) if index is None: return traj else: return traj[index]
def _parse_frame(tree, species): """Parse a certain frame from QBOX output Inputs: tree - ElementTree, <iteration> block from output file species - dict, data about species. Key is name of atom type, value is data about that type Return: Atoms object describing this iteration""" # Load in data about the system energy = float(tree.find("etotal").text) # Load in data about the cell unitcell = tree.find('atomset').find('unit_cell') cell = [] for d in ['a', 'b', 'c']: cell.append([float(x) for x in unitcell.get(d).split()]) stress_tree = tree.find('stress_tensor') if stress_tree is None: stresses = None else: stresses = [ float(stress_tree.find('sigma_%s' % x).text) for x in ['xx', 'yy', 'zz', 'yz', 'xz', 'xy'] ] # Create the Atoms object atoms = Atoms(pbc=True, cell=cell) # Load in the atom information forces = [] for atom in tree.find('atomset').findall('atom'): # Load data about the atom type spec = atom.get('species') symbol = species[spec]['symbol'] mass = species[spec]['mass'] # Get data about position / velocity / force pos = [float(x) for x in atom.find('position').text.split()] force = [float(x) for x in atom.find('force').text.split()] momentum = [ float(x) * mass for x in atom.find('velocity').text.split() ] # Create the objects atom = Atom(symbol=symbol, mass=mass, position=pos, momentum=momentum) atoms += atom forces.append(force) # Create the calculator object that holds energy/forces calc = SinglePointCalculator(atoms, energy=energy, forces=forces, stress=stresses) atoms.set_calculator(calc) return atoms
def insert_atoms( self, bc_kwargs, size=[1,1,1], composition=None, cetype="CEBulk", \ T=None, n_steps_per_temp=10000, eci=None ): """ Insert a new atoms object into the database """ if (composition is None): raise TypeError("No composition given") allowed_ce_types = ["CEBulk", "CECrystal"] if (not cetype in allowed_ce_types): raise ValueError( "cetype has to be one of {}".format(allowed_ce_types)) self.cetype = cetype if (eci is None): raise ValueError( "No ECIs given! Cannot determine required energy range!") if (cetype == "CEBulk"): small_bc = CEBulk(**bc_kwargs) small_bc.reconfigure_settings() elif (ctype == "CECrystal"): small_bc = CECrystal(**bc_kwargs) small_bc.reconfigure_settings() self._check_eci(small_bc, eci) calc = get_ce_calc(small_bc, bc_kwargs, eci=eci, size=size) calc.set_composition(composition) bc = calc.BC bc.atoms.set_calculator(calc) formula = bc.atoms.get_chemical_formula() if (self.template_atoms_exists(formula)): raise AtomExistsError( "An atom object with the specified composition already exists in the database" ) Emin, Emax = self._find_energy_range(bc.atoms, T, n_steps_per_temp) cf = calc.get_cf() data = {"cf": cf} # Store this entry into the database db = connect(self.wl_db_name) scalc = SinglePointCalculator(bc.atoms, energy=Emin) bc.atoms.set_calculator(scalc) outfname = "BC_wanglandau_{}.pkl".format( bc.atoms.get_chemical_formula()) with open(outfname, 'wb') as outfile: pck.dump(bc, outfile) kvp = { "Emin": Emin, "Emax": Emax, "bcfile": outfname, "cetype": self.cetype } data["bc_kwargs"] = bc_kwargs data["supercell_size"] = size db.write(calc.BC.atoms, key_value_pairs=kvp, data=data)
def finalize(atoms, energy=None, forces=None, stress=None): niggli_reduce(atoms) atoms.wrap() calc = SinglePointCalculator(atoms, energy=energy, forces=forces, stress=stress) atoms.calc = calc raw_score = -atoms.get_potential_energy() set_raw_score(atoms, raw_score)
def eval_image(ind): training_image = images[ind].copy() training_image.set_calculator( SinglePointCalculator( atoms=training_image, forces=images[ind].get_forces(apply_constraint=False), energy=images[ind].get_potential_energy())) ml_calc.add_data(training_image)
def single_point(self): results = {} for q in ['energy', 'forces', 'stress', 'xx']: try: results[q] = self.calc.results[q] except KeyError: pass self.set_calculator(SinglePointCalculator(self, **results))
def zmat_relax(self,atoms,nbin=10,relax_step=None, zmat_variable=None,zvlo=None,zvhi=None, traj='zmat.traj',relaxlog = ''): zmatrix = np.array(self.get_zmatrix(atoms)) initz = np.array(self.InitZmat) # target relax_step_ = nbin if relax_step is None else relax_step if not zmat_variable is None: i,j = zmat_variable initz = zmatrix.copy() initz[i][j] = initz[i][j] + zvhi # target zmatrix[i][j] = zmatrix[i][j] + zvlo # starting point: current configration relaxlog += ' ---------------------------\n' relaxlog += ' %d-%d-%d-%d (%d,%d) \n' %(self.zmat_id[i],self.zmat_index[i][0], self.zmat_index[i][1],self.zmat_index[i][2],i,j) relaxlog += ' ---------------------------\n' relaxlog += 'varied from: %8.4f to %8.4f,\n' %(zmatrix[i][j],initz[i][j]) else: relaxlog += 'relax the structure to %d/%d of the initial value ...\n' %(relax_step_,nbin) dz_ = (initz - zmatrix) dz_ = np.where(dz_>180.0,dz_-360.0,dz_) dz = np.where(dz_<-180.0,dz_+360.0,dz_) dz = dz/nbin his = TrajectoryWriter(traj,mode='w') images = [] nb_ = 0 for i_ in range(relax_step_): zmat_ = zmatrix+dz*(i_+1) zmat_ = np.where(zmat_>180.0,zmat_-360.0,zmat_) # scale to a reasonalbale range zmat_ = np.where(zmat_==-180.0,zmat_+0.000001,zmat_) zmat_ = np.where(zmat_==180.0,zmat_-0.000001,zmat_) zmat_ = np.where(zmat_<-180.0,zmat_+360.0,zmat_) # scale to a reasonalbale range atoms = self.zmat_to_cartation(atoms,zmat_) self.ir.calculate(atoms) calc = SinglePointCalculator(atoms,energy=self.ir.E) atoms.set_calculator(calc) his.write(atoms=atoms) images.append(atoms) bonds = getBonds(self.natom,self.ir.r,self.rmax*self.ir.re,self.ir.bo0) newbond,nbd = self.checkBond(bonds) if newbond: iatom,jatom = nbd if nb_ == 0: nbd_ = nbd r_ = self.ir.r[iatom][jatom] else: if nbd==nbd_: if self.ir.r[iatom][jatom]<r_: relaxlog += 'stop at %d/%d because new bond formed ...\n' %(i_,nbin) break r_ = self.ir.r[iatom][jatom] else: relaxlog += 'stop at %d/%d because new bond formed ...\n' %(i_,nbin) break nb_ += 1 his.close() return images,relaxlog
def as_atoms(self): a = self._a.unique().detach().numpy() atoms = (TorchAtoms(numbers=a, positions=len(a) * [(0, 0, 0)]) + TorchAtoms(numbers=self._b.detach().numpy(), positions=self._r.detach().numpy())) if 'target_energy' in self.__dict__: atoms.set_calculator( SinglePointCalculator(atoms, energy=self.target_energy)) return atoms
def repeat_unit_cell(self): for atoms in self: # Get quantities taking into account current repeat():' results = self.repeat_results(atoms, self.repeat.prod(), oldprod=self.repeat.prod()) atoms.cell *= self.repeat.reshape((3, 1)) atoms.calc = SinglePointCalculator(atoms, **results) self.repeat = np.ones(3, int)
def write(self, at, **kwargs): import ase.db from ase.calculators.singlepoint import SinglePointCalculator all_kwargs = self.kwargs.copy() all_kwargs.update(kwargs) all_kwargs.update(at.params) energy = at.params.get('energy', None) forces = getattr(at, 'force', None) if forces is not None: forces = forces.T stress = at.params.get('virial', None) if stress is not None: stress = -stress.view(np.ndarray) / at.get_volume() orig_calc = at.get_calculator() params = {} data = {} skip_params = ['energy', 'virial', 'calculator', 'id', 'unique_id'] # filter out duplicate data for (key, value) in all_kwargs.items(): key = key.lower() if key in skip_params: continue if (isinstance(value, int) or isinstance(value, basestring) or isinstance(value, float) or isinstance(value, bool)): # scalar key/value pairs params[key] = value else: # more complicated data structures data[key] = value skip_arrays = ['numbers', 'positions', 'species'] for (key, value) in at.arrays.items(): if key in skip_arrays: continue key = key.lower() data[key] = value try: calc = SinglePointCalculator(atoms=at, energy=energy, forces=forces, stress=stress) if orig_calc is not None: calc.name = orig_calc.name else: calc.name = all_kwargs.get('calculator', '(unknown)') at.set_calculator(calc) database = ase.db.connect(self.dbfile) database.write(at, key_value_pairs=params, data=data) finally: at.set_calculator(orig_calc)
def linear_correct(training_list, correction_dict, image_index, dataset): # atom_dict = {atom:i for i, atom in enumerate(atom_list)} # atom_dict_rev = {i:atom for i, atom in enumerate(atom_list)} # atom_count_list = [] training_atom_count_list = [] print("start counting atoms") for i, system in enumerate(training_list): temp_atoms = system.get_chemical_symbols() temp_atom_count_dict = {} for atom in temp_atoms: temp_atom_count_dict[atom] = temp_atom_count_dict.get(atom, 0) + 1 training_atom_count_list.append(temp_atom_count_dict) result2 = "" corrected_energy_list = [] atoms_count_list = [] for i, system in enumerate(training_list): energy = system.get_calculator().get_potential_energy() num_atoms = 0 for atom in training_atom_count_list[i].keys(): energy -= training_atom_count_list[i][atom] * correction_dict[atom] num_atoms += training_atom_count_list[i][atom] corrected_energy_list.append(energy) calc = SinglePointCalculator( system, energy=energy, forces=system.get_calculator().get_forces()) system.set_calculator(calc) atoms_count_list.append(num_atoms) corrected_energy_list = np.array(corrected_energy_list) atoms_count_list = np.array(atoms_count_list) corrected_energy_per_atom_list = np.divide(corrected_energy_list, atoms_count_list) result2 += "training me: {}\n".format(np.mean(corrected_energy_list)) result2 += "training mae: {}\n".format( np.mean(np.abs(corrected_energy_list))) result2 += "training mse: {}\n".format( np.mean(np.square(corrected_energy_list))) result2 += "training mepa: {}\n".format( np.mean(corrected_energy_per_atom_list)) result2 += "training maepa: {}\n".format( np.mean(np.abs(corrected_energy_per_atom_list))) result2 += "training msepa: {}\n".format( np.mean(np.square(corrected_energy_per_atom_list))) linear_model_info_filename = "{}_images/linear_model_info_{}.dat".format( dataset, image_index) log(linear_model_info_filename, result2) return training_list
def make_atoms_from_doc(doc, is_initial=False): ''' This is the inversion function for `make_doc_from_atoms`; it takes Mongo documents created by that function and turns them back into an ase.Atoms object. Args: doc Dictionary/json/Mongo document created by the `make_doc_from_atoms` function. Returns: atoms ase.Atoms object with an ase.SinglePointCalculator attached ''' if is_initial: atoms = Atoms([ Atom(atom['symbol'], atom['position'], tag=atom['tag'], momentum=atom['momentum'], magmom=atom['magmom'], charge=atom['charge']) for atom in doc['initial_configuration']['atoms']['atoms'] ], cell=doc['initial_configuration']['atoms']['cell'], pbc=doc['initial_configuration']['atoms']['pbc'], info=doc['initial_configuration']['atoms']['info'], constraint=[ dict2constraint(constraint_dict) for constraint_dict in doc['initial_configuration'] ['atoms']['constraints'] ]) results = doc['initial_configuration']['results'] else: atoms = Atoms([ Atom(atom['symbol'], atom['position'], tag=atom['tag'], momentum=atom['momentum'], magmom=atom['magmom'], charge=atom['charge']) for atom in doc['atoms']['atoms'] ], cell=doc['atoms']['cell'], pbc=doc['atoms']['pbc'], info=doc['atoms']['info'], constraint=[ dict2constraint(constraint_dict) for constraint_dict in doc['atoms']['constraints'] ]) results = doc['results'] calc = SinglePointCalculator(energy=results.get('energy', None), forces=results.get('forces', None), stress=results.get('stress', None), atoms=atoms) atoms.set_calculator(calc) return atoms
def write_optimized(self, atoms, energy): magmoms = None # XXX we could do better ... forces = np.zeros((len(atoms), 3)) calc = SinglePointCalculator(energy, forces, np.zeros((3, 3)), magmoms, atoms) atoms.set_calculator(calc) filename = '%s%s-optimized.traj' % (self.name, self.tag) traj = PickleTrajectory(filename, 'w', backup=False) traj.write(atoms) traj.close()
def repeat_unit_cell(self): for atoms in self: # Get quantities taking into account current repeat(): ref_energy = self.get_energy(atoms) ref_forces = self.get_forces(atoms) atoms.calc = SinglePointCalculator(atoms, energy=ref_energy, forces=ref_forces) atoms.cell *= self.repeat.reshape((3, 1)) self.repeat = np.ones(3, int)
def write_traj(self): if self.traj is not None: energy = self.atoms.calc.results['energy'] forces = np.zeros((len(self.atoms) + len(self.dummies), 3)) forces[:len(self.atoms)] = self.atoms.calc.results['forces'] atoms_tmp = self.atoms + self.dummies atoms_tmp.calc = SinglePointCalculator(atoms_tmp, energy=energy, forces=forces) self.traj.write(atoms_tmp)
def load_data_to_atoms(system_data): atoms_list = [] for i, atom in enumerate(system_data["atoms"]): atoms_list.append(Atom(atom, np.array(system_data["coordinates"][i]))) system = Atoms(atoms_list, cell=[50, 50, 50]) system.center() calc = SinglePointCalculator(system, energy=system_data["corrected_energy"]) system.set_calculator(calc) return system
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 _toatoms(self, include_results=False): if not include_results: return ase.atoms.Atoms( self.numbers, self.positions, cell=self.cell, pbc=(self.pbc & np.array([1, 2, 4])).astype(bool), ) if self.constraints: constraints = json.loads(self.constraints) if len(constraints[0]['kwargs']['indices']) > 0: constraints = [dict2constraint(d) for d in constraints] else: constraints = None atoms = ase.atoms.Atoms(self.numbers, self.positions, cell=self.cell, pbc=(self.pbc & np.array([1, 2, 4])).astype(bool), magmoms=self.magmoms, charges=self.charges, tags=self.tags, masses=self.masses, momenta=self.momenta, constraint=constraints) if not self.calculator == "unknown": params = self.get('calculator_parameters', {}) atoms.calc = get_calculator(self.calculator)(**params) else: all_properties = [ 'energy', 'forces', 'stress', 'dipole', 'charges', 'magmom', 'magmoms', 'free_energy' ] results = {} #print(getattr(self, 'energy')) for prop in all_properties: result = getattr(self, prop, None) if result is not None: results[prop] = result # print(results) if results: atoms.calc = SinglePointCalculator(atoms, **results) atoms.calc.name = getattr(self, 'calculator', 'unknown') atoms.info = {} atoms.info['unique_id'] = self.unique_id atoms.info['key_value_pairs'] = self.key_value_pairs data = self.data if data: atoms.info['data'] = data return atoms
def read_gamess_us_out(fd): atoms = None energy = None forces = None dipole = None for line in fd: # Geometry if _geom_re.match(line): fd.readline() symbols = [] pos = [] while True: atom = _atom_re.match(fd.readline()) if atom is None: break symbol, _, x, y, z = atom.groups() symbols.append(symbol.capitalize()) pos.append(list(map(float, [x, y, z]))) atoms = Atoms(symbols, np.array(pos) * Bohr) continue # Energy ematch = _energy_re.match(line) if ematch is not None: energy = float(ematch.group(1)) * Hartree # MPn energy. Supplants energy parsed above. elif line.strip().startswith('TOTAL ENERGY'): energy = float(line.strip().split()[-1]) * Hartree # Higher-level energy (e.g. coupled cluster) # Supplants energies parsed above. elif line.strip().startswith('THE FOLLOWING METHOD AND ENERGY'): energy = float(fd.readline().strip().split()[-1]) * Hartree # Gradients elif _grad_re.match(line): for _ in range(3): fd.readline() grad = [] while True: atom = _atom_re.match(fd.readline()) if atom is None: break grad.append(list(map(float, atom.groups()[2:]))) forces = -np.array(grad) * Hartree / Bohr elif _dipole_re.match(line): dipole = np.array(list(map(float, fd.readline().split()[:3]))) dipole *= Debye atoms.calc = SinglePointCalculator(atoms, energy=energy, forces=forces, dipole=dipole) return atoms
def finalize(atoms, energy=None, forces=None, stress=None): # Finalizes the atoms by attaching a SinglePointCalculator # and setting the raw score as the negative of the total energy atoms.wrap() calc = SinglePointCalculator(atoms, energy=energy, forces=forces, stress=stress) atoms.set_calculator(calc) raw_score = -atoms.get_potential_energy() set_raw_score(atoms, raw_score)
def add(self, data): from ase import Atoms from ase.calculators.singlepoint import SinglePointCalculator atoms = Atoms(data['elems'], cell=data['cell'], positions=data['coord']) atoms.calc = SinglePointCalculator(atoms=atoms, energy=data['e_data'], forces=data['f_data']) atoms.pbc = True self.traj.append(atoms)
def singlePoint(self, anew): a = anew.copy() # Save structure with ML-energy if self.master: self.writer_spPredict.write(a) #self.writer_spPredict.write(a) # broadcast structure, so all cores have the same pos = a.positions if self.master: pos = a.positions self.comm.broadcast(pos, 0) a.positions = pos self.comm.barrier() # Perform single-point - With error handling E = np.zeros(1) F = np.zeros((self.Natoms,3)) try: error_int = np.array([0]).astype(int) if self.master: label = self.traj_namebase + '{}'.format(self.traj_counter) E, F = singleGPAW(a, label, calc=self.calc) E = np.array([E]) except Exception as runtime_err: error_int = np.array([1]).astype(int) print('Error cought:', runtime_err) world.barrier() self.comm.broadcast(error_int, 0) if error_int[0]==1: raise RuntimeError('DFTB failed') world.barrier() self.comm.broadcast(E, 0) E = E[0] self.comm.broadcast(F, 0) # save structure for training a.energy = E results = {'energy': E, 'forces': F} calc = SinglePointCalculator(a, **results) a.set_calculator(calc) self.a_add.append(a) self.a_all.append(a) # Save to spTrain-trajectory self.writer_spTrain.write(a, energy=E, forces=F) self.traj_counter += 1 return E, F
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() 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]) ]] 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
def readposcars(poscars,energies='goodStructures'): ''' read POSCARS generated by USPEX''' f = open(poscars,'r') lines = f.readlines() f.close() f = open(energies,'r') linee = f.readlines() f.close() e = [] for i,le in enumerate(linee): if i>1: e.append(float(le.split()[-4])) l = lines[6].split() natom = 0 for i in l: natom += int(i) nstru = len(lines)/(natom+8) traj = TrajectoryWriter('strucs.traj',mode='w') for i in range(nstru): nl = i*(natom+8) cl1 = lines[nl+2].split() cl2 = lines[nl+3].split() cl3 = lines[nl+4].split() cell = [[float(cl1[0]),float(cl1[1]),float(cl1[2])], [float(cl2[0]),float(cl2[1]),float(cl2[2])], [float(cl3[0]),float(cl3[1]),float(cl3[2])]] cell = np.array(cell) anl = lines[nl+5].split() nsl = lines[nl+6].split() atom_name = [] for i_,sp in enumerate(anl): atom_name.extend([sp]*int(nsl[i_])) xf = [] for na in range(natom): xl = lines[nl+8+na].split() xf.append([float(xl[0]),float(xl[1]),float(xl[2])]) xf = np.array(xf) x = np.dot(xf,cell) A = Atoms(atom_name,x,cell=cell,pbc=[True,True,True]) calc = SinglePointCalculator(A,energy=e[i]) # print(e[i]) A.set_calculator(calc) traj.write(atoms=A) traj.close()
def calculate_and_hide(i): image = self.images[i] calc = image.get_calculator() if self.calculators[i] is None: self.calculators[i] = calc if calc is not None: if not isinstance(calc, SinglePointCalculator): self.images[i].set_calculator( SinglePointCalculator(image.get_potential_energy(), image.get_forces(), None, None, image)) self.emax = min(self.emax, image.get_potential_energy())
def read_geom(filename, _=-1): """Reads a .geom file produced by the CASTEP GeometryOptimization task and returns an atoms object. The information about total free energy and forces of each atom for every relaxation step will be stored for further analysis especially in a single-point calculator. Note that everything in the .geom file is in atomic units, which has been conversed to commonly used unit angstrom(length) and eV (energy). Note that the index argument has no effect as of now. Contribution by Wei-Bing Zhang. Thanks! """ from ase.calculators.singlepoint import SinglePointCalculator fileobj = open(filename) txt = fileobj.readlines() fileobj.close() traj = [] # Source: CODATA2002, used by default # in CASTEP 5.01 # but check with your version in case of error # ase.units is based on CODATA1986/ # here we hard-code from http://physics.nist.gov/cuu/Document/all_2002.pdf Hartree = 27.211384565719481 Bohr = 0.5291772108 print('N.B.: Energy in .geom file is not 0K extrapolated.') for i, line in enumerate(txt): if line.find("<-- E") > 0: start_found = True energy = float(line.split()[0]) * Hartree cell = [x.split()[0:3] for x in txt[i + 1:i + 4]] cell = array([[float(col) * Bohr for col in row] for row in cell]) if line.find('<-- R') > 0 and start_found: start_found = False geom_start = i for i, line in enumerate(txt[geom_start:]): if line.find('<-- F') > 0: geom_stop = i + geom_start break species = [line.split()[0] for line in txt[geom_start:geom_stop]] geom = array([[float(col) * Bohr for col in line.split()[2:5]] for line in txt[geom_start:geom_stop]]) forces = array([[ float(col) * Hartree / Bohr for col in line.split()[2:5] ] for line in txt[geom_stop:geom_stop + (geom_stop - geom_start)]]) image = ase.Atoms(species, geom, cell=cell, pbc=True) image.set_calculator( SinglePointCalculator(energy, forces, None, None, image)) traj.append(image) return traj
def compute(self, atoms): if 'pyscf.chkpt' in os.listdir('.') and self.skip_calculated: print('Re-using results') mol, results = load_scf('pyscf.chkpt') e = results['e_tot'] else: mf, mol = compute_KS(atoms, basis=self.basis, xc=self.xc, nxc=self.nxc, **self.engine_kwargs) e = mf.energy_tot() atoms.calc = SinglePointCalculator(atoms) atoms.calc.results = {'energy': e * Hartree} return atoms
def __getitem__(self, i=-1): if isinstance(i, slice): return [self[j] for j in range(*i.indices(len(self)))] N = len(self.offsets) if 0 <= i < N: self.fd.seek(self.offsets[i]) try: d = pickle.load(self.fd, encoding='bytes') d = { k.decode() if isinstance(k, bytes) else k: v for k, v in d.items() } except EOFError: raise IndexError if i == N - 1: self.offsets.append(self.fd.tell()) charges = d.get('charges') magmoms = d.get('magmoms') try: constraints = [c.copy() for c in self.constraints] except: constraints = [] warnings.warn('Constraints did not unpickle correctly.') atoms = Atoms(positions=d['positions'], numbers=self.numbers, cell=d['cell'], momenta=d['momenta'], magmoms=magmoms, charges=charges, tags=self.tags, masses=self.masses, pbc=self.pbc, info=unstringnify_info(d.get('info', {})), constraint=constraints) if 'energy' in d: calc = SinglePointCalculator(atoms, energy=d.get('energy', None), forces=d.get('forces', None), stress=d.get('stress', None), magmoms=magmoms) atoms.set_calculator(calc) return atoms if i >= N: for j in range(N - 1, i + 1): atoms = self[j] return atoms i = len(self) + i if i < 0: raise IndexError('Trajectory index out of range.') return self[i]
def snapshot(self, fake=False, copy=None): if copy is None: copy = self.atoms.copy() if fake: energy = self.results['energy'] forces = self.results['forces'] else: energy, forces = self._exact(copy) copy.set_calculator( SinglePointCalculator(copy, energy=energy, forces=forces)) copy.set_targets() return copy