Skip to main content

Universal Twisted Electronic Structure Calculation Package

Project description

General Toolkit for Twisted / Moiré Electronic Structure: MoireStudio

This repository provides a general-purpose toolkit for twisted / moiré (moire) systems, including both k·p and tight-binding (TB/Wannier) workflows, plus geometry utilities (commensurate-angle scan, moiré supercell generation) and basic visualization.

Target users: theorists and computational researchers working on 2D materials and twisted/moire systems.
Platforms: Linux / macOS / Windows (including WSL).


Features

  • k·p workflow

    • Band structures along high-symmetry paths
    • Chern number computation on k-meshes
  • TB / Wannier workflow

    • POSCAR-driven TB models (structure-based)
    • Wannier90-driven models (using .win / _hr.dat)
  • Geometry module

    • Real-space moiré point distribution
    • Commensurate-angle scan
    • Moiré supercell generation (POSCAR)
  • Visualization

    • Band plots
    • Moiré lattice point plots
    • Commensurate-angle distribution plots
  • Parallelism & cross-platform

    • Process/thread-based parallel backends with BLAS thread pinning
    • Windows-friendly multiprocessing (uses spawn mode)

Environment & Installation

  • Python ≥ 3.9
  • Required packages (minimal):
    • numpy
    • scipy
    • matplotlib

Install via:

pip install numpy scipy matplotlib

For better linear-algebra performance, a NumPy/SciPy build with MKL or another optimized BLAS is recommended.


Quick Start

From the project root:

python driver.py --input input.json

The main calculation mode is selected by the top-level JSON key "mode" and sub-key "task":

  • kp.band – k·p band structure
  • kp.chern – k·p Chern number
  • tb.band – TB/Wannier band structure (POSCAR or Wannier90)
  • struc.find_com – scan commensurate twist-angle distribution
  • struc.gen_pos – generate a moiré supercell (POSCAR + schematic plot)

Default output directory: ./outputs (configurable via io.output_dir).


Recommended Project Layout

project/
  driver.py
  solver.py
  twist_tb.py
  twist_kp.py
  twist_geometry.py
  read_tb_model.py
  twist_viz.py
  inputs/
    POSCAR                 # or Wannier90: *.win / *_hr.dat / FERMI_ENERGY
  outputs/                 # generated after running
  • Wannier90 input: requires *.win and *_hr.dat.
    • Fermi level can be provided via inputs/FERMI_ENERGY or via tb.wannier.fermi_energy.
  • POSCAR input: single-layer or bilayer structures are supported (controlled by struc.read_layer).

Input File input.json

Top-level structure

{
  "mode": "kp | tb | struc",
  "task": "...",
  "io":   { ... },
  "kp":   { ... },
  "tb":   { ... },
  "struc":{ ... }
}

Common section io

  • output_dir: output directory (default ./outputs)
  • input_dir: input directory (default ./inputs)
  • fig_band: filename for band plot (default <task>.png)
  • fig_moire: filename for moiré-point plot (default moire_points.png)
  • fig_comm: filename for commensurate-angle plot (default comm_angles.png)
  • show_plots: whether to show figures interactively (true/false)
  • Heterobilayer (optional):
    • t_prefix / b_prefix: Wannier file prefixes for top/bottom layers
    • t_fermi_energy / b_fermi_energy: corresponding Fermi energies

Geometry & Supercell struc

  • read_mode: "POSCAR" or "model" (Wannier)
  • read_layer: "bilayer" / "monolayer" (only in POSCAR mode)
  • ihetero: whether the system is heterobilayer (true/false)
  • pos_path / pos_prefix: path and prefix for POSCAR input
  • d_AA / d_AB: out-of-plane AA/AB interlayer distances (units consistent with input)

Supercell generation & search:

  • zero_point: reference lattice indices for moiré center
  • lim, search, accurate, if_gen_pos, write_by_hand:
    parameters controlling supercell search, commensurability scan and whether to dump a POSCAR.

Commensurate-angle scan:

  • max_angle, min_angle: scan range in degrees
  • lim: integer cutoff for commensurate search
  • step: scan step (deg)
  • accurate: numerical matching tolerance

Tight-Binding / Wannier tb

  • theta_deg: twist angle in degrees
  • cores: number of CPU cores for TB tasks
  • isparse: whether to use sparse workflow (recommended for large systems)
  • k_path: list of high-symmetry points in fractional coordinates
  • nk: total number of k-points along the path
  • labels: labels for each waypoint (e.g. ["G","M","K","G"])
  • ylim: energy window for plotting, e.g. [-0.2, 0.2]

Wannier options (when struc.read_mode="model"):

  • wannier.prefix: e.g. "wannier90" for inputs/wannier90.win and inputs/wannier90_hr.dat
  • wannier.fermi_energy: Fermi level; if omitted, the program attempts to read inputs/FERMI_ENERGY, otherwise defaults to 0.0.

k·p section kp

  • theta_deg: twist angle (deg)
  • tr: truncation index for reciprocal shells (default ≈3)
  • valley_pos: valley position in reduced coordinates, e.g. [2/3, 1/3]
  • mono_lat: 2×2 real-space primitive lattice of the monolayer
  • valley_name: "K" or "M" (controls mapping of the moiré reciprocal lattice)
  • V_z / m_z: layer potential and mass term for simple 2×2 Dirac-like models

Coupling definition:

  • inter_idxs / intra_idxs: lists of integer index pairs for moiré reciprocal vectors (e.g. [[0,0],[1,0],...])
  • inter_coes: list of coupling matrices corresponding to inter_idxs, as:
    • real numbers,
    • complex numbers [re, im],
    • or 2D complex matrices (nested lists).
  • intra_coes: [top_list, bottom_list], each element aligned with intra_idxs.
  • k-path parameters: path, nk, labels, ylim (same as TB).

Complex numbers in JSON

  • A bare scalar x is interpreted as a real number.
  • [re, im] is interpreted as a complex number re + i·im.
  • Complex matrices are written as nested lists of [re, im] entries.

Complete Example input.json

Below are shortened examples; you can adapt them to your own systems.

1. Geometry: scan commensurate angles – struc.find_com

{
  "mode": "struc",
  "task": "find_com",
  "io": { "input_dir": "./inputs", "output_dir": "./outputs", "fig_comm": "comm_angles.png" },
  "struc": {
    "read_mode": "POSCAR",
    "read_layer": "bilayer",
    "pos_path": "./inputs",
    "pos_prefix": "POSCAR",
    "ihetero": false,
    "d_AA": 3.5,
    "d_AB": 3.35,
    "max_angle": 5.0,
    "min_angle": 0.5,
    "lim": 12,
    "step": 0.02,
    "accurate": 0.01
  },
  "tb": { "theta_deg": 1.10 }
}

Output: outputs/commensurate_angle.txt and outputs/comm_angles.png.

2. Geometry: generate moiré supercell – struc.gen_pos

{
  "mode": "struc",
  "task": "gen_pos",
  "io": { "input_dir": "./inputs", "output_dir": "./outputs", "fig_moire": "moire_points.png" },
  "struc": {
    "read_mode": "POSCAR",
    "read_layer": "bilayer",
    "pos_path": "./inputs",
    "pos_prefix": "POSCAR",
    "ihetero": false,
    "d_AA": 3.5,
    "d_AB": 3.35,
    "zero_point": [0, 0],
    "lim": 20,
    "search": 0,
    "accurate": 0.01,
    "if_gen_pos": true
  },
  "tb": { "theta_deg": 1.10 }
}

Outputs: moiré point plot outputs/moire_points.png, and a generated/overwritten POSCAR at the project root.

3. TB: band structure from POSCAR – tb.band

{
  "mode": "tb",
  "task": "band",
  "io": {
    "input_dir": "./inputs",
    "output_dir": "./outputs",
    "fig_band": "tb_band.png",
    "show_plots": false
  },
  "struc": {
    "read_mode": "POSCAR",
    "read_layer": "bilayer",
    "pos_path": "./inputs",
    "pos_prefix": "POSCAR",
    "ihetero": false,
    "d_AA": 3.5,
    "d_AB": 3.35,
    "if_gen_pos": true
  },
  "tb": {
    "theta_deg": 1.10,
    "cores": 4,
    "isparse": false,
    "k_path": [[0,0],[0.5,0],[0.3333333,0.3333333],[0,0]],
    "nk": 201,
    "labels": ["G","M","K","G"],
    "ylim": [-0.2, 0.2]
  }
}

4. TB: band structure from Wannier90 – tb.band

{
  "mode": "tb",
  "task": "band",
  "io": { "input_dir": "./inputs", "output_dir": "./outputs", "fig_band": "tb_band_w90.png" },
  "struc": { "read_mode": "model", "ihetero": false },
  "tb": {
    "theta_deg": 1.10,
    "cores": 4,
    "isparse": false,
    "wannier": { "prefix": "wannier90", "fermi_energy": 0.0 },
    "k_path": [[0,0],[0.5,0],[0.3333333,0.3333333],[0,0]],
    "nk": 201,
    "labels": ["G","M","K","G"]
  }
}

If fermi_energy is not specified, the code tries to read inputs/FERMI_ENERGY; if missing, it defaults to 0.0.

5. k·p: band structure – kp.band

{
  "mode": "kp",
  "task": "band",
  "io": { "output_dir": "./outputs", "fig_band": "kp_band.png" },
  "kp": {
    "theta_deg": 1.10,
    "tr": 3,
    "valley_pos": [0.6666667, 0.3333333],
    "mono_lat": [[2.46, 0.0], [1.23, 2.13162820728]],
    "valley_name": "K",
    "V_z": 0.0,
    "m_z": 0.0,
    "inter_idxs": [[0,0],[1,0],[0,1]],
    "inter_coes": [[[0,0],[10,0]], [[0,0],[10,0]], [[0,0],[10,0]]],
    "intra_idxs": [[0,0]],
    "intra_coes": [
      [[[0,0],[0,0]], [[0,0],[0,0]]],
      [[[0,0],[0,0]], [[0,0],[0,0]]]
    ],
    "path": [[0,0],[0.5,0],[0.3333333,0.3333333],[0,0]],
    "nk": 201,
    "labels": ["G","M","K","G"],
    "ylim": [-0.2, 0.2]
  }
}

6. k·p: Chern number – kp.chern

{
  "mode": "kp",
  "task": "chern",
  "io": { "output_dir": "./outputs" },
  "kp": {
    "theta_deg": 1.10,
    "tr": 3,
    "valley_pos": [0.6666667, 0.3333333],
    "mono_lat": [[2.46, 0.0], [1.23, 2.13162820728]],
    "valley_name": "K",
    "V_z": 0.0,
    "m_z": 0.0,
    "inter_idxs": [[0,0]],
    "inter_coes": [[[0,0],[10,0]]],
    "intra_idxs": [],
    "intra_coes": [[],[]],
    "chern": { "n": 31, "band_index": 0 }
  }
}

Output: outputs/chern_number.txt (integer Chern number).


Outputs & Visualization

  • Band structures and k-path

    • band.txt: real matrix of shape (nk, nbands)
    • k_vec.txt: k-points in reduced coordinates
    • k_dist.txt: accumulated arc length along the path
    • k_node.txt: positions of high-symmetry points (x-axis ticks)
    • fig_band: band plot (PNG), name set via io.fig_band
  • Geometry

    • commensurate_angle.txt: twist angle, number of commensurate solutions, and a proxy for supercell size
    • fig_moire: moiré point distribution plot
    • POSCAR: generated/overwritten when running struc.gen_pos

To display plots interactively, set io.show_plots=true, or open the PNG files directly from the outputs/ directory.


Parallelism, Sparse Workflow & Large Systems

  • tb.cores: number of CPU cores used in TB calculations.

Sparse workflow (recommended for large systems, with tb.isparse=true):

  1. Use methods on TwistTB (in twist_tb.py) to build sparse blocks:
    • TwistTB.gen_r_ham_sparse_parallel(...): generate real-space sparse blocks
    • TwistTB.export_sparse_blocks(out_dir): export H0.npz, HRm.npz, and R_vectors.npy
  2. At run time, assemble H(k) from these blocks via a helper such as build_ham_from_npz(k, out_dir) and/or compute low-energy eigenpairs using:
    • solver.solve_low_energy_streaming_parallel(...) (sparse, streaming).

Dense workflow:

  • Build all dense Hamiltonians H(k) at once, e.g. gen_all_k_ham(k_vec)
  • Diagonalize using solver.solve_all_parallel(...).

Windows note: wrap parallel entry points in

if __name__ == "__main__":
    main()

to be compatible with the spawn start method on Windows.


FAQ (short)

  • Q1: POSCAR vs. Wannier90?

    • If you already have high-quality Wannier parameters → use read_mode="model".
    • If you start from structural geometry or only need moiré geometry → use read_mode="POSCAR".
  • Q2: Parallel runs crash on Windows?

    • Wrap calls in if __name__ == "__main__": as above.
    • Test with tb.cores = 1 first, then increase gradually.
  • Q3: Band calculation is too slow / runs out of memory?

    • Reduce nk or simplify the high-symmetry path.
    • Use sparse workflow (tb.isparse=true) plus streaming solvers.
    • Check BLAS thread counts (the code tries to clamp them, but it’s still good practice to set reasonable values in the environment).
  • Q4: How to write complex matrices in JSON?

    • Use [re, im] for each entry and nested lists for matrices (see “Complex numbers in JSON”).
  • Q5: No figures appear?

    • Set io.show_plots=true, or open the PNG files in outputs/.

Acknowledgements & Contributions

  • Issues and pull requests are welcome for improving documentation, examples, and code quality.
  • If this toolkit is useful for your research, a citation or acknowledgement is greatly appreciated.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

moirestudio-1.0.4.tar.gz (90.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

moirestudio-1.0.4-py3-none-any.whl (94.4 kB view details)

Uploaded Python 3

File details

Details for the file moirestudio-1.0.4.tar.gz.

File metadata

  • Download URL: moirestudio-1.0.4.tar.gz
  • Upload date:
  • Size: 90.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.16

File hashes

Hashes for moirestudio-1.0.4.tar.gz
Algorithm Hash digest
SHA256 37551fe35d7d6dc5aa0efb992f02b9f83af60a42d72de7562ffff1ebd47171b6
MD5 3ef64dca06e138c4e96d3f5ee9a4bfed
BLAKE2b-256 dc2c6eaf3cf297489c7d1febaebe5ed4bdd0f74238b5a4ebcd5efaa9c5d15482

See more details on using hashes here.

File details

Details for the file moirestudio-1.0.4-py3-none-any.whl.

File metadata

  • Download URL: moirestudio-1.0.4-py3-none-any.whl
  • Upload date:
  • Size: 94.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.16

File hashes

Hashes for moirestudio-1.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 5d548d1244eae88fbe6a818a4ac2ec652604915d6c9c6ace6c427b75ed657128
MD5 54bc14763a86b4658cc7d19ede91ea53
BLAKE2b-256 fb9376dfbf2bb34326bf8de7c7dad280f04eb75c0c2ea2b900f685d7333fbd93

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page