def __init__(self, atoms=None, gen='poscar.gen', ffield='ffield.json', index=-1, totstep=100, vdwnn=False, nn=True, initT=300, Tmax=25000, time_step=0.1, ro=None, rtole=0.6, Iter=0, bondTole=1.3, CheckDE=False, dEstop=0.5): self.Epot = [] self.epot = 0.0 self.ekin = 0.0 self.T = 0.0 self.initT = initT self.Tmax = Tmax self.totstep = totstep self.ro = ro self.rtole = rtole self.Iter = Iter self.atoms = atoms self.time_step = time_step self.step = 0 self.bondTole = bondTole self.CheckDE = CheckDE self.dEstop = dEstop if self.atoms is None: self.atoms = read(gen, index=index) self.atoms.calc = IRFF(atoms=self.atoms, libfile=ffield, rcut=None, nn=nn, vdwnn=vdwnn) self.natom = len(self.atoms) self.re = self.atoms.calc.re self.dyn = None self.atoms.calc.calculate(atoms=self.atoms) self.InitBonds = getBonds(self.natom, self.atoms.calc.r, self.bondTole * self.re) if (self.atoms is None) and gen.endswith('.gen'): MaxwellBoltzmannDistribution(self.atoms, self.initT * units.kB) else: temp = self.atoms.get_temperature() if temp > 0.0000001: scale = np.sqrt(self.initT / temp) p = self.atoms.get_momenta() p = scale * p self.atoms.set_momenta(p) else: MaxwellBoltzmannDistribution(self.atoms, self.initT * units.kB)
def test_fixrotation_asap(asap3): rng = np.random.RandomState(123) with seterr(all='raise'): atoms = bulk('Au', cubic=True).repeat((3, 3, 10)) atoms.pbc = False atoms.center(vacuum=5.0 + np.max(atoms.cell) / 2) print(atoms) atoms.calc = asap3.EMT() MaxwellBoltzmannDistribution(atoms, temperature_K=300, force_temp=True, rng=rng) Stationary(atoms) check_inertia(atoms) md = Langevin( atoms, timestep=20 * fs, temperature_K=300, friction=1e-3, logfile='-', loginterval=500, rng=rng) fx = FixRotation(atoms) md.attach(fx) md.run(steps=1000) check_inertia(atoms)
def run_md(fdata, atoms): from ase import units from ase.md.velocitydistribution import MaxwellBoltzmannDistribution from ase.md import VelocityVerlet fdata = fdata[:-7] traj = ase.io.Trajectory(fdata + ".traj", 'w') calc = Amp.load("amp.amp") atoms.set_calculator(calc) atoms.get_potential_energy() MaxwellBoltzmannDistribution(atoms, 100. * units.kB) #Boltzmann constant eV/K traj.write(atoms) dyn = VelocityVerlet(atoms, dt=1. * units.fs) for step in range(200): pot = atoms.get_potential_energy() # kin = atoms.get_kinetic_energy() with open(fdata + '.txt', 'a') as f: f.write("{}: Total Energy={}, POT={}, KIN={}\n".format( step, pot + kin, pot, kin)) dyn.run(5) ase.io.write(fdata + '.xyz', ase.io.read(fdata + '.traj'), append=True) traj.write(atoms)
def test_potentiostat(testdir): '''This is very realistic and stringent test of the potentiostatic accuracy with 32 atoms at ~235 meV/atom above the ground state.''' name = 'test_potentiostat' seed = 19460926 atoms = Al_block() E0 = atoms.get_potential_energy() atoms.rattle(stdev=0.18, seed=seed) initial_energy = atoms.get_potential_energy() rng = np.random.RandomState(seed) MaxwellBoltzmannDistribution(atoms, temperature_K=300, rng=rng) dyn = ContourExploration( atoms, **bulk_Al_settings, energy_target=initial_energy, rng=rng, trajectory=name + '.traj', logfile=name + '.log', ) print("Energy Above Ground State: {: .4f} eV/atom".format( (initial_energy - E0) / len(atoms))) for i in range(5): dyn.run(5) energy_error = (atoms.get_potential_energy() - initial_energy) / len(atoms) print('Potentiostat Error {: .4f} eV/atom'.format(energy_error)) assert 0 == pytest.approx(energy_error, abs=0.01)
def run(self): MaxwellBoltzmannDistribution(self.atoms, self.intT * units.kB) self.dyn = VelocityVerlet(self.atoms, self.time_step * units.fs, trajectory='md.traj') def printenergy(a=self.atoms): epot_ = a.get_potential_energy() r = a.calc.r.numpy() i_ = np.where(np.logical_and(r < self.rtole * self.ro, r > 0.0001)) n = len(i_[0]) self.Epot.append(epot_) self.epot = epot_ / self.natom self.ekin = a.get_kinetic_energy() / self.natom self.T = self.ekin / (1.5 * units.kB) self.step = self.dyn.nsteps print('Step %d Epot = %.3feV Ekin = %.3feV (T=%3.0fK) ' 'Etot = %.3feV' % (self.step, self.epot, self.ekin, self.T, self.epot + self.ekin)) try: assert n == 0 and self.T < self.Tmax, 'Atoms too closed!' except: for _ in i_: print('atoms pair', _) print('Atoms too closed or temperature too high, stop at %d.' % self.step) self.dyn.max_steps = self.dyn.nsteps - 1 # traj = Trajectory('md.traj', 'w', self.atoms) self.dyn.attach(printenergy, interval=1) # self.dyn.attach(traj.write,interval=1) self.dyn.run(self.totstep)
def __init__( self, atomsbatch, mdparam=DEFAULTNVEPARAMS, ): # initialize the atoms batch system self.atomsbatch = atomsbatch self.mdparam = mdparam # todo: structure optimization before starting # intialize system momentum MaxwellBoltzmannDistribution(self.atomsbatch, self.mdparam['T_init'] * units.kB) # set thermostats integrator = self.mdparam['thermostat'] self.integrator = integrator(self.atomsbatch, **self.mdparam['thermostat_params']) # attach trajectory dump self.traj = Trajectory(self.mdparam['traj_filename'], 'w', self.atomsbatch) self.integrator.attach(self.traj.write, interval=mdparam['save_frequency']) # attach log file self.integrator.attach(NeuralMDLogger(self.integrator, self.atomsbatch, self.mdparam['thermo_filename'], mode='a'), interval=mdparam['save_frequency'])
def run_md(atoms): from ase import units from ase.md.velocitydistribution import MaxwellBoltzmannDistribution from ase.md import VelocityVerlet traj = ase.io.Trajectory("traj.traj", 'w') calc = Amp.load("amp.amp") atoms.set_calculator(calc) atoms.get_potential_energy() MaxwellBoltzmannDistribution(atoms, 10. * units.kB) traj.write(atoms) dyn = VelocityVerlet(atoms, dt=1. * units.fs) f = open("md.ene", "w") f.write("{:^5s}{:^10s}{:^10s}{:^10s}\n".format("time", "Etot", "Epot", "Ekin")) for step in range(100): pot = atoms.get_potential_energy() # kin = atoms.get_kinetic_energy() tot = pot + kin f.write("{:5d}{:10.5f}{:10.5f}{:10.5f}\n".format(step, tot, pot, kin)) print("{}: Total Energy={}, POT={}, KIN={}".format( step, tot, pot, kin)) dyn.run(10) traj.write(atoms) f.close()
def amp_md(atoms, nstep, dt): from ase import units from ase.md.velocitydistribution import MaxwellBoltzmannDistribution from ase.md import VelocityVerlet traj = ase.io.Trajectory("traj.traj", 'w') try: calc = Amp.load("amp.amp") except FileNotFoundError: try: calc = Amp.load("amp-untrained-parameters.amp") except FileNotFoundError: print("Error: amp-pes.amp file does not exist, input amp-pot file by -p") sys.exit(1) atoms.set_calculator(calc) atoms.get_potential_energy() MaxwellBoltzmannDistribution(atoms, 300 * units.kB) traj.write(atoms) dyn = VelocityVerlet(atoms, dt=dt * units.fs) f = open("md.ene", "w") f.write("{:^5s} {:^10s} {:^10s} {:^10s}\n".format("time","Etot","Epot","Ekin")) for step in range(nstep): pot = atoms.get_potential_energy() # kin = atoms.get_kinetic_energy() tot = pot + kin f.write("{:5d}{:10.5f}{:10.5f}{:10.5f}\n".format(step, tot, pot, kin)) print("{}: Total Energy={}, POT={}, KIN={}".format(step, tot, pot, kin)) dyn.run(2) traj.write(atoms) # write kinetic energy, but pot is not seen in ase f.close()
def TestEnergyConservation(): print "Running TestEnergyConservation..." calc = Morse(elements, epsilon, alpha, rmin) atoms = SimpleCubic('Ar', size=(10, 10, 10), latticeconstant=5.0) n = 0 while n < 100: i = np.random.randint(len(atoms) - 1) if atoms[i].number != atomic_numbers['Ru']: atoms[i].number = atomic_numbers['Ru'] n += 1 atoms.set_calculator(calc) # Set initial momentum MaxwellBoltzmannDistribution(atoms, 300 * units.kB) # Run dynamics dyn = VelocityVerlet(atoms, 1.0 * units.fs, logfile='test-energy.dat', loginterval=10) dyn.run(10) etot = (atoms.get_potential_energy() + atoms.get_kinetic_energy()) / len(atoms) print "%-9s %-9s %-9s" % ("Epot", "Ekin", "Sum") for i in range(25): if i: dyn.run(100) epot = atoms.get_potential_energy() / len(atoms) ekin = atoms.get_kinetic_energy() / len(atoms) print "%9.5f %9.5f %9.5f" % (epot, ekin, epot + ekin) ReportTest("Step %i." % (i, ), epot + ekin, etot, 1e-3, silent=True)
def test_idealgas(): from ase.md import VelocityVerlet from ase.build import bulk from ase.units import kB from ase.md.velocitydistribution import MaxwellBoltzmannDistribution from ase.calculators.idealgas import IdealGas import numpy as np atoms = bulk('Kr').repeat((10, 10, 10)) assert len(atoms) == 1000 atoms.center(vacuum=100) atoms.set_calculator(IdealGas()) T = 1000 MaxwellBoltzmannDistribution(atoms, T * kB) print("Temperature: {} K".format(atoms.get_temperature())) md = VelocityVerlet(atoms, timestep=0.1) for i in range(5): md.run(5) s = atoms.get_stress(include_ideal_gas=True) p = -s[:3].sum() / 3 v = atoms.get_volume() N = len(atoms) T = atoms.get_temperature() print("pV = {} NkT = {}".format(p * v, N * kB * T)) assert np.fabs(p * v - N * kB * T) < 1e-6
def test_idealgas(): rng = np.random.RandomState(17) atoms = bulk('Kr').repeat((10, 10, 10)) assert len(atoms) == 1000 atoms.center(vacuum=100) atoms.calc = IdealGas() natoms = len(atoms) md_temp = 1000 MaxwellBoltzmannDistribution(atoms, temperature_K=md_temp, rng=rng) print("Temperature: {} K".format(atoms.get_temperature())) with VelocityVerlet(atoms, timestep=0.1) as md: for i in range(5): md.run(5) stress = atoms.get_stress(include_ideal_gas=True) stresses = atoms.get_stresses(include_ideal_gas=True) assert stresses.mean(0) == pytest.approx(stress) pressure = -stress[:3].sum() / 3 pV = pressure * atoms.cell.volume NkT = natoms * kB * atoms.get_temperature() print(f"pV = {pV} NkT = {NkT}") assert pV == pytest.approx(NkT, abs=1e-6)
def run(self, calc, filename): slab = self.starting_geometry.copy() slab.set_calculator(calc) np.random.seed(1) MaxwellBoltzmannDistribution(slab, self.temp * units.kB) if self.ensemble == "NVE": dyn = VelocityVerlet(slab, self.dt * units.fs) elif self.ensemble == "nvtberendsen": dyn = nvtberendsen.NVTBerendsen(slab, self.dt * units.fs, self.temp, taut=300 * units.fs) elif self.ensemble == "langevin": dyn = Langevin(slab, self.dt * units.fs, self.temp * units.kB, 0.002) traj = ase.io.Trajectory(filename + ".traj", "w", slab) dyn.attach(traj.write, interval=1) try: fixed_atoms = len(slab.constraints[0].get_indices()) except: fixed_atoms = 0 pass def printenergy(a=slab): """Function to print( the potential, kinetic, and total energy)""" epot = a.get_potential_energy() / len(a) ekin = a.get_kinetic_energy() / (len(a) - fixed_atoms) print("Energy per atom: Epot = %.3feV Ekin = %.3feV (T=%3.0fK) " "Etot = %.3feV" % (epot, ekin, ekin / (1.5 * units.kB), epot + ekin)) if printenergy: dyn.attach(printenergy, interval=10) dyn.run(self.count)
def apply_thermostat(self): alpha = self.alpha # collision strength dt = self.dt atoms = self.atoms kT = self.temperature Tcol = self.tcol # avg time between collisions Pcol = 1.0 - np.exp(-dt / Tcol) # Probability of collisions n = 0 # temp vector to reset velocity masses = self.atoms.get_masses() if not self.atoms.has('momenta'): from ase.md.velocitydistribution import MaxwellBoltzmannDistribution MaxwellBoltzmannDistribution(self.atoms, self.temperature) tmpv = atoms.get_velocities() for j in tmpv: if (np.random.random_sample() < Pcol): # check for collision new_v = np.sqrt(kT / masses[n]) * self.vrand( j) # call tsse.util for Gaussian rand vector tmpv[n] = np.sqrt( 1 - alpha**2 ) * j + alpha * new_v # mix old and rand velocities n += 1 if self.hyperplane == True: tmpv -= np.vdot(tmpv, self.eig) * self.eig self.atoms.set_velocities(tmpv) return
def init_vel(cml): ''' ''' arg = parse_cml_args(cml) # read in the initial structure init_pos = read(arg.poscar) # set the momenta corresponding to T MaxwellBoltzmannDistribution(init_pos, arg.temperature * ase.units.kB) Stationary(init_pos) ZeroRotation(init_pos) # scale the temperature to T vel = init_pos.get_velocities() Tn = init_pos.get_temperature() vel *= np.sqrt(arg.temperature / Tn) init_pos.set_velocities(vel) # write the structure write(arg.out, init_pos, vasp5=True, direct=True) # units in VASP and ASE are different vel = init_pos.get_velocities() * ase.units.fs # np.savetxt('init_vel.dat', vel, fmt='%20.16f') # append the velocities to the POSCAR with open(arg.out, 'a+') as pos: pos.write('\n') pos.write( '\n'.join([ ''.join(["%20.16f" % x for x in row]) for row in vel ]) )
def init_dynamics(self, Nm, Nembed, V, L, dt, T): self.L = L # Generate the box of junk self.__generategarbagebox__(Nm, Nembed, L, T) # Make mol self.mol = Atoms(symbols=self.S, positions=self.X) # Set box and PBC self.mol.set_cell(([[L, 0, 0], [0, L, 0], [0, 0, L]])) self.mol.set_pbc((True, True, True)) # Set ANI calculator self.mol.set_calculator(ANIENS(self.aens)) # Open MD output #self.mdcrd = open(xyzfile, 'w') # Open MD output #self.traj = open(trjfile, 'w') # Set the velocities corresponding to a boltzmann dist @ T/4.0 MaxwellBoltzmannDistribution(self.mol, 300.0 * units.kB) # Declare Dyn self.dyn = Langevin(self.mol, dt * units.fs, T * units.kB, 0.1)
def equilibrated(asap3, berendsenparams): """Make an atomic system with equilibrated temperature and pressure.""" rng = np.random.RandomState(42) with seterr(all='raise'): print() # Must be big enough to avoid ridiculous fluctuations atoms = bulk('Au', cubic=True).repeat((3, 3, 3)) #a[5].symbol = 'Ag' print(atoms) atoms.calc = asap3.EMT() MaxwellBoltzmannDistribution(atoms, temperature_K=100, force_temp=True, rng=rng) Stationary(atoms) assert abs(atoms.get_temperature() - 100) < 0.0001 md = NPTBerendsen(atoms, timestep=20 * fs, logfile='-', loginterval=200, **berendsenparams['npt']) # Equilibrate for 20 ps md.run(steps=1000) T = atoms.get_temperature() pres = -atoms.get_stress( include_ideal_gas=True)[:3].sum() / 3 / GPa * 10000 print("Temperature: {:.2f} K Pressure: {:.2f} bar".format(T, pres)) return atoms
def test_langevin_switching(): # params size = 6 T = 300 n_steps = 500 k1 = 2.0 k2 = 4.0 dt = 10 # for reproducibility np.random.seed(42) # setup atoms and calculators atoms = bulk('Al').repeat(size) calc1 = SpringCalculator(atoms.positions, k1) calc2 = SpringCalculator(atoms.positions, k2) # theoretical diff n_atoms = len(atoms) calc1.atoms = atoms calc2.atoms = atoms F1 = calc1.get_free_energy(T) / n_atoms F2 = calc2.get_free_energy(T) / n_atoms dF_theory = F2 - F1 # switch_forward dyn_forward = SwitchLangevin(atoms, calc1, calc2, dt * units.fs, T * units.kB, 0.01, n_steps, n_steps) MaxwellBoltzmannDistribution(atoms, 2 * T * units.kB) dyn_forward.run() dF_forward = dyn_forward.get_free_energy_difference() / len(atoms) # switch_backwards dyn_backward = SwitchLangevin(atoms, calc2, calc1, dt * units.fs, T * units.kB, 0.01, n_steps, n_steps) MaxwellBoltzmannDistribution(atoms, 2 * T * units.kB) dyn_backward.run() dF_backward = -dyn_backward.get_free_energy_difference() / len(atoms) # summary dF_switch = (dF_forward + dF_backward) / 2.0 error = dF_switch - dF_theory # print('delta_F analytical: {:12.6f} eV/atom'.format(dF_theory)) # print('delta_F forward: {:12.6f} eV/atom'.format(dF_forward)) # print('delta_F backward: {:12.6f} eV/atom'.format(dF_backward)) # print('delta_F average: {:12.6f} eV/atom'.format(dF_switch)) # print('delta_F error: {:12.6f} eV/atom'.format(error)) assert abs(error) < 1e-3
def _molecular_dynamics(self, resume=None): """Performs a molecular dynamics simulation, until mdmin is exceeded. If resuming, the file number (md%05i) is expected.""" self._log('msg', 'Molecular dynamics: md%05i' % self._counter) mincount = 0 energies, oldpositions = [], [] thermalized = False if resume: self._log('msg', 'Resuming MD from md%05i.traj' % resume) if os.path.getsize('md%05i.traj' % resume) == 0: self._log( 'msg', 'md%05i.traj is empty. Resuming from ' 'qn%05i.traj.' % (resume, resume - 1)) atoms = io.read('qn%05i.traj' % (resume - 1), index=-1) else: images = io.Trajectory('md%05i.traj' % resume, 'r') for atoms in images: energies.append(atoms.get_potential_energy()) oldpositions.append(atoms.positions.copy()) passedmin = self._passedminimum(energies) if passedmin: mincount += 1 self._atoms.set_momenta(atoms.get_momenta()) thermalized = True self._atoms.positions = atoms.get_positions() self._log('msg', 'Starting MD with %i existing energies.' % len(energies)) if not thermalized: MaxwellBoltzmannDistribution(self._atoms, temp=self._temperature * units.kB, force_temp=True) traj = io.Trajectory('md%05i.traj' % self._counter, 'a', self._atoms) self._constrain() dyn = NPT(self._atoms, timestep=self._timestep * units.fs, temperature=self._temperature * units.kB, externalstress=self._externalstress, ttime=self._ttime * units.fs, pfactor=self._pfactor * units.fs**2) # dyn = NPTber(self._atoms, timestep=self._timestep * units.fs, temperature=self._temperature, fixcm=True, pressure=self._pressure, taut=self._taut * units.fs, taup=self._taup * units.fs, compressibility=self._compressibility) log = MDLogger(dyn, self._atoms, 'md%05i.log' % self._counter, header=True, stress=False, peratom=False) dyn.attach(log, interval=1) dyn.attach(traj, interval=1) while mincount < self._mdmin: # self._constrain() dyn.run(1) # del self._atoms.constraints energies.append(self._atoms.get_potential_energy()) passedmin = self._passedminimum(energies) if passedmin: mincount += 1 oldpositions.append(self._atoms.positions.copy()) # Reset atoms to minimum point. self._atoms.positions = oldpositions[passedmin[0]]
def __init__( self, atomsbatch, final_aggr, init_aggr, mdparam=DEFAULTNVEPARAMS, ): ''' from nff.io import NeuralFF modelparams = dict() modelparams['n_atom_basis'] = 128 modelparams['n_filters'] = 128 modelparams['n_gaussians'] = 32 modelparams['n_convolutions'] = 3 modelparams['n_convolutions'] = 3 modelparams['cutoff'] = 3 thermo_int = GraphConvIntegration(modelparams) calc = NeuralFF(model=thermo_int, device=1) final_aggr = torch.Tensor([1.] * 127 + [0.]) init_aggr = torch.Tensor([1.] * 128) bulk.set_calculator(calc) nve = TI(bulk, final_aggr, init_aggr, DEFAULTNVEPARAMS) ''' # initialize the atoms batch system self.atomsbatch = atomsbatch self.mdparam = mdparam self.init_aggr = init_aggr self.final_aggr = final_aggr # todo: structure optimization before starting # intialize system momentum MaxwellBoltzmannDistribution(self.atomsbatch, self.mdparam['T_init'] * units.kB) # set thermostats integrator = self.mdparam['thermostat'] self.integrator = integrator(self.atomsbatch, **self.mdparam['thermostat_params']) # attach trajectory dump self.traj = Trajectory(self.mdparam['traj_filename'], 'w', self.atomsbatch) self.integrator.attach(self.traj.write, interval=mdparam['save_frequency']) # attach log file self.integrator.attach(NeuralMDLogger(self.integrator, self.atomsbatch, self.mdparam['thermo_filename'], mode='a'), interval=mdparam['save_frequency'])
def test_otf_md(md_engine, md_params, super_cell, flare_calc, qe_calc): np.random.seed(12345) flare_calculator = flare_calc[md_engine] # set up OTF MD engine otf_params = { 'init_atoms': [0, 1, 2, 3], 'output_name': md_engine, 'std_tolerance_factor': 2, 'max_atoms_added': len(super_cell.positions), 'freeze_hyps': 10 } # 'use_mapping': flare_calculator.use_mapping} md_kwargs = md_params[md_engine] # intialize velocity temperature = md_params['temperature'] MaxwellBoltzmannDistribution(super_cell, temperature * units.kB) Stationary(super_cell) # zero linear momentum ZeroRotation(super_cell) # zero angular momentum super_cell.set_calculator(flare_calculator) test_otf = ASE_OTF(super_cell, timestep=1 * units.fs, number_of_steps=3, dft_calc=qe_calc, md_engine=md_engine, md_kwargs=md_kwargs, **otf_params) # TODO: test if mgp matches gp # TODO: see if there's difference between MD timestep & OTF timestep # set up logger # otf_logger = OTFLogger(test_otf, super_cell, # logfile=md_engine+'.log', mode="w", data_in_logfile=True) # test_otf.attach(otf_logger, interval=1) test_otf.run() for f in glob.glob("scf*.pw*"): os.remove(f) for f in glob.glob("*.npy"): os.remove(f) for f in glob.glob("kv3*"): shutil.rmtree(f) for f in glob.glob("otf_data"): shutil.rmtree(f, ignore_errors=True) for f in glob.glob("out"): shutil.rmtree(f, ignore_errors=True) for f in os.listdir("./"): if md_engine in f or 'lmp.mgp' in f: os.remove(f) if 'slurm' in f: os.remove(f)
def run_md(self, f, Tmax, steps, n_steps, nmfile=None, displacement=0, min_steps=0, sig=0.34, t=0.1, nm=0, record=False): X, S, Na, cm = hdt.readxyz2(f) if nmfile != None: mode=self.get_mode(nmfile, Na, mn=nm) X=X+mode*np.random.uniform(-displacement,displacement) X=X[0] mol=Atoms(symbols=S, positions=X) mol.set_calculator(ANIENS(self.net,sdmx=20000000.0)) f=os.path.basename(f) T_eff = float(random.randrange(5, Tmax, 1)) # random T (random velocities) from 0K to TK minstep_eff = float(random.randrange(1, min_steps, 1)) # random T (random velocities) from 0K to TK dyn = Langevin(mol, t * units.fs, T_eff * units.kB, 0.01) MaxwellBoltzmannDistribution(mol, T_eff * units.kB) # steps=10000 #10000=1picosecond #Max number of steps to run # n_steps = 1 #Number of steps to run for before checking the standard deviation hsdt_Na=[] evkcal=hdt.evtokcal if record==True: #Records the coordinates at every step of the dynamics fname = f + '_record_' + str(T_eff) + 'K' + '.xyz' #name of file to store coodinated in def printenergy(name=fname, a=mol): """Function to print the potential, kinetic and total energy.""" fil= open(name,'a') Na=a.get_number_of_atoms() c = a.get_positions(wrap=True) fil.write('%s \n comment \n' %Na) for j, i in zip(a, c): fil.write(str(j.symbol) + ' ' + str(i[0]) + ' ' + str(i[1]) + ' ' + str(i[2]) + '\n') fil.close() dyn.attach(printenergy, interval=1) e=mol.get_potential_energy() #Calculate the energy of the molecule. Must be done to get the standard deviation s=mol.calc.stddev stddev = 0 tot_steps = 0 failed = False while (tot_steps <= steps): if stddev > sig and tot_steps > minstep_eff: #Check the standard deviation self.hstd.append(stddev) c = mol.get_positions() s = mol.get_chemical_symbols() Na=mol.get_number_of_atoms() self.Na_train.append(Na) self.coor_train.append(c) self.S_train.append(s) failed=True break else: #if the standard deviation is low, run dynamics, then check it again tot_steps = tot_steps + n_steps dyn.run(n_steps) stddev = evkcal*mol.calc.stddev c = mol.get_positions() s = mol.get_chemical_symbols() e=mol.get_potential_energy() #print("{0:.2f}".format(tot_steps*t),':',"{0:.2f}".format(stddev),':',"{0:.2f}".format(evkcal*e)) return c, s, tot_steps*t, stddev, failed, T_eff
def test_otf_md(md_engine, md_params, super_cell, flare_calc, qe_calc): np.random.seed(12345) flare_calculator = flare_calc[md_engine] # set up OTF MD engine otf_params = { "init_atoms": [0, 1, 2, 3], "output_name": md_engine, "std_tolerance_factor": 2, "max_atoms_added": len(super_cell.positions), "freeze_hyps": 10, "write_model": 1, } # 'use_mapping': flare_calculator.use_mapping} md_kwargs = md_params[md_engine] # intialize velocity temperature = md_params["temperature"] MaxwellBoltzmannDistribution(super_cell, temperature * units.kB) Stationary(super_cell) # zero linear momentum ZeroRotation(super_cell) # zero angular momentum super_cell.set_calculator(flare_calculator) test_otf = ASE_OTF( super_cell, timestep=1 * units.fs, number_of_steps=number_of_steps, dft_calc=qe_calc, md_engine=md_engine, md_kwargs=md_kwargs, trajectory=md_engine + "_otf.traj", **otf_params, ) # TODO: test if mgp matches gp # TODO: see if there's difference between MD timestep & OTF timestep test_otf.run() for f in glob.glob("scf*.pw*"): os.remove(f) for f in glob.glob("*.npy"): os.remove(f) for f in glob.glob("kv3*"): shutil.rmtree(f) for f in glob.glob("otf_data"): shutil.rmtree(f, ignore_errors=True) for f in glob.glob("out"): shutil.rmtree(f, ignore_errors=True) for f in os.listdir("./"): if ".mgp" in f or ".var" in f: os.remove(f) if "slurm" in f: os.remove(f)
def otf_md_test(md_engine): import atom_setup, flare_setup, qe_setup np.random.seed(12345) print(md_engine) # ----------- set up atoms ----------------- super_cell = atom_setup.super_cell # ----------- setup flare calculator --------------- flare_calc = deepcopy(flare_setup.flare_calc) super_cell.set_calculator(flare_calc) # ----------- setup qe calculator -------------- dft_calc = qe_setup.dft_calc # ----------- create otf object ----------- # set up OTF MD engine md_params = {'timestep': 1 * units.fs, 'trajectory': None, 'dt': None, 'externalstress': 0, 'ttime': 25, 'pfactor': 3375, 'mask': None, 'temperature': 500, 'taut': 1, 'taup': 1, 'pressure': 0, 'compressibility': 0, 'fixcm': 1, 'friction': 0.02} otf_params = {'dft_calc': dft_calc, 'init_atoms': [0, 1, 2, 3], 'std_tolerance_factor': 2, 'max_atoms_added' : len(super_cell.positions), 'freeze_hyps': 10, 'use_mapping': super_cell.calc.use_mapping} # intialize velocity temperature = md_params['temperature'] MaxwellBoltzmannDistribution(super_cell, temperature * units.kB) Stationary(super_cell) # zero linear momentum ZeroRotation(super_cell) # zero angular momentum test_otf = otf_md(md_engine, super_cell, md_params, otf_params) # set up logger test_otf.attach(OTFLogger(test_otf, super_cell, logfile=md_engine+'.log', mode="w", data_in_logfile=True), interval=1) # run otf number_of_steps = 3 test_otf.otf_run(number_of_steps) os.system('rm {}.log'.format(md_engine)) os.system('rm AgI.pw*') os.system('rm -r out') os.system('rm -r __pycache__') os.system('rm -r kv3') os.system('rm lmp.mgp') os.system('rm -r otf_data') os.system('rm *.npy')
def test_maxwellboltzmann(): from ase.md.velocitydistribution import MaxwellBoltzmannDistribution from ase.lattice.cubic import FaceCenteredCubic atoms = FaceCenteredCubic(size=(50, 50, 50), symbol="Cu", pbc=False) print("Number of atoms:", len(atoms)) MaxwellBoltzmannDistribution(atoms, temperature_K=0.1 / kB) temp = atoms.get_kinetic_energy() / (1.5 * len(atoms)) print("Temperature", temp, " (should be 0.1)") assert abs(temp - 0.1) < 1e-3
def ase_md_playground(): geom = AnaPot.get_geom((0.52, 1.80, 0), atoms=("H", )) atoms = geom.as_ase_atoms() # ase_calc = FakeASE(geom.calculator) # from ase.optimize import BFGS # dyn = BFGS(atoms) # dyn.run(fmax=0.05) import ase from ase import units from ase.io.trajectory import Trajectory from ase.md.velocitydistribution import MaxwellBoltzmannDistribution from ase.md.verlet import VelocityVerlet MaxwellBoltzmannDistribution(atoms, 300 * units.kB) momenta = atoms.get_momenta() momenta[0, 2] = 0. # Zero 3rd dimension atoms.set_momenta(momenta) dyn = VelocityVerlet(atoms, .005 * units.fs) # 5 fs time step. def printenergy(a): """Function to print the potential, kinetic and total energy""" epot = a.get_potential_energy() / len(a) ekin = a.get_kinetic_energy() / len(a) print('Energy per atom: Epot = %.3feV Ekin = %.3feV (T=%3.0fK) ' 'Etot = %.3feV' % (epot, ekin, ekin / (1.5 * units.kB), epot + ekin)) # Now run the dynamics printenergy(atoms) traj_fn = 'asemd.traj' traj = Trajectory(traj_fn, 'w', atoms) dyn.attach(traj.write, interval=5) # dyn.attach(bumms().bimms, interval=1) dyn.run(10000) printenergy(atoms) traj.close() traj = ase.io.read(traj_fn+"@:")#, "r") pos = [a.get_positions() for a in traj] from pysisyphus.constants import BOHR2ANG pos = np.array(pos) / BOHR2ANG calc = geom.calculator calc.plot() ax = calc.ax ax.plot(*pos[:,0,:2].T) plt.show()
def build_atoms(self, system, size, temp, seed=None): assert system in self.systems.keys(), "System {} not found!".format( system) atoms = self.systems[system](size) rng = np.random if seed is not None: rng.seed(seed) MaxwellBoltzmannDistribution(atoms, temp * units.kB, rng=rng) Stationary(atoms) ZeroRotation(atoms) return atoms
def create_system(self, name, time_step=1.0, temp=300, temp_init=None, restart=False, store=1, nvt=False, friction=0.001): """ Parameters ----------- name : str Name for output files. time_step : float, optional Time step in fs for simulation. temp : float, optional Temperature in K for NVT simulation. temp_init : float, optional Optional different temperature for initialization than thermostate set at. restart : bool, optional Determines whether simulation is restarted or not, determines whether new velocities are initialized. store : int, optional Frequency at which output is written to log files. nvt : bool, optional Determines whether to run NVT simulation, default is False. friction : float, optional friction coefficient in fs^-1 for Langevin integrator """ if temp_init is None: temp_init = temp if not self.md or restart: MaxwellBoltzmannDistribution(self.mol, temp_init * units.kB) if not nvt: self.md = VelocityVerlet(self.mol, time_step * units.fs) else: self.md = Langevin(self.mol, time_step * units.fs, temp * units.kB, friction / units.fs) logfile = os.path.join(self.tmp, "{}.log".format(name)) trajfile = os.path.join(self.tmp, "{}.traj".format(name)) logger = MDLogger(self.md, self.mol, logfile, stress=False, peratom=False, header=True, mode="a") trajectory = Trajectory(trajfile, "w", self.mol) self.md.attach(logger, interval=store) self.md.attach(trajectory.write, interval=store)
def test_apply_strain(self): calc = TersoffScr(**Tersoff_PRB_39_5566_Si_C__Scr) timestep = 1.0 * units.fs atoms = ase.io.read('cryst_rot_mod.xyz') atoms.set_calculator(calc) # constraints top = atoms.positions[:, 1].max() bottom = atoms.positions[:, 1].min() fixed_mask = ((abs(atoms.positions[:, 1] - top) < 1.0) | (abs(atoms.positions[:, 1] - bottom) < 1.0)) fix_atoms = FixAtoms(mask=fixed_mask) # strain orig_height = (atoms.positions[:, 1].max() - atoms.positions[:, 1].min()) delta_strain = timestep * 1e-5 * (1 / units.fs) rigid_constraints = False strain_atoms = ConstantStrainRate(orig_height, delta_strain) atoms.set_constraint(fix_atoms) # dynamics np.random.seed(0) simulation_temperature = 300 * units.kB MaxwellBoltzmannDistribution(atoms, 2.0 * simulation_temperature) dynamics = VelocityVerlet(atoms, timestep) def apply_strain(atoms, ConstantStrainRate, rigid_constraints): ConstantStrainRate.apply_strain(atoms, rigid_constraints) dynamics.attach(apply_strain, 1, atoms, strain_atoms, rigid_constraints) dynamics.run(100) # tests if rigid_constraints == True: answer = 0 temp_answer = 238.2066417638124 else: answer = 0.013228150080099255 temp_answer = 236.76904696481486 newpos = atoms.get_positions() current_height = newpos[:, 1].max() - newpos[:, 1].min() diff_height = (current_height - orig_height) self.assertAlmostEqual(diff_height, answer) temperature = (atoms.get_kinetic_energy() / (1.5 * units.kB * len(atoms))) self.assertAlmostEqual(temperature, temp_answer)
def _init_velocities(self, temp_init=300, remove_translation=True, remove_rotation=True): """ Initialize velocities for molecular dynamics Args: temp_init (float): Initial temperature in Kelvin (default 300) remove_translation (bool): Remove translation components of velocity (default True) remove_rotation (bool): Remove rotation components of velocity (default True) """ MaxwellBoltzmannDistribution(self.molecule, temp_init * units.kB) if remove_translation: Stationary(self.molecule) if remove_rotation: ZeroRotation(self.molecule)
def test_md(cp2k_factory): calc = cp2k_factory.calc(label='test_H2_MD') positions = [(0, 0, 0), (0, 0, 0.7245595)] atoms = Atoms('HH', positions=positions, calculator=calc) atoms.center(vacuum=2.0) MaxwellBoltzmannDistribution(atoms, temperature_K=0.5 * 300, force_temp=True) energy_start = atoms.get_potential_energy() + atoms.get_kinetic_energy() with VelocityVerlet(atoms, 0.5 * units.fs) as dyn: dyn.run(20) energy_end = atoms.get_potential_energy() + atoms.get_kinetic_energy() assert abs(energy_start - energy_end) < 1e-4