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.3.tar.gz (87.0 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.3-py3-none-any.whl (91.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: moirestudio-1.0.3.tar.gz
  • Upload date:
  • Size: 87.0 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.3.tar.gz
Algorithm Hash digest
SHA256 7ea4882992a0fc3609f0d1d4f04e9345fdc3508be86f7997e9837b1c269b602c
MD5 44f6f390860da5fe78ea7d69c75f5e66
BLAKE2b-256 3400421f259449f163e2e0b5ec113516271ddd3bdb336031f5a74b226fd92d33

See more details on using hashes here.

File details

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

File metadata

  • Download URL: moirestudio-1.0.3-py3-none-any.whl
  • Upload date:
  • Size: 91.2 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.3-py3-none-any.whl
Algorithm Hash digest
SHA256 08b1c0fcfc17cc5c450af5570a6d2079b28edc4e553c9b79146ca2150e126d44
MD5 dd6cfc1dcf118498f006b06917f3c157
BLAKE2b-256 849465386676f882009394b7efa04e1028dd3ec0a534f5e8b8005d4f1988bb56

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