Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
720ef4a
phonopy v4.1.0 compatible check
Zikkying Jul 7, 2026
eb5da9e
Add apex-flow Cursor skill for APEX workflow orchestration
Jul 14, 2026
41166fb
Merge pull request #3 from Letian88/devel-1.3.0
Zikkying Jul 14, 2026
3b9102a
Ship apex-skill package with combo screening and env project ID
Zikkying Jul 16, 2026
3943547
Harden apex-skill workflow guidance and packaging
Zikkying Jul 16, 2026
1332cbd
Improve gamma-surface workflow robustness
Zikkying Jul 16, 2026
f4c4ca6
rename skill name from apex-skill to apex-flow
Zikkying Jul 16, 2026
28516da
shorten prompt
Zikkying Jul 16, 2026
cf1a1fd
Agent default use submit -s for saving
Zikkying Jul 16, 2026
5fd4f29
Fix phonon displacement task ordering
Zikkying Jul 16, 2026
9e06672
Update DeepMD-kit with phonolammps supported docker. Now Default Dock…
Zikkying Jul 17, 2026
60177f5
Merge deepmodeling/devel-1.3.0 into PR branch
Zikkying Jul 17, 2026
db79d57
Bump package version to 1.3.0.post2
Zikkying Jul 17, 2026
b868abf
Use blocking APEX skill submissions
Zikkying Jul 17, 2026
01db0d6
Replace bundled DPA2 model with DPA-3.2-5M
Zikkying Jul 17, 2026
eccaf14
Update default APEX image to post2
Zikkying Jul 17, 2026
e3052eb
Test apex-flow skill configuration scripts
Zikkying Jul 17, 2026
8e15fdf
Validate Bohrium project IDs before submission
Zikkying Jul 18, 2026
bdcee37
Fix Grüneisen support for Phonopy 4
Zikkying Jul 18, 2026
b024e51
Enhance RSS Workflow and Configuration Management
Zikkying Jul 18, 2026
63afad7
Fix decohesive slabs for tilted lattice vectors
Zikkying Jul 18, 2026
3a47016
Release apex-flow 1.3.0.post3
Zikkying Jul 18, 2026
ccc9e1c
Force upgrade latest apex
Zikkying Jul 18, 2026
0cb370f
Ensure decohesive slabs stay right-handed for LAMMPS.
Zikkying Jul 18, 2026
9a90b05
Harden apex-flow skill for batch jobs, RSS, and VASP POTCAR uploads.
Zikkying Jul 19, 2026
e8af1b4
Release apex-flow 1.3.0.post4 and switch default Bohrium image to 1.3…
Zikkying Jul 19, 2026
c80a9d5
Fix skill script test for default VASP potcar_prefix.
Zikkying Jul 19, 2026
b5a253c
Stage VASP POTCARs into job root with potcar_prefix '.'.
Zikkying Jul 19, 2026
b639671
Fix validate_interaction test for required VASP potcar_prefix.
Zikkying Jul 19, 2026
48c7914
Require DFT k-spacing and license-gated VASP image discovery.
Zikkying Jul 19, 2026
966ccca
Release apex-flow 1.3.0.post5.
Zikkying Jul 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,20 @@ elastic_*
template
potential
all_result.json
usage
confs

# Keep packaged skill reference docs (overrides the bare `reference` rule above)
!apex/skills/
!apex/skills/**/
!apex/skills/**/reference/
!apex/skills/**/reference/**

# dflow debug folders generated by examples or local runs
**/dflow_debug/
**/dflow_debug/
# Generated MatMaster skill archive
apex-flow.zip

# Large DeePMD checkpoints (fetch with scripts/fetch_models.py; keep frozen *.pb in git)
apex/skills/apex-flow/models/**/*.pt
apex/skills/apex-flow/models/**/*.partial
35 changes: 28 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ Create `global_bohrium.json` to submit workflows to the Bohrium cloud platform:

```json
{
"lammps_image_name": "registry.dp.tech/dptech/prod-11045/deepmdkit-phonolammps:2.1.1",
"lammps_image_name": "registry.dp.tech/dptech/dp/native/prod-397637/deepmd-kit-phonolammps:3.1.3",
"lammps_run_command":"lmp -in in.lammps",
"scass_type":"c8_m31_1 * NVIDIA T4"
}
Expand Down Expand Up @@ -455,7 +455,7 @@ When you run `apex submit -c global_bohrium.json`, APEX auto-fills these default
- `k8s_api_server`: `https://workflows.deepmodeling.com`
- `batch_type`: `Bohrium`
- `context_type`: `Bohrium`
- `apex_image_name`: `registry.dp.tech/dptech/dp/native/prod-397637/apex:1.3.0`
- `apex_image_name`: `registry.dp.tech/dptech/dp/native/prod-397637/apex-flow:1.3.0.post`

Priority rule: values in your `-c` json file override account defaults.

Expand Down Expand Up @@ -638,12 +638,31 @@ Property selection behavior:

### 4.5 Decohesive energy line

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.

Recommended default planes by crystal family (JSON `miller_index` uses **3-index** Miller notation):

| Crystal structure | Recommended planes | JSON `miller_index` examples |
|-------------------|--------------------|------------------------------|
| **FCC** | $(100)$, $(110)$, $(111)$ | `[1,0,0]`, `[1,1,0]`, `[1,1,1]` |
| **BCC** | $(100)$, $(110)$, $(111)$ | `[1,0,0]`, `[1,1,0]`, `[1,1,1]` |
| **Diamond** | $(100)$, $(110)$, $(111)$ | `[1,0,0]`, `[1,1,0]`, `[1,1,1]` |
| **Zinc blende** | $(100)$, $(110)$, $(111)$ | `[1,0,0]`, `[1,1,0]`, `[1,1,1]` |
| **Rocksalt** | $(100)$, $(110)$, $(111)$ | `[1,0,0]`, `[1,1,0]`, `[1,1,1]` |
| **HCP** | $(0001)$, $(10\bar{1}0)$, $(11\bar{2}0)$ | `[0,0,1]`, `[1,0,0]`, `[1,1,0]` |
| **Perovskite** | $(001)$, $(110)$, $(111)$ | `[0,0,1]`, `[1,1,0]`, `[1,1,1]` |

Notes:

- 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).
- Polar / multi-termination faces (common for zinc blende $(111)$ and some perovskite cuts) still generate; APEX takes the first matching slab termination from pymatgen.

| Key | Type | Example | Description |
|-----|------|---------|-------------|
| `min_slab_size` | Integer | `10` | Minimum slab thickness. |
| `max_vacuum_size` | Integer | `11` | Maximum vacuum width. |
| `pert_xz` | Float | `0.01` | Perturbation along xz plane for surface energy. |
| `miller_miller` | List[Int] | `[1, 1, 0]` | Miller indices of the target plane. |
| `miller_index` | List[Int] | `[1, 1, 0]` | Miller indices of the target plane (**required**, 3-index). |

### 4.6 Elastic

Expand Down Expand Up @@ -733,6 +752,7 @@ Key parameters:
| `vacuum_size` | Float | `0` | Added vacuum layer thickness (Å). |
| `supercell_size` | Sequence[Int] | `[1, 1, 5]` | Slab supercell size. |
| `add_fix` | Sequence[String] | `["true","true","false"]` | Position constraints along x/y/z. |
| `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** |

Example:

Expand Down Expand Up @@ -778,6 +798,7 @@ adds vacuum along the selected fault normal for slab/free-surface calculations.
"slip_direction": [1, -1, -1],
"supercell_size": [1, 1, 20],
"vacuum_size": 15,
"closed_loop": false,
"add_fix": ["true", "true", "false"],
"n_steps_x": 20,
"n_steps_y": 20
Expand All @@ -788,15 +809,15 @@ adds vacuum along the selected fault normal for slab/free-surface calculations.

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.

> **Important:** Ensure the `run_image` (or local environment in debug mode) contains `phonoLAMMPS` when running LAMMPS-based phonon workflows.
> **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.

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| `primitive` | Bool | `false` | Reduce to primitive cell before phonon calculation. |
| `approach` | String | `"linear"` | VASP phonon method: `"linear"` or `"displacement"`. |
| `supercell_size` | Sequence[Int] | `[2, 2, 2]` | Supercell dimensions. |
| `MESH` | Sequence[Int] | `None` | Reciprocal-space mesh (e.g., `[8, 8, 8]`). |
| `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"`). |
| `PRIMITIVE_AXES` | String | `"P"` | Primitive axes used consistently by phonopy and phonoLAMMPS; accepts `"P"`, `"AUTO"`, or a 3×3 matrix. |
| `BAND` | String | `None` | Band path definition (falls back to SeeK-path when omitted). |
| `BAND_LABELS` | String | `None` | Labels for band segments. |
| `BAND_POINTS` | Integer | `51` | Number of sampling points per segment. |
Expand All @@ -820,8 +841,8 @@ APEX supports Grüneisen workflows based on phonon calculations at multiple stra
| `primitive` | Bool | `false` | Reduce to primitive cell before phonon calculation. |
| `approach` | String | `"linear"` | Phonon workflow approach; VASP Grüneisen currently uses linear response. |
| `supercell_size` | Sequence[Int] | `[2, 2, 2]` | Phonon supercell dimensions. |
| `MESH` | Sequence[Int] | `None` | Reciprocal-space mesh for mode summation. |
| `PRIMITIVE_AXES` | String | `None` | Custom primitive axes definition. |
| `MESH` | Sequence[Int] | `[20, 20, 20]` | Three positive reciprocal-space mesh dimensions for mode summation. |
| `PRIMITIVE_AXES` | String | `"P"` | Primitive axes used consistently for displacement generation and post-processing. |
| `BAND` | String | `None` | Band path definition (falls back to SeeK-path when omitted). |
| `BAND_LABELS` | String | `None` | Labels for band segments. |
| `BAND_POINTS` | Integer | `51` | Number of sampling points per segment. |
Expand Down
2 changes: 1 addition & 1 deletion apex/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import os
__version__ = '1.3.0.post1'
__version__ = '1.3.0.post5'
LOCAL_PATH = os.getcwd()


Expand Down
2 changes: 1 addition & 1 deletion apex/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"k8s_api_server": BOHRIUM_WORKFLOWS_HOST,
"batch_type": "Bohrium",
"context_type": "Bohrium",
"apex_image_name": "registry.dp.tech/dptech/dp/native/prod-397637/apex:1.3.0",
"apex_image_name": "registry.dp.tech/dptech/dp/native/prod-397637/apex-flow:1.3.0.post",
}
SENSITIVE_KEYS = {"password"}
ACCOUNT_FILE_ENV = "APEX_ACCOUNT_FILE"
Expand Down
5 changes: 4 additions & 1 deletion apex/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,10 @@ class Config:
pool_size: int = None
upload_python_packages: list = field(default_factory=list)
exclude_upload_files: list = field(default_factory=list)
lammps_image_name: str = None
lammps_image_name: str = (
"registry.dp.tech/dptech/dp/native/prod-397637/"
"deepmd-kit-phonolammps:3.1.3"
)
lammps_run_command: str = None
phonolammps_run_command: str = None
vasp_image_name: str = None
Expand Down
36 changes: 20 additions & 16 deletions apex/core/calculator/Lammps.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,12 @@ def _apply_gamma_fix_to_lammps_input(contents, add_fix):
elif line.split()[:4] == ["variable", "N", "equal", "count(all)"]:
upper_id = idx
break
if lower_id is None or upper_id is None:
return contents
if lower_id is None or upper_id is None or lower_id >= upper_id:
raise RuntimeError(
"Gamma add_fix was requested, but the generated LAMMPS input does "
"not contain a compatible minimization block with 'min_style cg' "
"and 'variable N equal count(all)' markers"
)
del lines[lower_id + 1 : upper_id - 1]
lines.insert(lower_id + 1, add_fix_str)
return "".join(lines)
Expand Down Expand Up @@ -386,6 +390,18 @@ def make_input_file(self, output_dir, task_type, task_param):
else:
raise RuntimeError("not supported calculation setting for LAMMPS")

elif cal_type == "static":
fc = lammps_utils.make_lammps_eval(
"conf.lmp", self.type_map, self.inter_func, self.model_param
)
elif cal_type == "finite_t_elastic":
fc = lammps_utils.make_lammps_FiniteTelastic(
"conf.lmp",
self.type_map,
self.inter_func,
self.model_param,
output_dir,
)
elif task_type in ["annealing", "Annealing"]:
# MD annealing schedule: equilibrate -> ramp -> hold -> cool
fc = lammps_utils.make_lammps_annealing(
Expand All @@ -396,34 +412,22 @@ def make_input_file(self, output_dir, task_type, task_param):
cal_setting,
)

elif cal_type == "static":
fc = lammps_utils.make_lammps_eval(
"conf.lmp", self.type_map, self.inter_func, self.model_param
)
elif cal_type == "npt+ave/time":
elif task_type == "finite_t_latt":
fc = lammps_utils.make_lammps_FiniteTlatt(
"conf.lmp",
self.type_map,
self.inter_func,
self.model_param,
cal_setting,
)
elif cal_type == "finite_t_elastic":
fc = lammps_utils.make_lammps_FiniteTelastic(
"conf.lmp",
self.type_map,
self.inter_func,
self.model_param,
output_dir,
)

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

if (
prop_type in {"gamma", "gamma_surface"}
and cal_type == "relaxation"
and "add_fix" in task_param
and task_param.get("add_fix") is not None
):
fc = _apply_gamma_fix_to_lammps_input(fc, task_param["add_fix"])

Expand Down
41 changes: 37 additions & 4 deletions apex/core/property/Decohesive.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,17 +258,50 @@ def __gen_slab_pmg(
sorted_frac_coords, sorted_species = zip(*ordered)

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

new_lattice = [a_vec, b_vec, elong_scale * c_vec]
new_lattice = np.array([a_vec, b_vec, elong_scale * c_vec], dtype=float)
new_frac_coords = []
for frac in sorted_frac_coords:
coord = frac.copy()
coord = np.array(frac, dtype=float)
coord[2] = coord[2] / elong_scale
new_frac_coords.append(coord)

# LAMMPS requires a right-handed box: det([a, b, c]) > 0.
# Slab construction (odd axis permutations / mirroring) can produce a
# left-handed cell; swapping a↔b restores chirality without changing
# the physical slab.
new_lattice, new_frac_coords = _ensure_right_handed_cell(
new_lattice, new_frac_coords
)

return Structure(
lattice=np.array(new_lattice), coords=new_frac_coords, species=sorted_species
lattice=new_lattice, coords=new_frac_coords, species=sorted_species
)


def _ensure_right_handed_cell(lattice, frac_coords):
"""Swap a↔b when det([a, b, c]) ≤ 0 so the cell is right-handed."""
lattice = np.array(lattice, dtype=float)
det = np.linalg.det(lattice)
if det > 0:
return lattice, [np.array(fc, dtype=float) for fc in frac_coords]
if abs(det) <= np.finfo(float).eps:
raise RuntimeError(
"Generated slab has a singular lattice (det ≈ 0); cannot convert to LAMMPS"
)
lattice = lattice[[1, 0, 2]]
fixed_frac = []
for frac in frac_coords:
coord = np.array(frac, dtype=float)
coord[0], coord[1] = coord[1], coord[0]
fixed_frac.append(coord)
return lattice, fixed_frac
Loading