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
spawnmode)
Environment & Installation
- Python ≥ 3.9
- Required packages (minimal):
numpyscipymatplotlib
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 structurekp.chern– k·p Chern numbertb.band– TB/Wannier band structure (POSCAR or Wannier90)struc.find_com– scan commensurate twist-angle distributionstruc.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
*.winand*_hr.dat.- Fermi level can be provided via
inputs/FERMI_ENERGYor viatb.wannier.fermi_energy.
- Fermi level can be provided via
- 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 (defaultmoire_points.png)fig_comm: filename for commensurate-angle plot (defaultcomm_angles.png)show_plots: whether to show figures interactively (true/false)- Heterobilayer (optional):
t_prefix/b_prefix: Wannier file prefixes for top/bottom layerst_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 inputd_AA/d_AB: out-of-plane AA/AB interlayer distances (units consistent with input)
Supercell generation & search:
zero_point: reference lattice indices for moiré centerlim,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 degreeslim: integer cutoff for commensurate searchstep: scan step (deg)accurate: numerical matching tolerance
Tight-Binding / Wannier tb
theta_deg: twist angle in degreescores: number of CPU cores for TB tasksisparse: whether to use sparse workflow (recommended for large systems)k_path: list of high-symmetry points in fractional coordinatesnk: total number of k-points along the pathlabels: 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"forinputs/wannier90.winandinputs/wannier90_hr.datwannier.fermi_energy: Fermi level; if omitted, the program attempts to readinputs/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 monolayervalley_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 tointer_idxs, as:- real numbers,
- complex numbers
[re, im], - or 2D complex matrices (nested lists).
intra_coes:[top_list, bottom_list], each element aligned withintra_idxs.- k-path parameters:
path,nk,labels,ylim(same as TB).
Complex numbers in JSON
- A bare scalar
xis interpreted as a real number. [re, im]is interpreted as a complex numberre + 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 coordinatesk_dist.txt: accumulated arc length along the pathk_node.txt: positions of high-symmetry points (x-axis ticks)fig_band: band plot (PNG), name set viaio.fig_band
-
Geometry
commensurate_angle.txt: twist angle, number of commensurate solutions, and a proxy for supercell sizefig_moire: moiré point distribution plotPOSCAR: generated/overwritten when runningstruc.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):
- Use methods on
TwistTB(intwist_tb.py) to build sparse blocks:TwistTB.gen_r_ham_sparse_parallel(...): generate real-space sparse blocksTwistTB.export_sparse_blocks(out_dir): exportH0.npz,HRm.npz, andR_vectors.npy
- At run time, assemble
H(k)from these blocks via a helper such asbuild_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".
- If you already have high-quality Wannier parameters → use
-
Q2: Parallel runs crash on Windows?
- Wrap calls in
if __name__ == "__main__":as above. - Test with
tb.cores = 1first, then increase gradually.
- Wrap calls in
-
Q3: Band calculation is too slow / runs out of memory?
- Reduce
nkor 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).
- Reduce
-
Q4: How to write complex matrices in JSON?
- Use
[re, im]for each entry and nested lists for matrices (see “Complex numbers in JSON”).
- Use
-
Q5: No figures appear?
- Set
io.show_plots=true, or open the PNG files inoutputs/.
- Set
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7ea4882992a0fc3609f0d1d4f04e9345fdc3508be86f7997e9837b1c269b602c
|
|
| MD5 |
44f6f390860da5fe78ea7d69c75f5e66
|
|
| BLAKE2b-256 |
3400421f259449f163e2e0b5ec113516271ddd3bdb336031f5a74b226fd92d33
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
08b1c0fcfc17cc5c450af5570a6d2079b28edc4e553c9b79146ca2150e126d44
|
|
| MD5 |
dd6cfc1dcf118498f006b06917f3c157
|
|
| BLAKE2b-256 |
849465386676f882009394b7efa04e1028dd3ec0a534f5e8b8005d4f1988bb56
|