def test_no_pbc_small_cell(self): a = io.read('aC.cfg') a.set_calculator(Tersoff()) a.set_pbc(False) e1 = a.get_potential_energy() i1, j1, r1 = a.calc.nl.get_neighbors(a.calc.particles) a.set_cell(a.cell*0.9, scale_atoms=False) e2 = a.get_potential_energy() self.assertAlmostEqual(e1, e2) i2, j2, r2 = a.calc.nl.get_neighbors(a.calc.particles) for k in range(len(a)): neigh1 = np.array(sorted(j1[i1==k])) neigh2 = np.array(sorted(j2[i2==k])) self.assertTrue(np.all(neigh1 == neigh2))
def test_pbc_shift_by_multiple_cells(self): a = io.read('aC.cfg') a.set_calculator(Tersoff()) e1 = a.get_potential_energy() i1, j1, r1 = a.calc.nl.get_neighbors(a.calc.particles) a[100].position += 3*a.cell[0] e2 = a.get_potential_energy() i2, j2, r2 = a.calc.nl.get_neighbors(a.calc.particles) for i in range(len(a)): n1 = np.array(sorted(j1[i1==i])) n2 = np.array(sorted(j2[i2==i])) if np.any(n1 != n2): print(i, n1, n2) a[100].position += a.cell.T.dot([1,3,-4]) e3 = a.get_potential_energy() self.assertAlmostEqual(e1, e2) self.assertAlmostEqual(e1, e3)
def test_pbc(self): a = Diamond('Si', latticeconstant=5.432, size=[2,2,2]) sx, sy, sz = a.get_cell().diagonal() a.set_calculator(Tersoff()) e1 = a.get_potential_energy() a.set_pbc([True,True,False]) e2 = a.get_potential_energy() a.set_pbc(True) a.set_cell([sx,sy,2*sz]) e3 = a.get_potential_energy() self.assertEqual(e2, e3) # This should give the unrelaxed surface energy esurf = (e2-e1)/(2*sx*sy) * Jm2 self.assertTrue(abs(esurf-2.309) < 0.001)
def test_floating_point_issue(self): calc = Tersoff() a1 = ase.Atoms('Si4C4', positions=np.array([[-4.41173839e-52, 0.00000000e+00, 0.00000000e+00], [-4.41173839e-52, 2.26371743e+00, 2.26371743e+00], [ 2.26371743e+00, 0.00000000e+00, 2.26371743e+00], [ 2.26371743e+00, 2.26371743e+00, 0.00000000e+00], [ 1.13185872e+00, 1.13185872e+00, 1.13185872e+00], [ 1.13185872e+00, 3.39557615e+00, 3.39557615e+00], [ 3.39557615e+00, 1.13185872e+00, 3.39557615e+00], [ 3.39557615e+00, 3.39557615e+00, 1.13185872e+00]]), cell=[4.527434867899659, 4.527434867899659, 4.527434867899659], pbc=True) a1.calc = calc a1.get_potential_energy() self.assertTrue((calc.nl.get_coordination_numbers(calc.particles, 3.0) == 4).all()) a2 = a1.copy() a2.calc = calc a2.set_scaled_positions(a2.get_scaled_positions()) a2.get_potential_energy() self.assertTrue((calc.nl.get_coordination_numbers(calc.particles, 3.0) == 4).all())
def test_mask_decomposition_bop(self): a = io.read('aC.cfg') for pot in [Tersoff, TersoffScr]: c = Tersoff() a.set_calculator(c) self.random_mask_test(a)
from ase.optimize import FIRE, LBFGS, LBFGSLineSearch from ase.optimize.precon import PreconLBFGS from ase.build import bulk from atomistica import Tersoff from ode import ODE12rOptimizer a0 = bulk('C', cubic=True) * 5 a0.rattle(0.05) del a0[0] for OPT in [ODE12rOptimizer, FIRE, LBFGS, LBFGSLineSearch, PreconLBFGS]: a = a0.copy() a.set_calculator(Tersoff()) opt = OPT(a) opt.run(fmax=1e-3) print()
def test_embedding_size_convergence(self): calc = Tersoff(**Tersoff_PRB_39_5566_Si_C) el = 'C' a0 = 3.566 surface_energy = 2.7326 * 10 crack_surface = [1, 1, 1] crack_front = [1, -1, 0] skin_x, skin_y = 1, 1 cryst = bulk(el, cubic=True) cryst.set_calculator(calc) FIRE(UnitCellFilter(cryst), logfile=None).run(fmax=1e-6) a0 = cryst.cell.diagonal().mean() bondlength = cryst.get_distance(0, 1) #print('a0 =', a0, ', bondlength =', bondlength) cryst = diamond(el, a0, [1, 1, 1], crack_surface, crack_front) cryst.set_pbc(True) cryst.set_calculator(calc) cryst.set_cell(cryst.cell.diagonal(), scale_atoms=True) C, C_err = fit_elastic_constants(cryst, verbose=False, symmetry='cubic', optimizer=FIRE, fmax=1e-6) #print('Measured elastic constants (in GPa):') #print(np.round(C*10/units.GPa)/10) bondlengths = [] refcell = None reftip_x = None reftip_y = None #[41, 39, 1], for i, n in enumerate([[21, 19, 1], [11, 9, 1], [6, 5, 1]]): #print(n) cryst = diamond(el, a0, n, crack_surface, crack_front) set_groups(cryst, n, skin_x, skin_y) cryst.set_pbc(True) cryst.set_calculator(calc) FIRE(UnitCellFilter(cryst), logfile=None).run(fmax=1e-6) cryst.set_cell(cryst.cell.diagonal(), scale_atoms=True) ase.io.write('cryst_{}.xyz'.format(i), cryst, format='extxyz') crk = crack.CubicCrystalCrack(crack_surface, crack_front, Crot=C / units.GPa) k1g = crk.k1g(surface_energy) tip_x = cryst.cell.diagonal()[0] / 2 tip_y = cryst.cell.diagonal()[1] / 2 a = cryst.copy() a.set_pbc([False, False, True]) k1 = 1.0 ux, uy = crk.displacements(cryst.positions[:, 0], cryst.positions[:, 1], tip_x, tip_y, k1 * k1g) a.positions[:, 0] += ux a.positions[:, 1] += uy # Center notched configuration in simulation cell and ensure enough vacuum. oldr = a[0].position.copy() if refcell is None: a.center(vacuum=10.0, axis=0) a.center(vacuum=10.0, axis=1) refcell = a.cell.copy() tip_x += a[0].x - oldr[0] tip_y += a[0].y - oldr[1] reftip_x = tip_x reftip_y = tip_y else: a.set_cell(refcell) # Shift tip position so all systems are exactly centered at the same spot a.positions[:, 0] += reftip_x - tip_x a.positions[:, 1] += reftip_y - tip_y refpositions = a.positions.copy() # Move reference crystal by same amount cryst.set_cell(a.cell) cryst.set_pbc([False, False, True]) cryst.translate(a[0].position - oldr) bond1, bond2 = crack.find_tip_coordination( a, bondlength=bondlength * 1.2) # Groups mark the fixed region and the region use for fitting the crack tip. g = a.get_array('groups') gcryst = cryst.get_array('groups') ase.io.write('cryst_{}.xyz'.format(i), cryst) a.set_calculator(calc) a.set_constraint(FixAtoms(mask=g == 0)) FIRE(a, logfile=None).run(fmax=1e-6) dpos = np.sqrt(( (a.positions[:, 0] - refpositions[:, 0]) / ux)**2 + ( (a.positions[:, 1] - refpositions[:, 1]) / uy)**2) a.set_array('dpos', dpos) distance_from_tip = np.sqrt((a.positions[:, 0] - reftip_x)**2 + (a.positions[:, 1] - reftip_y)**2) ase.io.write('crack_{}.xyz'.format(i), a) # Compute average bond length per atom neighi, neighj, neighd = neighbour_list('ijd', a, cutoff=bondlength * 1.2) coord = np.bincount(neighi) assert coord.max() == 4 np.savetxt( 'dpos_{}.out'.format(i), np.transpose( [distance_from_tip[coord == 4], dpos[coord == 4]])) # Compute distances from tipcenter neighdist = np.sqrt(( (a.positions[neighi, 0] + a.positions[neighj, 0]) / 2 - reftip_x)**2 + ( (a.positions[neighi, 1] + a.positions[neighj, 1]) / 2 - reftip_y)**2) np.savetxt('bl_{}.out'.format(i), np.transpose([neighdist, neighd])) bondlengths += [a.get_distance(bond1, bond2)] print(bondlengths, np.diff(bondlengths), bondlengths / bondlengths[-1] - 1) assert np.all(np.diff(bondlengths) > 0) assert np.max(bondlengths / bondlengths[0] - 1) < 0.01
from atomistica import Tersoff, Tersoff_PRB_39_5566_Si_C # A module defining a module needs to define only one variable, # named `calculator`, which should be an instance of the ase.calculator.Calculator, # a subclass of this, or a compatible class implementing the calculator interface. calculator = Tersoff(**Tersoff_PRB_39_5566_Si_C) no_checkpoint = True name = 'Tersoff'