Skip to content

Express analytical bridging as an explicit linear_ener composition instead of a bridging_method flag #5948

Description

@wanghan-iapcm

A bridged model is a linear composition — bridging_method builds a LinearEnergyModel whose atomic model is a LinearEnergyAtomicModel over [learned, InnerPotential]. But it is spelled as a flag on a non-composite model type, so the type you request is not the type you get:

get_standard_model({... "descriptor": {"type": "dpa4"}, ...})                     # -> DPA4EnergyModel
get_standard_model({... "bridging_method": "ZBL", "bridging_r_inner": 0.8, ...})  # -> LinearEnergyModel

Why the flag exists

linear_ener is already the composition axis and takes exactly the right shape — a repeated models: list of full sub-model specs plus weights ("sum" supported). What is missing is the child: InnerPotential has no config-level model type. It exists only as InnerPotentialAtomicModel, so it cannot be named in models:. The flag is the workaround for that gap.

What the workaround costs

  1. Type confusion — a standard (or dpa4) request silently returns a LinearEnergyModel.
  2. Implicit coupling — the radii are pushed into the sibling descriptor's InnerClamp/BridgingSwitch behind the user's back.
  3. Duplicated owners — every builder that accepts the flag must re-implement the composition, and they have already drifted: see Deprecate descriptor-scoped exclude_types in favour of the model-level build-seam owner #5947, where one builder promotes descriptor.exclude_types to model-level pair_exclude_types and the other does not, changing the energy of a 0.9 A Ni-O dimer by 79.97 eV (max force component 318.48 eV/A).

Proposed shape

"model": {
  "type": "linear_ener", "weights": "sum", "type_map": ["Ni", "O"],
  "pair_exclude_types": [[0, 1]],
  "models": [
    {"type": "standard", "descriptor": {"type": "dpa4", "...": "..."},
                         "fitting_net": {"type": "dpa4_ener", "...": "..."}},
    {"type": "inner_potential", "mode": "ZBL", "r_inner": 0.8, "r_outer": 1.2}
  ]
}

Tasks:

  1. Register inner_potential as a model type so it can be named as a linear_ener child.
  2. Have the composition derive the sibling descriptor's InnerClamp/BridgingSwitch from the inner_potential child at build time. Bridging is not a pure sum — the switch must reach inside the learned child (it drives the SFPG gate, see DPA4/SeZM zone-bridging (SFPG) gate is incomplete under domain decomposition; blocks ZBL and spin+ZBL multi-rank #5906) — so this coupling has to be expressed somewhere; deriving it keeps a single source of truth instead of asking the user to write the radii twice and hoping they agree.
  3. With the composition explicit, pair_exclude_types belongs to the linear model and governs both children by construction. The promotion in Deprecate descriptor-scoped exclude_types in favour of the model-level build-seam owner #5947 then has nothing left to do and can be deleted rather than deprecated.
  4. Keep bridging_method as sugar that expands to the canonical form through ONE normalizer (not per-builder), or deprecate it once the examples are migrated.
  5. Land pt and pt_expt together; argcheck is shared, so a schema that accepts a spelling one backend ignores is the same silent-divergence bug in a new place.

Related

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions