def test_screw_cyl_lammpslib(self): """Test make_crew_cyl() and call lammpslib caclulator. If lammps crashes, check "lammps.log" file in the tests directory See lammps and ASE documentation on how to make lammpslib work """ print("WARNING: In case lammps crashes no error message is printed: ", "check 'lammps.log' file in test folder") alat = 3.14339177996466 C11 = 523.0266819809012 C12 = 202.1786296941397 C44 = 160.88179872237012 cylinder_r = 40 cent_x = np.sqrt(6.0) * alat / 3.0 center = (cent_x, 0.0, 0.0) pot_name = "w_eam4.fs" target_toten = -13086.484626 # Target value for w_eam4 lammps = LAMMPSlib( lmpcmds=["pair_style eam/fs", "pair_coeff * * %s W" % pot_name], atom_types={'W': 1}, keep_alive=True, log_file="lammps.log") disloc_ini, bulk_ini, __ = sd.make_screw_cyl(alat, C11, C12, C44, cylinder_r=cylinder_r, l_extend=center) disloc_ini.set_calculator(lammps) ini_toten = disloc_ini.get_potential_energy() self.assertAlmostEqual(ini_toten, target_toten, places=4) disloc_fin, __, __ = sd.make_screw_cyl(alat, C11, C12, C44, cylinder_r=cylinder_r, center=center) disloc_fin.set_calculator(lammps) fin_toten = disloc_fin.get_potential_energy() self.assertAlmostEqual(fin_toten, target_toten, places=4) os.remove("lammps.log")
def LAMMPSLibCalculator(model_name, supported_species, supported_units, options): """ Only used for LAMMPS Simulator Models """ options_not_allowed = [ "lammps_header", "lmpcmds", "atom_types", "log_file", "keep_alive", ] _check_conflict_options(options, options_not_allowed, simulator="lammpslib") # Set up LAMMPS header commands lookup table # This units command actually has no effect, but is necessary because # LAMMPSlib looks in the header lines for units in order to set them # internally model_init = ["units " + supported_units + os.linesep] model_init.append("kim_init {} {}{}".format(model_name, supported_units, os.linesep)) model_init.append("atom_modify map array sort 0 0" + os.linesep) # Assign atom types to species atom_types = {} for i_s, s in enumerate(supported_species): atom_types[s] = i_s + 1 kim_interactions = [ "kim_interactions {}".format((" ").join(supported_species)) ] # Return LAMMPSlib calculator return LAMMPSlib(lammps_header=model_init, lammps_name=None, lmpcmds=kim_interactions, post_changebox_cmds=kim_interactions, atom_types=atom_types, log_file="lammps.log", keep_alive=True, **options)
def calc_lmp_force_sets(cmds, Scells_ph, atomtypes='atomic', logfile='log.lammps', lammps_header=[], create_atoms=True, create_box=True, boundary=True, keep_alive=False): """ This function uses ase and lammps' python API to calculate forces. Comment this funciton if it's not installed. In cmd, specifies the potential Scells takes the list of perturbated supercells, phonopyatom objs. """ if lammps_header == []: lammps_header = [ 'units metal', 'atom_style ' + atomtypes, 'atom_modify map array sort 0 0' ] if type(Scells_ph) != list: Scells_ph = [Scells_ph] force_scells = [] for scell_ph in Scells_ph: lammps = LAMMPSlib( lmpcmds=cmds, log_file=logfile, lammps_header=lammps_header, create_atoms=create_atoms, create_box=create_box, boundary=boundary, keep_alive=keep_alive) # lammps obj has to be in the loop. scell = api_ph.phonopyAtoms_to_aseAtoms(scell_ph) scell.set_calculator(lammps) forces = scell.get_forces() force_scells.append(forces.tolist()) return force_scells
def test_lammpslib_change_cell_bcs(): # test that a change in unit cell boundary conditions is # handled correctly by lammpslib import numpy as np from ase.calculators.lammpslib import LAMMPSlib from ase.lattice.cubic import FaceCenteredCubic cmds = ["pair_style eam/alloy", "pair_coeff * * NiAlH_jea.eam.alloy Ni H"] lammps = LAMMPSlib(lmpcmds=cmds, atom_types={ 'Ni': 1, 'H': 2 }, log_file='test.log', keep_alive=True) atoms = FaceCenteredCubic(size=(2, 2, 2), latticeconstant=3.52, symbol="Ni", pbc=True) atoms.calc = lammps energy_ppp_ref = -142.400000403 energy_ppp = atoms.get_potential_energy() print("Computed energy with boundary ppp = {}".format(energy_ppp)) np.testing.assert_allclose(energy_ppp, energy_ppp_ref, atol=1e-4, rtol=1e-4) atoms.set_pbc((False, False, True)) energy_ssp_ref = -114.524625705 energy_ssp = atoms.get_potential_energy() print("Computed energy with boundary ssp = {}".format(energy_ssp)) np.testing.assert_allclose(energy_ssp, energy_ssp_ref, atol=1e-4, rtol=1e-4)
def calc_lmp_force(cmds, Scell_ph, atomtypes='atomic', logfile='log.lammps', lammps_header=[], create_atoms=True, create_box=True, boundary=True, keep_alive=False): """ This function uses ase and lammps' python API to calculate forces. In cmd, specifies the potential Scells takes the list of perturbated supercells, phonopyatom objs. Settings in the lammps header will overwrite the settings of the atmotypes, if lammps_header is explictly specified. """ if lammps_header == []: lammps_header = [ 'units metal', 'atom_style ' + atomtypes, 'atom_modify map array sort 0 0' ] lammps = LAMMPSlib( lmpcmds=cmds, log_file=logfile, lammps_header=lammps_header, create_atoms=create_atoms, create_box=create_box, boundary=boundary, keep_alive=keep_alive) # lammps obj has to be in the loop. scell = api_ph.phonopyAtoms_to_aseAtoms(Scell_ph) scell.set_calculator(lammps) forces = scell.get_forces() return forces
def change_concentration(ge_concentration=0): # Read in 1728 atom system atoms = read('structures/1728_atom/aSi.xyz', format='xyz') # Swap in Ge atoms if ge_concentration != 0: symbols = np.array(atoms.get_chemical_symbols()) n_ge_atoms = int(np.round(ge_concentration * len(symbols), 0)) rng = np.random.default_rng(seed=random_seed) id = rng.choice(len(atoms), size=n_ge_atoms, replace=False) symbols[id] = 'Ge' atoms.set_chemical_symbols(symbols.tolist()) ge_concentration = str(int(ge_concentration * 100)) folder_string = 'structures/1728_atom/aSiGe_C' + str(ge_concentration) if not os.path.exists(folder_string): os.makedirs(folder_string) # Minimize structure - LAMMPS + ASE lammps_inputs = { 'lmpcmds': [ "pair_style tersoff", "pair_coeff * * forcefields/SiCGe.tersoff Si(D) Ge" ], "log_file": "min.log", "keep_alive": True } calc = LAMMPSlib(**lammps_inputs) atoms.set_calculator(calc) atoms.pbc = True search = LBFGSLineSearch(atoms) search.run(fmax=.001) write('structures/1728_atom/aSiGe_C' + str(ge_concentration) + '/replicated_atoms.xyz', search.atoms, format='xyz')
cmds.append(line) if (cnt > end_cmds): amendments.append(line) line = file.readline() cnt += 1 file.close() for i in range(0, len(charges)): amendments.append('set atom ' + str(int(i + 1)) + ' charge ' + str(charges[i])) lammps = LAMMPSlib(lmpcmds=cmds, lammps_header=header, amendments=amendments, log_file='asela.log', keep_alive=True, create_atoms=False, create_box=False, boundary=False) print('Done with reading LAMMPS file.') #print(header) #print(cmds) ################################################################################## atoms.set_calculator(lammps) print('Calculator set!') ##################################################################################
supercell = np.array([nrep, nrep, nrep]) # Configure force constant calculator forceconstants_config = {'atoms': atoms, 'supercell': supercell, 'folder': 'fc_c_diamond'} forceconstants = ForceConstants(**forceconstants_config) # Define input information for the ase LAMMPSlib calculator # Terosff potential for carbon (C.tersoff) is used for this example. lammps_inputs = {'lmpcmds': [ 'pair_style tersoff', 'pair_coeff * * forcefields/C.tersoff C'], 'keep_alive': True, 'log_file': 'lammps-c-diamond.log'} # Compute 2nd and 3rd IFCs with the defined calculator forceconstants.second.calculate(LAMMPSlib(**lammps_inputs)) forceconstants.third.calculate(LAMMPSlib(**lammps_inputs)) ### Set up the phonon object and the harmonic property calculations #### # Configure phonon object # 'k_points': number of k-points # 'is_classic': specify if the system is classic, True for classical and False for quantum # 'temperature: temperature (Kelvin) at which simulation is performed # 'folder': name of folder containing phonon property and thermal conductivity calculations # 'storage': Format to storage phonon properties ('formatted' for ASCII format data, 'numpy' # for python numpy array and 'memory' for quick calculations, no data stored") # Define the k-point mesh using 'kpts' parameter k_points = 5 #'k_points'=5 k points in each direction
cmds = [ "pair_style eam/alloy", "pair_coeff * * {path}/NiAlH_jea.eam.alloy Ni H" "".format(path=potential_path) ] nickel = bulk('Ni', cubic=True) nickel += Atom('H', position=nickel.cell.diagonal() / 2) # Bit of distortion nickel.set_cell(nickel.cell + [[0.1, 0.2, 0.4], [0.3, 0.2, 0.0], [0.1, 0.1, 0.1]], scale_atoms=True) lammps = LAMMPSlib(lmpcmds=cmds, atom_types={ 'Ni': 1, 'H': 2 }, log_file='test.log', keep_alive=True) nickel.set_calculator(lammps) E = nickel.get_potential_energy() F = nickel.get_forces() S = nickel.get_stress() print('Energy: ', E) print('Forces:', F) print('Stress: ', S) print()
# potential_path must be set as an environment variable potential_path = os.environ.get('LAMMPS_POTENTIALS_PATH', '.') cmds = ["pair_style eam/alloy", "pair_coeff * * {path}/NiAlH_jea.eam.alloy Ni H" "".format(path=potential_path)] nickel = bulk('Ni', cubic=True) nickel += Atom('H', position=nickel.cell.diagonal()/2) # Bit of distortion nickel.set_cell(nickel.cell + [[0.1, 0.2, 0.4], [0.3, 0.2, 0.0], [0.1, 0.1, 0.1]], scale_atoms=True) lammps = LAMMPSlib(lmpcmds=cmds, atom_types={'Ni': 1, 'H': 2}, log_file='test.log', keep_alive=True) nickel.set_calculator(lammps) E = nickel.get_potential_energy() F = nickel.get_forces() S = nickel.get_stress() print('Energy: ', E) print('Forces:', F) print('Stress: ', S) print() E = nickel.get_potential_energy() F = nickel.get_forces()
def calc(self, **kwargs): from ase.calculators.lammpslib import LAMMPSlib return LAMMPSlib(**kwargs)
# Configure force constant calculator forceconstants_config = {'atoms': atoms, 'supercell': supercell, 'folder': 'fc_c_diamond'} forceconstants = ForceConstants(**forceconstants_config) # Define input information for the ase LAMMPSlib calculator # Terosff potential for carbon (C.tersoff) is used for this example. lammps_inputs = {'lmpcmds': [ 'pair_style tersoff', 'pair_coeff * * forcefields/C.tersoff C'], 'keep_alive': True, 'log_file': 'lammps-c-diamond.log'} # Compute 2nd and 3rd IFCs with the defined calculators # delta_shift: finite difference displacement, in angstrom forceconstants.second.calculate(LAMMPSlib(**lammps_inputs), delta_shift=1e-4) forceconstants.third.calculate(LAMMPSlib(**lammps_inputs), delta_shift=1e-4) # -- Set up the phonon object and the anharmonic properties calculations -- # # Configure phonon object # 'k_points': number of k-points # 'is_classic': specify if the system is classic, True for classical and False for quantum # 'temperature: temperature (Kelvin) at which simulation is performed # 'folder': name of folder containing phonon property and thermal conductivity calculations # 'storage': Format to storage phonon properties ('formatted' for ASCII format data, 'numpy' # for python numpy array and 'memory' for quick calculations, no data stored) # Define the k-point mesh using 'kpts' parameter k_points = 5 # 'k_points'=5 k points in each direction phonons_config = {'kpts': [k_points, k_points, k_points],
import os import sys try: from ase.calculators.lammpslib import LAMMPSlib except: sys.exit("Failed to import lammpslib module") model_dir = os.path.dirname(__file__) header = ['units real', 'atom_style charge', 'atom_modify map array sort 0 0'] cmds = [ "pair_style reax/c NULL checkqeq no", "pair_coeff * * {}/ffield_APL_2014_SiO Si".format(model_dir) ] try: calculator = LAMMPSlib(lmpcmds=cmds, keep_alive=True, lammps_header=header, atom_types={"Si": 1}, lammps_name=os.environ['LAMMPS_NAME']) except: raise RuntimeError no_checkpoint = True name = 'ReaxFF'
### Generate reference structures and perform force calculations #### # a0: lattice parameter (Angstrom) # rattle_std: standard deviation of the distribution of displacements # number_of_structures: number of structures generated with standard rattle (random displacement) # and used in force calculations a0 = 5.432 rattle_std = 0.01 number_of_structures = 100 # Define input information for the ase LAMMPSlib calculator # Terosff potential for silicon (Si.tersoff) is used for this example. cmds = ['pair_style tersoff', 'pair_coeff * * forcefields/Si.tersoff Si'] calc = LAMMPSlib(lmpcmds=cmds, log_file='lammps_si_bulk_hiphive.log', keep_alive=True) calc = calc = LAMMPSlib(lmpcmds=cmds, log_file='lammps_si_bulk_hiphive.log', keep_alive=True) if not os.path.exists('structures'): os.mkdir('structures/') # Generate initial structure atoms_prim = bulk('Si', 'diamond', a=a0) n_prim = atoms_prim.get_masses().shape[0] # Replicate the unit cell 'nrep'=3 times nrep = 3 supercell = np.array([nrep, nrep, nrep]) initial_structure = atoms_prim.copy() * (supercell[0], 1, 1) * (
"boundary p p p", "atom_style atomic", "units metal", #"neighbor 2.0 bin", 'atom_modify map array', ] lammps_cmds = [ 'pair_style lj/cut 15.0', 'pair_coeff * * {} {}'.format(epsilon, sigma), #'pair_coeff 1 1 0.238 3.405', #'fix 1 all nve', ] #atom_types={'Ar':1} lammps = LAMMPSlib( lmpcmds=lammps_cmds, #atom_types=atom_types, lammps_header=lammps_header, log_file='LOG.log', keep_alive=True) #calculator = LennardJones() calculator = lammps atoms = a0.copy() atoms.set_calculator(calculator) opt = BFGS(atoms, trajectory=options.outputfile) #opt = BFGS(atoms) #opt.H0 = hessian opt.run(fmax=1e-3, steps=300) xyz_out = options.outputfile.replace(".traj", ".xyz").replace("Trajectories_ID",
def test_lammpslib(): # potential_path must be set as an environment variable cmds = [ "pair_style eam/alloy", "pair_coeff * * NiAlH_jea.eam.alloy Ni H" ] nickel = bulk('Ni', cubic=True) nickel += Atom('H', position=nickel.cell.diagonal() / 2) # Bit of distortion nickel.set_cell(nickel.cell + [[0.1, 0.2, 0.4], [0.3, 0.2, 0.0], [0.1, 0.1, 0.1]], scale_atoms=True) lammps = LAMMPSlib(lmpcmds=cmds, atom_types={ 'Ni': 1, 'H': 2 }, log_file='test.log', keep_alive=True) nickel.calc = lammps E = nickel.get_potential_energy() F = nickel.get_forces() S = nickel.get_stress() print('Energy: ', E) print('Forces:', F) print('Stress: ', S) print() E = nickel.get_potential_energy() F = nickel.get_forces() S = nickel.get_stress() lammps = LAMMPSlib(lmpcmds=cmds, log_file='test.log', keep_alive=True) nickel.calc = lammps E2 = nickel.get_potential_energy() F2 = nickel.get_forces() S2 = nickel.get_stress() assert_allclose(E, E2, atol=1e-4, rtol=1e-4) assert_allclose(F, F2, atol=1e-4, rtol=1e-4) assert_allclose(S, S2, atol=1e-4, rtol=1e-4) nickel.rattle(stdev=0.2) E3 = nickel.get_potential_energy() F3 = nickel.get_forces() S3 = nickel.get_stress() print('rattled atoms') print('Energy: ', E3) print('Forces:', F3) print('Stress: ', S3) print() assert not np.allclose(E, E3) assert not np.allclose(F, F3) assert not np.allclose(S, S3) nickel += Atom('H', position=nickel.cell.diagonal() / 4) E4 = nickel.get_potential_energy() F4 = nickel.get_forces() S4 = nickel.get_stress() assert not np.allclose(E4, E3) assert not np.allclose(F4[:-1, :], F3) assert not np.allclose(S4, S3) # the example from the docstring cmds = [ "pair_style eam/alloy", "pair_coeff * * NiAlH_jea.eam.alloy Al H" ] Ni = bulk('Ni', cubic=True) H = Atom('H', position=Ni.cell.diagonal() / 2) NiH = Ni + H lammps = LAMMPSlib(lmpcmds=cmds, log_file='test.log') NiH.calc = lammps print("Energy ", NiH.get_potential_energy()) # a more complicated example, reading in a LAMMPS data file # then we run the actual test with open('lammps.data', 'w') as fd: fd.write(lammps_data_file) at = ase.io.read('lammps.data', format='lammps-data', Z_of_type={1: 26}, units='real') header = [ "units real", "atom_style full", "boundary p p p", "box tilt large", "pair_style lj/cut/coul/long 12.500", "bond_style harmonic", "angle_style harmonic", "kspace_style ewald 0.0001", "kspace_modify gewald 0.01", "read_data lammps.data" ] cmds = [] lammps = LAMMPSlib(lammps_header=header, lmpcmds=cmds, atom_types={'Fe': 1}, create_atoms=False, create_box=False, boundary=False, keep_alive=True, log_file='test.log') at.calc = lammps dyn = VelocityVerlet(at, 1 * units.fs) assert_allclose(at.get_potential_energy(), 2041.411982950972, atol=1e-4, rtol=1e-4) dyn.run(10) assert_allclose(at.get_potential_energy(), 312.4315854721744, atol=1e-4, rtol=1e-4)