Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/abacusagent/constant.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,15 @@
RY_TO_EV = 13.60569253
THZ_TO_K = 47.9924

# Physical constants for effective mass calculation
HBAR_EV_S = 6.582119569e-16 # ℏ in eV·s
HBAR_J_S = 1.054571817e-34 # ℏ in J·s
ELECTRON_MASS_KG = 9.1093837015e-31 # m_e in kg
ANGSTROM_TO_M = 1e-10 # Å to m conversion
EV_TO_J = 1.602176634e-19 # eV to J conversion

# Derived constant: m*/m_e = EFFECTIVE_MASS_FACTOR / curvature
# where curvature is d²E/dk² in eV/Å⁻²
# Formula: m* = ℏ² / (m_e * d²E/dk²)
# Converting units: ℏ in J·s, m_e in kg, curvature in eV/Å⁻²
EFFECTIVE_MASS_FACTOR = (HBAR_J_S**2) / (ELECTRON_MASS_KG * EV_TO_J * ANGSTROM_TO_M**2)
109 changes: 108 additions & 1 deletion src/abacusagent/modules/band.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from pathlib import Path
from typing import Literal, Dict, List, Union
from typing import Literal, Dict, List, Union, Optional

from abacusagent.init_mcp import mcp
from abacusagent.modules.submodules.band import abacus_cal_band as _abacus_cal_band
from abacusagent.modules.submodules.band import abacus_cal_effective_mass as _abacus_cal_effective_mass

@mcp.tool()
def abacus_cal_band(abacus_inputs_dir: Path,
Expand Down Expand Up @@ -43,3 +44,109 @@ def abacus_cal_band(abacus_inputs_dir: Path,
"""
return _abacus_cal_band(abacus_inputs_dir, mode, kpath, high_symm_points, energy_min, energy_max, insert_point_nums)


@mcp.tool()
def abacus_cal_effective_mass(
band_calc_dir: Path,
calculation_points: Union[Literal["auto", "extrema"], List[Dict[str, Union[str, List[float], int]]]] = "auto",
fitting_window: int = 5,
directions: List[str] = ["kx", "ky", "kz"],
band_indices: Optional[List[int]] = None,
energy_range: Optional[List[float]] = None,
output_dir: Optional[Path] = None
) -> Dict[str, Union[List, Path, Dict, str]]:
"""
Calculate effective mass from band structure using parabolic fitting.

This function analyzes band structure data to compute effective masses at band extrema
(VBM/CBM) or user-specified k-points. It uses parabolic fitting E(k) = E₀ + a(k-k₀)²
to extract the band curvature d²E/dk², from which the effective mass is calculated
using m* = ℏ²/(d²E/dk²).

Args:
band_calc_dir: Path to directory containing band calculation results. Must have
BANDS_*.dat files from ABACUS NSCF or PYATB calculation.
calculation_points: Where to calculate effective mass. Options:
- "auto": Automatically detect VBM and CBM (default)
- "extrema": Find all local extrema within energy_range
- List of dicts: User-specified points, each dict contains:
* "type": "kpoint" or "high_symmetry"
* "coords": [kx, ky, kz] for "kpoint" type
* "label": "G", "M", "K", etc. for "high_symmetry" type
* "band_index": (optional) specific band index
fitting_window: Number of k-points on each side of extremum for parabolic
fitting. Larger values give smoother fits but may miss non-parabolic
behavior. Default: 5 (total 11 points used).
directions: Directions for effective mass calculation. Currently only "kpath"
direction (along the band path) is implemented. Default: ["kx", "ky", "kz"].
band_indices: Specific band indices to analyze. If None, analyzes all bands
near Fermi level. Default: None.
energy_range: [E_min, E_max] in eV relative to Fermi level for extrema
detection. Only used when calculation_points="extrema". Default: [-2, 2].
output_dir: Directory for output files (plots and JSON). If None, uses
band_calc_dir. Default: None.

Returns:
Dict containing:
- effective_mass_results: List of dicts with effective mass data for each point.
Each dict contains:
* point_info: Band index, k-point index, coordinates, energy, extrema type
* effective_masses: m* values in units of electron mass (m_e) for each direction
* fitting_data: k-distances, energies, and fitted values for plotting
- effective_mass_json: Path to JSON file with detailed results
- effective_mass_plots: List of paths to visualization plots (one per point + summary)
- summary: Dict with statistics:
* electron_effective_mass: {average, min, max, std} for CBM
* hole_effective_mass: {average, min, max, std} for VBM
- message: Success or error message

Raises:
RuntimeError: If band data files are not found or cannot be read
ValueError: If calculation_points format is invalid

Examples:
# Calculate effective mass at VBM and CBM automatically
result = abacus_cal_effective_mass("/path/to/band/calc")
print(f"Electron m* = {result['summary']['electron_effective_mass']['average']:.3f} m_e")

# Calculate at all extrema within ±3 eV of Fermi level
result = abacus_cal_effective_mass(
"/path/to/band/calc",
calculation_points="extrema",
energy_range=[-3.0, 3.0]
)

# Calculate at specific k-point
result = abacus_cal_effective_mass(
"/path/to/band/calc",
calculation_points=[
{"type": "kpoint", "coords": [0.0, 0.0, 0.0], "band_index": 10}
]
)

# Calculate at high symmetry point
result = abacus_cal_effective_mass(
"/path/to/band/calc",
calculation_points=[
{"type": "high_symmetry", "label": "G"}
]
)

Notes:
- Effective mass is reported in units of electron mass (m_e = 9.109×10⁻³¹ kg)
- Positive curvature → positive effective mass (electron-like)
- Negative curvature → negative effective mass (hole-like)
- Reported values are absolute values |m*|
- R² < 0.90 indicates poor parabolic fit; consider denser k-mesh
- For accurate results, use insert_point_nums ≥ 30 in band calculation
"""
return _abacus_cal_effective_mass(
band_calc_dir,
calculation_points,
fitting_window,
directions,
band_indices,
energy_range,
output_dir
)

Loading