MACE-Field extends the MACE architecture to learn electric-field–dependent energy functionals for molecules and periodic materials. From a single scalar electric enthalpy, MACE-Field exposes dielectric response observables via automatic differentiation, ensuring derivative consistency by construction.
Status
This repository tracks development of MACE-Field while it is being upstreamed into MACE:
ACEsuit#1177
Given an electric enthalpy
-
Polarization
$\mathbf{P} = -\frac{1}{\Omega},\frac{\partial E}{\partial \mathbf{E}}$ -
Born effective charges (BECs)
$Z^\ast_{\kappa,\alpha\beta} = \frac{\partial P_\alpha}{\partial R_{\kappa,\beta}}$ -
Polarizability/susceptibility
$\chi_{\alpha\beta} = \frac{\partial P_\alpha}{\partial E_\beta}$
All quantities are derivative-consistent (Maxwell relations, acoustic sum rule, etc.) because they come from differentiating the same scalar.
MACE-Field supports:
- training from scratch, and
- fine-tuning existing MACE foundation models to become field-aware.
git clone https://github.com/mdi-group/mace-field.git
pip install ./maceMACE-Field preserves the standard MACE backbone and readout, but injects a uniform electric field (an 1o) into the latent equivariant features at each interaction layer.
Conceptually:
- Local atomic neighbourhoods are expanded into equivariant features (as in MACE/ACE).
- A global electric field couples to these features through symmetry-allowed tensor products.
- The model still outputs a scalar energy (electric enthalpy).
- Dielectric observables are obtained by exact differentiation of this scalar.
At zero field, MACE-Field reduces to standard MACE, allowing for the reuse of foundation weights.
MACE-Field uses ASE-readable datasets (typically extended XYZ / extxyz).
| Key | Shape | Units |
|---|---|---|
REF_energy |
scalar | eV |
REF_stress or REF_virials |
(6,) or (3,3) | eV/ų (stress) or eV (virials) |
REF_electric_field |
(3,) | V/Å |
REF_polarization |
(3,) | e/Ų |
REF_polarizability |
(3,3) or (9,) | e/(V·Å) |
| Key | Shape | Units |
|---|---|---|
REF_forces |
(N,3) | eV/Å |
REF_becs |
(N,3,3) | e |
Key names can be overridden via CLI/config flags.
Training uses the standard MACE CLI with:
--model MACEField--loss universal_field
python -m mace.scripts.run_train \
--model MACEField \
--name MACEField_model \
--train_file data/field_train.xyz \
--valid_fraction 0.2 \
--device cuda \
--r_max 5.0 \
--num_interactions 2 \
--num_channels 128 \
--max_L 1 \
--loss universal_field \
--energy_weight 1.0 \
--forces_weight 100.0 \
--polarization_weight 1.0 \
--becs_weight 100.0 \
--polarizability_weight 100.0Polarization is multi-valued under lattice translations. During training, MACE-Field compares folded polarization differences, which:
- avoids branch discontinuities,
- supports ferroelectric switching paths,
- preserves conservative/derivative definitions.
One of MACE-Field’s key strengths is foundation-model inheritance. You can fine-tune a pretrained MACE model (e.g. mace-mp-0b3) to add polarization/BEC/polarisability behaviour with minimal loss of energy/force accuracy.
name: mace-field-mp-0b3-mh
foundation_model: mace-mp-0b3-medium.model
model: MACEField
loss: universal_field
multiheads_finetuning: true
heads:
mp-dielectric:
train_file: becs-polarizabilities-train.xyz
valid_file: becs-polarizabilities-valid.xyz
mp-polarization:
train_file: polarizations-train.xyz
valid_file: polarizations-valid.xyz
pt_train_file: mp_replay.xyz
compute_forces: true
compute_polarization: true
compute_becs: true
compute_polarizability: trueRun:
torchrun --standalone --nproc_per_node=gpu \
python -m mace.scripts.run_train --config config.yamlfrom mace.calculators import MACECalculator
calc = MACECalculator(
model_path="MACEField.model",
model_type="MACEField",
electric_field=[0.0, 0.0, 0.02], # overrides per-structure field
device="cuda",
)
atoms.calc = calc
E = atoms.get_potential_energy()
P = atoms.calc.results["polarization"] # (3,)
Z = atoms.calc.results["becs"] # (N,3,3)
alpha = atoms.calc.results["polarizability"] # (3,3)mace_eval_configs \
--configs input.xyz \
--model MACEField.model \
--output output.xyz \
--compute_polarization \
--compute_becs \
--compute_polarizabilityatoms.info["REF_electric_field"] = [0.0, 0.0, 0.1]
# If you want a time-dependent field:
calc.electric_field = [0.0, 0.0, Ez_t]This enables workflows such as:
- ferroelectric hysteresis loops,
- finite-temperature dielectric response,
- IR / Raman response driven by field/strain protocols.
MACE-Field can be used in LAMMPS via the MLIAP interface (including Kokkos GPU builds). The simplest and most robust way to supply a uniform field is via an environment variable read by the MLIAP Python wrapper.
Example (Kokkos GPU, single GPU):
export MACE_EFIELD_MODE=env \
export MACE_EFIELD=0,0,0.3 \
lmp -k on g 1 -sf kk -pk kokkos gpu/aware on neigh half newton on -in in.lammps_macefieldThis feeds
MACE-Field’s LAMMPS ML-IAP wrapper can take a time-dependent electric field by updating the environment variable MACE_EFIELD every MD step from LAMMPS equal-style variables.
This approach keeps the wrapper simple: it only needs to re-read os.environ["MACE_EFIELD"] each step.
Define Ex, Ey, Ez in your in.lammps (here Ez is sinusoidal in step):
variable E0 equal 0.30
variable period equal 2000
variable Ex equal 0.0
variable Ey equal 0.0
variable Ez equal v_E0*sin(2.0*PI*step/v_period)
This Python snippet runs inside LAMMPS, reads the current values using extract_variable, and updates MACE_EFIELD:
python set_mace_efield here """
import os
from lammps import lammps
def set_mace_efield(lammps_ptr):
lmp = lammps(ptr=lammps_ptr)
ex = float(lmp.extract_variable("Ex", None, 0))
ey = float(lmp.extract_variable("Ey", None, 0))
ez = float(lmp.extract_variable("Ez", None, 0))
os.environ["MACE_EFIELD"] = f"{ex},{ey},{ez}"
"""
fix mace_efield all python/invoke 1 end_of_step set_mace_efield
What this does:
- LAMMPS evaluates
Ex/Ey/Ezfor the currentstep. - The Python hook converts them to floats and sets
MACE_EFIELD="ex,ey,ez". - The MACE-Field LAMMPS wrapper reads
MACE_EFIELDon the next force call and feeds it to the model.
If you use this code, please cite:
@misc{martin2025generallearningelectricresponse,
title={General Learning of the Electric Response of Inorganic Materials},
author={Martin, Bradley A. A. and Ganose, Alex M. and Kapil, Venkat and Li, Tingwei and Butler, Keith T.},
year={2025},
eprint={2508.17870},
archivePrefix={arXiv},
primaryClass={cond-mat.mtrl-sci}
}and the main MACE papers:
@inproceedings{Batatia2022mace,
title={{MACE}: Higher Order Equivariant Message Passing Neural Networks for Fast and Accurate Force Fields},
author={Batatia, Ilyes and Kovacs, David Peter and Simm, Gregor N. C. and Ortner, Christoph and Csanyi, Gabor},
booktitle={Advances in Neural Information Processing Systems},
year={2022}
}
@misc{Batatia2022Design,
title = {The Design Space of E(3)-Equivariant Atom-Centered Interatomic Potentials},
author = {Batatia, Ilyes and Batzner, Simon and Kov{'a}cs, D{'a}vid P{'e}ter and Musaelian, Albert and Simm, Gregor N. C. and Drautz, Ralf and Ortner, Christoph and Kozinsky, Boris and Cs{'a}nyi, G{'a}bor},
year = {2022},
eprint = {2205.06643},
archiveprefix = {arXiv}
}- MACE-Field: [email protected]
- MACE core: [email protected]
- Issues & feature requests: https://github.com/mdi-group/mace-field/issues