print 'Finding initial dislocation core positions...' try: defect.params['core'] except KeyError: defect.params['core'] = np.array([98.0, 98.0, 1.49]) defect = set_quantum(defect, params.n_core) MaxwellBoltzmannDistribution(defect, 2.0*sim_T) if dyn_type =='eam': dynamics = VelocityVerlet(defect, timestep) 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()
def makecrack_main(params, stem): """Given a CrackParams object `param`, construct and return a new crack slab Atoms object.""" xmlfilename = stem+'.xml' print_title('Initialisation') verbosity_push(params.io_verbosity) params.print_() print("Initialising classical potential with args " + params.classical_args.strip() + " from file " + xmlfilename) classicalpot = Potential(params.classical_args, param_filename=xmlfilename) classicalpot.print_() mpi_glob = MPI_context() crack_slab, width, height, E, v, v2, bulk = crack_make_slab(params, classicalpot) if params.crack_free_surfaces: depth = crack_slab.pos[3,:].max() - crack_slab.pos[3,:].min() else: depth = crack_slab.lattice[3,3] # Save bulk cube (used for qm_rescale_r parameter in crack code) if params.qm_args.startswith('TB'): bigger_bulk = supercell(bulk, 2, 2, 2) bulk = bigger_bulk bulk.write(stem+'_bulk.xyz') crack_slab.write(stem+'_slab.xyz') crack_slab.params['OrigWidth'] = width crack_slab.params['OrigHeight'] = height crack_slab.params['OrigDepth'] = depth crack_slab.params['YoungsModulus'] = E crack_slab.params['PoissonRatio_yx'] = v crack_slab.params['PoissonRatio_yz'] = v2 # Open surfaces, remain periodic in z direction (normal to plane) # and optionally also in x direction if crack_double_ended is true if not params.crack_double_ended: crack_slab.lattice[1,1] = crack_slab.lattice[1,1] + params.crack_vacuum_size crack_slab.lattice[2,2] = crack_slab.lattice[2,2] + params.crack_vacuum_size crack_slab.set_lattice(crack_slab.lattice, False) # 3D crack with free surfaces at z = +/- depth/2 if params.crack_free_surfaces: crack_slab.pos[3,:] -= crack_slab.pos[3,:].mean() # center on z=0 crack_slab.lattice[3,3] = crack_slab.lattice[3,3] + params.crack_vacuum_size crack_slab.set_lattice(crack_slab.lattice, False) # Map atoms into cell AFTER changing to the new lattice crack_slab.map_into_cell() miny, maxy = crack_slab.pos[2,:].min(), crack_slab.pos[2,:].max() assert abs((maxy-miny) - height) < 1e-5 # be sure that remapping didn't change height of slab # Add various properties to crack_slab crack_slab.add_property('hybrid', 0) crack_slab.add_property('hybrid_mark', HYBRID_NO_MARK) crack_slab.add_property('changed_nn', 0) crack_slab.add_property('move_mask', 0) crack_slab.add_property('nn', 0) crack_slab.add_property('old_nn', 0) crack_slab.add_property('md_old_changed_nn', 0) crack_slab.add_property('edge_mask', 0) crack_slab.add_property('crack_surface', False) crack_slab.add_property('crack_front', False) if params.crack_fix_dipoles: crack_slab.add_property('fixdip', False) print_title('Fixing Atoms') # Fix top and bottom edges - anything within crack_edge_fix_tol of ymax or ymin is fixed miny, maxy = crack_slab.pos[2,:].min(), crack_slab.pos[2,:].max() crack_slab.move_mask[:] = 1 crack_slab.move_mask[(abs(crack_slab.pos[2,:]-maxy) < params.crack_edge_fix_tol) | (abs(crack_slab.pos[2,:]-miny) < params.crack_edge_fix_tol)] = 0 if params.crack_fix_sides: maxx, minx = crack_slab.pos[1,:].min(), crack_slab.pos[1,:].max() crack_slab.move_mask[(abs(crack_slab.pos[1,:]-maxx) < params.crack_edge_fix_tol) | (abs(crack_slab.pos[1,:]-minx) < params.crack_edge_fix_tol)] = 0 print('%d atoms. %d fixed atoms' % (crack_slab.n, crack_slab.n - crack_slab.move_mask.sum())) print_title('Setting edge mask') crack_slab.edge_mask[:] = 0 minx, maxx = crack_slab.pos[1,:].min(), crack_slab.pos[1,:].max() crack_slab.edge_mask[(abs(crack_slab.pos[1,:]-minx) < params.selection_edge_tol) | (abs(crack_slab.pos[1,:]-maxx) < params.selection_edge_tol)] = 1 miny, maxy = crack_slab.pos[2,:].min(), crack_slab.pos[2,:].max() crack_slab.edge_mask[(abs(crack_slab.pos[2,:]-miny) < params.selection_edge_tol) | (abs(crack_slab.pos[2,:]-maxy) < params.selection_edge_tol)] = 1 if params.crack_free_surfaces: # Open surfaces at +/- z minz, maxz = crack_slab.pos[3,:].min(), crack_slab.pos[3,:].max() crack_slab.edge_mask[(abs(crack_slab.pos[3,:]-minz) < params.selection_edge_tol) | (abs(crack_slab.pos[3,:]-maxz) < params.selection_edge_tol)] = 1 if params.crack_fix_dipoles: print_title('Fixing dipoles') crack_slab.fixdip[(abs(crack_slab.pos[2,:]-maxy) < params.crack_fix_dipoles_tol) | (abs(crack_slab.pos[2,:]-miny) < params.crack_fix_dipoles_tol)] = 1 if params.crack_fix_sides: maxx, minx = crack_slab.pos[1,:].min(), crack_slab.pos[1,:].max() crack_slab.fixdip[(abs(crack_slab.pos[1,:]-maxx) < params.crack_fix_dipoles_tol) | (abs(crack_slab.pos[1,:]-minx) < params.crack_fix_dipoles_tol)] = 1 if params.crack_curved_front: crack_make_seed_curved_front(crack_slab, params) else: crack_make_seed(crack_slab, params) if params.crack_apply_initial_load: crack_calc_load_field(crack_slab, params, classicalpot, params.crack_loading, overwrite_pos=True, mpi=mpi_glob) crack_slab.write('dump.xyz') crack_update_connect(crack_slab, params) if not params.simulation_classical: if (params.selection_method.strip() == 'crack_front' or params.crack_tip_method.strip() == 'local_energy'): classicalpot.calc(crack_slab, local_energy=True) crack_setup_marks(crack_slab, params) crack_update_selection(crack_slab, params) if params.any_per_atom_tau(): # Set up per_atom_tau property for ramped Langevin thermostat: # # tau # ^ # |\ /| |\ /| max_tau # | \ / | | \ / | # | \ / | constant E | \ / | # | \ / | (tau = 0) | \ / | # | \/ | | \/ | # +----------+---------------------+----------+---> x # -w/2 -w/2+r w/2-r w/2 w_by_2 = crack_slab.OrigWidth/2. ramp_len = params.crack_thermostat_ramp_length max_tau = params.crack_thermostat_ramp_max_tau print 'Adding thermostat ramp with length', ramp_len, 'max_tau', max_tau @np.vectorize def tau(x): if x < -w_by_2 + ramp_len/2: q = (x+w_by_2)/(ramp_len/2.) return max_tau*(1.- q) elif (x > -w_by_2 + ramp_len/2 and x < -w_by_2 + ramp_len): q = (x+w_by_2-ramp_len/2.)/(ramp_len/2.) return max_tau*q elif (x > -w_by_2 + ramp_len and x < w_by_2 - ramp_len): return 0. elif (x > w_by_2 - ramp_len and x < w_by_2 - ramp_len/2): q = (x-w_by_2+ramp_len)/(ramp_len/2.) return max_tau*(1.- q) else: q = (x-w_by_2+ramp_len/2.)/(ramp_len/2.) return max_tau*q crack_slab.add_property('per_atom_tau', tau(crack_slab.pos[1,:])) return crack_slab
print 'Finding initial dislocation core positions...' try: defect.params['core'] except KeyError: defect.params['core'] = np.array([98.0, 98.0, 1.49]) defect = set_quantum(defect, params.n_core) MaxwellBoltzmannDistribution(defect, 2.0 * sim_T) if dyn_type == 'eam': dynamics = VelocityVerlet(defect, timestep) 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)