def fit(phase): db = connect(DB_NAME) if phase == 'fcc': ref_fcc = db.get(id=1).toatoms() elif phase == 'fcc2x2x2': ref_fcc = db.get(group=3).toatoms() else: ref_fcc = db.get(id=41) structures = [] groups = [] scond = [('phase', '=', phase), ('rattle_std', '<', 0.02)] for row in db.select(scond): groups.append(row.group) for g in groups: try: atoms = db.get(group=g, struct_type='final').toatoms() structures.append(atoms) except Exception as exc: print(exc) structures = prepare_structures(structures, ref_fcc) cutoffs = [3.0, 3.0, 3.0] cs = ClusterSpace(structures[0], cutoffs, symprec=1e-4) print(cs) print(structures) sc = StructureContainer(cs) for structure in structures: try: sc.add_structure(structure) except Exception as exc: print(exc) print(sc) A, y = sc.get_fit_data() At = get_rotational_constraint_matrix(sc.cluster_space) yt = np.zeros((At.shape[0])) lam_trans = 0.001 A_full = np.vstack((A, lam_trans * At)) y_full = np.hstack((y, yt)) # A_full = A # y_full = y opt = Optimizer((A_full, y_full), standardize=False) opt.train() #plot_fit(opt, sc) print(opt) fcp = ForceConstantPotential(cs, opt.parameters) fcp.write(f'mgsi_{phase}.fcp') print(fcp)
def phonon_dos(fcp_file): if 'fcc2x2x2' in fcp_file: prim = read(ref_fcc_conv2x2x2) else: prim = read(ref_fcc) fcp = ForceConstantPotential.read(fcp_file) mesh = [33, 33, 33] atoms_phonopy = PhonopyAtoms(symbols=prim.get_chemical_symbols(), scaled_positions=prim.get_scaled_positions(), cell=prim.cell) phonopy = Phonopy(atoms_phonopy, supercell_matrix=5 * np.eye(3), primitive_matrix=None) supercell = phonopy.get_supercell() supercell = Atoms(cell=supercell.cell, numbers=supercell.numbers, pbc=True, scaled_positions=supercell.get_scaled_positions()) fcs = fcp.get_force_constants(supercell) phonopy.set_force_constants(fcs.get_fc_array(order=2)) phonopy.set_mesh(mesh, is_eigenvectors=True, is_mesh_symmetry=False) phonopy.run_total_dos() phonopy.plot_total_DOS() plt.savefig("phononDOS.png", dpi=200) Nq = 51 G2X = get_band(np.array([0, 0, 0]), np.array([0.5, 0.5, 0]), Nq) X2K2G = get_band(np.array([0.5, 0.5, 1.0]), np.array([0, 0, 0]), Nq) G2L = get_band(np.array([0, 0, 0]), np.array([0.5, 0.5, 0.5]), Nq) bands = [G2X, X2K2G, G2L] phonopy.set_band_structure(bands) phonopy.plot_band_structure() xticks = plt.gca().get_xticks() xticks = [x * hbar * 1e15 for x in xticks] # Convert THz to meV # plt.gca().set_xticks(xticks) plt.gca().set_xlabel("Frequency (THz)") plt.savefig("phononBand.png", dpi=200) phonopy.run_thermal_properties(t_step=10, t_max=800, t_min=100) tp_dict = phonopy.get_thermal_properties_dict() temperatures = tp_dict['temperatures'] free_energy = tp_dict['free_energy'] fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.plot(temperatures, free_energy) plt.show()
def md_calculation(fcp_file): from ase import units from ase.io.trajectory import Trajectory from ase.md.velocitydistribution import MaxwellBoltzmannDistribution from ase.md.langevin import Langevin from ase.md import MDLogger if 'fcc' in fcp_file: ref_cell = read(ref_fcc) P = np.array([[-1, 1, 1], [1, -1, 1], [1, 1, -1]]) P *= 3 atoms = make_supercell(ref_cell, P) else: raise ValueError("Unknown phase") fcp = ForceConstantPotential.read(fcp_file) fcs = fcp.get_force_constants(atoms) calc = ForceConstantCalculator(fcs) atoms.set_calculator(calc) temperature = 200 number_of_MD_steps = 100 time_step = 5 # in fs dump_interval = 10 traj_file = "data/md_" + fcp_file.split('.')[0] + '{}.traj'.format( temperature) log_file = "data/md_log_{}.log".format(temperature) dyn = Langevin(atoms, time_step * units.fs, temperature * units.kB, 0.02) logger = MDLogger(dyn, atoms, log_file, header=True, stress=False, peratom=True, mode='w') traj_writer = Trajectory(traj_file, 'w', atoms) dyn.attach(logger, interval=dump_interval) dyn.attach(traj_writer.write, interval=dump_interval) # run MD MaxwellBoltzmannDistribution(atoms, temperature * units.kB) dyn.run(number_of_MD_steps)
def get_fc2(supercell, primitive, displacements, forces, atom_list=None, options=None, log_level=0): if options is None: option_dict = {} else: option_dict = decode_options(options) structures = [] for d, f in zip(displacements, forces): structure = Atoms(cell=supercell.cell, scaled_positions=supercell.scaled_positions, numbers=supercell.numbers, pbc=True) structure.new_array('displacements', d) structure.new_array('forces', f) structure.calc = None structures.append(structure) cutoffs = [ option_dict['cutoff'], ] cs = ClusterSpace(structures[0], cutoffs) print(cs) cs.print_orbits() sc = StructureContainer(cs) for structure in structures: sc.add_structure(structure) print(sc) opt = Optimizer(sc.get_fit_data()) opt.train() print(opt) fcp = ForceConstantPotential(cs, opt.parameters) print(fcp)
cs = ClusterSpace(prim, [5.0, 5.0, 4.5, 4.0, 4.0]) # train FCP sc = StructureContainer(cs) for i in range(3): atoms = supercell.copy() atoms.rattle(0.3, seed=100*i) atoms = prepare_structure(atoms, supercell, calc=EMT()) sc.add_structure(atoms) opt = Optimizer(sc.get_fit_data()) opt.train() print(opt) # get fcs fcp = ForceConstantPotential(cs, opt.parameters) fcs = fcp.get_force_constants(supercell) # calculate reference forces supercell_rattle = supercell.copy() supercell_rattle.rattle(0.2) calc = ForceConstantCalculator(fcs) supercell_rattle.set_calculator(calc) forces = supercell_rattle.get_forces() np.savetxt('forces_hiphive.txt', forces) # write gpumd files write_atoms_gpumd('xyz.in', supercell_rattle) write_r0('r0.in', supercell)
def run_hiphive(supercell, primitive, displacements, forces, options, symprec, log_level): """Run hiphive supercell : Supercell Perfect supercell. primitive : Primitive Primitive cell. displacements : ndarray Displacements of atoms in supercell. shape=(supercells, natom, 3) forces : ndarray Forces on atoms in supercell. shape=(supercells, natom, 3) options : str Force constants calculation options. log_level : int Log control. 0: quiet, 1: normal, 2: verbose 3: debug """ ase_supercell = phonopy_atoms_to_ase(supercell) ase_prim = phonopy_atoms_to_ase(primitive) # setup training structures structures = [] for d, f in zip(displacements, forces): structure = ase_supercell.copy() structure.new_array('displacements', d) structure.new_array('forces', f) structures.append(structure) # parse options if options is None: options_dict = {} else: options_dict = _decode_options(options) # select cutoff max_cutoff = estimate_maximum_cutoff(ase_supercell) - 1e-5 if 'cutoff' in options_dict: cutoff = options_dict['cutoff'] if cutoff > max_cutoff: raise ValueError( 'Cutoff {:.4f} is larger than maximum allowed ' 'cutoff, {:.4f}, for the given supercell.' '\nDecrease cutoff or provide larger supercells.'.format( cutoff, max_cutoff)) else: cutoff = max_cutoff # setup ClusterSpace cutoffs = [cutoff] cs = ClusterSpace(ase_prim, cutoffs, symprec=symprec) cs.print_orbits() sc = StructureContainer(cs) for structure in structures: sc.add_structure(structure) n_rows, n_cols = sc.data_shape if n_rows < n_cols: raise ValueError('Fitting problem is under-determined.' '\nProvide more structures or decrease cutoff.') # Estimate error opt = Optimizer(sc.get_fit_data(), train_size=0.75) opt.train() print(opt) print('RMSE train : {:.4f}'.format(opt.rmse_train)) print('RMSE test : {:.4f}'.format(opt.rmse_test)) # Final train opt = Optimizer(sc.get_fit_data(), train_size=1.0) opt.train() # get force constants fcp = ForceConstantPotential(cs, opt.parameters) fcs = fcp.get_force_constants(ase_supercell) fc2 = fcs.get_fc_array(order=2) return fc2
sc = StructureContainer(cs) for structure in rattled_structures: sc.add_structure(structure) print('\n') print('Structure container building ups are completed!') ############# Develop force constant potential model ################# # Fit models for 2nd and 3rd order # fit_method: str to specify which fitting method to use opt = Optimizer(sc.get_fit_data(), fit_method='least-squares', seed=seed_int_struct) opt.train() print(opt) fcp = ForceConstantPotential(cs, opt.parameters) ########### Generate and save force constant of desired orders ############# fcs = fcp.get_force_constants(initial_structure) # Set up hiPhive fcs folder hiphive_filename = 'hiPhive_si_bulk/' primitive_fname = 'hiPhive_si_bulk/atom_prim.xyz' if not os.path.isdir(hiphive_filename): os.mkdir(hiphive_filename) write(primitive_fname, atoms_prim, format='xyz') # Explicitly set periodic boundary conditions (pbc) for replicated structures. # This pbc infomration is now used when loading fcs to kaldo # [True, True, True] means pbc is applied in all three directions. replicated_structure.set_pbc(np.array([True, True, True]))
def calc_fcs( phono3py, calc, unitcell_f='Unknown', cp_files=None, sym_fc=True, fc_calc=None, r_cut=None, ): """ fc_calc: None or 'alm' r_cut: None or float. Use hiPhive if provided. """ # Check if structure is lower triangular cell for c in ((0, 1), (0, 2), (1, 2)): if phono3py.primitive.get_cell()[c[0], c[1]] != 0. and calc == 'lmp': raise ValueError('Please provide lower triangular cell.') # phono3py.generate_displacements() fc2_snd = phono3py.get_phonon_supercells_with_displacements() fc3_snd = phono3py.get_supercells_with_displacements() fc2_job_name = '{}-x{}{}{}_d0.010_sym{}-fc2'.format( calc, *np.diag(phono3py.get_phonon_supercell_matrix()), phono3py._is_symmetry, ) fc3_job_name = '{}-x{}{}{}_d0.030_sym{}-fc3'.format( calc, *np.diag(phono3py.get_supercell_matrix()), phono3py._is_symmetry, ) fc2_npy_name = '{}-forces.npy'.format(fc2_job_name) fc3_npy_name = '{}-forces.npy'.format(fc3_job_name) calc_dir = 'calcs' fc2_path = '{}/{}'.format(calc_dir, fc2_job_name) fc3_path = '{}/{}'.format(calc_dir, fc3_job_name) # from phonopy.interface.vasp import write_vasp call('mkdir -p {}/poscars'.format(fc2_path), shell=True) write_vasp('{}/poscars/SPOSCAR'.format(fc2_path), phono3py.get_phonon_supercell()) for i in range(len(fc2_snd)): write_vasp('{}/poscars/POSCAR-{:03d}'.format(fc2_path, i + 1), fc2_snd[i]) # call('mkdir -p {}/poscars'.format(fc3_path), shell=True) write_vasp('{}/poscars/SPOSCAR'.format(fc3_path), phono3py.get_supercell()) for i in range(len(fc3_snd)): write_vasp('{}/poscars/POSCAR-{:05d}'.format(fc3_path, i + 1), fc3_snd[i]) try: fc2_forces = np.load(fc2_npy_name) except: calc_fc2 = True print('\n*** NOTE) Failed to load {} file. ***\n'.format(fc2_npy_name)) else: calc_fc2 = False print('\n=== NOTE) Loaded: {} ===\n'.format(fc2_npy_name)) if calc_fc2: print('=== NOTE) Starting fc2 calculations! ===\n') fc2_forces = [] for i in range(len(fc2_snd)): folder = 'disp-{:03d}'.format(i + 1) wdir = '{}/{}'.format(fc2_path, folder) budir = '{}/bu-{}'.format(fc2_path, folder) call('rm -rf {}'.format(budir), shell=True) call('mv {} {}'.format(wdir, budir), shell=True) call('mkdir -p {}'.format(wdir), shell=True) write_vasp('{}/POSCAR'.format(wdir), fc2_snd[i]) fc2_forces.append(_calc_forces(wdir, calc, cp_files)) print(' == Progress: {}/{}'.format(i + 1, len(fc2_snd))) np.save(fc2_npy_name, fc2_forces) try: fc3_forces = np.load(fc3_npy_name) except: calc_fc3 = True print('\n*** NOTE) Failed to load {} file. ***\n'.format(fc3_npy_name)) else: calc_fc3 = False print('\n=== NOTE) Loaded: {} ===\n'.format(fc3_npy_name)) if calc_fc3: print('=== NOTE) Starting fc3 calculations! ===\n') fc3_forces = [] for i in range(len(fc3_snd)): folder = 'disp-{:05d}'.format(i + 1) wdir = '{}/{}'.format(fc3_path, folder) budir = '{}/bu-{}'.format(fc3_path, folder) call('rm -rf {}'.format(budir), shell=True) call('mv {} {}'.format(wdir, budir), shell=True) call('mkdir -p {}'.format(wdir), shell=True) write_vasp('{}/POSCAR'.format(wdir), fc3_snd[i]) fc3_forces.append(_calc_forces(wdir, calc, cp_files)) print(' == Progress: {}/{}'.format(i + 1, len(fc3_snd))) np.save(fc3_npy_name, fc3_forces) # phono3py.phonon_forces = np.array(fc2_forces) phono3py.forces = np.array(fc3_forces) # phono3py.produce_fc3( symmetrize_fc3r=sym_fc, fc_calculator=fc_calc, ) phono3py.produce_fc2( symmetrize_fc2=sym_fc, fc_calculator=fc_calc, ) if r_cut: # from ase.io import read from ase.calculators.singlepoint import SinglePointDFTCalculator fc2_disp_ds = phono3py.get_phonon_displacement_dataset()['first_atoms'] fc2_sposcar = read('{}/poscars/SPOSCAR'.format(fc2_path)) fc2_supers = [] for i in range(len(fc2_disp_ds)): displacements = np.zeros(fc2_sposcar.get_positions().shape, dtype=float) displacements[fc2_disp_ds[i] ['number']] += fc2_disp_ds[i]['displacement'] fc2_supers.append(fc2_sposcar.copy()) fc2_supers[-1].new_array( 'displacements', displacements, ) fc2_supers[-1]._calc = SinglePointDFTCalculator(fc2_supers[-1]) fc2_supers[-1]._calc.results['forces'] = fc2_disp_ds[i]['forces'] # rotational sum rule from hiphive import ForceConstants, ClusterSpace, StructureContainer cs = ClusterSpace(fc2_sposcar, [r_cut]) sc = StructureContainer(cs) for s in fc2_supers: sc.add_structure(s) from hiphive.fitting import Optimizer opt = Optimizer(sc.get_fit_data(), train_size=1.0) opt.train() print(opt) parameters = opt.parameters from hiphive import ForceConstantPotential, enforce_rotational_sum_rules parameters_rot = enforce_rotational_sum_rules(cs, parameters, ['Huang', 'Born-Huang']) fcp_rot = ForceConstantPotential(cs, parameters_rot) fcs = fcp_rot.get_force_constants(fc2_sposcar).get_fc_array(order=2) phono3py.set_fc2(fcs) # # Not implemented yet in hiPhive # fc3_disp_ds = phono3py.get_displacement_dataset()['first_atoms'] # fc3_sposcar = read('{}/poscars/SPOSCAR'.format(fc3_path)) # fc3_supers = [] # for i in range(len(fc3_disp_ds)): # displacements_1st = np.zeros(fc3_sposcar.get_positions().shape, dtype=float) # displacements_1st[fc3_disp_ds[i]['number']] += fc3_disp_ds[i]['displacement'] # for j in range(len(fc3_disp_ds[i]['second_atoms'])): # displacements_2nd = np.zeros(fc3_sposcar.get_positions().shape, dtype=float) # displacements_2nd[fc3_disp_ds[i]['second_atoms'][j]['number']] += fc3_disp_ds[i]['second_atoms'][j]['displacement'] # displacements = displacements_1st + displacements_2nd # fc3_supers.append(fc3_sposcar.copy()) # fc3_supers[-1].new_array( # 'displacements', # displacements, # ) # fc3_supers[-1]._calc = SinglePointDFTCalculator(fc3_supers[-1]) # fc3_supers[-1]._calc.results['forces'] = fc3_disp_ds[i]['second_atoms'][j]['forces'] return phono3py
def run_hiphive(supercell, primitive, displacements, forces, options, symprec, log_level): """Run hiphive. supercell : Supercell Perfect supercell. primitive : Primitive Primitive cell. displacements : ndarray Displacements of atoms in supercell. shape=(supercells, natom, 3) forces : ndarray Forces on atoms in supercell. shape=(supercells, natom, 3) options : str Force constants calculation options. log_level : int Log control. 0: quiet, 1: normal, 2: verbose 3: debug """ try: from hiphive import ClusterSpace, ForceConstantPotential, StructureContainer from hiphive.cutoffs import estimate_maximum_cutoff from hiphive.fitting import Optimizer from hiphive.input_output.logging_tools import set_config except ImportError: raise ImportError("hiPhive python module was not found.") set_config(level=30) ase_supercell = phonopy_atoms_to_ase(supercell) ase_prim = phonopy_atoms_to_ase(primitive) # setup training structures structures = [] for d, f in zip(displacements, forces): structure = ase_supercell.copy() structure.new_array("displacements", d) structure.new_array("forces", f) structures.append(structure) # parse options if options is None: options_dict = {} else: options_dict = _decode_options(options) # select cutoff max_cutoff = estimate_maximum_cutoff(ase_supercell) - 1e-5 if "cutoff" in options_dict: cutoff = options_dict["cutoff"] if cutoff > max_cutoff: raise ValueError( "Cutoff {:.4f} is larger than maximum allowed " "cutoff, {:.4f}, for the given supercell." "\nDecrease cutoff or provide larger supercells.".format( cutoff, max_cutoff)) else: cutoff = max_cutoff # setup ClusterSpace cutoffs = [cutoff] cs = ClusterSpace(ase_prim, cutoffs, symprec=symprec) cs.print_orbits() sc = StructureContainer(cs) for structure in structures: sc.add_structure(structure) n_rows, n_cols = sc.data_shape if n_rows < n_cols: raise ValueError("Fitting problem is under-determined." "\nProvide more structures or decrease cutoff.") # Estimate error opt = Optimizer(sc.get_fit_data(), train_size=0.75) opt.train() print(opt) print("RMSE train : {:.4f}".format(opt.rmse_train)) print("RMSE test : {:.4f}".format(opt.rmse_test)) # Final train opt = Optimizer(sc.get_fit_data(), train_size=1.0) opt.train() # get force constants fcp = ForceConstantPotential(cs, opt.parameters) fcs = fcp.get_force_constants(ase_supercell) fc2 = fcs.get_fc_array(order=2) return fc2
def calculate_high_order_phi(): from ase.io import read import numpy as np from hiphive import ClusterSpace, StructureContainer from hiphive.utilities import get_displacements from hiphive import ForceConstantPotential from hiphive.fitting import Optimizer from hiphive.calculators import ForceConstantCalculator import os if os.path.exists('POSCAR-md'): reference_structure = read('POSCAR-md') else: return None if not os.path.exists('./vasprun_md.xml'): return None a = reference_structure.get_cell_lengths_and_angles()[0] cs = ClusterSpace(reference_structure, [0.3 * a, 0.35 * a, 0.35 * a]) sc = None #try: # sc = StructureContainer.read("./structure_container") # print("successfully loaded the structure container "+str(sc)) #except: try: fit_structures = [] atoms = read("./vasprun_md.xml", index=':') for i, a in enumerate(atoms): displacements = get_displacements(a, reference_structure) atoms_tmp = reference_structure.copy() atoms_tmp.new_array('displacements', displacements) atoms_tmp.new_array('forces', a.get_forces()) atoms_tmp.positions = reference_structure.positions fit_structures.append(atoms_tmp) sc = StructureContainer( cs) # need a cluster space to instantiate the object! sc.delete_all_structures() for ii, s in enumerate(fit_structures): try: sc.add_structure(s) except Exception as e: print(ii, e) pass except: pass if sc is not None: try: opt = Optimizer(sc.get_fit_data(), fit_method="ardr", train_size=0.9) opt.train() fcp = ForceConstantPotential(cs, opt.parameters) fcs = fcp.get_force_constants(reference_structure) except Exception as e: print(e) return None from core.external.vasp.anharmonic_score import AnharmonicScore sigmas_2 = None sigmas_3 = None sigmas_4 = None try: scorer = AnharmonicScore(md_frames='./vasprun_md.xml', ref_frame='./POSCAR-md', force_constants=fcs.get_fc_array(2), include_third_order=False, include_fourth_order=False) sigmas_2, _ = scorer.structural_sigma(return_trajectory=False) except: pass try: scorer = AnharmonicScore(md_frames='./vasprun_md.xml', ref_frame='./POSCAR-md', force_constants=fcs.get_fc_array(2), include_third_order=True, third_order_fc=fcs.get_fc_array(3), include_fourth_order=False) sigmas_3, _ = scorer.structural_sigma(return_trajectory=False) except: pass try: scorer = AnharmonicScore(md_frames='./vasprun_md.xml', ref_frame='./POSCAR-md', force_constants=fcs.get_fc_array(2), include_third_order=True, third_order_fc=fcs.get_fc_array(3), include_fourth_order=True, fourth_order_fc=fcs.get_fc_array(4)) sigmas_4, _ = scorer.structural_sigma(return_trajectory=False) except: pass f = open('sigmas.dat', 'w') f.write('sigma_2' + '\t' + str(sigmas_2) + '\n') f.write('sigma_3' + '\t' + str(sigmas_3) + '\n') f.write('sigma_4' + '\t' + str(sigmas_4) + '\n') f.close()
def calc_phonon( calculator, phonon, acoustic_sum_rule=True, rot_sum_rule=False, r_cut=None, F_0_correction=False, verbose=False, ase_calc=None, cp_files=None, subscript=None, fc_calc=None, ): """ calc -- Specify calculator. One of these. [vasp, lmp, amp, amp_tf, amp_tf_bunch] phonon -- Phonopy phonon object. """ # Check if structure is lower triangular cell # for c in ((0,1), (0,2), (1,2)): # if phonon._primitive.get_cell()[c[0],c[1]] != 0. and calculator == 'lmp': # raise ValueError('Please provide lower triangular cell.') import sys if verbose: np.set_printoptions(threshold=sys.maxsize) if fc_calc == 'alm': disp = phonon.get_displacements() delta = np.linalg.norm(disp[0][0]) disp = np.concatenate([[np.zeros(disp.shape[1:])], disp], axis=0) else: delta = np.linalg.norm(phonon.get_displacements()[0][1:4]) disp = [[0, 0, 0, 0]] + phonon.get_displacements() job_name = '{}-x{}{}{}_d{:5.3f}_sym{}'.format( calculator, *np.diag(phonon.get_supercell_matrix()), delta, phonon._is_symmetry, ) if subscript is not None: job_name += '_s' + str(subscript) # Define names npy_name = '{}-fc2-forces.npy'.format(job_name) if phonon._nac_params is not None: nac = True else: nac = False pckl_name = '{}-RSR{}-rcut{}-NAC{}-fc2.bin'.format(job_name, rot_sum_rule, r_cut, nac) calc_dir = './calcs/{}'.format(job_name) # Environment preset call(['rm -rf ' + calc_dir + '/poscars'], shell=True) call(['mkdir -p ' + calc_dir + '/poscars'], shell=True) call(['cp SPOSCAR POSCAR-000'], shell=True) call(['mv POSCAR-* SPOSCAR ' + calc_dir + '/poscars/'], shell=True) # Load saved pickle file print('') try: forces = np.load(npy_name) if forces is None: raise ValueError(' Error:: npy file is not containing forces info') except: print( '<< CAUTION >> Fail to load npy file. << CAUTION >>' .center(120)) print(('<< CAUTION >>' + ':: Expected file name ::'.center(43) + '<< CAUTION >>').center(120)) print(('<< CAUTION >>' + npy_name.center(43) + '<< CAUTION >>').center(120)) do_calc = True else: print('>>>>>>> Pickle file "{}" has been loaded. <<<<<<<<'.format( npy_name).center(120)) do_calc = False print('') if do_calc: if calculator == 'vasp': calc = calc_vasp elif calculator == 'lmp': calc = calc_lmp elif calculator == 'ase_calc': calc = calc_ase_calc elif calculator == 'amp_tf': calc = calc_amp_tf elif calculator == 'amp_tf_bunch': calc = calc_amp_tf_bunch else: raise ValueError( 'Unknown calculator ({}) has been provided.'.format( calculator)) print(">>>>>>> {} calculation will be carried out. <<<<<<<<".format( calculator).center(120)) forces = calc(phonon, disp, calc_dir, F_0_correction, ase_calc, cp_files) np.save(npy_name, forces) if verbose: print('\n\n' + 'forces' + '\n' + str(forces)) phonon.set_forces(forces) # Produce fc phonon.produce_force_constants(fc_calculator=fc_calc) if acoustic_sum_rule: phonon.symmetrize_force_constants() if r_cut: if rot_sum_rule: # from ase.io import read from ase.calculators.singlepoint import SinglePointDFTCalculator sposcar = read(calc_dir + '/poscars/SPOSCAR') supers = [] for i in range(len(forces)): supers.append(sposcar.copy()) displacements = np.zeros(sposcar.get_positions().shape, dtype=float) displacements[disp[i + 1][0]] += disp[i + 1][1:] supers[-1].new_array( 'displacements', displacements, ) supers[-1]._calc = SinglePointDFTCalculator(supers[-1]) supers[-1]._calc.results['forces'] = forces[i] # rotational sum rule from hiphive import ForceConstants, ClusterSpace, StructureContainer cs = ClusterSpace(sposcar, [r_cut]) sc = StructureContainer(cs) for s in supers: sc.add_structure(s) from hiphive.fitting import Optimizer opt = Optimizer(sc.get_fit_data(), train_size=1.0) opt.train() print(opt) parameters = opt.parameters from hiphive import ForceConstantPotential, enforce_rotational_sum_rules parameters_rot = enforce_rotational_sum_rules( cs, parameters, ['Huang', 'Born-Huang']) fcp_rot = ForceConstantPotential(cs, parameters_rot) fcs = fcp_rot.get_force_constants(sposcar).get_fc_array(order=2) phonon.set_force_constants(fcs) else: phonon.set_force_constants_zero_with_radius(r_cut) if verbose: print('\n\ndisplacement_dataset =>\n\n') print(phonon.get_displacement_dataset()) print('\n\nforce_constants =>\n\n') print(phonon.get_force_constants()) import pickle as pckl pckl.dump(phonon, open(pckl_name, 'wb'), protocol=2) return phonon