ASE on your local PC (Cu-Ag-Au)
2025 June 16
The files used in this tutorial can be downloaded from CrySPY_utility/examples/ase_Cu-Ag-Au_EA-vc.
This tutorial demonstrates a test run on a local machine using ASE’s lightweight Pure Python EMT calculator.
The target system is the ternary Cu-Ag-Au system.
cryspy.in
Example of cryspy.in
.
[basic]
algo = EA-vc
calc_code = ASE
nstage = 1
njob = 5
jobcmd = zsh
jobfile = job_cryspy
[structure]
atype = Cu Ag Au
ll_nat = 0 0 0
ul_nat = 8 8 8
[ASE]
ase_python = ase_in.py
[EA]
n_pop = 20
n_crsov = 5
n_perm = 2
n_strain = 2
n_rand = 2
n_add = 3
n_elim = 3
n_subs = 3
target = random
n_elite = 2
n_fittest = 10
slct_func = TNM
t_size = 2
end_point = 0.0 0.0 0.0
maxgen_ea = 0
[option]
calc_in/
The contents under calc_in/
are the same as those in Tutorial > Random Search (RS) > ASE on your local PC.
calc_in/ase_in.py_1
from ase.constraints import FixSymmetry
from ase.filters import FrechetCellFilter
from ase.calculators.emt import EMT
from ase.optimize import BFGS
import numpy as np
from ase.io import read, write
# ---------- input structure
# CrySPY outputs 'POSCAR' as an input file in work/xxxxxx directory
atoms = read('POSCAR', format='vasp')
# ---------- setting and run
atoms.calc = EMT()
atoms.set_constraint([FixSymmetry(atoms)])
cell_filter = FrechetCellFilter(atoms, hydrostatic_strain=False)
opt = BFGS(cell_filter)
opt.run(fmax=0.01, steps=2000)
# ---------- opt. structure and energy
# [rule in ASE interface]
# output file for energy: 'log.tote' in eV/cell
# CrySPY reads the last line of 'log.tote'
# output file for structure: 'CONTCAR' in vasp format
e = cell_filter.atoms.get_total_energy()
with open('log.tote', mode='w') as f:
f.write(str(e))
# ------ write structure
opt_atoms = cell_filter.atoms.copy()
opt_atoms.set_constraint(None) # remove constraint for pymatgen
write('CONTCAR', opt_atoms, format='vasp', direct=True)
calc_in/job_cryspy
#!/bin/sh
# ---------- ASE
python3 ase_in.py > out.log
# ---------- CrySPY
sed -i -e '3 s/^.*$/done/' stat_job
ASE-CHGNet(Cu-Au)
2025 June 16
Info
CHGNet needs to be installed.
The files used in this tutorial can be downloaded from CrySPY_utility/examples/ase_chgnet_Cu-Au_EA-vc.
In this tutorial, we assume that a computing cluster with a job scheduler is used together with the machine learning potential CHGNet.
The calculation can also be performed on a local PC, so if you prefer this, please modify the input settings accordingly.
The target system is the binary Cu-Au system.
Pre-calculation
In EA-vc, the per-atom energies of each elemental phase must be used as the reference in the end_point
setting of cryspy.in
, so they need to be calculated beforehand.
There should be two directories inside the example.
Au-fcc
├── POSCAR
├── chgnet_in.py
└── job_cryspy
Cu-fcc
├── POSCAR
├── chgnet_in.py
└── job_cryspy
Each directory contains a crystal structure file (POSCAR
), a Python script (chgnet_in.py
) to perform structure relaxation and calculate energy, and a job script (job_cryspy
).
Please modify these files according to your computing environment.
Submit the job (replace the job submission command as appropriate for your system).
cd Au-fcc
qsub job_cryspy
cd ../Cu-fcc
qsub job_cryspy
cd ..
When the calculations finish successfully, a file named end_point
will be created in each directory, containing the energy per atom (eV/atom) after structure relaxation.
cat Au-fcc/end_point
-3.2357187271118164
cat Cu_fcc/end_point
-4.083529472351074
These values are then used as input for the cryspy.in
file.
cryspy.in
[basic]
algo = EA-vc
calc_code = ASE
nstage = 1
njob = 20
jobcmd = qsub
jobfile = job_cryspy
[structure]
atype = Cu Au
ll_nat = 0 0
ul_nat = 8 8
[ASE]
ase_python = chgnet_in.py
[EA]
n_pop = 20
n_crsov = 5
n_perm = 2
n_strain = 2
n_rand = 2
n_add = 3
n_elim = 3
n_subs = 3
target = random
n_elite = 2
n_fittest = 10
slct_func = TNM
t_size = 2
maxgen_ea = 0
end_point = -4.08352709 -3.23571777
[option]
calc_in/
The contents under calc_in/ are the same as those in Tutorial > Random Search (RS) > ASE on your local PC, with minor modifications for CHGNet.
Be sure to adjust paths such as the Python executable in the job script to match your computing environment.
Be sure to adjust the Python executable path in the job script.
calc_in/chgnet_in.py_1
# ---------- import
from ase.constraints import FixSymmetry
from ase.filters import FrechetCellFilter
from ase.io import read, write
from ase.optimize import FIRE, BFGS, LBFGS
from chgnet.model import CHGNetCalculator
# ---------- input structure
# CrySPY outputs 'POSCAR' as an input file in work/xxxxxx directory
atoms = read('POSCAR')
# ---------- set up
atoms.calc = CHGNetCalculator()
atoms.set_constraint([FixSymmetry(atoms)])
cell_filter = FrechetCellFilter(atoms)
opt = BFGS(cell_filter, trajectory='opt.traj')
# ---------- run
opt.run(fmax=0.01, steps=2000)
# ---------- write structure
write('opt_struc.vasp', cell_filter.atoms, format='vasp', direct=True)
# ---------- opt. structure and energy
# [rule in ASE interface]
# output file for energy: 'log.tote' in eV/cell
# CrySPY reads the last line of 'log.tote'
# output file for structure: 'CONTCAR' in vasp format
# ------ energy
e = cell_filter.atoms.get_total_energy() # eV/cell
with open('log.tote', mode='w') as f:
f.write(str(e))
# ------ struc
opt_atoms = cell_filter.atoms.copy()
opt_atoms.set_constraint(None) # remove constraint for pymatgen
write('CONTCAR', opt_atoms, format='vasp', direct=True)
calc_in/job_cryspy
#!/bin/sh
#$ -cwd
#$ -V -S /bin/bash
####$ -V -S /bin/zsh
#$ -N CuAu_CrySPY_ID
#$ -pe smp 2
# ---------- OpenMP
export OMP_NUM_THREADS=2
# ---------- ASE
/usr/local/Python-3.10.13/bin/python3 chgnet_in.py > out.log
# --------- CrySPY
sed -i -e '3 s/^.*$/done/' stat_job
Create next generation
2025 June 16
First run
When you run cryspy
, the program enters structure generation mode.
It generates the first generation of random structures and then exits.
It can be confirmed from the output that structures are generated with the number of atoms within the range specified by ll_nat
and ul_nat
.
...
[2025-06-16 10:04:45,648][cryspy_init][INFO] # ---------- Initial structure generation
[2025-06-16 10:04:45,648][rs_gen][INFO] # ------ mindist
[2025-06-16 10:04:45,650][struc_util][INFO] Cu - Cu: 1.32
[2025-06-16 10:04:45,650][struc_util][INFO] Cu - Ag: 1.385
[2025-06-16 10:04:45,650][struc_util][INFO] Cu - Au: 1.34
[2025-06-16 10:04:45,650][struc_util][INFO] Ag - Ag: 1.45
[2025-06-16 10:04:45,650][struc_util][INFO] Ag - Au: 1.405
[2025-06-16 10:04:45,650][struc_util][INFO] Au - Au: 1.36
[2025-06-16 10:04:45,650][rs_gen][INFO] # ------ generate structures
[2025-06-16 10:04:45,659][gen_pyxtal][WARNING] Compoisition [1 4] not compatible with symmetry 34: spg = 34 retry.
[2025-06-16 10:04:45,662][gen_pyxtal][WARNING] Compoisition [ 2 2 12] not compatible with symmetry 39: spg = 39 retry.
[2025-06-16 10:04:45,691][gen_pyxtal][INFO] Structure ID 0: (3, 1, 2) Space group: 82 --> 119 I-4m2
[2025-06-16 10:04:45,694][gen_pyxtal][WARNING] Compoisition [6 6 2] not compatible with symmetry 57: spg = 57 retry.
[2025-06-16 10:04:45,749][gen_pyxtal][INFO] Structure ID 1: (1, 8, 5) Space group: 71 --> 71 Immm
[2025-06-16 10:04:45,857][gen_pyxtal][INFO] Structure ID 2: (3, 7, 8) Space group: 174 --> 174 P-6
...
The file cryspy.stat
shows that the current generation’s information is being added during the EA process.
[status]
generation = 1
id_queueing = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Optimize structures
After running cryspy
several times and completing the structure optimization for the first generation, the output will appear as shown below.
...
[2025-06-16 10:25:56,962][ctrl_job][INFO] Done generation 1
[2025-06-16 10:25:56,962][ctrl_job][INFO] Calculate convex hull for generation 1
[2025-06-16 10:25:57,854][ctrl_job][INFO]
EA is ready
Convex hull
At this point, the hull distance data and the convex hull plot have been output to ./data/convex_hull/
.
ID hull distance (eV/atom) Num_atom
7 0.000000 (0, 2, 6)
14 0.036510 (1, 7, 6)
17 0.064702 (0, 1, 5)
19 0.113649 (0, 0, 8)
16 0.168530 (6, 4, 8)
9 0.186497 (8, 4, 6)
1 0.187379 (1, 8, 5)
11 0.233893 (4, 5, 4)
3 0.273365 (6, 5, 5)
10 0.326759 (1, 4, 4)
2 0.330749 (3, 7, 8)
8 0.359543 (6, 2, 7)
4 0.404169 (4, 4, 2)
18 0.422989 (0, 6, 8)
13 0.428456 (0, 6, 3)
5 0.444792 (7, 4, 7)
6 0.464305 (7, 7, 7)
12 0.556654 (3, 0, 0)
15 0.560062 (6, 7, 1)
0 0.644278 (3, 1, 2)
- conv_hull_gen_1.svg

Create next generation
Once all preparations are complete, running cryspy
again automatically creates a backup and starts generating the next-generation structures.
...
[2025-06-16 10:37:19,860][ctrl_job][INFO] Done generation 1
[2025-06-16 10:37:20,136][utility][INFO] Backup data
[2025-06-16 10:37:20,173][ea_next_gen][INFO] # ---------- Evolutionary algorithm
[2025-06-16 10:37:20,174][ea_next_gen][INFO] Generation 2
[2025-06-16 10:37:20,174][ea_next_gen][INFO] # ------ natural selection
[2025-06-16 10:37:20,177][ea_next_gen][INFO] ranking without duplication (including elite):
[2025-06-16 10:37:20,177][ea_next_gen][INFO] Structure ID 7, fitness: 0.00000
[2025-06-16 10:37:20,177][ea_next_gen][INFO] Structure ID 14, fitness: 0.03651
[2025-06-16 10:37:20,177][ea_next_gen][INFO] Structure ID 17, fitness: 0.06470
[2025-06-16 10:37:20,177][ea_next_gen][INFO] Structure ID 19, fitness: 0.11365
[2025-06-16 10:37:20,177][ea_next_gen][INFO] Structure ID 16, fitness: 0.16853
[2025-06-16 10:37:20,177][ea_next_gen][INFO] Structure ID 9, fitness: 0.18650
[2025-06-16 10:37:20,177][ea_next_gen][INFO] Structure ID 1, fitness: 0.18738
[2025-06-16 10:37:20,177][ea_next_gen][INFO] Structure ID 11, fitness: 0.23389
[2025-06-16 10:37:20,177][ea_next_gen][INFO] Structure ID 3, fitness: 0.27336
[2025-06-16 10:37:20,177][ea_next_gen][INFO] Structure ID 10, fitness: 0.32676
[2025-06-16 10:37:20,177][ea_next_gen][INFO] # ------ Generate children
[2025-06-16 10:37:20,177][ea_child][INFO] # -- mindist
[2025-06-16 10:37:20,179][struc_util][INFO] Cu - Cu: 1.32
[2025-06-16 10:37:20,179][struc_util][INFO] Cu - Ag: 1.385
[2025-06-16 10:37:20,179][struc_util][INFO] Cu - Au: 1.34
[2025-06-16 10:37:20,179][struc_util][INFO] Ag - Ag: 1.45
[2025-06-16 10:37:20,179][struc_util][INFO] Ag - Au: 1.405
[2025-06-16 10:37:20,179][struc_util][INFO] Au - Au: 1.36
[2025-06-16 10:37:20,217][crossover][INFO] Structure ID 20 (0, 4, 7) was generated from 19 and 14 by crossover. Space group: 1 P1
[2025-06-16 10:37:20,219][crossover][INFO] Structure ID 21 (0, 1, 7) was generated from 7 and 17 by crossover. Space group: 1 P1
[2025-06-16 10:37:20,221][crossover][INFO] Structure ID 22 (3, 0, 8) was generated from 16 and 19 by crossover. Space group: 1 P1
[2025-06-16 10:37:20,225][crossover][INFO] Structure ID 23 (0, 1, 7) was generated from 7 and 17 by crossover. Space group: 1 P1
...
[2025-06-16 10:37:20,809][ea_next_gen][INFO] # ------ Select elites
[2025-06-16 10:37:20,809][ea_next_gen][INFO] Structure ID 7 keeps as the elite
[2025-06-16 10:37:20,809][ea_next_gen][INFO] Structure ID 14 keeps as the elite
After that, simply running cryspy
repeatedly will advance the structure search.
Check results
This section focuses on the differences from the EA method.
cryspy_rslt
Below is an example of a cryspy_rslt
file after completing calculations up to the third generation.
In EA-vc, formation energy (Ef_eV_atom
) and number of atoms (Num_atom
) are also included.
Gen Spg_num Spg_sym Spg_num_opt Spg_sym_opt E_eV_atom Ef_eV_atom Num_atom Magmom Opt
0 1 119 I-4m2 119 I-4m2 0.639865 0.639865 (3, 1, 2) NaN no_file
1 1 71 Immm 71 Immm 0.182650 0.182650 (1, 8, 5) NaN no_file
2 1 174 P-6 187 P-6m2 0.324864 0.324864 (3, 7, 8) NaN no_file
3 1 71 Immm 71 Immm 0.269227 0.269227 (6, 5, 5) NaN no_file
4 1 12 C2/m 65 Cmmm 0.401521 0.401521 (4, 4, 2) NaN no_file
7 1 123 P4/mmm 123 P4/mmm -0.009930 -0.009930 (0, 2, 6) NaN no_file
10 1 107 I4mm 107 I4mm 0.320875 0.320875 (1, 4, 4) NaN no_file
5 1 121 I-42m 121 I-42m 0.439643 0.439643 (7, 4, 7) NaN no_file
6 1 115 P-4m2 115 P-4m2 0.459892 0.459892 (7, 7, 7) NaN no_file
8 1 81 P-4 81 P-4 0.354247 0.354247 (6, 2, 7) NaN no_file
9 1 11 P2_1/m 11 P2_1/m 0.182084 0.182084 (8, 4, 6) NaN no_file
11 1 10 P2/m 10 P2/m 0.229819 0.229819 (4, 5, 4) NaN no_file
nat_data
Information on the number of atoms is also included in nat_data
.
ID ('Cu', 'Ag', 'Au')
0 (3, 1, 2)
1 (1, 8, 5)
2 (3, 7, 8)
3 (6, 5, 5)
4 (4, 4, 2)
5 (7, 4, 7)
6 (7, 7, 7)
7 (0, 2, 6)
8 (6, 2, 7)
9 (8, 4, 6)
10 (1, 4, 4)
...
hull_dist_all_gen_x
For example, after the third generation is completed, the hull distance data is output to the file ./convex_hull/hull_dist_all_gen_3
.
ID hull distance (eV/atom) Num_atom
43 0.000000 (0, 2, 5)
42 0.000000 (0, 5, 5)
48 0.000000 (0, 1, 5)
46 0.000009 (0, 1, 5)
28 0.000011 (0, 1, 5)
41 0.000360 (0, 4, 6)
47 0.001838 (0, 1, 5)
36 0.001992 (1, 1, 6)
21 0.002544 (0, 1, 7)
23 0.002551 (0, 1, 7)
24 0.002795 (0, 4, 7)
conv_hull_gen_x.svg
The convex hull plot at the end of generation 3 is saved as ./convex_hull/conv_hull_gen_3.svg
.
Although svg is the default format, it can be changed to pdf or png by modifying the fig_format
in the input file.

Analysis and visualization
Automatic convex hull plotting
In EA-vc simulations of binary and ternary systems, a convex hull plot is automatically generated at the end of each generation.
For further customization, you can edit the plot yourself using a Jupyter notebook.
For quaternary systems, visualization using Plotly with Jupyter is available (Plotly should already be installed automatically, as it is a dependency of pymatgen).
Below are some usage examples.
Binary system

The above figure shows an example after search up to the third generation, with red labels added for explanation.
The input file settings related to convex hull plotting are listed below (default values in parentheses).
show_max
: Upper limit of the y-axis (0.2)label_stable
: Whether to display compositions of stable phases (True)vmax
: Maximum value of the colorbar on the right (0.2)bottom_margin
: Margin between the minimum value and the lower end of the y-axis (0.02)fig_format
: File format of the output figure. Supported formats: svg, png, pdf. (svg)
Each marker corresponding to the latest generation is marked with a cross.
Ternary system

The above figure shows an example after search up to the third generation, with red labels added for explanation.
The input file settings related to convex hull plotting are listed below (default values in parentheses).
show_max
: Only entries with a hull distance less than or equal to show_max are plotted. (0.2)label_stable
: Whether to display compositions of stable phases (True)vmax
: Maximum value of the colorbar on the right (0.2)bottom_margin
: Not applicable to ternary systemsfig_format
: File format of the output figure. Supported formats: svg, png, pdf. (svg)
Each marker corresponding to the latest generation is marked with a cross.
Download data
It is assumed here that you analyze and visualize CrySPY data on your local PC.
If you use CrySPY on a supercomputer or workstation, download the data to your local machine.
You can delete the work
and backup
directories if they are not needed, as their file size can be very large.
Jupyter notebook
Move to the data/ directory in the results you downloaded earlier.
Then, if the CrySPY utility has already been downloaded locally, copy cryspy_analyzer_EA-vc.ipynb
.
Alternatively, you can download it directly from GitHub (CrySPY_utility/notebook/).
The Jupyter notebook file includes the same functions as the CrySPY code, allowing you to freely customize the convex hull plots.
Execute the cells in order as appropriate, and choosing one of the following options will produce the same plot as the automatic output.
- Binary system, matplotlib
- Ternary system, matplotlib
In the section
- Interactive plot using Plotly,
interactive plots using Plotly are available for binary, ternary, and quaternary systems.
See CrySPY > Tutorial > Interactive Mode (Jupyter Notebook) #Interactive plot using Plotly for example plots.