Skip to content

fix(generation): spin-polarised inputs start every moment at zero #177

Description

@junwen94

What is emitted

generation.py:224-227 is the whole of the magnetic input:

if advice.spin_orbit.enabled:
    lines.extend(["  noncolin = .true.", "  lspinorb = .true."])
elif advice.magnetism.spin_polarized:
    lines.append("  nspin = 2")

starting_magnetization appears nowhere in the repository, and neither do
angle1 or angle2.

Why that is a problem

The collinear branch starts every species at zero moment. Quantum ESPRESSO
defaults starting_magnetization to 0. With nspin = 2 and no starting
moments the two spin channels are identical, so the SCF has no symmetry to
break and normally settles on the non-magnetic solution. The input says
spin-polarised and the calculation is not.

This is the quiet direction of the error. The run converges, reports a total
magnetisation of zero, and nothing about it looks wrong.

The spin-orbit branch discards the magnetism advice entirely. The elif
means that whenever an operator passes spin_orbit_coupling=True, whatever
_advise_magnetism concluded is dropped. Skipping nspin = 2 is correct --
it is not allowed alongside noncolin -- but the advice is not translated into
the non-collinear form either. A non-collinear calculation needs
starting_magnetization together with angle1 and angle2 per species to
define the directions; with none of them, the moments are zero and the
directions undefined.

So a magnetic heavy-element system, which is the case SOC exists for, gets the
most expensive spin treatment available and no magnetism at all.

This is a contracts gap, not only a generation one

MagnetismAdvice carries spin_polarized, magnetic_elements, and
provenance. There is no field for a moment, an ordering, or a direction, so
generation.py has nothing it could write even if it wanted to. Fixing this
means deciding what magnetism advice contains before deciding how to print it.

What is needed

  1. A moment on MagnetismAdvice, per species or per site.
  2. Emit starting_magnetization whenever nspin = 2 is emitted. Even a
    crude non-zero default is strictly better than zero, because zero is the one
    value guaranteed not to produce the calculation the input claims.
  3. Translate magnetism into the non-collinear branch rather than dropping
    it, which needs angle1/angle2 and therefore a direction in the advice.
  4. Decide what an ordering means here. An antiferromagnetic arrangement may
    not fit the chemical cell, and converging one can require a magnetic
    supercell -- which changes the structure every later recommendation is made
    for, k-mesh included. That makes magnetism the first setting whose answer can
    feed backwards through the pipeline, and it should be settled deliberately
    rather than discovered later.

Item 2 is worth doing on its own, ahead of the rest.

Not in scope

The relativistic pseudopotential linkage is already correct:
_advise_pseudopotentials sets relativistic_mode = "full" when SOC is
enabled, and warns when heavy elements are present without it.

Related: #175 records the heuristic that decides spin_polarized in the first
place. goldilocks-ml's magnetism scaffolding records the three quantities a
model would have to supply -- is_magnetic, ordering, and
magnetic_moments -- and notes that only the third buys a magnetic
calculation.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingcoreCore package pipeline, contracts, and recommendations

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions