-
Notifications
You must be signed in to change notification settings - Fork 360
Add MACEField: train, finetune, and infer electric-field responses (polarization, BECs, polarizability) from energy #1177
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…to AtomicData class
… with option for this loss.
…nd most functions
…h dim separately.
… not using the unit electric field vector for the angular components. Whilst I was at it, I also added a radial component for the electric field for cases where it is not zero.
… 0.01 eV/A a la VASP.
…tion lattice and make it modulo the polarisation quantum).
…e --device choices so I can use --device="cuda:1"
…e use of foundation models.
Added detailed documentation for MACE-Field, including data format, required labels, and training instructions.
|
@ilyes319 Sorry for the delay on this - finally got the tests done. They appear to pass locally on my end. There are a few branch conflicts that need to be resolved. I had a look:
Let me know what you think and if you need anything more from me. Cheers, |
…r (for num_atoms)
|
Okay, fixed up the tests. Everything now seems green... I am not sure if some tests are timing out. I extended the LAMMPs code to work with MACEField, so now it can be used to do MD with a static or time-dependent electric field. The LAMMPS: constant electric fieldExample (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 LAMMPS: time-dependent electric field (MACE-Field via env var)MACE-Field’s LAMMPS ML-IAP wrapper can take a time-dependent electric field by updating the environment variable This approach keeps the wrapper simple: it only needs to re-read 1) Define the field as LAMMPS equal-style variablesDefine 2) Push
|
|
Example LAMMPS-MLIAP for polarisation hysteresis for BTO - oscillatory electric field simulation for 10ps for 16875 atom supercell. Ran on 4 L4 Nvidia gpus. |
Add MACEField: train, finetune, and infer electric-field responses (polarization, BECs, polarizability) from energy
Summary
This PR introduces
MACEField— a uniform-electric-field extension that injects an external field (o3.Irreps("1o")) into MACE’s latent node features. By differentiating the energy w.r.t. field and atomic displacements, the model exposes autograd-consistent responses:Polarization:$\qquad \displaystyle \mathbf P = -\frac{1}{\Omega},\frac{\partial E}{\partial \mathbf E} \quad [\mathbf P:\ \mathrm{e}/Å^2]$
Born effective charges (BECs):$\qquad \displaystyle Z_{\kappa,\alpha\beta} = \Omega,\frac{\partial P_\beta}{\partial u_{\kappa,\alpha}} \qquad [Z:\ \mathrm{e}]$
Polarizability / susceptibility:$\qquad \displaystyle \chi_{\alpha\beta} = \frac{\partial P_\alpha}{\partial E_\beta} = -\frac{1}{\Omega},\frac{\partial^2 E}{\partial E_\alpha,\partial E_\beta} \quad [\chi:\ \mathrm{e}/(\mathrm{V}\cdotÅ)]$
Heads are opt-in, work with batching and per-graph fields, and can be used from scratch or to finetune a foundation model to be field-aware.
What’s new
MACEFieldinjects a uniform field ("1o") and mixes it via equivariant tensor products + linear mixing.polarization,becs,polarizability(when requested) alongside E/F/σ; supports per-graph fields.run_train.py; batch inference viamace_eval_configs; plotting during training shows new outputs; ASE calculator example included.Electric field source
--electric-fieldin CLI as optional input to model) — takes precedence if provided — used mainly for inference and MD.xyz(info["REF_electric_field"]) — used mainly for trainingLoss function (universal_field) — what’s optimized
We use a multi-task objective
UniversalFieldLossthat combines the standard E/F/σ terms as inUniversalLosswith field-response heads.Polarization folding — resolving Berry-phase branches
As polarization in a periodic crystal is multi-valued: during training we fold the polarization difference onto the nearest branch before computing the loss:
Use$\Delta \mathbf{P}^{\text{fold}}$ in $\mathcal{L}_P$ . This makes the objective branch-invariant and avoids discontinuities across ferroelectric paths or mixed-cell datasets.
Example training script (CLI)
Targets & shapes (convention):
info["REF_polarization"]→[3](e/Ų) ·arrays["REF_becs"]→[n_atoms,3,3](e) ·info["REF_polarizability"]→[3,3](e/(V·Å))Weighting tips: start with
forces≈100,polarization≈1,becs≈50–150,polarizability≈50–150Field source: prefer per-frame
info["REF_electric_field"]in the dataset; pass an explicit field only if you want to override such as during finite-field MDPlotting: polarization, becs and polarizability errors and parities show alongside energy, forces and stress during training with
--plot=TrueFinetune a foundation model to be field-aware
MACEFieldcan be used to finetune existing foundation models to be "field aware".For example, with heterogeneous data where our datasets are:
becs-polarizabilities.xyzhas just becs and polarizability data (useconfig_energy_weight=0.0,config_forces_weight=0.0,config_stress_weight=0.0andconfig_polarization_weight=0.0).polarizations.xyzhas just polarization data (useconfig_energy_weight=0.0,config_forces_weight=0.0,config_stress_weight=0.0,config_becs_weight=0.0andconfig_polarizability_weight=0.0)we can do multiheaded finetuning on the
mp-0b3model usingMACEFieldwith a config:Run:
torchrun --standalone --nproc_per_node="gpu" ./mace/cli/run_train.py --config config.yamlNote: Still experimental. Maybe interesting to investigate frozen weights, initializing new MACEField weights as 0 or small, etc.
Inference
Batch CLI —
mace_eval_configsUses per-frame
info["REF_electric_field"]unless an explicit field option is provided via--electric-field [E_x, E_y, E_z](explicit overrides). Writes predictions back to the XYZ.Finite-field Molecular Dynamics
ASE calculator
For time-dependent electric field, we can use
calc.electric_field = [E_x, E_z, E_z]to update through logger.Data format
Extended-XYZ per frame:
info["REF_electric_field"]as[Ex,Ey,Ez]; optional labelsinfo["REF_polarization"](e/Ų),info["REF_polarizability"](e/(V·Å)), andarrays["REF_becs"](e).Implementation highlights
Irreps("1o"), mixed via equivariant tensor products + linear mixing.Limitations / TODO
TL;DR: Learn and evaluate electric-field responses in MACE. Train from scratch or finetune a foundation model; run batch inference via
mace_eval_configsor interactively finite-field MD via ASE — with explicit field overrides, per-graph fields, and polarization folding in loss.