def fit_density_functions(setfl_fn): from pypospack.eamtools import SeatonSetflReader setfl = SeatonSetflReader(path=setfl_fn) setfl.read() rdata = create_r(setfl.n_r*setfl.d_r,setfl.n_r) rhodata = setfl.density_function('Ni') param_names = ['r0','A0','B0','C0','y','gamma','rc','h'] p0 = [Ni_dens_params[k] for k in param_names] from scipy.optimize import curve_fit popt,pcov = curve_fit( func_mishin2003_density_w_cutoff, rdata,rhodata, method='dogbox', p0=p0) plot_fitted_density_functions( rdata, rhodata, func_mishin2003_density_w_cutoff(rdata,*popt)) for k in zip(param_names,p0,popt): print(k) return OrderedDict([k for k in zip(param_names,popt)])
def fit_pair_potentials(setfl_fn): from pypospack.eamtools import SeatonSetflReader setfl = SeatonSetflReader(path=setfl_fn) setfl.read() param_names = ['b1','b2','r1','V0','delta','rc','h'] param_0 = [NiNi_pair_params[k] for k in param_names] rdata = create_r(setfl.n_r*setfl.d_r,setfl.n_r) phidata = np.array(setfl.pair_function('NiNi'))/rdata rdata_2 = rdata[rdata>1.5] phidata_2 = phidata[rdata>1.5] param_0 from scipy.optimize import curve_fit while True: param_opt,pocv = curve_fit( func_generalized_lj_w_cutoff, rdata_2,phidata_2, method='trf', p0=param_0) for k in zip(param_names,param_0,param_opt): print(k) if all([np.abs(k[1]/k[0]-1) < 0.01 for k in zip(param_opt,param_0)]): break param_0 = param_opt plot_pair_potential( rdata, phidata, func_generalized_lj_w_cutoff(rdata,*param_opt))
def plot_eam_potential_from_setflfile(filename): import matplotlib.pyplot as plt fig, ax = plt.subplots(3, 1) setfl = SeatonSetflReader(path=setfl_filename) setfl.read() # plot the pair potential function for pair in setfl.element_pairs: pair_x = create_r(setfl.n_r * setfl.d_r, setfl.n_r) pair_y = setfl.pair_function(pair) / pair_x ax[0].plot(pair_x, pair_y, label=pair) ax[0].legend() # plot the density functions for s in setfl.elements: dens_x = create_r(setfl.n_r * setfl.d_r, setfl.n_r) dens_y = setfl.density_function(s) ax[1].plot(dens_x, dens_y, label=s) ax[1].legend() # plot the embedding energy function for s in setfl.elements: embed_x = create_r(setfl.n_rho * setfl.d_rho, setfl.n_rho) embed_y = setfl.embedding_function(s) ax[2].plot(embed_x, embed_y, label=s) ax[2].legend() fig.tight_layout() plt.show()
class EamPotentialFitter(object): """ class of determining the parameters from a SETFL file This class will determine the optimum parameters for a given formalism given a setfl file. See the testing directory for an example on how to use this. Currently only works for elemental systems Args: symbols (list): a list of chemical symbols Attributes: pair_potentials (OrderedDict): key is the pair in `NiNi` format. density_functions (OrderedDict): key is the density in 'Ni' format. One density function per element. embedding_functions (OrderedDict): key is the pair in `Ni' format. One embedding function per element setfl_reader (SeatonSetflReader): """ def __init__(self, symbols): self.symbols = symbols self.pair_potentials = OrderedDict([ ("".join(k), None) for k in determine_eam_setfl_pairs(symbols) ]) self.density_functions = OrderedDict([(k, None) for k in symbols]) self.embedding_functions = OrderedDict([(k, None) for k in symbols]) pair_names = ["".join(k) for k in determine_eam_setfl_pairs(symbols)] self.parameters = OrderedDict() self.parameters['p0'] = OrderedDict() self.parameters['p0']['pair'] = OrderedDict([(k, None) for k in pair_names]) self.parameters['p0']['embedding'] = OrderedDict([(k, None) for k in symbols]) self.parameters['p0']['density'] = OrderedDict([(k, None) for k in symbols]) self.parameters['popt'] = OrderedDict() self.parameters['popt']['pair'] = OrderedDict([(k, None) for k in pair_names]) self.parameters['popt']['embedding'] = OrderedDict([(k, None) for k in symbols]) self.parameters['popt']['density'] = OrderedDict([(k, None) for k in symbols]) self.formalisms = OrderedDict() self.formalisms['pair'] = OrderedDict([(k, None) for k in pair_names]) self.formalisms['embedding'] = OrderedDict([(k, None) for k in symbols]) self.formalisms['density'] = OrderedDict([(k, None) for k in symbols]) self.setfl_reader = None def initialize_from_setfl_file(filename): pass def read_setfl_file(self, filename): """ reads a setfl file This method creates an instance of SeatonSetflReader Args: filename (str): the path to the SETFL file """ self.setfl_reader = SeatonSetflReader(path=filename) self.setfl_reader.read() def fit_potential_pair(self, func_pair_potential, symbol_pair, param0, rlow=None): if not isinstance(self.setfl_reader, SeatonSetflReader): m = "the read_setfl_command method must be run before this method" raise EamSetflFitterException(m) pair_name = "".join(symbol_pair) arg_names = [ k for k in inspect.signature(func_pair_potential).parameters if k != 'r' ] p0 = [param0[k] for k in arg_names if k != 'r'] # maximum interatomic spacing distance rmax = self.setfl_reader.n_r * self.setfl_reader.d_r # interatomic spacing distance step size rN = self.setfl_reader.n_r if rlow is None: r = create_r(rmax, rN) phi = np.array(self.setfl_reader.pair_function(pair_name)) else: r_ = create_r(rmax, rN) phi_ = np.array(self.setfl_reader.pair_function(pair_name)) r = r_[r_ > rlow] phi = phi_[r_ > rlow] # iterate until convergence while True: popt, pcov = curve_fit(func_pair_potential, r, phi, method='trf', p0=p0) if all([np.abs(k[1] / k[0] - 1) < 0.01 for k in zip(popt, p0)]): break p0 = popt self.parameters['p0']['pair'][pair_name] = param0 self.parameters['popt']['pair'][pair_name] = OrderedDict([ (k[0], k[1]) for k in zip(arg_names, popt) ]) self.formalisms['pair'][pair_name] = func_pair_potential def fit_density_function(self, func_density, symbol, param0, rlow=None): if not isinstance(self.setfl_reader, SeatonSetflReader): m = "the read_setfl_command method must be run before this method" raise EamSetflFitterException(m) arg_names = [ k for k in inspect.getargspec(func_density)[0] if k != 'r' ] p0 = [param0[k] for k in arg_names] # maximum interatomic spacing distance rmax = self.setfl_reader.n_r * self.setfl_reader.d_r # interatomic spacing distance step size rN = self.setfl_reader.n_r if rlow is None: r = create_r(rmax, rN) rho = np.array(self.setfl_reader.density_function(symbol)) else: # temporary arrays r_ = create_r(rmax, rN) rho_ = np.array(self.setfl_reader.density_function(symbol)) # final arrays r = r_[r_ > rlow] rho = rho_[r_ > rlow] # iterate until convergence while True: popt, pcov = curve_fit(func_density, r, rho, method='trf', p0=p0) if all([np.abs(k[1] / k[0] - 1) < 0.01 for k in zip(popt, p0)]): break p0 = popt self.parameters['p0']['density'][symbol] = param0 self.parameters['popt']['density'][symbol] = OrderedDict([ (k[0], k[1]) for k in zip(arg_names, popt) ]) self.formalisms['density'][symbol] = func_density def fit_embedding_function(self, func_embedding_function, symbol, param0): raise NotImplementedError def fit_analytical_embedding_function(self): raise NotImplementedError def fit_eos_embedding_function(self, func_embedding, symbol, param0, bounds=None): arg_names = [ k for k in inspect.getargspec(func_embedding)[0] \ if k not in ['rho','lattice_type'] ] p0 = [param0[k] for k in arg_names] # maximum interatomic spacing distance rhomax = self.setfl_reader.n_rho * self.setfl_reader.d_rho # interatomic spacing distance step size rhoN = self.setfl_reader.n_rho rho = create_rho(rhomax, rhoN) embedding = np.array(self.setfl_reader.density_function(symbol)) print(param0) # iterate until convergence while True: try: popt, pcov = curve_fit(func_embedding, rho, embedding, method='trf', p0=p0, bounds=bounds) except ValueError: print(param0) print([(k[0], k[1]) for k in zip(arg_names, popt)]) print([(k[0], k[1]) for k in zip(arg_names, popt)]) if all([np.abs(k[1] / k[0] - 1) < 0.01 for k in zip(popt, p0)]): break p0 = popt self.parameters['p0']['embedding'][symbol] = param0 self.parameters['popt']['embedding'][symbol] = OrderedDict([ (k[0], k[1]) for k in zip(arg_names, popt) ]) self.formalisms['embedding'][symbol] = func_embedding
fig.tight_layout() plt.show() if __name__ == "__main__": #setfl_filename = os.path.join( # 'test_EamSetflFile', # 'Ni1_Mendelev_2010.eam.fs') setfl_filename = os.path.join( pypospack.utils.get_pypospack_root_directory(), 'data', 'potentials', 'Ni__eam', 'Mishin-Ni-Al-2009.eam.alloy') setfl_reader = SeatonSetflReader(path=setfl_filename) setfl_reader.read() print("elements: ", setfl_reader.elements) print("element_pairs: ", setfl_reader.element_pairs) print("n_rho: ", setfl_reader.n_rho) print("d_rho: ", setfl_reader.d_rho) print("n_r: ", setfl_reader.n_r) print("d_r: ", setfl_reader.d_r) print("cutoff: ", setfl_reader.cutoff) assert len(setfl_reader.embedding_function("Ni")) == setfl_reader.n_r assert len(setfl_reader.density_function("Ni")) == setfl_reader.n_rho assert len(setfl_reader.pair_function("NiNi")) == setfl_reader.n_r plot_eam_potential_from_setflfile(setfl_filename)