def batch_to_atoms(batch): n_systems = batch.neighbors.shape[0] natoms = batch.natoms.tolist() numbers = torch.split(batch.atomic_numbers, natoms) fixed = torch.split(batch.fixed, natoms) forces = torch.split(batch.force, natoms) positions = torch.split(batch.pos, natoms) tags = torch.split(batch.tags, natoms) cells = batch.cell energies = batch.y.tolist() atoms_objects = [] for idx in range(n_systems): atoms = Atoms( numbers=numbers[idx].tolist(), positions=positions[idx].cpu().detach().numpy(), tags=tags[idx].tolist(), cell=cells[idx].cpu().detach().numpy(), constraint=FixAtoms(mask=fixed[idx].tolist()), pbc=[True, True, True], ) calc = sp( atoms=atoms, energy=energies[idx], forces=forces[idx].cpu().detach().numpy(), ) atoms.set_calculator(calc) atoms_objects.append(atoms) return atoms_objects
def convert_to_singlepoint(images): """ Replaces the attached calculators with singlepoint calculators Parameters ---------- images: list List of ase atoms images with attached calculators for forces and energies. """ images = copy_images(images) singlepoint_images = [] cwd = os.getcwd() for image in images: os.makedirs("./temp", exist_ok=True) os.chdir("./temp") sample_energy = image.get_potential_energy(apply_constraint=False) sample_forces = image.get_forces(apply_constraint=False) image.set_calculator( sp(atoms=image, energy=float(sample_energy), forces=sample_forces)) singlepoint_images.append(image) os.chdir(cwd) os.system("rm -rf ./temp") return singlepoint_images
def calculate(atoms): with tempfile.TemporaryDirectory() as tmp_dir: atoms.get_calculator().set(directory=tmp_dir) sample_energy = atoms.get_potential_energy(apply_constraint=False) sample_forces = atoms.get_forces(apply_constraint=False) atoms.set_calculator( sp(atoms=atoms, energy=sample_energy, forces=sample_forces)) return atoms
def minimize(clus,calc): ''' Cluster relaxation ''' clus.calc = copy.deepcopy(calc) with tempfile.TemporaryDirectory() as tmp_dir: clus.get_calculator().set(directory=tmp_dir) #dyn = BFGS(clus,logfile = None) #dyn.run(fmax = 0.05,steps = 1000) energy = clus.get_potential_energy() clus.set_calculator(sp(atoms=clus, energy=energy)) return clus
def minimize_vasp(clus, calc): """ Cluster relaxation function for using the inbuilt VASP optimizer All files related to the vasp run (INCAR,OUTCAR etc) are stored in a temporary directory """ clus.calc = calc with tempfile.TemporaryDirectory() as tmp_dir: clus.get_calculator().set(directory=tmp_dir) energy = clus.get_potential_energy() clus.set_calculator(sp(atoms=clus, energy=energy)) return clus
def test_fp_match(): for i in range(100): # Tests whether the generated fingerprints are consistent with that of AMPs atoms = molecule("H2O") atoms.set_cell([10, 10, 10]) atoms.set_pbc = [True] * 3 atoms.set_calculator( sp(atoms=atoms, energy=-1, forces=np.array([[-1, -1, -1], [-1, -1, -1]])) ) Gs = {} images = [atoms] Gs["G2_etas"] = [0.005] * 2 Gs["G2_rs_s"] = [0] * 2 Gs["G4_etas"] = [0.005] * 2 Gs["G4_zetas"] = [1.0, 4.0] Gs["G4_gammas"] = [1.0, -1.0] Gs["cutoff"] = 6.5 elements = list( sorted(set([atom.symbol for atoms in images for atom in atoms])) ) G = make_symmetry_functions(elements=elements, type="G2", etas=Gs["G2_etas"]) G += make_symmetry_functions( elements=elements, type="G4", etas=Gs["G4_etas"], zetas=Gs["G4_zetas"], gammas=Gs["G4_gammas"], ) G = {"O": G, "H": G} hashes = stock_hash(images) amp_hash = list(hashes.keys())[0] make_amp_descriptors_simple_nn(images, Gs, cores=1, label='test', elements=elements) s_nn_hash = list(new_hash(images, Gs).keys())[0] with open("amp-data-fingerprints.ampdb/loose/" + s_nn_hash, "rb") as f: simple_nn = load(f) os.system("rm amp-data-fingerprints.ampdb/loose/" + s_nn_hash) descriptor = Gaussian(elements=elements, Gs=G, cutoff=Cosine(Gs["cutoff"])) descriptor.calculate_fingerprints(hashes, calculate_derivatives=True) with open("amp-data-fingerprints.ampdb/loose/" + amp_hash, "rb") as f: amp = load(f) os.system("rm amp-data-fingerprints.ampdb/loose/" + amp_hash) for s, am in zip(simple_nn, amp): for i, j in zip(s[1], am[1]): assert abs(i - j) <= 1e-5, "Fingerprints do not match!"
def convert_to_singlepoint(images): """ Replaces the attached calculators with singlepoint calculators Parameters ---------- images: list List of ase atoms images with attached calculators for forces and energies. """ images = copy_images(images) singlepoint_images = [] # cwd = os.getcwd() for image in images: if isinstance(image.get_calculator(), sp): singlepoint_images.append(image) continue # os.makedirs("./vasp_temp", exist_ok=True) # os.chdir("./vasp_temp") sample_energy = image.get_potential_energy(apply_constraint=False) sample_forces = image.get_forces(apply_constraint=False) if isinstance(image.get_calculator(), DeltaCalc): image.info["parent energy"] = image.get_calculator( ).parent_results["energy"] image.info["base energy"] = image.get_calculator( ).base_results["energy"] image.info["parent fmax"] = np.max( np.abs(image.get_calculator().parent_results["forces"])) sp_calc = sp(atoms=image, energy=float(sample_energy), forces=sample_forces) sp_calc.implemented_properties = ["energy", "forces"] image.set_calculator(sp_calc) # image.get_potential_energy() # image.get_forces() # image.calc.results["energy"] = float(image.calc.results["energy"]) # sp_calc = sp(atoms=image, **image.calc.results) # sp_calc.implemented_properties = list(image.calc.results.keys()) # image.set_calculator(sp_calc) singlepoint_images.append(image) # os.chdir(cwd) # os.system("rm -rf ./vasp_temp") return singlepoint_images
def convert_to_top_k_forces(images, k): images = copy_images(images) singlepoint_images = [] for image in images: top_k = np.sqrt((image.get_forces()**2).sum(axis=1)) threshold = np.partition(top_k, -k)[-k] top_k[top_k < threshold] = 0 top_k[top_k >= threshold] = 1 top_k_forces = (image.get_forces().T * top_k).T sp_calc = sp(atoms=image, energy=float(image.get_potential_energy()), forces=top_k_forces) sp_calc.implemented_properties = ["energy", "forces"] image.set_calculator(sp_calc) singlepoint_images.append(image) return singlepoint_images
def minimize(clus, calculator, optimizer, vasp_inter): """ Cluster relaxation using an ase optimizer Refer https://wiki.fysik.dtu.dk/ase/ase/optimize.html for a list of possible optimizers Recommended optimizer with VASP is GPMin """ if vasp_inter == True: with calculator as calc: clus.calc = calculator with tempfile.TemporaryDirectory() as tmp_dir: clus.get_calculator().set(directory=tmp_dir) dyn = optimizer(clus, logfile=None) dyn.run(fmax=0.05, steps=2000) energy = clus.get_potential_energy() else: clus.calc = calculator with tempfile.TemporaryDirectory() as tmp_dir: clus.get_calculator().set(directory=tmp_dir) dyn = optimizer(clus, logfile=None) dyn.run(fmax=0.05, steps=1000) energy = clus.get_potential_energy() clus.set_calculator(sp(atoms=clus, energy=energy)) return clus
def calculate(self, atoms, properties, system_changes): Calculator.calculate(self, atoms, properties, system_changes) energy_pred = self.ensemble_calc.get_potential_energy(atoms) force_pred = self.ensemble_calc.get_forces(atoms) uncertainty = atoms.info["uncertainty"][0] db = connect('dft_calls.db') cwd = os.getcwd() if uncertainty >= self.uncertain_tol: print('DFT required') new_data = atoms.copy() new_data.set_calculator(copy.copy(self.parent_calc)) # os.makedirs("./temp", exist_ok=True) # os.chdir("./temp") energy_pred = new_data.get_potential_energy(apply_constraint=False) force_pred = new_data.get_forces(apply_constraint=False) new_data.set_calculator( sp(atoms=new_data, energy=energy_pred, forces=force_pred)) # os.chdir(cwd) # os.system("rm -rf ./temp") energy_list.append(energy_pred) db.write(new_data) self.ensemble_sets, self.parent_dataset = bootstrap_ensemble( self.parent_dataset, self.ensemble_sets, new_data=new_data) self.ensemble_calc = make_ensemble(self.ensemble_sets, self.trainer, self.base_calc, self.refs, self.n_cores) self.parent_calls += 1 else: db.write(None) self.results["energy"] = energy_pred self.results["forces"] = force_pred
kpts=(1, 1, 1)) # Define initial set of images, can be as few as 1. If 1, make sure to slab = fcc100("Cu", size=(3, 3, 3)) ads = molecule("CO") add_adsorbate(slab, ads, 3, offset=(1, 1)) cons = FixAtoms(indices=[atom.index for atom in slab if (atom.tag == 3)]) slab.set_constraint(cons) slab.center(vacuum=13.0, axis=2) slab.set_pbc(True) slab.wrap(pbc=True) slab.set_calculator(copy.copy(dft_calc)) sample_energy = slab.get_potential_energy(apply_constraint=False) sample_forces = slab.get_forces(apply_constraint=False) slab.set_calculator( sp(atoms=slab, energy=sample_energy, forces=sample_forces)) ase.io.write("./slab.traj", slab) images = [slab] # Define symmetry functions Gs = {} Gs["G2_etas"] = np.logspace(np.log10(0.05), np.log10(5.0), num=4) Gs["G2_rs_s"] = [0] * 4 Gs["G4_etas"] = [0.005] Gs["G4_zetas"] = [1.0, 4.0] Gs["G4_gammas"] = [+1.0, -1] Gs["cutoff"] = 6.0 training_params = { "al_convergence": {
from ase.build import molecule from ase.calculators.singlepoint import SinglePointCalculator as sp from amp_simple_nn.convert import make_amp_descriptors_simple_nn import numpy as np atoms = molecule('O2') atoms.set_cell([10,10,10]) print(atoms.positions) atoms.set_calculator(sp(atoms=atoms, energy = -1, forces = np.array([[-1,-1,-1],[-1,-1,-1]]))) images = [atoms] g2_etas = [0.005] g2_rs_s = [0] * 4 g4_etas = [0.005] g4_zetas = [1., 4.] g4_gammas = [1., -1.] cutoff = 4 make_amp_descriptors_simple_nn(images,g2_etas,g2_rs_s,g4_etas, g4_zetas,g4_gammas,cutoff)
from amp import Amp from ase.io import read, write from amp.model.neuralnetwork import NeuralNetwork from amp.descriptor.gaussian import Gaussian, make_symmetry_functions from amp.model import LossFunction from ase.build import molecule from ase.calculators.singlepoint import SinglePointCalculator as sp from amp_simple_nn.convert import make_amp_descriptors_simple_nn import numpy as np atoms = molecule('O2') atoms.set_cell([10, 10, 10]) atoms.set_calculator( sp(atoms=atoms, energy=-1, forces=np.array([[-1, -1, -1], [-1, -1, -1]]))) #Convergence parameters energy_rmse = 0.0001 force_rmse = 0.01 energy_maxresid = None force_maxresid = None convergence = { 'energy_rmse': energy_rmse, 'force_rmse': force_rmse, 'energy_maxresid': energy_maxresid, 'force_maxresid': force_maxresid } ncores = 1 hiddenlayers = (5, 5) elements = atoms.get_chemical_symbols()