def __init__(self, atoms, name, potential, calc_energy=True): """ Initialise the writer with the templating atoms and potential. """ self.atoms = atoms self.name = name self.potential = potential self.calc_energy = calc_energy self.counter = 0 # TODO: check naming self.base_dir = os.getcwd() run_path = '{0}'.format(atoms.info['name']) info("Putting files in {0}.".format(run_path)) os.mkdir(run_path) os.chdir(run_path) trajectory = 'traj_{0}.xyz'.format(atoms.info['name']) self.out = AtomsWriter(trajectory)
def relax_structure(atoms, relax_fmax=0.05, traj_interval=None): """ Relax atoms object. If it contains a 'fixed_mask' array, then run constrained relaxation """ arel = atoms.copy() try: fix_mask = atoms.get_array("fixed_mask") print("Running relaxation with %d constrained atoms" % fix_mask.sum()) const = FixAtoms(mask=fix_mask) arel.set_constraint(const) except: print("No constraints specified, running relaxation") arel.set_calculator(calc) opt = FIRE(arel) # LBFGS(arel) # if traj_interval is not None: from quippy.io import AtomsWriter out = AtomsWriter("traj-relax_structure.xyz") trajectory_write = lambda: out.write(QAtoms(arel, charge=None)) opt.attach(trajectory_write, interval=traj_interval) opt.run(fmax=relax_fmax) return arel
def run(opts, args, verbosity): args = args[:] con = connect(args.pop(0)) if args: if len(args) == 1 and args[0].isdigit(): expressions = int(args[0]) else: expressions = ','.join(args) else: expressions = [] if opts.count or opts.uniq: opts.limit = 0 rows = con.select(expressions, verbosity=verbosity, limit=opts.limit) if opts.count: n = 0 for row in rows: n += 1 print('%s' % plural(n, 'row')) return dcts = list(rows) if len(dcts) > 0: if opts.include_all or opts.list_columns: keys = [] for dct in dcts: if hasattr(dct, 'key_value_pairs'): for key in dct.key_value_pairs.keys(): if key not in keys: keys.append(key) opts.columns = ','.join(['+'+key for key in keys]) f = Formatter(opts.columns, opts.sort) if verbosity >= 1: ids, columns = f.format(dcts, opts) if verbosity > 1 or opts.list_columns: for col in columns: if not opts.list_columns: print 'COLUMN', print col if opts.list_columns: return if opts.extract is not None: if '%' not in opts.extract: writer = AtomsWriter(opts.extract) for i, dct in enumerate(dcts): if '%' in opts.extract: filename = opts.extract % i writer = AtomsWriter(filename) at = dict2atoms(dct) if verbosity > 1: print 'Writing config %d %r to %r' % (i, at, writer) writer.write(at)
def relax_gb(gb_file='file_name', traj_steps=120, total_steps=1200, force_tol=0.05): """Method to relax a grain_boundary bicrystal structure. Requires a .json file with at a minimum the 'param_file' variable specified. Args: gb_file(str): gbid. traj_steps(int): number of steps between print trajectories. total_steps(int): total number of force relaxation steps. force_tol(float): Force relaxation criterion in ev/A. Returns: :class:`ase.Atoms` Object """ def converged(grain, smax, fmax): maxstress = max(grain.get_stress().ravel()) rmsforces = np.sum(grain.get_forces()**2, axis=1)**0.5 maxforce = max(rmsforces) if maxforce < fmax and maxstress < smax: return True return False with open('subgb.json', 'r') as outfile: j_dict = json.load(outfile) try: POT_DIR = os.path.join(app.root_path, 'potentials') except KeyError: sys.exit( "Please set POTDIR in os environment. `export POTDIR='path/to/potfiles/`" ) try: param_file = j_dict['param_file'] if param_file == 'iron_mish.xml': eam_pot = os.path.join(POT_DIR, 'iron_mish.xml') r_scale = 1.0129007626 elif param_file == 'Fe_Mendelev.xml': eam_pot = os.path.join(POT_DIR, 'Fe_Mendelev.xml') r_scale = 1.00894848312 elif param_file == 'PotBH.xml': eam_pot = os.path.join(POT_DIR, 'PotBH.xml') r_scale = 1.00894848312 elif param_file == 'Fe_Ackland.xml': eam_pot = os.path.join(POT_DIR, 'Fe_Ackland.xml') r_scale = 1.00894185389 elif param_file == 'Fe_Dudarev.xml': eam_pot = os.path.join(POT_DIR, 'Fe_Dudarev.xml') r_scale = 1.01279093417 elif param_file == 'gp33b.xml': eam_pot = os.path.join(POT_DIR, 'gp33b.xml') sparse_file = 'gp33b.xml.sparseX.GAP_2016_10_3_60_19_29_10_8911' eam_pot_sparse = os.path.join(POT_DIR, sparse_file) shutil.copy(eam_pot, './') shutil.copy(eam_pot_sparse, './') else: print 'No paramfile found!' sys.exit() except KeyError: print 'No EAM potential file with that name. Relax failed.' sys.exit() print 'Using: ', eam_pot pot_file = eam_pot.split('/')[-1] print '{0}.xyz'.format(gb_file) print os.getcwd() grain = io.read('{0}.xyz'.format(gb_file), index='-1') if param_file != 'gp33b.xml': pot = Potential( 'IP EAM_ErcolAd do_rescale_r=T r_scale={0}'.format(r_scale), param_filename=eam_pot) else: pot = Potential('IP GAP', param_filename=eam_pot) grain.set_calculator(pot) grain.info['adsorbate_info'] = None E_gb_init = grain.get_potential_energy() traj_file = gb_file if 'traj' in traj_file: out = AtomsWriter('{0}'.format('{0}.xyz'.format(traj_file))) else: out = AtomsWriter('{0}'.format('{0}_traj.xyz'.format(traj_file))) strain_mask = [0, 0, 1, 0, 0, 0] ucf = UnitCellFilter(grain, strain_mask) opt = FIRE(ucf) cell = grain.get_cell() A = cell[0][0] * cell[1][1] H = cell[2][2] #Calculation dumps total energyenergy and grainboundary area data to json file. with open('subgb.json', 'r') as f: gb_dict = json.load(f) #Write an initial dict so we know if the system has been initialized but the calculation is not finished. with open('subgb.json', 'w') as outfile: for key, value in gb_dict.items(): j_dict[key] = value json.dump(j_dict, outfile, indent=2) CONVERGED = False FORCE_TOL = force_tol #default to 5 if traj_steps = 120, otherwise increases num_iters = int(float(total_steps) / float(traj_steps)) logging.debug('num_iters: {}'.format(num_iters)) for i in range(num_iters): opt.run(fmax=FORCE_TOL, steps=traj_steps) out.write(grain) force_array = grain.get_forces() max_force_II = max([max(f) for f in force_array]) max_forces = [ np.sqrt(fx**2 + fy**2 + fz**2) for fx, fy, fz in zip( grain.properties['force'][0], grain.properties['force'][1], grain.properties['force'][2]) ] if max(max_forces) <= FORCE_TOL: CONVERGED = True break out.close() gb_dict['converged'] = CONVERGED E_gb = grain.get_potential_energy() gb_dict['E_gb'] = E_gb gb_dict['E_gb_init'] = E_gb_init gb_dict['area'] = A with open('subgb.json', 'w') as outfile: for key, value in gb_dict.items(): j_dict[key] = value json.dump(j_dict, outfile, indent=2) if param_file == 'gp33b.xml': os.remove(param_file) os.remove(sparse_file) else: pass return grain
defect.set_cutoff(3.0) defect.calc_connect() new_core = pp_nye_tensor(defect, dis_type=dis_type) defect.info['core']= new_core defect.write('{0}_therm.xyz'.format(input_file)) print 'Crack Simulation Finished' if calc_nye or calc_virial: #ats = AtomsReader('{0}_traj.xyz'.format(input_file)) ats = AtomsReader('{0}.xyz'.format(input_file)) hyb = np.zeros(ats[0].n) #calc_nye tensor for each configuration in the trajectory: print len(hyb) print ats[0].params print len(ats) traj_burg = AtomsWriter('{0}_burg.xyz'.format(input_file)) for i, at in enumerate(ats[::sampling]): try: del at.properties['edgex'] del at.properties['edgey'] del at.properties['screw'] except KeyError: #property doesn't exist on atoms object pass if i > 0: at.info['core'] = new_core new_core = pp_nye_tensor(at, dis_type=dis_type) if calc_virial: at.set_calculator(pot) pp_virial(at) print i, new_core
dynamics.attach(pass_print_context(defect, dynamics)) elif dyn_type == 'LOTF': defect.info['core'] = np.array([98.0, 98.0, 1.49]) print 'Initializing LOTFDynamics' verbosity_push(PRINT_VERBOSE) dynamics = LOTFDynamics(defect, timestep, params.extrapolate_steps, check_force_error=False) dynamics.set_qm_update_func(update_qm_region) dynamics.attach(pass_print_context(defect, dynamics)) dynamics.attach(traj_writer, print_interval, defect) else: print 'No dyn_type chosen', 1 / 0 trajectory = AtomsWriter('{0}.traj.xyz'.format(input_file)) print 'Running Crack Simulation' dynamics.run(nsteps) #Write cooked i.e. thermalized ceel to file. defect.set_cutoff(3.0) defect.calc_connect() new_core = pp_nye_tensor(defect, dis_type=dis_type) defect.info['core'] = new_core defect.write('{0}_therm.xyz'.format(input_file)) print 'Crack Simulation Finished' if calc_nye or calc_virial: #ats = AtomsReader('{0}_traj.xyz'.format(input_file)) ats = AtomsReader('{0}.xyz'.format(input_file)) hyb = np.zeros(ats[0].n) #calc_nye tensor for each configuration in the trajectory:
import os import glob import argparse from quippy import Atoms from quippy.io import AtomsWriter, AtomsReader parser = argparse.ArgumentParser() parser.add_argument("-p", "--pattern", required=True) parser.add_argument("-j", "--jobfile") pattern = args.pattern jobs = glob.glob(pattern) out = AtomsWriter('traj.xyz') for job in jobs: struct_file = os.path.join(job, 'feb{0}.xyz'.format(job[-3:])) ats = AtomsReader(struct_file)[-1] out.write(ats)
atoms.params['core'] = crackpos print HYBRID_ACTIVE_MARK print 'Core Found. No. Quantum Atoms:', sum(atoms.hybrid[:]) else: print 'No cell geometry given, specifiy either disloc or crack', 1/0 # ********* Setup and run MD *********** # Set the initial temperature to 2*simT: it will then equilibriate to # simT, by the virial theorem if params.test_mode: np.random.seed(0) # use same random seed each time to be deterministic if params.rescale_velo: MaxwellBoltzmannDistribution(atoms, 2.0*sim_T) # Save frames to the trajectory every `traj_interval` time steps # but only when interpolating trajectory = AtomsWriter(os.path.join(params.rundir, params.traj_file)) # Initialise the dynamical system system_timer('init_dynamics') if params.extrapolate_steps == 1: dynamics = VelocityVerlet(atoms, params.timestep) check_force_error = False if not params.classical: qmmm_pot.set(calc_weights=True) dynamics.state_label = 'D' else: print 'Initializing LOTF Dynamics' dynamics = LOTFDynamics(atoms, params.timestep, params.extrapolate_steps, check_force_error=check_force_error) system_timer('init_dynamics') #Function to update the QM region at the beginning of each extrapolation cycle
class ParamWriter(object): """ Write out configurations to a trajectory and castep files to individual subdirectories. """ def __init__(self, atoms, name, potential, calc_energy=True): """ Initialise the writer with the templating atoms and potential. """ self.atoms = atoms self.name = name self.potential = potential self.calc_energy = calc_energy self.counter = 0 # TODO: check naming self.base_dir = os.getcwd() run_path = '{0}'.format(atoms.info['name']) info("Putting files in {0}.".format(run_path)) os.mkdir(run_path) os.chdir(run_path) trajectory = 'traj_{0}.xyz'.format(atoms.info['name']) self.out = AtomsWriter(trajectory) def write_config(self, params): cell_params = params[:6] # Make a list of 3 item lists atom_params = [self.atoms[0].position] + zip(*[iter(params[6:])] * 3) new_atoms = self.atoms.copy() new_atoms.set_cell([[cell_params[0], 0.0, 0.0], [cell_params[1], cell_params[2], 0.0], [cell_params[3], cell_params[4], cell_params[5]]]) new_atoms.set_positions(atom_params) info("Cell volume: {0}".format(new_atoms.get_volume())) if self.calc_energy: self.potential.calc(new_atoms, energy=True, forces=True, virial=True) # Add to the xyz self.out.write(new_atoms) sp_path = '{0:03d}'.format(self.counter) write_filename = '{0}.{1:03d}'.format(self.atoms.info['name'], self.counter) os.mkdir(sp_path) os.chdir(sp_path) castep_write(new_atoms, filename=write_filename, kpoint_spacing=0.015) info("Wrote a configuration {0}.".format(write_filename)) os.chdir('..') self.counter += 1 def close(self): """ Clean up. """ self.out.close() os.chdir(self.base_dir)
for k in at.info.keys(): if k not in ['energy', 'strain']: del at.info[k] # ***** Setup and run MD ***** # Initialise the dynamical system initial_momenta = at.get_momenta() dynamics = Langevin(at, params.timestep, params.sim_T * units.kB, 8e-4, logfile=log_name) # Save frames to the trajectory every `traj_interval` time steps out = AtomsWriter(traj_name) def trajectory_write(at): atout = at.copy() for k in atout.arrays.keys(): if k not in ['species', 'positions', 'momenta', 'numbers', 'force']: atout.set_array(k, None) for k in atout.info.keys(): if k not in ['energy', 'time', 'temperature', 'pbc', 'Lattice']: del atout.info[k] at.info['energy'] = at.get_potential_energy() out.write(atout) dynamics.attach(trajectory_write, params.traj_interval, at) # Save trajectory
np.random.seed(42) # use same random seed each time to be deterministic if 'thermalized' not in crack_dict.keys(): MaxwellBoltzmannDistribution(atoms, 2.0*sim_T) crack_dict['thermalized'] = True elif crack_dict['thermalized'] == False: MaxwellBoltzmannDistribution(atoms, 2.0*sim_T) crack_dict['thermalized'] = True else: pass # Now keep a record if this crack cell has been thermalized: with open("crack_info.pckl", "w") as f: pickle.dump(crack_dict,f) # Save frames to the trajectory every `traj_interval` time steps. trajectory = AtomsWriter(os.path.join(rundir, traj_file)) # Initialise the dynamical system system_timer('init_dynamics') if extrapolate_steps == 1: dynamics = VelocityVerlet(atoms, timestep) check_force_error = False if not classical: qmmm_pot.set(calc_weights=True) dynamics.state_label = 'D' else: print 'Initializing LOTF Dynamics' dynamics = LOTFDynamics(atoms, timestep, extrapolate_steps, check_force_error=check_force_error) system_timer('init_dynamics') # Function to update the QM region at the beginning of each extrapolation cycle
surf_cell = gb_frac.build_surface(bp = sym_tilt_110[0][1]) pot = Potential('IP EAM_ErcolAd', param_filename=eam_pot) bulk.set_calculator(pot) ener_per_atom = bulk.get_potential_energy()/len(bulk) surf_cell.set_calculator(pot) surf_ener = surf_cell.get_potential_energy() cell = surf_cell.get_cell() A = cell[0][0]*cell[1][1] gamma = (surf_ener- len(surf_cell)*ener_per_atom)/A print '2*gamma ev/A2', gamma print '2*gamma J/m2', gamma/(units.J/units.m**2) j_dict = {'or_axis':or_axis, 'bp':bp, 'gamma':gamma} with open('gbfrac.json','w') as f: json.dump(j_dict, f) out = AtomsWriter('{0}'.format('{0}_surf.xyz'.format(gbid))) out.write(Atoms(surf_cell)) out.close() frac_cell = gb_frac.build_tilt_sym_frac() #Unit cell for grain boundary fracture cell: print frac_cell.get_cell().round(2) frac_cell = Atoms(frac_cell) frac_cell = del_atoms(frac_cell) #Relax grainboundary crack cell unit cell: pot = Potential('IP EAM_ErcolAd', param_filename='Fe_Mendelev.xml') frac_cell.set_calculator(pot) slab_opt = FIRE(frac_cell) slab_opt.run(fmax = (0.02*units.eV/units.Ang))
def molecular_dynamics(system, potential, potential_filename=None, temperature=300, total_steps=1100000, timestep=1.0, connect_interval=200, write_interval=20000, equilibration_steps=100000, out_of_plane=None, random_seed=None): """ Run very simple molecular dynamics to generate some configurations. Writes configurations out as xyz and CASTEP files. """ info("Inside MD.") if random_seed is None: random_seed = random.SystemRandom().randint(0, 2**63) quippy.system.system_set_random_seeds(random_seed) info("Quippy Random Seed {0}.".format(random_seed)) system = Atoms(system) # Can take Potential objects, or just use a string if not isinstance(potential, Potential): if potential_filename: potential = Potential(potential, param_filename=potential_filename) else: potential = Potential(potential) system.set_calculator(potential) dynamical_system = DynamicalSystem(system) with Capturing(debug_on_exit=True): dynamical_system.rescale_velo(temperature) if out_of_plane is not None: # Stop things moving vertically in the cell dynamical_system.atoms.velo[3, :] = 0 base_dir = os.getcwd() run_path = '{0}_{1:g}/'.format(system.info['name'], temperature) info("Putting files in {0}.".format(run_path)) os.mkdir(run_path) os.chdir(run_path) trajectory = 'traj_{0}_{1:g}.xyz'.format(system.info['name'], temperature) out = AtomsWriter(trajectory) dynamical_system.atoms.set_cutoff(potential.cutoff() + 2.0) dynamical_system.atoms.calc_connect() potential.calc(dynamical_system.atoms, force=True, energy=True, virial=True) structure_count = 0 # Basic NVE molecular dynamics for step_number in range(1, total_steps + 1): dynamical_system.advance_verlet1(timestep, virial=dynamical_system.atoms.virial) potential.calc(dynamical_system.atoms, force=True, energy=True, virial=True) dynamical_system.advance_verlet2(timestep, f=dynamical_system.atoms.force, virial=dynamical_system.atoms.virial) # Maintenance of the system if not step_number % connect_interval: debug("Connect at step {0}".format(step_number)) dynamical_system.atoms.calc_connect() if step_number < equilibration_steps: with Capturing(debug_on_exit=True): dynamical_system.rescale_velo(temperature) if not step_number % write_interval: debug("Status at step {0}".format(step_number)) # Print goes to captured stdout with Capturing(debug_on_exit=True): dynamical_system.print_status( epot=dynamical_system.atoms.energy) dynamical_system.rescale_velo(temperature) if step_number > equilibration_steps: debug("Write at step {0}".format(step_number)) out.write(dynamical_system.atoms) sp_path = '{0:03d}'.format(structure_count) write_filename = '{0}_{1:g}.{2:03d}'.format( system.info['name'], temperature, structure_count) os.mkdir(sp_path) os.chdir(sp_path) castep_write(dynamical_system.atoms, filename=write_filename) espresso_write(dynamical_system.atoms, prefix=write_filename) write_extxyz("{0}.xyz".format(write_filename), dynamical_system.atoms) info("Wrote a configuration {0}.".format(write_filename)) os.chdir('..') structure_count += 1 out.close() os.chdir(base_dir) info("MD Done.")
(1.5*units.kB*len(atoms))) atoms.info['strain'] = get_strain(atoms) atoms.info['G'] = get_energy_release_rate(atoms)/(units.J/units.m**2) crack_pos = find_crack_tip_stress_field(atoms, calc=mm_pot) atoms.info['crack_pos_x'] = crack_pos[0] atoms.info['d_crack_pos_x'] = crack_pos[0] - orig_crack_pos[0] print log_format % atoms.info dynamics.attach(printstatus) # Check if the crack has advanced, and stop incrementing the strain if it has def check_if_cracked(atoms): crack_pos = find_crack_tip_stress_field(atoms, calc=mm_pot) # stop straining if crack has advanced more than tip_move_tol if not atoms.info['is_cracked'] and (crack_pos[0] - orig_crack_pos[0]) > tip_move_tol: atoms.info['is_cracked'] = True del atoms.constraints[atoms.constraints.index(strain_atoms)] dynamics.attach(check_if_cracked, 1, atoms) # Save frames to the trajectory every `traj_interval` time steps trajectory = AtomsWriter(traj_file) dynamics.attach(trajectory, traj_interval, atoms) # Start running! dynamics.run(nsteps)
def constrained_minim(atoms, method='LBFGS', vacuum=20.0, k_spring=0.6, clamp_mask=None, initial_positions=None, fmax=0.05, spring='point'): c = np.ptp(atoms.positions, axis=0) c += vacuum atoms.set_cell(np.diag(c)) if clamp_mask is None: at_help = Atoms('crack.xyz') clamp_mask = at_help.get_array('clamp_mask') if initial_positions is None: at_help = Atoms('crack.xyz') at_help.get_array('pos_orig') if spring == 'plane': springs = [ Hookean(a1=i, a2=[0, -1, 0, initial_positions[i, 1]], k=k_spring, rt=0) for i in np.where(clamp_mask)[0] ] else: springs = [ Hookean(a1=i, a2=initial_positions[i], k=k_spring, rt=0) for i in np.where(clamp_mask)[0] ] from quippy.io import AtomsWriter out = AtomsWriter("traj-relax_structure.xyz") trajectory_write = lambda: out.write(atoms) if method == "LBFGS": pot = atoms.calc cc = ConstraintCalculator(springs) sc = SumCalculator(pot, cc) left, bottom, _ = initial_positions.min(axis=0) fix_line_mask = (initial_positions[:, 0] < left + 6.5) fix_line = FixAtoms(mask=fix_line_mask) atoms.set_array('fix_line_mask', fix_line_mask) atoms.set_constraint(fix_line) atoms.set_calculator(sc) opt = LBFGS(atoms, use_armijo=False) elif method == "FIRE": right, top, _ = initial_positions.max(axis=0) left, bottom, _ = initial_positions.min(axis=0) fix_line_mask = np.logical_or(initial_positions[:, 0] > right - 6.5, initial_positions[:, 0] < left + 6.5) fix_line_idx = np.where(fix_line_mask)[0] fix_line = [FixedLine(i, np.array([0, 1, 0])) for i in fix_line_idx] atoms.set_array('fix_line_mask', fix_line_mask) atoms.set_constraint(fix_line + springs) opt = FIRE(atoms, dtmax=2.5, maxmove=0.5) elif method == "mix": # do a first opt by keeping vertical edges fixed, then make them move along y right, top, _ = initial_positions.max(axis=0) left, bottom, _ = initial_positions.min(axis=0) fix_line_mask = np.logical_or(initial_positions[:, 0] > right - 6.5, initial_positions[:, 0] < left + 6.5) fix_line_idx = np.where(fix_line_mask)[0] pot = atoms.calc cc = ConstraintCalculator(springs) sc = SumCalculator(pot, cc) atoms.set_constraint(FixAtoms(mask=fix_line_mask)) atoms.set_calculator(sc) LBFGS(atoms, use_armijo=False).run(fmax=0.2) fix_line = [FixedLine(i, np.array([0, 1, 0])) for i in fix_line_idx] atoms.set_array('fix_line_mask', fix_line_mask) atoms.set_constraint(fix_line + springs) atoms.set_calculator(pot) opt = vanillaLBFGS(atoms) else: print("Method not understood") return opt.attach(trajectory_write, interval=5) opt.run(fmax=fmax) return
def __init__(self, atoms, timestep, trajectory, trajectoryinterval=10, initialtemperature=None, logfile='-', loginterval=1, loglabel='D'): # we will do the calculation in place, to minimise number of copies, # unless atoms is not a quippy Atoms if not isinstance(atoms, Atoms): warnings.warn( 'Dynamics atoms is not quippy.Atoms instance, copy forced!') atoms = Atoms(atoms) self.atoms = atoms fortran_indexing = False if hasattr(atoms, 'fortran_indexing'): fortran_indexing = atoms.fortran_indexing if self.atoms.has('masses'): if self.atoms.has_property('mass'): if abs(self.atoms.mass / MASSCONVERT - self.atoms.get_masses()) > 1e-3: raise RuntimeError( 'Dynamics confused as atoms has inconsistent "mass" and "masses" arrays' ) else: self.atoms.add_property('mass', self.atoms.get_masses() * MASSCONVERT) else: if self.atoms.has_property('mass'): self.atoms.set_masses(self.atoms.mass / MASSCONVERT) else: self.atoms.set_masses('defaults') if self.atoms.has('momenta'): if self.atoms.has_property('velo'): if abs(self.atoms.velo * sqrt(MASSCONVERT) - self.atoms.get_velocities().T).max() > 1e-3: raise RuntimeError( 'Dynamics confused as atoms has inconsistent "velo" and "momenta" arrays' ) else: self.atoms.add_property('velo', (self.atoms.get_velocities() / sqrt(MASSCONVERT)).T) else: if self.atoms.has_property('velo'): self.atoms.set_velocities(self.atoms.velo.T * sqrt(MASSCONVERT)) else: # start with zero momenta self.atoms.set_momenta(np.zeros_like(self.atoms.positions)) self.atoms.add_property('velo', 0., n_cols=3) self._ds = DynamicalSystem(self.atoms, fortran_indexing=fortran_indexing) if initialtemperature is not None: if not all(abs(self._ds.atoms.velo) < 1e-3): msg = ('initialtemperature given but Atoms already ' + 'have non-zero velocities!') raise RuntimeError(msg) self._ds.rescale_velo(initialtemperature) # now self._ds.atoms is either a Fortran shallowcopy of atoms, # or a copy if input atoms was not an instance of quippy.Atoms if 'time' in atoms.info: self.set_time(atoms.info['time']) # from ASE units to fs self.observers = [] self.set_timestep(timestep) if trajectory is not None: if isinstance(trajectory, basestring): trajectory = AtomsWriter(trajectory) self.attach(trajectory, trajectoryinterval, self._ds.atoms) self.loglabel = loglabel if logfile is not None: if isinstance(logfile, basestring): logfile = InOutput(logfile, OUTPUT) self.attach(self.print_status, loginterval, logfile)
dynamical_system.set_barostat(type=BAROSTAT_HOOVER_LANGEVIN, p_ext=0.0, hydrostatic_strain=True, diagonal_strain=True, finite_strain_formulation=False, tau_epsilon=10.0, w_epsilon=10000.0, w_epsilon_factor=10000.0, t=TEMPERATURE) dynamical_system.add_thermostat(type=THERMOSTAT_ALL_PURPOSE, t=TEMPERATURE, tau=100.0) dynamical_system.rescale_velo(TEMPERATURE) total_steps = 1100000 timestep = 0.1 # fs connect_interval = 200 write_interval = 20000 equilibration_steps = 100000 trajectory = 'traj_{}_{}.xyz'.format(lattice.func_name, TEMPERATURE) out = AtomsWriter(trajectory) dynamical_system.atoms.calc_connect() fs_potential.calc(dynamical_system.atoms, force=True, energy=True, virial=True) # Basic NVE molecular dynamics for step_number in range(1, total_steps+1): dynamical_system.advance_verlet1(timestep, virial=dynamical_system.atoms.virial) fs_potential.calc(dynamical_system.atoms, force=True, energy=True, virial=True) dynamical_system.advance_verlet2(timestep, f=dynamical_system.atoms.force, virial=dynamical_system.atoms.virial) # Maintenance of the system if not step_number % connect_interval: