# W.I.P
import numpy as np
import argparse
import os
from EPWpy.default.default import *
from EPWpy.Abinit.write_Abinit import *
from EPWpy.Abinit.set_Abinit import *
from EPWpy.structure.lattice import *
from EPWpy.utilities.set_files import *
from EPWpy.utilities.k_gen import *
from EPWpy.EPWpy_prepare import PyPrepare
from EPWpy.EPWpy_run import PyRun
from EPWpy.structure.lattice import *
[docs]
class PyAbinit(SetDir, SetAbinit):
"""
High-level interface to the ABINIT simulation package.
The `PyAbinit` class provides automated setup, input generation, and
file transfer utilities for **ABINIT** calculations, with optional
interoperability with Quantum ESPRESSO (QE) workflows.
It inherits from:
- **SetDir** → manages directory creation and organization
- **SetAbinit** → provides parameter defaults and methods to define ABINIT input files
The class can be initialized with a `PyQE` object to enable transfer
of structural and pseudopotential data between QE and ABINIT runs.
Attributes
----------
system : str
Name of the material or system (used for directory naming).
code : str
Path to the ABINIT executable or script directory (default: current directory).
home : str
Current working directory when initialized.
env : str
Parallel execution environment command (e.g., "mpirun", "srun").
QE : PyQE
A `PyQE` instance providing data and pseudopotentials for ABINIT preparation.
verbosity : int
Controls the verbosity of logging (default: 1).
abinit_params : dict
Dictionary storing input parameters for ABINIT.
transfer_file : list
List of files to be copied or linked to the ABINIT run directory.
run_serial : bool
If True, runs ABINIT calculations in serial mode.
"""
def __init__(self, QE, type_input: dict = None, system: str = 'si',
code: str = '.', env: str = 'mpirun'):
"""
Initialize the ABINIT interface and optionally link to a QE workflow.
This constructor sets up a working environment for ABINIT calculations,
linking QE-generated pseudopotentials and structure files if a `PyQE`
object is provided. It also initializes default ABINIT parameters and
creates a working directory.
Parameters
----------
QE : PyQE
A `PyQE` class instance used to extract structural and pseudopotential
data from Quantum ESPRESSO runs.
type_input : dict, optional
Dictionary specifying input configuration for ABINIT.
Example:
``{"ecut": 60, "ngkpt": [6, 6, 6], "ixc": 11}``
system : str, optional
Name of the system (default: "si").
code : str, optional
Path to ABINIT executables (default: ".").
env : str, optional
Execution environment command (default: "mpirun").
Notes
-----
- Automatically creates a directory named after `system`.
- If the QE object has `pseudo_auto=True`, pseudopotentials are fetched
automatically from the QE configuration.
- Default ABINIT parameter dictionaries and transfer lists are initialized.
Example
-------
>>> from epwpy import PyQE, PyAbinit
>>> qe = PyQE({"type": "scf"}, system="si")
>>> ab = PyAbinit(qe, {"ecut": 40, "ngkpt": [6,6,6]}, system="si")
>>> ab.write_input() # Generates ABINIT input file
"""
if type_input is None:
type_input = {}
self.system = system
self.code = code
self.home = os.getcwd()
self.env = env
os.system('mkdir ' + self.system)
self.QE = QE
self.verbosity = 1
# Material and run defaults
self.abinit_params = {}
self.transfer_file = []
# Run settings
self.run_serial = True
if self.QE.pseudo_auto:
self.get_pseudo(type_input)
[docs]
def abi(self, input_abi=None, name='abi'):
"""
Prepare and write an ABINIT input file.
This method serves as the main interface for constructing ABINIT
input files. It takes a dictionary of ABINIT keywords and parameters,
initializes the working environment, and writes the formatted input
file to disk.
Parameters
----------
input_abi : dict, optional
Dictionary containing ABINIT input keywords and values.
Each key should correspond to a valid ABINIT variable.
Example:
``{"ecut": 50, "ngkpt": [6,6,6], "nstep": 100}``
name : str, optional
Name of the ABINIT input file to write (default: "abi").
Notes
-----
- ABINIT supports multi-step workflows in a **single input file**,
so care must be taken when defining `input_abi` to avoid conflicts
between different calculation stages.
- The function internally calls:
1. `set_work()` → sets the current working directory.
2. `set_abi()` → updates ABINIT parameters.
3. `WriteAbinitFiles()` → handles file generation.
4. `set_home()` → restores the base working directory.
Example
-------
>>> from epwpy import PyAbinit
>>> ab = PyAbinit(qe, {"ecut": 40, "ngkpt": [6,6,6]}, system="si")
>>> ab.abi({"ecut": 50, "nstep": 50}, name="scf")
# Generates 'scf.in' for ABINIT
"""
if input_abi is None:
input_abi = {}
self.set_work()
self.set_abi(input_abi)
self.writer = WriteAbinitFiles(self.abinit_params)
self.writer.write_abi(name)
self.set_home()
[docs]
def get_pseudo(self, type_input):
"""
Gets the pseudos for abinit
"""
print('Downloading pseudo for Abinit')
self.lattice = lattice({})
self.lattice.atomic_species = self.QE.pw_atomic_species
self.lattice.pseudo_typ = 'PBE-FR-PDv0.4'
self.lattice.pseudo_orbitals = ['','_r','-sp_r','-d_r','-s_r','-sp','-d','-s']
self.lattice.pseudo_end = 'psp8'
if ('pseudo_type' in type_input.keys()):
print('setting pseudo type to:', type_input['pseudo_type'])
self.lattice.pseudo_typ = type_input['pseudo_type']
if ('pseudo_orbitals' in type_input.keys()):
self.lattice.pseudo_orbitals = type_input['pseudo_orbitals']
self.lattice.atomic_species = self.QE.pw_atomic_species['atomic_species']
pseudo, pseudo_dir = self.lattice.get_pseudo()
print(pseudo,pseudo_dir)
self.QE.pw_control['pseudo_dir']='\''+pseudo_dir+'\''
self.QE.pw_atomic_species['pseudo'] = pseudo
self.pseudo = self.QE.pw_atomic_species['pseudo']
[docs]
def prepare(self, procs=1, type_run='abinit', name=None, infile=None, transfer_file=None):
"""
This function prepares Abinit files
"""
if transfer_file is None:
transfer_file = []
if (len(transfer_file) != 0):
for file in transfer_file:
self.transfer_file.append(file)
if infile is None:
infile = f'{type_run}.in'
if name is None:
name = type_run
self.prep=PyPrepare(self.prefix,self.pseudo,self.transfer_file)
self.set_work()
self.set_home()
if (type_run == 'abinit'):
self.set_work()
self.prep.prepare_abinit(name, infile)
self.set_home()
[docs]
def run(self, procs, type_run='abinit', infile=None, name=None, parallelization=None, flow_parallelization=None, flavor='cplx'):
if flow_parallelization is None:
flow_parallelization = []
"""
Run utility of EPWpy
"""
self.run_Abi=PyRun(procs,self.env,self.code)
self.run_Abi.serial = self.run_serial
self.procs = procs
self.run_Abi.verbosity = self.verbosity
self.run_Abi.proc_set = None
#self.flow_parallelization = flow_parallelization
if (parallelization != None):
if (self.verbosity > 1):
print('parallelization chosen: ', parallelization)
self.run_Abi.proc_set = parallelization
if (type_run=='abinit'):
self.set_work()
self.run_Abi.run_abinit(folder='abinit',name=infile)
self.set_home()
[docs]
def QE2Abi(QE_class):
pass