def makePotentialObjects(): # O-O Interaction: # Buckingham # A = 1633.00510, rho = 0.327022, C = 3.948790 f_OO = potentialforms.buck(1633.00510, 0.327022, 3.948790) # U-U Interaction: # Buckingham # A = 294.640000, rho = 0.327022, C = 0.0 f_UU = potentialforms.buck(294.640000, 0.327022, 0.0) # O-U Interaction # Buckingham + Morse. # Buckingham: # A = 693.648700, rho = 693.648700, C = 0.0 # Morse: # D0 = 0.577190, alpha = 1.6500, r0 = 2.36900 buck_OU = potentialforms.buck(693.648700, 0.327022, 0.0) morse_OU = potentialforms.morse(1.6500, 2.36900, 0.577190) # Compose the buckingham and morse functions into a single function # using the atsim.potentials.plus() function f_OU = plus(buck_OU, morse_OU) # Construct list of Potential objects potential_objects = [ Potential('O', 'O', f_OO), Potential('U', 'U', f_UU), Potential('O', 'U', f_OU) ] return potential_objects
def testBuck(): r = 0.5 a = 1388.773 rho = 2.76 c = 175.0 potfunc = potentialforms.buck(a, rho, c) pytest.approx(-10041.34343) == potfunc(r)
def test_spline_modifier(): bks_buck = potentialforms.buck(18003.7572, 1.0 / 4.87318, 133.5381) bks_coul = potentialforms.coul(2.4, -1.2) bks = atsim.potentials.plus(bks_buck, bks_coul) zbl = potentialforms.zbl(14, 8) spline = atsim.potentials.SplinePotential(zbl, bks_buck, 0.8, 1.4) buck_spline = PotentialFormInstanceTuple( potential_form="as.buck", parameters=[18003.7572, 1.0 / 4.87318, 133.5381], start=MultiRangeDefinitionTuple('>', 1.4), next=None) exp_spline = PotentialFormInstanceTuple(potential_form="exp_spline", parameters=[], start=MultiRangeDefinitionTuple( ">=", 0.8), next=buck_spline) zbl_spline = PotentialFormInstanceTuple(potential_form="as.zbl", parameters=[14, 8], start=MultiRangeDefinitionTuple( ">", 0.0), next=exp_spline) pmt = PotentialModifierTuple(modifier='spline', potential_forms=[zbl_spline], start=MultiRangeDefinitionTuple('>', 0.0), next=None) pfr = Potential_Form_Registry(ConfigParser(io.StringIO()), True) mr = Modifier_Registry() pfb = Potential_Form_Builder(pfr, mr) mod_spline = pfb.create_potential_function(pmt) for i in range(1, 100): r = float(i) / 10.0 expect = spline(r) actual = mod_spline(r) assert pytest.approx(expect, abs=1e-3) == actual assert pytest.approx(zbl(0.7)) == mod_spline(0.7) assert pytest.approx(bks_buck(2.0)) == mod_spline(2.0) assert pytest.approx(spline(1.2)) == mod_spline(1.2) assert pytest.approx(zbl.deriv(0.7)) == mod_spline.deriv(0.7) assert pytest.approx(bks_buck.deriv(2.0)) == mod_spline.deriv(2.0) assert pytest.approx(spline.deriv(1.2)) == mod_spline.deriv(1.2) assert pytest.approx(zbl.deriv2(0.7)) == mod_spline.deriv2(0.7) assert pytest.approx(bks_buck.deriv2(2.0)) == mod_spline.deriv2(2.0) assert pytest.approx(spline.deriv2(1.2)) == mod_spline.deriv2(1.2)
def test_single_pair(tmpdir): gulp_input = u"""single cell 50.0 50.0 50.0 90.0 90.0 90.0 cartesian Au 25.0 25.0 25.0 B {} 25.0 25.0 species Au 0.0 B 0.0 include potentials.lib""" buck = potentialforms.buck(1000.0, 0.23, 11.6) mrdefn = Multi_Range_Defn(">", 0, buck) mrpot = create_Multi_Range_Potential_Form(mrdefn) pot = Potential(u"Au", u"B", mrpot) tabulation = pair_tabulation.GULP_PairTabulation([pot], 10.0, 500) with tmpdir.join("potentials.lib").open("w") as potfile: tabulation.write(potfile) # Reproduce a buckingham potential at sepns of 0.1 1.1 2.1 and 3.1 for x in [0.6, 1.1, 2.1, 3.1]: gulp_infile = io.StringIO(gulp_input.format(x + 25.0)) gulp_infile.seek(0) expect = pytest.approx(buck(x), rel=1e-4) gulp_outfile = io.StringIO() runGULP(gulp_infile, gulp_outfile, cwd=tmpdir.strpath) gulp_outfile.seek(0) actual = extractGULPEnergy(gulp_outfile) assert expect == actual
def test_exp_spline_spline_potential(): bks_buck = potentialforms.buck(18003.7572, 0.2052048149, 133.5381) bks_coul = potentialforms.coul(2.4, -1.2) bks = plus(bks_buck, bks_coul) zbl = potentialforms.zbl(14, 8) spline = SplinePotential(zbl, bks_buck, 0.8, 1.4) expect_sc = (115.86040201825199, -554.9048594160315, 1103.3742860731818, -1086.9207282302543, 526.6282676867107, -100.6955851023172, 0.0) actual = spline.splineCoefficients assert DeepDiff(expect_sc, actual, significant_digits=5) == {} for i in range(int(1.4 - 0.8 / 0.1) + 1): r = float(i) * 0.1 + 0.8 args = [r] args.extend(expect_sc) expect = potentialforms.exp_spline(*args) assert pytest.approx(expect) == spline(r)
def test_buck4_spline(): A = 11272.6 rho = 0.1363 C = 134.0 born_mayer = potentialforms.bornmayer(A, rho) dispersion = potentialforms.buck(0, 1, C) r_detach = 1.2 r_min = 2.1 r_attach = 2.6 detach = Spline_Point(born_mayer, r_detach) attach = Spline_Point(dispersion, r_attach) spline = Buck4_Spline(detach, attach, r_min) spline5_coeffs_expect = (479.9553, -1372.5304, 1562.2233, -881.9685, 246.4347, -27.2447) spline3_coeffs_expect = (42.8917, -55.4965, 23.0774, -3.1314) assert pytest.approx(spline.spline5(1.3)) == 0.8227238 DeepDiff(spline5_coeffs_expect, spline.spline5.args, significant_digits=4) == {} assert pytest.approx(spline.spline3(2.4)) == -0.662829 DeepDiff(spline3_coeffs_expect, spline.spline3.args, significant_digits=4) == {} all_coefficients = spline5_coeffs_expect + spline3_coeffs_expect assert DeepDiff(all_coefficients, spline.spline_coefficients, significant_digits=4) == {} assert pytest.approx(spline(1.0)) == 6.869673 assert pytest.approx(spline(2.0)) == -0.8365282 assert pytest.approx(spline(2.1)) == -0.8797423 assert pytest.approx(spline(2.4)) == -0.662829 assert pytest.approx(spline(2.6)) == -0.4337752 assert pytest.approx(spline(2.8)) == -0.3125235
def main(): bks_buck = potentialforms.buck(18003.7572, 1.0 / 4.87318, 133.5381) bks_coul = potentialforms.coul(2.4, -1.2) bks = atsim.potentials.plus(bks_buck, bks_coul) zbl = potentialforms.zbl(14, 8) spline = atsim.potentials.SplinePotential(zbl, bks_buck, 0.8, 1.4) atsim.potentials.plot('bks_buck.dat', 0.1, 10.0, bks_buck, 5000) atsim.potentials.plot('bks_coul.dat', 0.1, 10.0, bks_coul, 5000) atsim.potentials.plot('bks.dat', 0.1, 10.0, bks, 5000) atsim.potentials.plot('zbl.dat', 0.1, 10.0, zbl, 5000) atsim.potentials.plot('spline.dat', 0.1, 10.0, spline, 5000) bks_SiO = atsim.potentials.Potential('Si', 'O', spline) with open('bks_SiO.lmptab', 'w') as outfile: atsim.potentials.writePotentials('LAMMPS', [bks_SiO], 10.0, 5000, out=outfile)
def test_exp_spline(): bks_buck = potentialforms.buck(18003.7572, 1.0 / 4.87318, 133.5381) bks_coul = potentialforms.coul(2.4, -1.2) bks = plus(bks_buck, bks_coul) zbl = potentialforms.zbl(14, 8) r_detach = 0.8 r_attach = 1.4 v_detach = zbl(r_detach) v_attach = bks_buck(r_attach) dvdr_detach = gradient(zbl) dvdr_attach = gradient(bks_buck) ddvdr_detach = gradient(dvdr_detach) ddvdr_attach = gradient(dvdr_attach) detach = Spline_Point(zbl, r_detach) attach = Spline_Point(bks_buck, r_attach) assert pytest.approx(v_detach) == detach.v assert pytest.approx(v_attach) == attach.v assert pytest.approx(dvdr_detach(r_detach)) == detach.deriv assert pytest.approx(dvdr_attach(r_attach)) == attach.deriv assert pytest.approx(ddvdr_detach(r_detach)) == detach.deriv2 assert pytest.approx(ddvdr_attach(r_attach)) == attach.deriv2 spline = Exp_Spline(detach, attach) expect = (115.86040051844031, -554.9048516522953, 1103.3742702460838, -1086.9207123704682, 526.6282598808259, -100.69558359094829, 0.0) actual = spline.spline_coefficients assert DeepDiff(expect, actual, significant_digits=5) == {}
def testPlusDeriv(): """Test that the plus() function returns wrapped functions that make use of analytical derivatives where available""" class AnalyticalDeriv(object): def __init__(self, m, deriv): self._m = m self._deriv = deriv def __call__(self, r): return self._m * r + 3.0 def deriv(self, r): return self._deriv # First test that if neither function in the plus has an analytical derivative, # that the wrapped function also doesn't have a .deriv() method def f(r): return -4.0 * r def g(r): return 10.0 * r wrapped = plus(f, g) assert not hasattr(wrapped, "deriv") assert pytest.approx(wrapped(2.0)) == 12.0 assert pytest.approx(6.0) == gradient(wrapped)(2.0) # Now test that if both functions provide analytical derivatives they are # used and the wrapped function provides a deriv function. f_a = AnalyticalDeriv(-4.0, -24.0) g_a = AnalyticalDeriv(10.0, 100.0) wrapped = plus(f_a, g_a) assert hasattr(wrapped, "deriv") assert pytest.approx(wrapped(2.0)) == 18.0 assert pytest.approx(6.0) == num_deriv(2.0, wrapped) assert pytest.approx(76.0) == wrapped.deriv(2.0) assert pytest.approx(76.0) == gradient(wrapped)(2.0) # Now test that if one of the functions doesn't provide a deriv - the # one that does is still used. wrapped = plus(f_a, g) assert hasattr(wrapped, "deriv") assert pytest.approx(wrapped(2.0)) == 15.0 assert pytest.approx(6.0) == num_deriv(2.0, wrapped) assert pytest.approx(-14.0) == wrapped.deriv(2.0) assert pytest.approx(-14.0) == gradient(wrapped)(2.0) # Now do tests for deriv2() method wrapped = plus(f, g) assert not hasattr(wrapped, "deriv2") r = 1.6 A = 1000.0 rho = 0.1 C = 32 def b_f(r): return A * math.exp(-r / rho) - C / r**6 A_h = 100.0 B_h = 50.0 def h_f(r): return (A_h / r**12) - (B_h / r**10) # Create functions with analytical derivatives b_a = potentialforms.buck(A, rho, C) h_a = potentialforms.hbnd(A_h, B_h) assert hasattr(b_a, 'deriv2') assert hasattr(h_a, 'deriv2') assert not hasattr(b_f, 'deriv2') assert not hasattr(h_f, 'deriv2') expect_energy = pytest.approx(h_f(r) + b_f(r)) wrapped_f = plus(h_f, b_f) assert not hasattr(wrapped_f, 'deriv2') assert expect_energy == wrapped_f(r) wrapped_a = plus(h_a, b_a) assert hasattr(wrapped_a, 'deriv2') assert expect_energy == wrapped_a(r) wrapped_m = plus(h_f, b_a) assert hasattr(wrapped_m, 'deriv2') assert expect_energy == wrapped_m(r) expect = pytest.approx(-29.1717612428203) expect_loose = pytest.approx(-29.1717612428203, rel=1e-4) assert expect_loose == gradient(gradient(wrapped_f))(r) assert expect == gradient(gradient(wrapped_a))(r) assert expect_loose == gradient(gradient(wrapped_m))(r) assert expect == wrapped_a.deriv2(r) assert expect_loose == wrapped_m.deriv2(r) # Now let's deliberately change the deriv2 returned by h_a and b_a to make sure the analytical forms are being used. def d2(self, r): return 20.0 def d2_2(self, r): return 30.0 h_a.deriv2 = types.MethodType(d2, h_a) #, h_a.__class__) b_a.deriv2 = types.MethodType(d2_2, b_a) #, b_a.__class__) wrapped = plus(h_a, b_a) assert pytest.approx(20.0 + 30.0) == wrapped.deriv2(r) assert pytest.approx(20.0 + 30.0) == gradient(gradient(wrapped))(r)
def testPlus(): potfunc = plus(potentialforms.buck(1388.773, 2.76, 175.0), potentialforms.hbnd(300.0, 20.0)) pytest.approx(1198278.65656831) == potfunc(0.5)
def test_buck4_spline(): A = 11272.6 rho = 0.1363 C = 134.0 born_mayer = potentialforms.bornmayer(A, rho) dispersion = potentialforms.buck(0, 1, C) r_detach = 1.2 r_min = 2.1 r_attach = 2.6 spline = atsim.potentials.spline.Buck4_SplinePotential( born_mayer, dispersion, r_detach, r_attach, r_min) disp_spline = PotentialFormInstanceTuple(potential_form="as.buck", parameters=[0.0, 1.0, C], start=MultiRangeDefinitionTuple( '>', r_attach), next=None) buck4_spline = PotentialFormInstanceTuple(potential_form="buck4_spline", parameters=[r_min], start=MultiRangeDefinitionTuple( ">=", r_detach), next=disp_spline) bm_spline = PotentialFormInstanceTuple(potential_form="as.bornmayer", parameters=[A, rho], start=MultiRangeDefinitionTuple( ">", 0.0), next=buck4_spline) pmt = PotentialModifierTuple(modifier='spline', potential_forms=[bm_spline], start=MultiRangeDefinitionTuple('>', 0.0), next=None) pfr = Potential_Form_Registry(ConfigParser(io.StringIO()), True) mr = Modifier_Registry() pfb = Potential_Form_Builder(pfr, mr) mod_spline = pfb.create_potential_function(pmt) for i in range(1, 100): r = float(i) / 10.0 expect = spline(r) actual = mod_spline(r) assert pytest.approx(expect, abs=1e-3) == actual assert pytest.approx(born_mayer(0.7)) == mod_spline(0.7) assert pytest.approx(dispersion(3.0)) == mod_spline(3.0) assert pytest.approx(spline(2.0)) == mod_spline(2.0) assert pytest.approx(spline(2.4)) == mod_spline(2.4) assert pytest.approx(born_mayer.deriv(0.7)) == mod_spline.deriv(0.7) assert pytest.approx(dispersion.deriv(3.0)) == mod_spline.deriv(3.0) assert pytest.approx(spline.deriv(2.0)) == mod_spline.deriv(2.0) assert pytest.approx(spline.deriv(2.4)) == mod_spline.deriv(2.4) assert pytest.approx(born_mayer.deriv2(0.7)) == mod_spline.deriv2(0.7) assert pytest.approx(dispersion.deriv2(3.0)) == mod_spline.deriv2(3.0) assert pytest.approx(spline.deriv2(2.0)) == mod_spline.deriv2(2.0) assert pytest.approx(spline.deriv2(2.4)) == mod_spline.deriv2(2.4)
def test_structure(tmpdir): gulp_input = u"""single cell 5.468 5.468 5.468 90.0 90.0 90.0 frac U 0 0 0 U 1/2 1/2 0 U 1/2 0 1/2 U 0 1/2 1/2 O 1/4 1/4 1/4 O 1/4 3/4 1/4 O 3/4 3/4 1/4 O 3/4 1/4 1/4 O 1/4 1/4 3/4 O 1/4 3/4 3/4 O 3/4 3/4 3/4 O 3/4 1/4 3/4 species U 4.0 O -2.0 include potentials.lib""" # First calculate the expected energy using GULP's built-in analytical potentials with tmpdir.join("potentials.lib").open("w") as potfile: potfile.write("buck\n") potfile.write("O O 9547.96 0.2192 32.0 15.0\n") potfile.write("O U 1761.775 0.35642 0.0 15.0\n") gulp_infile = io.StringIO(gulp_input) gulp_infile.seek(0) gulp_outfile = io.StringIO() runGULP(gulp_infile, gulp_outfile, cwd=tmpdir.strpath) gulp_outfile.seek(0) expect = extractGULPEnergy(gulp_outfile) tmpdir.join("potentials.lib").remove() assert not tmpdir.join("potentials.lib").exists() # Now build a potential model and tabulate it - then re-run the calculation and check the energies match. pot_OO = Potential( "O", "O", create_Multi_Range_Potential_Form( Multi_Range_Defn(">", 0, potentialforms.buck(9547.96, 0.2192, 32.0)))) pot_UO = Potential( "U", "O", create_Multi_Range_Potential_Form( Multi_Range_Defn(">", 0, potentialforms.bornmayer(1761.775, 0.35642)))) potlist = [pot_OO, pot_UO] tabulation = pair_tabulation.GULP_PairTabulation(potlist, 15.0, 500) with tmpdir.join("potentials.lib").open("w") as potfile: tabulation.write(potfile) gulp_infile.seek(0) gulp_outfile = io.StringIO() runGULP(gulp_infile, gulp_outfile, cwd=tmpdir.strpath) gulp_outfile.seek(0) actual = extractGULPEnergy(gulp_outfile) assert pytest.approx(expect) == actual tmpdir.join("potentials.lib").remove() assert not tmpdir.join("potentials.lib").exists() # Now do the same again but use the procedural interface with tmpdir.join("potentials.lib").open("w") as potfile: writePotentials("GULP", potlist, 15.0, 500, out=potfile) gulp_infile.seek(0) gulp_outfile = io.StringIO() runGULP(gulp_infile, gulp_outfile, cwd=tmpdir.strpath) gulp_outfile.seek(0) actual = extractGULPEnergy(gulp_outfile) assert pytest.approx(expect) == actual
def testExample(self): """Test example basak_tabulate.py""" from atsim.potentials import potentialforms import itertools exampleModule = _loadModule(self.test_name) dldir = _getDLPolyResourceDirectory() oldpwd = os.getcwd() try: os.chdir(self.tempdir) shutil.copyfile(os.path.join(dldir, "CONTROL_pair"), "CONTROL") exampleModule.main() def dotest(d, testfunc): # exampleModule.main() pobjs = exampleModule.makePotentialObjects() species = [d["speciesA"], d["speciesB"]] spairs = [ tuple(sorted(p)) for p in itertools.combinations_with_replacement( species, 2) ] species = set(spairs) pobjs = [ p for p in pobjs if tuple(sorted([p.speciesA, p.speciesB])) in species ] with open('TABLE', 'w') as outfile: atsim.potentials.writePotentials('DL_POLY', pobjs, 6.5, 6500, out=outfile) d = dict(d) for i in range(4): r = float(i) r += 1.0 expect = testfunc(r) d['Ax'] = r with open(os.path.join(dldir, "CONFIG_pair.in"), 'r') as infile: with open("CONFIG", "w") as outfile: outfile.write(infile.read() % d) from io import StringIO sio = StringIO() print(u"vdw %d" % len(pobjs), file=sio) for p in pobjs: print(u"%s %s tab" % (p.speciesA, p.speciesB), file=sio) d["potDef"] = sio.getvalue() with open(os.path.join(dldir, "FIELD_pair.in"), 'r') as infile: with open("FIELD", "w") as outfile: outfile.write(infile.read() % d) runDLPoly() dlenergy = extractDLPOLYEnergy() self.assertAlmostEqual(expect, dlenergy, places=4) os.remove("STATIS") os.remove("CONFIG") os.remove("FIELD") d = dict(speciesA="O", speciesB="O", Ax=0.0, Ay=0.0, Az=0.0, Bx=0.0, By=0.0, Bz=0.0) testfunc = potentialforms.buck(1633.00510, 0.327022, 3.948790) dotest(d, testfunc) d = dict(speciesA="U", speciesB="U", Ax=0.0, Ay=0.0, Az=0.0, Bx=0.0, By=0.0, Bz=0.0) testfunc = potentialforms.buck(294.640000, 0.327022, 0.0) dotest(d, testfunc) d = dict(speciesA="O", speciesB="U", Ax=0.0, Ay=0.0, Az=0.0, Bx=0.0, By=0.0, Bz=0.0) buck_OU = potentialforms.buck(693.648700, 0.327022, 0.0) morse_OU = potentialforms.morse(1.6500, 2.36900, 0.577190) testfunc = atsim.potentials.plus(buck_OU, morse_OU) dotest(d, testfunc) finally: os.chdir(oldpwd)