def lmp_calculator(gp_model, mgp_model): species = gp_model.training_statistics['species'] specie_symbol_list = " ".join(species) masses = [ f"{i} {_Z_to_mass[_element_to_Z[species[i]]]}" for i in range(len(species)) ] # set up input params label = 'tmp_lmp' by = 'yes' if 'twobody' in gp_model.kernels else 'no' ty = 'yes' if 'threebody' in gp_model.kernels else 'no' parameters = { 'command': os.environ.get('lmp'), # set up executable for ASE 'newton': 'off', 'pair_style': 'mgp', 'pair_coeff': [f'* * {label}.mgp {specie_symbol_list} {by} {ty}'], 'mass': masses } files = [f'{label}.mgp'] # create ASE calc lmp_calc = LAMMPS(label=f'tmp{label}', keep_tmp_files=True, tmp_dir='./tmp/', parameters=parameters, files=files, specorder=species) yield lmp_calc del lmp_calc
def test_lmp_calc(bodies, multihyps, all_lmp_calc): label = f'{bodies}{multihyps}' # set up input params by = 'no' ty = 'no' if '2' in bodies: by = 'yes' if '3' in bodies: ty = 'yes' parameters = { 'command': os.environ.get('lmp'), # set up executable for ASE 'newton': 'off', 'pair_style': 'mgp', 'pair_coeff': [f'* * {label}.mgp H He {by} {ty}'], 'mass': ['1 2', '2 4'] } files = [f'{label}.mgp'] # create ASE calc lmp_calc = LAMMPS(label=f'tmp{label}', keep_tmp_files=True, tmp_dir='./tmp/', parameters=parameters, files=files) all_lmp_calc[label] = lmp_calc
def test_NaCl_minimize(): from ase.calculators.lammpsrun import LAMMPS from ase.spacegroup import crystal from ase.data import atomic_numbers, atomic_masses from ase.optimize import QuasiNewton from ase.constraints import UnitCellFilter from numpy.testing import assert_allclose a = 6.15 n = 4 nacl = crystal(['Na', 'Cl'], [(0, 0, 0), (0.5, 0.5, 0.5)], spacegroup=225, cellpar=[a, a, a, 90, 90, 90]).repeat((n, n, n)) # Buckingham parameters from # https://physics.stackexchange.com/questions/250018 pair_style = 'buck/coul/long 12.0' pair_coeff = ['1 1 3796.9 0.2603 124.90'] pair_coeff += ['2 2 1227.2 0.3214 124.90'] pair_coeff += ['1 2 4117.9 0.3048 0.0'] masses = [ '1 {}'.format(atomic_masses[atomic_numbers['Na']]), '2 {}'.format(atomic_masses[atomic_numbers['Cl']]) ] with LAMMPS( specorder=['Na', 'Cl'], pair_style=pair_style, pair_coeff=pair_coeff, masses=masses, atom_style='charge', kspace_style='pppm 1.0e-5', keep_tmp_files=True, ) as calc: for a in nacl: if a.symbol == 'Na': a.charge = +1. else: a.charge = -1. nacl.set_calculator(calc) assert_allclose(nacl.get_potential_energy(), -1896.216737561538, atol=1e-4, rtol=1e-4) nacl.get_potential_energy() ucf = UnitCellFilter(nacl) dyn = QuasiNewton(ucf, force_consistent=False) dyn.run(fmax=1.0E-2) assert_allclose(nacl.get_potential_energy(), -1897.208861729178, atol=1e-4, rtol=1e-4)
def __init__(self, structure, parameters={}, label='mpintlmp', specorder=None, always_triclinic=True, no_data_file=False): LAMMPS.__init__(self, label=label, parameters=parameters, specorder=specorder, files=[], always_triclinic=always_triclinic, no_data_file=no_data_file) self.structure = structure self.atoms = AseAtomsAdaptor().get_atoms(structure) self.label = label self.parameters = parameters self.specorder = specorder self.always_triclinic = always_triclinic self.no_data_file = no_data_file self.charges = None if 'charges' in self.parameters: self.charges = self.parameters['charges']
def test_Pt_md_constraints_multistep(): from ase.calculators.lammpsrun import LAMMPS from numpy.testing import assert_allclose from ase.test.eam_pot import Pt_u3 from ase.build import fcc111 import os pot_fn = 'Pt_u3.eam' f = open(pot_fn, 'w') f.write(Pt_u3) f.close() slab = fcc111('Pt', size=(2, 2, 5), vacuum=30.0) # We use fully periodic boundary conditions because the Lammpsrun # calculator does not know if it can convert the cell correctly with # mixed ones and will give a warning. slab.pbc = 1 params = {} params['pair_style'] = 'eam' params['pair_coeff'] = ['1 1 {}'.format(pot_fn)] with LAMMPS(specorder=['Pt'], files=[pot_fn], **params) as calc: slab.set_calculator(calc) assert_allclose(slab.get_potential_energy(), -110.3455014595596, atol=1e-4, rtol=1e-4) params['group'] = [ 'lower_atoms id ' + ' '.join([ str(i + 1) for i, tag in enumerate(slab.get_tags()) if tag >= 4 ]) ] params['fix'] = ['freeze_lower_atoms lower_atoms setforce 0.0 0.0 0.0'] params['run'] = 100 params['timestep'] = 0.0005 params['dump_period'] = 10 params['write_velocities'] = True calc.parameters = params # set_atoms=True to read final coordinates and velocities after # NVE simulation calc.run(set_atoms=True) Ek = calc.atoms.copy().get_kinetic_energy() assert_allclose(Ek, 0.1014556059885532, atol=1e-4, rtol=1e-4) assert_allclose(Ek, calc.thermo_content[-1]['ke'], atol=1e-4, rtol=1e-4) assert_allclose(slab.get_potential_energy(), -110.4469605087525, atol=1e-4, rtol=1e-4) os.remove(pot_fn)
def __init__(self, structure, parameters={}, label='mpintlmp', specorder=None, always_triclinic=False, no_data_file=False): LAMMPS.__init__(self, label=label, parameters=parameters, specorder=specorder, files=[], always_triclinic=always_triclinic, no_data_file=no_data_file) self.structure = structure self.atoms = AseAtomsAdaptor().get_atoms(structure) self.label = label self.parameters = parameters self.specorder = specorder self.always_triclinic = always_triclinic self.no_data_file = no_data_file self.charges = None if 'charges' in self.parameters: self.charges = self.parameters['charges']
def mo(cmd=None): cwd = os.getcwd() if cmd == None: cmd = os.path.join(cwd, 'lmp_serial') os.environ['LAMMPS_COMMAND'] = cmd os.chdir(os.path.dirname(os.path.abspath(__file__))) parameters = {'pair_style': 'eam/alloy', 'pair_coeff': ['* * Mo.set Mo']} files = ['Mo.set'] calc = LAMMPS(parameters=parameters, files=files) os.chdir(cwd) return calc
def hyster_study(edge, folder=None): if folder == None: folder = os.getcwd() print folder for fileC in os.listdir(folder): if fileC[-6:] == '.simul': fileC = folder + fileC _, length, _, _, v, T, dt, fric, dtheta, \ thresZ, interval, deltaY, theta, M, edge = read_simul_params_file(fileC) mdfile = fileC[:-6] + '.traj' traj = PickleTrajectory(mdfile, 'r') atoms_init = traj[0] constraints, _, twist, rend_b, rend_t = get_constraints(atoms_init, edge, \ bond, None, key = 'twist_p') #constraints, _, rend_b, rend_t = get_constraints(atoms_init, edge, \ # bond, None, key = 'twist_p') atoms = traj[-1] atoms.set_constraint(constraints) vels = (traj[-2].positions - traj[-1].positions) / (interval * dt) atoms.set_velocities(vels) calc = LAMMPS(parameters=get_lammps_params()) atoms.set_calculator(calc) view(atoms) dyn = Langevin(atoms, dt * units.fs, T * units.kB, fric) twist.set_angle(theta) dyn.run(10 * interval) view(atoms) traj_new = PickleTrajectory(fileC[:-6] + '_hyst.traj', 'w', atoms) mdlogf = fileC[:-6] + '_hyst.log' do_dynamics(mdlogf, atoms, dyn, rend_b, rend_t, v, dt, deltaY, \ theta, dtheta, length, thresZ, \ interval, traj_new, M, twist) mdhystf = fileC[:-6] + '_hyst.traj' logfile = fileC[:-6] + '.log' append_files(logfile, mdlogf, logfile[:-4] + '_comp.log') call([ 'ase-gui', mdfile, mdhystf, '-o', logfile[:-4] + '_comp.traj' ])
def test_Pt_stress_cellopt(): import numpy as np from numpy.testing import assert_allclose from ase.calculators.lammpsrun import LAMMPS from ase.build import bulk from ase.test.eam_pot import Pt_u3 from ase.constraints import ExpCellFilter from ase.optimize import BFGS # (For now) reuse eam file stuff from other lammps test: pot_fn = 'Pt_u3.eam' f = open(pot_fn, 'w') f.write(Pt_u3) f.close() params = {} params['pair_style'] = 'eam' params['pair_coeff'] = ['1 1 {}'.format(pot_fn)] with LAMMPS(specorder=['Pt'], files=[pot_fn], **params) as calc: rng = np.random.RandomState(17) atoms = bulk('Pt') * (2, 2, 2) atoms.rattle(stdev=0.1) atoms.cell += 2 * rng.rand(3, 3) atoms.calc = calc assert_allclose(atoms.get_stress(), calc.calculate_numerical_stress(atoms), atol=1e-4, rtol=1e-4) opt = BFGS(ExpCellFilter(atoms), trajectory='opt.traj') for i, _ in enumerate(opt.irun(fmax=0.001)): pass cell1_ref = np.array([[0.16524, 3.8999, 3.92855], [4.211015, 0.634928, 5.047811], [4.429529, 3.293805, 0.447377]]) assert_allclose(np.asarray(atoms.cell), cell1_ref, atol=3e-4, rtol=3e-4) assert_allclose(atoms.get_stress(), calc.calculate_numerical_stress(atoms), atol=1e-4, rtol=1e-4) assert i < 80, 'Expected 59 iterations, got many more: {}'.format(i)
def test_Ar_minimize_multistep(): from ase.calculators.lammpsrun import LAMMPS from ase.cluster.icosahedron import Icosahedron from ase.data import atomic_numbers, atomic_masses from numpy.testing import assert_allclose ar_nc = Icosahedron('Ar', noshells=2) ar_nc.cell = [[300, 0, 0], [0, 300, 0], [0, 0, 300]] ar_nc.pbc = True params = {} params['pair_style'] = 'lj/cut 8.0' params['pair_coeff'] = ['1 1 0.0108102 3.345'] params['masses'] = ['1 {}'.format(atomic_masses[atomic_numbers['Ar']])] with LAMMPS(specorder=['Ar'], **params) as calc: ar_nc.calc = calc F1_numer = calc.calculate_numerical_forces(ar_nc) assert_allclose(ar_nc.get_potential_energy(), -0.468147667942117, atol=1e-4, rtol=1e-4) assert_allclose(ar_nc.get_forces(), F1_numer, atol=1e-4, rtol=1e-4) params['minimize'] = '1.0e-15 1.0e-6 2000 4000' # add minimize calc.parameters = params # set_atoms=True to read final coordinates after minimization calc.run(set_atoms=True) # get final coordinates after minimization ar_nc.set_positions(calc.atoms.positions) assert_allclose(ar_nc.get_potential_energy(), -0.4791815887032201, atol=1e-4, rtol=1e-4) assert_allclose(ar_nc.get_forces(), calc.calculate_numerical_forces(ar_nc), atol=1e-4, rtol=1e-4)
def relaxBend(bend, left_idxs, right_idxs, edge, bond, mdrelax): constraints = [] constraints.append(FixAtoms(indices=left_idxs)) constraints.append(FixAtoms(indices=right_idxs)) #twist = twistConst_Rod(bend, 1, edge, bond ,F = 20) #twist.set_angle(np.pi/3 + 2./180*np.pi) #constraints.append(twist) add_pot = LJ_potential_smooth(bend, bond) constraints.append(add_pot) calc = LAMMPS(parameters=get_lammps_params()) bend.set_calculator(calc) # END CALCULATOR # RELAX bend.set_constraint(constraints) dyn = BFGS(bend, trajectory=mdrelax) dyn.run(fmax=0.05)
def all_lmp(): all_lmp_dict = {} species = ["H", "He"] specie_symbol_list = " ".join(species) masses = [ f"{i} {_Z_to_mass[_element_to_Z[species[i]]]}" for i in range(len(species)) ] parameters = { "command": os.environ.get("lmp"), # set up executable for ASE "newton": "off", "pair_style": "mgp", "mass": masses, } # set up input params for bodies in body_list: for multihyps in multi_list: # create ASE calc label = f"{bodies}{multihyps}" files = [f"{label}.mgp"] by = "yes" if bodies == "2" else "no" ty = "yes" if bodies == "3" else "no" parameters["pair_coeff"] = [ f"* * {label}.mgp {specie_symbol_list} {by} {ty}" ] lmp_calc = LAMMPS( label=label, keep_tmp_files=True, tmp_dir="./tmp/", parameters=parameters, files=files, specorder=species, ) all_lmp_dict[f"{bodies}{multihyps}"] = lmp_calc yield all_lmp_dict del all_lmp_dict
def test_Ar_minimize(): from ase.calculators.lammpsrun import LAMMPS from ase.cluster.icosahedron import Icosahedron from ase.data import atomic_numbers, atomic_masses from numpy.testing import assert_allclose from ase.optimize import LBFGS ar_nc = Icosahedron('Ar', noshells=2) ar_nc.cell = [[300, 0, 0], [0, 300, 0], [0, 0, 300]] ar_nc.pbc = True params = {} params['pair_style'] = 'lj/cut 8.0' params['pair_coeff'] = ['1 1 0.0108102 3.345'] params['masses'] = ['1 {}'.format(atomic_masses[atomic_numbers['Ar']])] with LAMMPS(specorder=['Ar'], **params) as calc: ar_nc.calc = calc assert_allclose(ar_nc.get_potential_energy(), -0.468147667942117, atol=1e-4, rtol=1e-4) assert_allclose(ar_nc.get_forces(), calc.calculate_numerical_forces(ar_nc), atol=1e-4, rtol=1e-4) dyn = LBFGS(ar_nc, force_consistent=False) dyn.run(fmax=1E-6) assert_allclose(ar_nc.get_potential_energy(), -0.4791815886953914, atol=1e-4, rtol=1e-4) assert_allclose(ar_nc.get_forces(), calc.calculate_numerical_forces(ar_nc), atol=1e-4, rtol=1e-4)
def test_no_data_file_wrap(): """ If 'create_atoms' hasn't been given the appropriate 'remap yes' option, atoms falling outside of a periodic cell are not actually created. The lammpsrun calculator will then look at the thermo output and determine a discrepancy the number of atoms reported compared to the length of the ASE Atoms object and raise a RuntimeError. This problem can only possibly arise when the 'no_data_file' option for the calculator is set to True. Furthermore, note that if atoms fall outside of the box along non-periodic dimensions, create_atoms is going to refuse to create them no matter what, so you simply can't use the 'no_data_file' option if you want to allow for that scenario. """ from ase.atoms import Atoms from ase.calculators.lammpsrun import LAMMPS # Make a periodic box and put one atom outside of it pos = [[0.0, 0.0, 0.0], [-2.0, 0.0, 0.0]] atoms = Atoms(symbols=["Ar"] * 2, positions=pos, cell=[10.0, 10.0, 10.0], pbc=True) # Set parameters for calculator params = {} params["pair_style"] = "lj/cut 8.0" params["pair_coeff"] = ["1 1 0.0108102 3.345"] # Don't write a data file string. This will force # ase.calculators.lammps.inputwriter.write_lammps_in to write a bunch of # 'create_atoms' commands into the LAMMPS input file params["no_data_file"] = True with LAMMPS(specorder=["Ar"], **params) as calc: atoms.calc = calc atoms.get_potential_energy()
def corr_KC(): atoms = graphene_nanoribbon(1, 1, type='armchair', C_C=bond, saturated=False) atoms.rotate([1, 0, 0], np.pi / 2, rotate_cell=True) if edge == 'ac': atoms.rotate([0, 0, 1], -np.pi / 2, rotate_cell=True) del atoms[[0, 3]] trans_idx = 1 elif edge == 'zz': del atoms[[1, 0]] trans_idx = 0 atoms.set_cell([20, 20, 10]) atoms.center() params = {} params['positions'] = atoms.positions params['chemical_symbols'] = atoms.get_chemical_symbols() params['ia_dist'] = 10 params['edge'] = edge params['bond'] = bond params['ncores'] = 2 add_KC = KC_potential_p(params, True) constraints = [] for i in range(len(atoms)): fix_l = FixedLine(i, [0., 0., 1.]) constraints.append(fix_l) constraints.append(add_KC) lamp_parameters = get_lammps_params(H=False) calc = LAMMPS(parameters=lamp_parameters) #, files=['lammps.data']) atoms.set_calculator(calc) atoms.set_constraint(constraints) #dyn = BFGS(atoms, trajectory = 'test.traj') #dyn.run(fmax=0.05) #plot_posits(atoms, edge, bond) trans_vec = trans_atomsKC(atoms.positions[trans_idx], edge, bond) atoms.translate(trans_vec) #plot_posits(atoms, edge, bond) init_pos = atoms.positions.copy() r_around = init_pos[trans_idx] #thetas = np.linspace(0, np.pi/3, 7) #, endpoint = False) #thetas_deg = np.array([1,3,5,7,9,11,12,13,15,17,43,45,47,48,49,51,57,55,57,59]) thetas_deg = np.array([ .5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, 16.5, 17.5, 18.5, 19.5 ]) traj = PickleTrajectory(path + '%s_corr_twist_thetas_(%.1f-%.1f).traj' \ %(edge, np.min(thetas_deg), np.max(thetas_deg)), 'w', atoms) n = 100 for i, theta_deg in enumerate(thetas_deg): fname = path + 'corr_%s_theta=%.2f.data' % (edge, theta_deg) print 'Calculating theta = %.2f' % (theta_deg) theta = theta_deg / 360 * np.pi * 2 print 'time ' + str(datetime.now().time()) atoms.positions = init_pos atoms.rotate([0, 0, 1], theta, center=r_around) rot_init_pos = atoms.positions.copy() lat_vec_theta1 = lat_vec1.copy() lat_vec_theta2 = lat_vec2.copy() trans_vec2 = lat_vec_theta2.copy() / n data = np.zeros((n, n)) for k in range(n): atoms.positions = rot_init_pos atoms.translate(lat_vec_theta1 * float(k) / n) #plot_posits(atoms, edge, bond, vecs = [lat_vec_theta1, lat_vec_theta2]) print '%.1f percent done' % (100 * float(k) / n) for l in range(n): atoms.translate(trans_vec2) emin = get_optimal_h(atoms, len(atoms), dyn=False)[0] data[ k, l] = emin #atoms.get_potential_energy()/len(atoms) #emin # saveAndPrint(atoms, traj, False) header = '%s runs along x-dir, angle measured from x-axis, natoms = %i. x (Angs), e (eV/atom), hmin \n\ the lattice vectors are l1 = [%.5f, %.5f, %.5f] and l2 = [%.5f, %.5f, %.5f], they are divided in %i parts. data[i,j,:] \n\ -> atoms pos += l1/n*i + l2/n*j, initial position is such that atom1 is in middle if hexagon.' \ %(edge, len(atoms), lat_vec_theta1[0], lat_vec_theta1[1], lat_vec_theta1[2], \ lat_vec_theta2[0], lat_vec_theta2[1], lat_vec_theta2[2], n) np.savetxt(fname, data, header=header)
#!/usr/bin/env python3 import os, wget from ase import Atom, Atoms from ase.build import bulk from ase.calculators.lammpsrun import LAMMPS #基于文件的ASE计算器 from ase.calculators.lammpslib import LAMMPSlib #基于LAMMPS原生的Python接口 # 势函数下载 url = "https://openkim.org/files/MO_418978237058_005/NiAlH_jea.eam.alloy" pot_fname = wget.filename_from_url(url) if not os.path.exists(pot_fname): pot_fname = wget.download(url) # 模型构建 Ni = bulk('Ni', cubic=True) H = Atom('H', position=Ni.cell.diagonal() / 2) NiH = Ni + H NiH.pbc = True # 开始计算 lammps = LAMMPS(files=[pot_fname], parameters={ 'pair_style': 'eam/alloy', 'pair_coeff': ['* * {} H Ni'.format(pot_fname)] }) lammps.set(command="/usr/bin/lmp") NiH.calc = lammps print("Energy ", NiH.get_potential_energy())
import os from ase.calculators.lammpsrun import LAMMPS os.environ[ "ASE_LAMMPSRUN_COMMAND"] = "/Users/Cas/gits/lammps-ace/src/lmp_serial" model_dir = os.path.dirname(os.path.realpath(__file__)) parameters = { 'pair_style': 'pace', 'pair_coeff': ['* * Si_B8_N4_18_07_lap_dia_1.1_rep_2B+ACE.ace Si'] } files = [os.path.join(model_dir, "Si_B8_N4_18_07_lap_dia_1.1_rep_2B+ACE.ace")] calculator = LAMMPS(parameters=parameters, files=files) name = "ACE" no_checkpoint = True
from numpy.testing import assert_allclose from ase.calculators.lammpsrun import LAMMPS from ase.build import bulk from ase.test.eam_pot import Pt_u3 from ase.constraints import ExpCellFilter from ase.optimize import BFGS # (For now) reuse eam file stuff from other lammps test: pot_fn = 'Pt_u3.eam' f = open(pot_fn, 'w') f.write(Pt_u3) f.close() params = {} params['pair_style'] = 'eam' params['pair_coeff'] = ['1 1 {}'.format(pot_fn)] calc = LAMMPS(specorder=['Pt'], files=[pot_fn], **params) rng = np.random.RandomState(17) atoms = bulk('Pt') * (2, 2, 2) atoms.rattle(stdev=0.1) atoms.cell += 2 * rng.rand(3, 3) atoms.calc = calc assert_allclose(atoms.get_stress(), calc.calculate_numerical_stress(atoms), atol=1e-4, rtol=1e-4) opt = BFGS(ExpCellFilter(atoms), trajectory='opt.traj') for i, _ in enumerate(opt.irun(fmax=0.05)):
def corr_KC(width, edge): #width = 5 #edge = 'ac' params0 = get_simulParams(edge)[-1] bond = params0['bond'] atoms = create_stucture(1, width, edge, key='top', a=bond)[0] atoms.set_cell([40, 40, 20]) atoms.center() atoms.positions[:, 2] = 3.4 h_t = [] for i in range(len(atoms)): if atoms[i].number == 1: h_t.append(i) del atoms[h_t] params = {} params['positions'] = atoms.positions params['chemical_symbols'] = atoms.get_chemical_symbols() params['ia_dist'] = 10 params['edge'] = edge params['bond'] = bond params['ncores'] = 2 add_KC = KC_potential_p(params) constraints = [] for i in range(len(atoms)): fix_l = FixedLine(i, [0., 0., 1.]) constraints.append(fix_l) constraints.append(add_KC) lamp_parameters = get_lammps_params(H=False) calc = LAMMPS(parameters=lamp_parameters) #, files=['lammps.data']) atoms.set_calculator(calc) atoms.set_constraint(constraints) #dyn = BFGS(atoms, trajectory = 'test.traj') #dyn.run(fmax=0.05) trans_vec = trans_atomsKC(atoms.positions[0], edge, bond) atoms.translate(trans_vec) init_pos = atoms.positions.copy() middle = [ np.average(init_pos[:, 0]), np.average(init_pos[:, 1]), np.average(init_pos[:, 2]) ] thetas = np.linspace(np.pi / 2, np.pi, 91) L = 4 * bond ds = .05 n = int(L / ds) for i, theta in enumerate(thetas): fname = path + 'corr_w=%02d_%s_theta=%.2f.data' % (width, edge, theta / (2 * np.pi) * 360) if not os.path.isfile(fname): print 'Calculating w=%i, theta = %.2f' % (width, theta / (2 * np.pi) * 360) atoms.positions = init_pos atoms.rotate([0, 0, 1], theta, center=middle) trans_vec = np.array([-np.sin(theta), np.cos(theta), 0]) data = np.zeros((n, 3)) for j in range(n): atoms.translate(ds * trans_vec) emin, hmin = get_optimal_h(atoms, len(atoms), dyn=False) data[j, :] = [j * ds, emin, hmin] #plot_posits(atoms, edge, bond) header = '%s runs along x-dir, angle measured from x-axis, natoms = %i. x (Angs), e (eV/atom), hmin' % ( edge, len(atoms)) np.savetxt(fname, data, header=header)
def shearDyn(width, edge, save = False): ratio = 8 atoms = create_stucture(ratio, width, edge, key = 'top') # FIXES constraints = [] top, bot = get_topInds(atoms) rend = get_rightInds(atoms, top) fix_bot = FixAtoms(indices = bot) view(atoms) constraints.append(fix_bot) for i in rend: constraints.append(FixedLine(i, (1,0,0))) # KC params = get_params(atoms) params['top_inds'] \ = top add_kc = KC_potential_p(params) constraints.append(add_kc) # END FIXES # CALCULATOR LAMMPS parameters = {'pair_style':'rebo', 'pair_coeff':['* * CH.airebo C H'], 'mass' :['1 12.0', '2 1.0'], 'units' :'metal', 'boundary' :'p p f'} calc = LAMMPS(parameters=parameters) atoms.set_calculator(calc) # END CALCULATOR # TRAJECTORY mdfile, mdlogfile, mdrelax = get_fileName(edge, width, ratio, v, taito = False) if save: traj = PickleTrajectory(mdfile, 'w', atoms) else: traj = None #data = np.zeros((M/interval, 5)) # RELAX atoms.set_constraint(add_kc) dyn = BFGS(atoms, trajectory = mdrelax) dyn.run(fmax=0.05) # FIX AFTER RELAXATION atoms.set_constraint(constraints) # DYNAMICS dyn = Langevin(atoms, dt*units.fs, T*units.kB, fric) n = 0 header = '#t [fs], d [Angstrom], epot_tot [eV], ekin_tot [eV], etot_tot [eV] \n' log_f = open(mdlogfile, 'w') log_f.write(header) log_f.close() if T != 0: # put initial MaxwellBoltzmann velocity distribution mbd(atoms, T*units.kB) for i in range(0, M): if tau < i*dt: hw = i*dy for ind in rend: atoms[ind].position[1] += dy dyn.run(1) if i%interval == 0: epot, ekin = saveAndPrint(atoms, traj, False)[:2] if T != 0: if tau < i*dt: hw = i*dy - tau*v else: hw = 0 else: hw = i*dy data = [i*dt, hw, epot, ekin, epot + ekin] if save: log_f = open(mdlogfile, 'a') stringi = '' for k,d in enumerate(data): if k == 0: stringi += '%.2f ' %d elif k == 1: stringi += '%.6f ' %d else: stringi += '%.12f ' %d log_f.write(stringi + '\n') log_f.close() n += 1 if save and T != 0 and i*dt == tau: log_f = open(mdlogfile, 'a') log_f.write('# Thermalization complete. ' + '\n') log_f.close() if 1e2 <= M: if i%(int(M/100)) == 0: print 'ready = %.1f' %(i/(int(M/100))) + '%'
def shearDyn(width, ratio, edge, save=False): atoms, L, W, length_int, b_idxs = create_stucture(ratio, width, edge, key='top') view(atoms) # FIXES constraints, add_LJ, twist, rend_b, rend_t = get_constraints(atoms, edge, bond, b_idxs, key='twist') # END FIXES # CALCULATOR LAMMPS calc = LAMMPS(parameters=get_lammps_params()) atoms.set_calculator(calc) # END CALCULATOR # TRAJECTORY mdfile, mdlogfile, mdrelax, simulfile = get_fileName('LJ', edge + '_twist', width, \ length_int, int(T), taito) if save: traj = PickleTrajectory(mdfile, 'w', atoms) else: traj = None #data = np.zeros((M/interval, 5)) # RELAX atoms.set_constraint(add_LJ) dyn = BFGS(atoms, trajectory=mdrelax) dyn.run(fmax=0.05) # FIX AFTER RELAXATION atoms.set_constraint(constraints) # DYNAMICS dyn = Langevin(atoms, dt * units.fs, T * units.kB, fric) header = '#t [fs], shift y [Angstrom], Rad, epot_tot [eV], \ ekin_tot [eV], etot_tot [eV], F [eV/angst] \n' write_line_own(mdlogfile, header, 'w') if T != 0: # put initial MaxwellBoltzmann velocity distribution mbd(atoms, T * units.kB) y0 = atoms.positions[rend_b, 1][0] kink_formed = False dir_vec = np.array([0., 1., 0.]) i, m = 0, 0 interval = 20 print 'width = %i, length = %i' % (width, length_int) M_therm = int(tau / dt) dyn.run(M_therm) F = 0. while not kink_formed: pos_0 = atoms.positions[rend_b][0] F_vec = F * np.array([dir_vec[1], -dir_vec[0], 0.]) twist.set_F(F_vec) dyn.run(interval) i += interval epot, ekin = saveAndPrint(atoms, traj, False)[:2] pos_1 = atoms.positions[rend_b][0] deltaY = pos_1[1] - y0 v = np.sign(pos_1[1] - pos_0[1]) * np.linalg.norm( (pos_1 - pos_0) / (interval * dt)) R = get_R(L, deltaY) dir_vec = get_dir(atoms, rend_b, rend_t) data = [ i * dt, deltaY, R, epot, ekin, epot + ekin, F_vec[0], F_vec[1], F_vec[2] ] #if vmax/5 < v: F -= .01 if v < vmax / 5 and not kink_formed: F += .01 print deltaY, v, F if save: stringi = '' for k, d in enumerate(data): if k == 0: stringi += '%.2f ' % d elif k == 1 or k == 2: stringi += '%.4f ' % d else: stringi += '%.12f ' % d write_line_own(mdlogfile, stringi + '\n', 'a') if thres_Z < np.max(atoms.positions[:, 2]) and m == 0: idxs = np.where(thres_Z < atoms.positions[:, 2]) write_line_own(mdlogfile, '# Kink! at idxs %s' % str(idxs) + '\n', 'a') print ' kink formed! ' kink_formed = True F = 0 if save and T != 0 and i * dt == tau: write_line_own(mdlogfile, '# Thermalization complete. ' + '\n', 'a') if i % 100 == 0: print i if kink_formed: m += 1 make_simul_param_file(simulfile, W, L, width, length_int, v, deltaY/i, T, \ dt, fric, thres_Z, interval, deltaY, i, edge)
def shearDyn(params_set, pot_key, save=False): bond = params_set['bond'] T = params_set['T'] taito = params_set['taito'] dt, fric = params_set['dt'], params_set['fric'] tau = params_set['tau'] vmax = params_set['vmax'] vMAX = params_set['vMAX'] thres_Z = params_set['thresZ'] width = params_set['width'] ratio = params_set['ratio'] edge = params_set['edge'] atoms, L, W, length_int, b_idxs = \ create_stucture(ratio, width, edge, key = 'top', a = bond) mdfile, mdlogfile, mdrelax, simulfile, folder, relaxed \ = get_fileName(pot_key, edge + '_twistRod', width, \ length_int, vmax * 1000, int(T), taito) #view(atoms) # FIXES constraints, add_pot, twist, rend_b, rend_t = \ get_constraints(atoms, edge, bond, b_idxs, \ key = 'twist_p', pot = pot_key) # END FIXES if relaxed: atoms = PickleTrajectory(mdrelax, 'r')[-1] else: trans = trans_atomsKC(atoms.positions[rend_b], edge, bond) atoms.translate(trans) #plot_posits(atoms, edge, bond) # CALCULATOR LAMMPS calc = LAMMPS(parameters=get_lammps_params()) atoms.set_calculator(calc) # END CALCULATOR # TRAJECTORY if save: traj = PickleTrajectory(mdfile, 'w', atoms) else: traj = None #data = np.zeros((M/interval, 5)) # RELAX atoms.set_constraint(add_pot) dyn = BFGS(atoms, trajectory=mdrelax) dyn.run(fmax=0.05) dist = np.linalg.norm(atoms.positions[rend_b] - atoms.positions[rend_t]) twist.set_dist(dist) # FIX AFTER RELAXATION atoms.set_constraint(constraints) # DYNAMICS dyn = Langevin(atoms, dt * units.fs, T * units.kB, fric) header = '#t [fs], shift y [Angstrom], Rad, theta [rad], hmax [A], epot_tot [eV], ekin_tot [eV], etot_tot [eV], F [eV/angst] \n' write_line_own(mdlogfile, header, 'w') if T != 0: # put initial MaxwellBoltzmann velocity distribution mbd(atoms, T * units.kB) y0 = atoms.positions[rend_b, 1] kink_formed = False kink_vanished = False i = 0 print 'width = %i, length = %i, v=%.6f' % (width, length_int, vmax) M_therm = int(tau / dt) dyn.run(M_therm) M = int(2 * L / (np.pi * dt * vmax)) M_min = int(2 * L / (np.pi * dt * vMAX)) dtheta = np.pi / 2 / M dtheta_max = np.pi / 2 / M_min interval = int(M / 1000) theta, time, m = 0., 0., 0 i_kink = 0 while 0. <= theta: if not kink_formed: if theta < np.pi / 4: theta += dtheta_max else: theta += dtheta twist.set_angle(theta) else: if i_kink / 10 < m: theta -= dtheta twist.set_angle(theta) dyn.run(1) if i % interval == 0: epot, ekin = saveAndPrint(atoms, traj, False)[:2] deltaY = atoms.positions[rend_b, 1] - y0 hmax = np.max( atoms.positions[:, 2]) #substract the height of the plane? R = get_R(L, deltaY) data = [time, deltaY, R, theta, hmax, epot, ekin, epot + ekin] if save: stringi = '' for k, d in enumerate(data): if k == 0: stringi += '%.2f ' % d elif k == 1 or k == 2: stringi += '%.4f ' % d else: stringi += '%.12f ' % d write_line_own(mdlogfile, stringi + '\n', 'a') if thres_Z < hmax and not kink_formed: idxs = np.where(thres_Z < atoms.positions[:, 2]) write_line_own(mdlogfile, '# Kink! at idxs %s' % str(idxs) + '\n', 'a') print ' kink formed! ' + str(i / interval) kink_formed = True i_kink = i if hmax < 3.6 and kink_formed and not kink_vanished: write_line_own(mdlogfile, '# Kink vanished! \n', 'a') print ' kink vanished ' kink_vanished = True print i / interval, theta / (2 * np.pi) * 360, R if kink_formed: m += 1 i += 1 time += dt make_simul_param_file(simulfile, W, L, width, length_int, dtheta/dt, dtheta, T, \ dt, fric, thres_Z, interval, deltaY, theta, i, edge) return folder
def shearDyn(width, ratio, edge, save=False, force_dir_update=True): atoms, L, W, length_int, b_idxs = create_stucture(ratio, width, edge, key='rib+base') view(atoms) # FIXES constraints, add_LJ, rend_b, rend_t = get_constraints( atoms, edge, bond, b_idxs) # END FIXES # CALCULATOR LAMMPS calc = LAMMPS(parameters=get_lammps_params()) atoms.set_calculator(calc) # END CALCULATOR # TRAJECTORY add = '' if force_dir_update: add = '_ff' mdfile, mdlogfile, mdrelax, simulfile = get_fileName('LJ', edge + add, width, \ length_int, int(T), taito) if save: traj = PickleTrajectory(mdfile, 'w', atoms) else: traj = None #data = np.zeros((M/interval, 5)) # RELAX atoms.set_constraint(add_LJ) dyn = BFGS(atoms, trajectory=mdrelax) dyn.run(fmax=0.05) # FIX AFTER RELAXATION atoms.set_constraint(constraints) # DYNAMICS dyn = Langevin(atoms, dt * units.fs, T * units.kB, fric) n = 0 header = '#t [fs], shift y [Angstrom], Rad, epot_tot [eV], ekin_tot [eV], etot_tot [eV] \n' write_line_own(mdlogfile, header, 'w') if T != 0: # put initial MaxwellBoltzmann velocity distribution mbd(atoms, T * units.kB) deltaY = 0. eta = 1.1 # ratio between the lengths of the streched and compressed side of the ribbon. r = L / W # length to width ratio. deltaYMax = W / 2. * (eta + 1) / (eta - 1) * (1 - np.cos(2 * r * (eta - 1) / (eta + 1))) # Estimate for the required shift dy = v * dt M = deltaYMax / dy interval = int(M / 1000) kink_formed = False dir_vec = np.array([0., 1., 0.]) i, m = 0, 0 print 'width = %i, length = %i' % (width, length_int) while m <= int(M / 30): if tau < i * dt: deltaY += dy * dir_vec[1] for ind in rend_b: atoms[ind].position[:] += dy * dir_vec dyn.run(1) if i % interval == 0: epot, ekin = saveAndPrint(atoms, traj, False)[:2] R = get_R(L, deltaY) if force_dir_update: dir_vec = get_dir(atoms, rend_b, rend_t) data = [i * dt, deltaY, R, epot, ekin, epot + ekin] if save: stringi = '' for k, d in enumerate(data): if k == 0: stringi += '%.2f ' % d elif k == 1 or k == 2: stringi += '%.4f ' % d else: stringi += '%.12f ' % d write_line_own(mdlogfile, stringi + '\n', 'a') n += 1 if thres_Z < np.max(atoms.positions[:, 2]) and m == 0: idxs = np.where(thres_Z < atoms.positions[:, 2]) write_line_own(mdlogfile, '# Kink! at idxs %s' % str(idxs) + '\n', 'a') print ' kink formed! ' kink_formed = True if save and T != 0 and i * dt == tau: write_line_own(mdlogfile, '# Thermalization complete. ' + '\n', 'a') if i % int(M / 100) == 0: print str(i / int(M / 100)) + ' ~ % done' if kink_formed: m += 1 i += 1 make_simul_param_file(simulfile, W, L, width, length_int, v, dy, T, \ dt, fric, thres_Z, interval, deltaY, M, edge)
def calc(self, **kwargs): from ase.calculators.lammpsrun import LAMMPS return LAMMPS(command=self.executable, **kwargs)
from ase.calculators.lammpsrun import LAMMPS from ase.cluster.icosahedron import Icosahedron from ase.data import atomic_numbers, atomic_masses from numpy.testing import assert_allclose from ase.optimize import LBFGS ar_nc = Icosahedron('Ar', noshells=2) ar_nc.cell = [[300, 0, 0], [0, 300, 0], [0, 0, 300]] ar_nc.pbc = True params = {} params['pair_style'] = 'lj/cut 8.0' params['pair_coeff'] = ['1 1 0.0108102 3.345'] params['masses'] = ['1 {}'.format(atomic_masses[atomic_numbers['Ar']])] calc = LAMMPS(specorder=['Ar'], **params) ar_nc.set_calculator(calc) assert_allclose(ar_nc.get_potential_energy(), -0.468147667942117, atol=1e-4, rtol=1e-4) assert_allclose(ar_nc.get_forces(), calc.calculate_numerical_forces(ar_nc), atol=1e-4, rtol=1e-4) dyn = LBFGS(ar_nc, force_consistent=False) dyn.run(fmax=1E-6)
lammpsrun calculator will then look at the thermo output and determine a discrepancy the number of atoms reported compared to the length of the ASE Atoms object and raise a RuntimeError. This problem can only possibly arise when the 'no_data_file' option for the calculator is set to True. Furthermore, note that if atoms fall outside of the box along non-periodic dimensions, create_atoms is going to refuse to create them no matter what, so you simply can't use the 'no_data_file' option if you want to allow for that scenario. """ from ase.atoms import Atoms from ase.calculators.lammpsrun import LAMMPS # Make a periodic box and put one atom outside of it pos = [[0.0, 0.0, 0.0], [-2.0, 0.0, 0.0]] atoms = Atoms(symbols=["Ar"] * 2, positions=pos, cell=[10.0, 10.0, 10.0], pbc=True) # Set parameters for calculator params = {} params["pair_style"] = "lj/cut 8.0" params["pair_coeff"] = ["1 1 0.0108102 3.345"] # Don't write a data file string. This will force # ase.calculators.lammps.inputwriter.write_lammps_in to write a bunch of # 'create_atoms' commands into the LAMMPS input file params["no_data_file"] = True with LAMMPS(specorder=["Ar"], **params) as calc: atoms.calc = calc energy = atoms.get_potential_energy()
# https://physics.stackexchange.com/questions/250018 pair_style = 'buck/coul/long 12.0' pair_coeff = ['1 1 3796.9 0.2603 124.90'] pair_coeff += ['2 2 1227.2 0.3214 124.90'] pair_coeff += ['1 2 4117.9 0.3048 0.0'] masses = [ '1 {}'.format(atomic_masses[atomic_numbers['Na']]), '2 {}'.format(atomic_masses[atomic_numbers['Cl']]) ] calc = LAMMPS( specorder=['Na', 'Cl'], pair_style=pair_style, pair_coeff=pair_coeff, masses=masses, atom_style='charge', kspace_style='pppm 1.0e-5', keep_tmp_files=True, ) for a in nacl: if a.symbol == 'Na': a.charge = +1. else: a.charge = -1. nacl.set_calculator(calc) E = nacl.get_potential_energy()
from ase.io import read, write import numpy as np from ase.calculators.lammpsrun import LAMMPS from ase import units from ase.stressbox import stressbox import math parameters = { 'units': 'metal', 'atom_style': 'atomic', 'boundary': 'p p p', 'pair_style': 'sw', 'pair_coeff': ['* * Si.sw Si'] } lmp_calc = LAMMPS(parameters=parameters) refatom = read('si_alpha_1000atoms_sw_relax.lmpdata', format='lammps-data', style="atomic") patom = read('si_alpha_1000atoms_random.lmpdata', format='lammps-data', style="atomic") patom.set_calculator(lmp_calc) pstress = patom.get_cell() * 0.0 fixstrain = np.ones((3, 3))
pot_fn = 'Pt_u3.eam' f = open(pot_fn, 'w') f.write(Pt_u3) f.close() slab = fcc111('Pt', size=(10, 10, 5), vacuum=30.0) # We use fully periodic boundary conditions because the Lammpsrun # calculator does not know if it can convert the cell correctly with # mixed ones and will give a warning. slab.pbc = 1 params = {} params['pair_style'] = 'eam' params['pair_coeff'] = ['1 1 {}'.format(pot_fn)] calc = LAMMPS(specorder=['Pt'], files=[pot_fn], **params) slab.set_calculator(calc) E = slab.get_potential_energy() F = slab.get_forces() assert abs(E - -2758.63) < 1E-2 assert abs(norm(F) - 11.3167) < 1E-4 # !TODO: tests nothing as atom postions are not set without set_atoms=True assert abs(norm(slab.positions) - 955.259) < 1E-3 params['group'] = [ 'lower_atoms id ' + ' '.join([str(i + 1) for i, tag in enumerate(slab.get_tags()) if tag >= 4]) ] params['fix'] = ['freeze_lower_atoms lower_atoms setforce 0.0 0.0 0.0'] params['run'] = 100
def LAMMPSRunCalculator(model_name, model_type, supported_species, options, debug, **kwargs): """ Used for Portable Models or LAMMPS Simulator Models if specifically requested """ def get_params(model_name, supported_units, supported_species, atom_style): """ Extract parameters for LAMMPS calculator from model definition lines. Returns a dictionary with entries for "pair_style" and "pair_coeff". Expects there to be only one "pair_style" line. There can be multiple "pair_coeff" lines (result is returned as a list). """ parameters = {} # In case the SM supplied its own atom_style in its model-init -- only needed # because lammpsrun writes data files and needs to know the proper format if atom_style: parameters["atom_style"] = atom_style # Set units to prevent them from defaulting to metal parameters["units"] = supported_units parameters["model_init"] = [ "kim_init {} {}{}".format(model_name, supported_units, os.linesep) ] parameters["kim_interactions"] = "kim_interactions {}{}".format( (" ").join(supported_species), os.linesep) # For every species in "supported_species", add an entry to the # "masses" key in dictionary "parameters". parameters["masses"] = [] for i, species in enumerate(supported_species): if species not in atomic_numbers: raise KIMCalculatorError( "Could not determine mass of unknown species " "{} listed as supported by model".format(species)) massstr = str( convert( atomic_masses[atomic_numbers[species]], "mass", "ASE", supported_units, )) parameters["masses"].append(str(i + 1) + " " + massstr) return parameters options_not_allowed = [ "parameters", "files", "specorder", "keep_tmp_files" ] _check_conflict_options(options, options_not_allowed, simulator="lammpsrun") # If no atom_style kwarg is passed, lammpsrun will default to atom_style atomic, # which is what we want for KIM Portable Models atom_style = kwargs.get("atom_style", None) # Simulator Models will supply their own units from their metadata. For Portable # Models, we use "metal" units. supported_units = kwargs.get("supported_units", "metal") # Set up kim_init and kim_interactions lines parameters = get_params(model_name, supported_units, supported_species, atom_style) return LAMMPS(**parameters, specorder=supported_species, keep_tmp_files=debug, **options)
from ase.calculators.lammpsrun import LAMMPS from ase.cluster.icosahedron import Icosahedron from ase.data import atomic_numbers, atomic_masses from numpy.linalg import norm ar_nc = Icosahedron('Ar', noshells=2) ar_nc.cell = [[300, 0, 0], [0, 300, 0], [0, 0, 300]] ar_nc.pbc = True params = {} params['pair_style'] = 'lj/cut 8.0' params['pair_coeff'] = ['1 1 0.0108102 3.345'] params['mass'] = ['1 {}'.format(atomic_masses[atomic_numbers['Ar']])] calc = LAMMPS(specorder=['Ar'], parameters=params) ar_nc.set_calculator(calc) E = ar_nc.get_potential_energy() F = ar_nc.get_forces() assert abs(E - -0.47) < 1E-2 assert abs(norm(F) - 0.0574) < 1E-4 assert abs(norm(ar_nc.positions) - 23.588) < 1E-3 params['minimize'] = '1.0e-15 1.0e-6 2000 4000' # add minimize calc.params = params # set_atoms=True to read final coordinates after minimization calc.run(set_atoms=True)