Example #1
0
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')
Example #2
0
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()
Example #3
0
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)
Example #4
0
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
Example #6
0
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
Example #7
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
Example #8
0
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
Example #9
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
Example #10
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')
Example #11
0
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()
Example #12
0
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
Example #13
0
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
Example #14
0
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()
Example #15
0
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')
Example #16
0
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
Example #17
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
            
    #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.
Example #18
0
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
Example #19
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.
Example #20
0
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
Example #21
0
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
Example #22
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
Example #23
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
Example #24
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.
Example #25
0
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)
Example #26
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.
Example #27
0
    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
Example #28
0
    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()
Example #29
0
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
Example #30
0
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()
Example #31
0
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
Example #33
0
 def release(self):
     world.barrier()
     if world.rank == 0:
         os.remove(self.name)
Example #34
0
def read_json(name):
    fd = open(name, 'r')
    results = loads(fd.read())
    fd.close()
    world.barrier()
    return numpyfy(results)
Example #35
0
def read_json(name):
    fd = open(name, 'r')
    results = loads(fd.read())
    fd.close()
    world.barrier()
    return numpyfy(results)
Example #36
0
 def release(self):
     world.barrier()
     if world.rank == 0:
         os.remove(self.name)