def main_elph__init(structure_path, params_fd_path, supercell, log, symmetry_tol, disp_split, stop_after_displacements, raman_settings): from gpaw import GPAW if raman_settings['write_mode_intensities'] and raman_settings[ 'permutations'] == 'original': parprint( f"--write-mode-intensities requires --no-permutations or --permutations=fast" ) sys.exit(1) calc = GPAW(structure_path) if calc.wfs.kpt_u[0].C_nM is None: parprint( f"'{structure_path}': no wavefunctions! You must save your .gpw file with 'mode=\"all\"'!" ) sys.exit(1) if calc.parameters['convergence']['bands'] == 'occupied': parprint( f"'{structure_path}': WARNING: only occupied bands were converged! Please converge some conduction band states as these are an explicit part of the electron-phonon computation." ) if params_fd_path is not None: params_fd = json.load(open(params_fd_path)) else: params_fd = {} # atoms = Cluster(ase.build.molecule('CH4')) # atoms.minimal_box(4) # atoms.pbc = True if os.path.exists('phonopy_disp.yaml'): parprint('using saved phonopy_disp.yaml') else: parprint('computing phonopy_disp.yaml') world.barrier( ) # avoid race condition where rank 0 creates file before others enter phonon = get_minimum_displacements( unitcell=ase_atoms_to_phonopy(calc.atoms), supercell_matrix=np.diag(supercell), displacement_distance=DISPLACEMENT_DIST, phonopy_kw=dict(symprec=symmetry_tol, ), ) if world.rank == 0: phonon.save('phonopy_disp.yaml') world.barrier( ) # avoid race condition where rank 0 creates file before others enter # Structure with initial guess of wavefunctions for displacement calculations. if os.path.exists('supercell.eq.gpw'): parprint('using saved supercell.eq.gpw') else: parprint('computing supercell.eq.gpw') supercell_atoms = make_gpaw_supercell(calc, supercell, **dict(params_fd, txt=log)) ensure_gpaw_setups_initialized(supercell_atoms.calc, supercell_atoms) supercell_atoms.get_potential_energy() supercell_atoms.calc.write('supercell.eq.gpw', mode='all')
def elph_do_symmetry_expansion(supercell, calc, displacement_dist, phonon, disp_carts, disp_sites, supercell_atoms): from gpaw.elph.electronphonon import ElectronPhononCoupling natoms_prim = len(calc.get_atoms()) disp_values = [read_elph_input(f'sym-{index}') for index in range(len(disp_sites))] # NOTE: phonon.symmetry includes pure translational symmetries of the supercell # so we use an empty quotient group quotient_perms = np.array([np.arange(len(supercell_atoms))]) super_lattice = supercell_atoms.get_cell()[...] super_symmetry = phonon.symmetry.get_symmetry_operations() oper_sfrac_rots = super_symmetry['rotations'] oper_sfrac_trans = super_symmetry['translations'] oper_cart_rots = np.array([super_lattice.T @ Rfrac @ np.linalg.inv(super_lattice).T for Rfrac in oper_sfrac_rots]) oper_cart_trans = oper_sfrac_trans @ super_lattice oper_phonopy_coperms = phonon.symmetry.get_atomic_permutations() oper_phonopy_deperms = np.argsort(oper_phonopy_coperms, axis=1) # Convert permutations by composing the following three permutations: into phonopy order, apply oper, back to ase order parprint('phonopy deperms:', oper_phonopy_deperms.shape) deperm_phonopy_to_ase = interop.get_deperm_from_phonopy_sc_to_ase_sc(natoms_prim, supercell) oper_deperms = [np.argsort(deperm_phonopy_to_ase)[deperm][deperm_phonopy_to_ase] for deperm in oper_phonopy_deperms] del oper_phonopy_coperms, oper_phonopy_deperms elphsym = symmetry.ElphGpawSymmetrySource.from_setups_and_ops( setups=supercell_atoms.calc.wfs.setups, lattice=super_lattice, oper_cart_rots=oper_cart_rots, oper_cart_trans=oper_cart_trans, oper_deperms=oper_deperms, ) if world.rank == 0: full_derivatives = symmetry.expand_derivs_by_symmetry( disp_sites, # disp -> atom disp_carts, # disp -> 3-vec disp_values, # disp -> T (displaced value, optionally minus equilibrium value) elph_callbacks_2(supercell_atoms.calc.wfs, elphsym, supercell=supercell), # how to work with T oper_cart_rots, # oper -> 3x3 oper_perms=oper_deperms, # oper -> atom' -> atom quotient_perms=quotient_perms, ) # NOTE: confusingly, Elph wants primitive atoms, but a calc for the supercell elph = ElectronPhononCoupling(calc.atoms, calc=supercell_atoms.calc, supercell=supercell) displaced_cell_index = elph.offset del elph # that's all we needed it for eq_Vt, eq_dH, eq_forces = read_elph_input('eq') for a in range(natoms_prim): for c in range(3): delta_Vt, delta_dH, delta_forces = full_derivatives[natoms_prim * displaced_cell_index + a][c] for sign in [-1, +1]: disp = interop.AseDisplacement(atom=a, axis=c, sign=sign) disp_Vt = eq_Vt + sign * displacement_dist * delta_Vt disp_dH = {k: eq_dH[k] + sign * displacement_dist * delta_dH[k] for k in eq_dH} disp_forces = eq_forces + sign * displacement_dist * delta_forces pickle.dump(disp_forces, paropen(f'phonons.{disp}.pckl', 'wb'), protocol=2) pickle.dump((disp_Vt, disp_dH), paropen(f'elph.{disp}.pckl', 'wb'), protocol=2) world.barrier()
def get_mode_raman(outpath, eigendata, cart_pol_derivs): if os.path.exists(outpath): parprint(f'Found existing {outpath}') return world.barrier() parprint(f'Computing mode raman tensors... ({outpath})') cart_pol_derivs = np.load('raman-cart.npy') mode_pol_derivs = [] for row in eigendata['eigenvectors']: mode_displacements = eigendata['atom_masses'].repeat(3) ** -0.5 * row mode_displacements /= np.linalg.norm(mode_displacements) # ∂α_ij ∂α_ij ∂x_ak # ----- = sum ( ----- ----- ) # ∂u_n a,k ∂x_ak ∂u_n # # = dot product of (3n-dimensional gradient of ∂α_ij) # with (3n-dimensional displacement vector of mode n) mode_pol_deriv = np.dot( # move i and j (axes 2 and 3) to the outside and combine axes 0 and 1 (x components) cart_pol_derivs.transpose((2, 3, 0, 1)).reshape((9, -1)), mode_displacements, ).reshape((3, 3)) mode_pol_derivs.append(mode_pol_deriv) np.save(outpath, mode_pol_derivs)
def main( name, # root="../ZnVO/", root="/cluster/scratch/ttian/ZnVO", model="A", clean=False): if name not in ("Zn", "Co"): return False # Directory if rank == 0: base_dir = os.path.join(root, "{}V2O5".format(name)) if clean: shutil.rmtree(base_dir, ignore_errors=True) if not os.path.exists(base_dir): os.makedirs(base_dir) world.barrier() if clean: return # on all ranks base_dir = os.path.join(root, "{}V2O5".format(name)) parprint("Running {} with model type {}".format(name, model)) relax(base_dir=base_dir, model=model) return 0
def _startup(self): """Initiates a run, and determines if running from previous data or a fresh run.""" status = np.array(-1.) exists = self._read_minima() if world.rank == 0: if not exists: # Fresh run with new minima file. status = np.array(0.) elif not os.path.exists(self._logfile): # Fresh run with existing or shared minima file. status = np.array(1.) else: # Must be resuming from within a working directory. status = np.array(2.) world.barrier() world.broadcast(status, 0) if status == 2.: self._resume() else: self._counter = 0 self._log('init') self._log('msg', 'Performing initial optimization.') if status == 1.: self._log( 'msg', 'Using existing minima file with %i prior ' 'minima: %s' % (len(self._minima), self._minima_traj)) self._optimize() self._check_results() self._counter += 1
def main( name, # root="../ZnVO/", root="/cluster/scratch/ttian/ZnVO", clean=False): if name not in ("Zn", "Co", "ghost-Co"): return False # Directory if rank == 0: base_dir = os.path.join(root, "{}V2O5".format(name)) if clean: shutil.rmtree(base_dir, ignore_errors=True) if not os.path.exists(base_dir): os.makedirs(base_dir) world.barrier() if clean: return # on all ranks base_dir = os.path.join(root, "{}V2O5".format(name)) # atoms = make_super(base_dir) # add_adatom(atoms, scaled_pos=(1 / 2, 1 / 2, 1 / 2)) # parprint(atoms) # view(atoms.copy()) if name in ("Zn", "Co"): neb(base_dir=base_dir) else: neb_ghost(base_dir=base_dir) return 0
def _startup(self): """Initiates a run, and determines if running from previous data or a fresh run.""" status = np.array(-1.) exists = self._read_minima() if rank == 0: if not exists: # Fresh run with new minima file. status = np.array(0.) elif not os.path.exists(self._logfile): # Fresh run with existing or shared minima file. status = np.array(1.) else: # Must be resuming from within a working directory. status = np.array(2.) world.barrier() world.broadcast(status, 0) if status == 2.: self._resume() else: self._counter = 0 self._log('init') self._log('msg', 'Performing initial optimization.') if status == 1.: self._log('msg', 'Using existing minima file with %i prior ' 'minima: %s' % (len(self._minima), self._minima_traj)) self._optimize() self._check_results() self._counter += 1
def main( name, # root="../ZnVO/", root="/cluster/scratch/ttian/ZnVO", clean=False): if name not in ("Zn", "Co"): return False # Directory if rank == 0: base_dir = os.path.join(root, "{}V2O5".format(name)) if clean: shutil.rmtree(base_dir, ignore_errors=True) if not os.path.exists(base_dir): os.makedirs(base_dir) world.barrier() if clean: return # on all ranks atoms = get_structure(name) parprint(atoms) base_dir = os.path.join(root, "{}V2O5".format(name)) relax(atoms, name=name, base_dir=base_dir) return 0
def main(name, imag="init", root="/cluster/scratch/ttian/ZnVO", clean=False): assert imag in ("init", "final") if name not in ("Zn", "Co"): return False # Directory if rank == 0: base_dir = os.path.join(root, "{}V2O5".format(name)) if clean: shutil.rmtree(base_dir, ignore_errors=True) if not os.path.exists(base_dir): os.makedirs(base_dir) world.barrier() if clean: return # on all ranks base_dir = os.path.join(root, "{}V2O5".format(name)) if imag == "init": calc_img(base_dir=base_dir, scaled_pos=(0, 0, 1 / 2), index=imag) else: calc_img(base_dir=base_dir, scaled_pos=(1 / 2, 1 / 2, 1 / 2), index=imag) return 0
def write_gpw_file(): """write gs dft calculation """ # start by cleaning up a bit if world.rank == 0: for name in Path().glob('*.npy'): Path(name).unlink() for name in Path().glob('*.tmp.*.pckl'): Path(name).unlink() world.barrier() params = dict(mode=PW(400), xc='PBE', basis='dzp', kpts={ 'size': (6, 6, 1), 'gamma': True }, occupations=FermiDirac(width=0.05)) slab = mx2('MoSS', '2H', 3.184, 3.127) slab.center(vacuum=8, axis=2) slab.pbc = (1, 1, 0) slab.calc = GPAW(txt='gs.txt', **params) slab.get_forces() slab.get_stress() slab.calc.write('gs.gpw')
def copy_chk(base, prev, now): """Copy chk file from previous state""" if rank == 0: copyfile(base / "{0}.chk".format(prev), base / "{0}.chk".format(now)) else: pass world.barrier()
def make_force_sets_and_excitations(cachepath, disp_filenames, phonon, atoms, ex_kw): if os.path.exists(cachepath): parprint(f'Found existing {cachepath}') return np.load(cachepath) world.barrier() parprint( f'Computing force sets and polarizability data at displacements... ({cachepath})' ) eq_atoms = atoms.copy() def iter_displacement_files(): eq_force_filename = disp_filenames['force']['eq'] eq_ex_filename = disp_filenames['ex']['eq'] yield 'eq', eq_force_filename, eq_ex_filename, eq_atoms disp_phonopy_sites, disp_carts = get_phonopy_displacements(phonon) for i, disp_atoms in enumerate( iter_displaced_structures(atoms, disp_phonopy_sites, disp_carts)): force_filename = disp_filenames['force']['disp'].format(i) ex_filename = disp_filenames['ex']['disp'].format(i) yield 'disp', force_filename, ex_filename, disp_atoms # Make files for one displacement at a time for disp_kind, force_filename, ex_filename, disp_atoms in iter_displacement_files( ): if os.path.exists(ex_filename): continue world.barrier() atoms.set_positions(disp_atoms.get_positions()) disp_forces = atoms.get_forces() ex = LrTDDFT(atoms.calc, **ex_kw) if disp_kind == 'eq': # For inspecting the impact of differences in the calculator # between ionic relaxation and raman computation. parprint('Max equilibrium force during raman:', np.absolute(disp_forces).max()) if world.rank == 0: np.save(force_filename, disp_forces) ex.write(ex_filename) # combine force sets into one file force_sets = np.array([ np.load(disp_filenames['force']['disp'].format(i)) for i in range(len(phonon.get_displacements())) ]) np.save(cachepath, force_sets) for i in range(len(phonon.get_displacements())): os.unlink(disp_filenames['force']['disp'].format(i)) return force_sets
def expand_raman_by_symmetry(cachepath, phonon, disp_filenames, get_polarizability, ex_kw, subtract_equilibrium_polarizability): if os.path.exists(cachepath): parprint(f'Found existing {cachepath}') return np.load(cachepath) world.barrier() parprint(f'Expanding raman data by symmetry... ({cachepath})') disp_phonopy_sites, disp_carts = get_phonopy_displacements(phonon) prim_symmetry = phonon.primitive_symmetry.get_symmetry_operations() lattice = phonon.primitive.get_cell()[...] carts = phonon.primitive.get_positions() oper_frac_rots = prim_symmetry['rotations'] oper_frac_trans = prim_symmetry['translations'] oper_cart_rots = np.array( [np.linalg.inv(lattice).T @ R @ lattice.T for R in oper_frac_rots]) oper_cart_trans = oper_frac_trans @ lattice oper_deperms = [] for cart_rot, cart_trans in zip(oper_cart_rots, oper_cart_trans): carts = phonon.primitive.get_positions() transformed_carts = carts @ cart_rot.T + cart_trans oper_deperms.append(get_deperm(carts, transformed_carts, lattice)) oper_deperms = np.array(oper_deperms) disp_tensors = np.array([ get_polarizability( LrTDDFT.read(disp_filenames['ex']['disp'].format(i), **ex_kw)) for i in range(len(disp_phonopy_sites)) ]) if subtract_equilibrium_polarizability: disp_tensors -= get_polarizability( LrTDDFT.read(disp_filenames['ex']['eq'], **ex_kw)) pol_derivs = symmetry.expand_derivs_by_symmetry( disp_phonopy_sites, disp_carts, disp_tensors, symmetry.Tensor2Callbacks(), oper_cart_rots, oper_deperms, ) pol_derivs = np.array( pol_derivs.tolist()) # (n,3) dtype=object --> (n,3,3,3) dtype=complex np.save(cachepath, pol_derivs) return pol_derivs
def elph_do_supercell_matrix(log, calc, supercell): from gpaw.elph.electronphonon import ElectronPhononCoupling # calculate_supercell_matrix breaks if parallelized over domains so parallelize over kpt instead # (note: it prints messages from all processes but it DOES run faster with more processes) supercell_atoms = GPAW('supercell.eq.gpw', txt=log, parallel={'domain': (1,1,1), 'band': 1, 'kpt': world.size}).get_atoms() elph = ElectronPhononCoupling(calc.atoms, supercell=supercell, calc=supercell_atoms.calc) elph.set_lcao_calculator(supercell_atoms.calc) # to initialize bfs.M_a ensure_gpaw_setups_initialized(supercell_atoms.calc, supercell_atoms) elph.calculate_supercell_matrix(dump=1) world.barrier()
def relax_atoms(outpath, atoms): from ase import optimize if os.path.exists(outpath): parprint(f'Found existing {outpath}') return world.barrier() parprint(f'Relaxing structure... ({outpath})') dyn = optimize.FIRE(atoms) dyn.run(fmax=0.05) # FIXME: consider using something else to write, like pymatgen.io.vasp.Poscar with significant_figures=15. # ASE always writes {:11.8f} in frac coords, which can be a dangerous amount of rounding # for large unit cells. atoms.write(outpath, format='vasp')
def get_eigensolutions_at_q(cachepath, phonon, q): if os.path.exists('eigensolutions-gamma.npz'): parprint('Found existing eigensolutions-gamma.npz') return dict(np.load(cachepath)) world.barrier() parprint('Diagonalizing dynamical matrix at gamma... (eigensolutions-gamma.npz)') phonon.produce_force_constants() frequencies, eigenvectors = phonon.get_frequencies_with_eigenvectors(q) out = dict( atom_masses=phonon.masses, frequencies=frequencies, eigenvectors=eigenvectors.T, # store as rows ) np.savez(cachepath, **out) return out
def read_and_do_montecarlo(filename,use_gas): d = SurfaceMonteCarloData() d.read(filename) print "Starting "+str(len(d))+" sims." surfaces = data.fcc.surface_names #for n in range(0,len(d)): for n in range(world.rank,len(d),world.size): file = outdir+"/a%05i.amc.gz" % n if not os.path.exists(file): layers = d[n][1] # Really d[n]["layers"] atoms = FaceCenteredCubic(d.atomic_number, surfaces, layers,latticeconstant=d.lattice_constant) resizecluster(atoms, d.fitsize) print "Resized number of atoms:", len(atoms) do_monte_carlo(atoms,n,outdir,use_gas) world.barrier()#Let the cpu's wait until all in same state.
def main(formula, root="/cluster/scratch/ttian/2D-bulk/", clean=False): # candidates = {} # if rank == 0: # If MX2 then use a larger c if any([s in formula for s in ("I", "O", "S", "Se", "Te")]): c = 6.0 else: c = 3.0 candidates = get_structure(formula, c=c) # candidates = broadcast(candidates, root=0) parprint(rank, candidates) # Directory manipulation if rank == 0: for name in candidates: base_dir = os.path.join(root, name) if clean: shutil.rmtree(base_dir, ignore_errors=True) if not os.path.exists(base_dir): os.makedirs(base_dir) world.barrier() if clean: return # on all ranks # On all ranks for name in candidates: base_dir = os.path.join(root, name) mol = candidates[name] # Relaxation and gs relax(mol, name=name, base_dir=base_dir) parprint("Relaxation for {} finished!".format(name)) excited(base_dir=base_dir) parprint("Excitation for {} finished!".format(name)) permittivity(base_dir=base_dir, mode="df") parprint("Permittivity for {} finished!".format(name)) # polarizability(base_dir=base_dir, mode="tetra") # # parprint("Polarizability using tetra {} finished!".format(name)) return 0
def read_and_do_montecarlo(filename): d = SurfaceMonteCarloData() d.read(filename) print "Starting "+str(len(d))+" sims." surfaces = data.fcc.surface_names #for n in range(0,len(d)): for n in range(world.rank,len(d),world.size): file = outdir+"/a%05i.amc.gz" % n if not os.path.exists(file): layers = d[n][1] # Really d[n]["layers"] atoms = FaceCenteredCubic(d.atomic_number, surfaces, layers,latticeconstant=d.lattice_constant) resizecluster(atoms, d.fitsize) print "Resized number of atoms:", len(atoms) do_monte_carlo(atoms,n,outdir) world.barrier()#Let the cpu's wait until all in same state.
def main(mater, n_max=16): # Delete all previous files if world.rank == 0: for f in glob.glob(os.path.join(data_path, "{}/gwqeh*".format(mater))): os.remove(f) world.barrier() for n in range(2, n_max): parprint(n) gwqeh(mater, n_layers=n) # Just try! res = [] for n in range(1, n_max): print(n) gap = get_gap(mater, n) res.append((n, gap)) res = numpy.array(res) f_name = os.path.join(res_path, "{}-gwqeh-gap.csv".format(mater)) numpy.savetxt(f_name, X=res, delimiter=",", header="N, Eg (eV)") return
def run_single(formula, prototype, root="/cluster/scratch/ttian/bulk", clean=False): prototype = convert_name(prototype)[0] name = "{}-{}".format(formula, prototype) base_dir = join(root, name) # Directory manipulation if rank == 0: if clean: shutil.rmtree(base_dir, ignore_errors=True) if not exists(base_dir): os.makedirs(base_dir) world.barrier() sb = StructureBuilder() atoms, *_ = sb.get_structure(formula, prototype) m_calc = MaterCalc(atoms=atoms, base_dir=base_dir) if prototype != "perovskite": m_calc.relax(fmax=0.002) else: # m_calc.relax(fmax=0.02, method="UCF") m_calc.relax(skip=True) m_calc.ground_state() if prototype != "perovskite": eg_min, eg_dir, *_ = m_calc.bandgap(method="pbe") parprint("PBE min/dir: {:.3f}\t{:.3f}".format(eg_min, eg_dir)) eg_min, eg_dir, *_ = m_calc.bandgap(method="gllb") parprint("GLLB min/dir: {:.3f}\t{:.3f}".format(eg_min, eg_dir)) else: pass # eg_min, eg_dir, *_ = m_calc.bandgap(method="pbe", skip=True) # parprint("PBE min/dir: {:.3f}\t{:.3f}".format(eg_min, eg_dir)) # eg_min, eg_dir, *_ = m_calc.bandgap(method="gllb", skip=True) # parprint("GLLB min/dir: {:.3f}\t{:.3f}".format(eg_min, eg_dir)) # Use db values m_calc.excited_state() m_calc.dielectric(method="rpa") return 0
def main(formula, kind, fermi_shift=0, root="/cluster/scratch/ttian/2D/", clean=False): # candidates = {} # if rank == 0: # candidates = get_structure(formula) # candidates = broadcast(candidates, root=0) # parprint(rank, candidates) name = "{}-{}".format(formula, kind) base_dir = os.path.join(root, name) # Directory manipulation if rank == 0: if clean: shutil.rmtree(base_dir, ignore_errors=True) if not os.path.exists(base_dir): os.makedirs(base_dir) world.barrier() if clean: return # on all ranks # On all ranks # Relaxation and gs # relax(mol, name=name, # base_dir=base_dir) # parprint("Relaxation for {} finished!".format(name)) # excited(base_dir=base_dir) # parprint("Excitation for {} finished!".format(name)) polarizability(base_dir=base_dir, mode="df", fermi_shift=fermi_shift) # add fermilevel parprint("Polarizability for {} with Fermi Shift {} finished!".format( name, fermi_shift)) # polarizability(base_dir=base_dir, mode="tetra") # # parprint("Polarizability using tetra {} finished!".format(name)) return 0
def main(formula, prototype=None, root="/cluster/scratch/ttian/2D", clean=False): # candidates = {} # if rank == 0: candidates = get_structure(formula, prototype) # candidates = broadcast(candidates, root=0) parprint(rank, candidates) # Directory manipulation if rank == 0: for name in candidates: base_dir = os.path.join(root, name) if clean: shutil.rmtree(base_dir, ignore_errors=True) if not os.path.exists(base_dir): os.makedirs(base_dir) world.barrier() if clean: return # on all ranks # On all ranks for name in candidates: base_dir = os.path.join(root, name) parprint(name) mol = candidates[name] # Relaxation and gs relax(mol, name=name, base_dir=base_dir) parprint("Relaxation for {} finished!".format(name)) excited(base_dir=base_dir) parprint("Excitation for {} finished!".format(name)) polarizability(base_dir=base_dir, mode="df") parprint("Polarizability for {} finished!".format(name)) # polarizability(base_dir=base_dir, mode="tetra") # # parprint("Polarizability using tetra {} finished!".format(name)) return 0
def read_and_do_montecarlo(filename,use_gas): d = SurfaceMonteCarloData() d.read(filename) print "Starting "+str(len(d))+" sims." surfaces = data.fcc.surface_names #Only one worker should create the filename outdir = determine_create_dirname(filename) #for n in range(0,len(d)): for n in range(world.rank,len(d),world.size): layers = d[n][1] # Really d[n]["layers"] multiplicity = d.get_multiplicity(n) atoms = FaceCenteredCubic(d.atomic_number, surfaces, layers,latticeconstant=d.lattice_constant) print "Number of atoms:", len(atoms) resizecluster(atoms, d.fitsize) print "Resized number of atoms:", len(atoms) do_monte_carlo(atoms,n,outdir,use_gas,multiplicity) world.barrier()#Let the cpu's wait until all in same state.
def run_single(name="Si", prototype=None): sb = StructureBuilder() mater = sb.get_structure(formula=name, prototype=prototype) parprint("Before", mater) if len(mater) != 1: return mater = mater[0] base_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)), "../../tmp/", "{}-{}/".format(name, prototype)) if rank == 0: if not os.path.exists(base_dir): os.makedirs(base_dir) world.barrier() calc = GPAW( mode=dict(name="pw", ecut=800), occupations=dict(name="fermi-dirac", width=0.01), basis="dzp", xc="PBE", kpts=dict(gamma=True, density=4.0), # Very rough k-density txt=os.path.join(base_dir, "{}-{}.txt".format(name, prototype))) mater.set_calculator(calc) sf = StrainFilter(mater) traj_filename = os.path.join(base_dir, "{}-{}.traj".format(name, prototype)) log_filename = os.path.join(base_dir, "{}-{}.log".format(name, prototype)) # Overwrite file with open(traj_filename, "w") as _: pass with open(log_filename, "w") as _: pass opt_strain = ase.optimize.BFGS(sf, trajectory=traj_filename, logfile=log_filename) opt_force = ase.optimize.BFGS(mater, trajectory=traj_filename, logfile=log_filename) opt_strain.run(fmax=0.02) # opt_force.run(fmax=0.02) parprint("After", mater)
def read_and_do_montecarlo(filename, use_gas): d = SurfaceMonteCarloData() d.read(filename) print "Starting " + str(len(d)) + " sims." surfaces = data.fcc.surface_names #Only one worker should create the filename outdir = determine_create_dirname(filename) #for n in range(0,len(d)): for n in range(world.rank, len(d), world.size): layers = d[n][1] # Really d[n]["layers"] multiplicity = d.get_multiplicity(n) atoms = FaceCenteredCubic(d.atomic_number, surfaces, layers, latticeconstant=d.lattice_constant) print "Number of atoms:", len(atoms) resizecluster(atoms, d.fitsize) print "Resized number of atoms:", len(atoms) do_monte_carlo(atoms, n, outdir, use_gas, multiplicity) world.barrier() #Let the cpu's wait until all in same state.
def __init__( self, atoms, # A ase.atoms.Atoms object base_dir, param_file=default_json_file): # Read the parameters if os.path.exists(param_file): with open(param_file, "r") as f: params = json.load(f) self.__params = params else: raise FileNotFoundError("No parameter file!") # Base_dir for all data if not os.path.exists(base_dir): if rank == 0: os.makedirs(base_dir) # Recursively makedirs world.barrier() # Handle file path-related issues self.__base_dir = os.path.abspath(base_dir) self.__relaxed_traj = os.path.join(self.__base_dir, "relaxed.traj") self.__relaxed_gllb_traj = os.path.join(self.__base_dir, "relaxed_gllb.traj") self.__gs_file = os.path.join(self.__base_dir, "gs.gpw") # ground state in PBE self.__gs_gllb_file = os.path.join( self.__base_dir, "gs_gllb.gpw") # ground state in PBE self.__bg_file_template = os.path.join(self.__base_dir, "bg_{}.npz") # to add later self.__es_file = os.path.join(self.__base_dir, "es.gpw") # excited states in PBE self.__eps_file_template = os.path.join(self.__base_dir, "eps_{}.npz") if isinstance(atoms, Atoms): self.atoms = atoms elif atoms is None: # Dummy instance for checking only self.atoms = None else: raise TypeError("Atom must be an Atoms instance!") return
def calculate(self, atoms=None, properties=['energy'], system_changes=all_changes): # We don't call FileIOCalculator.calculate here, because that method # calls subprocess.call(..., shell=True), which we don't want to do. # So, we reproduce some content from that method here. Calculator.calculate(self, atoms, properties, system_changes) # If a parameter file exists in the working directory, delete it # first. If we need that file, we'll recreate it later. localparfile = os.path.join(self.directory, '.dftd3par.local') if os.path.isfile(localparfile): os.remove(localparfile) # Write XYZ or POSCAR file and .dftd3par.local file if we are using # custom damping parameters. self.write_input(self.atoms, properties, system_changes) command = self._generate_command() # Finally, call dftd3 and parse results. with paropen(self.label + '.out', 'w') as f: if world.rank == 0: # DFTD3 does not run in parallel # so we only need it to run on 1 core errorcode = subprocess.call(command, cwd=self.directory, stdout=f) else: errorcode = None world.barrier() # Wait for the call() to complete on the master node errorcode = broadcast(errorcode, root=0) if errorcode: raise RuntimeError('%s returned an error: %d' % (self.name, errorcode)) self.read_results()
def determine_create_dirname(filename): outdir, ext = os.path.splitext(filename) assert (ext == ".smc") suffix = 1 if use_gas: outdirtmp = outdir + "_amc_gas" else: outdirtmp = outdir + "_amc" while os.path.exists(outdirtmp): if use_gas: outdirtmp = outdir + "_amc_gas_" + str(suffix) else: outdirtmp = outdir + "_amc_" + str(suffix) suffix += 1 #Create this new directory: world.barrier() if world.rank == 0: os.mkdir(outdirtmp) else: while not os.path.exists(outdirtmp): sleep(1) #Now we have a unique directory, return it. return outdirtmp
def get_minimum_displacements( cachepath: str, unitcell: phonopy.structure.atoms.PhonopyAtoms, supercell_matrix: np.ndarray, displacement_distance: float, phonopy_kw: dict = {}, ): # note: applying phonopy_kw on load is necessary because phonopy will recompute symmetry load = lambda: phonopy.load(cachepath, produce_fc=False, **phonopy_kw) if os.path.exists(cachepath): parprint(f'Found existing {cachepath}') return load() world.barrier() # avoid race condition where rank 0 creates file before others enter parprint(f'Getting displacements... ({cachepath})') if world.rank == 0: phonon = phonopy.Phonopy(unitcell, supercell_matrix, factor=phonopy.units.VaspToTHz, **phonopy_kw) phonon.generate_displacements(distance=displacement_distance) parprint(f'Saving displacements...') phonon.save(cachepath) world.barrier() parprint(f'Loading displacements...') return load()
def determine_create_dirname(filename): outdir, ext = os.path.splitext(filename) assert(ext == ".smc") suffix = 1 if use_gas: outdirtmp = outdir+"_amc_gas" else: outdirtmp = outdir+"_amc" while os.path.exists(outdirtmp): if use_gas: outdirtmp = outdir+"_amc_gas_"+str(suffix) else: outdirtmp = outdir+"_amc_"+str(suffix) suffix+=1 #Create this new directory: world.barrier() if world.rank == 0: os.mkdir(outdirtmp) else: while not os.path.exists(outdirtmp): sleep(1) #Now we have a unique directory, return it. return outdirtmp
def main(begin=0, end=None): sb = StructureBuilder() assert begin >= 0 entries = sb.entries if end is None: end = len(entries) candidates = entries[begin:end] # End is not calculated! results_all = [] for i, line in enumerate(candidates): name = line["formula"] prototype = line["prototype"] res_single = run_single(sb, name, prototype) for entry in res_single: results_all.append(entry) parprint(type(results_all), results_all) world.barrier() if rank == 0: with open( os.path.join(cur_dir, "../../tmp/", "relax_result_{}-{}.json".format(begin, end)), "w") as f: json.dump(results_all, f) return
def release(self): world.barrier() if world.rank == 0: os.remove(self.name)
def read_json(name): fd = open(name, 'r') results = loads(fd.read()) fd.close() world.barrier() return numpyfy(results)