PyABACUS#
PyABACUS is the official Python interface for ABACUS, providing a convenient way to run DFT calculations directly from Python scripts.
Installation#
From Source (Recommended)#
cd /path/to/abacus-develop/python/pyabacus
pip install -e .
With C++ Driver Support#
For full functionality including direct library calls (faster than subprocess), build ABACUS with Python bindings:
cmake -B build -DENABLE_PYABACUS=ON -DENABLE_LCAO=ON
cmake --build build -j8
pip install -e python/pyabacus
Note: The pyabacus package on PyPI is a different project and is NOT related to ABACUS. Please install from source as shown above.
Quick Start#
Basic SCF Calculation#
import pyabacus
# Run calculation from a directory containing INPUT, STRU, KPT files
result = pyabacus.abacus("./Si_scf/")
# Check results
print(f"Converged: {result.converged}")
print(f"Total energy: {result.etot_ev:.6f} eV")
print(result.summary())
Calculate Forces and Stress#
result = pyabacus.abacus(
"./Si_relax/",
calculate_force=True,
calculate_stress=True,
)
# Access forces (in eV/Angstrom)
if result.has_forces:
forces = result.forces_ev_ang
print(f"Max force: {forces.max():.6f} eV/Ang")
# Access stress tensor (in kbar)
if result.has_stress:
print(f"Stress tensor:\n{result.stress}")
Parallel Calculation#
# Run with MPI and OpenMP parallelization
result = pyabacus.abacus(
"./Si_scf/",
nprocs=4, # 4 MPI processes (mpirun -np 4)
nthreads=2, # 2 OpenMP threads (OMP_NUM_THREADS=2)
)
This is equivalent to running:
OMP_NUM_THREADS=2 mpirun -np 4 abacus
Silent Mode#
# Run without output
result = pyabacus.abacus("./Si_scf/", verbosity=0)
API Reference#
pyabacus.abacus()#
Main function for running ABACUS calculations.
def abacus(
input_dir: str = None,
*,
input_file: str = None,
stru_file: str = None,
kpt_file: str = None,
pseudo_dir: str = None,
orbital_dir: str = None,
output_dir: str = None,
calculate_force: bool = True,
calculate_stress: bool = False,
verbosity: int = 1,
nprocs: int = 1,
nthreads: int = 1,
) -> CalculationResult
Parameters:
Parameter | Type | Default | Description |
|---|---|---|---|
| str |
| Directory containing INPUT, STRU, KPT files |
| str | None | Explicit path to INPUT file |
| str | None | Explicit path to STRU file |
| str | None | Explicit path to KPT file |
| str | None | Directory containing pseudopotentials |
| str | None | Directory containing orbital files (LCAO) |
| str |
| Directory for output files |
| bool | True | Whether to calculate forces |
| bool | False | Whether to calculate stress tensor |
| int | 1 | Output level (0=silent, 1=normal, 2=verbose) |
| int | 1 | Number of MPI processes |
| int | 1 | Number of OpenMP threads |
Returns: CalculationResult object
CalculationResult#
Container for calculation results.
Attributes:
Attribute | Type | Description |
|---|---|---|
| bool | Whether SCF converged |
| int | Number of SCF iterations |
| float | Final charge density difference |
| float | Total energy (Ry) |
| float | Total energy (eV) |
| ndarray | Forces on atoms (nat, 3) in Ry/Bohr |
| ndarray | Forces in eV/Angstrom |
| ndarray | Stress tensor (3, 3) in kbar |
| float | Fermi energy (eV) |
| float | Band gap (eV) |
| int | Number of atoms |
| int | Number of atom types |
| int | Number of bands |
| int | Number of k-points |
| str | Path to output directory (OUT.$suffix) |
| str | Path to the main log file |
| dict | Dictionary of output files (filename -> path) |
Methods:
Method | Description |
|---|---|
| Return a formatted summary string |
| Dictionary of all energy components |
| Whether forces are available |
| Whether stress is available |
| Whether output directory exists |
| Get full path to specific output file |
| List all output file names |
Output File Tracking#
PyABACUS automatically tracks output files generated during calculations:
result = pyabacus.abacus("./Si_scf/")
# Check output directory
print(f"Output directory: {result.output_dir}")
print(f"Log file: {result.log_file}")
# List all output files
print("Output files:")
for filename in result.list_output_files():
print(f" {filename}")
# Get path to specific file
bands_file = result.get_output_file("BANDS_1.dat")
if bands_file:
# Read and process band structure data
import numpy as np
bands = np.loadtxt(bands_file)
Common Output Files#
File | Description |
|---|---|
| Main calculation log |
| Band structure data |
| Projected density of states |
| Charge density in cube format |
| Spin-up charge density |
| Spin-down charge density |
| Band eigenvalues and occupations |
| K-point information |
Convenience Functions#
run_scf()#
Alias for abacus() with default SCF parameters:
result = pyabacus.run_scf("./Si_scf/")
run_relax()#
Alias for abacus() with force calculation enabled:
result = pyabacus.run_relax("./Si_relax/")
Examples#
Energy vs. Lattice Constant#
import pyabacus
import numpy as np
lattice_constants = np.linspace(5.0, 5.5, 11)
energies = []
for a in lattice_constants:
# Modify STRU file with new lattice constant
# ... (file modification code)
result = pyabacus.abacus("./Si_eos/", verbosity=0)
energies.append(result.etot_ev)
# Plot equation of state
import matplotlib.pyplot as plt
plt.plot(lattice_constants, energies, 'o-')
plt.xlabel("Lattice constant (Ang)")
plt.ylabel("Energy (eV)")
plt.savefig("eos.png")
Parallel Batch Calculations#
import pyabacus
from pathlib import Path
# Run calculations for multiple systems with parallelization
systems = ["Si", "Ge", "C"]
results = {}
for system in systems:
input_dir = Path(f"./{system}_scf/")
if input_dir.exists():
result = pyabacus.abacus(
str(input_dir),
nprocs=4,
nthreads=2,
)
results[system] = {
"energy": result.etot_ev,
"converged": result.converged,
"bandgap": result.bandgap,
}
# Print summary
for system, data in results.items():
print(f"{system}: E={data['energy']:.4f} eV, gap={data['bandgap']:.2f} eV")
Troubleshooting#
ABACUS executable not found#
If you see “ABACUS executable not found”, ensure:
ABACUS is installed and in your PATH
Or build with C++ driver support (see Installation)
MPI not found#
If you see “mpirun/mpiexec not found” when using nprocs > 1:
Install MPI (OpenMPI or MPICH)
Ensure
mpirunormpiexecis in your PATHOr set
nprocs=1to run without MPI
Import errors#
If import pyabacus fails:
Ensure pyabacus is installed:
pip install pyabacusCheck Python version compatibility (Python 3.8+)
Calculation not converging#
Check the log file for details:
result = pyabacus.abacus("./problem_case/")
if not result.converged:
log_path = result.get_output_file("running_scf.log")
if log_path:
with open(log_path) as f:
print(f.read()[-2000:]) # Print last 2000 chars
Forces or stress not available#
Forces and stress are parsed from the ABACUS output log. Ensure:
cal_forceis set in your INPUT file for forcescal_stressis set in your INPUT file for stressThe calculation completed successfully