def MakeAtoms(elem1, elem2=None): if elem2 is None: elem2 = elem1 a1 = reference_states[elem1]['a'] a2 = reference_states[elem2]['a'] a0 = (0.5 * a1**3 + 0.5 * a2**3)**(1.0/3.0) * 1.03 if ismaster: # 50*50*50 would be big enough, but some vacancies are nice. print "Z1 = %i, Z2 = %i, a0 = %.5f" % (elem1, elem2, a0) atoms = FaceCenteredCubic(symbol='Cu', size=(51,51,51)) nremove = len(atoms) - 500000 assert nremove > 0 remove = np.random.choice(len(atoms), nremove, replace=False) del atoms[remove] if isparallel: atoms = atoms.repeat(cpuLayout) if elem1 != elem2: z = atoms.get_atomic_numbers() z[np.random.choice(len(atoms), len(atoms)/2, replace=False)] = elem2 atoms.set_atomic_numbers(z) else: atoms = None if isparallel: atoms = MakeParallelAtoms(atoms, cpuLayout) MaxwellBoltzmannDistribution(atoms, T * units.kB) return atoms
def MakeCu(T=300, size=(29, 29, 30)): print "Preparing", T, "K Copper system." atoms = FaceCenteredCubic(directions=[[1, 0, 0], [0, 1, 0], [0, 0, 1]], symbol='Cu', size=size) atoms.set_calculator(EMT()) MaxwellBoltzmannDistribution(atoms, 2 * T * units.kB) #dyn = VelocityVerlet(atoms, 5*units.fs) dyn = Langevin(atoms, 5 * units.fs, T * units.kB, 0.05) dyn.run(50) print "Done. Temperature =", temperature(atoms), \ "K. Number of atoms: ", len(atoms) return atoms
def MakeCu3Ni(T=300): print "Preparing", T, "K NiCu3 system." atoms = L1_2(directions=[[1, 0, 0], [0, 1, 0], [0, 0, 1]], symbol=('Ni', 'Cu'), latticeconstant=3.61, size=(29, 29, 30)) atoms.set_calculator(EMT()) MaxwellBoltzmannDistribution(atoms, 2 * T * units.kB) #dyn = VelocityVerlet(atoms, 5*units.fs) dyn = Langevin(atoms, 5 * units.fs, T * units.kB, 0.05) dyn.run(50) print "Done. Temperature =", temperature(atoms), \ "K. Number of atoms: ", len(atoms) return atoms
def MakeAtoms(elem1, elem2=None): if elem2 is None: elem2 = elem1 a1 = reference_states[elem1]['a'] a2 = reference_states[elem2]['a'] a0 = (0.5 * a1**3 + 0.5 * a2**3)**(1.0 / 3.0) * 1.03 if ismaster: print "Z1 = %i, Z2 = %i, a0 = %.5f" % (elem1, elem2, a0) # 50*50*50 would be big enough, but some vacancies are nice. atoms = FaceCenteredCubic(symbol='Cu', size=(51, 51, 51)) nremove = len(atoms) - 500000 assert nremove > 0 remove = np.random.choice(len(atoms), nremove, replace=False) del atoms[remove] if elem1 != elem2: z = atoms.get_atomic_numbers() z[np.random.choice(len(atoms), len(atoms) / 2, replace=False)] = elem2 atoms.set_atomic_numbers(z) if isparallel: # Move this contribution into position uc = atoms.get_cell() x = mpi.world.rank % cpuLayout[0] y = (mpi.world.rank // cpuLayout[0]) % cpuLayout[1] z = mpi.world.rank // (cpuLayout[0] * cpuLayout[1]) assert (0 <= x < cpuLayout[0]) assert (0 <= y < cpuLayout[1]) assert (0 <= z < cpuLayout[2]) offset = x * uc[0] + y * uc[1] + z * uc[2] new_uc = cpuLayout[0] * uc[0] + cpuLayout[1] * uc[1] + cpuLayout[ 2] * uc[2] atoms.set_cell(new_uc, scale_atoms=False) atoms.set_positions(atoms.get_positions() + offset) # Distribute atoms. Maybe they are all on the wrong cpu, but that will # be taken care of. atoms = MakeParallelAtoms(atoms, cpuLayout) MaxwellBoltzmannDistribution(atoms, T * units.kB) return atoms
import sys if len(sys.argv) == 2: arg = sys.argv[1] else: arg = 'Wrong number of arguments.' if arg == 'EMT': filename = 'small_EMT.dat' elif arg == 'EMT2013': filename = 'small_EMT2013.dat' else: print __doc__ sys.exit(1) T = 450 atoms = FaceCenteredCubic(size=(10, 10, 10), symbol='Cu', pbc=False) if arg == 'EMT': atoms.set_calculator(EMT()) else: atoms.set_calculator(EMT2013(EMT2013_parameters)) print "Setting temperature:", T, "K" MaxwellBoltzmannDistribution(atoms, 2 * T * units.kB) Stationary(atoms) dyn1 = Langevin(atoms, 2 * units.fs, temperature=T * units.kB, friction=0.05) dyn1.run(200) dyn = VelocityVerlet(atoms, 3 * units.fs, logfile=filename, loginterval=25) dyn.run(10000000) # 10^7 timesteps is 3 ns.
isparallel = world.size != 1 if world.size == 1: cpulayout = None elif world.size == 2: cpulayout = [2,1,1] elif world.size == 3: cpulayout = [1,3,1] elif world.size == 4: cpulayout = [2,1,2] if ismaster: init = FaceCenteredCubic(size=(10,10,10), symbol='Cu', pbc=False) z = init.get_positions()[:,2] fixedatoms = np.less(z, 0.501*z.max()) print len(init), sum(fixedatoms) MaxwellBoltzmannDistribution(init, 6000*units.kB) init.set_tags(fixedatoms) else: init = None print print "Running simulation with Filter" atoms1 = MakeParallelAtoms(init, cpulayout) atoms1.arrays['r_init'] = atoms1.get_positions() atoms1.set_calculator(EMT()) atoms1a = Filter(atoms1, mask=np.logical_not(atoms1.get_tags())) dyn = VelocityVerlet(atoms1a, 3*units.fs) dyn.run(100) print
logger.write(modelname) logger.write(asapversion + "\n") if ismaster: bigtable.write("%-5d " % mpi.world.size) fasttable.write("%-5d " % mpi.world.size) for size, steps in systemSizes: atoms = MakeCu(size) atomspercpu = len(atoms) positions = atoms.get_positions() basis = atoms.get_cell() atomicnumber = int(atoms.get_atomic_numbers()[0]) # Run the serial timings MaxwellBoltzmannDistribution(atoms, 300 * units.kB) name = "Verlet%d" % (atomspercpu, ) atoms.set_calculator(EMT()) dyn = VelocityVerlet(atoms, 5 * units.fs) verlet = SerialTiming(name, dyn.run, steps, atomspercpu) name = "Langevin%d" % (atomspercpu, ) dyn = Langevin(atoms, 5 * units.fs, 300 * units.kB, 0.001) langevin = SerialTiming(name, dyn.run, steps, atomspercpu) #name = "NPT%d" % (atomspercpu,) #dyn = NPT(atoms, 5*units.fs, 300*units.kB, 0, 25*units.fs, # (75*units.fs)**2 * 140*units.GPa) #npt = SerialTiming(name, dyn.run, steps, atomspercpu) # A distributed atoms.Repeat n = mpi.world.rank gridpos = (n % cpuLayout[0], (n / cpuLayout[0]) % cpuLayout[1],
def run_md(atoms, id, settings_fn): """The function does Molecular Dyanamic simulation (MD) on a material, given by argument atoms. Parameters: atoms (obj): an atoms object defined by class in ase. This is the material which MD will run on. id (int): an identifying number for the material. Returns: obj:atoms object defined in ase, is returned. """ # Read settings settings = read_settings_file(settings_fn) initial_unitcell_atoms = copy.deepcopy(atoms) # Scale atoms object, cubic size = settings['supercell_size'] atoms = atoms * size * (1, 1, 1) # atoms = atoms * (size,size,size) #print(atoms.get_chemical_symbols()) N = len(atoms.get_chemical_symbols()) # Use KIM for potentials from OpenKIM use_kim = settings['use_kim'] # Use Asap for a huge performance increase if it is installed use_asap = True # Create a copy of the initial atoms object for future reference old_atoms = copy.deepcopy(atoms) # Describe the interatomic interactions with OpenKIM potential if use_kim: # use KIM potential atoms.calc = KIM( "LJ_ElliottAkerson_2015_Universal__MO_959249795837_003") else: # otherwise, default to asap3 LennardJones atoms.calc = LennardJones([18], [0.010323], [3.40], rCut=6.625, modified=True) # Set the momenta corresponding to temperature from settings file MaxwellBoltzmannDistribution(atoms, settings['temperature'] * units.kB) # Select integrator if settings['ensemble'] == "NVE": from ase.md.verlet import VelocityVerlet dyn = VelocityVerlet(atoms, settings['time_step'] * units.fs) elif settings['ensemble'] == "NVT": from ase.md.langevin import Langevin dyn = Langevin(atoms, settings['time_step'] * units.fs, settings['temperature'] * units.kB, settings['friction']) interval = settings['interval'] # Creates trajectory files in directory trajectory_files traj = Trajectory("trajectory_files/" + id + ".traj", 'w', atoms) dyn.attach(traj.write, interval=interval) # Number of decimals for most calculated properties. decimals = settings['decimals'] # Boolean indicating if the material is monoatomic. monoatomic = len(set(atoms.get_chemical_symbols())) == 1 # Calculation and writing of properties properties.initialize_properties_file(atoms, initial_unitcell_atoms, id, decimals, monoatomic) dyn.attach(properties.calc_properties, 100, old_atoms, atoms, id, decimals, monoatomic) # unnecessary, used for logging md runs # we should write some kind of logger for the MD def logger(a=atoms): # store a reference to atoms in the definition. """Function to print the potential, kinetic and total energy.""" epot = a.get_potential_energy() / len(a) ekin = a.get_kinetic_energy() / len(a) t = ekin / (1.5 * units.kB) print('Energy per atom: Epot = %.3feV Ekin = %.3feV (T=%3.0fK) ' 'Etot = %.3feV' % (epot, ekin, t, epot + ekin)) # Running the dynamics dyn.attach(logger, interval=interval) #logger() #dyn.run(settings['max_steps']) # check for thermal equilibrium counter = 0 equilibrium = False for i in range(round(settings['max_steps'] / settings['search_interval'])): # hyperparameter epot, ekin_pre, etot, t = properties.energies_and_temp(atoms) # kör steg som motsvarar säg 5 fs dyn.run(settings['search_interval']) # hyperparamter epot, ekin_post, etot, t = properties.energies_and_temp(atoms) #print(abs(ekin_pre-ekin_post) / math.sqrt(N)) #print(counter) if (abs(ekin_pre - ekin_post) / math.sqrt(N)) < settings['tolerance']: counter += 1 else: counter = 0 if counter > settings['threshold']: # hyperparameter print("reached equilibrium") equilibrium = True break if equilibrium: dyn.run(settings['max_steps']) properties.finalize_properties_file(atoms, id, decimals, monoatomic) else: properties.delete_properties_file(id) raise RuntimeError("MD did not find equilibrium") return atoms