Partial and mixed occupancy

TiOF2 unit cell with disordered O/F anion sites rendered as wedges

Hofmann can render sites with partial or mixed crystallographic occupancy. Such mixed sites are drawn as pie wedges; one wedge per species, with each wedge’s angle equal to that species’ occupancy.

Constructing a mixed site

Mixed sites are expressed by passing a Composition value in the species list, in place of a plain string label:

import numpy as np
from hofmann import Composition, StructureScene, Frame

anion = Composition({"F": 2 / 3, "O": 1 / 3})
scene = StructureScene(
    species=["Ti", anion, anion, anion],
    frames=[Frame(
        coords=np.array([
            [0.0, 0.0, 0.0],
            [1.9, 0.0, 0.0],
            [0.0, 1.9, 0.0],
            [0.0, 0.0, 1.9],
        ]),
        lattice=np.eye(3) * 3.8,
    )],
)

Vacancies

When a Composition’s occupancies sum to less than one, the missing fraction is treated as a vacancy fraction:

fe_partial = Composition({"Fe": 0.7})  # 70% Fe, 30% vacancy
Single Fe site at 70% occupancy with a vacancy wedge

The vacancy wedge is filled with the canvas background colour by default. A custom vacancy colour can be set by passing the vacancy_colour field on RenderStyle.

From a pymatgen Structure

A pymatgen Structure represents partial occupancy and species disorder natively. from_pymatgen() reads this directly: any site with more than one species, or with a single species at occupancy below one, becomes a Composition in the resulting scene.

from hofmann import StructureScene

# 'structure' is any pymatgen Structure
scene = StructureScene.from_pymatgen(structure)
scene.render_mpl("output.svg")

Loading from a CIF file

CIFs can be loaded with pymatgen and passed through to from_pymatgen(). For example:

data_disordered_site
_chemical_formula_sum    'Fe0.7 Mn0.3'
_cell_length_a       2.8
_cell_length_b       2.8
_cell_length_c       2.8
_cell_angle_alpha    90.0
_cell_angle_beta     90.0
_cell_angle_gamma    90.0

_space_group_name_H-M_alt    'P 1'
_space_group_IT_number       1

loop_
  _space_group_symop_operation_xyz
  'x, y, z'

loop_
  _atom_site_type_symbol
  _atom_site_label
  _atom_site_fract_x
  _atom_site_fract_y
  _atom_site_fract_z
  _atom_site_occupancy
  Fe  Fe1  0.5  0.5  0.5  0.7
  Mn  Mn1  0.5  0.5  0.5  0.3
from pymatgen.core import Structure
from hofmann import StructureScene

structure = Structure.from_file("disordered_site.cif")
scene = StructureScene.from_pymatgen(structure)
scene.render_mpl("disordered.svg")
Single mixed-occupancy Fe/Mn site rendered as a two-wedge atom

Customising appearance

Each wedge takes its colour from the corresponding species’ colour. The radius of the whole site is the occupancy-weighted average of its constituents’ radii, with the weights renormalised over the occupied species only – so a half-vacant site is drawn at the same size as a fully occupied one.

Three RenderStyle fields control the wedge layout:

  • wedge_start_angle sets the starting orientation (default 12 o’clock).

  • show_wedge_edges toggles radial edges between wedges (default on; set to False to stroke only the outer arc).

  • vacancy_colour overrides the vacancy fill (default: canvas background colour).

For example:

from hofmann import RenderStyle

style = RenderStyle(
    wedge_start_angle=0.0,        # start at 3 o'clock
    show_wedge_edges=False,       # outer arc only, no radial edges
    vacancy_colour="lightgrey",   # explicit vacancy fill
)
scene.render_mpl("structure.svg", style=style)

For more specific styling – for example, colouring all mixed sites the same way to flag disordered positions – attach per-site data with set_atom_data() and use the colour_by parameter when rendering. See Colouring by per-atom data.

Visibility of constituent species

Setting visible to False hides every site whose species is given as a plain label. It does not hide that species when it appears as a constituent of a Composition: a mixed site is always drawn with all of its constituents, regardless of any per-species visible flag.

Bonding and polyhedra

A BondSpec or PolyhedronSpec rule applies to a mixed site whenever any of its constituent species matches the rule. Each pair of atoms still produces at most one bond, even when several rules match: for a 70 / 30 Fe / Mn site bonded to an O neighbour, defining both ("Fe", "O") and ("Mn", "O") rules gives one bond, not two. When more than one rule matches a pair, the first in list order wins. Vacancies never form bonds.

The half-bond at the mixed-site end is drawn in the colour of the dominant species – the constituent with the highest occupancy, with ties broken alphabetically.