Model assembly and hr-file I/O
Helpers for building a tbmodels.Model from the API’s dense head
predictions and writing it out as HDF5 or a Wannier90-style
_hr.dat file.
See Exporting models: sparse .npz, HDF5, _hr.dat, pybinding, PythTB, Kwant for the customer-facing walkthrough,
including the model.to_pb() pybinding-conversion path.
- tailwater.hr_export.write_hr_output(hr_model: Model, out_path: str, fmt: str = 'hdf5')[source]
Persist a tbmodels.Model. fmt is “hdf5” or “hr_dat”.
- tailwater.hr_export.build_hr_model(edge_pred, onsite_pred, gdata, LM, atoms: List[Tuple[str, List[float]]], hop_threshold: float = 0.01)[source]
Build a tbmodels.Model from the model’s dense predictions.
- Parameters:
edge_pred (torch.Tensor or ndarray, shape [num_edges, 18, 18, 2]) – (or anything reshape-compatible). Real/imag in the last dim. Self-loop entries are overwritten by onsite_pred internally — caller may pass the raw head output unchanged.
onsite_pred (torch.Tensor or ndarray, shape [num_atoms, 18, 18, 2].)
gdata (PyG Data with edge_index, edge_vectors, inv_data,) – node_features. Same object the model consumed.
LM (3x3 lattice matrix (rows = lattice vectors, Å). Passed) – to
tbmodels.Modelasuc.atoms ([(symbol, [x, y, z]), ...]. Per-atom Cartesian) – positions; used as the sublattice positions of the
tbmodels.Modelso the per-atom orbitals carry the same geometric labels they have in the structure.hop_threshold (drop hops with
|val| <= this(eV). Default 0.01.)
- Returns:
hr_model
- Return type:
tbmodels.Model populated with on-site energies and hops.
- tailwater.hr_export.build_hr_model_fast(edge_pred, onsite_pred, gdata, LM, atoms: List[Tuple[str, List[float]]], hop_threshold: float = 0.01)[source]
Vectorized equivalent of build_hr_model — same output, much faster.
The reference build_hr_model loops l × atm1 × s1o × atm2 × s2o in pure Python, which is ~num_R * N^2 * 18^2 inner iterations and crosses into multi-minute territory for ~50-atom inputs. This function keeps the EXACT same iteration order (so tbmodels’ first-add-wins semantics and the model’s non-Hermitian inter-atom predictions produce the same final recorded values) but lifts the threshold check, the active-mask filter, the magnitude computation, the value gather, and the orbital-index lookup out of Python and into NumPy. The surviving per-hop Python loop only visits hops that actually got recorded.
Order preservation is what makes this drop-in safe: np.nonzero on a [num_R, N, 18, N, 18] mask returns indices in C (row-major) order, which is identical to the reference’s outer-to-inner nested-loop ordering of those five axes.
Approximate speedup on a 50-atom material: ~100-300x for the hop insertion phase. Output (the tbmodels.Model) is byte-identical to build_hr_model’s output as long as pb.Lattice / tbmodels.Model.add_hop are deterministic — both are.