Tasks Module¶
The tasks module contains the implementation of various simulation tasks.
Static Calculations¶
calculate_single_point¶
Calculate energy, forces, and stress for a structure.
Parameters:
atoms(Atoms): ASE Atoms objectcalculator(Calculator): ASE calculator
Returns: dict with energy, forces, stress, etc.
Optimization¶
Static calculations: single-point energy and structure optimization
optimize_structure ¶
optimize_structure(atoms: Atoms, calculator, fmax: float = 0.05, steps: int = 500, optimizer: str = 'LBFGS', optimize_cell: bool = False, trajectory: Optional[str] = None, logfile: Optional[str] = None) -> Atoms
Optimize atomic structure.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
atoms
|
Atoms
|
Input ASE Atoms object |
required |
calculator
|
ASE calculator |
required | |
fmax
|
float
|
Force convergence criterion (eV/Å) |
0.05
|
steps
|
int
|
Maximum optimization steps |
500
|
optimizer
|
str
|
Optimizer name ("LBFGS", "BFGS", "FIRE") |
'LBFGS'
|
optimize_cell
|
bool
|
Whether to optimize cell parameters |
False
|
trajectory
|
Optional[str]
|
Path to save optimization trajectory |
None
|
logfile
|
Optional[str]
|
Path to save optimization log |
None
|
Returns:
| Type | Description |
|---|---|
Atoms
|
Optimized Atoms object |
Source code in src/mace_inference/tasks/static.py
optimize_structure¶
def optimize_structure(
atoms: Atoms,
calculator: Calculator,
fmax: float = 0.05,
steps: int = 500,
optimizer: str = "BFGS",
relax_cell: bool = False,
fix_symmetry: bool = False,
trajectory: Optional[str] = None
) -> dict
Optimize atomic positions and cell.
Molecular Dynamics¶
Molecular dynamics simulations
run_nvt_md ¶
run_nvt_md(atoms: Atoms, calculator, temperature_K: float = 300, timestep: float = 1.0, steps: int = 1000, trajectory: Optional[str] = None, logfile: Optional[str] = None, log_interval: int = 100, taut: Optional[float] = None, friction: Optional[float] = None, progress_callback: Optional[Callable[[int, int], None]] = None) -> Atoms
Run NVT molecular dynamics using Langevin thermostat.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
atoms
|
Atoms
|
Input ASE Atoms object |
required |
calculator
|
ASE calculator |
required | |
temperature_K
|
float
|
Target temperature (K) |
300
|
timestep
|
float
|
Time step (fs) |
1.0
|
steps
|
int
|
Number of MD steps |
1000
|
trajectory
|
Optional[str]
|
Trajectory file path |
None
|
logfile
|
Optional[str]
|
Log file path |
None
|
log_interval
|
int
|
Logging interval (steps) |
100
|
taut
|
Optional[float]
|
Temperature coupling time (fs) - alternative to friction |
None
|
friction
|
Optional[float]
|
Friction coefficient (1/fs) |
None
|
progress_callback
|
Optional[Callable[[int, int], None]]
|
Optional callback function(current_step, total_steps) |
None
|
Returns:
| Type | Description |
|---|---|
Atoms
|
Final Atoms object after MD |
Examples:
>>> def progress(current, total):
... print(f"MD progress: {current}/{total} steps ({100*current/total:.1f}%)")
>>> atoms = run_nvt_md(atoms, calc, steps=1000, progress_callback=progress)
Source code in src/mace_inference/tasks/dynamics.py
run_npt_md ¶
run_npt_md(atoms: Atoms, calculator, temperature_K: float = 300, pressure_GPa: float = 0.0, timestep: float = 1.0, steps: int = 1000, trajectory: Optional[str] = None, logfile: Optional[str] = None, log_interval: int = 100, taut: Optional[float] = None, taup: Optional[float] = None, compressibility_au: Optional[float] = None, progress_callback: Optional[Callable[[int, int], None]] = None) -> Atoms
Run NPT molecular dynamics using NPT ensemble.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
atoms
|
Atoms
|
Input ASE Atoms object |
required |
calculator
|
ASE calculator |
required | |
temperature_K
|
float
|
Target temperature (K) |
300
|
pressure_GPa
|
float
|
Target pressure (GPa) |
0.0
|
timestep
|
float
|
Time step (fs) |
1.0
|
steps
|
int
|
Number of MD steps |
1000
|
trajectory
|
Optional[str]
|
Trajectory file path |
None
|
logfile
|
Optional[str]
|
Log file path |
None
|
log_interval
|
int
|
Logging interval (steps) |
100
|
taut
|
Optional[float]
|
Temperature coupling time (fs) |
None
|
taup
|
Optional[float]
|
Pressure coupling time (fs) |
None
|
compressibility_au
|
Optional[float]
|
Isothermal compressibility (atomic units) |
None
|
progress_callback
|
Optional[Callable[[int, int], None]]
|
Optional callback function(current_step, total_steps) |
None
|
Returns:
| Type | Description |
|---|---|
Atoms
|
Final Atoms object after MD |
Examples:
>>> def progress(current, total):
... print(f"NPT MD: {current}/{total} steps")
>>> atoms = run_npt_md(atoms, calc, temperature_K=300, pressure_GPa=0.1,
... steps=1000, progress_callback=progress)
Source code in src/mace_inference/tasks/dynamics.py
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | |
run_nvt¶
def run_nvt(
atoms: Atoms,
calculator: Calculator,
temperature: float,
timestep: float = 1.0,
steps: int = 1000,
friction: float = 0.01,
save_interval: int = 10,
log_interval: int = 100
) -> dict
Run NVT molecular dynamics with Langevin thermostat.
run_npt¶
def run_npt(
atoms: Atoms,
calculator: Calculator,
temperature: float,
pressure: float,
timestep: float = 1.0,
steps: int = 1000,
save_interval: int = 10,
log_interval: int = 100
) -> dict
Run NPT molecular dynamics with Berendsen barostat.
Phonon Calculations¶
Phonon calculations and thermal properties
ase_to_phonopy ¶
Convert ASE Atoms to Phonopy Atoms.
calculate_phonon ¶
calculate_phonon(atoms: Atoms, calculator: Calculator, supercell_matrix: Union[List[int], ndarray, int] = 2, displacement: float = 0.01, mesh: Optional[List[int]] = None, output_dir: Optional[str] = None) -> PhononResult
Calculate phonon properties.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
atoms
|
Atoms
|
Input ASE Atoms object |
required |
calculator
|
Calculator
|
ASE calculator |
required |
supercell_matrix
|
Union[List[int], ndarray, int]
|
Supercell size (e.g., [2, 2, 2] or 2) |
2
|
displacement
|
float
|
Atomic displacement distance (Å) |
0.01
|
mesh
|
Optional[List[int]]
|
k-point mesh for phonon DOS (default: [20, 20, 20]) |
None
|
output_dir
|
Optional[str]
|
Output directory for phonon files |
None
|
Returns:
| Type | Description |
|---|---|
PhononResult
|
Dictionary containing phonon object and basic properties |
Source code in src/mace_inference/tasks/phonon.py
calculate_thermal_properties ¶
calculate_thermal_properties(phonon: Phonopy, t_min: float = 0, t_max: float = 1000, t_step: float = 10) -> ThermalPropertiesResult
Calculate thermal properties from phonon object.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
phonon
|
Phonopy
|
Phonopy object with force constants |
required |
t_min
|
float
|
Minimum temperature (K) |
0
|
t_max
|
float
|
Maximum temperature (K) |
1000
|
t_step
|
float
|
Temperature step (K) |
10
|
Returns:
| Type | Description |
|---|---|
ThermalPropertiesResult
|
Dictionary with thermal properties |
Source code in src/mace_inference/tasks/phonon.py
calculate_phonon¶
def calculate_phonon(
atoms: Atoms,
calculator: Calculator,
supercell: Tuple[int, int, int] = (2, 2, 2),
delta: float = 0.01,
mesh: Tuple[int, int, int] = (20, 20, 20)
) -> dict
Calculate phonon frequencies and density of states.
calculate_thermal_properties¶
def calculate_thermal_properties(
phonon: Phonopy,
t_min: float = 0,
t_max: float = 1000,
t_step: float = 10
) -> dict
Calculate thermal properties from phonon data.
Mechanical Properties¶
Mechanical properties calculations
calculate_bulk_modulus ¶
calculate_bulk_modulus(atoms: Atoms, calculator: Calculator, n_points: int = 11, scale_range: Tuple[float, float] = (0.95, 1.05), eos_type: str = 'birchmurnaghan') -> BulkModulusResult
Calculate bulk modulus using equation of state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
atoms
|
Atoms
|
Input ASE Atoms object |
required |
calculator
|
Calculator
|
ASE calculator |
required |
n_points
|
int
|
Number of volume points |
11
|
scale_range
|
Tuple[float, float]
|
Volume scaling range (min_scale, max_scale) |
(0.95, 1.05)
|
eos_type
|
str
|
Equation of state type ("birchmurnaghan", "murnaghan", etc.) |
'birchmurnaghan'
|
Returns:
| Type | Description |
|---|---|
BulkModulusResult
|
Dictionary with equilibrium volume, energy, and bulk modulus |
Source code in src/mace_inference/tasks/mechanics.py
calculate_elastic_constants ¶
calculate_elastic_constants(atoms: Atoms, calculator: Calculator, delta: float = 0.01, symmetry: str = 'auto') -> Dict[str, Any]
Calculate elastic constants using stress-strain relationships.
Uses finite differences to compute the elastic tensor from stress responses to applied strains.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
atoms
|
Atoms
|
Input ASE Atoms object (should be relaxed) |
required |
calculator
|
Calculator
|
ASE calculator |
required |
delta
|
float
|
Strain magnitude for finite differences |
0.01
|
symmetry
|
str
|
Crystal symmetry ("auto", "cubic", "hexagonal", "orthorhombic", "full") |
'auto'
|
Returns:
| Type | Description |
|---|---|
Dict[str, Any]
|
Dictionary with elastic constants in GPa |
Example
result = calculate_elastic_constants(atoms, calculator) print(f"C11 = {result['C'][0,0]:.1f} GPa") print(f"Bulk modulus = {result['K_V']:.1f} GPa")
Source code in src/mace_inference/tasks/mechanics.py
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | |
calculate_bulk_modulus¶
def calculate_bulk_modulus(
atoms: Atoms,
calculator: Calculator,
scale_range: Tuple[float, float] = (0.95, 1.05),
n_points: int = 7,
eos: str = "birchmurnaghan"
) -> dict
Calculate bulk modulus by fitting equation of state.
Adsorption¶
Adsorption energy and coordination analysis
calculate_adsorption_energy ¶
calculate_adsorption_energy(framework: Atoms, adsorbate: Union[str, Atoms], site_position: List[float], calculator: Calculator, optimize: bool = True, fmax: float = 0.05, fix_framework: bool = True) -> AdsorptionResult
Calculate gas adsorption energy in framework (MOF, zeolite, etc.).
E_ads = E(framework+adsorbate) - E(framework) - E(adsorbate)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
framework
|
Atoms
|
Framework structure (MOF, zeolite, etc.) as ASE Atoms |
required |
adsorbate
|
Union[str, Atoms]
|
Adsorbate molecule name (e.g., "CO2") or Atoms object |
required |
site_position
|
List[float]
|
Adsorption site position [x, y, z] |
required |
calculator
|
Calculator
|
ASE calculator |
required |
optimize
|
bool
|
Whether to optimize the adsorption complex |
True
|
fmax
|
float
|
Force convergence for optimization |
0.05
|
fix_framework
|
bool
|
Whether to fix framework atoms during optimization |
True
|
Returns:
| Type | Description |
|---|---|
AdsorptionResult
|
Dictionary with adsorption energy and structures |
Source code in src/mace_inference/tasks/adsorption.py
analyze_coordination ¶
analyze_coordination(atoms: Atoms, metal_indices: Optional[List[int]] = None, cutoff_multiplier: float = 1.2) -> CoordinationResult
Analyze coordination environment around metal centers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
atoms
|
Atoms
|
ASE Atoms object |
required |
metal_indices
|
Optional[List[int]]
|
Indices of metal atoms (auto-detect if None) |
None
|
cutoff_multiplier
|
float
|
Multiplier for natural cutoff radii |
1.2
|
Returns:
| Type | Description |
|---|---|
CoordinationResult
|
Dictionary with coordination analysis |
Source code in src/mace_inference/tasks/adsorption.py
find_adsorption_sites ¶
find_adsorption_sites(atoms: Atoms, grid_spacing: float = 0.5, probe_radius: float = 1.2, min_distance: float = 2.0, energy_cutoff: float = None) -> List[np.ndarray]
Find potential adsorption sites in porous structure using grid-based search.
This function identifies void spaces in the structure that could accommodate adsorbate molecules by searching for grid points that are sufficiently far from all atoms.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
atoms
|
Atoms
|
ASE Atoms object (porous structure like MOF, zeolite) |
required |
grid_spacing
|
float
|
Grid spacing for site search (Å) |
0.5
|
probe_radius
|
float
|
Minimum distance from any atom to be considered a void (Å) |
1.2
|
min_distance
|
float
|
Minimum distance between identified sites (Å) |
2.0
|
energy_cutoff
|
float
|
Optional energy cutoff for filtering sites (not implemented) |
None
|
Returns:
| Type | Description |
|---|---|
List[ndarray]
|
List of potential adsorption site positions [x, y, z] |
Example
sites = find_adsorption_sites(mof, probe_radius=1.5) print(f"Found {len(sites)} potential sites") for site in sites[:5]: ... print(f" Site at {site}")
Source code in src/mace_inference/tasks/adsorption.py
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 | |
calculate_adsorption_energy¶
def calculate_adsorption_energy(
framework: Atoms,
adsorbate: Atoms,
site_position: List[float],
calculator: Calculator,
optimize: bool = True,
fmax: float = 0.05,
fix_framework: bool = True
) -> dict
Calculate adsorption energy of a gas molecule in a framework.
The adsorption energy is calculated as: