Quick start =========== End-to-end: get a tight-binding Hamiltonian from the API, project it into a near-Fermi subspace, and run a surface Green's function on the result. .. note:: This guide assumes you have ``tailwater`` installed (``pip install tailwater``) and a username/password issued by the Tailwater team. The client talks to the hosted API at ``https://api.tailwater.io`` automatically — no configuration needed. 1. Get the artifacts from the API --------------------------------- ``project=True`` returns the artifacts you need for fine-tuning and analysis in one credit-billed call: .. code-block:: python from pymatgen.core import Structure from tailwater import tw_api_call structure = Structure.from_file("MyMaterial.cif") paths = tw_api_call( structure = structure, user = "acme-research", password = "...", output_path = "./outputs", filename = "my_material", project = True, ) # paths = {"embeddings": "...", "npz": "...", "win": "..."} # The Hamiltonian comes back as a sparse SparseHR (wannier90_hr.npz). # For small systems (< 30 atoms) it is also auto-converted to a dense # HDF5, added under paths["hdf5"] — see :doc:`exporting_models`. The returned dict always contains a ``"win"`` key — the parsed ``wannier90.win`` file the server actually ran inference on, useful for tracing graph-construction differences across API and offline runs. 2. (Optional) Fine-tune the heads to fit a near-Fermi window ------------------------------------------------------------ Fit the output heads to the predicted Hamiltonian's eigenvalues inside a narrow energy window (a compact, downfolded model), using the bundle's ``embeddings.pt`` + sparse ``wannier90_hr.npz``: .. code-block:: python from tailwater import subspace_projection subspace_projection( start_lr = 1e-4, end_lr = 1e-5, num_epochs = 20, energy_range = (-2.0, 2.0), # eV, relative to E_F decay_sigma = 0.5, device = "cpu", save_path = "./projection_out", embed_path = paths["embeddings"], hr_npz_path = paths["npz"], # fit the heads to the sparse Hamiltonian ) After training, ``./projection_out/`` contains a fine-tuned heads checkpoint, a projected (subspace-restricted) HDF5 model, and a ``.basis.json`` describing the orbital basis of the projection. 3. Analyze the model -------------------- For semiconductors and insulators, anchor the energy zero to the valence band maximum so every calculator below shares a physically natural reference — see :doc:`fermi_alignment` for the full guide. .. code-block:: python import numpy as np from tailwater import ( as_tbmodels, align_to_vbm, SurfaceGreensFunction, BulkDOS, bulk_band_structure, ) model = as_tbmodels(paths["npz"]) # dense tbmodels.Model from the sparse .npz model = align_to_vbm(model) # (optional, for non-metals) VBM -> 0 # Bulk DOS (KPM, k-mesh averaged) dos = BulkDOS(model, k_mesh=(8, 8, 8), energies=(-4, 4)).run() dos.figure.savefig("bulk_dos.png") # Surface Green's function (Lopez-Sancho). # n_jobs=-1 parallelizes across every CPU core — see :doc:`performance`. sgf = SurfaceGreensFunction( model, surface=np.eye(3), energies=np.linspace(-1, 1, 201), k_path=[[0, 0.5, 0], [0, 0, 0], [0.333, 0.333, 0]], k_labels=["M", r"$\Gamma$", "K"], n_jobs=-1, ).run() sgf.figure_top.savefig("surface_top.png") # Bulk band structure (auto k-path via seekpath, if installed) fig = bulk_band_structure(model, auto=True, structure=structure, spacing=0.02, e_range=(-3, 3)) fig.savefig("bands.png") # 2D Fermi-arc / constant-energy surface map at E = 0 # See :doc:`fermi_arcs` for the full guide. from tailwater import FermiArcMap arc = FermiArcMap( model, surface=np.eye(3), energy=0.0, Nx=40, Ny=40, thickness=6, NN=5, eps=0.005, n_jobs=-1, ).run() arc.figure_top_interpolated.savefig("fermi_arc_top.png")