def test_average_atom_Fe_Cu_Ni(self): """Create A-atom potential for a Fe-Cu-Ni eam/alloy potential at equicomposition The input potential is from Ref. [1]_ and was downloaded from the NIST database [2]_. The generated The generated A-atom potential is compared to a reference A-atom potential, which was created with an independent implementation. This is not a very strong test, but should capture some regressions. References ---------- [1] G. Bonny, R.C. Pasianot, N. Castin, and L. Malerba (2009), "Ternary Fe-Cu-Ni many-body potential to model reactor pressure vessel steels: First validation by simulated thermal annealing", Philosophical Magazine, 89(34-36), 3531-3546. DOI: 10.1080/14786430903299824. [2] https://www.ctcms.nist.gov/potentials/Download/2009--Bonny-G-Pasianot-R-C-Castin-N-Malerba-L--Fe-Cu-Ni/1/FeCuNi.eam.alloy """ input_table = "FeCuNi.eam.alloy" reference_table = "FeCuNi_reference_A-atom_Fe33Cu33Ni33.eam.alloy" concentrations = np.array((1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0)) source, parameters, F, f, rep = io.read_eam(input_table) (new_parameters, new_F, new_f, new_rep) = average_atom.average_potential(concentrations, parameters, F, f, rep) ref_source, ref_parameters, ref_F, ref_f, ref_rep = io.read_eam( reference_table) diff_F = np.linalg.norm(ref_F - new_F) diff_f = np.linalg.norm(ref_f - new_f) diff_rep = np.linalg.norm(ref_rep - new_rep) print(diff_F, diff_f, diff_rep) self.assertTrue(diff_F < self.tol) self.assertTrue(diff_f < self.tol) self.assertTrue(diff_rep < self.tol)
def test_eam_alloy_read_write(self): source, parameters, F, f, rep = read_eam("CuAgNi_Zhou.eam.alloy", kind="eam/alloy") write_eam(source, parameters, F, f, rep, "CuAgNi_Zhou.eam.alloy_copy", kind="eam/alloy") source1, parameters1, F1, f1, rep1 = read_eam( "CuAgNi_Zhou.eam.alloy_copy", kind="eam/alloy") os.remove("CuAgNi_Zhou.eam.alloy_copy") fail = 0 for i, p in enumerate(parameters): try: for j, d in enumerate(p): if d != parameters[i][j]: fail += 1 except: if p != parameters[i]: fail += 1 self.assertTrue(fail == 0) self.assertTrue((F == F1).all()) self.assertTrue((f == f1).all()) for i in range(len(rep)): for j in range(len(rep)): if j < i: self.assertTrue((rep[i, j, :] == rep1[i, j, :]).all())
def test_average_atom_Ni_Al(self): """Create A-atom potential for a Ni-Al eam/alloy potential and 15% Al The input potential is from Ref. [1]_ and was downloaded from the NIST database [2]_. The generated The generated A-atom potential is compared to a reference A-atom potential, which was created with an independent implementation. This is not a very strong test, but should capture some regressions. References ---------- [1] G.P. Purja Pun, and Y. Mishin (2009), "Development of an interatomic potential for the Ni-Al system", Philosophical Magazine, 89(34-36), 3245-3267. DOI: 10.1080/14786430903258184. [2] https://www.ctcms.nist.gov/potentials/Download/2009--Purja-Pun-G-P-Mishin-Y--Ni-Al/2/Mishin-Ni-Al-2009.eam.alloy """ input_table = "Mishin-Ni-Al-2009.eam.alloy" reference_table = "Mishin-Ni-Al-2009_reference_A-atom_Ni85Al15.eam.alloy" concentrations = np.array((0.85, 0.15)) source, parameters, F, f, rep = io.read_eam(input_table) (new_parameters, new_F, new_f, new_rep) = average_atom.average_potential(concentrations, parameters, F, f, rep) ref_source, ref_parameters, ref_F, ref_f, ref_rep = io.read_eam( reference_table) diff_F = np.linalg.norm(ref_F - new_F) diff_f = np.linalg.norm(ref_f - new_f) diff_rep = np.linalg.norm(ref_rep - new_rep) print(diff_F, diff_f, diff_rep) self.assertTrue(diff_F < self.tol) self.assertTrue(diff_f < self.tol) self.assertTrue(diff_rep < self.tol)
def __init__(self, fn=None, atomic_numbers=None, F=None, f=None, rep=None, cutoff=None, kind='eam/alloy'): Calculator.__init__(self) if fn is not None: source, parameters, F, f, rep = read_eam(fn, kind=kind) self.atnums = parameters.atomic_numbers self.cutoff = parameters.cutoff dr = parameters.distance_grid_spacing dF = parameters.density_grid_spacing # Create spline interpolation self.F = _make_splines(dF, F) self.f = _make_splines(dr, f) self.rep = _make_splines(dr, rep) else: self.atnums = atomic_numbers self.F = F self.f = f self.rep = rep self.cutoff = cutoff self.atnum_to_index = -np.ones(np.max(self.atnums)+1, dtype=int) self.atnum_to_index[self.atnums] = \ np.arange(len(self.atnums)) # Derivative of spline interpolation self.dF = _make_derivative(self.F) self.df = _make_derivative(self.f) self.drep = _make_derivative(self.rep)
def average(input_table, output_table, concentrations): """Create Average-atom potential for an Embedded Atom Method potential Read an EAM potential from INPUT_TABLE, create the Average-atom potential for the random alloy with composition specified by CONCENTRATIONS and write a new table with both the original and the A-atom potential functions to OUTPUT_TABLE. CONCENTRATIONS is a whitespace-separated list of the concentration of the elements, in the order in which the appear in the input table. """ source, parameters, F, f, rep = io.read_eam(input_table) (new_parameters, new_F, new_f, new_rep) = average_atom.average_potential( np.array(concentrations, dtype=float), parameters, F, f, rep ) composition = " ".join( [str(c * 100.0) + f"% {e}," for c, e in zip(np.array(concentrations, dtype=float), parameters.symbols)] ) composition = composition.rstrip(",") source += f", averaged for composition {composition}" io.write_eam( source, new_parameters, new_F, new_f, new_rep, output_table, kind="eam/alloy", )
def test_mix_eam_alloy(self): if False: source,parameters,F,f,rep = read_eam("CuAu_Zhou.eam.alloy",kind="eam/alloy") source1,parameters1,F1,f1,rep1 = mix_eam(["Cu_Zhou.eam.alloy","Au_Zhou.eam.alloy"],"eam/alloy","weight") write_eam(source1,parameters1,F1,f1,rep1,"CuAu_mixed.eam.alloy",kind="eam/alloy") calc0 = EAM('CuAu_Zhou.eam.alloy') calc1 = EAM('CuAu_mixed.eam.alloy') a = FaceCenteredCubic('Cu', size=[2,2,2]) a.set_calculator(calc0) FIRE(StrainFilter(a, mask=[1,1,1,0,0,0]), logfile=None).run(fmax=0.001) e0 = a.get_potential_energy()/len(a) a = FaceCenteredCubic('Cu', size=[2,2,2]) a.set_calculator(calc1) FIRE(StrainFilter(a, mask=[1,1,1,0,0,0]), logfile=None).run(fmax=0.001) e1 = a.get_potential_energy()/len(a) self.assertTrue(e0-e1 < 0.0005) a = FaceCenteredCubic('Au', size=[2,2,2]) a.set_calculator(calc0) FIRE(StrainFilter(a, mask=[1,1,1,0,0,0]), logfile=None).run(fmax=0.001) e0 = a.get_potential_energy()/len(a) a = FaceCenteredCubic('Au', size=[2,2,2]) a.set_calculator(calc1) FIRE(StrainFilter(a, mask=[1,1,1,0,0,0]), logfile=None).run(fmax=0.001) e1 = a.get_potential_energy()/len(a) self.assertTrue(e0-e1 < 0.0005) a = L1_2(['Au', 'Cu'], size=[2,2,2], latticeconstant=4.0) a.set_calculator(calc0) FIRE(UnitCellFilter(a, mask=[1,1,1,0,0,0]), logfile=None).run(fmax=0.001) e0 = a.get_potential_energy()/len(a) a = L1_2(['Au', 'Cu'], size=[2,2,2], latticeconstant=4.0) a.set_calculator(calc1) FIRE(UnitCellFilter(a, mask=[1,1,1,0,0,0]), logfile=None).run(fmax=0.001) e1 = a.get_potential_energy()/len(a) self.assertTrue(e0-e1 < 0.0005) a = L1_2(['Cu', 'Au'], size=[2,2,2], latticeconstant=4.0) a.set_calculator(calc0) FIRE(UnitCellFilter(a, mask=[1,1,1,0,0,0]), logfile=None).run(fmax=0.001) e0 = a.get_potential_energy()/len(a) a = L1_2(['Cu', 'Au'], size=[2,2,2], latticeconstant=4.0) a.set_calculator(calc1) FIRE(UnitCellFilter(a, mask=[1,1,1,0,0,0]), logfile=None).run(fmax=0.001) e1 = a.get_potential_energy()/len(a) self.assertTrue(e0-e1 < 0.0005) a = B1(['Au', 'Cu'], size=[2,2,2], latticeconstant=4.0) a.set_calculator(calc0) FIRE(UnitCellFilter(a, mask=[1,1,1,0,0,0]), logfile=None).run(fmax=0.001) e0 = a.get_potential_energy()/len(a) a = B1(['Au', 'Cu'], size=[2,2,2], latticeconstant=4.0) a.set_calculator(calc1) FIRE(UnitCellFilter(a, mask=[1,1,1,0,0,0]), logfile=None).run(fmax=0.001) e1 = a.get_potential_energy()/len(a) self.assertTrue(e0-e1 < 0.0005) os.remove("CuAu_mixed.eam.alloy")
def test_eam_read_write(self): source,parameters,F,f,rep = read_eam("Au_u3.eam",kind="eam") write_eam(source,parameters,F,f,rep,"Au_u3_copy.eam",kind="eam") source1,parameters1,F1,f1,rep1 = read_eam("Au_u3_copy.eam",kind="eam") os.remove("Au_u3_copy.eam") for i,p in enumerate(parameters): try: diff = p - parameters1[i] except: diff = None if diff is None: self.assertTrue(p == parameters1[i]) else: print(i, p, parameters1[i], diff, self.tol, diff < self.tol) self.assertTrue(diff < self.tol) self.assertTrue((F == F1).all()) self.assertTrue((f == f1).all()) self.assertTrue((rep == rep1).all())
def test_eam_read_write(self): source, parameters, F, f, rep = read_eam("Au_u3.eam", kind="eam") write_eam(source, parameters, F, f, rep, "Au_u3_copy.eam", kind="eam") source1, parameters1, F1, f1, rep1 = read_eam("Au_u3_copy.eam", kind="eam") os.remove("Au_u3_copy.eam") for i, p in enumerate(parameters): try: diff = p - parameters1[i] except: diff = None if diff is None: self.assertTrue(p == parameters1[i]) else: print(i, p, parameters1[i], diff, self.tol, diff < self.tol) self.assertTrue(diff < self.tol) self.assertTrue((F == F1).all()) self.assertTrue((f == f1).all()) self.assertArrayAlmostEqual(rep, rep1)
def test_eam_alloy_read_write(self): source,parameters,F,f,rep = read_eam("CuAgNi_Zhou.eam.alloy",kind="eam/alloy") write_eam(source,parameters,F,f,rep,"CuAgNi_Zhou.eam.alloy_copy",kind="eam/alloy") source1,parameters1,F1,f1,rep1 = read_eam("CuAgNi_Zhou.eam.alloy_copy",kind="eam/alloy") os.remove("CuAgNi_Zhou.eam.alloy_copy") fail = 0 for i,p in enumerate(parameters): try: for j,d in enumerate(p): if d != parameters[i][j]: fail+=1 except: if p != parameters[i]: fail +=1 self.assertTrue(fail == 0) self.assertTrue((F == F1).all()) self.assertTrue((f == f1).all()) for i in range(len(rep)): for j in range(len(rep)): if j < i : self.assertTrue((rep[i,j,:] == rep1[i,j,:]).all())
def test_mix_eam_alloy(self): if False: source, parameters, F, f, rep = read_eam("CuAu_Zhou.eam.alloy", kind="eam/alloy") source1, parameters1, F1, f1, rep1 = mix_eam( ["Cu_Zhou.eam.alloy", "Au_Zhou.eam.alloy"], "eam/alloy", "weight") write_eam(source1, parameters1, F1, f1, rep1, "CuAu_mixed.eam.alloy", kind="eam/alloy") calc0 = EAM('CuAu_Zhou.eam.alloy') calc1 = EAM('CuAu_mixed.eam.alloy') a = FaceCenteredCubic('Cu', size=[2, 2, 2]) a.set_calculator(calc0) FIRE(StrainFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) e0 = a.get_potential_energy() / len(a) a = FaceCenteredCubic('Cu', size=[2, 2, 2]) a.set_calculator(calc1) FIRE(StrainFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) e1 = a.get_potential_energy() / len(a) self.assertTrue(e0 - e1 < 0.0005) a = FaceCenteredCubic('Au', size=[2, 2, 2]) a.set_calculator(calc0) FIRE(StrainFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) e0 = a.get_potential_energy() / len(a) a = FaceCenteredCubic('Au', size=[2, 2, 2]) a.set_calculator(calc1) FIRE(StrainFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) e1 = a.get_potential_energy() / len(a) self.assertTrue(e0 - e1 < 0.0005) a = L1_2(['Au', 'Cu'], size=[2, 2, 2], latticeconstant=4.0) a.set_calculator(calc0) FIRE(UnitCellFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) e0 = a.get_potential_energy() / len(a) a = L1_2(['Au', 'Cu'], size=[2, 2, 2], latticeconstant=4.0) a.set_calculator(calc1) FIRE(UnitCellFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) e1 = a.get_potential_energy() / len(a) self.assertTrue(e0 - e1 < 0.0005) a = L1_2(['Cu', 'Au'], size=[2, 2, 2], latticeconstant=4.0) a.set_calculator(calc0) FIRE(UnitCellFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) e0 = a.get_potential_energy() / len(a) a = L1_2(['Cu', 'Au'], size=[2, 2, 2], latticeconstant=4.0) a.set_calculator(calc1) FIRE(UnitCellFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) e1 = a.get_potential_energy() / len(a) self.assertTrue(e0 - e1 < 0.0005) a = B1(['Au', 'Cu'], size=[2, 2, 2], latticeconstant=4.0) a.set_calculator(calc0) FIRE(UnitCellFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) e0 = a.get_potential_energy() / len(a) a = B1(['Au', 'Cu'], size=[2, 2, 2], latticeconstant=4.0) a.set_calculator(calc1) FIRE(UnitCellFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) e1 = a.get_potential_energy() / len(a) self.assertTrue(e0 - e1 < 0.0005) os.remove("CuAu_mixed.eam.alloy")