def systems_minimum(): """two atoms at potential minimum""" atoms = Atoms('H2', positions=[[0, 0, 0], [0, 0, 2**(1.0 / 6.0)]]) calc = LennardJones(rc=1.0e5) atoms.calc = calc yield atoms calc = LennardJones(rc=1.0e5, smooth=True) atoms.calc = calc yield atoms
def calculate(self, atoms=None, properties=['energy'], system_changes=all_changes): LennardJones.calculate(self, atoms, properties, system_changes) if 'forces' in self.results: self.results['forces'] += 1e-4 * self.rng.normal( size=self.results['forces'].shape, ) if 'stress' in self.results: self.results['stress'] += 1e-4 * self.rng.normal( size=self.results['stress'].shape, )
def calculate(self, atoms=None, properties=['energy'], system_changes=all_changes): LennardJones.calculate(self, atoms, properties, system_changes) natoms = len(self.atoms) epsilon = self.parameters.epsilon sigma = self.parameters.sigma k = self.parameters.k r0 = self.parameters.r0 rc = self.parameters.rc if rc is None: rc = 3 * r0 energy = 0.0 forces = np.zeros((natoms, 3)) stress = np.zeros((3, 3)) tags = self.atoms.get_tags() for tag in np.unique(tags): # Adding (intramolecular) harmonic potential part indices = np.where(tags == tag)[0] assert len(indices) == 2 a1, a2 = indices d = self.atoms.get_distance(a1, a2, mic=True, vector=True) r = np.linalg.norm(d) energy += 0.5 * k * (r - r0) ** 2 f = -k * (r - r0) * d forces[a1] -= f forces[a2] += f stress += np.dot(np.array([f]).T, np.array([d])) # Substracting intramolecular LJ part r2 = r ** 2 c6 = (sigma**2 / r2)**3 c12 = c6 ** 2 energy += -4 * epsilon * (c12 - c6).sum() f = (24 * epsilon * (2 * c12 - c6) / r2) * d forces[a1] -= -f forces[a2] += -f stress += -np.dot(np.array([f]).T, np.array([d])) if 'stress' in properties: stress += stress.T.copy() stress *= -0.5 / self.atoms.get_volume() self.results['stress'] += stress.flat[[0, 4, 8, 5, 2, 1]] self.results['energy'] += energy self.results['free_energy'] += energy self.results['forces'] += forces
def test_basin(): # Global minima from # Wales and Doye, J. Phys. Chem. A, vol 101 (1997) 5111-5116 E_global = {4: -6.000000, 5: -9.103852, 6: -12.712062, 7: -16.505384} N = 7 R = N**(1. / 3.) np.random.seed(42) pos = np.random.uniform(-R, R, (N, 3)) s = Atoms('He' + str(N), positions=pos) s.calc = LennardJones() original_positions = 1. * s.get_positions() ftraj = 'lowest.traj' for GlobalOptimizer in [ BasinHopping(s, temperature=100 * kB, dr=0.5, trajectory=ftraj, optimizer_logfile=None) ]: if isinstance(GlobalOptimizer, BasinHopping): GlobalOptimizer.run(10) Emin, smin = GlobalOptimizer.get_minimum() else: GlobalOptimizer(totalsteps=10) Emin = s.get_potential_energy() smin = s print("N=", N, 'minimal energy found', Emin, ' global minimum:', E_global[N]) # recalc energy smin.calc = LennardJones() E = smin.get_potential_energy() assert abs(E - Emin) < 1e-15 other = read(ftraj) E2 = other.get_potential_energy() assert abs(E2 - Emin) < 1e-15 # check that only minima were written last_energy = None for im in io.read(ftraj, index=':'): energy = im.get_potential_energy() if last_energy is not None: assert energy < last_energy last_energy = energy # reset positions s.set_positions(original_positions)
def atoms(rc=1.0e5): """parametrized Atoms object with Calculator attached ready for testing""" atoms = Atoms("H2", positions=[[0, 0, 0], [0, 0, 2**(1.0 / 6.0)]]) calc = LennardJones(rc=rc) atoms.calc = calc return atoms
def test_precon_amin(): cu0 = bulk("Cu") * (2, 2, 2) sigma = cu0.get_distance(0, 1) * (2.**(-1. / 6)) lj = LennardJones(sigma=sigma) # perturb the cell cell = cu0.get_cell() cell *= 0.95 cell[1, 0] += 0.2 cell[2, 1] += 0.5 cu0.set_cell(cell, scale_atoms=True) energies = [] for use_armijo in [True, False]: for a_min in [None, 1e-3]: atoms = cu0.copy() atoms.calc = lj opt = PreconLBFGS(atoms, precon=Exp(A=3), use_armijo=use_armijo, a_min=a_min, variable_cell=True) opt.run(fmax=1e-3, smax=1e-4) energies.append(atoms.get_potential_energy()) # check we get the expected energy for all methods assert np.abs(np.array(energies) - -63.5032311942).max() < 1e-4
def getValues(position): # Create positions array array = [] for i in range(len(position) // 3): line = [0, 0, 0] line[0] = position[3 * i] line[1] = position[3 * i + 1] line[2] = position[3 * i + 2] array.append(line) # troubleshooting #print(array) # Set up calculator calc = LennardJones() # load atoms object p = ase.Atoms('Pt' + str(len(position) // 3), positions=array) # Set Calculator p.set_calculator(calc) # Forces are the first 3N values of the list array2, and the potential energy is the final value forces = p.get_forces() array2 = [] for i in range(len(position) // 3): for j in range(3): array2.append(forces[i][j]) array2.append(p.get_potential_energy()) #array2.append(p.get_potential_energy()) return array2
def create_2d_square_data(ndata, size, dbname): sigma = 1.0 d = 2 ** (1 / 6) * sigma assert type(size) is int positions = np.zeros((size ** 2, 3)) x = np.array(range(size)) * d x1, x2 = np.meshgrid(x, x) positions[:, 0] = x1.reshape(-1) positions[:, 1] = x2.reshape(-1) cell = [size * d, size * d, 0] init_atoms = Atoms("H{}".format(size ** 2), positions=positions, cell=cell, pbc=[1,1,0]) calculator = LennardJones(sigma=sigma) init_atoms.set_calculator(calculator) dbname = dbname if dbname.endswith(".db") else dbname + ".db" with connect(dbname) as db: for _ in range(ndata): atoms = deepcopy(init_atoms) disp = get_random_displacement(size, d) atoms.set_positions(atoms.positions + disp) db.write( atoms, data={ "energy": atoms.get_total_energy(), "forces": atoms.get_forces(), "displacements": disp, }, )
def __init__(self, doc, queue, calculator=None): """ Initialise a relaxation with ASE. Parameters: doc (dict): the structure to optimise. queue (mp.Queue): the queue to push the result to. Keyword arguments: calculator (ase.Calculator): the calculator object to use for force/energy computation. Default is LennardJones. """ from copy import deepcopy from matador.utils.viz_utils import doc2ase from ase.constraints import UnitCellFilter if calculator is None: from ase.calculators.lj import LennardJones self.calc = LennardJones() else: self.calc = calculator self.doc = deepcopy(doc) self.atoms = doc2ase(doc) self.atoms.set_calculator(self.calc) self.ucf = UnitCellFilter(self.atoms) self.queue = queue
def test_atoms(paper): # from aflow import K # import aflow.keywords_json as K from aflow import K paper.reset_iter() from ase.calculators.lj import LennardJones from ase.atoms import Atoms LJ = LennardJones() kw = {} kw[K.energy_cell] = "dft_energy" rawentry = paper[2] at = rawentry.atoms(keywords=kw, calculator=LJ) assert isinstance(at, Atoms) assert isinstance(at.get_total_energy(), float) assert "dft_energy" in at.results assert at.results["dft_energy"] == rawentry.energy_cell at0 = rawentry.atoms(keywords=kw, calculator=LJ) assert at0 == at at2 = paper[2].atoms(calculator=LJ) assert not hasattr(at2, "results")
def getLJeigenvaluesB(X, S, epsilon, sigma, rc, getForceMatrix): from ase import Atoms from ase.build import bulk from ase.calculators.lj import LennardJones from ase.phonons import Phonons import numpy as np from scipy import linalg as LA calc = LennardJones(sigma=sigma, epsilon=epsilon, rc=rc) # chemStr = 'H' + str(len(X)) # atoms = Atoms(chemStr, X, calculator=calc ) atoms = Atoms(getChemStr(S), X, calculator=calc) energy = atoms.get_potential_energy() eig = [] if getForceMatrix: ph = Phonons(atoms, calc) ph.run() ph.read(acoustic=True) ph.clean() f = ph.get_force_constant() (l, m, n) = f.shape if l == 1: ff = np.reshape(f, (m, n)) else: print("error") # eig = LA.eigvalsh(ff) # eig is a numpy array # return energy, [float("{0:.5f}".format(eig[i])) for i in range(len(eig))]
def test_fix_bond_length_mic(): import ase from ase.calculators.lj import LennardJones from ase.constraints import FixBondLength from ase.optimize import FIRE for wrap in [False, True]: a = ase.Atoms('CCC', positions=[[1, 0, 5], [0, 1, 5], [-1, 0.5, 5]], cell=[10, 10, 10], pbc=True) if wrap: a.set_scaled_positions(a.get_scaled_positions() % 1.0) a.calc = LennardJones() a.set_constraint(FixBondLength(0, 2)) d1 = a.get_distance(0, 2, mic=True) FIRE(a, logfile=None).run(fmax=0.01) e = a.get_potential_energy() d2 = a.get_distance(0, 2, mic=True) assert abs(e - -2.034988) < 1e-6 assert abs(d1 - d2) < 1e-6
def __init__(self, path, pot, aseStruct): self.path = path self.pot = pot # # path should not end in '/' # make these variables global: epsilon = 0.1 sigma = 2.5 rcut = 7.50 aCell = 15.0 # defining dictionary of Z:LAMMPStype atom_types = {} listZ = list(set(aseStruct.get_atomic_numbers())) # [ (j, i+1) for i,j in enumerate( list(set(aseStruct.get_atomic_numbers())) )] for i in range(len(listZ)): atom_types[listZ[i]] = i + 1 # # path = '/Users/chinchay/Documents/9_Git/reverseEnergyPartitioning' log_file = path + "/log.txt" if pot == "aseLJ": from ase.calculators.lj import LennardJones self.calc = LennardJones(sigma=sigma, epsilon=epsilon, rc=rc) else: from lammpslib import LAMMPSlib cmds = [ "pair_style mlip " + path + "/" + pot, "pair_coeff * * " ] # lammps_header = [ "units metal"] <<< it does not work in definition of mylammps. Verify code # print(atom_types) # self.mylammps self.calc = LAMMPSlib(lmpcmds=cmds, atom_types=atom_types, keep_alive=True, log_file=log_file)
def atoms(): """two atoms at potential minimum""" atoms = bulk('X', 'fcc', a=a0) atoms.calc = LennardJones() return atoms
def evaluate(self, imember): entry = self.population.get_entry(imember) pcm_structure = pychemia.Structure.from_dict(entry['structure']) ase_structure = pychemia.external.ase.pychemia2ase(pcm_structure) ase_structure.set_calculator(LennardJones()) dyn = QuasiNewton(ase_structure) dyn.run() ase_structure.set_constraint( FixAtoms(mask=[True for atom in ase_structure])) ucf = UnitCellFilter(ase_structure) qn = QuasiNewton(ucf) qn.run() new_structure = pychemia.external.ase.ase2pychemia(ase_structure) energy = ase_structure.get_potential_energy() forces = ase_structure.get_forces() stress = ase_structure.get_stress() new_properties = { 'energy': float(energy), 'forces': generic_serializer(forces), 'stress': generic_serializer(stress) } self.population.db.update(imember, structure=new_structure, properties=new_properties)
def qe_calc(): from ase.calculators.lj import LennardJones dft_calculator = LennardJones() yield dft_calculator del dft_calculator
def systems_bulk(): atoms = bulk("Ar", cubic=True) atoms.set_cell(atoms.cell * stretch, scale_atoms=True) calc = LennardJones(rc=10) atoms.calc = calc yield atoms atoms = bulk("Ar", cubic=True) atoms.set_cell(atoms.cell * stretch, scale_atoms=True) # somewhat hand-picked parameters, but ok for comparison calc = LennardJones(rc=12, ro=10, smooth=True) atoms.calc = calc yield atoms
def calculator(self): """The calculator to use when evaluating the objective function""" if self._calculator is None: self._calculator = LennardJones() if self.verbose: print("BASC: Using Lennard-Jones calculator!") return self._calculator
def qe_calc(): from ase.calculators.lj import LennardJones dft_calculator = LennardJones() dft_calculator.parameters.sigma = 3.0 dft_calculator.parameters.rc = 3 * dft_calculator.parameters.sigma yield dft_calculator del dft_calculator
def test_unitcellfilterpressure(): a0 = bulk('Cu', cubic=True) # perturb the atoms s = a0.get_scaled_positions() s[:, 0] *= 0.995 a0.set_scaled_positions(s) # perturb the cell a0.cell[...] += np.random.uniform(-1e-2, 1e-2, size=9).reshape((3, 3)) atoms = a0.copy() atoms.calc = LennardJones() ucf = UnitCellFilter(atoms, scalar_pressure=10.0 * GPa) # test all derivatives f, fn = gradient_test(ucf) assert abs(f - fn).max() < 1e-6 opt = FIRE(ucf) opt.run(1e-3) # check pressure is within 0.1 GPa of target sigma = atoms.get_stress() / GPa pressure = -(sigma[0] + sigma[1] + sigma[2]) / 3.0 assert abs(pressure - 10.0) < 0.1 atoms = a0.copy() atoms.calc = LennardJones() ecf = ExpCellFilter(atoms, scalar_pressure=10.0 * GPa) # test all deritatives f, fn = gradient_test(ecf) assert abs(f - fn).max() < 1e-6 opt = LBFGSLineSearch(ecf) opt.run(1e-3) # check pressure is within 0.1 GPa of target sigma = atoms.get_stress() / GPa pressure = -(sigma[0] + sigma[1] + sigma[2]) / 3.0 assert abs(pressure - 10.0) < 0.1
def setUp(self): """ builds the test case. Test the order=1 structure manager implementation against a triclinic crystal. """ self.calc = LennardJones() self.error_threshold = 1e-8 # test file contains a reduced selection of self.kernel_input_filename = ( "reference_data/tests_only/sparse_kernel_inputs.json") # only some inputs are selected from the test inputs to reduce test time self.selected_test_indices = [0, 1] self.matrix_indices_in_voigt_notation = [ (0, 0), (1, 1), (2, 2), (1, 2), (0, 2), (0, 1), ]
def __init__(self, atoms, calc=LennardJones(), moving=None): # We are going to repeatedly set_positions() for this # instance, So we make a copy to avoid effects visible # outside: self.atoms = atoms.copy() # FIXME: should we assume atoms were already associated with a # calculator instead of using LJ as default? self.atoms.set_calculator(calc) # list of moving atoms whose coordinates are considered as # variables: self.moving = moving
def setup_atoms(): rng = np.random.RandomState(1) a0 = bulk('Cu', cubic=True) # perturb the atoms s = a0.get_scaled_positions() s[:, 0] *= 0.995 a0.set_scaled_positions(s) # perturb the cell a0.cell += rng.uniform(-1e-1, 1e-2, size=(3, 3)) a0.set_calculator(LennardJones()) return a0
def test_finite_difference(): # ensure that we got the modified forces right h = 1e-10 r = 8.0 calc = LennardJones(smooth=True, ro=6, rc=10, sigma=3) atoms = Atoms('H2', positions=[[0, 0, 0], [r, 0, 0]]) atoms2 = Atoms('H2', positions=[[0, 0, 0], [r + h, 0, 0]]) atoms.calc = calc atoms2.calc = calc fd_force = (atoms2.get_potential_energy() - atoms.get_potential_energy()) / h force = atoms.get_forces()[0, 0] np.testing.assert_allclose(fd_force, force)
def run_neb_calculation(cpu): images = [PickleTrajectory('H.traj')[-1]] for i in range(4): images.append(images[0].copy()) images[-1].positions[6, 1] = 2 - images[0].positions[6, 1] neb = NEB(images, parallel=True, world=cpu) neb.interpolate() images[cpu.rank + 1].set_calculator(LennardJones()) dyn = BFGS(neb) dyn.run(fmax=0.01) if cpu.rank == 1: results.append(images[2].get_potential_energy())
def test_derivitives(): """ Test the calcualted derivitives: forces and stress with a LJ calculator against ASE's implementation """ from ase.collections import g2 from ase.build import bulk from ase.calculators.lj import LennardJones from pinn.models import potential_model from pinn.calculator import PiNN_calc import numpy as np params = { 'model_dir': '/tmp/pinn_test/lj', 'network': 'lj', 'network_params': { 'rc': 3 }, 'model_params': {} } model = potential_model(params) pi_lj = PiNN_calc(model) test_set = [bulk('Cu').repeat([3, 3, 3]), bulk('Mg'), g2['H2O']] for atoms in test_set: pos = atoms.get_positions() atoms.set_positions(pos + np.random.uniform(0, 0.2, pos.shape)) atoms.set_calculator(pi_lj) f_pinn, e_pinn = atoms.get_forces(), atoms.get_potential_energy() atoms.set_calculator(LennardJones()) f_ase, e_ase = atoms.get_forces(), atoms.get_potential_energy() assert np.all(np.abs(f_pinn - f_ase) < 1e-3) assert np.abs(e_pinn - e_ase) < 1e-3 if np.any(atoms.pbc): atoms.set_calculator(pi_lj) s_pinn = atoms.get_stress() atoms.set_calculator(LennardJones()) s_ase = atoms.get_stress() assert np.all(np.abs(s_pinn - s_ase) < 1e-3)
def test(): from ase.io import Trajectory import numpy as np from theforce.util.flake import hexagonal_flake from ase.calculators.lj import LennardJones from ase import Atoms cell = np.array([9., 9., 9.]) positions = hexagonal_flake(a=1.1, centre=True) + cell/2 atoms = Atoms(positions=positions, cell=cell, pbc=True) atoms.set_calculator(LennardJones(epsilon=1.0, sigma=1.0, rc=3.0)) atoms.get_potential_energy() sys = System(atoms) sys.xyz.requires_grad = True sys.build_nl(3.0) r2 = (sys.r**2).sum(dim=-1) energy = 2*((1.0/r2)**6-(1.0/r2)**3).sum() energy.backward() print(torch.allclose(sys.target_forces, -sys.xyz.grad))
def test_bulk_stress(): # check stress computation for sanity and reference # reference value computed for "non-smooth" LJ, so # we only test that atoms = bulk("Ar", cubic=True) atoms.set_cell(atoms.cell * stretch, scale_atoms=True) calc = LennardJones(rc=10) atoms.calc = calc stress = atoms.get_stress() stresses = atoms.get_stresses() assert np.allclose(stress, stresses.sum(axis=0)) # check reference pressure pressure = sum(stress[:3]) / 3 assert pressure == reference_pressure
def test_dimer(): from ase import Atom, Atoms from ase.calculators.lj import LennardJones from ase.constraints import FixBondLength dimer = Atoms([Atom('X', (0, 0, 0)), Atom('X', (0, 0, 1))], calculator=LennardJones(), constraint=FixBondLength(0, 1)) print(dimer.get_forces()) print(dimer.positions) dimer.positions[:] += 0.1 print(dimer.positions) dimer.positions[:, 2] += 5.1 print(dimer.positions) dimer.positions[:] = [(1, 2, 3), (4, 5, 6)] print(dimer.positions) dimer.set_positions([(1, 2, 3), (4, 5, 6.2)]) print(dimer.positions)
def test_fix_bond_length_mic(wrap): a = ase.Atoms('CCC', positions=[[1, 0, 5], [0, 1, 5], [-1, 0.5, 5]], cell=[10, 10, 10], pbc=True) if wrap: a.set_scaled_positions(a.get_scaled_positions() % 1.0) a.calc = LennardJones() a.set_constraint(FixBondLength(0, 2)) d1 = a.get_distance(0, 2, mic=True) with FIRE(a, logfile=None) as opt: opt.run(fmax=0.01) e = a.get_potential_energy() d2 = a.get_distance(0, 2, mic=True) assert abs(e - -2.034988) < 1e-6 assert abs(d1 - d2) < 1e-6