def test_water(): from ase.calculators.gaussian import Gaussian from ase.atoms import Atoms from ase.optimize.lbfgs import LBFGS from ase.io import read # First test to make sure Gaussian works calc = Gaussian(xc='pbe', chk='water.chk', label='water') calc.clean() water = Atoms('OHH', positions=[(0, 0, 0), (1, 0, 0), (0, 1, 0)], calculator=calc) opt = LBFGS(water) opt.run(fmax=0.05) forces = water.get_forces() energy = water.get_potential_energy() positions = water.get_positions() # Then test the IO routines water2 = read('water.log') forces2 = water2.get_forces() energy2 = water2.get_potential_energy() positions2 = water2.get_positions() # Compare distances since positions are different in standard orientation. dist = water.get_all_distances() dist2 = read('water.log', index=-1).get_all_distances() assert abs(energy - energy2) < 1e-7 assert abs(forces - forces2).max() < 1e-9 assert abs(positions - positions2).max() < 1e-6 assert abs(dist - dist2).max() < 1e-6
def dimer(self): dimer = Atoms([self.symbol, self.symbol], pbc=True, cell=(self.a, self.a, self.a)) self.Edimer = np.zeros((self.ng, 7)) self.Fdimer = np.zeros((self.ng, 7, 2)) q0 = self.d0 / np.sqrt(3) eigensolver = 'rmm-diis' if self.symbol in ['Ti', 'Sn', 'Te', 'Ba']: eigensolver = 'cg' for i in range(self.ng): h = self.gridspacings[i] calc = GPAW(h=h, txt='%s-dimer-%.3f.txt' % (self.symbol, h), mixer=Mixer(beta=0.1, nmaxold=5, weight=50), #mixer=Mixer(beta=0.05, nmaxold=7, weight=100), eigensolver=eigensolver, maxiter=300, nbands=-10, **self.parameters) dimer.set_calculator(calc) y = [] for j in range(-3, 4): q = q0 * (1 + j * 0.02) dimer.positions[1] = (q, q, q) try: e = calc.get_potential_energy(dimer, force_consistent=True) self.Edimer[i, j + 3] = e except ConvergenceError: raise self.Fdimer[i, j + 3] = dimer.get_forces()[:, 0]
def eggbox(self): atom = Atoms(self.symbol, pbc=True, cell=(self.a, self.a, self.a)) negg = 25 self.Eegg = np.zeros((self.ng, negg)) self.Fegg = np.zeros((self.ng, negg)) eigensolver = 'rmm-diis' if self.symbol in ['Na', 'Mg']: eigensolver = 'cg' if self.symbol in ['Sc', 'Ti', 'V', 'Mn', 'Ni', 'Zn']: eigensolver = 'cg' if self.symbol in ['Zr', 'Nb', 'Mo', 'Ru', 'Rh', 'Pd', 'Ag']: eigensolver = 'cg' if self.symbol in ['Sn', 'Sb', 'Te', 'Ba']: eigensolver = 'cg' if self.symbol in ['Hf', 'Ta', 'W', 'Re', 'Os', 'Ir', 'Pt', 'Hg', 'Pb', 'Bi']: eigensolver = 'cg' for i in range(self.ng): h = self.gridspacings[i] calc = GPAW(h=h, txt='%s-eggbox-%.3f.txt' % (self.symbol, h), mixer=Mixer(beta=0.1, nmaxold=5, weight=50), eigensolver=eigensolver, maxiter=300, nbands=-10, **self.parameters) atom.set_calculator(calc) for j in range(negg): x = h * j / (2 * negg - 2) atom[0].x = x try: e = calc.get_potential_energy(atom, force_consistent=True) self.Eegg[i, j] = e except ConvergenceError: raise self.Fegg[i, j] = atom.get_forces()[0, 0]
def eggbox(self): atom = Atoms(self.symbol, pbc=True, cell=(self.a, self.a, self.a)) negg = 25 self.Eegg = np.zeros((self.ng, negg)) self.Fegg = np.zeros((self.ng, negg)) eigensolver = 'rmm-diis' if self.symbol in ['Ti', 'Sn', 'Te', 'Ba']: eigensolver = 'cg' for i in range(self.ng): h = self.gridspacings[i] calc = GPAW(h=h, txt='%s-eggbox-%.3f.txt' % (self.symbol, h), mixer=Mixer(beta=0.1, nmaxold=5, weight=50), eigensolver=eigensolver, maxiter=300, nbands=-10, **self.parameters) atom.set_calculator(calc) for j in range(negg): x = h * j / (2 * negg - 2) atom[0].x = x try: e = calc.get_potential_energy(atom, force_consistent=True) self.Eegg[i, j] = e except ConvergenceError: raise self.Fegg[i, j] = atom.get_forces()[0, 0]
def dimer(self): dimer = Atoms([self.symbol, self.symbol], pbc=True, cell=(self.a, self.a, self.a)) self.Edimer = np.zeros((self.ng, 7)) self.Fdimer = np.zeros((self.ng, 7, 2)) q0 = self.d0 / np.sqrt(3) eigensolver = 'rmm-diis' if self.symbol in ['Ti', 'Sn', 'Te', 'Ba']: eigensolver = 'cg' for i in range(self.ng): h = self.gridspacings[i] calc = GPAW( h=h, txt='%s-dimer-%.3f.txt' % (self.symbol, h), mixer=Mixer(beta=0.1, nmaxold=5, weight=50), #mixer=Mixer(beta=0.05, nmaxold=7, weight=100), eigensolver=eigensolver, maxiter=300, nbands=-10, **self.parameters) dimer.set_calculator(calc) y = [] for j in range(-3, 4): q = q0 * (1 + j * 0.02) dimer.positions[1] = (q, q, q) try: e = calc.get_potential_energy(dimer, force_consistent=True) self.Edimer[i, j + 3] = e except ConvergenceError: raise self.Fdimer[i, j + 3] = dimer.get_forces()[:, 0]
def ase_task(cid, calc, atcor, ian): """Base task for inproc calculators (e.g. Psi4). For Parameters and Returns see above :func:`ase_fio_task`. :func:`ase_task` uses ``grain.subproc.subprocify`` to "asyncify" the calculator, as we assume that an inproc calculator's ``calculate`` method is CPU intensive. ``subprocify`` requires an async context to maintain a subprocess pool. This could be simply achieved by:: from grain.subproc import subprocess_pool_scope async with subprocess_pool_scope(): # Safely call subprocified functions within .. note:: Task calling this experiences an overhead for the first few runs due to ``subprocify``'s subprocess startup cost, which will be amortized later as the subprocesses are reused. """ from ase.atoms import Atoms from ase.units import Hartree as hart2ev, Bohr as b2a from .util import timeblock mol = Atoms(numbers=ian, positions=atcor) mol.calc = calc with timeblock(cid): mol._calc.calculate(mol, ['energy', 'forces'], []) return ( mol.get_potential_energy() / hart2ev, mol.get_forces() * b2a / hart2ev, )
def test_lammps_neighlist_buf(factory, testdir): # this is a perfectly symmetric FCC configurations, all forces should be zero # As of 6 May 2021, if lammpslib does wrap before rotating into lammps coord system # lammps messes up the neighbor list. This may or may not be fixed in lammps eventually, # but can also be worked around by having lammpslib do the wrap just before passing coords # to lammps os.chdir(testdir) atoms = Atoms('He', cell=[[2.045, 2.045, 0.0], [2.045, 0.0, 2.045], [0.0, 2.045, 2.045]], pbc=[True] * 3) atoms *= 6 calc = factory.calc(lmpcmds=[ 'pair_style lj/cut 0.5995011000293092E+01', 'pair_coeff * * 3.0 3.0' ], atom_types={ 'H': 1, 'He': 2 }, log_file=None, keep_alive=True, lammps_header=[ 'units metal', 'atom_style atomic', 'atom_modify map array sort 0 0' ]) atoms.calc = calc f = atoms.get_forces() fmag = np.linalg.norm(f, axis=1) print(f'> 1e-6 f[{np.where(fmag > 1e-6)}] = {f[np.where(fmag > 1e-6)]}') print(f'max f[{np.argmax(fmag)}] = {np.max(fmag)}') assert len(np.where(fmag > 1e-10)[0]) == 0
def test_gfn1_xtb_3d(): """Test ASE interface to GFN1-xTB""" thr = 5.0e-6 atoms = Atoms( symbols='C4O8', positions=np.array([ [0.9441259872, 0.9437851680, 0.9543505632], [3.7179966528, 0.9556570368, 3.7316862240], [3.7159517376, 3.7149292800, 0.9692330016], [0.9529872864, 3.7220864832, 3.7296981120], [1.6213905408, 1.6190616096, 1.6313879040], [0.2656685664, 0.2694175776, 0.2776540416], [4.3914553920, 1.6346256864, 3.0545920000], [3.0440834880, 0.2764611744, 4.4080419264], [4.3910577696, 3.0416409504, 0.2881058304], [3.0399936576, 4.3879335936, 1.6497353376], [0.2741322432, 4.4003734944, 3.0573754368], [1.6312174944, 3.0434586528, 4.4023048032], ]), cell=np.array([5.68032, 5.68032, 5.68032]), pbc=np.array([True, True, True]), ) forces = np.array([ [0.05008078, 0.06731033, 0.06324782], [-0.03885473, 0.07550136, -0.06667888], [-0.06455676, -0.04199831, 0.06908718], [0.04672903, -0.06303119, -0.06002863], [-1.9460667, -1.94514641, -1.94923488], [1.92953942, 1.91109506, 1.92038457], [-1.91269913, -1.95500822, 1.94675148], [1.94009239, 1.91238163, -1.93489981], [-1.90757165, 1.94211445, 1.94655816], [1.94283273, -1.90965163, -1.95863335], [1.91207771, -1.94256232, 1.9337591], [-1.95160309, 1.94899525, -1.91031277], ]) charges = np.array([ 0.74256902, 0.74308482, 0.74305612, 0.74300613, -0.37010244, -0.37234708, -0.37134504, -0.37177066, -0.37176288, -0.37133667, -0.37178059, -0.37127074, ]) calc = XTB(method="GFN1-xTB") atoms.set_calculator(calc) assert atoms.pbc.all() assert approx(atoms.get_potential_energy(), abs=thr) == -1256.768167202048 assert approx(atoms.get_forces(), abs=thr) == forces assert approx(atoms.get_charges(), abs=thr) == charges
def test_gfn1_xtb_3d(): """Test ASE interface to GFN1-xTB""" thr = 5.0e-6 atoms = Atoms( symbols="C4O8", positions=np.array([ [0.9441259872, 0.9437851680, 0.9543505632], [3.7179966528, 0.9556570368, 3.7316862240], [3.7159517376, 3.7149292800, 0.9692330016], [0.9529872864, 3.7220864832, 3.7296981120], [1.6213905408, 1.6190616096, 1.6313879040], [0.2656685664, 0.2694175776, 0.2776540416], [4.3914553920, 1.6346256864, 3.0545920000], [3.0440834880, 0.2764611744, 4.4080419264], [4.3910577696, 3.0416409504, 0.2881058304], [3.0399936576, 4.3879335936, 1.6497353376], [0.2741322432, 4.4003734944, 3.0573754368], [1.6312174944, 3.0434586528, 4.4023048032], ]), cell=np.array([5.68032, 5.68032, 5.68032]), pbc=np.array([True, True, True]), ) forces = np.array([ [-0.08831700, -0.07001294, -0.07468651], [-0.03556765, -0.02242341, +0.03047788], [+0.03228896, -0.03948204, -0.02892694], [-0.02569098, +0.03373080, -0.03161988], [-1.90306812, -1.90236730, -1.90612450], [+1.98861177, +1.96958105, +1.97849378], [-1.88898997, -1.93509024, +1.91692369], [+1.92988257, +1.95061533, -1.94116843], [-1.93844982, +1.93069254, +1.96026641], [+1.91146115, -1.88620597, -1.93901862], [+1.94936349, -1.94760369, +1.92150003], [-1.93152440, +1.91856587, -1.88611692], ]) stress = np.array([ +4.49045792e-02, +4.49168887e-02, +4.49566951e-02, +3.38245641e-05, +1.52117499e-05, +1.13328271e-04, ]) atoms.calc = TBLite(method="GFN1-xTB") assert atoms.pbc.all() assert approx(atoms.get_potential_energy(), abs=thr) == -1257.0801067985549 assert approx(atoms.get_forces(), abs=thr) == forces assert approx(atoms.get_stress(), abs=thr) == stress
def test_gfn1_xtb_0d(): """Test ASE interface to GFN1-xTB""" thr = 1.0e-5 atoms = Atoms( symbols="CHOCH2CH4CH2OH", positions=np.array([ [+1.578385, +0.147690, +0.343809], [+1.394750, +0.012968, +1.413545], [+1.359929, -1.086203, -0.359782], [+0.653845, +1.215099, -0.221322], [+1.057827, +2.180283, +0.093924], [+0.729693, +1.184864, -1.311438], [-0.817334, +1.152127, +0.208156], [-1.303525, +2.065738, -0.145828], [-0.883765, +1.159762, +1.299260], [+1.984120, -1.734446, -0.021385], [+2.616286, +0.458948, +0.206544], [-1.627725, -0.034052, -0.311301], [-2.684229, +0.151015, -0.118566], [-1.501868, -0.118146, -1.397506], [-1.324262, -1.260154, +0.333377], [-0.417651, -1.475314, +0.076637], ]), ) forces = np.array([ [-0.37070590, -0.51067739, -0.27981764], [-0.04339461, -0.09290876, +0.22940156], [+0.11141234, +0.46678720, +0.24552625], [+0.04255709, +0.19019316, -0.23531997], [-0.01897377, +0.10810803, +0.05314982], [-0.07150720, -0.05182148, -0.08413638], [+0.06631826, +0.10587709, +0.29833479], [-0.01062355, +0.02301460, -0.04964730], [+0.06610108, -0.02724994, +0.09234280], [+0.06519070, -0.19311773, -0.01152205], [+0.23879786, +0.09871398, -0.04009526], [-0.04381577, -0.49997745, +0.08672818], [-0.23259608, +0.13735636, +0.06783414], [+0.08297636, -0.09566973, -0.20602954], [-0.23686052, +0.57454371, -0.17194215], [+0.35512370, -0.23317164, +0.00519275], ]) atoms.calc = TBLite(method="GFN1-xTB") assert approx(atoms.get_potential_energy(), abs=thr) == -632.7363734598027 assert approx(atoms.get_forces(), abs=thr) == forces
def test_gfn2_xtb_0d(): """Test ASE interface to GFN2-xTB""" thr = 1.0e-5 atoms = Atoms( symbols="CHOCH2CH4CH2OH", positions=np.array([ [+1.578385, +0.147690, +0.343809], [+1.394750, +0.012968, +1.413545], [+1.359929, -1.086203, -0.359782], [+0.653845, +1.215099, -0.221322], [+1.057827, +2.180283, +0.093924], [+0.729693, +1.184864, -1.311438], [-0.817334, +1.152127, +0.208156], [-1.303525, +2.065738, -0.145828], [-0.883765, +1.159762, +1.299260], [+1.984120, -1.734446, -0.021385], [+2.616286, +0.458948, +0.206544], [-1.627725, -0.034052, -0.311301], [-2.684229, +0.151015, -0.118566], [-1.501868, -0.118146, -1.397506], [-1.324262, -1.260154, +0.333377], [-0.417651, -1.475314, +0.076637], ]), ) forces = np.array([ [-0.28561308, -0.48587499, -0.28392027], [-0.05526371, -0.07403870, +0.09666022], [+0.18830054, +0.39163807, +0.33884887], [-0.01165266, +0.24651648, -0.16778052], [-0.05367208, +0.03368724, +0.05115729], [-0.09605395, -0.10000312, +0.01096077], [+0.09422811, +0.18571407, +0.17796656], [+0.02651446, -0.04073478, -0.03656254], [+0.07886459, -0.05806164, +0.00649897], [-0.00786081, -0.07975814, -0.03179608], [+0.13328259, +0.03208869, -0.04638662], [+0.08197190, -0.39156437, +0.12108031], [-0.11454175, -0.01484728, +0.09974090], [+0.09786247, -0.09131053, -0.05738535], [-0.26638845, +0.47604034, -0.27858358], [+0.19002181, -0.02949135, -0.00049892], ]) calc = TBLite(method="GFN2-xTB", atoms=atoms) assert approx(atoms.get_potential_energy(), abs=thr) == -592.6794366990786 assert approx(atoms.get_forces(), abs=thr) == forces
async def ase_fio_task(cid, calc, atcor, ian, cell=None, pbc=None): """Base task for calculators implementing the `FileIOCalculator`_ interface (e.g. Gaussian, Orca, QE). .. _FileIOCalculator: https://gitlab.com/ase/ase/-/blob/master/ase/calculators/calculator.py Class ``FileIOCalculator`` is patched to enable async calculation through async subprocess. See ``monkey_patch.py`` for details. Args: cid (str): Calculation ID, for time record only calc: The calculator instance atcor (ndarray[(N,3), float]): Atom coordinate ian (ndarray[(N,), int]): Atomic numbers pbc (bool or (bool, bool, bool)): Periodic boundary conditions along each axis. Arg for ``ase.atoms.Atoms`` cell (ndarray[(3,3), float] or see ASE doc): Unit cell size. Arg for ``ase.atoms.Atoms`` Returns: Energy (in hartree) and forces (in hartree/angstrom) .. note:: Any task calling this should make sure that the calculator itself's ``calculate`` method get handled, as this only takes care of ``FileIOCalculator.calculate``. """ from ase.atoms import Atoms from ase.units import Hartree as hart2ev, Bohr as b2a from .util import timeblock mol = Atoms(numbers=ian, positions=atcor, cell=cell, pbc=pbc) mol.calc = calc with timeblock(cid): await mol._calc.acalculate(mol, ['energy', 'forces'], []) return ( mol.get_potential_energy() / hart2ev, mol.get_forces() * b2a / hart2ev, )
def test_gfn2xtb_lbfgs(): """Perform geometry optimization with GFN2-xTB and L-BFGS""" thr = 1.0e-5 atoms = Atoms( symbols="NHCHC2H3OC2H3ONHCH3", positions=np.array([ [1.40704587284727, -1.26605342016611, -1.93713466561923], [1.85007200612454, -0.46824072777417, -1.50918242392545], [-0.03362432532150, -1.39269245193812, -1.74003582081606], [-0.56857009928108, -1.01764444489068, -2.61263467107342], [-0.44096297340282, -2.84337808903410, -1.48899734014499], [-0.47991761226058, -0.55230954385212, -0.55520222968656], [-1.51566045903090, -2.89187354810876, -1.32273881320610], [-0.18116520746778, -3.45187805987944, -2.34920431470368], [0.06989722340461, -3.23298998903001, -0.60872832703814], [-1.56668253918793, 0.00552120970194, -0.52884675001441], [1.99245341064342, -1.73097165236442, -3.08869239114486], [3.42884244212567, -1.30660069291348, -3.28712665743189], [3.87721962540768, -0.88843123009431, -2.38921453037869], [3.46548545761151, -0.56495308290988, -4.08311788302584], [4.00253374168514, -2.16970938132208, -3.61210068365649], [1.40187968630565, -2.43826111827818, -3.89034127398078], [0.40869198386066, -0.49101709352090, 0.47992424955574], [1.15591901335007, -1.16524842262351, 0.48740266650199], [0.00723492494701, 0.11692276177442, 1.73426297572793], [0.88822128447468, 0.28499001838229, 2.34645658013686], [-0.47231557768357, 1.06737634000561, 1.52286682546986], [-0.70199987915174, -0.50485938116399, 2.28058247845421], ]), ) calc = XTB(method="GFN2-xTB", solvent="water", accuracy=0.1) atoms.set_calculator(calc) opt = LBFGS(atoms) opt.run(fmax=0.1) assert approx(atoms.get_potential_energy(), thr) == -897.4533662470938 assert approx(np.linalg.norm(atoms.get_forces(), ord=2), thr) == 0.19359647527783497
calc = Gaussian(method='pbepbe', basis='sto-3g', force='force', nproc=1, chk='water.chk', label='water') calc.clean() water = Atoms('OHH', positions=[(0, 0, 0), (1, 0, 0), (0, 1, 0)], calculator=calc) opt = LBFGS(water) opt.run(fmax=0.05) forces = water.get_forces() energy = water.get_potential_energy() positions = water.get_positions() # Then test the IO routines from ase.io import read water2 = read('water.log') forces2 = water2.get_forces() energy2 = water2.get_potential_energy() positions2 = water2.get_positions() #compare distances since positions are different in standard orientation dist = water.get_all_distances() dist2 = read('water.log', quantity='structures')[-1].get_all_distances() assert abs(energy - energy2) < 1e-7 assert abs(forces - forces2).max() < 1e-9
class TestCalculator_SW_Potential(quippytest.QuippyTestCase): def setUp(self): self.xml = """ <SW_params n_types="2" label="PRB_31_plus_H"> <comment> Stillinger and Weber, Phys. Rev. B 31 p 5262 (1984), extended for other elements </comment> <per_type_data type="1" atomic_num="1" /> <per_type_data type="2" atomic_num="14" /> <per_pair_data atnum_i="1" atnum_j="1" AA="0.0" BB="0.0" p="0" q="0" a="1.0" sigma="1.0" eps="0.0" /> <per_pair_data atnum_i="1" atnum_j="14" AA="8.581214" BB="0.0327827" p="4" q="0" a="1.25" sigma="2.537884" eps="2.1672" /> <per_pair_data atnum_i="14" atnum_j="14" AA="7.049556277" BB="0.6022245584" p="4" q="0" a="1.80" sigma="2.0951" eps="2.1675" /> <!-- triplet terms: atnum_c is the center atom, neighbours j and k --> <per_triplet_data atnum_c="1" atnum_j="1" atnum_k="1" lambda="21.0" gamma="1.20" eps="2.1675" /> <per_triplet_data atnum_c="1" atnum_j="1" atnum_k="14" lambda="21.0" gamma="1.20" eps="2.1675" /> <per_triplet_data atnum_c="1" atnum_j="14" atnum_k="14" lambda="21.0" gamma="1.20" eps="2.1675" /> <per_triplet_data atnum_c="14" atnum_j="1" atnum_k="1" lambda="21.0" gamma="1.20" eps="2.1675" /> <per_triplet_data atnum_c="14" atnum_j="1" atnum_k="14" lambda="21.0" gamma="1.20" eps="2.1675" /> <per_triplet_data atnum_c="14" atnum_j="14" atnum_k="14" lambda="21.0" gamma="1.20" eps="2.1675" /> </SW_params> """ quippy.system_module.system_reseed_rng(2065775975) self.pot_calculator = Potential('IP SW', param_str=self.xml) self.at = Atoms('Si8', positions=diamond_pos, pbc=True, cell=[5.44, 5.44, 5.44]) self.f = np.zeros((3, len(self.at)), order='F') self.df = np.zeros((3, len(self.at)), order='F') self.v = np.zeros((3, 3), order='F') self.energy_ref = -34.5038375509 self.forces_ref = np.array([[0.89920374, -0.38025157, -0.38727027], [0.36623356, -0.52403757, 0.7200206], [-0.36952654, 0.12899529, 0.00458111], [-0.19912365, -0.1632057, 1.08509495], [-0.67565314, -0.59410498, -0.47921521], [0.17097454, 0.5847822, -0.31088749], [0.43613712, 0.90811269, 0.1600328], [-0.62824563, 0.03970963, -0.79235649]]) self.virial_ref = np.array([[-0.34103601, 0.60925144, -0.02138795], [0.60925144, -0.36145702, -0.19375487], [-0.02138795, -0.19375487, -0.34640615]]).T # Voigt notation by hand from virial self.stress_ref = -np.array([ -0.34103601, -0.36145702, -0.34640615, -0.19375487, -0.02138795, 0.60925144 ]) / self.at.get_volume() self.at.set_calculator(self.pot_calculator) def test_energy(self): self.assertAlmostEqual(self.at.get_potential_energy(), self.energy_ref) def test_forces(self): self.assertArrayAlmostEqual(self.at.get_forces(), self.forces_ref, tol=1E-06) def test_stress(self): self.assertArrayAlmostEqual(self.at.get_stress(), self.stress_ref) def test_virial(self): self.assertArrayAlmostEqual(self.pot_calculator.get_virial(self.at), self.virial_ref, tol=1E-06) def test_calc_args_1(self): self.pot_calculator.calculate(self.at, propertes=["forces"], calc_args="do_rescale_E E_scale=1.01") f = self.pot_calculator.results['forces'] self.assertArrayAlmostEqual(f, self.forces_ref * 1.01, tol=1E-06) def test_calc_args_2(self): self.pot_calculator.calculate(self.at, properties=["forces"], do_rescale_E=True, E_scale=1.01) f = self.pot_calculator.results['forces'] self.assertArrayAlmostEqual(f, self.forces_ref * 1.01, tol=1E-06) def test_calc_args_3(self): pot2 = Potential('IP SW', param_str=self.xml, calc_args="do_rescale_E E_scale=1.01") f = pot2.get_forces(self.at) self.assertArrayAlmostEqual(f, self.forces_ref * 1.01, tol=1E-06) def test_calc_args_4(self): pot2 = Potential('IP SW', param_str=self.xml, calc_args={ 'do_rescale_E': True, 'E_scale': 1.01 }) f = pot2.get_forces(self.at) self.assertArrayAlmostEqual(f, self.forces_ref * 1.01, tol=1E-06)
def phonopy_run_calculate(phonon, phonpy, supercell, single): # calculate forces using PhonoPy: phonopy/example/ase/8Si-phonon.py # get the displacements disps = phonpy.get_displacements() # get displaced supercells: api_phonopy._build_supercells_with_displacements() supercells = phonpy.get_supercells_with_displacements() # Do calculation on equilibrium structure (used to improve gradient accuracy) supercell.set_calculator(phonon.calc) feq = phonons_run_eq(phonon, supercell) for i, a in enumerate(phonon.indices): try: feq[a] -= feq.sum(0) # translational invariance except AttributeError: pass # compute the forces set_of_forces = [] for d in range(len(supercells)): # skip if this step has been done already. filename = '%s.%d.pckl' % (phonon.name, d) if isfile(filename): f = open(filename, 'rb') forces = pickle.load(f) f.close() else: # proceed with force calculation for current displaced supercell disp = disps[d] scell = supercells[d] if rank == 0: print("[ASE/PhonoPy] Moving atom #%-3i %-3s to " % \ (disp[0], scell.get_chemical_symbols()[disp[0]]), disp[1:]) cell = Atoms(symbols=scell.get_chemical_symbols(), scaled_positions=scell.get_scaled_positions(), cell=scell.get_cell(), pbc=True) cell.set_calculator(phonon.calc) forces = cell.get_forces() drift_force = forces.sum(axis=0) # print "[Phonopy] Drift force:", "%11.5f"*3 % tuple(drift_force) # Simple translational invariance for force in forces: force -= drift_force / forces.shape[0] if feq is not None: try: forces -= feq # forward difference, but assumes equilibrium is not always 0 except AttributeError: print( "[ASE/PhonoPy] Can not use forward difference (equilibrium forces are mis-formatted)" ) # save the forces in a pickle f = opencew(filename) if f is not None and rank == 0: sys.stdout.write('Writing %s\n' % filename) pickle.dump(forces, f, protocol=2) f.close() # in single shot mode, we return when forces were computed if single and d + 1 < len(supercells): return set_of_forces, True, len(supercells) - d - 1 # store the incremental list of forces set_of_forces.append(forces) return set_of_forces, False, 0
from ase.atoms import Atoms from ase.optimize.lbfgs import LBFGS # First test to make sure Gaussian works calc = Gaussian(method='pbepbe', basis='sto-3g', force='force', nproc=1, chk='water.chk', label='water') calc.clean() water = Atoms('OHH', positions=[(0., 0. ,0. ), (1. ,0. ,0. ), (0. ,1. ,0. )], calculator=calc) opt = LBFGS(water) opt.run(fmax=0.05) forces = water.get_forces() energy = water.get_potential_energy() positions = water.get_positions() # Then test the IO routines from ase.io import read water2 = read('water/water.log') forces2 = water2.get_forces() energy2 = water2.get_potential_energy() positions2 = water2.get_positions() assert (energy - energy2) < 1e-14 assert (forces.all() - forces2.all()) < 1e-14 assert (positions.all() - positions2.all()) < 1e-14
def test_gfn1_xtb_0d(): """Test ASE interface to GFN1-xTB""" thr = 1.0e-5 atoms = Atoms( symbols='CHOCH2CH4CH2OH', positions=np.array([ [1.578385, 0.147690, 0.343809], [1.394750, 0.012968, 1.413545], [1.359929, -1.086203, -0.359782], [0.653845, 1.215099, -0.221322], [1.057827, 2.180283, 0.093924], [0.729693, 1.184864, -1.311438], [-0.817334, 1.152127, 0.208156], [-1.303525, 2.065738, -0.145828], [-0.883765, 1.159762, 1.299260], [1.984120, -1.734446, -0.021385], [2.616286, 0.458948, 0.206544], [-1.627725, -0.034052, -0.311301], [-2.684229, 0.151015, -0.118566], [-1.501868, -0.118146, -1.397506], [-1.324262, -1.260154, 0.333377], [-0.417651, -1.475314, 0.076637], ]), ) forces = np.array([[-0.37070590, -0.51067739, -0.27981764], [-0.04339461, -0.09290876, 0.22940156], [0.11141234, 0.46678720, 0.24552625], [0.04255709, 0.19019316, -0.23531997], [-0.01897377, 0.10810803, 0.05314982], [-0.07150720, -0.05182148, -0.08413638], [0.06631826, 0.10587709, 0.29833479], [-0.01062355, 0.02301460, -0.04964730], [0.06610108, -0.02724994, 0.09234280], [0.06519070, -0.19311773, -0.01152205], [0.23879786, 0.09871398, -0.04009526], [-0.04381577, -0.49997745, 0.08672818], [-0.23259608, 0.13735636, 0.06783414], [0.08297636, -0.09566973, -0.20602954], [-0.23686052, 0.57454371, -0.17194215], [0.35512370, -0.23317164, 0.00519275]]) charges = np.array([ 0.19494678, 0.01759972, -0.57108503, -0.05371086, 0.02458495, 0.03915074, -0.06889977, 0.02521441, 0.03350058, 0.34380081, 0.01442221, 0.20053193, 0.02454679, 0.01011690, -0.58349877, 0.34877861, ]) dipole_moment = np.array([0.76943477, 0.33021928, 0.05670150]) atoms.calc = XTB(method="GFN1-xTB") assert approx(atoms.get_potential_energy(), thr) == -632.7363734598027 assert approx(atoms.get_forces(), thr) == forces assert approx(atoms.get_charges(), thr) == charges assert approx(atoms.get_dipole_moment(), thr) == dipole_moment
def test_gfn2_xtb_0d(): """Test ASE interface to GFN2-xTB""" thr = 1.0e-5 atoms = Atoms( symbols='CHOCH2CH4CH2OH', positions=np.array([ [1.578385, 0.147690, 0.343809], [1.394750, 0.012968, 1.413545], [1.359929, -1.086203, -0.359782], [0.653845, 1.215099, -0.221322], [1.057827, 2.180283, 0.093924], [0.729693, 1.184864, -1.311438], [-0.817334, 1.152127, 0.208156], [-1.303525, 2.065738, -0.145828], [-0.883765, 1.159762, 1.299260], [1.984120, -1.734446, -0.021385], [2.616286, 0.458948, 0.206544], [-1.627725, -0.034052, -0.311301], [-2.684229, 0.151015, -0.118566], [-1.501868, -0.118146, -1.397506], [-1.324262, -1.260154, 0.333377], [-0.417651, -1.475314, 0.076637], ]), ) forces = np.array([ [-0.28561158, -0.48592026, -0.28392327], [-0.05526158, -0.07403455, 0.09665539], [0.18824950, 0.39170140, 0.33881928], [-0.01166074, 0.24653252, -0.16779606], [-0.05367503, 0.03368063, 0.05115422], [-0.09605262, -0.10000389, 0.01097286], [0.09423300, 0.18573616, 0.17797438], [0.02651896, -0.04073849, -0.03655980], [0.07886359, -0.05806479, 0.00649360], [-0.00780520, -0.07979390, -0.03175697], [0.13328595, 0.03209283, -0.04638514], [0.08197778, -0.39157299, 0.12107401], [-0.11453823, -0.01485088, 0.09974068], [0.09786017, -0.09130861, -0.05738675], [-0.26643400, 0.47603727, -0.27856705], [0.19005003, -0.02949244, -0.00050938], ]) charges = np.array([ 0.08239823, 0.03066406, -0.44606929, -0.06139043, 0.03610596, 0.05389499, -0.06991855, 0.03384415, 0.04665524, 0.28688538, 0.02246569, 0.08251610, 0.03810481, 0.01883776, -0.46691965, 0.31192554, ]) dipole_moment = np.array([0.62120710, 0.28006659, 0.04465985]) calc = XTB(method="GFN2-xTB", atoms=atoms) assert approx(atoms.get_potential_energy(), abs=thr) == -592.6794366990786 assert approx(atoms.get_forces(), abs=thr) == forces assert approx(atoms.get_charges(), abs=thr) == charges assert approx(atoms.get_dipole_moment(), abs=thr) == dipole_moment atoms.calc.set( accuracy=0.1, electronic_temperature=500.0, max_iterations=20, solvent="ch2cl2", ) assert approx(atoms.get_potential_energy(), abs=thr) == -592.9940608761889