valyte 0.1.7__tar.gz → 0.1.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {valyte-0.1.7 → valyte-0.1.9}/PKG-INFO +17 -12
- valyte-0.1.7/valyte.egg-info/PKG-INFO → valyte-0.1.9/README.md +12 -26
- {valyte-0.1.7 → valyte-0.1.9}/setup.py +5 -1
- valyte-0.1.9/valyte/band.py +289 -0
- {valyte-0.1.7 → valyte-0.1.9}/valyte/cli.py +24 -1
- valyte-0.1.9/valyte/data/__init__.py +0 -0
- valyte-0.1.9/valyte/data/bradcrack.json +1194 -0
- {valyte-0.1.7 → valyte-0.1.9}/valyte/kpoints.py +12 -0
- valyte-0.1.9/valyte/potcar.py +61 -0
- valyte-0.1.7/README.md → valyte-0.1.9/valyte.egg-info/PKG-INFO +31 -1
- {valyte-0.1.7 → valyte-0.1.9}/valyte.egg-info/SOURCES.txt +4 -1
- {valyte-0.1.7 → valyte-0.1.9}/valyte.egg-info/requires.txt +3 -0
- valyte-0.1.7/valyte/band.py +0 -56
- {valyte-0.1.7 → valyte-0.1.9}/MANIFEST.in +0 -0
- {valyte-0.1.7 → valyte-0.1.9}/setup.cfg +0 -0
- {valyte-0.1.7 → valyte-0.1.9}/valyte/Logo.png +0 -0
- {valyte-0.1.7 → valyte-0.1.9}/valyte/__init__.py +0 -0
- {valyte-0.1.7 → valyte-0.1.9}/valyte/band_plot.py +0 -0
- {valyte-0.1.7 → valyte-0.1.9}/valyte/dos_plot.py +0 -0
- {valyte-0.1.7 → valyte-0.1.9}/valyte/supercell.py +0 -0
- {valyte-0.1.7 → valyte-0.1.9}/valyte/valyte_band.png +0 -0
- {valyte-0.1.7 → valyte-0.1.9}/valyte/valyte_dos.png +0 -0
- {valyte-0.1.7 → valyte-0.1.9}/valyte.egg-info/dependency_links.txt +0 -0
- {valyte-0.1.7 → valyte-0.1.9}/valyte.egg-info/entry_points.txt +0 -0
- {valyte-0.1.7 → valyte-0.1.9}/valyte.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
2
|
Name: valyte
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.9
|
|
4
4
|
Summary: A comprehensive CLI tool for VASP pre-processing (Supercells, K-points) and post-processing (DOS, Band Structure plotting)
|
|
5
5
|
Home-page: https://github.com/nikyadav002/Valyte-Project
|
|
6
6
|
Author: Nikhil
|
|
@@ -13,15 +13,9 @@ Description-Content-Type: text/markdown
|
|
|
13
13
|
Requires-Dist: numpy
|
|
14
14
|
Requires-Dist: matplotlib
|
|
15
15
|
Requires-Dist: pymatgen
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
Dynamic: description
|
|
20
|
-
Dynamic: description-content-type
|
|
21
|
-
Dynamic: home-page
|
|
22
|
-
Dynamic: requires-dist
|
|
23
|
-
Dynamic: requires-python
|
|
24
|
-
Dynamic: summary
|
|
16
|
+
Requires-Dist: scipy
|
|
17
|
+
Requires-Dist: click
|
|
18
|
+
Requires-Dist: seekpath
|
|
25
19
|
|
|
26
20
|
<p align="center">
|
|
27
21
|
<img src="valyte/Logo.png" alt="Valyte Logo" width="100%"/>
|
|
@@ -119,6 +113,9 @@ valyte supercell 3 3 1 -i POSCAR_primitive -o POSCAR_3x3x1
|
|
|
119
113
|
|
|
120
114
|
Automatically generate a KPOINTS file with high-symmetry paths for band structure calculations.
|
|
121
115
|
|
|
116
|
+
> [!TIP]
|
|
117
|
+
> **Smart K-Path Generation (New in v0.1.7+)**: Valyte now automatically determines the standard path (e.g., `\Gamma - Y - V` for Monoclinic cells) using the **Bradley-Cracknell** convention by default. This ensures clean, publication-ready labels without external dependencies.
|
|
118
|
+
|
|
122
119
|
```bash
|
|
123
120
|
valyte band kpt-gen [options]
|
|
124
121
|
```
|
|
@@ -127,12 +124,20 @@ valyte band kpt-gen [options]
|
|
|
127
124
|
- `-i`, `--input`: Input POSCAR file (default: `POSCAR`).
|
|
128
125
|
- `-n`, `--npoints`: Points per segment (default: `40`).
|
|
129
126
|
- `-o`, `--output`: Output filename (default: `KPOINTS`).
|
|
127
|
+
- `--mode`: Path convention. Options: `bradcrack` (Default), `seekpath`, `latimer_munro`, `setyawan_curtarolo`.
|
|
130
128
|
|
|
131
129
|
**Example:**
|
|
132
130
|
```bash
|
|
133
|
-
|
|
131
|
+
# Default (Smart/BradCrack)
|
|
132
|
+
valyte band kpt-gen -n 60
|
|
133
|
+
|
|
134
|
+
# Explicitly use Seekpath convention
|
|
135
|
+
valyte band kpt-gen --mode seekpath
|
|
134
136
|
```
|
|
135
137
|
|
|
138
|
+
> [!IMPORTANT]
|
|
139
|
+
> The command will generate a **`POSCAR_standard`** file. You **MUST** use this structure for your band structure calculation (i.e., `cp POSCAR_standard POSCAR`) because the K-path corresponds to this specific orientation. Using your original POSCAR may result in incorrect paths.
|
|
140
|
+
|
|
136
141
|
### 🕸️ Generate K-Points (Interactive)
|
|
137
142
|
|
|
138
143
|
Generate a `KPOINTS` file for SCF calculations interactively.
|
|
@@ -1,28 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.2
|
|
2
|
-
Name: valyte
|
|
3
|
-
Version: 0.1.7
|
|
4
|
-
Summary: A comprehensive CLI tool for VASP pre-processing (Supercells, K-points) and post-processing (DOS, Band Structure plotting)
|
|
5
|
-
Home-page: https://github.com/nikyadav002/Valyte-Project
|
|
6
|
-
Author: Nikhil
|
|
7
|
-
Author-email: nikhil@example.com
|
|
8
|
-
Classifier: Programming Language :: Python :: 3
|
|
9
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
-
Classifier: Operating System :: OS Independent
|
|
11
|
-
Requires-Python: >=3.6
|
|
12
|
-
Description-Content-Type: text/markdown
|
|
13
|
-
Requires-Dist: numpy
|
|
14
|
-
Requires-Dist: matplotlib
|
|
15
|
-
Requires-Dist: pymatgen
|
|
16
|
-
Dynamic: author
|
|
17
|
-
Dynamic: author-email
|
|
18
|
-
Dynamic: classifier
|
|
19
|
-
Dynamic: description
|
|
20
|
-
Dynamic: description-content-type
|
|
21
|
-
Dynamic: home-page
|
|
22
|
-
Dynamic: requires-dist
|
|
23
|
-
Dynamic: requires-python
|
|
24
|
-
Dynamic: summary
|
|
25
|
-
|
|
26
1
|
<p align="center">
|
|
27
2
|
<img src="valyte/Logo.png" alt="Valyte Logo" width="100%"/>
|
|
28
3
|
</p>
|
|
@@ -119,6 +94,9 @@ valyte supercell 3 3 1 -i POSCAR_primitive -o POSCAR_3x3x1
|
|
|
119
94
|
|
|
120
95
|
Automatically generate a KPOINTS file with high-symmetry paths for band structure calculations.
|
|
121
96
|
|
|
97
|
+
> [!TIP]
|
|
98
|
+
> **Smart K-Path Generation (New in v0.1.7+)**: Valyte now automatically determines the standard path (e.g., `\Gamma - Y - V` for Monoclinic cells) using the **Bradley-Cracknell** convention by default. This ensures clean, publication-ready labels without external dependencies.
|
|
99
|
+
|
|
122
100
|
```bash
|
|
123
101
|
valyte band kpt-gen [options]
|
|
124
102
|
```
|
|
@@ -127,12 +105,20 @@ valyte band kpt-gen [options]
|
|
|
127
105
|
- `-i`, `--input`: Input POSCAR file (default: `POSCAR`).
|
|
128
106
|
- `-n`, `--npoints`: Points per segment (default: `40`).
|
|
129
107
|
- `-o`, `--output`: Output filename (default: `KPOINTS`).
|
|
108
|
+
- `--mode`: Path convention. Options: `bradcrack` (Default), `seekpath`, `latimer_munro`, `setyawan_curtarolo`.
|
|
130
109
|
|
|
131
110
|
**Example:**
|
|
132
111
|
```bash
|
|
133
|
-
|
|
112
|
+
# Default (Smart/BradCrack)
|
|
113
|
+
valyte band kpt-gen -n 60
|
|
114
|
+
|
|
115
|
+
# Explicitly use Seekpath convention
|
|
116
|
+
valyte band kpt-gen --mode seekpath
|
|
134
117
|
```
|
|
135
118
|
|
|
119
|
+
> [!IMPORTANT]
|
|
120
|
+
> The command will generate a **`POSCAR_standard`** file. You **MUST** use this structure for your band structure calculation (i.e., `cp POSCAR_standard POSCAR`) because the K-path corresponds to this specific orientation. Using your original POSCAR may result in incorrect paths.
|
|
121
|
+
|
|
136
122
|
### 🕸️ Generate K-Points (Interactive)
|
|
137
123
|
|
|
138
124
|
Generate a `KPOINTS` file for SCF calculations interactively.
|
|
@@ -2,16 +2,20 @@ from setuptools import setup, find_packages
|
|
|
2
2
|
|
|
3
3
|
setup(
|
|
4
4
|
name="valyte",
|
|
5
|
-
version="0.1.
|
|
5
|
+
version="0.1.9",
|
|
6
6
|
packages=find_packages(),
|
|
7
7
|
install_requires=[
|
|
8
8
|
"numpy",
|
|
9
9
|
"matplotlib",
|
|
10
10
|
"pymatgen",
|
|
11
|
+
"scipy",
|
|
12
|
+
"click",
|
|
13
|
+
"seekpath"
|
|
11
14
|
],
|
|
12
15
|
include_package_data=True,
|
|
13
16
|
package_data={
|
|
14
17
|
"valyte": ["*.png"],
|
|
18
|
+
"valyte.data": ["*.json"],
|
|
15
19
|
},
|
|
16
20
|
entry_points={
|
|
17
21
|
"console_scripts": [
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Band structure KPOINTS generation module for Valyte.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import json
|
|
7
|
+
import numpy as np
|
|
8
|
+
import seekpath
|
|
9
|
+
import spglib
|
|
10
|
+
from pymatgen.core import Structure
|
|
11
|
+
from pymatgen.symmetry.bandstructure import HighSymmKpath
|
|
12
|
+
from pymatgen.symmetry.analyzer import SpacegroupAnalyzer
|
|
13
|
+
try:
|
|
14
|
+
from importlib.resources import files as ilr_files
|
|
15
|
+
except ImportError:
|
|
16
|
+
import importlib_resources as ilr_files
|
|
17
|
+
|
|
18
|
+
from valyte.potcar import generate_potcar
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def generate_band_kpoints(poscar_path="POSCAR", npoints=40, output="KPOINTS", symprec=0.01, mode="bradcrack"):
|
|
22
|
+
"""
|
|
23
|
+
Generates KPOINTS file in line-mode for band structure calculations.
|
|
24
|
+
Uses SeeK-path method for high-symmetry path determination.
|
|
25
|
+
|
|
26
|
+
IMPORTANT: Writes a standardized POSCAR (POSCAR_standard) that MUST be used
|
|
27
|
+
for the band structure calculation to ensure K-points are valid.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
poscar_path (str): Path to input POSCAR file.
|
|
31
|
+
npoints (int): Number of points per segment (default: 40).
|
|
32
|
+
output (str): Output filename for KPOINTS.
|
|
33
|
+
symprec (float): Symmetry precision for standardization (default: 0.01).
|
|
34
|
+
mode (str): Standardization convention (default: "bradcrack").
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
if not os.path.exists(poscar_path):
|
|
38
|
+
raise FileNotFoundError(f"{poscar_path} not found")
|
|
39
|
+
|
|
40
|
+
# Read structure
|
|
41
|
+
structure = Structure.from_file(poscar_path)
|
|
42
|
+
|
|
43
|
+
# --- K-Point Generation Logic ---
|
|
44
|
+
if mode == "bradcrack":
|
|
45
|
+
try:
|
|
46
|
+
kpath = BradCrackKpath(structure, symprec=symprec)
|
|
47
|
+
prim_std = kpath.prim
|
|
48
|
+
path = kpath.path
|
|
49
|
+
kpoints = kpath.kpoints
|
|
50
|
+
|
|
51
|
+
# Write standardized POSCAR from BradCrack logic
|
|
52
|
+
standard_filename = "POSCAR_standard"
|
|
53
|
+
prim_std.to(filename=standard_filename)
|
|
54
|
+
except Exception as e:
|
|
55
|
+
print(f"❌ Error generating BradCrack path: {e}")
|
|
56
|
+
return
|
|
57
|
+
|
|
58
|
+
else:
|
|
59
|
+
# Fallback to Pymatgen logic for other modes
|
|
60
|
+
try:
|
|
61
|
+
# Map 'seekpath' alias to 'hinuma' which pymatgen uses (wrapper around seekpath)
|
|
62
|
+
if mode == "seekpath":
|
|
63
|
+
mode = "hinuma"
|
|
64
|
+
|
|
65
|
+
# Standardize structure first using SpacegroupAnalyzer
|
|
66
|
+
sga = SpacegroupAnalyzer(structure, symprec=symprec)
|
|
67
|
+
prim_std = sga.get_primitive_standard_structure()
|
|
68
|
+
except Exception as e:
|
|
69
|
+
print(f"❌ Error during standardization: {e}")
|
|
70
|
+
return
|
|
71
|
+
|
|
72
|
+
# Get high-symmetry path for the STANDARDIZED structure
|
|
73
|
+
try:
|
|
74
|
+
kpath = HighSymmKpath(prim_std, path_type=mode, symprec=symprec)
|
|
75
|
+
|
|
76
|
+
# Write the standardized primitive structure
|
|
77
|
+
standard_filename = "POSCAR_standard"
|
|
78
|
+
prim_std.to(filename=standard_filename)
|
|
79
|
+
|
|
80
|
+
# Get the path
|
|
81
|
+
path = kpath.kpath["path"]
|
|
82
|
+
kpoints = kpath.kpath["kpoints"]
|
|
83
|
+
except Exception as e:
|
|
84
|
+
print(f"❌ Error generating K-path: {e}")
|
|
85
|
+
return
|
|
86
|
+
|
|
87
|
+
# Write KPOINTS file
|
|
88
|
+
try:
|
|
89
|
+
with open(output, "w") as f:
|
|
90
|
+
f.write("KPOINTS for Band Structure\n")
|
|
91
|
+
f.write(f"{npoints}\n")
|
|
92
|
+
f.write("Line-mode\n")
|
|
93
|
+
f.write("Reciprocal\n")
|
|
94
|
+
|
|
95
|
+
for subpath in path:
|
|
96
|
+
for i in range(len(subpath) - 1):
|
|
97
|
+
start_label = subpath[i]
|
|
98
|
+
end_label = subpath[i+1]
|
|
99
|
+
|
|
100
|
+
start_coords = kpoints[start_label]
|
|
101
|
+
end_coords = kpoints[end_label]
|
|
102
|
+
|
|
103
|
+
f.write(f"{start_coords[0]:10.6f} {start_coords[1]:10.6f} {start_coords[2]:10.6f} ! {start_label}\n")
|
|
104
|
+
f.write(f"{end_coords[0]:10.6f} {end_coords[1]:10.6f} {end_coords[2]:10.6f} ! {end_label}\n")
|
|
105
|
+
f.write("\n") # Optional newline between segments
|
|
106
|
+
|
|
107
|
+
print(f"✅ Generated {output} ({' - '.join([' - '.join(seg) for seg in path])})")
|
|
108
|
+
print(f"✅ Generated {standard_filename} (Standardized Primitive Cell)")
|
|
109
|
+
print(f"\n⚠️ IMPORTANT: You MUST use '{standard_filename}' for your band calculation!")
|
|
110
|
+
print(f" The K-points are generated for this standardized orientation.")
|
|
111
|
+
print(f" Using your original POSCAR may result in incorrect paths or 'Reciprocal lattice' errors.")
|
|
112
|
+
|
|
113
|
+
except Exception as e:
|
|
114
|
+
print(f"❌ Error writing KPOINTS file: {e}")
|
|
115
|
+
|
|
116
|
+
# --- POTCAR Generation ---
|
|
117
|
+
try:
|
|
118
|
+
print("ℹ️ Generating default POTCAR (PBE)...")
|
|
119
|
+
generate_potcar(poscar_path=poscar_path, functional="PBE", output="POTCAR")
|
|
120
|
+
except Exception as e:
|
|
121
|
+
print(f"⚠️ Could not generate POTCAR: {e}")
|
|
122
|
+
print(" (Proceeding without stopping, as KPOINTS are already generated)")
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class BradCrackKpath:
|
|
127
|
+
"""
|
|
128
|
+
Native implementation of Bradley-Cracknell K-path generation.
|
|
129
|
+
Replicates logic from Sumo/SeeK-path to determine standard paths.
|
|
130
|
+
"""
|
|
131
|
+
def __init__(self, structure, symprec=0.01):
|
|
132
|
+
self.structure = structure
|
|
133
|
+
self.symprec = symprec
|
|
134
|
+
|
|
135
|
+
# Use SpacegroupAnalyzer for basic data
|
|
136
|
+
sga = SpacegroupAnalyzer(structure, symprec=symprec)
|
|
137
|
+
self._spg_data = sga.get_symmetry_dataset()
|
|
138
|
+
|
|
139
|
+
# Use SeeK-path to get primitive/conventional structures matches Sumo Kpath.__init__
|
|
140
|
+
|
|
141
|
+
# refine_cell logic from Sumo base class
|
|
142
|
+
# atom_numbers = [site.specie.number for site in structure]
|
|
143
|
+
# But pymatgen structure to spglib cell tuple:
|
|
144
|
+
# cell = (lattice, positions, numbers)
|
|
145
|
+
cell = (structure.lattice.matrix, structure.frac_coords, [s.specie.number for s in structure])
|
|
146
|
+
|
|
147
|
+
# Sumo uses spglib.refine_cell on the cell first?
|
|
148
|
+
# "std = spglib.refine_cell(sym._cell, symprec=symprec)"
|
|
149
|
+
# pymatgen sga._cell is (lattice, positions, numbers)
|
|
150
|
+
|
|
151
|
+
# seekpath.get_path takes the cell structure
|
|
152
|
+
# output is dictionary
|
|
153
|
+
self._seek_data = seekpath.get_path(cell, symprec=symprec)
|
|
154
|
+
|
|
155
|
+
# Reconstruct primitive structure from seekpath output
|
|
156
|
+
prim_lattice = self._seek_data["primitive_lattice"]
|
|
157
|
+
prim_pos = self._seek_data["primitive_positions"]
|
|
158
|
+
prim_types = self._seek_data["primitive_types"]
|
|
159
|
+
# Map types back to species?
|
|
160
|
+
# We need a map from number to Element.
|
|
161
|
+
# unique_species from sga?
|
|
162
|
+
# Let's just use explicit element list from input structure, assuming types are consistent?
|
|
163
|
+
# Or better, use sga to map Z to elements.
|
|
164
|
+
|
|
165
|
+
# Setup element mapping
|
|
166
|
+
# Create a map from atomic number to Element object from input structure
|
|
167
|
+
z_to_specie = {s.specie.number: s.specie for s in structure}
|
|
168
|
+
prim_species = [z_to_specie[z] for z in prim_types]
|
|
169
|
+
|
|
170
|
+
self.prim = Structure(prim_lattice, prim_species, prim_pos)
|
|
171
|
+
|
|
172
|
+
conv_lattice = self._seek_data["conv_lattice"]
|
|
173
|
+
conv_pos = self._seek_data["conv_positions"]
|
|
174
|
+
conv_types = self._seek_data["conv_types"]
|
|
175
|
+
conv_species = [z_to_specie[z] for z in conv_types]
|
|
176
|
+
self.conv = Structure(conv_lattice, conv_species, conv_pos)
|
|
177
|
+
|
|
178
|
+
# Now determine Bravais lattice for BradCrack
|
|
179
|
+
self._get_bradcrack_path()
|
|
180
|
+
|
|
181
|
+
def _get_bradcrack_path(self):
|
|
182
|
+
|
|
183
|
+
# Determine lattice parameters from CONVENTIONAL cell
|
|
184
|
+
a, b, c = self.conv.lattice.abc
|
|
185
|
+
angles = self.conv.lattice.angles
|
|
186
|
+
# finding unique axis for monoclinic
|
|
187
|
+
# logic from BradCrackKpath.__init__
|
|
188
|
+
# "unique = angles.index(min(angles, key=angles.count))"
|
|
189
|
+
# usually 90, 90, beta. So unique is beta (non-90) index? No.
|
|
190
|
+
# Monoclinic: alpha=gamma=90, beta!=90. 90 appears twice. non-90 appears once.
|
|
191
|
+
# min count of angle values?
|
|
192
|
+
# if angles are [90, 90, 105], counts are {90:2, 105:1}. min count is 1. value is 105. index is 2.
|
|
193
|
+
# so unique is index of non-90 degree angle.
|
|
194
|
+
|
|
195
|
+
# Round angles to avoid float issues
|
|
196
|
+
angles_r = [round(x, 3) for x in angles]
|
|
197
|
+
unique_val = min(angles_r, key=angles_r.count)
|
|
198
|
+
unique = angles_r.index(unique_val)
|
|
199
|
+
|
|
200
|
+
# Get Space Group Symbol and Number
|
|
201
|
+
# From seekpath? or sga?
|
|
202
|
+
# Sumo uses: "spg_symbol = self.spg_symbol" which is "self._spg_data['international']"
|
|
203
|
+
# spglib dataset returns 'international'
|
|
204
|
+
spg_symbol = self._spg_data["international"]
|
|
205
|
+
spg_number = self._spg_data["number"]
|
|
206
|
+
|
|
207
|
+
lattice_type = self.get_lattice_type(spg_number)
|
|
208
|
+
|
|
209
|
+
bravais = self._get_bravais_lattice(spg_symbol, lattice_type, a, b, c, unique)
|
|
210
|
+
|
|
211
|
+
# Load JSON
|
|
212
|
+
|
|
213
|
+
json_file = ilr_files("valyte.data").joinpath("bradcrack.json")
|
|
214
|
+
with open(json_file, 'r') as f:
|
|
215
|
+
data = json.load(f)
|
|
216
|
+
|
|
217
|
+
if bravais not in data:
|
|
218
|
+
raise ValueError(f"Bravais lattice code '{bravais}' not found in BradCrack data.")
|
|
219
|
+
|
|
220
|
+
self.bradcrack_data = data[bravais]
|
|
221
|
+
self.kpoints = self.bradcrack_data["kpoints"]
|
|
222
|
+
self.path = self.bradcrack_data["path"]
|
|
223
|
+
|
|
224
|
+
def get_lattice_type(self, number):
|
|
225
|
+
# Logic from Sumo
|
|
226
|
+
if 1 <= number <= 2: return "triclinic"
|
|
227
|
+
if 3 <= number <= 15: return "monoclinic"
|
|
228
|
+
if 16 <= number <= 74: return "orthorhombic"
|
|
229
|
+
if 75 <= number <= 142: return "tetragonal"
|
|
230
|
+
if 143 <= number <= 167:
|
|
231
|
+
if number in [146, 148, 155, 160, 161, 166, 167]: return "rhombohedral"
|
|
232
|
+
return "trigonal"
|
|
233
|
+
if 168 <= number <= 194: return "hexagonal"
|
|
234
|
+
if 195 <= number <= 230: return "cubic"
|
|
235
|
+
return "unknown"
|
|
236
|
+
|
|
237
|
+
def _get_bravais_lattice(self, spg_symbol, lattice_type, a, b, c, unique):
|
|
238
|
+
# Logic from Sumo BradCrackKpath._get_bravais_lattice
|
|
239
|
+
if lattice_type == "triclinic": return "triclinic"
|
|
240
|
+
|
|
241
|
+
elif lattice_type == "monoclinic":
|
|
242
|
+
if "P" in spg_symbol:
|
|
243
|
+
if unique == 0: return "mon_p_a"
|
|
244
|
+
elif unique == 1: return "mon_p_b"
|
|
245
|
+
elif unique == 2: return "mon_p_c"
|
|
246
|
+
elif "C" in spg_symbol:
|
|
247
|
+
if unique == 0: return "mon_c_a"
|
|
248
|
+
elif unique == 1: return "mon_c_b"
|
|
249
|
+
elif unique == 2: return "mon_c_c"
|
|
250
|
+
|
|
251
|
+
elif lattice_type == "orthorhombic":
|
|
252
|
+
if "P" in spg_symbol: return "orth_p"
|
|
253
|
+
elif "A" in spg_symbol or "C" in spg_symbol:
|
|
254
|
+
if a > b: return "orth_c_a"
|
|
255
|
+
elif b > a: return "orth_c_b"
|
|
256
|
+
elif "F" in spg_symbol:
|
|
257
|
+
# 1/a^2 etc conditions... need to replicate exact math
|
|
258
|
+
# Copied from Sumo source view
|
|
259
|
+
inv_a2 = 1/a**2; inv_b2 = 1/b**2; inv_c2 = 1/c**2
|
|
260
|
+
if (inv_a2 < inv_b2 + inv_c2) and (inv_b2 < inv_c2 + inv_a2) and (inv_c2 < inv_a2 + inv_b2):
|
|
261
|
+
return "orth_f_1"
|
|
262
|
+
elif inv_c2 > inv_a2 + inv_b2: return "orth_f_2"
|
|
263
|
+
elif inv_b2 > inv_a2 + inv_c2: return "orth_f_3"
|
|
264
|
+
elif inv_a2 > inv_c2 + inv_b2: return "orth_f_4"
|
|
265
|
+
elif "I" in spg_symbol:
|
|
266
|
+
if a > b and a > c: return "orth_i_a"
|
|
267
|
+
elif b > a and b > c: return "orth_i_b"
|
|
268
|
+
elif c > a and c > b: return "orth_i_c"
|
|
269
|
+
|
|
270
|
+
elif lattice_type == "tetragonal":
|
|
271
|
+
if "P" in spg_symbol: return "tet_p"
|
|
272
|
+
elif "I" in spg_symbol:
|
|
273
|
+
if a > c: return "tet_i_a"
|
|
274
|
+
else: return "tet_i_c"
|
|
275
|
+
|
|
276
|
+
elif lattice_type in ["trigonal", "hexagonal", "rhombohedral"]:
|
|
277
|
+
if "R" in spg_symbol:
|
|
278
|
+
if a > np.sqrt(2)*c: return "trig_r_a"
|
|
279
|
+
else: return "trig_r_c"
|
|
280
|
+
elif "P" in spg_symbol:
|
|
281
|
+
if unique == 0: return "trig_p_a"
|
|
282
|
+
elif unique == 2: return "trig_p_c"
|
|
283
|
+
|
|
284
|
+
elif lattice_type == "cubic":
|
|
285
|
+
if "P" in spg_symbol: return "cubic_p"
|
|
286
|
+
elif "I" in spg_symbol: return "cubic_i"
|
|
287
|
+
elif "F" in spg_symbol: return "cubic_f"
|
|
288
|
+
|
|
289
|
+
return "unknown"
|
|
@@ -27,6 +27,7 @@ from valyte.band import generate_band_kpoints
|
|
|
27
27
|
from valyte.band_plot import plot_band_structure
|
|
28
28
|
from valyte.dos_plot import load_dos, plot_dos
|
|
29
29
|
from valyte.kpoints import generate_kpoints_interactive
|
|
30
|
+
from valyte.potcar import generate_potcar
|
|
30
31
|
|
|
31
32
|
def parse_element_selection(inputs):
|
|
32
33
|
"""
|
|
@@ -116,10 +117,19 @@ def main():
|
|
|
116
117
|
kpt_gen_parser.add_argument("-i", "--input", default="POSCAR", help="Input POSCAR file")
|
|
117
118
|
kpt_gen_parser.add_argument("-n", "--npoints", type=int, default=40, help="Points per segment")
|
|
118
119
|
kpt_gen_parser.add_argument("-o", "--output", default="KPOINTS", help="Output filename")
|
|
120
|
+
kpt_gen_parser.add_argument("--symprec", type=float, default=0.01, help="Symmetry precision (default: 0.01)")
|
|
121
|
+
|
|
122
|
+
kpt_gen_parser.add_argument("--mode", default="bradcrack", help="Standardization mode (default: bradcrack)")
|
|
119
123
|
|
|
120
124
|
# --- K-Point Generation (Interactive) ---
|
|
121
125
|
subparsers.add_parser("kpt", help="Interactive K-Point Generation (SCF)")
|
|
122
126
|
|
|
127
|
+
# --- POTCAR Generation ---
|
|
128
|
+
potcar_parser = subparsers.add_parser("potcar", help="Generate POTCAR")
|
|
129
|
+
potcar_parser.add_argument("-i", "--input", default="POSCAR", help="Input POSCAR file")
|
|
130
|
+
potcar_parser.add_argument("-o", "--output", default="POTCAR", help="Output filename")
|
|
131
|
+
potcar_parser.add_argument("--functional", default="PBE", help="Functional (default: PBE)")
|
|
132
|
+
|
|
123
133
|
args = parser.parse_args()
|
|
124
134
|
|
|
125
135
|
if args.command == "dos":
|
|
@@ -169,13 +179,26 @@ def main():
|
|
|
169
179
|
print(f"❌ Error: {e}")
|
|
170
180
|
sys.exit(1)
|
|
171
181
|
|
|
182
|
+
elif args.command == "potcar":
|
|
183
|
+
try:
|
|
184
|
+
generate_potcar(
|
|
185
|
+
poscar_path=args.input,
|
|
186
|
+
functional=args.functional,
|
|
187
|
+
output=args.output
|
|
188
|
+
)
|
|
189
|
+
except Exception as e:
|
|
190
|
+
print(f"❌ Error: {e}")
|
|
191
|
+
sys.exit(1)
|
|
192
|
+
|
|
172
193
|
elif args.command == "band":
|
|
173
194
|
if args.band_command == "kpt-gen":
|
|
174
195
|
try:
|
|
175
196
|
generate_band_kpoints(
|
|
176
197
|
poscar_path=args.input,
|
|
177
198
|
npoints=args.npoints,
|
|
178
|
-
output=args.output
|
|
199
|
+
output=args.output,
|
|
200
|
+
symprec=args.symprec,
|
|
201
|
+
mode=args.mode
|
|
179
202
|
)
|
|
180
203
|
except Exception as e:
|
|
181
204
|
print(f"❌ Error: {e}")
|
|
File without changes
|