|
| 1 | +.. _partial_occupancy: |
| 2 | + |
| 3 | +Partial and mixed occupancy |
| 4 | +============================ |
| 5 | + |
| 6 | +Hofmann can render sites that are partially occupied (a fraction of an |
| 7 | +atom) or shared between multiple species (a solid solution). These |
| 8 | +sites appear as VESTA-style pie wedges, one wedge per constituent |
| 9 | +species, with wedge angles proportional to occupancy. |
| 10 | + |
| 11 | +Constructing a mixed site |
| 12 | +-------------------------- |
| 13 | + |
| 14 | +Mixed sites are expressed by passing a :class:`Composition` value in |
| 15 | +the ``species`` list, in place of a plain string label:: |
| 16 | + |
| 17 | + import numpy as np |
| 18 | + from hofmann import Composition, StructureScene, Frame |
| 19 | + |
| 20 | + fe_mn = Composition({"Fe": 0.7, "Mn": 0.3}) |
| 21 | + scene = StructureScene( |
| 22 | + species=["Fe", fe_mn, fe_mn, "O"], |
| 23 | + frames=[Frame(coords=np.array([ |
| 24 | + [0.0, 0.0, 0.0], |
| 25 | + [2.0, 0.0, 0.0], |
| 26 | + [4.0, 0.0, 0.0], |
| 27 | + [6.0, 0.0, 0.0], |
| 28 | + ]))], |
| 29 | + ) |
| 30 | + |
| 31 | +Reusing a single ``Composition`` value across many rows is the |
| 32 | +recommended way to keep authoring concise. |
| 33 | + |
| 34 | +Vacancies |
| 35 | +--------- |
| 36 | + |
| 37 | +A :class:`Composition` whose occupancies sum to less than one carries |
| 38 | +an implicit vacancy fraction:: |
| 39 | + |
| 40 | + fe_partial = Composition({"Fe": 0.7}) # 70% Fe + 30% vacancy |
| 41 | + |
| 42 | +The vacancy fraction renders as an opaque wedge filled with the |
| 43 | +canvas background colour by default, so partial sites still read as |
| 44 | +solid circles with a "missing" slice. Set |
| 45 | +:attr:`~hofmann.RenderStyle.vacancy_colour` to override with an |
| 46 | +explicit colour (for example, ``"lightgrey"`` on a white canvas to |
| 47 | +make the vacancy stand out). |
| 48 | + |
| 49 | +Loading from pymatgen |
| 50 | +--------------------- |
| 51 | + |
| 52 | +:func:`~hofmann.from_pymatgen` propagates partial occupancies |
| 53 | +directly: any :class:`pymatgen.core.PeriodicSite` whose ``species`` |
| 54 | +mapping has more than one entry, or a single entry at occupancy less |
| 55 | +than one, becomes a :class:`Composition` in the resulting scene. No |
| 56 | +preprocessing or manual handling is required. |
| 57 | + |
| 58 | +Customising appearance |
| 59 | +---------------------- |
| 60 | + |
| 61 | +By default a mixed site is drawn at a radius equal to the |
| 62 | +occupancy-weighted average of its constituents' |
| 63 | +:attr:`~hofmann.AtomStyle.radius`, normalised by the total species |
| 64 | +occupancy so that vacancy fractions do not shrink the site. Each |
| 65 | +wedge uses its species' :attr:`~hofmann.AtomStyle.colour`. |
| 66 | +For more specific styling — for example, colouring all mixed sites the |
| 67 | +same way to highlight disordered positions — use |
| 68 | +:meth:`~hofmann.StructureScene.set_atom_data` and the ``colour_by`` |
| 69 | +parameter of the render methods, exactly as for pure sites. |
| 70 | + |
| 71 | +The wedge layout itself is controlled by three render-style fields: |
| 72 | + |
| 73 | +- :attr:`~hofmann.RenderStyle.wedge_start_angle` sets the starting |
| 74 | + orientation (default 12 o'clock). |
| 75 | +- :attr:`~hofmann.RenderStyle.show_wedge_edges` toggles radial edges |
| 76 | + between wedges (default on; set to ``False`` to stroke only the |
| 77 | + outer arc). |
| 78 | +- :attr:`~hofmann.RenderStyle.vacancy_colour` overrides the vacancy |
| 79 | + fill (default: canvas background colour). |
| 80 | + |
| 81 | +Visibility of constituent species |
| 82 | +--------------------------------- |
| 83 | + |
| 84 | +:attr:`~hofmann.AtomStyle.visible` is a per-species flag — setting it |
| 85 | +to ``False`` hides every pure-string site of that species. It does |
| 86 | +**not** apply to constituents of a :class:`Composition`: a mixed site |
| 87 | +is always drawn with all of its constituents, regardless of any |
| 88 | +constituent's ``visible`` flag. This avoids the visually inconsistent |
| 89 | +state where a constituent is hidden in the wedge rendering but its |
| 90 | +species still attracts bonds and matches rule lookups. To |
| 91 | +de-emphasise specific mixed sites, use |
| 92 | +:meth:`~hofmann.StructureScene.set_atom_data` with ``colour_by`` to |
| 93 | +recolour them at the row level. |
| 94 | + |
| 95 | +Bonding and polyhedra |
| 96 | +--------------------- |
| 97 | + |
| 98 | +:class:`BondSpec` and :class:`PolyhedronSpec` rules fire on a mixed |
| 99 | +site whenever any constituent species satisfies the rule. A 70 / 30 |
| 100 | +Fe / Mn site with both ``("Fe", "O")`` and ``("Mn", "O")`` bond rules |
| 101 | +defined produces exactly one bond per neighbour, drawn at whichever |
| 102 | +matching cutoff is permissive enough. Vacancy fractions never |
| 103 | +participate in bonding. |
| 104 | + |
| 105 | +The half-bond at a mixed-site end uses the dominant species' |
| 106 | +colour — the species with the highest occupancy in the composition, |
| 107 | +with alphabetical tiebreak. The wedges, not the bond, communicate the |
| 108 | +full composition. |
0 commit comments