Skip to content

Commit 9896b55

Browse files
Merge pull request #122 from Zikkying/devel-1.3.0
Add APEX Skill and Update Gamma Surface with New Features
2 parents 65d7d2d + 966ccca commit 9896b55

60 files changed

Lines changed: 9076 additions & 176 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,20 @@ elastic_*
3535
template
3636
potential
3737
all_result.json
38+
usage
39+
confs
40+
41+
# Keep packaged skill reference docs (overrides the bare `reference` rule above)
42+
!apex/skills/
43+
!apex/skills/**/
44+
!apex/skills/**/reference/
45+
!apex/skills/**/reference/**
3846

3947
# dflow debug folders generated by examples or local runs
40-
**/dflow_debug/
48+
**/dflow_debug/
49+
# Generated MatMaster skill archive
50+
apex-flow.zip
51+
52+
# Large DeePMD checkpoints (fetch with scripts/fetch_models.py; keep frozen *.pb in git)
53+
apex/skills/apex-flow/models/**/*.pt
54+
apex/skills/apex-flow/models/**/*.partial

README.md

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ Create `global_bohrium.json` to submit workflows to the Bohrium cloud platform:
237237

238238
```json
239239
{
240-
"lammps_image_name": "registry.dp.tech/dptech/prod-11045/deepmdkit-phonolammps:2.1.1",
240+
"lammps_image_name": "registry.dp.tech/dptech/dp/native/prod-397637/deepmd-kit-phonolammps:3.1.3",
241241
"lammps_run_command":"lmp -in in.lammps",
242242
"scass_type":"c8_m31_1 * NVIDIA T4"
243243
}
@@ -455,7 +455,7 @@ When you run `apex submit -c global_bohrium.json`, APEX auto-fills these default
455455
- `k8s_api_server`: `https://workflows.deepmodeling.com`
456456
- `batch_type`: `Bohrium`
457457
- `context_type`: `Bohrium`
458-
- `apex_image_name`: `registry.dp.tech/dptech/dp/native/prod-397637/apex:1.3.0`
458+
- `apex_image_name`: `registry.dp.tech/dptech/dp/native/prod-397637/apex-flow:1.3.0.post`
459459
460460
Priority rule: values in your `-c` json file override account defaults.
461461
@@ -638,12 +638,31 @@ Property selection behavior:
638638
639639
### 4.5 Decohesive energy line
640640
641+
Decohesive builds a rigid-separation series on one user-specified Miller plane via pymatgen `SlabGenerator`. It does **not** auto-enumerate planes (unlike `surface`) and has **no** crystal-type nested overrides (unlike `gamma`). Any structure that can form that slab is supported; set `miller_index` explicitly.
642+
643+
Recommended default planes by crystal family (JSON `miller_index` uses **3-index** Miller notation):
644+
645+
| Crystal structure | Recommended planes | JSON `miller_index` examples |
646+
|-------------------|--------------------|------------------------------|
647+
| **FCC** | $(100)$, $(110)$, $(111)$ | `[1,0,0]`, `[1,1,0]`, `[1,1,1]` |
648+
| **BCC** | $(100)$, $(110)$, $(111)$ | `[1,0,0]`, `[1,1,0]`, `[1,1,1]` |
649+
| **Diamond** | $(100)$, $(110)$, $(111)$ | `[1,0,0]`, `[1,1,0]`, `[1,1,1]` |
650+
| **Zinc blende** | $(100)$, $(110)$, $(111)$ | `[1,0,0]`, `[1,1,0]`, `[1,1,1]` |
651+
| **Rocksalt** | $(100)$, $(110)$, $(111)$ | `[1,0,0]`, `[1,1,0]`, `[1,1,1]` |
652+
| **HCP** | $(0001)$, $(10\bar{1}0)$, $(11\bar{2}0)$ | `[0,0,1]`, `[1,0,0]`, `[1,1,0]` |
653+
| **Perovskite** | $(001)$, $(110)$, $(111)$ | `[0,0,1]`, `[1,1,0]`, `[1,1,1]` |
654+
655+
Notes:
656+
657+
- HCP must use the **3-index** values above. Four-index Miller–Bravais vectors (e.g. `[0,0,0,1]`) are **not** accepted by `decohesive` (no Bravais conversion).
658+
- Polar / multi-termination faces (common for zinc blende $(111)$ and some perovskite cuts) still generate; APEX takes the first matching slab termination from pymatgen.
659+
641660
| Key | Type | Example | Description |
642661
|-----|------|---------|-------------|
643662
| `min_slab_size` | Integer | `10` | Minimum slab thickness. |
644663
| `max_vacuum_size` | Integer | `11` | Maximum vacuum width. |
645664
| `pert_xz` | Float | `0.01` | Perturbation along xz plane for surface energy. |
646-
| `miller_miller` | List[Int] | `[1, 1, 0]` | Miller indices of the target plane. |
665+
| `miller_index` | List[Int] | `[1, 1, 0]` | Miller indices of the target plane (**required**, 3-index). |
647666
648667
### 4.6 Elastic
649668
@@ -733,6 +752,7 @@ Key parameters:
733752
| `vacuum_size` | Float | `0` | Added vacuum layer thickness (Å). |
734753
| `supercell_size` | Sequence[Int] | `[1, 1, 5]` | Slab supercell size. |
735754
| `add_fix` | Sequence[String] | `["true","true","false"]` | Position constraints along x/y/z. |
755+
| `closed_loop` | Bool | `false` | when `true`, derive two periodic in-plane translation vectors from the generated slab. and slip_length or slip_length_y will be **ignored** |
736756
737757
Example:
738758
@@ -778,6 +798,7 @@ adds vacuum along the selected fault normal for slab/free-surface calculations.
778798
"slip_direction": [1, -1, -1],
779799
"supercell_size": [1, 1, 20],
780800
"vacuum_size": 15,
801+
"closed_loop": false,
781802
"add_fix": ["true", "true", "false"],
782803
"n_steps_x": 20,
783804
"n_steps_y": 20
@@ -788,15 +809,15 @@ adds vacuum along the selected fault normal for slab/free-surface calculations.
788809
789810
APEX integrates parts of [dflow-phonon](https://github.com/Chengqian-Zhang/dflow-phonon) and wraps [Phonopy](https://github.com/phonopy/phonopy) / [phonoLAMMPS](https://github.com/abelcarreras/phonolammps). [SeeK-path](https://seekpath.readthedocs.io/en/latest/index.html) automatically generates high-symmetry k-paths.
790811
791-
> **Important:** Ensure the `run_image` (or local environment in debug mode) contains `phonoLAMMPS` when running LAMMPS-based phonon workflows.
812+
> **Important:** LAMMPS phonon and Grüneisen workflows always use `registry.dp.tech/dptech/dp/native/prod-397637/deepmd-kit-phonolammps:3.1.3`. During `apex submit`, APEX overrides any other configured LAMMPS image for these properties.
792813
793814
| Key | Type | Default | Description |
794815
|-----|------|---------|-------------|
795816
| `primitive` | Bool | `false` | Reduce to primitive cell before phonon calculation. |
796817
| `approach` | String | `"linear"` | VASP phonon method: `"linear"` or `"displacement"`. |
797818
| `supercell_size` | Sequence[Int] | `[2, 2, 2]` | Supercell dimensions. |
798819
| `MESH` | Sequence[Int] | `None` | Reciprocal-space mesh (e.g., `[8, 8, 8]`). |
799-
| `PRIMITIVE_AXES` | String | `None` | Custom primitive axes definition (`"0.0 0.5 0.5 0.5 0.0 0.5 0.5 0.5 0.0"`). |
820+
| `PRIMITIVE_AXES` | String | `"P"` | Primitive axes used consistently by phonopy and phonoLAMMPS; accepts `"P"`, `"AUTO"`, or a 3×3 matrix. |
800821
| `BAND` | String | `None` | Band path definition (falls back to SeeK-path when omitted). |
801822
| `BAND_LABELS` | String | `None` | Labels for band segments. |
802823
| `BAND_POINTS` | Integer | `51` | Number of sampling points per segment. |
@@ -820,8 +841,8 @@ APEX supports Grüneisen workflows based on phonon calculations at multiple stra
820841
| `primitive` | Bool | `false` | Reduce to primitive cell before phonon calculation. |
821842
| `approach` | String | `"linear"` | Phonon workflow approach; VASP Grüneisen currently uses linear response. |
822843
| `supercell_size` | Sequence[Int] | `[2, 2, 2]` | Phonon supercell dimensions. |
823-
| `MESH` | Sequence[Int] | `None` | Reciprocal-space mesh for mode summation. |
824-
| `PRIMITIVE_AXES` | String | `None` | Custom primitive axes definition. |
844+
| `MESH` | Sequence[Int] | `[20, 20, 20]` | Three positive reciprocal-space mesh dimensions for mode summation. |
845+
| `PRIMITIVE_AXES` | String | `"P"` | Primitive axes used consistently for displacement generation and post-processing. |
825846
| `BAND` | String | `None` | Band path definition (falls back to SeeK-path when omitted). |
826847
| `BAND_LABELS` | String | `None` | Labels for band segments. |
827848
| `BAND_POINTS` | Integer | `51` | Number of sampling points per segment. |

apex/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import os
2-
__version__ = '1.3.0.post1'
2+
__version__ = '1.3.0.post5'
33
LOCAL_PATH = os.getcwd()
44

55

apex/account.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"k8s_api_server": BOHRIUM_WORKFLOWS_HOST,
1414
"batch_type": "Bohrium",
1515
"context_type": "Bohrium",
16-
"apex_image_name": "registry.dp.tech/dptech/dp/native/prod-397637/apex:1.3.0",
16+
"apex_image_name": "registry.dp.tech/dptech/dp/native/prod-397637/apex-flow:1.3.0.post",
1717
}
1818
SENSITIVE_KEYS = {"password"}
1919
ACCOUNT_FILE_ENV = "APEX_ACCOUNT_FILE"

apex/config.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@ class Config:
6060
pool_size: int = None
6161
upload_python_packages: list = field(default_factory=list)
6262
exclude_upload_files: list = field(default_factory=list)
63-
lammps_image_name: str = None
63+
lammps_image_name: str = (
64+
"registry.dp.tech/dptech/dp/native/prod-397637/"
65+
"deepmd-kit-phonolammps:3.1.3"
66+
)
6467
lammps_run_command: str = None
6568
phonolammps_run_command: str = None
6669
vasp_image_name: str = None

apex/core/calculator/Lammps.py

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,12 @@ def _apply_gamma_fix_to_lammps_input(contents, add_fix):
123123
elif line.split()[:4] == ["variable", "N", "equal", "count(all)"]:
124124
upper_id = idx
125125
break
126-
if lower_id is None or upper_id is None:
127-
return contents
126+
if lower_id is None or upper_id is None or lower_id >= upper_id:
127+
raise RuntimeError(
128+
"Gamma add_fix was requested, but the generated LAMMPS input does "
129+
"not contain a compatible minimization block with 'min_style cg' "
130+
"and 'variable N equal count(all)' markers"
131+
)
128132
del lines[lower_id + 1 : upper_id - 1]
129133
lines.insert(lower_id + 1, add_fix_str)
130134
return "".join(lines)
@@ -386,6 +390,18 @@ def make_input_file(self, output_dir, task_type, task_param):
386390
else:
387391
raise RuntimeError("not supported calculation setting for LAMMPS")
388392

393+
elif cal_type == "static":
394+
fc = lammps_utils.make_lammps_eval(
395+
"conf.lmp", self.type_map, self.inter_func, self.model_param
396+
)
397+
elif cal_type == "finite_t_elastic":
398+
fc = lammps_utils.make_lammps_FiniteTelastic(
399+
"conf.lmp",
400+
self.type_map,
401+
self.inter_func,
402+
self.model_param,
403+
output_dir,
404+
)
389405
elif task_type in ["annealing", "Annealing"]:
390406
# MD annealing schedule: equilibrate -> ramp -> hold -> cool
391407
fc = lammps_utils.make_lammps_annealing(
@@ -396,34 +412,22 @@ def make_input_file(self, output_dir, task_type, task_param):
396412
cal_setting,
397413
)
398414

399-
elif cal_type == "static":
400-
fc = lammps_utils.make_lammps_eval(
401-
"conf.lmp", self.type_map, self.inter_func, self.model_param
402-
)
403-
elif cal_type == "npt+ave/time":
415+
elif task_type == "finite_t_latt":
404416
fc = lammps_utils.make_lammps_FiniteTlatt(
405417
"conf.lmp",
406418
self.type_map,
407419
self.inter_func,
408420
self.model_param,
409421
cal_setting,
410422
)
411-
elif cal_type == "finite_t_elastic":
412-
fc = lammps_utils.make_lammps_FiniteTelastic(
413-
"conf.lmp",
414-
self.type_map,
415-
self.inter_func,
416-
self.model_param,
417-
output_dir,
418-
)
419423

420424
else:
421425
raise RuntimeError("not supported calculation type for LAMMPS")
422426

423427
if (
424428
prop_type in {"gamma", "gamma_surface"}
425429
and cal_type == "relaxation"
426-
and "add_fix" in task_param
430+
and task_param.get("add_fix") is not None
427431
):
428432
fc = _apply_gamma_fix_to_lammps_input(fc, task_param["add_fix"])
429433

apex/core/property/Decohesive.py

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -258,17 +258,50 @@ def __gen_slab_pmg(
258258
sorted_frac_coords, sorted_species = zip(*ordered)
259259

260260
a_vec, b_vec, c_vec = slab.lattice.matrix
261-
slab_height = abs(c_vec[2])
261+
# ``reorient_lattice=False`` preserves the input orientation, so the
262+
# slab-normal c vector is not necessarily aligned with Cartesian z.
263+
# Using c_vec[2] therefore produces a zero divisor for valid surfaces
264+
# such as bcc (100) and (110), yielding NaNs in the LAMMPS data file.
265+
slab_height = np.linalg.norm(c_vec)
266+
if slab_height <= np.finfo(float).eps:
267+
raise RuntimeError("Generated slab has a zero-length c lattice vector")
262268
self.is_flip = c_vec[2] < 0
263269
elong_scale = 1 + (abs(vacuum_size) / slab_height)
264270

265-
new_lattice = [a_vec, b_vec, elong_scale * c_vec]
271+
new_lattice = np.array([a_vec, b_vec, elong_scale * c_vec], dtype=float)
266272
new_frac_coords = []
267273
for frac in sorted_frac_coords:
268-
coord = frac.copy()
274+
coord = np.array(frac, dtype=float)
269275
coord[2] = coord[2] / elong_scale
270276
new_frac_coords.append(coord)
271277

278+
# LAMMPS requires a right-handed box: det([a, b, c]) > 0.
279+
# Slab construction (odd axis permutations / mirroring) can produce a
280+
# left-handed cell; swapping a↔b restores chirality without changing
281+
# the physical slab.
282+
new_lattice, new_frac_coords = _ensure_right_handed_cell(
283+
new_lattice, new_frac_coords
284+
)
285+
272286
return Structure(
273-
lattice=np.array(new_lattice), coords=new_frac_coords, species=sorted_species
287+
lattice=new_lattice, coords=new_frac_coords, species=sorted_species
288+
)
289+
290+
291+
def _ensure_right_handed_cell(lattice, frac_coords):
292+
"""Swap a↔b when det([a, b, c]) ≤ 0 so the cell is right-handed."""
293+
lattice = np.array(lattice, dtype=float)
294+
det = np.linalg.det(lattice)
295+
if det > 0:
296+
return lattice, [np.array(fc, dtype=float) for fc in frac_coords]
297+
if abs(det) <= np.finfo(float).eps:
298+
raise RuntimeError(
299+
"Generated slab has a singular lattice (det ≈ 0); cannot convert to LAMMPS"
274300
)
301+
lattice = lattice[[1, 0, 2]]
302+
fixed_frac = []
303+
for frac in frac_coords:
304+
coord = np.array(frac, dtype=float)
305+
coord[0], coord[1] = coord[1], coord[0]
306+
fixed_frac.append(coord)
307+
return lattice, fixed_frac

0 commit comments

Comments
 (0)