Source code for EPWpy.EPWpy_prepare

from __future__ import annotations

__author__= "Sabyasachi Tiwari, Shashi Mishra"
__copyright__= "Copyright 2024, EPWpy project"
__version__= "1.0"
__maintainer__= "Sabyasachi Tiwari"
__maintainer_email__= "sabyasachi.tiwari@austin.utexas.edu"
__status__= "Production"
__date__= "May 03, 2024"

import numpy as np
import os
import subprocess as sp
from EPWpy.utilities.set_files import*
from EPWpy.utilities.epw_pp import *
from EPWpy.utilities.printing import *
from EPWpy.utilities.write_job import *

[docs] class PyPrepare(SetDir): """ The :class:`PyPrepare` class handles setup tasks required before running EPW or related first-principles simulations. It inherits from :class:`SetDir` and is mainly responsible for preparing and transferring necessary files (e.g., pseudopotentials, input decks) to the working directory. This class is typically used internally by :class:`PyRun`, but it can also be invoked independently for pre-processing or file management tasks. **Attributes** --------------- prefix : str Name prefix used for input/output files and working directories. pseudo : str Path to the pseudopotential directory or file. files : list of str List of files to be transferred or linked for the run. folder_name : str Name of the folder where files will be prepared (default: ``'dummy'``). dolink : bool Whether to create symbolic links instead of copying files (default: ``False``). """ def __init__(self, prefix, pseudo, files=None): """ Initialize a :class:`PyPrepare` object. Parameters ----------- prefix : str Base prefix for the simulation (e.g., system name). pseudo : str Path to the pseudopotential(s) used for the calculation. Only needed for VASP calculations files : list of str, optional List of additional input or data files to prepare (default: an empty list). Notes ----- - Sets default folder name to ``'dummy'``. - Disables symbolic linking (`dolink = False`) by default. """ if files is None: files = [] self.prefix = prefix self.pseudo = pseudo self.files = files self.folder_name = 'dummy' self.dolink = False
[docs] def decorated_save(func): """ Saves state """ def inner(self,**kwargs): fold = kwargs['name'] self.save = Save_state(' ',' ') dict1 = {f'{util}':fold} self._save_json('state',dict1)#self.pw_system) func(self,**kwargs) return inner
# @decorated_save
[docs] def prepare_custom(self, name: str = 'custom', filename: str = 'custom.in'): """ Prepare a custom calculation directory and transfer input files. This method sets up a folder for a custom calculation and copies the necessary input files to that directory. It can be used for any calculation type where the inputs are not standard SCF/EPW workflows. Parameters ---------- name : str, optional Name of the directory to create for the custom calculation (default: ``"custom"``). filename : str, optional Name of the input file to copy into the custom directory (default: ``"custom.in"``). Workflow -------- 1. Creates a new directory ``name`` via ``makedir()``. 2. Transfers required files using ``run_transfer(name); these are provided through file_transfer=[]``. 3. Copies the specified input file into the new directory using ``run()``. Notes ----- - Useful for setting up calculations that do not follow the standard SCF/EPW workflow. - Ensures the folder structure is ready for independent runs. Example ------- >>> prepare_custom(name="my_custom_calc", filename="my_input.in") """ self.makedir(name) self.run_transfer(name) self.run(f'{filename}',f'{name}')
[docs] def prepare_scf(self, name: str = 'scf', filename: str = 'scf.in'): """ Prepare a self-consistent field (SCF) calculation directory. This method creates a folder for an SCF calculation and copies the SCF input file into that directory. It ensures the directory structure is ready for running Quantum ESPRESSO SCF calculations. Parameters ---------- name : str, optional Name of the directory to create for the SCF calculation (default: ``"scf"``). filename : str, optional Name of the SCF input file to copy (default: ``"scf.in"``). Workflow -------- 1. Creates the SCF directory using ``makedir()``. 2. Copies the specified input file into the SCF directory using ``run()``. Notes ----- - Assumes the SCF input file exists in the current working directory. - This setup is a prerequisite for performing SCF calculations. Example ------- >>> prepare_scf(name="scf_run", filename="si.scf.in") """ self.makedir(name) self.run(f'{filename}',f'{name}')
[docs] def prepare_nscf(self, name: str = 'nscf', filename: str = 'nscf.in'): """ Prepare a non-self-consistent field (NSCF) calculation directory. This method sets up the folder structure and transfers necessary input files for an NSCF calculation. It uses the same workflow as `prepare_post_scf()`, ensuring that the required SCF outputs are available for the NSCF run. Parameters ---------- name : str, optional Name of the directory for the NSCF calculation (default: ``"nscf"``). filename : str, optional Name of the NSCF input file to copy (default: ``"nscf.in"``). Workflow -------- 1. Calls `prepare_post_scf()` to create the directory and transfer files. 2. Ensures SCF outputs and NSCF input are in place for the calculation. Notes ----- - Assumes that the corresponding SCF calculation has already been completed. - This setup is required for proper NSCF or bandstructure calculations. Example ------- >>> prepare_nscf(name="nscf_run", filename="si.nscf.in") """ self.prepare_post_scf(name, filename)
[docs] def prepare_bs(self, name: str = 'bs', filename: str = 'bs.in'): """ Prepare a bandstructure (BS) calculation directory. This method sets up the folder structure and transfers necessary input files for a bandstructure calculation. It uses the same workflow as `prepare_post_scf()`, ensuring that required SCF outputs are available for the BS run. Parameters ---------- name : str, optional Name of the directory for the bandstructure calculation (default: ``"bs"``). filename : str, optional Name of the bandstructure input file to copy (default: ``"bs.in"``). Workflow -------- 1. Calls `prepare_post_scf()` to create the directory and transfer files. 2. Ensures SCF outputs and BS input are in place for the calculation. Notes ----- - Assumes that a corresponding SCF calculation has already been completed. - This setup is necessary for proper bandstructure analysis. Example ------- >>> prepare_bs(name="bs_run", filename="si.bs.in") """ self.prepare_post_scf(name, filename)
[docs] def prepare_ph(self, name: str = 'ph', filename: str = 'ph.in'): """ Prepare a phonon (PH) calculation directory. This method sets up the folder structure and transfers necessary input files for a phonon calculation. It uses the same workflow as `prepare_post_scf()`, ensuring that required SCF outputs are available for the phonon run. Parameters ---------- name : str, optional Name of the directory for the phonon calculation (default: ``"ph"``). filename : str, optional Name of the phonon input file to copy (default: ``"ph.in"``). Workflow -------- 1. Calls `prepare_post_scf()` to create the directory and transfer files. 2. Ensures SCF outputs and PH input are in place for the calculation. Notes ----- - Assumes that a corresponding SCF calculation has already been completed. - Necessary for running phonon calculations using Quantum ESPRESSO. Example ------- >>> prepare_ph(name="ph_run", filename="si.ph.in") """ self.prepare_post_scf(name, filename)
[docs] def prepare_pp(self, name: str = 'pp', filename: str = 'pp.in'): """ Prepare a post-processing (PP) calculation directory. Copies the PP input file into the specified directory. Parameters ---------- name : str, optional Target directory name (default: "pp"). filename : str, optional PP input file name (default: "pp.in"). Example ------- >>> prepare_pp(name="pp_run", filename="si.pp.in") """ self.prepare_post_scf(name, filename)
[docs] def prepare_q2r(self, name: str = 'ph', filename: str = 'q2r.in'): """ Prepare a q2r calculation directory. Copies the q2r input file into the specified folder. Parameters ---------- name : str, optional Target directory (default: "ph"). filename : str, optional Input file name (default: "q2r.in"). Example ------- >>> prepare_q2r(name="ph_run", filename="si.q2r.in") """ self.run(f'{filename}', f'./{name}')
[docs] def prepare_dvscf_q2r(self, name: str = 'ph', filename: str = 'dvscf_q2r.in'): """ Prepare a dvscf_q2r calculation directory. Copies the dvscf_q2r input file into the specified folder. Parameters ---------- name : str, optional Target directory (default: "ph"). filename : str, optional Input file name (default: "dvscf_q2r.in"). Example ------- >>> prepare_dvscf_q2r(name="ph_run", filename="si.dvscf_q2r.in") """ self.run(f'{filename}', f'./{name}')
[docs] def prepare_postahc(self, name: str = 'ph', filename: str = 'postahc.in'): """ Prepare a postahc calculation directory. Copies the postahc input file into the specified folder. Parameters ---------- name : str, optional Target directory (default: "ph"). filename : str, optional Input file name (default: "postahc.in"). Example ------- >>> prepare_postahc(name="ph_run", filename="si.postahc.in") """ self.run(f'{filename}', f'./{name}')
[docs] def prepare_bands(self, name: str = 'bs', filename: str = 'bands.in'): """ Prepare a bandstructure (BANDS) calculation directory. Copies the BANDS input file into the specified folder. Parameters ---------- name : str, optional Target directory (default: "bs"). filename : str, optional Input file name (default: "bands.in"). Example ------- >>> prepare_bands(name="bs_run", filename="si.bands.in") """ self.run(f'{filename}', f'./{name}')
[docs] def prepare_matdyn(self, name: str = 'ph', filename: str = 'matdyn.in'): """ Prepare a matdyn calculation directory. Copies the matdyn input file into the specified folder. Parameters ---------- name : str, optional Target directory (default: "ph"). filename : str, optional Input file name (default: "matdyn.in"). Example ------- >>> prepare_matdyn(name="ph_run", filename="si.matdyn.in") """ self.run(f'{filename}', f'./{name}')
[docs] def prepare_dynmat(self, name: str = 'ph', filename: str = 'dynmat.in'): """ Prepare a dynmat calculation directory. Copies the dynmat input file into the specified folder. Parameters ---------- name : str, optional Target directory (default: "ph"). filename : str, optional Input file name (default: "dynmat.in"). Example ------- >>> prepare_dynmat(name="ph_run", filename="si.dynmat.in") """ self.run(f'{filename}', f'./{name}')
[docs] def prepare_nscf2supercond(self, name = 'nscf', filename = 'nscf2supercond.in'): """ Prepares an nscf2supercond calculation """ self.run_transfer(name) self.run(f'{filename}',f'./{name}')
[docs] def prepare_phdos(self, name = 'ph', filename = 'phdos.in'): """ Prepares a phdos calculation """ self.run_transfer(name) self.run(f'{filename}',f'./{name}')
[docs] def prepare_nscf_tetra(self, name = 'nscf_tetra', filename = 'nscf.in'): """ Prepares a nscf tetragonal calculation """ self.run_transfer(name) self.prepare_post_scf(name, filename)
[docs] def prepare_dos(self, name = 'nscf', filename = 'dos.in'): """ Prepares a dos calculation """ self.run_transfer(name) self.run(f'{filename}',f'./{name}')
[docs] def prepare_pdos(self, name = 'nscf', filename = 'pdos.in'): """ Prepares a pdos calculation """ self.run_transfer(name) self.run(f'{filename}', f'./{name}')
[docs] def prepare_fbw(self, name = 'fbw', filename = 'fbw.in'): """ Prepares FBW calculation """ self.prepare_post_epw(name, filename)
[docs] def prepare_outerbands(self, name = 'epw_outerbands', filename = 'epw_outerbands.in'): """ Prepares outerbands calculation """ self.prepare_post_epw(name, filename)
[docs] def prepare_fbw_mu(self, name = 'fbw_mu', filename = 'fbw_mu.in'): """ Prepares fbw mu calculation """ self.prepare_post_epw(name, filename)
[docs] def prepare_nesting(self, name = 'nesting', filename = 'nesting.in'): """ Prepares nesting calculation """ self.prepare_post_epw2(name, filename)
[docs] def prepare_phselfen(self, name = 'phselfen', filename = 'phselfen.in'): """ Prepares phselfen calculation """ self.prepare_post_epw2(name, filename)
[docs] def prepare_zg(self, name: str = 'zg', filename: str = 'zg.in'): """ Prepare a ZG calculation directory. This method sets up the folder and transfers all necessary input files for a ZG calculation, including SCF outputs, phonon dynamical matrices, force constants, and any additional files required. Parameters ---------- name : str, optional Target directory for the ZG calculation (default: "zg"). filename : str, optional ZG input file name (default: "zg.in"). Workflow -------- 1. Creates the directory if it doesn't exist. 2. Transfers files from previous SCF and PH calculations. 3. Copies the specified ZG input file. Example ------- >>> prepare_zg(name="zg_run", filename="si.zg.in") """ self.makedir(name) for file in self.files: self.run(file, f'./{name}') self.run(f'{filename}', f'./{name}') self.run(f'./{self.scf_fold}/' + str(self.prefix) + '.save', './zg') self.run(f'./{self.ph_fold}/_ph0', f'./{name}') self.run(f'./{self.ph_fold}/*dyn*', f'./{name}') self.run(f'./{self.ph_fold}/*.fc', f'./{name}') self.run(f'./{self.scf_fold}/scf.in', f'./{name}')
[docs] def prepare_eps(self, name: str = 'eps', filename: str = 'eps.in'): """ Prepare an epsilon.x calculation directory for QE. Transfers the NSCF outputs and wavefunction files required for dielectric function calculations using epsilon.x. Parameters ---------- name : str, optional Target directory for the epsilon calculation (default: "eps"). filename : str, optional Input file for epsilon.x (default: "eps.in"). Workflow -------- 1. Creates the target directory. 2. Transfers NSCF save folder and wavefunction files. 3. Copies the epsilon input file. Example ------- >>> prepare_eps(name="eps_run", filename="si.eps.in") """ self.makedir(name) self.run(f'{filename}', f'./{name}') self.run(f'./{self.nscf_fold}/' + str(self.prefix) + '.save', f'./{name}') self.run(f'./{self.nscf_fold}/*wfc*', f'./{name}')
[docs] def prepare_epw1(self, name: str = 'epw', filename: str = 'epw1.in'): """ Prepare EPW coarse-grid (epw1) calculation directory. Sets up the folder for the first EPW step using coarse k/q grids. Transfers necessary NSCF and phonon outputs, copies the EPW input file, and optionally performs post-processing. Parameters ---------- name : str, optional Target directory for the EPW calculation (default: "epw"). filename : str, optional Input file for EPW step 1 (default: "epw1.in"). Workflow -------- 1. Creates the directory if it doesn’t exist. 2. Transfers NSCF `.save` folder and phonon `_ph0` directory, or links them if `dolink=True`. 3. Copies dynamical matrices from the PH folder. 4. Copies the EPW input file. 5. Transfers additional files and runs post-processing (`pp()`). Example ------- >>> prepare_epw1(name="epw_run", filename="si.epw1.in") """ self.makedir(name) cwd = os.getcwd() if not self.dolink: self.run(f'./{self.nscf_fold}/' + str(self.prefix) + '.save', f'./{name}') self.run(f'./{self.ph_fold}/_ph0', f'./{name}') else: self.link(f'{cwd}/{self.nscf_fold}/{self.prefix}.save', f'./{name}') self.link(f'{cwd}/{self.ph_fold}/_ph0', f'{cwd}/{name}') self.run(f'./{self.ph_fold}/' + str(self.prefix) + '.dyn*', f'./{name}') self.run(f'{filename}', f'./{name}') self.run_transfer(name) self.changedir(name) self.pp() self.changedir('../')
[docs] def prepare_epw2(self, name: str = 'epw', filename: str = 'epw2.in'): """ Prepare EPW second-step (interpolated) calculation directory. Sets up the EPW coarse-to-fine interpolation step by transferring necessary files from the previous EPW calculation and copying the step 2 input file. Parameters ---------- name : str, optional Target directory for the EPW calculation (default: "epw"). filename : str, optional Input file for EPW step 2 (default: "epw2.in"). Workflow -------- 1. Transfers files from the previous EPW calculation. 2. Copies the EPW step 2 input file into the target directory. Example ------- >>> prepare_epw2(name="epw_run", filename="si.epw2.in") """ self.run_transfer(name) self.run(f'{filename}', f'./{name}')
[docs] def prepare_epw3(self, name: str = 'epw', filename: str = 'epw3.in'): """ Prepare EPW third-step calculation directory. Sets up the final EPW calculation step, typically for computing properties on dense k/q grids. Transfers files from the previous EPW step and copies the step 3 input file. Parameters ---------- name : str, optional Target directory for the EPW calculation (default: "epw"). filename : str, optional Input file for EPW step 3 (default: "epw3.in"). Workflow -------- 1. Transfers files from the previous EPW calculation. 2. Copies the EPW step 3 input file into the target directory. Example ------- >>> prepare_epw3(name="epw_run", filename="si.epw3.in") """ self.run_transfer(name) self.run(f'{filename}', f'./{name}')
[docs] def prepare_wannier(self, name = 'wannier', filename = ''): """ Prepares Wannier files """ self.makedir(name) self.run_transfer(name) self.run(f'./{self.nscf_fold}/'+str(self.prefix)+'.save', f'./{name}') self.run(str(self.prefix)+'.win', f'./{name}') self.run(str(self.prefix)+'.pw2wan', f'./{name}')
[docs] def prepare_dummy(self): """ Prepares a dummy run on any type """ self.makedir(self.folder_name) self.run_transfer(self.outfile) self.run(self.infile, self.outfile)
[docs] def prepare_post_scf(self, name, filename): """ Prepare the post-SCF environment for EPW calculations. This method sets up the necessary folder structure and transfers required files from a completed SCF calculation to a new working directory for subsequent EPW workflows. Parameters ---------- name : str Name of the target directory where post-SCF files will be prepared. filename : str Name of the input file or folder to be copied for the particular calculation. Workflow -------- 1. Creates a new directory ``name`` via ``makedir()``. 2. Transfers essential files using ``run_transfer(name)``. 3. Copies the specified SCF output or folder to the new directory using ``run()``. 4. Ensures the SCF save folder (``{prefix}.save``) is available in the post-SCF directory. Notes ----- - Assumes that a standard SCF calculation has already been completed. - This step is necessary to prepare the input files and folder structure for EPW or further post-processing calculations. Example ------- >>> prepare_post_scf(name="epw_workdir", filename="si.scf.out") """ self.makedir(name) self.run_transfer(name) self.run(f'{filename}', f'./{name}') self.run(f'./{self.scf_fold}/'+str(self.prefix)+'.save', f'./{name}')
[docs] def prepare_post_epw(self, name, filename): """ Prepares a post epw calculation outside epw folder """ self.makedir(f'{name}') self.link(f'../{self.epw_fold}/{self.prefix}.ephmat', f'{name}') self.run(f'./{self.epw_fold}/*.fmt', f'{name}') self.run(f'./{self.epw_fold}/{self.prefix}.a2f', f'{name}') self.run(f'./{self.epw_fold}/{self.prefix}.dos', f'{name}') self.run(f'{filename}', f'{name}')
[docs] def prepare_post_epw2(self, name, filename): """ Prepares a post epw calculation outside epw folder """ self.makedir(f'{name}') self.run(f'../{self.epw_fold}/{self.prefix}.epmatwp',f'{name}') self.run(f'./{self.epw_fold}/*.fmt', f'{name}') self.run(f'./{self.epw_fold}/{self.prefix}.ukk', f'{name}') self.run(f'./{self.ph_fold}/{self.prefix}._band.kpt', f'{name}') self.run(f'{filename}', f'{name}')
[docs] def prepare_abinit(self, name='abinit', filename = 'abi.abi'): """ Prepares an Abinit calculation """ self.makedir(f'{name}') self.run(f'{filename}',f'./{name}')
[docs] def prepare_vasp(self, name='vasp', filename = 'INCAR', structure = 'POSCAR'): """ Prepares an Abinit calculation """ self.makedir(f'{name}') self.run(f'{filename}', f'./{name}') self.run(f'KPOINTS', f'./{name}') self.run(f'{self.pseudo}', f'./{name}/POTCAR') self.run(f'{structure}', f'./{name}/POSCAR')
[docs] def prepare_vasp_nscf(self, name='bands', filename = 'INCAR', name_vasp = 'vasp', structure ='POSCAR'): """ Prepares an Abinit calculation """ fold = f'{name_vasp}/{name}' self.makedir(f'{fold}') self.run(f'{filename}', f'./{fold}') self.run(f'KPOINTS', f'./{fold}') self.run(f'{name_vasp}/WAVECAR', f'./{fold}') self.run(f'{name_vasp}/CHGCAR', f'./{fold}') self.run(f'{name_vasp}/POTCAR', f'./{fold}') self.run(f'{structure}', f'./{fold}/POSCAR') self.run_transfer(f'{fold}')
[docs] def run_transfer(self, name: str): """ Transfer a list of files into a specified directory. Iterates over the `self.files` list and copies each non-None file into the target directory using the class's `run` method. Parameters ---------- name : str Target directory where files should be copied. Example ------- >>> run_transfer("epw_run") """ for file in self.files: if file is not None: self.run(file, f'./{name}')
[docs] def run(self, infile, outfile): """ Execute the main preparation step by copying or linking files. This method handles the transfer of input files required for a given EPW or Quantum ESPRESSO calculation. Depending on whether symbolic linking is enabled (:attr:`dolink`), the method either copies the files or creates symbolic links. If script writing is enabled (i.e., ``self.writer.script_params['write_script'] == True``), the corresponding shell command is written to the run script instead of being executed immediately. **Parameters** ---------------- infile : str Path to the input file or directory to be copied or linked. outfile : str Destination path or filename for the prepared file. **Behavior** ------------- - If :attr:`dolink` is ``False`` → performs a deep copy using ``cp -r``. - If :attr:`dolink` is ``True`` → creates a symbolic link in the current working directory. - If ``self.writer.script_params['write_script']`` is enabled, the copy/link command is written to the script instead of being executed. **Examples** ------------- >>> prep = PyPrepare(prefix='si', pseudo='Si.pz-vbc.UPF') >>> prep.run('scf.in', 'workdir/scf.in') This copies ``scf.in`` into the working directory. """ if (self.dolink == False): cmd = 'cp -r ' + str(infile) + ' ' + str(outfile) if (self.writer.script_params['write_script'] == True): self.writer.write_execute(cmd) else: sp.Popen(cmd, shell=True).wait() else: cwd = os.getcwd() self.link(f'{cwd}/{infile}', f'{cwd}/{outfile}')
[docs] def pp(self): try: prefix=self.prefix.replace('\'','') if (self.writer.script_params['write_script'] == True): self.writer.write_pp(prefix) else: run_pp(prefix) except FileNotFoundError: prefix='\''+str(prefix)+'\'' run_pp(prefix)