pyextal.jaxGeo.refine

The refinement: Adam in segments, the geometry refined between them.

Adam runs on the structure factors, thickness, scale, background and probe. Every geo_every steps from geo_start it stops, and the geometry (gl, rotation, tiltx, tilty) is refined by Levenberg-Marquardt on exact JAX derivatives of the loss with everything else held fixed (jaxGeo.lm, jaxGeo.objective, jaxGeo.geometry). Adam’s state carries across segments, so releasing the geometry does not reset the momentum on the structure factors.

Before anything is refined, two checks must pass: the affine geometry model must reproduce the exported tilt grid, and the JAX excitation errors must reproduce the engine’s. Either failing means the derivatives would be of the wrong function, and the run stops.

Complex structure factors (imag)

imag='none' refines the real parts of U_g and U’_g only, which is exact for a centrosymmetric group with its inversion centre on the origin. 'elastic' frees Im U_g and 'both' Im U’_g as well, so each refined U_g has an amplitude and a continuous phase. That forces three things:

  • Friedel symmetry, not the space group. Under SpaceGroup a centrosymmetric group makes the engine fill U(-g) with the same complex value as U(g) – inversion for real U_g, a non-Hermitian potential once Im U_g is free. Friedel pairs U(-g) = U(g)* instead – Hermitian, and true for any crystal – and drops the space-group ties, so each (g, -g) pair is one complex parameter and its equivalents off the zone stay at their tabulated values. symmetry defaults to Friedel whenever imag is not 'none'.

  • Both of g and -g are named (jaxGeo.reflections.friedel_reflections), so the engine’s label for the pair is always among the requested reflections.

  • The origin is not free. A complex U_g on its own is defined only up to an origin shift, U_g -> U_g exp(2 pi i g.r0). Every reflection not refined stays real at its tabulated value, which pins the origin; the refined phases are relative to that reference.

Imaginary parts start at zero. Their gradient there is not zero when the data break the centrosymmetry: to first order it measures exactly the difference between a pair’s rocking curves that a real U_g cannot produce. A caution: an asymmetric (g, -g) pair on zone is also what a residual tilt, a thickness gradient or a mis-set rotation produces – check that the geometry has converged and that the real-only run cannot fit the pair before attributing a phase to the structure. The run ends with a table of amplitude and phase.

A specimen in layers (layers)

With layers=N the specimen is N slabs stacked along the beam, entrance surface first, each with its own thickness and its own copy of every refined structure factor; the wave is propagated through them in turn. Reflections not refined are the same tabulated values in every layer. It is for a crystal whose structure is not uniform through its thickness – a damaged or reconstructed surface layer, a strain or composition gradient, a second domain. A uniform crystal makes the layers redundant: they drift to the same U_g, or one shrinks towards zero thickness.

layer_fractions shares the starting thickness between the layers (default equal); each layer’s thickness then refines independently. refine_layers (1-based) chooses whose structure factors are free – e.g. 2 holds layer 1 at the tabulated (bulk) values. Identical layers that start identical and are all free can trade structure factors almost freely, so holding the bulk layer or starting from unequal fractions breaks that symmetry. The run ends with a per-layer table and <h5>_<run>_layers.png.

Over-subtracted reflections (oversub)

See jaxGeo.oversub: listed reflections are compared as max(sim - c - k * I(000), 0), with c and k fitted at oversub_start and then released to Adam.

Functions

_select_cpu()

Forces the CPU backend, before or after JAX has been imported.

refine([settings])

Runs a refinement, or validates its setup with dry_run.

Module Contents

pyextal.jaxGeo.refine._select_cpu()

Forces the CPU backend, before or after JAX has been imported.

pyextal.jaxGeo.refine.refine(settings=None, **overrides)

Runs a refinement, or validates its setup with dry_run.

Parameters:
  • settings (RefineSettings, optional) – The options.

  • **overrides – Fields to change on settings (or on the defaults).

Returns:

config, params, metadata, constants, geometry (the refined geometry dict) and, unless dry_run, run (the run key written to the file, or None if the simulation failed), loss_history and geometry_history.

Return type:

dict

Raises:

SetupError – If the dataset, the .dat or the options are unusable.