Subsections of CrySPY document

Subsections of Version Information

Version 1.5.0

Important change

Composition constraints in EA-vc

  • Added min_comp and max_comp to specify lower and upper bounds on each atom type’s composition fraction. These constraints can be combined with charge neutrality.
  • Features > Composition Constraints

Input file

  • Moved plotting parameters from the [EA] section to the new [visual] section.
  • Deprecated cgen. Use plot_min_gen and plot_max_gen to select generations to display, and ref_gen to specify the reference generation.
  • Renamed the reference energies for formation energy calculations from end_point to ref_energies. end_point is still accepted for backward compatibility.
  • Removed target and timeout_mol.
  • Input File > [EA] Section, Input File > [visual] Section, Input File > [structure] Section

Common

  • Updated the minimum requirements to Python 3.10 and PyXtal 1.0.7.
  • Removed support for using random and evolutionary structure generation as a standalone library.

Added

Subcommand

  • cryspy-print: Display the contents or a summary of a pickle file. For rslt_data.pkl, row selection, composition filtering, and regeneration of text result files are also supported.
  • cryspy-extract-struc: Extract structures from structure data and save them as CIF files or display their information.
  • Integrated these commands into CrySPY as replacements for CrySPY Utility’s print_pkl.py and extract_struc.py.

Plotting and replotting

  • Added support for RS and EA energy plots in cryspy-Eplot.
  • Added separate controls for the displayed generation range and the reference generation in EA and EA-vc.
  • Added axis_order to change element positions and support for displaying the allowed composition range in EA-vc.
  • Added cryspy-Eplot -c to check the allowed composition range specified in the input before starting a search.
  • Added terminals to plot convex hulls with compound terminals.
  • Commands > cryspy-Eplot, Input File > [visual] Section

Input parameters

Niggli reduction

Result and figure output

  • Added rslt_out to control when cryspy_rslt and cryspy_rslt_energy_asc are written. The default is always.
  • Added energy_output_interval to control the output interval for EA energy plots and EA-vc convex hull plots and hull-distance files. The default is 1 (every generation); 0 disables automatic output.
  • EA-vc convex hulls and hull distances are still calculated every generation, regardless of the output interval.
  • Input File > [option] Section

Charge neutrality condition

  • Improved the calculation of atom-count combinations that satisfy charge neutrality.
  • Added support for multivalent species, for example, charge = (2 3) -2.
  • Added cn_mode to select enumeration or sampling of atom-count combinations. In auto mode, the method is selected based on max_cn_grid_points.
  • Features > Charge Neutrality Condition

Backup

  • Added backup_interval to specify the automatic backup interval.
  • Backup directory names now include the progress number and unit. Manual backups also include manual.
  • Features > Backup

Changed

Default values in EA-vc

Loading initial structures

  • Added stricter validation of data loaded with load_struc_flag = True. Structure IDs, structure counts, atom types, and atom counts are checked. EA-vc also checks composition constraints and charge neutrality.
  • If fewer structures than required are loaded, the remaining structures are generated randomly.
  • Features > Loading Initial Structures

Fixed

  • Fixed an infinite loop in EA parent selection when the same parent was repeatedly selected while attempting to choose two distinct parents.
  • Fixed roulette selection probabilities when all candidates have the same fitness.
  • Fixed EA-vc elite reselection after changes to atom-count bounds, composition constraints, or n_elite. Elites are now reselected from past results.
  • Fixed errors when structures excluded from convex hull calculations were considered as elites or parent candidates in EA-vc.
  • Fixed a missing random number generator argument in the atom-addition step of crossover that affected reproducibility.
  • Fixed cases where lock_cryspy was left behind after input errors in interactive mode.

Version 1.4.3

Fixed

  • Elimintion in EA-vc: fixed a bug that let the atom count go below the minimum.
  • Substitution in EA-vc: fixed a bug where the atom count went negative mid-run.

Version 1.4.2

Important change

Added

Changed

Job file auto-rewriting

Priority order of structure optimization input file names

x is the stage number.

  1. x_ase_in.py
  2. ase_in.py_x
  3. ase_in.py

In previous versions, the second style ase_in.py_x was used.

Fixed

  • Fixed a bug in mindist check after structure optimization (when structure data could not be obtained correctly)

Version 1.4.1

Important change

EA-vc

Added

Charge neutral condition

Subcommand

Version 1.4.0

Important change

New algorithm: EA-vc

Interactive mode

EA

  • tot_struc is no longer used in EA. The number of structures in the first generation is now determined by n_pop.

Interatomic distance check after structrue optimization

  • Added check_mindist_opt to the [option] section in cryspy.in.
  • Default: check_mindist_opt = True.
  • After structure relaxation, a check is performed to ensure that the minimum interatomic distance constraint is satisfied.

Common

  • The natot parameter in cryspy.in has been removed.
  • Ctrl_ext has been removed.

Fixed

  • Fixed a bug related to using TS as the score in BO.
  • Several other minor fixes.

Version 1.3.0

Important change

Common

  • working directory name
    work000000 –> work0
  • We used to pickle data by grouping several data into tuples, but we changed it to pickle each item individually.
    For example, rs_id_data.pkl –> id_queueing.pkl and id_running.pkl

BO

Fixed

soiap

  • support for recent pymatgen

Added

  • Random structure generation and structure generation by EA are now available as libraries. (removed in version 1.5.0)

for developer

  • We stopped using global variables (rin), now uses dataclass for input data.
  • Many of the input variables were lists, but we changed them to tuples.

Version 1.2.5

Bug fix

  • simple bug fix

Version 1.2.4

Bug fix

EA

  • default value of cls_lat: equal –> random

EA-vc

  • test version of variable composition EA (EA-vc). only binary system for now.

Version 1.2.2

Enthalpy

You can use enthalpy instead of energy for VASP and QE.

See also

Version 1.2.1

ASE interface

Bug fixed for multiple stages.

Version 1.1.1

Bug fix for spg_error

In random structure generation, when a structure cannot be generated for a certain space group, the space group number is recorded in the variable sgp_error, and the number is skipped thereafter, but a bug was found in which the number was registered incorrectly in rare cases. Therefore, this spg_error function has been removed.

Version 1.1.0

Parallelization with MPI

Random structure generation using MPI has been available.

See also

LAQA

Updated score formula to take into account the stress term (T. Yamashita and H. Sekine, Sci. Technol. Adv. Mater. Meth. 2, 84 (2022).).

See also

Backup

Files are copied to the directory named by the date and time in “backup” directory.
See features/backup in detail.

Version 1.0.0

Install and run

CrySPY is now available in PyPI. You can install by

pip install csp-cryspy

The executable script, cryspy is automatically installed in your PATH. To run CrySPY, just type cryspy:

cryspy &

CrySPY stops once before going to next selection (BO, LAQA) or next generation (EA). For example, EA case:

[old version]

  • cryspy run
    • check jobs (finish current generation?)
    • structure generation by EA automatically starts

[CrySPY 1.0.0]

  • cryspy run
    • check jobs (finish current generation?)
    • stop
  • cryspy run
    • auto backup
    • structure generation by EA automatically starts

Auto and manual backup

Automatically backup:

  • before going to next selection or next generation
  • structure generation

To manually back up:

cryspy -b

See features/backup in detail.

Clean

cryspy -c

See features/clean in detail.

Directory tree

Changed the directory tree.

  • genstruc/RS –> RS/
  • genstruc/EA –> EA/
  • genstruc/struc_util.py –> util/
  • utility.py –> util/

IO

  • Fixed standard output file and standard error file: log_cryspy and err_cryspy
  • cryspy.out is obsoleted

Moved to CrySPY Utility

With the change in installation method, examples and cal_fingerprint have been moved to the CrySPY Utility.

COMBO

The python library COMBO is now optional in CrySPY. If you do not use Bayesian optimizaion, you do not need to install it.

New calc_code

  • ext: Deprecated in version 1.4.0.

cryspy.in

fppath

New input variable for cal_fingerprint. See Instllation/cryspy/cryspy_1.0

fwpath

New input variable for find_wy. See Instllation/requirements/find_wy

mindist

  • mindist can be omitted in cryspy.in
  • mindist_ea is obsoleted
  • added mindist_mol_bs and mindist_mol_bs_factor in cryspy.in

Version 0.10.3 or earlier

  • [2022 May 17] version 0.10.3 released
    • Bug fixed: LAMMPS IO.
  • [2022 January 24] version 0.10.2 released
    • Added nrot: maximum number of times to rotate molecules in mol_bs
  • [2021 September 30] version 0.10.1 released
    • Fixed the problem of numpy.random.seed in multiprocessing
  • [2021 July 25] version 0.10.0 released
    • Support PyXtal 0.2.9 or later
    • LAQA can be used with QE
    • Upper and lower limits of energy for EA and BO
  • [2021 July 13] paper published
    • Our paper on CrySPY software has been published in STAM:Methods
  • [2021 March 18] version 0.9.2 released
    • Support pymatgen v2022.
  • [2021 February 7] version 0.9.0 released
    • Interfaced with OpenMX
    • Employ PyXtal library to generate initial structures
    • If you use PyXtal (default), find_wy program is not required
    • LAQA can be used with soiap
    • Change the name: [lattice] section –> [structure] section
    • Several input variables move to [structure] section
      • natot: [basic] –> [structure]
      • atype: [basic] –> [structure]
      • nat: [basic] –> [structure]
      • maxcnt: [option] –> [structure]
      • symprec: [option] –> [structure]
      • spgnum: [option] –> [structure]
    • New features
      • Molecular crystal structure generation
      • Scale volume
  • [2020 March 19] paper published
  • [2020 February 16] version 0.8.0 released
    • Migrate to Python 3
    • CrySPY logo created
    • Change several variable names and data formats
    • Change style of output for energy: eV/cell –> eV/atom
    • IDs of working directories corresponds to structure IDs
    • New features
      • recalculation
      • manual select in BO
  • [2018 December 5] version 0.7.0 released
    • New features
      • Evolutionary algorithm
  • [2018 August 20] version 0.6.4 released
  • [2018 July 2] version 0.6.3 released
  • [2018 June 26] Version 0.6.2 released
  • [2018 March 1] Version 0.6.1 released
  • [2018 January 9] paper published

Subsections of Installation

Python

Last updated: October 17, 2026

Python

CrySPY 1.5.0 or Later

  • Python >= 3.10
    • PyXtal (>= 1.0.7)
    • (optional) mpi4py
    • (optional, required if algo is BO) PHYSBO
    • (optional, required if algo is BO) dscribe
    • (optional) nglview

Installing csp-cryspy with pip automatically installs required libraries such as PyXtal, pymatgen, and ASE. See Installation > CrySPY 1.3.0 or Later for details.

CrySPY 1.3.0 – 1.4.3

  • Python >= 3.9
    • PyXtal (>= 0.5.3)
    • (optional) mpi4py
    • (optional, required if algo is BO) PHYSBO (Not COMBO)
    • (optional, required if algo is BO) dscribe
    • (optional) nglview

If you install csp-cryspy with pip, necessary libraries such as PyXtal, pymatgen, and ASE will be installed automatically. Go to Installation > CrySPY for detail.

2025 June 17, Tested and confirmed to work in the following environments (as installed via pip install csp-cryspy)

  • python 3.13.5
  • CrySPY 1.4.0
  • numpy 1.26.4 (with physbo) and 2.3.0(without physbo. physbo requires numpy < 2.0)
  • pandas 2.3.0
  • pymatgen 2025.6.14
  • pyxtal 1.0.9
  • scipy 1.15.3

Quick Install

pip install csp-cryspy

When using BO

pip install dscribe physbo

CrySPY 1.1.0 – 1.2.5

  • Python >= 3.8
    • PyXtal (>= 0.5.3)
    • (optional) mpi4py
    • (optional, required if algo is BO) COMBO

If you install csp-cryspy with pip, necessary libraries such as PyXtal will be installed automatically. Go to Installation > CrySPY. Manual installation of COMBO is required when using Bayesian optimization.

CrySPY 1.0.0

  • Python >= 3.8
    • PyXtal (>= 0.5.3)
    • (optional, required if algo is BO) COMBO
Info

[2023 April 22] How to instlal PyXtal (pyshtools) on arm64 MacOS is figured out. See Arm64 on MacOS (without Rosseta 2)
[2023 March 15] On MacOS, it is difficult to install PyXtal in the arm64 environment, so it is recommended to use the x86_64 environment with Rosetta 2.

CrySPY 0.10.0 – 0.10.3

Tested with Homebrew Python 3.8.x and 3.9.x on Mac and Python 3.8.x on Linux.

CrySPY 0.9.2

Tested with Homebrew Python 3.8.x and 3.9.x on Mac and Python 3.8.x on Linux.

Info

[2021 July 15] If you use PyXtal >= 0.2.9, update CrySPY to the version 0.10.0 or later.

Info

[2021 March 18] There is a breaking change in pymatgen 2022.x.x. CrySPY 0.9.2 and PyXtal 0.2.2 support this change in pymatgen.

Info

[2021 Feb. 5] PyXtal depends on numba, but numba does not support Python 3.9. So you should use Python 3.8.x for a while.
[2021 March 18] Currently numba supports Python 3.9.x.

Info

[2021 Feb. 7] PyXtal requires SciPy, but the latest version of SciPy (v1.6.0) might include a bug for deepcopy. You should use SciPy v1.5.4 for a while.
[2021 March 18] This bug has been fixed in SciPy v1.6.1.

CrySPY 0.9.0 – 0.9.1

CrySPY 0.8.0 or Earlier

See the old document which is included CrySPY itself.

CrySPY 1.3.0 or Later

Last updated: July 9, 2026

CrySPY

pip

pip install csp-cryspy

Please note that the name is csp-cryspy on PyPI, not cryspy. The main command, cryspy, is automatically installed in your PATH. You can check by

which cryspy

From version 1.4.1, several additional subcommand are also installed.

Editable Mode

If you want to modify and use the CrySPY source code, it is convenient to install CrySPY in editable mode using the -e option of pip.

Since the GitHub main branch may contain development code that differs from the official release, download the source archive of the desired release from the release page.

After extracting the archive, run:

pip install -e ./CrySPY-x.x.x

PHYSBO and DScribe (Optional)

If you use Bayesian optimization, PHYSBO and DScribe are required.

pip install physbo dscribe
Info

cal_fingerprint program and COMBO are obsolete.

mpi4py (Optional)

When performing random structure generation with MPI parallelization, mpi4py is required.

pip install mpi4py

Jupyter and nglview (Optional)

For analysis on a local PC or in interactive mode, Jupyter is required. If you want to visualize crystal structures using nglview in interactive mode, install nglview by pip.

pip install nglview

CrySPY 1.0.0 -- 1.2.5

CrySPY

pip

CrySPY 1.0.0 or later can be installed by pip.

pip install csp-cryspy

The executable script, cryspy, is automatically installed in your PATH. You can check by

which cryspy

Editable Mode

If you want to change the source code of CrySPY, you can use pip’s editable mode (-e option).

git clone https://github.com/Tomoki-YAMASHITA/CrySPY.git
pip install -e ./CrySPY

Instead of git clone, you can download the compressed file from the release page

cal_fingerprint (Optional)

cal_fingerprint is a program to calculate structure descriptors and is required if algo is BO. From CrySPY 1.0.0, the cal_fingerprint program is included in CrySPY utility. See Instllation/CrySPY_utility/Compile cal_fingerprint for compilation.

Put the executable file of cal_fingerprint in your PATH. Or, specify the path of the executable file in cryspy.in as follows:

[BO]
fppath = /xxx/xxx/xxx/cal_fingerprint

Arm64 on MacOS (Without Rosseta 2)

Info

In PyXtal, starting from version 0.6.3, pyshtools is no longer mandatory. Therefore, you can ignore the information written below if you are using a recent version of PyXtal.

  1. Install miniforge3 (We do not know how to install pyshtools with homebrew python.)
  2. Install pymatgen, pyshtools by conda (recent versions of pyshtools are available in conda-forge)
conda install pymatgen
conda install pyshtools
  1. Install CrySPY
pip3 install csp-cryspy

Structure Optimizer

Structure Optimizer

At least one optimizer is required.

CrySPY 0.10.3 or Earlier

Installation of CrySPY is very simple. Just download it!

Download

You can put the source code of CrySPY in an arbitrary directory. For example, let us put the source code in ~/CrySPY_root/CrySPY-x.x.x (x.x.x means the version). Use git or download the compressed file.

Git

mkdir ~/CrySPY_root
cd ~/CrySPY_root
git clone https://github.com/Tomoki-YAMASHITA/CrySPY.git CrySPY-x.x.x

ZIP or tar.gz File

Download the source as a zip or tar.gz file from GitHub release.
Then put the source like ~/CrySPY_root/CrySPY-x.x.x

Directory Tree

Directory tree in ~/CrySPY_root/CrySPY-x.x.x/:

CrySPY-x.x.x
├── CHANGELOG.md
├── CrySPY/
│   ├── BO/
│   ├── EA/
│   ├── IO/
│   ├── LAQA/
│   ├── RS/
│   ├── __init__.py
│   ├── calc_dscrpt/
│   ├── f-fingerprint/
│   ├── find_wy/
│   ├── gen_struc/
│   ├── interface/
│   ├── job/
│   └── start/
│   └── utility.py
├── LICENSE
├── README.md
├── cryspy.py
├── docs/
├── example/
└── utility/
Info

Main script is cryspy.py.

Setup (Optional)

find_wy (Optional)

When you use find_wy, put the executable file of find_wy in ~/CrySPY_root/CrySPY-x.x.x/CrySPY/find_wy/, so that the executable file path is ~/CrySPY_root/CrySPY-x.x.x/CrySPY/find_wy/find_wy.

cd ~/CrySPY_root/CrySPY-x.x.x/CrySPY/find_wy
cp ~/local/find_wy/find_wy .

Compile cal_fingerprint (Optional)

When you use Bayesian optimization, compile cal_fingerpirnt program which calculates structure descriptors.

cd ~/CrySPY_root/CrySPY-x.x.x/CrySPY/f-fingerprint
emacs Makefile
make

Make sure that the executable file of cal_fingerprint exists in ~/CrySPY_root/CrySPY-x.x.x/CrySPY/f-fingerprint/.

find_wy (Optional)

CrySPY have utilized find_wy to generate a random structure for a given space group (symmetry). However, CrySPY employs PyXtal library for structure generation as default since version 0.9.0. You can skip to install find_wy in CrySPY 0.9.0 or later, but you may use find_wy. For CrySPY 0.8.x or earlier, find_wy is required to generate a random structure for a given space group.

Info

You can skip to install find_wy in CrySPY 0.9.0 or later.

Installation of find_wy

m_tspace

First you need compile m_tspace for find_wy. Check these sites to compile it.

Download the source code of m_tspace in an arbitrary directory. For example:

$ mkdir -p ~/local
$ cd ~/local
$ git clone https://github.com/nim-hrkn/m_tspace.git

Additional two files are required to compile m_tspace. Download the following files in ~/local/m_tspace from TSPASE:

$ cd m_tspace
$ wget http://phoenix.mp.es.osaka-u.ac.jp/~tspace/tspace_main/tsp07/tsp98.f
$ wget http://phoenix.mp.es.osaka-u.ac.jp/~tspace/tspace_main/tsp07/prmtsp.f

Edit the makefile and run the make command. If you use ifort, you had better delete -check all option and use -O2 option.

$ emacs makefile
$ head -n 4 makefile
#FC=gfortran
#FFLAGS=-g -cpp -DUSE_GEN -ffixed-line-length-255
FC=ifort
FFLAGS=-O2 -g -traceback -cpp -DUSE_GEN -132
$ make

If you used gfortran, you might face the following problem:

tsp98.f:9839:32:

       CALL SUBGRP(MG,JG,MGT,JGT,NTAB,IND)
                                1
Error: Actual argument contains too few elements for dummy argument 'ntab' (12/48) at (1)
make: *** [tsp98.o] Error 1

Then change the source file of tsp98.f like this (line 9925):

Before:

9913: C SUBROUTINE SUBGRP ====*====3====*====4====*====5====*====6====*====7
9914: C
9915: C    IF (JG(I),I=1,MG) IS A SUBGROUP OF (JGT(J),J=1,MGT) THEN
9916: C          TABLE (NTAB(I),I=1,MG) IS MADE HERE AND IND=0
9917: C    ELSE
9918: C          IND=-1
9919: C
9920: C                 1993/12/25
9921: C                   BY  S.TANAKA AND A. YANASE
9922: C---*----1----*----2----*----3----*----4----*----5----*----6----*----7
9923: C
9924:       SUBROUTINE SUBGRP(MG,JG,MGT,JGT,NTAB,IND)
9925:       DIMENSION NTAB(48),JG(48),JGT(48)

After:

9913: C SUBROUTINE SUBGRP ====*====3====*====4====*====5====*====6====*====7
9914: C
9915: C    IF (JG(I),I=1,MG) IS A SUBGROUP OF (JGT(J),J=1,MGT) THEN
9916: C          TABLE (NTAB(I),I=1,MG) IS MADE HERE AND IND=0
9917: C    ELSE
9918: C          IND=-1
9919: C
9920: C                 1993/12/25
9921: C                   BY  S.TANAKA AND A. YANASE
9922: C---*----1----*----2----*----3----*----4----*----5----*----6----*----7
9923: C
9924:       SUBROUTINE SUBGRP(MG,JG,MGT,JGT,NTAB,IND)
9925:       DIMENSION NTAB(12),JG(48),JGT(48)

If you succeed in compiling, you get m_tsp.a.

find_wy

Check these sites to compile find_wy:

Download the source code of find_wy in an arbitrary directory. For example:

$ mkdir -p ~/local
$ cd ~/local
$ git clone https://github.com/nim-hrkn/find_wy.git

Edit make.inc and set the path to the m_tsp.a that you just prepared.

$ cd find_wy
$ emacs make.inc
$ head -n 4 make.inc
TSPPATH=~/local/m_tspace
#INCPATH = -I $(TSPPATH)
TSP=$(TSPPATH)/m_tsp.a

You can delete -check all option and use -O2 option. Then run the make command.

$ make

When you get the executable file of find_wy, run the following command for test:

$ ./find_wy input_sample/input_si4o8.txt

If there is no problem, POS_WY_SKEL_ALL.json file is generated.

Executable File of find_wy

CrySPY 1.0.0 or Later

Put the executable file of find_wy in your PATH. Or, specify the path of the executable file in cryspy.in as follows:

[structure]
use_find_wy = True
fwpath = /xxx/xxx/xxx/find_wy

CrySPY 0.10.3 or Earlier

When you use find_wy, put the executable file of find_wy in ~/CrySPY_root/CrySPY-x.x.x/CrySPY/find_wy/, so that the executable file path is ~/CrySPY_root/CrySPY-x.x.x/CrySPY/find_wy/find_wy.

CrySPY Utility (Optional)

Setting up Python environment in your local PC is useful to analyze CrySPY results. Utility tools (jupyter notebook and python scripts) are available for analysis and visualization. Input examples are also included in CrySPY utility.

Info

You need several Python libraries such as

Download CrySPY Utility

Git

$ git clone https://github.com/Tomoki-YAMASHITA/CrySPY_utility.git

ZIP

Go to CrySPY utility and click green Code button, then choose Download ZIP.

Subsections of Command

cryspy-Eplot

Last updated: October 16, 2026

cryspy-Eplot Command

Starting from CrySPY version 1.4.1, the cryspy-Eplot command is installed. In EA-vc, a convex hull plot is automatically generated and saved at the end of each generation by default. Use energy_output_interval in the [option] section to change the output interval or disable automatic output (see Input File > [option] Section). If you wish to modify the plotting parameters afterward, you can regenerate the plot using the cryspy-Eplot command.

For the input parameters that can be changed, see the following page.

Usage and Options

Run the following command in the directory containing cryspy.in.

cryspy-Eplot [options]
OptionDescription
-c, --composition-windowSave a plot of the composition range specified in cryspy.in. See Checking the Composition Range for details.

Energy Plots (RS, EA)

energy_RS_10 energy_RS_10 energy_EA_gen_3 energy_EA_gen_3

Convex Hull Plots (EA-vc)

Standard Plots (Binary and Ternary Systems)

Binary convex hull plot Binary convex hull plot Ternary convex hull plot Ternary convex hull plot

Replotting Specific Generations

An example using the convex hull from generation 3 and displaying structures from generation 2.

Convex hull from generation 3 with structures from generation 2 Convex hull from generation 3 with structures from generation 2

Plotting with Composition Constraints

Examples of binary and ternary plots with composition constraints. The blue region represents the allowed composition range.

Binary convex hull plot with composition constraints Binary convex hull plot with composition constraints Ternary convex hull plot with composition constraints Ternary convex hull plot with composition constraints

Checking the Composition Range (-c)

From version 1.5.0, the allowed composition range can be plotted using the -c option when composition constraints are specified.

For EA-vc with min_comp or max_comp specified, the following command plots the allowed composition range defined in the current cryspy.in. No search-result data is required, so the constraints can be checked before starting a search.

cryspy-Eplot -c

For standard binary and ternary systems, the plot is saved as ./data/convex_hull/composition_window_input.<fig_format>. fig_format defaults to svg and can be changed to png or pdf in the [visual] section. The species arrangement is specified by axis_order in the same section. The input in the filename indicates that the plot is based on the input at execution time, independently of the generation number.

Examples for binary and ternary systems are shown below.

Allowed composition range for a binary system Allowed composition range for a binary system Allowed composition range for a ternary system Allowed composition range for a ternary system

These plots represent the continuous composition region determined by min_comp and max_comp. They do not account for integer atom-count constraints from ll_nat and ul_nat or charge neutrality from charge. For input examples and an explanation of the plots, see Composition Constraints.

When -c is specified, the command outputs the composition-window plot and exits. To replot the energy or convex hull of search results, run cryspy-Eplot without -c.

Changing Axis Arrangement

Change axis_order in the [visual] section of cryspy.in, then run cryspy-Eplot to redraw the plot with a different arrangement of species. For details, see Tutorial > EA-vc > Analysis and Visualization and Input File > [visual] Section.

For binary systems, assign l (left) and r (right) in the order of atype. The examples below use axis_order = lr (left) and axis_order = rl (right).

Binary axis arrangement: lr Binary axis arrangement: lr Binary axis arrangement: rl Binary axis arrangement: rl

For ternary systems, assign t (top), l (left), and r (right) in the order of atype. The examples below use axis_order = tlr (left) and axis_order = ltr (right).

Ternary axis arrangement: tlr Ternary axis arrangement: tlr Ternary axis arrangement: ltr Ternary axis arrangement: ltr

Convex Hulls with Compound Terminals (terminals)

Specify two or three compound compositions with terminals in the [visual] section of cryspy.in to plot a convex hull using those compositions as references. This uses pymatgen’s CompoundPhaseDiagram. Depending on the reference compositions, a ternary system can also be plotted as a pseudo-ternary system, or a quaternary system as a pseudo-ternary system. Here, we show an example of plotting a ternary system as a pseudo-binary system. This setting is for post-analysis with cryspy-Eplot and does not affect convex-hull calculations or natural selection during the search.

The following example uses a ternary Li–Al–O search through generation 30 with a charge neutrality condition imposed. The [structure] section is configured as follows.

[structure]
atype = Li Al O
ll_nat = 0 0 0
ul_nat = 40 40 40
charge = 1 3 -2

Compositions satisfying this charge neutrality condition lie on the line connecting Li2O and Al2O3 in the ternary composition diagram. Using these compound compositions as references therefore allows the convex hull to be plotted as a pseudo-binary Li2O–Al2O3 system. See Features > Charge Neutrality Condition for details on imposing charge neutrality.

The left figure shows the ternary convex hull referenced to the elements; the right figure shows the pseudo-binary convex hull referenced to Li2O and Al2O3.

Li–Al–O convex hull referenced to the elements Li–Al–O convex hull referenced to the elements Convex hull referenced to Li2O and Al2O3 Convex hull referenced to Li2O and Al2O3

To obtain the right figure, configure the [visual] section as follows and run cryspy-Eplot.

[visual]
terminals = Li2O Al2O3
cryspy-Eplot

The output filename includes _terminals_Li2O-Al2O3 to identify the reference compound compositions. In this example, the plot is saved in the default SVG format as ./data/convex_hull/conv_hull_gen_30_terminals_Li2O-Al2O3.svg.

With two compound compositions, omitting terminal_axis_order uses the default lr: Li2O is placed on the left and Al2O3 on the right, following the order in terminals. Each specified compound composition must have an entry in the phase-diagram data used for plotting. See Input File > [visual] Section for parameter details.

cryspy-calc-convex-hull

Last updated: October 16, 2026

cryspy-calc-convex-hull Command

Recalculate the EA-vc convex hull and each structure’s hull distance using results up to a specified generation. Use this after excluding incorrect structures with cryspy-skip or changing the energy cutoffs with emin_ea and emax_ea.

Run the command in the CrySPY calculation directory, specifying a generation number.

cryspy-calc-convex-hull 10

This example uses results from generations 1 through 10 to recalculate the convex hull and hull distances at generation 10. It updates that generation’s data in pd_data.pkl and hdist_data.pkl and writes a hull-distance table. A convex hull plot is also generated for binary and ternary systems.

See Features > Skip Calculations for the detailed procedure.

cryspy-skip

Last updated: October 16, 2026

cryspy-skip Command

Cancel results already recorded in rslt_data.pkl and mark the specified structures as skipped. Use this when incorrect electronic states or similar problems have produced abnormal energies.

Run the command in the CrySPY calculation directory, specifying one or more structure IDs.

cryspy-skip 198 157

This example invalidates the optimized structures and energies for IDs 198 and 157 and sets their Opt values to skip. For EA and EA-vc, these structures are also removed from the elite data if present. For EA-vc, recalculate the convex hull with cryspy-calc-convex-hull as needed.

See Features > Skip Calculations for the detailed procedure and how to skip calculations while they are running.

cryspy-print

Last updated: October 16, 2026

cryspy-print Command

From v1.5.0, cryspy-print lets you inspect pickle files under data/pkl_data/. It replaces CrySPY Utility’s print_pkl.py, displaying contents or a summary according to the file type. For rslt_data.pkl, it also supports sorting by energy, selecting rows, filtering by composition, and regenerating result files.

Usage and Options

cryspy-print infile [options]

The input file can be specified with a relative or absolute path. Gzip-compressed files are also supported. The file type is determined by its filename, so keep names such as rslt_data.pkl unchanged.

Argument or optionDescription
infilePickle file to display. Gzip-compressed files, such as rslt_data.pkl.gz, are also accepted.
--no-sortDisplay rslt_data.pkl in its stored row order without sorting.
--head NDisplay the first N rows after filtering and sorting. N must be a positive integer.
--tail NDisplay the last N rows after filtering and sorting. N must be a positive integer.
--allDisplay all rows after filtering and sorting.
-c N [N ...], --composition N [N ...]Filter EA-vc results in rslt_data.pkl by composition ratio, specified in atype order.
--writeRegenerate ./data/cryspy_rslt and ./data/cryspy_rslt_energy_asc from rslt_data.pkl.
-h, --helpShow help.

--no-sort, --head, --tail, --all, --composition, and --write are options for rslt_data.pkl. --head, --tail, and --all cannot be combined. --write cannot be combined with display options.

Supported Files and Output

FileOutput
input_data.pklInput settings grouped by section. Fields whose value is None are omitted.
init_struc_data.pkl, opt_struc_data.pkl, struc_step_data.pkl, elite_struc.pkl, init_dscrpt_data.pkl, opt_dscrpt_data.pklNumber of stored entries (Number of structures). Structure IDs are not listed.
rslt_data.pklResults table, sorted by energy in ascending order by default.
hdist_data.pklLatest generation and its number of structures. Prints No hull distance data if empty.
pd_data.pklLatest generation and its numbers of stable entries and all entries. Prints No phase diagram data if empty.
cn_comb_data.pklCharge-neutrality settings and the number of charge-neutral combinations. Reports when cn_comb is None.

The contents of the following files are pretty-printed.

  • Common: id_queueing.pkl, id_running.pkl, energy_step_data.pkl, force_step_data.pkl, stress_step_data.pkl, kpt_data.pkl, rng_state_data.pkl
  • EA: gen.pkl, ea_info.pkl, ea_origin.pkl, elite_fitness.pkl
  • EA-vc: nat_data.pkl
  • BO: n_selection.pkl, id_select_hist.pkl, bo_mean.pkl, bo_var.pkl, bo_score.pkl
  • LAQA: tot_step_select.pkl, laqa_energy.pkl, laqa_bias.pkl, laqa_score.pkl, laqa_step.pkl, laqa_struc.pkl

An unsupported filename causes an error.

Examples

Checking Structure Counts, Input Settings, and Fitness

cryspy-print ./data/pkl_data/init_struc_data.pkl

Output for a file containing ten entries:

Number of structures: 10

opt_struc_data.pkl and elite_struc.pkl also display the structure count. To inspect individual structures, use the -p option of cryspy-extract-struc.

cryspy-print ./data/pkl_data/input_data.pkl
cryspy-print ./data/pkl_data/elite_fitness.pkl

input_data.pkl displays settings grouped into sections such as [basic] and [structure]. elite_fitness.pkl displays a dictionary of structure IDs and fitness values.

Displaying Results

cryspy-print ./data/pkl_data/rslt_data.pkl

Results are sorted in ascending order of Ef_eV_atom if that column exists, or E_eV_atom otherwise. All rows are displayed if there are at most 100 rows. For larger tables, the command displays the count and sort order, followed by the first 100 rows.

cryspy-print ./data/pkl_data/rslt_data.pkl --head 10
cryspy-print ./data/pkl_data/rslt_data.pkl --tail 5
cryspy-print ./data/pkl_data/rslt_data.pkl --all

These display the first ten rows, last five rows, or all rows of the table sorted by energy in ascending order. Use --no-sort to keep the stored row order. It can be combined with row selection.

cryspy-print ./data/pkl_data/rslt_data.pkl --no-sort --head 10

Filtering EA-vc Results by Composition

cryspy-print ./data/pkl_data/rslt_data.pkl -c 1 2 --head 10

This selects structures with a composition ratio of 1:2 in atype order and displays the first ten rows in ascending energy order. Atom counts such as (1, 2) and (2, 4) match the same ratio. Specify one non-negative integer per element, with at least one positive value. This option requires EA-vc results with a Num_atom column. A message is displayed if no structures match.

For an example with output, see Tutorial > EA-vc > Check Results > Checking Results for a Specific Composition.

Inspecting Gzip-Compressed Files

cryspy-print ./data/pkl_data/rslt_data.pkl.gz --head 10

The file is read without decompression beforehand. Other supported files can also be supplied in gzip-compressed form.

Regenerating Result Files

Run the following in the calculation directory containing cryspy.in.

cryspy-print ./data/pkl_data/rslt_data.pkl --write

This regenerates the following files, overwriting existing files.

  • ./data/cryspy_rslt: Results in their stored row order.
  • ./data/cryspy_rslt_energy_asc: Results sorted by Ef_eV_atom in ascending order, or E_eV_atom if the former column is absent.

Files are written to data/ under the directory where the command is run. This directory must exist. The operation is also recorded in log_cryspy.

cryspy-extract-struc

Last updated: October 16, 2026

cryspy-extract-struc Command

From v1.5.0, cryspy-extract-struc extracts structures from init_struc_data.pkl or opt_struc_data.pkl and saves them as CIF files. This command integrates CrySPY Utility’s extract_struc.py into CrySPY. It can also print structure information without writing files.

Usage and Options

cryspy-extract-struc infile [options]

The input file can be specified with a relative or absolute path. CIF files are saved in the directory where the command is run. Specify exactly one of -i, -a, or -t; these options cannot be combined.

Argument or optionDescription
infileA structure-data pickle file, such as init_struc_data.pkl or opt_struc_data.pkl. Gzip-compressed files are also supported.
-i INDEX [INDEX ...], --index INDEX [INDEX ...]Structure IDs to extract. Multiple IDs can be specified.
-a, --all_idExtract all structures in the input file.
-t TOP, --top TOPExtract the specified number of structures in ascending order of E_eV_atom in rslt_data.pkl.
-p, --printPrint structure information without writing CIF files.
-r, --rankUse with -t to prefix output filenames with the rank.
-s, --symmetrizedWrite CIF files with symmetry information.
--tolerance TOLERANCETolerance for symmetry detection with -s. The default is 0.01.
-h, --helpShow help.

Examples

Extracting by Structure ID

cryspy-extract-struc ./data/pkl_data/opt_struc_data.pkl -i 0 1

Structures with IDs 0 and 1 are saved as 0.cif and 1.cif in the current directory. Missing IDs are skipped with a warning.

cryspy-extract-struc ./data/pkl_data/opt_struc_data.pkl -i 0 1 -p

With -p, structure IDs and structure information are printed without creating CIF files.

Extracting the Lowest-Energy Structures

cryspy-extract-struc ./data/pkl_data/opt_struc_data.pkl -t 3

This extracts the three lowest-energy structures. rslt_data.pkl must be in the same directory as the input file. Output filenames are {ID}.cif.

Adding -r produces filenames of the form {rank}_{ID}.cif. Ranks start from 1.

cryspy-extract-struc ./data/pkl_data/opt_struc_data.pkl -t 3 -r

Extracting All Structures

cryspy-extract-struc ./data/pkl_data/init_struc_data.pkl -a

All initial structures are saved as {ID}.cif.

Writing Symmetry Information

cryspy-extract-struc ./data/pkl_data/opt_struc_data.pkl -i 0 1 -s --tolerance 0.01

With -s, output CIF files include symmetry information such as the space group. --tolerance is optional. Adding symmetry information may change the cell representation and the number of atoms.

Extracting from Gzip-Compressed Files

cryspy-extract-struc ./data/pkl_data/opt_struc_data.pkl.gz -i 0 1

Gzip-compressed structure data can be read directly without decompression. Options such as -a, -t, -p, and -s can be used in the same way. When using -t, place rslt_data.pkl in the same directory as the compressed input file.

Subsections of Tutorial

Random Search (RS)

Info

ASE is easy to start for beginners because when you install CrySPY, ASE is also automatically installed. Although not highly accurate, ASE provides very lightweight and fast interatomic potentials, making it suitable for testing on a laptop or other low-spec machines.

Preparation of Input Files

Follow one of the instructions below, then proceed to the section on running CrySPY.

Running CrySPY

  1. Check cryspy.in
  2. (version 0.10.3 or earlier) Script to Run
  3. First Run
  4. Submit Job
  5. Check Results
  6. Append Structures
  7. Analysis and Visualization

Subsections of Random Search (RS)

ASE on Your Local PC

Last updated: October 16, 2026

ASE provides interfaces to different codes. ASE also includes Pure Python EMT calculator, which is suitable for testing CrySPY because of its fast and easy structure optimization.

In this tutorial, we try to use CrySPY in your local PC (Mac or Linux). The target system is Cu 8 atoms.

Assumption

Here, we assume the following conditions:

  • CrySPY 1.2.0 or later in your local PC
  • CrySPY job filename: job_cryspy
  • ase input filename: ase_in.py

Input Files

Move to your working directory, and copy the example files by one of the following methods.

cd ase_Cu8_RS
tree
.
├── calc_in
│   ├── ase_in.py
│   └── job_cryspy
└── cryspy.in

cryspy.in

cryspy.in is the input file of CrySPY.

[basic]
algo = RS
calc_code = ASE
tot_struc = 5
nstage = 1
njob = 5
jobcmd = zsh
jobfile = job_cryspy

[structure]
atype = Cu
nat = 8

[ASE]
ase_python = ase_in.py

[option]
rslt_out = always

In [basic] section, jobcmd = zsh can be changed to jobcmd = sh or jobcmd = bash in accordance with your environment. CrySPY runs zsh job_cryspy as a background job internally.

[ASE] section is required when you use ASE.

You can name the following files whatever you want:

  • jobfile: job_cryspy
  • ase_python: ase_in.py

The other input variables are discussed later.

calc_in Directory

The job file and input files for ASE are prepared in this directory.

Job File

The name of the job file must match the value of jobfile in cryspy.in. The example of job file (here, job_cryspy) is shown below.

#!/bin/sh

# ---------- ASE
python3 ase_in.py

You can specify the input (ase_in.py) file names, but it must match the values of ase_python in cryspy.in. You must add sed -i -e ‘3 s/^.*$/done/’ stat_job at the end of the file in CrySPY. Starting from version 1.4.2, CrySPY automatically appends the following line to the end of the job file. (See also: Features > Job file auto-rewriting)

# ---------- CrySPY
sed -i -e '3s/^sub.*/done/' stat_job
Note

For versions older than 1.4.2, the last line of the job file must be written as sed -i -e '3s/^sub.*/done/' stat_job. If you use a job file with this sed command in version 1.4.2 or later, it will simply be executed twice, which does not cause any problems.
The meaning of the above sed command is to change the part starting with “sub” in the third line of the file stat_job to “done”.

Tip

(Detail: Features > Job file auto-rewriting)
In the job file of CrySPY, the string CrySPY_ID is automatically replaced with the structure ID. When you use a job scheduler such as PBS and SLURM, it is useful to set the structure ID to the job name. For example, in the PBS system, #PBS -N Si_CrySPY_ID in ID 10 is replaced with #PBS -N Si_10. Note that starting with a number will result in an error. You should add a prefix like Si_.

Input for ASE

Input files corresponding to the number of stages (nstage in cryspy.in) are required. Prepare the input file names by adding x_ as a prefix or _x as a suffix, where x is the stage number.

CrySPY searches for input files in the following order of priority:

  1. x_ase_in.py
  2. ase_in.py_x
  3. ase_in.py

If you use the same input for all stages, you can omit x_ or _x.

In this ASE tutorial, since nstage = 1 is used, only one ASE input file, ase_in.py, is needed. You can omit x_ or _x. An example of ase_in.py is shown below (for details on how to use ASE, refer to the official documentation).

from ase.constraints import FixSymmetry
from ase.filters import FrechetCellFilter
from ase.calculators.emt import EMT
from ase.optimize import BFGS
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)

# ---------- run
converged = opt.run(fmax=0.01, steps=2000)

# ---------- rule in ASE interface
# output file for energy: 'log.tote' in eV/cell
#                         CrySPY reads the last line of 'log.tote' file
# outimized structure: 'CONTCAR' file in vasp format
# check_opt: 'out_check_opt' file ('done' or 'not yet')
#                         CrySPY reads the last line of 'out_check_opt' file

# ------ 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)

# ------ check_opt
with open('out_check_opt', mode='w') as f:
    if converged:
        f.write('done\n')
    else:
        f.write('not yet\n')

Unlike VASP and QE, the ASE input (python script) is more flexible. CrySPY has three rules:

  1. Energy is output in units of eV/cell to log.tote file. CrySPY reads the last line of it.
  2. Optimized structure is output to CONTCAR file in the VASP format.
  3. The result of the optimization convergence check should be written as either done or not_yet in a file named out_check_opt. CrySPY reads the last line of this file.

Running CrySPY

Go to Running CrySPY

soiap on Your Local PC

Info

The information written here is slightly outdated, so please refer to the latest tutorial: Tutorial > Random Search (RS) > ASE on your local PC. The content on this page should still work without any issues.

Last updated: October 16, 2026

soiap is Structure Optimization with InterAtomic Potential. It is suitable for testing CrySPY because of its fast structure optimization. See instructions to install soiap.

In this tutorial, we try to use CrySPY in your local PC (Mac or Linux). The target system is Si 8 atoms.

Assumption

Here, we assume the following conditions:

  • (only version 0.10.3 or earlier) CrySPY main script: ~/CrySPY_root/CrySPY-0.9.0/cryspy.py
  • CrySPY job filename: job_cryspy
  • soiap executable file: ~/local/soiap-0.3.0/src/soiap
  • soiap input filename: soiap.in
  • soiap output filename: soiap.out
  • soiap input structure filename: initial.cif

Input Files

Move to your working directory, and copy input example files by one of the following methods.

  • Download from Cryspy_utility/examples/soiap_Si8_RS
  • Copy from CrySPY utility that you installed
  • (only version 0.10.3 or earlier) cp -r ~/CrySPY_root/CrySPY-0.9.0/example/v0.9.0/soiap_RS_Si8 .
cd soiap_RS_Si8
tree
.
├── calc_in
│   ├── job_cryspy
│   └── soiap.in_1
└── cryspy.in

cryspy.in

cryspy.in is the input file of CrySPY.

[basic]
algo = RS
calc_code = soiap
tot_struc = 5
nstage = 1
njob = 2
jobcmd = zsh
jobfile = job_cryspy

[structure]
atype = Si
nat = 8

[soiap]
soiap_infile = soiap.in
soiap_outfile = soiap.out
soiap_cif = initial.cif

[option]
rslt_out = always

In [basic] section, jobcmd = zsh can be changed to jobcmd = sh or jobcmd = bash in accordance with your environment. CrySPY runs zsh job_cryspy as a background job internally.

[soiap] section is required when you use soiap.

You can name the following files whatever you want:

  • jobfile
  • soiap_infile
  • soiap_outfile
  • soiap_cif

The other input variables are discussed later.

calc_in Directory

The job file and input files for soiap are prepared in this directory.

Job File

The name of the job file must match the value of jobfile in cryspy.in. The example of job file (here, job_cryspy) is shown below.

#!/bin/sh

# ---------- soiap
EXEPATH=/path/to/soiap
$EXEPATH/soiap soiap.in 2>&1 > soiap.out

# ---------- CrySPY
sed -i -e '3 s/^.*$/done/' stat_job

Change /path/to/soiap into right path suitable for your environment. You can specify the input (soiap.in) and output (soiap.out) file names, but they must match the values of soiap_infile and soiap_outfile in cryspy.in. The job file is written in the same way as the one you usually use except for the last line. You must add sed -i -e '3 s/^.*$/done/' stat_job at the end of the file in CrySPY.

Note

sed -i -e '3 s/^.*$/done/' stat_job is required at the end of the job file.

Tip

In the job file of CrySPY, the string “CrySPY_ID” is automatically replaced with the structure ID. When you use a job scheduler such as PBS and SLURM, it is useful to set the structure ID to the job name. For example, in the PBS system, #PBS -N Si_CrySPY_ID in ID 10 is replaced with #PBS -N Si_10. Note that starting with a number will result in an error. You should add a prefix like Si_.

Input for soiap

Input files based on the number of stages (nstage in cryspy.in) are required. Name the input file(s) with a suffix _x. Here x means the stage number.

We are using nstage = 1, so we need only soiap.in_1.

soiap.in_1 is listed below.

crystal initial.cif ! CIF file for the initial structure
symmetry 1 ! 0: not symmetrize displacements of the atoms or 1: symmetrize

md_mode_cell 3 ! cell-relaxation method
               ! 0: FIRE, 2: quenched MD, or 3: RFC5
number_max_relax_cell 100 ! max. number of the cell relaxation
number_max_relax 1 ! max. number of the atom relaxation
max_displacement 0.1 ! max. displacement of atoms in Bohr

external_stress_v 0.0 0.0 0.0 ! external pressure in GPa

th_force 5d-5 ! convergence threshold for the force in Hartree a.u.
th_stress 5d-7 ! convergence threshold for the stress in Hartree a.u.

force_field 1 ! force field
              ! 1: Stillinger-Weber for Si, 2: Tsuneyuki potential for SiO2,
              ! 3: ZRL for Si-O-N-H, 4: ADP for Nd-Fe-B, 5: Jmatgen, or
              ! 6: Lennard-Jones

The input structure file is specified at the first line. Use the same name as the value of soiap_cif in cryspy.in.

Running CrySPY

Go to Running CrySPY

VASP

Last updated: October 16, 2026

In this tutorial, we try to use CrySPY in a PC cluster with a job scheduler system such as PBS. Here we employ VASP. The target system is Na8Cl8, 16 atoms.

Assumption

Here, we assume the following conditions:

  • CrySPY 1.2.0 or later in your PC cluster
  • CrySPY job command: qsub
  • CrySPY job filename: job_cryspy
  • executable file, vasp_std in your PC cluster

Input Files

Move to your working directory, and copy the example files by one of the following methods.

cd vasp_Na8Cl8_RS
tree
.
├── calc_in
│   ├── 1_INCAR
│   ├── 2_INCAR
│   ├── POTCAR_dummy
│   └── job_cryspy
└── cryspy.in

cryspy.in

cryspy.in is the input file of CrySPY.

[basic]
algo = RS
calc_code = VASP
tot_struc = 5
nstage = 2
njob = 2
jobcmd = qsub
jobfile = job_cryspy

[structure]
atype = Na Cl
nat = 8 8
mindist_1 = 2.5 1.5
mindist_2 = 1.5 2.5

[VASP]
kppvol = 40 80

[option]
rslt_out = always

In [basic] section, jobcmd = qsub can be changed in accordance with your environment. CrySPY runs qsub job_cryspy as a background job internally in this setting. You can name the following file whatever you want:

  • jobfile

We adopt a stage-based system for structure optimization calculations. Here, we use nstage = 2. For example, users can configure the following settings. In the first stage, only the ionic positions are relaxed, fixing the cell shape, with low k-point grid density. Next, the ionic positions and cell shape are fully relaxed with high accuracy in the second stage.

[VASP] section is required when you use VASP. You have to specify k-point grid density (Å^-3) for each stage in kppvol.

Info

See Input file > Kpoint for details of kppvol

The other input variables are discussed later.

calc_in Directory

The job file and input files for VASP are prepared in this directory.

Job File

The name of the job file must match the value of jobfile in cryspy.in. The example of job file (here, job_cryspy) is shown below.

#!/bin/sh
#$ -cwd
#$ -V -S /bin/bash
####$ -V -S /bin/zsh
#$ -N Na8Cl8_CrySPY_ID
#$ -pe smp 20
####$ -q ibis1.q
####$ -q ibis2.q
####$ -q ibis3.q
####$ -q ibis4.q

# ---------- vasp
VASPROOT=/usr/local/vasp/vasp.6.4.2/bin
mpirun -np $NSLOTS $VASPROOT/vasp_std

Change VASPROOT to the appropriate path suitable for your environment. The job file is written in the same way as the one you usually use except for the last line. You must add sed -i -e ‘3 s/^.*$/done/’ stat_job at the end of the file in CrySPY. Starting from version 1.4.2, CrySPY automatically appends the following line to the end of the job file. (See also: Features > Job file auto-rewriting)

# ---------- CrySPY
sed -i -e '3s/^sub.*/done/' stat_job
Note

For versions older than 1.4.2, the last line of the job file must be written as sed -i -e '3s/^sub.*/done/' stat_job. If you use a job file with this sed command in version 1.4.2 or later, it will simply be executed twice, which does not cause any problems.
The meaning of the above sed command is to change the part starting with “sub” in the third line of the file stat_job to “done”.

Tip

(Detail: Features > Job file auto-rewriting)
In the job file of CrySPY, the string CrySPY_ID is automatically replaced with the structure ID. When you use a job scheduler such as PBS and SLURM, it is useful to set the structure ID to the job name. For example, in the PBS system, #PBS -N Si_CrySPY_ID in ID 10 is replaced with #PBS -N Si_10. Note that starting with a number will result in an error. You should add a prefix like Si_.

Input for VASP

Input files corresponding to the number of stages (nstage in cryspy.in) are required. Prepare the input file names by adding x_ as a prefix or _x as a suffix, where x is the stage number.

CrySPY searches for input files in the following order of priority:

  1. x_INCAR
  2. INCAR_x
  3. INCAR

If you use the same input for all stages, you can omit x_ or _x.

We are using nstage = 2, so we need 1_INCAR_1 and 2_INCAR. Here, 1_INCAR is set to fix the cell and relax only the ionic positions, while 2_INCAR is configured to fully relax both the cell and ionic positions.

1_INCAR

SYSTEM = NaCl
!!!LREAL = Auto
Algo = Fast
NSW = 40

LWAVE = .FALSE.
!LCHARG = .FALSE.

ISPIN =  1

ISMEAR = 0
SIGMA = 0.1

IBRION = 2
ISIF = 2

EDIFF = 1e-5
EDIFFG = -0.01

2_INCAR

SYSTEM = NaCl
!!LREAL = Auto
Algo = Fast
NSW = 200

ENCUT = 341

!!LWAVE = .FALSE.
!!LCHARG = .FALSE.


ISPIN =  1

ISMEAR = 0
SIGMA = 0.1

IBRION = 2
ISIF = 3

EDIFF = 1e-5
EDIFFG = -0.01

CrySPY automatically generates POSCAR and KPOINTS files. You have to prepare POTCAR file yourself. The POTCAR included in this example file is empty, so please be aware of that.

Warning

POTCAR in this example is empty. We cannot distribute it.

Running CrySPY

Go to Running CrySPY

QE

Last updated: October 16, 2026

In this tutorial, we try to use CrySPY in a machine with a job scheduler system such as PBS. Here we employ QUANTUM ESPRESSO. (QE). The target system is Si 8 atoms.

Assumption

Here, we assume the following conditions:

  • CrySPY job command: qsub
  • CrySPY job filename: job_cryspy
  • QE executable file: /usr/local/qe-6.5/bin/pw.x
  • QE input filename: pwscf.in
  • QE output filename: pwscf.out

Input Files

Move to your working directory, and copy input example files by one of the following methods.

  • Download from CrySPY_utility/examples/qe_Si8_RS
  • Copy from CrySPY utility that you installed
  • (only version 0.10.3 or earlier) cp -r ~/CrySPY_root/CrySPY-0.9.0/example/v0.9.0/QE_Si8_RS .
cd QE_RS_Si8
tree
.
├── calc_in
│   ├── job_cryspy
│   ├── 1_pwscf.in
│   └── 2_pwscf.in
└── cryspy.in

cryspy.in

cryspy.in is the input file of CrySPY.

[basic]
algo = RS
calc_code = QE
tot_struc = 5
nstage = 2
njob = 2
jobcmd = qsub
jobfile = job_cryspy

[structure]
atype = Si
nat = 8

[QE]
qe_infile = pwscf.in
qe_outfile = pwscf.out
kppvol =  40  80

[option]
rslt_out = always

In [basic] section, jobcmd = qsub can be changed in accordance with your environment. CrySPY runs qsub job_cryspy as a background job internally in this setting.

We adopt a stage-based system for structure optimization calculations. Here, we use nstage = 2. For example, users can configure the following settings. In the first stage, only the ionic positions are relaxed, fixing the cell shape, with low k-point grid density. Next, the ionic positions and cell shape are fully relaxed with high accuracy in the second stage.

[QE] section is required when you use QE. You have to specify k-point grid density (Å^-3) for each stage in kppvol.

Info

See Input file > Kpoint for details of kppvol

You can name the following files whatever you want:

  • jobfile
  • qe_infile
  • qe_outfile

The other input variables are discussed later.

calc_in Directory

The job file and input files for QE are prepared in this directory.

Job File

The name of the job file must match the value of jobfile in cryspy.in. The example of job file (here, job_cryspy) is shown below.

#!/bin/sh
#$ -cwd
#$ -V -S /bin/bash
####$ -V -S /bin/zsh
#$ -N Si8_CrySPY_ID
#$ -pe smp 20
####$ -q ibis1.q
####$ -q ibis2.q

mpirun -np $NSLOTS /path/to/pw.x < pwscf.in > pwscf.out


if [ -e "CRASH" ]; then
    sed -i -e '3 s/^.*$/skip/' stat_job
    exit 1
fi

Change /path/to/pw.x to the appropriate path suitable for your environment. You can specify the input (pwscf.in) and output (pwscf.out) file names, but they must match the values of qe_infile and qe_outfile in cryspy.in.

The job file is written in the same way as the one you usually use except for the last line. You must add sed -i -e ‘3 s/^.*$/done/’ stat_job at the end of the file in CrySPY. Starting from version 1.4.2, CrySPY automatically appends the following line to the end of the job file. (See also: Features > Job file auto-rewriting)

# ---------- CrySPY
sed -i -e '3s/^sub.*/done/' stat_job
Note

For versions older than 1.4.2, the last line of the job file must be written as sed -i -e '3s/^sub.*/done/' stat_job. If you use a job file with this sed command in version 1.4.2 or later, it will simply be executed twice, which does not cause any problems.
The meaning of the above sed command is to change the part starting with “sub” in the third line of the file stat_job to “done”.

Tip

(Detail: Features > Job file auto-rewriting)
In the job file of CrySPY, the string “CrySPY_ID” is automatically replaced with the structure ID. When you use a job scheduler such as PBS and SLURM, it is useful to set the structure ID to the job name. For example, in the PBS system, #PBS -N Si_CrySPY_ID in ID 10 is replaced with #PBS -N Si_10. Note that starting with a number will result in an error. You should add a prefix like Si_.

Input for QE

Input files corresponding to the number of stages (nstage in cryspy.in) are required. Prepare the input file names by adding x_ as a prefix or _x as a suffix, where x is the stage number.

CrySPY searches for input files in the following order of priority:

  1. x_pwscf.in
  2. pwscf.in_x
  3. pwscf.in

We are using nstage = 2, so we need 1_pwscf.in and 2_pwscf.in. Here, 1_pwscf.in is set to fix the cell and relax only the ionic positions, while 2_pwscf.in is configured to fully relax both the cell and ionic positions.

1_pwscf.in

 &control
    title = 'Si8'
    calculation = 'relax'
    nstep = 100
    restart_mode = 'from_scratch',
    pseudo_dir = '/usr/local/pslibrary.1.0.0/pbe/PSEUDOPOTENTIALS/'
    outdir='./out.d/'
 /

 &system
    ibrav = 0
    nat = 8
    ntyp = 1
    ecutwfc = 44.0
    occupations = 'smearing'
    degauss = 0.01
 /

 &electrons
 /

 &ions
 /

 &cell
 /

ATOMIC_SPECIES
  Si  28.086  Si.pbe-n-kjpaw_psl.1.0.0.UPF

1_pwscf.in

 &control
    title = 'Si8'
    calculation = 'vc-relax'
    nstep = 200
    restart_mode = 'from_scratch',
    pseudo_dir = '/usr/local/pslibrary.1.0.0/pbe/PSEUDOPOTENTIALS/'
    outdir='./out.d/'
 /

 &system
    ibrav = 0
    nat = 8
    ntyp = 1
    ecutwfc = 44.0
    occupations = 'smearing'
    degauss = 0.01
 /

 &electrons
 /

 &ions
 /

 &cell
 /

ATOMIC_SPECIES
  Si  28.086  Si.pbe-n-kjpaw_psl.1.0.0.UPF

Change pseudo_dir to your suitable directory. Inputs for structure data and k-point such as ATOMIC_POSITIONS and K_POINTS are automatically appended by CrySPY with pymatgen. Users do not have to prepare them in x_pwscf.in.

Running CrySPY

Go to Running CrySPY

OpenMX

Coming soon.

LAMMPS

Coming soon.

Check cryspy.in

Last updated: October 16, 2026

See Input File in detail.

Let’s take a look at cryspy.in again. This may be slightly different depending on calc_code you chose.

[basic]
algo = RS
calc_code = ASE
tot_struc = 5
nstage = 1
njob = 5
jobcmd = zsh
jobfile = job_cryspy

[structure]
atype = Cu
nat = 8

[ASE]
ase_python = ase_in.py

[option]
rslt_out = always

[basic] Section

  • algo: Algorithm. Set RS for Random Search.
  • calc_code: Structure optimizer. Choose from VASP, QE, OMX, soiap, LAMMPS, ASE
  • tot_struc: The total number of structures. In this case, 5 random structures are generated at 1st run.
  • nstage: The number of stages. It’s up to you.
  • njob: The number of jobs running at the same time. In this example, CrySPY sets 2 slots for structure optimization, in other words, optimizes every 2 structures.
  • jobcmd: Command for jobs. Use bash, zsh, qsub, and so on.
  • jobfile: File name of the job file.

[structure] Section

  • atype: Atom type. e.g. for Na8Cl8: atype = Na Cl.
  • nat: The number of atoms corresponding to each atype. e.g. for Na8Cl8: nat = 8 8

Script to Run

Note

For version 1.0.0 or later, skip this page. The executable script is automatically installed.

Assumption

Here, we assume the following condition:

  • CrySPY main script: ~/CrySPY_root/CrySPY-0.9.0/cryspy.py

Make Script

Let’s make a convenient shell script to avoid typing long commands over and over again. Here, we create the script, cryspy (any file name will do).

$ emacs cryspy
$ chmod 744 cryspy
$ cat cryspy
#!/bin/sh

python3 -u ~/CrySPY_root/CrySPY-0.9.0/cryspy.py 1>> log 2>> err

-u option (unbuffered option) can be omitted.

You can put this script in your $PATH, or just use like bash ./cryspy.

First Run

2025 March 6, updated

Make sure you have the following in your working directory.

  • calc_in/
  • (cryspy)
  • cryspy.in
$ ls
calc_in/  cryspy.in

Then, run CyrSPY!

cryspy

If you use old version (0.10.3 or earlier):

bash ./cryspy

At the first run, CrySPY goes into structure generation mode. CrySPY stops after 5 structure generation.

If it worked properly, the following output appears on the screen:

[2025-03-06 18:52:21,495][cryspy_init][INFO] 


Start CrySPY 1.4.0b10


[2025-03-06 18:52:21,495][cryspy_init][INFO] # ---------- Library version info
[2025-03-06 18:52:21,495][cryspy_init][INFO] pandas version: 2.2.2
[2025-03-06 18:52:21,495][cryspy_init][INFO] pymatgen version: 2025.1.24
[2025-03-06 18:52:21,495][cryspy_init][INFO] pyxtal version: 1.0.6
[2025-03-06 18:52:21,495][cryspy_init][INFO] # ---------- Read input file, cryspy.in
[2025-03-06 18:52:21,496][write_input][INFO] [basic]
[2025-03-06 18:52:21,496][write_input][INFO] algo = RS
[2025-03-06 18:52:21,496][write_input][INFO] calc_code = ASE
[2025-03-06 18:52:21,496][write_input][INFO] tot_struc = 5
[2025-03-06 18:52:21,496][write_input][INFO] nstage = 1
[2025-03-06 18:52:21,496][write_input][INFO] njob = 2
[2025-03-06 18:52:21,496][write_input][INFO] jobcmd = zsh
[2025-03-06 18:52:21,496][write_input][INFO] jobfile = job_cryspy
...
(omitted)
...
[2025-03-06 18:52:21,497][rs_gen][INFO] # ---------- Initial structure generation
[2025-03-06 18:52:21,497][rs_gen][INFO] # ------ mindist
[2025-03-06 18:52:21,498][struc_util][INFO] Cu - Cu: 1.32
[2025-03-06 18:52:21,498][rs_gen][INFO] # ------ generate structures
[2025-03-06 18:52:21,519][gen_pyxtal][INFO] Structure ID      0: (8,) Space group:  31 -->  31 Pmn2_1
[2025-03-06 18:52:21,525][gen_pyxtal][INFO] Structure ID      1: (8,) Space group: 198 --> 198 P2_13
[2025-03-06 18:52:21,554][gen_pyxtal][INFO] Structure ID      2: (8,) Space group:   4 -->   4 P2_1
[2025-03-06 18:52:21,580][gen_pyxtal][INFO] Structure ID      3: (8,) Space group: 193 --> 191 P6/mmm
[2025-03-06 18:52:21,581][gen_pyxtal][WARNING] Compoisition [8] not compatible with symmetry 172:     spg = 172 retry.
[2025-03-06 18:52:21,625][gen_pyxtal][INFO] Structure ID      4: (8,) Space group:  64 -->  64 Cmce
[2025-03-06 18:52:22,013][cryspy_init][INFO] Elapsed time for structure generation: 0:00:00.516183

Several output files are also generated.

  • (cryspy.out): Short log. only version 0.10.3 or earlier.
  • cryspy.stat: Status file.
  • data/init_POSCARS: Initial struture file in POSCAR format. You can open this file using VESTA
  • data/pkl_data: Directory to save pickled data.
  • log_cryspy: log.
  • err_cryspy: error and warning.

Let’s take a look at cryspy.stat file.

[status]
id_queueing = 0 1 2 3 4

Structure ID 0 – 4 are queueing because we just generated structures, and have not submitted yet.

Tip

Check the initial structures, if the distances between atoms are too close, you should set the mindist in cryspy.in.

Submit Job

2023 July 10, update

Continue

CrySPY continues the simulation if you have cryspy.stat file.

Tip

Continue if you have crypy.stat
Start from the beginning if you don’t have cryspy.stat

Submit Job

Run CyrSPY again.

cryspy

Check the screen or log_cryspy file.

[2023-07-10 18:52:51,859][cryspy_restart][INFO] 


Restart CrySPY 1.2.0


[2023-07-10 18:52:51,869][ctrl_job][INFO] # ---------- job status
[2023-07-10 18:52:51,904][ctrl_job][INFO] ID      0: submit job, Stage 1
[2023-07-10 18:52:51,931][ctrl_job][INFO] ID      1: submit job, Stage 1

And also cryspy.stat file.

...
(omit)
...
[status]
id_queueing = 2 3 4
id      0 = Stage 1
id      1 = Stage 1

CrySPY submitted two jobs for structure ID 0 and 1 as you set njob = 2 in cryspy.in. Calculations are performed in the work directory. These directory names correspond to their structure ID.

tree -d work
work
├── 000000
├── 000001
└── fin

When the two jobs are done, run CrySPY again.

cryspy
[2023-07-10 18:55:01,053][cryspy_restart][INFO] 


Restart CrySPY 1.2.0


[2023-07-10 18:55:01,058][ctrl_job][INFO] # ---------- job status
[2023-07-10 18:55:01,058][ctrl_job][INFO] ID      0: Stage 1 Done!
[2023-07-10 18:55:01,093][ctrl_job][INFO]     collect results: E = -0.00696997755502915 eV/atom
[2023-07-10 18:55:01,132][ctrl_job][INFO] ID      1: Stage 1 Done!
[2023-07-10 18:55:01,133][ctrl_job][INFO]     collect results: E = 0.4934076667166454 eV/atom
[2023-07-10 18:55:01,144][cryspy][INFO] 

recheck 1

[2023-07-10 18:55:01,145][ctrl_job][INFO] # ---------- job status
[2023-07-10 18:55:01,153][ctrl_job][INFO] ID      2: submit job, Stage 1
[2023-07-10 18:55:01,161][ctrl_job][INFO] ID      3: submit job, Stage 1

If you set nstage = 2 (more than 2), new jobs on stage 2 for ID 0 and 1 are submitted. If you set nstage = 1, CrySPY collects calculation data of ID 0 and 1, then submits next ID’s jobs. Directories of the finished structure are moved to the fin directory.

Repeat cryspy several times until all 5 structures are done. You can delete the work directory when the simulation is done if you do not need it.

The auto script (repeat_cryspy) may help you.

Check Results

Last updated: October 16, 2026

Move to data directory. There should be a few more files.

$ cd data
$ ls
cryspy_rslt  cryspy_rslt_energy_asc  init_POSCARS  opt_POSCARS  pkl_data/
  • cryspy_rslt: Result file.
  • cryspy_rslt_energy_asc: Result file sorted in energy ascending order.
  • init_POSCARS: Initial struture file in POSCAR format.
  • opt_POSCARS: Optimized structure file in POSCAR format.
  • pkl_data/: Directory to save pickled data.

The results are written to text files, cryspy_rslt and cryspy_rslt_energy_asc (and also saved in pickle data in pkl_data directory).

From v1.5.0, rslt_out in the [option] section controls when cryspy_rslt and cryspy_rslt_energy_asc are written. The default is always. See Input File > [option] Section for details.

Each result appends to cryspy_rslt file in the order in which one finished earlier.

cat cryspy_rslt
   Spg_num Spg_sym  Spg_num_opt Spg_sym_opt  E_eV_atom  Magmom      Opt
0      139  I4/mmm          139      I4/mmm  -3.000850     NaN     done
1       98  I4_122           12        C2/m  -3.978441     NaN  not_yet
2       16    P222           16        P222  -3.348616     NaN  not_yet
3       36  Cmc2_1           36      Cmc2_1  -3.520306     NaN  not_yet
4       36  Cmc2_1            4        P2_1  -3.304168     NaN  not_yet
Info

Not ID order in cryspy_rslt

In cryspy_rslt_energy_asc file, the results are sorted in energy ascending order.

cat cryspy_rslt_energy_asc
   Spg_num Spg_sym  Spg_num_opt Spg_sym_opt  E_eV_atom  Magmom      Opt
1       98  I4_122           12        C2/m  -3.978441     NaN  not_yet
3       36  Cmc2_1           36      Cmc2_1  -3.520306     NaN  not_yet
2       16    P222           16        P222  -3.348616     NaN  not_yet
4       36  Cmc2_1            4        P2_1  -3.304168     NaN  not_yet
0      139  I4/mmm          139      I4/mmm  -3.000850     NaN     done

Spg_num and Spg_sym show space group information on initial structures. Spg_num_opt and Spg_sym_opt are those of optimized structures. The last column Opt indicates whether or not optimization reached required accuracy.

Append Structures

Last updated: October 16, 2026

Of course only 5 structures are not enough to find stable structures. You can append structures whenever you want. Here let’s append more 5 structures.

For Si-Si mindist, the default value of 1.11 Å is used in the first structure generation (see log_cryspy), which is a little too close. Let us try to set the mindist to 2.0 Å.

Info

Edit cryspy.in and change the value of tot_struc into 10, and add mindist_1 = 2.0

emacs cryspy.in
cat cryspy.in
[basic]
algo = RS
calc_code = soiap
tot_struc = 10
nstage = 1
njob = 2
jobcmd = zsh
jobfile = job_cryspy

[structure]
atype = Si
nat = 8
mindist_1 = 2.0

[soiap]
soiap_infile = soiap.in
soiap_outfile = soiap.out
soiap_cif = initial.cif

[option]
rslt_out = always

Then run cryspy, and check log_cryspy file.

cryspy &
cat log_cryspy
...
(omit)
...

2023/03/19 00:01:47
CrySPY 1.0.0
Restart cryspy.py


Changed tot_struc from 5 to 10
Changed mindist from None to [[2.0]]

Backup data

# ---------- Append structures
# ------ mindist
Si - Si 2.0
Structure ID      5 was generated. Space group: 218 --> 221 Pm-3m
Structure ID      6 was generated. Space group:  86 --> 129 P4/nmm
Structure ID      7 was generated. Space group: 129 --> 129 P4/nmm
Structure ID      8 was generated. Space group: 191 --> 191 P6/mmm
Structure ID      9 was generated. Space group:  31 -->  31 Pmn2_1

Remember that CrySPY goes into structure generation mode whenever you change the value of tot_struc. In this mode, CrySPY does not do any other action such as collecting data, submitting jobs, and so on.

Note

Structure generation mode whenever you change the value of tot_struc.
From version 1.0.0, CrySPY automatically backs up when adding structures. See features/backup.

Repeat cryspy & several times until all appended structures are done. The auto script (repeat_cryspy) may help you.

Analysis and Visualization

Last updated: February 9, 2026

Energy Plot

Since version 1.4.4, results can be easily visualized using the cryspy-Eplot command as follows:

cryspy-Eplot 

The file is saved to ./data/energy_plot/energy_RS_{tot_struc}.{fig_fotmat}.

energy_RS_10 energy_RS_10

The following input variables can be modified by specifying them in the [visual] section of cryspy.in. See also CrySPY > Input file > [visual] section.

...

[visual]
ymax = 0.2
markersize = 10
fig_format = svg

...

For more advanced data analysis or figure customization, download the files and use Jupyter Notebook as shown below.

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_RS.ipynb. Alternatively, you can download it directly from GitHub (CrySPY_utility/notebook/). Launch Jupyter (e.g., VS Code, Jupyter Lab, or Jupyter Notebook), and simply run the cells in order to obtain a figure like the one shown below.

Cu8_RS Cu8_RS

Subsections of Evolutionary Algorithm (EA)

ASE on Your Local PC

Last updated: October 16, 2026

The files used in this tutorial can be downloaded from CrySPY_utility/examples/ase_Cu8Au8_EA. This tutorial demonstrates a test run on a local machine using ASE’s lightweight Pure Python EMT calculator. The target system is Cu8Au8.

cryspy.in

Example of cryspy.in.

[basic]
algo = EA
calc_code = ASE
nstage = 1
njob = 5
jobcmd = zsh
jobfile = job_cryspy

[structure]
atype = Cu Au
nat = 8 8

[EA]
n_pop = 10
n_crsov = 5
n_perm = 2
n_strain = 2
n_rand = 1
n_elite = 1
n_fittest = 5
slct_func = TNM
t_size = 2
maxgen_ea = 0

[ASE]
ase_python = ase_in.py

[option]
rslt_out = always
energy_output_interval = 1
backup_interval = 1
  • Use algo = EA.
  • From v1.5.0, energy_output_interval in the [option] section sets the output interval in generations for the energy plot. Default: 1 (every generation); 0 disables automatic output.
  • From v1.5.0, backup_interval in the [option] section sets the automatic backup interval in generations. The default is 1; 0 disables automatic backups. See Features > Backup for details.
  • When using a bash environment, set jobcmd to bash.
  • In EA, tot_struc is not used. The number of structures is determined by n_pop.
  • n_pop = n_crsov + n_perm + n_strain + n_rand
  • For parameters in the [EA] section, refer to Input file > [EA] section and Search algorithms > Evolutionary algorithm (EA).

calc_in/

The contents under calc_in/ are the same as in Tutorial > Random Search (RS) > ASE in 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
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)

# ---------- run
converged = opt.run(fmax=0.01, steps=2000)

# ---------- rule in ASE interface
# output file for energy: 'log.tote' in eV/cell
#                         CrySPY reads the last line of 'log.tote' file
# outimized structure: 'CONTCAR' file in vasp format
# check_opt: 'out_check_opt' file ('done' or 'not yet')
#                         CrySPY reads the last line of 'out_check_opt' file

# ------ 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)

# ------ check_opt
with open('out_check_opt', mode='w') as f:
    if converged:
        f.write('done\n')
    else:
        f.write('not yet\n')

calc_in/job_cryspy

#!/bin/sh

# ---------- ASE
python3 ase_in.py > out.log

Create Next Generation

Last updated: October 16, 2026

First Run

When you run cryspy, the program enters structure generation mode. It generates the first generation of random structures and then exits.

cryspy

log

...
[2025-04-06 09:15:34,720][ea_init][INFO] # ---------- Initialize evolutionary algorithm
[2025-04-06 09:15:34,720][ea_init][INFO] # ------ Generation 1
[2025-04-06 09:15:34,720][ea_init][INFO] 10 structures by random

In EA, running cryspy appends the current generation’s information to cryspy.stat.

[status]
generation = 1
id_queueing = 0 1 2 3 4 5 6 7 8 9

Optimize Structures

After running cryspy several times and completing the structure optimization for the first generation, the output will appear as shown below.

...
[2025-04-06 09:20:26,218][ctrl_job][INFO] Done generation 1
[2025-04-06 09:20:26,218][ctrl_job][INFO] 
EA is ready

Create Next Generation

Once all preparations are complete, running cryspy again starts generating the next-generation structures. By default (backup_interval = 1), an automatic backup is performed immediately before generating these structures. From v1.5.0, backup_interval in the [option] section can be used to change the interval in generations; 0 disables automatic backups. See Features > Backup for details.

cryspy
...
[2025-04-06 09:35:11,546][cryspy_restart][INFO] read input, cryspy.in
[2025-04-06 09:35:11,554][ctrl_job][INFO] # ---------- job status
[2025-04-06 09:35:11,554][ctrl_job][INFO] Done generation 1
[2025-04-06 09:35:11,554][utility][INFO] Backup data
[2025-04-06 09:35:11,611][ea_next_gen][INFO] # ---------- Evolutionary algorithm
[2025-04-06 09:35:11,611][ea_next_gen][INFO] Generation 2
[2025-04-06 09:35:11,613][ea_next_gen][INFO] # ------ natural selection
[2025-04-06 09:35:11,687][ea_next_gen][INFO] ranking without duplication (including elite):
[2025-04-06 09:35:11,687][ea_next_gen][INFO] Structure ID      1, fitness:   -0.00530
[2025-04-06 09:35:11,687][ea_next_gen][INFO] Structure ID      3, fitness:    0.01490
[2025-04-06 09:35:11,687][ea_next_gen][INFO] Structure ID      4, fitness:    0.04485
[2025-04-06 09:35:11,687][ea_next_gen][INFO] Structure ID      7, fitness:    0.11501
[2025-04-06 09:35:11,687][ea_next_gen][INFO] Structure ID      8, fitness:    0.15254
[2025-04-06 09:35:11,687][ea_next_gen][INFO] # ------ Generate children
[2025-04-06 09:35:11,687][ea_child][INFO] # -- mindist
[2025-04-06 09:35:11,689][struc_util][INFO] Cu - Cu: 1.32
[2025-04-06 09:35:11,689][struc_util][INFO] Cu - Au: 1.34
[2025-04-06 09:35:11,689][struc_util][INFO] Au - Au: 1.36
[2025-04-06 09:35:11,740][crossover][INFO] Structure ID     10 (8, 8) was generated from      3 and      1 by crossover. Space group:   1 P1
[2025-04-06 09:35:11,764][crossover][WARNING] remove_within_mindist: some atoms within mindist. retry.
[2025-04-06 09:35:11,774][crossover][INFO] Structure ID     11 (8, 8) was generated from      3 and      1 by crossover. Space group:   1 P1
[2025-04-06 09:35:11,789][crossover][INFO] Structure ID     12 (8, 8) was generated from      1 and      4 by crossover. Space group:   1 P1
[2025-04-06 09:35:11,833][crossover][INFO] Structure ID     13 (8, 8) was generated from      1 and      3 by crossover. Space group:   1 P1
[2025-04-06 09:35:11,852][crossover][WARNING] mindist in _add_border_line: Cu - Cu, 0.567032320824818. retry.
[2025-04-06 09:35:11,861][crossover][INFO] Structure ID     14 (8, 8) was generated from      7 and      1 by crossover. Space group:   1 P1
[2025-04-06 09:35:11,875][permutation][INFO] Structure ID     15 (8, 8) was generated from      1 by permutation. Space group: 146 R3
[2025-04-06 09:35:11,888][permutation][INFO] Structure ID     16 (8, 8) was generated from      3 by permutation. Space group:   1 P1
[2025-04-06 09:35:11,890][strain][WARNING] mindist in strain: Cu - Cu, 1.3050485787603692. retry.
[2025-04-06 09:35:11,903][strain][INFO] Structure ID     17 (8, 8) was generated from      3 by strain. Space group:   1 P1
[2025-04-06 09:35:11,917][strain][INFO] Structure ID     18 (8, 8) was generated from      1 by strain. Space group:   1 P1
[2025-04-06 09:35:12,513][ea_child][INFO] # ------ Random structure generation
[2025-04-06 09:35:12,513][rs_gen][INFO] # ------ mindist
[2025-04-06 09:35:12,515][struc_util][INFO] Cu - Cu: 1.32
[2025-04-06 09:35:12,515][struc_util][INFO] Cu - Au: 1.34
[2025-04-06 09:35:12,515][struc_util][INFO] Au - Au: 1.36
[2025-04-06 09:35:12,516][rs_gen][INFO] # ------ generate structures
[2025-04-06 09:35:12,530][gen_pyxtal][INFO] Structure ID     19: (8, 8) Space group:  86 -->  86 P4_2/n
[2025-04-06 09:35:12,533][ea_next_gen][INFO] # ------ Select elites
[2025-04-06 09:35:12,533][ea_next_gen][INFO] Structure ID      9 keeps as the elite

After that, simply running cryspy repeatedly will advance the structure search.

Check Results

Last updated: October 16, 2026

cryspy_rslt

The following is an example of cryspy_rslt after completing calculations up to the third generation. In EA, generation information (Gen) is also included.

From v1.5.0, rslt_out in the [option] section controls when cryspy_rslt and cryspy_rslt_energy_asc are written. The default is always. See Input File > [option] Section for details.

    Gen  Spg_num Spg_sym  Spg_num_opt Spg_sym_opt  E_eV_atom  Magmom      Opt
0     1      214  I4_132          230       Ia-3d   1.168743     NaN  no_file
1     1      198   P2_13          198       P2_13  -0.005303     NaN  no_file
2     1       95  P4_322           95      P4_322   0.389566     NaN  no_file
3     1       27    Pcc2           27        Pcc2   0.014898     NaN  no_file
4     1       60    Pbcn           60        Pbcn   0.044852     NaN  no_file
5     1      116   P-4c2          116       P-4c2   0.403246     NaN  no_file
6     1      187   P-6m2          187       P-6m2   1.054706     NaN  no_file
7     1      161     R3c          160         R3m   0.115009     NaN  no_file
8     1      146      R3          146          R3   0.152535     NaN  no_file
9     1       60    Pbcn           47        Pmmm  -0.005676     NaN  no_file
10    2        1      P1            1          P1   0.026070     NaN  no_file
11    2        1      P1            7          Pc   0.005898     NaN  no_file
12    2        1      P1            1          P1   0.005208     NaN  no_file
13    2        1      P1            1          P1   0.005506     NaN  no_file
14    2        1      P1            1          P1   0.024364     NaN  no_file
15    2      146      R3          146          R3   0.011525     NaN  no_file
16    2        1      P1            1          P1   0.014590     NaN  no_file
17    2        1      P1            1          P1   0.015236     NaN  no_file
18    2        1      P1            2         P-1  -0.012335     NaN  no_file
19    2       86  P4_2/n          140      I4/mcm   0.274548     NaN  no_file
20    3        1      P1            1          P1   0.013611     NaN  no_file
21    3        1      P1           10        P2/m  -0.014166     NaN  no_file
22    3        1      P1            1          P1   0.019472     NaN  no_file
23    3        1      P1            1          P1   0.011641     NaN  no_file
24    3        1      P1            1          P1   0.000297     NaN  no_file
25    3        1      P1            1          P1   0.005596     NaN  no_file
26    3        1      P1            1          P1   0.013374     NaN  no_file
27    3        1      P1            2         P-1   0.005055     NaN  no_file
28    3        2     P-1           12        C2/m  -0.012396     NaN  no_file
29    3      182  P6_322          182      P6_322   0.711472     NaN  no_file

ea_info

The EA parameters used in each generation are recorded in ea_info.

Gen Population Crossover Permutation Strain Random Elite crs_lat slct_func
  1         10         0           0      0     10     0  random       TNM
  2         10         5           2      2      1     1  random       TNM
  3         10         5           2      2      1     1  random       TNM

ea_origin

Information about the structure generation method and parent individuals is output to ea_origin.

Gen Struc_ID   Operation   Parent
  1        0      random     None
  1        1      random     None
  1        2      random     None
  1        3      random     None
  1        4      random     None
  1        5      random     None
  1        6      random     None
  1        7      random     None
  1        8      random     None
  1        9      random     None
  2       10   crossover   (3, 1)
  2       11   crossover   (3, 1)
  2       12   crossover   (1, 4)
  2       13   crossover   (1, 3)
  2       14   crossover   (7, 1)
  2       15 permutation     (1,)
  2       16 permutation     (3,)
  2       17      strain     (3,)
  2       18      strain     (1,)
  2       19      random     None
  2        9       elite    elite
  3       20   crossover (18, 12)
  3       21   crossover  (12, 9)
  3       22   crossover (12, 18)
  3       23   crossover  (18, 9)
  3       24   crossover (13, 18)
  3       25 permutation    (18,)
  3       26 permutation     (9,)
  3       27      strain    (18,)
  3       28      strain    (18,)
  3       29      random     None
  3       18       elite    elite

Analysis and Visualization

Last updated: October 16, 2026

Automatic Energy Plotting

Since version 1.4.4, the energy plot is automatically generated after each generation finishes by default.

The figure is saved to ./data/energy_plot/energy_EA_gen_{gen}.{fig_fotmat}.

From version 1.5.0, the output interval in generations can be changed with energy_output_interval in the [option] section. The default is 1 (every generation); 0 disables automatic output. See Input File > [option] Section for details.

energy_EA_gen_3 energy_EA_gen_3

The following input variables can be set in the [visual] section of cryspy.in. See also CrySPY > Input file > [visual] section.

...
[visual]
ymax = 0.2
markersize = 10
fig_format = svg
...

Replotting with cryspy-Eplot

If you want to fine-tune the figure and replot it, you can easily do so using the cryspy-Eplot command as follows:

cryspy-Eplot 

When using the cryspy-Eplot command, the following variables can also be specified in the [visual] section in addition to the standard variables above.

  • plot_min_gen
  • plot_max_gen
  • ref_gen

For example, to replot the figure at generation 2, write the [visual] section as follows:

...
[visual]
plot_max_gen = 2
...

Then, run the following command:

cryspy-Eplot 

energy_EA_gen_2 energy_EA_gen_2

In this case, CrySPY overwrites ./data/energy_plot/energy_EA_gen_{gen}.{fig_fotmat}.

You can specify the range of generations to be plotted using plot_min_gen and plot_max_gen. When plot_min_gen is set to specify a range (even if its value is 1), the output is saved with a different filename such as ./data/energy_plot/energy_EA_gen_{plot_min_gen}-{plot_max_gen}.{fig_fotmat}, instead of the usual one. For example, to extract only the results of the second generation from the results available at generation 2:

...
[visual]
plot_min_gen = 2
plot_max_gen = 2
...

energy_EA_gen_2-2 energy_EA_gen_2-2

To change which generation the plot goes up to (i.e., the maximum value of the x-axis), specify the generation with ref_gen. For example, as shown in the image at the top of this page, if three generations have been completed and you want to extract only the results from the second generation, set the [visual] section in cryspy.in as follows:

...
[visual]
plot_max_gen = 2
plot_min_gen = 2
ref_gen = 3
...

If ref_gen is specified, the output filename becomes energy_EA_gen_{plot_min_gen}-{plot_max_gen}_ref_{ref_gen}.{fig_format}.

energy_EA_gen_2-2 energy_EA_gen_2-2

For more advanced data analysis or figure customization, download the files and use Jupyter Notebook as shown below.

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.ipynb. Alternatively, you can download it directly from GitHub (CrySPY_utility/notebook/). Launch Jupyter (e.g., VS Code, Jupyter Lab, or Jupyter Notebook), and simply run the cells in order to obtain a figure like the one shown below.

Cu8Au8_EA Cu8Au8_EA

Variable-Composition Evolutionary Algorithm (EA-vc)

Info
Info

System requirements

Preparation of Input Files

Follow one of the instructions below, then proceed to the section on running CrySPY.

To impose a charge neutrality condition, specify charge in the [structure] section of cryspy.in. See Features > Charge neutrality condition for details.

To restrict the composition range explored by the search, specify min_comp and max_comp in the [structure] section of cryspy.in (version 1.5.0 or later). These constraints can also be combined with charge neutrality. See Features > Composition Constraints for details.

Running CrySPY

Subsections of Variable-Composition Evolutionary Algorithm (EA-vc)

ASE on Your Local PC (Cu-Ag-Au)

Last updated: October 16, 2026

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
n_elite = 2
n_fittest = 10
slct_func = TNM
t_size = 2
ref_energies = 0.0 0.0 0.0
maxgen_ea = 0

[option]
rslt_out = always
energy_output_interval = 1
backup_interval = 1

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

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)

# ---------- run
converged = opt.run(fmax=0.01, steps=2000)

# ---------- rule in ASE interface
# output file for energy: 'log.tote' in eV/cell
#                         CrySPY reads the last line of 'log.tote' file
# outimized structure: 'CONTCAR' file in vasp format
# check_opt: 'out_check_opt' file ('done' or 'not yet')
#                         CrySPY reads the last line of 'out_check_opt' file

# ------ 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)

# ------ check_opt
with open('out_check_opt', mode='w') as f:
    if converged:
        f.write('done\n')
    else:
        f.write('not yet\n')

calc_in/job_cryspy

#!/bin/sh

# ---------- ASE
python3 ase_in.py > out.log

MLIP(Cu-Au)

Last updated: October 16, 2026

Info
  • A machine learning interatomic potential (MLIP) with an ASE Calculator interface must be installed.
  • This tutorial uses CHGNet as an example.

The files used in this tutorial can be downloaded from CrySPY_utility/examples/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 interatomic potential (MLIP) CHGNet. By changing the Calculator, you can use a variety of MLIPs. 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 ref_energies (end_point in versions 1.4.3 and earlier) 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 ref_energies will be created in each directory, containing the energy per atom (eV/atom) after structure relaxation.

cat Au_fcc/ref_energies
-3.2357187271118164
cat Cu_fcc/ref_energies
-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
n_elite = 2
n_fittest = 10
slct_func = TNM
t_size = 2
maxgen_ea = 0
ref_energies = -4.08352709  -3.23571777

[option]
rslt_out = always
energy_output_interval = 1
backup_interval = 1
  • Use algo = EA-vc.
  • From v1.5.0, energy_output_interval in the [option] section sets the output interval in generations for the convex-hull plot and hull-distance file. Default: 1 (every generation); 0 disables automatic output.
  • From v1.5.0, backup_interval in the [option] section sets the automatic backup interval in generations. The default is 1; 0 disables automatic backups. See Features > Backup for details.
  • Since MLIPs use the ASE Calculator interface, set calc_code = ASE.
  • Change jobcmd according to your computing environment.
  • In the [structure] section, use ll_nat to specify the minimum number of atoms for each element, and ul_nat for the maximum.
  • n_pop = n_crsov + n_perm + n_strain + n_rand + n_add + n_elim + n_subs
  • In the ref_energies (end_point in versions 1.4.3 and earlier), enter the per-atom energies (in eV/atom) of each pure element—Cu and Au. Use the values obtained from the pre-calculations, and make sure the order follows that of atype.
  • For the parameters in the [EA] section, refer to CrySPY > Input file > [EA] Section and CrySPY > Search algorithms > Variable-composition evolutionary algorithm (EA-vc).
  • Refer also to CrySPY > Tutorial > Variable-composition evolutionary algorithm (EA-VC) > Analysis and Visualization for the parameters of the automatically generated convex hull plot.

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

# ---------- 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
converged = opt.run(fmax=0.01, steps=2000)

# ---------- rule in ASE interface
# output file for energy: 'log.tote' in eV/cell
#                         CrySPY reads the last line of 'log.tote' file
# outimized structure: 'CONTCAR' file in vasp format
# check_opt: 'out_check_opt' file ('done' or 'not yet')
#                         CrySPY reads the last line of 'out_check_opt' file

# ------ 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)

# ------ check_opt
with open('out_check_opt', mode='w') as f:
    if converged:
        f.write('done\n')
    else:
        f.write('not yet\n')

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

VASP(Fe-Al)

Last updated: October 16, 2026

EA-vc became compatible with VASP in version 1.4.2.

The files used here can be downloaded from CrySPY_utility/examples/vasp_Fe-Al_EA-vc. This tutorial assumes calculations are performed on a computer cluster with a job scheduler using VASP. The target system is a binary Fe-Al alloy, and calculations are performed assuming ferromagnetism.

Pre-Calculation

In EA-vc, the per-atom energies of each elemental phase must be used as the reference in the ref_energies (end_point in versions 1.4.3 and earlier) setting of cryspy.in, so they need to be calculated beforehand. There should be two directories inside the example.

Al-fcc
├── POSCAR
├── INCAR
├── POTCAR_dummy
└── job_cryspy
Fe-bcc
├── POSCAR
├── INCAR
├── POTCAR_dummy
└── job_cryspy

Crystal structure data (POSCAR), input files for structure optimization and energy calculation (INCAR), and job scripts (job_cryspy) are provided, so edit them as needed to match your computing environment. Also, the POTCAR files cannot be distributed, so please prepare them yourself.

In the INCAR file, be sure to use the same cutoff and other values for the single-element calculations as you will use in the final calculations.

Run the jobs (replace the job submission command as appropriate for your environment).

cd Al_fcc
qsub job_cryspy
cd ../Fe_bcc
qsub job_cryspy
cd ..

After the calculations are finished, obtain the energy per atom. In this case, since BCC and FCC unit cells each contain one atom, you can use the total energy value directly. Normally, divide the total energy by the number of atoms in the unit cell to obtain the per-atom energy.

cryspy.in

cryspy.in

[basic]
algo = EA-vc
calc_code = VASP
nstage = 2
njob = 10
jobcmd = qsub
jobfile = job_cryspy

[structure]
atype =  Fe Al
ll_nat =  0  0
ul_nat =  8  8

[VASP]
kppvol = 40 120
vasp_MAGMOM = 4.0 0.0

[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
n_elite = 2
n_fittest = 10
slct_func = TNM
t_size = 2
maxgen_ea = 0
ref_energies = -8.24249611  -3.74226843

[option]
rslt_out = always
energy_output_interval = 1
backup_interval = 1
  • Use algo = EA-vc.
  • From v1.5.0, energy_output_interval in the [option] section sets the output interval in generations for the convex-hull plot and hull-distance file. Default: 1 (every generation); 0 disables automatic output.
  • From v1.5.0, backup_interval in the [option] section sets the automatic backup interval in generations. The default is 1; 0 disables automatic backups. See Features > Backup for details.
  • Change jobcmd according to your computing environment.
  • In the [structure] section, use ll_nat to specify the minimum number of atoms for each element, and ul_nat for the maximum.
  • n_pop = n_crsov + n_perm + n_strain + n_rand + n_add + n_elim + n_subs
  • In the ref_energies (end_point in versions 1.4.3 and earlier), enter the per-atom energies (in eV/atom) of each pure element—Cu and Au. Use the values obtained from the pre-calculations, and make sure the order follows that of atype.
  • For the parameters in the [EA] section, refer to CrySPY > Input file > [EA] Section and CrySPY > Search algorithms > Variable-composition evolutionary algorithm (EA-vc).
  • Refer also to CrySPY > Tutorial > Variable-composition evolutionary algorithm (EA-VC) > Analysis and Visualization for the parameters of the automatically generated convex hull plot.

For VASP

In the [VASP] section, specify the MAGMOM values for each element corresponding to atype in vasp_MAGMOM. When CrySPY copies the INCAR file to ./work/xxx/INCAR (where xxx is the structure ID), it appends n*vasp_MAGMOM (n is the number of atoms).

For example, if atype = (‘Fe’, ‘Al’), nat = (5, 3), and vasp_MAGMOM = (4.0 0.0), the following will be appended.

MAGMOM = 5*4.0 3*0.0

Although not used in this tutorial, INCAR’s LDAUL, LDAUU, and LDAUJ are also supported. In cryspy.in, they are used with the vasp_ prefix as follows:

[VASP]
kppvol = 40 120
vasp_MAGMOM = 4.0 0.0
vasp_LDAUL = 2 -1
vasp_LDAUU = 4.0 0.0
vasp_LDAUJ = 0.0 0.0

If the system changes from a binary alloy to a single element, such as nat = (5, 0), CrySPY will append the following to ./work/xxx/INCAR. No action is taken for elements with an atomic number of zero.

MAGMOM = 5*4.0
LDAUL = 2
LDAUU = 4.0
LDAUJ = 0.0

calc_in/

POTCAR

In EA-vc, prepare a separate POTCAR file for each element. The file names should be:

  • POTCAR_Fe
  • POTCAR_Al

Add the element name as written in atype to the end of the file name. CrySPY prepares ./work/xxx/POTCAR according to the number of atoms in the structure. For example, if the structure consists only of Fe (nat = (5, 0)), use POTCAR_Fe. If the structure is Fe-Al (nat = (4, 4)), concatenate POTCAR_Fe and POTCAR_Al to create POTCAR.

job_cryspy

#!/bin/sh
#$ -cwd
#$ -V -S /bin/bash
####$ -V -S /bin/zsh
#$ -N FeAl_CrySPY_ID
#$ -pe smp 32


# ---------- vasp
VASPROOT=/usr/local/vasp/vasp.6.4.2/bin
mpirun -np $NSLOTS $VASPROOT/vasp_std

INCAR

1_INCAR

SYSTEM = FeAl

Algo = Fast
####LREAL = Auto
ENCUT = 348

ISMEAR = 1
SIGMA = 0.1

NSW = 40
IBRION = 2
ISIF = 2

ISPIN = 2
######MAGMOM =   # cryspy append MAGMOM in work/xx/INCAR 

EDIFF = 1e-6
EDIFFG = -0.01

KPAR = 4

LWAVE = .FALSE.
LCHARG = .FALSE.

2_INCAR

SYSTEM = FeAl

Algo = Fast
####LREAL = Auto
ENCUT = 348

ISMEAR = 1
SIGMA = 0.1

NSW = 200
IBRION = 2
ISIF = 3

ISPIN = 2
######MAGMOM =   # cryspy append MAGMOM in work/xx/INCAR 

EDIFF = 1e-6
EDIFFG = -0.01

KPAR = 4

LWAVE = .FALSE.
LCHARG = .FALSE.

QE(Fe-Al)

Last updated: October 16, 2026

EA-vc became compatible with QE in version 1.4.2.

The files used here can be downloaded from CrySPY_utility/examples/qe_Fe-Al_EA-vc. This tutorial assumes calculations are performed on a computer cluster with a job scheduler using QE. The target system is a binary Fe-Al alloy, and calculations are performed assuming ferromagnetism.

Pre-Calculation

In EA-vc, the per-atom energies of each elemental phase must be used as the reference in the ref_energies (end_point in versions 1.4.3 and earlier) setting of cryspy.in, so they need to be calculated beforehand. There should be two directories inside the example.

Al-fcc
├── pwscf.in
└── job_cryspy
Fe-bcc
├── pwscf.in
└── job_cryspy

Input files (pwscf.in) and job scripts (job_cryspy) are provided, so edit them as needed to match your computing environment.

In the pwscf.in file, be sure to use the same cutoff and other values for the single-element calculations as you will use in the final calculations.

Run the jobs (replace the job submission command as appropriate for your environment).

cd Al_fcc
qsub job_cryspy
cd ../Fe_bcc
qsub job_cryspy
cd ..

After the calculations are finished, convert the energy per atom to eV units. In this case, since BCC and FCC unit cells each contain one atom, you can use the total energy value directly. Normally, divide the total energy by the number of atoms in the unit cell to obtain the per-atom energy.

cryspy.in

cryspy.in

[basic]
algo = EA-vc
calc_code = QE
nstage = 2
njob = 10
jobcmd = qsub
jobfile = job_cryspy

[structure]
atype =  Fe Al
ll_nat =  0  0
ul_nat =  8  8

[QE]
kppvol = 40 120
qe_infile = pwscf.in
qe_outfile = pwscf.out

[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
n_elite = 2
n_fittest = 10
slct_func = TNM
t_size = 2
maxgen_ea = 6
ref_energies = -3406.14117375  -91.25463006

[option]
rslt_out = always
energy_output_interval = 1
backup_interval = 1
  • Use algo = EA-vc.
  • From v1.5.0, energy_output_interval in the [option] section sets the output interval in generations for the convex-hull plot and hull-distance file. Default: 1 (every generation); 0 disables automatic output.
  • From v1.5.0, backup_interval in the [option] section sets the automatic backup interval in generations. The default is 1; 0 disables automatic backups. See Features > Backup for details.
  • Change jobcmd according to your computing environment.
  • In the [structure] section, use ll_nat to specify the minimum number of atoms for each element, and ul_nat for the maximum.
  • n_pop = n_crsov + n_perm + n_strain + n_rand + n_add + n_elim + n_subs
  • In the ref_energies (end_point in versions 1.4.3 and earlier), enter the per-atom energies (in eV/atom) of each pure element—Cu and Au. Use the values obtained from the pre-calculations, and make sure the order follows that of atype.
  • For the parameters in the [EA] section, refer to CrySPY > Input file > [EA] Section and CrySPY > Search algorithms > Variable-composition evolutionary algorithm (EA-vc).
  • Refer also to CrySPY > Tutorial > Variable-composition evolutionary algorithm (EA-VC) > Analysis and Visualization for the parameters of the automatically generated convex hull plot.

For QE

Unlike VASP, support for variable-composition in QE is straightforward. For binary system searches, always prepare binary system inputs in ./calc_in, and for ternary systems, always prepare ternary system inputs. However, only nat needs to be changed, so CrySPY automatically rewrites it. When preparing, write nat with any appropriate number as shown below:

nat = 1

In ./work/xxx/, CrySPY automatically rewrites lines that start with nat (excluding leading whitespace) to:

    nat = (actual number of atoms)

calc_in/

job_cryspy

#!/bin/sh
#$ -cwd
#$ -V -S /bin/bash
####$ -V -S /bin/zsh
#$ -N FeAl_CrySPY_ID
#$ -pe smp 32


QEROOT=/usr/local/qe/q-e-qe-7.3.1/bin
mpirun -np $NSLOTS $QEROOT/pw.x -nk 4 < pwscf.in > pwscf.out


if [ -e "CRASH" ]; then
    sed -i -e '3 s/^.*$/skip/' stat_job
    exit 1
fi

pwscf.in

1_pwscf.in

&control
calculation = 'relax'
nstep = 40
pseudo_dir = '/usr/local/qe/gbrv/all_pbe_UPF_v1.5/'
outdir='./outdir/'
/


&system
ibrav = 0
nat = 1
ntyp = 2
ecutwfc = 40
ecutrho = 200

occupations = "smearing"
smearing    = "mp"
degauss     =  0.01

nspin = 2
starting_magnetization(1) = 0.4
starting_magnetization(2) = 0.0
/


&electrons
mixing_beta = 0.4
/

&ions
/

&cell
/

ATOMIC_SPECIES
Fe -1.0 fe_pbe_v1.5.uspp.F.UPF
Al -1.0 al_pbe_v1.uspp.F.UPF

2_pwscf.in

&control
calculation = 'vc-relax'
nstep = 200
pseudo_dir = '/usr/local/qe/gbrv/all_pbe_UPF_v1.5/'
outdir='./outdir/'
/


&system
ibrav = 0
nat = 1
ntyp = 2
ecutwfc = 40
ecutrho = 200

occupations = "smearing"
smearing    = "mp"
degauss     =  0.01

nspin = 2
starting_magnetization(1) = 0.4
starting_magnetization(2) = 0.0
/


&electrons
mixing_beta = 0.4
/

&ions
/

&cell
/

ATOMIC_SPECIES
Fe -1.0 fe_pbe_v1.5.uspp.F.UPF
Al -1.0 al_pbe_v1.uspp.F.UPF

Create Next Generation

Last updated: October 16, 2026

First Run

When you run cryspy, the program enters structure generation mode. It generates the first generation of random structures and then exits.

cryspy

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.

...
[2026-07-07 15:18:02,548][cryspy_init][INFO] # ---------- Initial structure generation
[2026-07-07 15:18:02,548][rs_gen][INFO] # ------ mindist
[2026-07-07 15:18:02,549][struc_util][INFO] Cu - Cu: 1.32
[2026-07-07 15:18:02,549][struc_util][INFO] Cu - Ag: 1.385
[2026-07-07 15:18:02,549][struc_util][INFO] Cu - Au: 1.34
[2026-07-07 15:18:02,549][struc_util][INFO] Ag - Ag: 1.45
[2026-07-07 15:18:02,549][struc_util][INFO] Ag - Au: 1.405
[2026-07-07 15:18:02,549][struc_util][INFO] Au - Au: 1.36
[2026-07-07 15:18:02,549][rs_gen][INFO] # ------ Generate random structures
[2026-07-07 15:18:02,712][gen_pyxtal][INFO] Structure ID      0: (6, 6, 2) Space group: 196 --> 216 F-43m
[2026-07-07 15:18:02,721][gen_pyxtal][WARNING] Compoisition [7 5 3] not compatible with symmetry 224:     spg = 224 retry.
[2026-07-07 15:18:02,726][gen_pyxtal][WARNING] Compoisition [3 3] not compatible with symmetry 134:     spg = 134 retry.
[2026-07-07 15:18:02,733][gen_pyxtal][WARNING] Compoisition [ 6  4 16] not compatible with symmetry 140:     spg = 140 retry.
[2026-07-07 15:18:02,822][gen_pyxtal][INFO] Structure ID      1: (1, 4, 3) Space group:  23 -->  71 Immm
[2026-07-07 15:18:02,839][gen_pyxtal][INFO] Structure ID      2: (2, 2, 8) Space group: 150 --> 150 P321
...

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.

...
[2026-07-07 15:21:18,273][ea_next_gen][INFO] Done generation 1
[2026-07-07 15:21:18,273][ea_next_gen][INFO] Calculate convex hull for generation 1
Ignoring fixed y limits to fulfill fixed data aspect with adjustable data limits.
[2026-07-07 15:21:18,772][ea_next_gen][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/.

  • hull_dist_all_gen_1
      ID    hull distance (eV/atom)    Num_atom
      14                   0.000000    (0, 1, 3)
       9                   0.088493    (2, 8, 8)
      15                   0.105278    (8, 7, 5)
      10                   0.200962    (8, 0, 7)
       8                   0.210806    (0, 3, 3)
      13                   0.247862    (5, 6, 8)
      19                   0.258563    (6, 6, 1)
       5                   0.261977    (2, 6, 4)
       6                   0.269711    (7, 7, 2)
      18                   0.290792    (1, 6, 6)
      11                   0.292541    (8, 3, 1)
      16                   0.356158    (6, 2, 4)
       2                   0.373888    (2, 2, 8)
       7                   0.514507    (0, 4, 4)
      12                   0.548770    (3, 4, 4)
       1                   0.617685    (1, 4, 3)
       3                   0.761585    (1, 0, 8)
      17                   0.934091    (6, 4, 7)
       4                   0.955053    (2, 8, 4)
       0                   1.019078    (6, 6, 2)
  • conv_hull_gen_1.svg conv_hull_gen_1.svg conv_hull_gen_1.svg

Create Next Generation

Once all preparations are complete, running cryspy again starts generating the next-generation structures. By default (backup_interval = 1), an automatic backup is performed immediately before generating these structures. From v1.5.0, backup_interval in the [option] section can be used to change the interval in generations; 0 disables automatic backups. See Features > Backup for details.

cryspy
...
[2026-07-07 15:29:32,182][ea_next_gen][INFO] Done generation 1
[2026-07-07 15:29:32,505][utility][INFO] Backup data
[2026-07-07 15:29:32,512][ea_next_gen][INFO] # ---------- Evolutionary algorithm
[2026-07-07 15:29:32,512][ea_next_gen][INFO] Generation 2
[2026-07-07 15:29:32,512][ea_next_gen][INFO] # ------ Apply nat/composition constraints
[2026-07-07 15:29:32,512][ea_next_gen][INFO] Current candidates after constraint filter: 20
[2026-07-07 15:29:32,513][ea_next_gen][INFO] Elite structures after constraint filter: 0
[2026-07-07 15:29:32,513][ea_next_gen][INFO] # ------ natural selection
[2026-07-07 15:29:32,515][ea_next_gen][INFO] ranking without duplication (including elite):
[2026-07-07 15:29:32,515][ea_next_gen][INFO] Structure ID     14, fitness:    0.00000
[2026-07-07 15:29:32,515][ea_next_gen][INFO] Structure ID      9, fitness:    0.08849
[2026-07-07 15:29:32,515][ea_next_gen][INFO] Structure ID     15, fitness:    0.10528
[2026-07-07 15:29:32,515][ea_next_gen][INFO] Structure ID     10, fitness:    0.20096
[2026-07-07 15:29:32,515][ea_next_gen][INFO] Structure ID      8, fitness:    0.21081
[2026-07-07 15:29:32,515][ea_next_gen][INFO] Structure ID     13, fitness:    0.24786
[2026-07-07 15:29:32,515][ea_next_gen][INFO] Structure ID     19, fitness:    0.25856
[2026-07-07 15:29:32,515][ea_next_gen][INFO] Structure ID      5, fitness:    0.26198
[2026-07-07 15:29:32,515][ea_next_gen][INFO] Structure ID      6, fitness:    0.26971
[2026-07-07 15:29:32,515][ea_next_gen][INFO] Structure ID     18, fitness:    0.29079
[2026-07-07 15:29:32,515][ea_next_gen][INFO] # ------ Generate children
[2026-07-07 15:29:32,515][ea_child][INFO] # -- mindist
[2026-07-07 15:29:32,517][struc_util][INFO] Cu - Cu: 1.32
[2026-07-07 15:29:32,517][struc_util][INFO] Cu - Ag: 1.385
[2026-07-07 15:29:32,517][struc_util][INFO] Cu - Au: 1.34
[2026-07-07 15:29:32,517][struc_util][INFO] Ag - Ag: 1.45
[2026-07-07 15:29:32,517][struc_util][INFO] Ag - Au: 1.405
[2026-07-07 15:29:32,517][struc_util][INFO] Au - Au: 1.36
[2026-07-07 15:29:32,521][ea_child][INFO] eligible candidates for crossover and strain: 10
[2026-07-07 15:29:32,521][ea_child][INFO] eligible candidates for permutation: 10
[2026-07-07 15:29:32,521][ea_child][INFO] eligible candidates for addition: 10
[2026-07-07 15:29:32,522][ea_child][INFO] eligible candidates for elimination: 10
[2026-07-07 15:29:32,522][ea_child][INFO] eligible candidates for substitution: 10
[2026-07-07 15:29:32,527][crossover][WARNING] remove_within_mindist: some atoms within mindist. retry.
[2026-07-07 15:29:32,532][crossover][WARNING] remove_within_mindist: some atoms within mindist. retry.
[2026-07-07 15:29:32,537][crossover][WARNING] remove_within_mindist: some atoms within mindist. retry.
[2026-07-07 15:29:32,541][crossover][WARNING] remove_within_mindist: some atoms within mindist. retry.
[2026-07-07 15:29:32,547][crossover][WARNING] remove_within_mindist: some atoms within mindist. retry.
[2026-07-07 15:29:32,551][crossover][WARNING] remove_within_mindist: some atoms within mindist. retry.
[2026-07-07 15:29:32,556][crossover][WARNING] remove_within_mindist: some atoms within mindist. retry.
[2026-07-07 15:29:32,561][crossover][WARNING] remove_within_mindist: some atoms within mindist. retry.
[2026-07-07 15:29:32,564][crossover][WARNING] remove_within_mindist: some atoms within mindist. retry.
[2026-07-07 15:29:32,569][crossover][WARNING] remove_within_mindist: some atoms within mindist. retry.
[2026-07-07 15:29:32,592][crossover][WARNING] remove_within_mindist: some atoms within mindist. retry.
[2026-07-07 15:29:32,622][crossover][WARNING] remove_within_mindist: some atoms within mindist. retry.
[2026-07-07 15:29:32,644][crossover][WARNING] remove_within_mindist: some atoms within mindist. retry.
[2026-07-07 15:29:32,667][crossover][INFO] Structure ID     20 (8, 3, 5) was generated from     10 and     15 by crossover. Space group:   1 P1
[2026-07-07 15:29:32,668][crossover][INFO] Structure ID     21 (0, 1, 5) was generated from     14 and      8 by crossover. Space group:   1 P1
...
...
...
[2026-07-07 15:29:33,401][ea_next_gen][INFO] # ------ Apply nat/composition constraints to elite candidates
[2026-07-07 15:29:33,401][ea_next_gen][INFO] Elite candidates after constraint filter: 20
[2026-07-07 15:29:33,401][ea_next_gen][INFO] Structure ID     14 keeps as the elite
[2026-07-07 15:29:33,401][ea_next_gen][INFO] Structure ID      9 keeps as the elite

After that, simply running cryspy repeatedly will advance the structure search.

Check Results

Last updated: October 16, 2026

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.

From v1.5.0, rslt_out in the [option] section controls when cryspy_rslt and cryspy_rslt_energy_asc are written. The default is always. See Input File > [option] Section for details.

    Gen  Spg_num   Spg_sym  Spg_num_opt Spg_sym_opt  E_eV_atom  Ef_eV_atom   Num_atom  Magmom   Opt
0     1      216     F-43m          216       F-43m   1.016698    1.016698  (6, 6, 2)     NaN  done
1     1       71      Immm           71        Immm   0.611438    0.611438  (1, 4, 3)     NaN  done
2     1      150      P321          150        P321   0.365560    0.365560  (2, 2, 8)     NaN  done
3     1      191    P6/mmm          191      P6/mmm   0.761585    0.761585  (1, 0, 8)     NaN  done
4     1      139    I4/mmm          139      I4/mmm   0.950294    0.950294  (2, 8, 4)     NaN  done
5     1       59      Pmmn           59        Pmmn   0.256424    0.256424  (2, 6, 4)     NaN  done
6     1       16      P222           16        P222   0.267629    0.267629  (7, 7, 2)     NaN  done
7     1      183      P6mm          191      P6/mmm   0.506178    0.506178  (0, 4, 4)     NaN  done
8     1       35      Cmm2           35        Cmm2   0.202477    0.202477  (0, 3, 3)     NaN  done
9     1       32      Pba2           32        Pba2   0.081089    0.081089  (2, 8, 8)     NaN  done
10    1      148       R-3          148         R-3   0.200962    0.200962  (8, 0, 7)     NaN  done

Checking Results for a Specific Composition

From v1.5.0, the -c (--composition) option of cryspy-print displays only results with a specified composition ratio from rslt_data.pkl. Specify the ratio in atype order. In this example, atype = Cu Ag Au, so the following command selects structures with no Cu and an Ag:Au ratio of 1:1.

cryspy-print data/pkl_data/rslt_data.pkl -c 0 1 1 --all

Ratios are reduced before comparison, so IDs 7 and 8 in the table above, with Num_atom values of (0, 4, 4) and (0, 3, 3), both match. Matching results are displayed in ascending order of formation energy (Ef_eV_atom). --all displays all matching rows; replace it with --head 10 to display only the ten lowest-energy results.

Output for the data in the table above:

   Gen  Spg_num Spg_sym  Spg_num_opt Spg_sym_opt  E_eV_atom  Ef_eV_atom   Num_atom  Magmom   Opt
8    1       35    Cmm2           35        Cmm2   0.202477    0.202477  (0, 3, 3)     NaN  done
7    1      183    P6mm          191      P6/mmm   0.506178    0.506178  (0, 4, 4)     NaN  done

nat_data

Information on the number of atoms and composition is also included in nat_data.

      ID    ('Cu', 'Ag', 'Au')    Composition
       0    (    6,     6,     2)    (0.429, 0.429, 0.143)
       1    (    1,     4,     3)    (0.125, 0.500, 0.375)
       2    (    2,     2,     8)    (0.167, 0.167, 0.667)
       3    (    1,     0,     8)    (0.111, 0.000, 0.889)
       4    (    2,     8,     4)    (0.143, 0.571, 0.286)
       5    (    2,     6,     4)    (0.167, 0.500, 0.333)
       6    (    7,     7,     2)    (0.438, 0.438, 0.125)
       7    (    0,     4,     4)    (0.000, 0.500, 0.500)
       8    (    0,     3,     3)    (0.000, 0.500, 0.500)
       9    (    2,     8,     8)    (0.111, 0.444, 0.444)
      10    (    8,     0,     7)    (0.533, 0.000, 0.467)
...

hull_dist_all_gen_x

With the default settings, for example, after the third generation is completed, the hull distance data is output to the file ./data/convex_hull/hull_dist_all_gen_3. The output interval is set with energy_output_interval in the [option] section. The default is 1 (every generation); 0 disables automatic file output. See Input File > [option] Section for details.

      ID    hull distance (eV/atom)    Num_atom
      21                   0.000000    (0, 1, 5)
      46                   0.000000    (0, 1, 3)
      49                   0.000000    (0, 2, 3)
      56                   0.000000    (3, 0, 1)
      14                   0.000000    (0, 1, 3)
      28                   0.000001    (0, 1, 3)
      48                   0.002585    (0, 1, 3)
      45                   0.006762    (2, 8, 8)
      26                   0.007389    (2, 8, 8)
...

conv_hull_gen_x.svg

With the default settings, the convex hull plot at the end of generation 3 is saved as ./data/convex_hull/conv_hull_gen_3.svg. Automatic output of the convex hull plot follows the same energy_output_interval setting. Although svg is the default format, it can be changed to pdf or png by modifying the fig_format in the input file.

case_Cu-Ag-Au_EA-vc_gen3.svg case_Cu-Ag-Au_EA-vc_gen3.svg

Analysis and Visualization

Last updated: October 16, 2026

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 by default. The figure is saved to ./data/convex_hull/conv_hull_gen_{gen}.{fig_fotmat}.

From version 1.5.0, the output interval in generations can be changed with energy_output_interval in the [option] section. The default is 1 (every generation); 0 disables automatic output of the convex-hull plot and hull-distance file. The convex hull and hull distances are still calculated every generation. See Input File > [option] Section for details.

Binary System

fig_EA-vc_2d_lr fig_EA-vc_2d_lr fig_EA-vc_2d_rl fig_EA-vc_2d_rl

The above figures show examples after the search up to the third generation. The following input variables can be set in the [visual] section of cryspy.in. See also CrySPY > Input file > [visual] section.

...
[visual]
ymax = 0.2
markersize = 10
fig_format = svg
label_stable = True
vmax = 0.2
bottom_margin = 0.04
axis_order = lr
...

Here, vmax is the maximum value of the colorbar for the hull distance, and bottom_margin is the margin between the minimum formation energy and the lower limit of the y-axis. As shown in the left figure, when axis_order = lr (the default setting), the convex hull plot is drawn so that atype[0] is on the left and atype[1] is on the right. The right figure shows the case with axis_order = rl. That is, when atype = Cu Au, the pure Cu crystal is placed on the right side of the plot, while the pure Au crystal is placed on the left.

Ternary System

EA-vc_3d.svg EA-vc_3d.svg EA-vc_3d_ltr.svg EA-vc_3d_ltr.svg

The figures above show the examples for a ternary system. The following input variables can be set in the [visual] section of cryspy.in. See also CrySPY > Input file > [visual] section.

...
[visual]
markersize = 10
fig_format = svg
###show_max = 0.4
label_stable = True
vmax = 0.2
axis_order = tlr
...

Here, show_max specifies the maximum hull distance shown in ternary systems. In the above example, it is commented out, so the default value None is applied. When axis_order = tlr (the default setting), atype[0], atype[1], and atype[2] are placed at the top, left, and right vertices, respectively, in the ternary convex hull plot, as shown in the left figure. Adjust the vertex order accordingly for other permutations such as trl, ltr, etc. The right figure shows an example with axis_order = ltr. For atype = Cu Ag Au, Cu is placed at the left vertex, Ag at the top vertex, and Au at the right vertex.

Charge Neutrality Condition

The following convex hull plots show examples with a charge neutrality condition imposed by specifying charge. See Features > Charge Neutrality Condition for input examples and details on specifying charges.

Binary examples: single-valence (left) and multi-valence (right).

  • single-valence: (Cu, Au) = (+1, -1)
  • multi-valence: (Cu, Au) = ((+2, +3), -2)

Binary example with a single-valence charge neutrality condition Binary example with a single-valence charge neutrality condition Binary example with a multi-valence charge neutrality condition Binary example with a multi-valence charge neutrality condition

Ternary examples: single-valence (left) and multi-valence (right).

  • single-valence: (Cu, Ag, Au) = (+1, +2, -1)
  • multi-valence: (Cu, Ag, Au) = (+1, (+2, +3), -2)

Ternary example with a single-valence charge neutrality condition Ternary example with a single-valence charge neutrality condition Ternary example with a multi-valence charge neutrality condition Ternary example with a multi-valence charge neutrality condition

Composition Constraints

From version 1.5.0, min_comp and max_comp can restrict the composition range explored by the search. When composition constraints are set, the allowed range is shown as a blue region in the convex hull plot. See Features > Composition Constraints for input examples and an explanation of the plots.

Examples of search results through generation 3 for binary (left) and ternary (right) systems.

Binary search results with composition constraints Binary search results with composition constraints Ternary search results with composition constraints Ternary search results with composition constraints

To check the composition range specified in the input without using search results, use the cryspy-Eplot -c option.

Combining Charge Neutrality with Composition Constraints

Composition constraints can also be combined with charge neutrality specified by charge. In that case, the blue region represents only the composition constraints, and generated structures must also satisfy charge neutrality within that region. See Features > Composition Constraints for input examples.

Example of ternary search results through generation 3 with both conditions applied.

Ternary search results with charge neutrality and composition constraints Ternary search results with charge neutrality and composition constraints

Replotting with cryspy-Eplot

If you want to fine-tune the figure and replot it, you can easily do so using the cryspy-Eplot command as follows:

cryspy-Eplot 

Replotting Specific Generations

When using the cryspy-Eplot command, the following variables can also be specified in the [visual] section in addition to the standard variables above.

  • plot_min_gen
  • plot_max_gen
  • ref_gen

For example, to replot the figure at generation 2, write the [visual] section as follows:

...
[visual]
plot_max_gen = 2
...

Then, run the following command:

cryspy-Eplot 

conv_hull_gen_2.svg conv_hull_gen_2.svg

In this case, CrySPY overwrites ./data/convex_hull/conv_hull_gen_{gen}.{fig_fotmat}.

You can specify the range of generations to be plotted using plot_min_gen and plot_max_gen. When plot_min_gen is set to specify a range (even if its value is 1), the output is saved with a different filename such as ./data/convex_hull/conv_hull_gen_{plot_min_gen}-{plot_max_gen}.{fig_fotmat}, instead of the usual one.

conv_hull_gen_1-1_ref_3.svg conv_hull_gen_1-1_ref_3.svg conv_hull_gen_2-2_ref_3.svg conv_hull_gen_2-2_ref_3.svg conv_hull_gen_3-3_ref_3.svg conv_hull_gen_3-3_ref_3.svg

For example, from left to right, the figures above show convex hull plots including only the structures from the first, second, and third generations, respectively. Note that the convex hull (solid line) in all plots is based on the third generation using ref_gen = 3. The value of ref_gen must be set to be greater than or equal to plot_max_gen. As shown in the central figure, to extract only the results of the second generation, specify the following settings in the [visual] section.

...
[visual]
plot_min_gen = 2
plot_max_gen = 2
ref_gen = 3
...

If ref_gen is specified, the output filename becomes conv_hull_gen_{plot_min_gen}-{plot_max_gen}_ref_{ref_gen}.{fig_format}.

Convex Hulls with Compound Terminals

You can also plot a convex hull referenced to compound compositions by specifying terminals in the [visual] section. For an example, see Commands > cryspy-Eplot > Convex Hulls with Compound Terminals.

The following example uses Li–Al–O search results through generation 30 with a charge neutrality condition imposed. The left figure shows the ternary convex hull referenced to the elements; the right figure shows the pseudo-binary convex hull referenced to Li2O and Al2O3.

Li–Al–O convex hull referenced to the elements Li–Al–O convex hull referenced to the elements Convex hull referenced to Li2O and Al2O3 Convex hull referenced to Li2O and Al2O3

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.

fig_conv_plotly3d_ternary fig_conv_plotly3d_ternary fig_conv_plotly3d_ternary fig_conv_plotly3d_ternary fig_conv_plotly3d_ternary fig_conv_plotly3d_ternary

Bayesian Optimization (BO)

BO

LAQA

Last updated: October 16, 2026

Info

First, see Tutorial > Random Search (RS) for basic usage of CrySPY.
Here, we assume CrySPY 1.1.0 or later.

The example files used here can be downloaded from CrySPY_utility/examples/qe_Si16_LAQA. In this tutorial, only 50 initial structures are generated, but originally, LAQA is designed to select candidates from many more structures.

Input

cryspy.in

Here is an example of cryspy.in.

[basic]
algo = LAQA
calc_code = QE
tot_struc = 50
nstage = 1
njob = 10
jobcmd = qsub
jobfile = job_cryspy

[structure]
atype = Si
nat = 16
mindist_1 = 1.5

[QE]
qe_infile = pwscf.in
qe_outfile = pwscf.out
kppvol =  80

[LAQA]
nselect_laqa = 4

[option]
rslt_out = always
backup_interval = 1
  • nstage must be 1 in LAQA
  • From v1.5.0, backup_interval in the [option] section sets the automatic backup interval in selections. The default is 1; 0 disables automatic backups. See Features > Backup for details.
  • You have to write nselect_laqa in [LAQA] section. nselect_laqa is the number of candidates you select at one time.

If you want to change the value of the weight for LAQA score, edit wf and ws as below. If omitted, the default values are used (0.1 and 10.0, respectively). See, Search algorithms > LAQA for the score.

[LAQA]
nselect_laqa = 4
wf = 0.1
ws = 10.0

calc_in/pwscf.in_1

&control
    calculation = 'vc-relax'
    pseudo_dir = '/usr/local/gbrv/all_pbe_UPF_v1.5/'
    outdir='./outdir/'
    nstep = 10
/

&system
    ibrav = 0
    nat = 16
    ntyp = 1
    ecutwfc = 40
    ecutrho = 200
    occupations = 'smearing'
    degauss = 0.01
/

&electrons
/

&ions
/

&cell
/

ATOMIC_SPECIES
  Si -1.0 si_pbe_v1.uspp.F.UPF
  • nstep controls how many steps of structure optimization can proceed in one selection. (NSW for VASP)

calc_in/job_cryspy

#!/bin/sh
#$ -cwd
#$ -V -S /bin/bash
####$ -V -S /bin/zsh
#$ -N Si_CrySPY_ID
#$ -pe smp 20
####$ -q ibis1.q
####$ -q ibis2.q

mpirun -np $NSLOTS pw.x -nk 4 < pwscf.in > pwscf.out

if [ -e "CRASH" ]; then
    sed -i -e '3 s/^.*$/skip/' stat_job
    exit 1
fi

sed -i -e '3 s/^.*$/done/' stat_job
  • The job file is the same as the usual way.

Run

Tip

An automatic script is also available. See the bottom of this page.

Just type cryspy for the 1st run.

cryspy &

Check log_cryspy. 50 random structures are generated.

2023/05/13 13:02:07
CrySPY 1.1.0
Start cryspy.py
Number of MPI processes: 1

Read input file, cryspy.in
Save input data in cryspy.stat

# --------- Generate initial structures
# ------ mindist
Si - Si 1.5
Structure ID      0 was generated. Space group: 165 --> 165 P-3c1
Structure ID      1 was generated. Space group:  66 -->  66 Cccm
Structure ID      2 was generated. Space group: 146 --> 146 R3
Structure ID      3 was generated. Space group:  82 -->  82 I-4
Structure ID      4 was generated. Space group: 162 --> 162 P-31m
...
...
...
Structure ID     47 was generated. Space group:  90 -->  90 P42_12
Structure ID     48 was generated. Space group: 214 --> 214 I4_132
Structure ID     49 was generated. Space group:  23 -->  23 I222

Elapsed time for structure generation: 0:00:10.929030


# ---------- Initialize LAQA
# ---------- Selection 0
selected_id: 50 IDs

In LAQA, jobs of structure optimization for all structures are submitted once at the beginning. Note that only 10 steps are proceeded here since we set nstep = 10. Repeat cryspy command until all of these (10 steps) are completed. If necessary, you can also submit all jobs at once by increasing the value of njob.

After all the initial optimizations, LAQA is ready is displayed at the end of log_cryspy.

2023/05/13 13:23:31
CrySPY 1.1.0
Restart cryspy.py
Number of MPI processes: 1



# ---------- job status
ID     41: Stage 1 Done!

LAQA is ready

Next cryspy run will make the first selection.

2023/05/13 13:23:33
CrySPY 1.1.0
Restart cryspy.py
Number of MPI processes: 1



# ---------- job status

Backup data

# ---------- Selection 1
selected_id: 37 8 10 48

Here, only the number set in nselect_laqa will be selected. Type cryspy to submit the jobs (next 10 steps).

cryspy &
2023/05/13 13:23:36
CrySPY 1.1.0
Restart cryspy.py
Number of MPI processes: 1



# ---------- job status
ID     37: submit job, Stage 1
ID      8: submit job, Stage 1
ID     10: submit job, Stage 1
ID     48: submit job, Stage 1

Then, by repeating this over and over again, the optimization of the structure selected according to the score advances by 10 steps each time. Proceed until several structures are completed, and finish (stop) when you like.

Status

If you want to check the LAQA score during the simulation, you can look at the status file:

  • ./data/LAQA_status

Other files for LAQA will be output:

  • ./data_LAQA_bias
  • ./data_LAQA_energy
  • ./data_LAQA_score
  • ./data_LAQA_selected_id
  • ./data_LAQA_step

Analysis and Visualization

It is assumed here that you analyze and visualize CrySPY data in your local PC. If you use CrySPY in super computers or workstations, download the data in your local PC. You can delete the work and backup directory if you do not need it because the file size could be very large. You may gzip the pkl data to decrease the file size.

Jupyter Notebook

Move to the data/ directory in results you just downloaded. Then copy cryspy_analyzer_LAQA.ipynb from CrySPY utility.

You can obtain the graph and animation with the notebook. In the gif below, all of the optimizations were completed. This is just for animation. (When all of the optimizations are completed, the computational cost is the same as random search.)

fig_LAQA fig_LAQA

This graph shows the energy as a function of optimization step. The red lines indicate three structures with the lowest energy. The most stable one reached diamond structure. The structures that eventually become stable were selected at an early stage.

Info

If algo = LAQA, the followings are automatically set in the [option] section.

  • force_step_flag = True
  • stress_step_flag = True

Force and stress data are collected step by step. Energy and structure data are NOT. They are collected for each selection. In other words, in this case, energy and structure data are saved once every 10 steps. If you want to collect energy and structure data step by step, manually set up as follows:

[option]
energy_step_flag = True
struc_step_flag = True

Auto Script

You may find it tedious to run cryspy over and over again. The auto script could help you.

repeat_cryspy

Loading Initial Structures

Last updated: October 16, 2026

This tutorial creates init_struc_data.pkl from three CIF files and loads the structures as initial structures. The example is an RS search for eight Cu atoms: three structures are loaded and two more are generated randomly, giving five initial structures in total. See Features > Loading Initial Structures for details of the loading checks.

Preparation

Prepare cryspy.in and calc_in/ in a new working directory as in Tutorial > Random Search (RS) > ASE on Your Local PC. Use the same ase_in.py and job_cryspy files in calc_in/. Do not run cryspy yet.

Conversion uses CrySPY Utility’s pos2pkl.py. The commands below assume that pos2pkl.py is on your PATH. See Installation > CrySPY Utility for setup.

Download the following example CIF files into the working directory. Each contains eight Cu atoms.

.
├── Cu8_1.cif
├── Cu8_2.cif
├── Cu8_3.cif
├── calc_in
│   ├── ase_in.py
│   └── job_cryspy
└── cryspy.in

Converting Structure Data

Run the following command in the working directory. Use -s for files containing one structure each, such as CIF files.

pos2pkl.py -s Cu8_1.cif Cu8_2.cif Cu8_3.cif
Composition: Cu8

Converted. The number of structures: 3
Save init_struc_data.pkl

The command creates init_struc_data.pkl in the current directory. IDs are assigned in input order: Cu8_1.cif, Cu8_2.cif, and Cu8_3.cif receive IDs 0, 1, and 2, respectively. See CrySPY Utility > pos2pkl.py for conversion details.

cryspy.in

Configure cryspy.in as follows.

[basic]
algo = RS
calc_code = ASE
tot_struc = 5
nstage = 1
njob = 5
jobcmd = zsh
jobfile = job_cryspy

[structure]
atype = Cu
nat = 8

[ASE]
ase_python = ase_in.py

[option]
load_struc_flag = True
  • atype = Cu and nat = 8 match the atom type and atom count in all three input structures.
  • tot_struc = 5 combines the three loaded structures with two randomly generated structures.
  • load_struc_flag = True enables loading initial structures.
  • Adjust jobcmd for your computing environment.

Placing the Data and Running CrySPY

Before the first cryspy run, place the converted data as follows.

mkdir -p data/pkl_data
cp init_struc_data.pkl data/pkl_data/
cryspy

CrySPY loads three structures and generates two more randomly, then exits after preparing the initial structures. Continue as in a normal RS run by executing cryspy again to start structure optimization.

Checking the Loaded Structures

./data/init_POSCARS contains all five structures: the three loaded structures and the two randomly generated structures.

Structure IDInitial structure
0Loaded from Cu8_1.cif
1Loaded from Cu8_2.cif
2Loaded from Cu8_3.cif
3, 4Generated randomly

./data/pkl_data/init_struc_data.pkl is also updated to contain these five structures. Invalid structure counts, atom types, or compositions raise an error. See Features > Loading Initial Structures > Checks During Loading for details.

Molecular Crystal Structure Prediction

Last updated: October 16, 2026

Info

First, see Tutorial > Random Search (RS) for basic usage of CrySPY.

In this section, we give a tutorial on the molecular structure generation part only. On this page, “molecular crystals” refers to crystals generated by placing molecules or groups of atoms as structural units. This also includes cases where single atoms or polyatomic ions are used as units, as in the Li3PS4 example.

Since version 0.9.0, CrySPY has been able to generate random molecular crystal structures using PyXtal.

You need to use a pre-defined molecular by PyXtal’s database (see, https://pyxtal.readthedocs.io/en/latest/Usage.html?highlight=benzene#pyxtal-molecule-pyxtal-molecule)) or create molecule files that define molecular structures.

Pre-Defined Molecule

PyXtal currently supports C60, H2O, CH4, NH3, benzene, naphthalene, anthracene, tetracene, pentacene, coumarin, resorcinol, benzamide, aspirin, ddt, lindane, glycine, glucose, and ROY.

Let us generate molecular crystal structures that consist of 2 benzenes.

Move to your working directory, and copy input example files by one of the following methods.

Take a look at cryspy.in.

$ cat cryspy.in
[basic]
algo = RS
calc_code = QE
tot_struc = 6
nstage = 2
njob = 2
jobcmd = qsub
jobfile = job_cryspy

[structure]
struc_mode = mol
atype = H C
nat = 12 12
mol_file = benzene
nmol = 2

[QE]
qe_infile = pwscf.in
qe_outfile = pwscf.out
kppvol = 40  60

[option]
rslt_out = always

In generating molecular crystal structures, you have to set struc_mode = mol in the [structure] section. Molecule file(s) and the number of molecule(s) are specified as:

  • mol_file = benzene
  • nmol = 2

The timeout_mol option was removed in v1.5.0.

Run CrySPY and see the initial structures (./data/init_POSCARS).

User-Defined Molecule

Move to your working directory, and copy input example files for 2 formula units of Li3PS4.

  • version 1.0.0 or later
    • Copy from CrySPY utility
  • version 0.10.3 or earlier
    • cp -r ~/CrySPY_root/CrySPY-0.9.0/example/QE_Li3PS4_2fu_RS_mol .
$ cd QE_Li3PS4_2fu_RS_mol
$ ls
Li.xyz  PS4.xyz  calc_in/  cryspy.in

Molecule files of Li and PS4 are included. Supported formats in PyXtal are .xyz, .gjf, .g03, .g09, .com, .inp, .out, and pymatgen’s JSON serialized molecules.

$ cat Li.xyz
1
New structure
 Li  0.000  0.000  0.000
$ cat PS4.xyz
5
New structure
 P    0.000000    0.000000    0.000000
 S    1.200000    1.200000   -1.200000
 S    1.200000   -1.200000    1.200000
 S   -1.200000    1.200000    1.200000
 S   -1.200000   -1.200000   -1.200000

Check cryspy.in.

$ cat cryspy.in
[basic]
algo = RS
calc_code = QE
tot_struc = 4
nstage = 2
njob = 1
jobcmd = qsub
jobfile = job_cryspy

[structure]
struc_mode = mol
atype = Li P S
nat = 6 2 8
mol_file = ./Li.xyz  ./PS4.xyz
nmol = 6 2

[QE]
qe_infile = pwscf.in
qe_outfile = pwscf.out
kppvol = 40  60

[option]
rslt_out = always

A single atom (Li atom in this case) is treated as a molecule in the molecular crystal structure generation mode. In this example, a random molecular structure is composed of six Li molecules (atoms) and two PS4 molecules specified as:

  • mol_file = ./Li.xyz ./PS4.xyz
  • nmol = 6 2

In mol_file, set relative path of molecule files from cryspy.in. Here the molecule files are placed in the same directory.

Run CrySPY and see the initial structures (./data/init_POSCARS).

Volume of Unit Cell

The volume scaling factor can be specified with vol_factor in cryspy.in. The default is 1.1. Specify a single positive number. For example, to set the factor to 1.5, write:

struc_mode = mol
atype = Li P S
nat = 6 2 8
mol_file = ./Li.xyz  ./PS4.xyz
nmol = 6 2
vol_factor = 1.5

Random Structure Generation with MPI

Last updated: October 16, 2026

Info

First, see Tutorial > Random Search (RS) for basic usage of CrySPY.

Info

Requirements:

  • CrySPY 1.1.0 1.2.3 or later
  • mpi4py
  • MPI library (Open MPI, Intel MPI, MPICH, etc.)
Warning

1.1.0 <= CrySPY <=1.2.2 has a bug. When you use bash (zsh) to run a job with MPI (e.g., jobcmd = zsh, jobfile = job_cryspy), the MPI job does not run. There is no problem when you use a job scheduler (qsub, sbatch). It has already fixed in version 1.2.3.

mpi4py

Install mpi4py if it is not already installed.

pip install mpi4py

Input

cryspy.in is the same as normal usage and does not need to be changed. Here we try structure generation with MPI using the following settings:

[basic]
algo = RS
calc_code = soiap
tot_struc = 100
nstage = 1
njob = 2
jobcmd = zsh
jobfile = job_cryspy

[structure]
atype = Si
nat = 8

[soiap]
soiap_infile = soiap.in
soiap_outfile = soiap.out
soiap_cif = initial.cif

[option]
rslt_out = always

All except tot_struc, atype, and nat are irrelevant for structure generation and can be ignored here.

Run

To generate structures with 4 MPI processes, use mpiexec -n with the -p option:

mpiexec -n 4 cryspy -p

If you submit jobs through a job scheduler, prepare a job script as shown below:

#!/bin/sh
#$ -cwd
#$ -V -S /bin/bash
#$ -N n_nproc
#$ -pe smp 4


mpirun -np $NSLOTS ~/.local/bin/cryspy

Please edit the location of the executable script cryspy.

Result

CrySPY simply divides the task (number of structures) by the number of processes:

  • Rank 0: IDs 0 – 24
  • Rank 1: IDs 25 – 49
  • Rank 2: IDs 50 – 74
  • Rank 3: IDs 75 – 99

CrySPY outputs the log in the order they are generated as follows:

2023/04/24 22:47:51
CrySPY 1.1.0
Start cryspy.py
Number of MPI processes: 4

Read input file, cryspy.in
Save input data in cryspy.stat

# --------- Generate initial structures
# ------ mindist
Si - Si 1.11
Structure ID     25 was generated. Space group: 138 --> 123 P4/mmm
Structure ID     75 was generated. Space group:  99 -->  99 P4mm
Structure ID      0 was generated. Space group: 127 --> 123 P4/mmm
Structure ID      1 was generated. Space group:  61 -->  61 Pbca
Structure ID     50 was generated. Space group:  38 -->  38 Amm2
Structure ID     51 was generated. Space group: 134 --> 123 P4/mmm
Structure ID     26 was generated. Space group: 111 --> 123 P4/mmm
Structure ID      2 was generated. Space group:   9 -->   9 Cc
Structure ID      3 was generated. Space group:  80 -->  80 I4_1
Structure ID      4 was generated. Space group: 107 --> 107 I4mm
Structure ID      5 was generated. Space group:  75 -->  75 P4
Structure ID     76 was generated. Space group: 108 --> 108 I4cm
Structure ID     77 was generated. Space group: 100 --> 100 P4bm
Structure ID     27 was generated. Space group: 207 --> 221 Pm-3m

However, the order in init_POSCARS is by structure ID since CrySPY outputs after all structures have been generated.

ID_0
1.0
   2.9636956737951818    0.0000000000000002    0.0000000000000002
   0.0000000000000000    2.9636956737951818    0.0000000000000002
   0.0000000000000000    0.0000000000000000    6.2634106638053080
Si
8
direct
  -0.1602734164607877   -0.1602734164607877   -0.0000000000000000 Si
   0.1602734164607877    0.1602734164607877    0.5000000000000000 Si
   0.6602734164607877    0.3397265835392123    0.7500000000000000 Si
   0.3397265835392122    0.6602734164607877    0.2500000000000000 Si
   0.4469739273741755    0.4469739273741755   -0.0000000000000000 Si
   0.5530260726258245    0.5530260726258244    0.5000000000000000 Si
   0.0530260726258245    0.9469739273741754    0.7500000000000000 Si
   0.9469739273741754    0.0530260726258245    0.2500000000000000 Si
ID_1
1.0
   7.2751506682509657    0.0000000000000004    0.0000000000000004
   0.0000000000000000    7.2751506682509657    0.0000000000000004
   0.0000000000000000    0.0000000000000000    5.1777634169924873
Si
8
direct
  -0.3845341807505553   -0.3845341807505553    0.4999999999999999 Si
   0.3845341807505553    0.3845341807505553    0.5000000000000000 Si
   0.3845341807505553   -0.3845341807505553    0.0000000000000000 Si
  -0.3845341807505553    0.3845341807505553   -0.0000000000000000 Si
   0.0000000000000000    0.5000000000000000    0.2500000000000000 Si
   0.5000000000000000    0.0000000000000000    0.7500000000000000 Si
   0.0000000000000000    0.5000000000000000    0.7500000000000000 Si
   0.5000000000000000    0.0000000000000000    0.2500000000000000 Si
ID_2
1.0
  -4.3660398676292269   -4.3660398676292269    0.0000000000000000
  -4.3660398676292269   -0.0000000000000003   -4.3660398676292269
   0.0000000000000000   -4.3660398676292269   -4.3660398676292269
Si
8
direct
   0.8700001548800920    0.8700001548800920    0.1299998451199080 Si
   0.1299998451199080    0.1299998451199080    0.8700001548800920 Si
   0.8700001548800920    0.1299998451199080    0.8700001548800920 Si
   0.1299998451199080    0.8700001548800920    0.1299998451199080 Si
   0.1299998451199080    0.8700001548800920    0.8700001548800920 Si
   0.8700001548800920    0.1299998451199080    0.1299998451199080 Si
   0.7500000000000000    0.7500000000000000    0.7500000000000000 Si
   0.2500000000000000    0.2500000000000000    0.2500000000000000 Si
Note

Except for the random structure generation part, there is no point in using MPI because it is not parallelized.

Info

Interactive Mode (Jupyter Notebook)

Last updated: October 16, 2026

Info

Requirements:

  • CrySPY 1.4.0 or later
  • Jupyter
  • Structure optimization software compatible with ASE (e.g., machine learning potentials).
  • nglview (optional)

Preparation

When CrySPY is installed, ASE is automatically installed as well. Set up Jupyter to be usable on a workstation or local PC. In this tutorial, Pure Python EMT calculator is used for structure optimization. Note that the accuracy of the EMT potential is poor, as it is intended for demonstration purposes only.

The example notebook also includes code for using the machine learning potential CHGNet. If you want to try CHGNet, make sure to install it in advance using pip.

Input File

Move to your working directory, and copy the example files by one of the following methods.

Even in interactive mode, cryspy.in is used as the input file. The calc_in directory is not used in interactive mode. You can refer to the examples of cryspy.in in the input_examples directory.

Here, the following cryspy.in using EA-vc will be used. For more details on EA-vc, refer to the EA-vc tutorial.

[basic]
algo = EA-vc
calc_code = ASE
nstage = 1
njob = 10
jobcmd = zsh
jobfile = job_cryspy

[structure]
atype = Cu Au
ll_nat = 0 0
ul_nat = 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
n_elite = 2
n_fittest = 10
slct_func = TNM
t_size = 2
maxgen_ea = 5
ref_energies = 0.0 0.0

[option]
rslt_out = always

Notebook

Open cryspy_interactive.ipynb and execute the cells from the top.

Check Current Working Directory

The first cell only checks the files and the contents of cryspy.in.

!pwd
print()
!ls
print()
!cat cryspy.in

Import

Ignore the commented-out sections this time and execute the cell that imports the core libraries for CrySPY’s interactive mode.

# ---------- import
from cryspy.interactive import action

Initialize CrySPY

This cell corresponds to a standard initial run. It reads cryspy.in and generates the initial structures.

# ---------- initial structure generation
action.initialize()

Set Calculator

This cell sets the ASE calculator. Here, ASE’s EMT is used.

# ---------- EMT in ASE
from ase.calculators.emt import EMT
calculator = EMT()

# ---------- CHGNet
#from chgnet.model import CHGNetCalculator
#calculator = CHGNetCalculator()

Restart CrySPY

Executing this cell starts the optimization of the previously generated initial structures. In interactive mode, structure optimization calculations are performed sequentially, one by one. A progress bar is also displayed during the process.

# ---------- structure optimization
action.restart(
    njob=20,    # njob=0: njob in cryspy.in will be used
    calculator=calculator,
    optimizer='BFGS',    # 'FIRE', 'BFGS' or 'LBFGS'
    symmetry=True,       # default: True
    fmax=0.01,           # default: 0.01 eV/Å
    steps=2000,          # default: 2000
)
  • njob: The number of structures to be optimized in a single execution. If set to 0, the value specified in cryspy.in is used.
  • calculator: Assign the previously set calculator.
  • optimizer: Select from FIRE, BFGS, or LBFGS. Specify as a string.
  • symmetry: If True, structure optimization is performed while preserving symmetry.
  • fmax: The maximum atomic force (eV/Å) used for convergence criteria.
  • steps: Maximum optimization steps.

If the njob value is set to a small number, execute this cell multiple times to complete the optimization of all initial structures. When using EA-vc, the following message will be displayed upon completion.

EA is ready

Executing this cell again will trigger generational turnover. Once the next-generation structures are generated, continue executing this cell repeatedly in the same manner.

Show Results

Running this cell allows you to display files such as cryspy_rslt_energy_asc.

# ---------- show results
#!cat ./data/cryspy_rslt    # Order of structure optimization completion
!cat ./data/cryspy_rslt_energy_asc    # show energy ascending order
#!sed -n 2,4p ./data/cryspy_rslt    # show i--jth lines
#!tail -n 5 ./data/cryspy_rslt    # show last 5 lines

Structure Visualization

You can interactively visualize both the initial and optimized structures.

from ase.visualize import view
atoms = action.get_atoms('opt', cid=0)    # 'init' or 'opt'
view(atoms, viewer='ngl')    # viewer = 'ngl', 'ase', or 'x3d'

Changing opt to init in action.get_atoms('opt', cid=0) allows you to check the initial structure. The cid parameter specifies the structure ID. Since this utilizes ASE’s functionality, the viewer option supports ngl, ase, and x3d. To use ngl, you need to install nglview, so make sure to install it via pip in advance.

fig_struc_visu fig_struc_visu

Energy Plot for RS, EA

For random search (RS) and evolutionary algorithm (EA), an energy graph shown below can be displayed. In the case of EA-vc, direct energy comparison is not possible due to differences in the number of atoms, so the convex hull plot, discussed later, is used instead.

fig, ax = action.plot_E(
              title=None,
              ymax=2.0,
              ymin=-0.5,
              markersize=12,
              marker_edge_width=1.0,
              marker_edge_color='black',
              alpha=1.0,
          )

fig_eplot fig_eplot

Convex Hull Plot for EA-vc

Interactive Plot Using Plotly

For EA-vc, an interactive convex hull plot using Plotly is available. When CrySPY is installed, Plotly is automatically installed as well. This convex hull plot utilizes pymatgen’s functionality.

action.interactive_plot_convex_hull(cgen=None, show_unstable=0.2, ternary_style='2d')
  • cgen: Which generation’s data to plot up to. If None, data will be plotted up to the latest generation.
  • show_unstable: The maximum hull distance value to display on the plot
  • ternary_style
    • Binary system: ternary_style = ‘2d’
    • Ternary system: ternary_style = ‘2d’, ‘3d’
    • Quaternary system: ternary_style = ‘3d’

fig_convplot fig_convplot

When performing calculations with ternary or quaternary systems instead of binary systems, you can obtain the following interactive plots.

From left to right:

  • Ternary system (ternary_style = ‘2d’)
  • Ternary system (ternary_style = ‘3d’)
  • Quaternary system (ternary_style = ‘3d’)

fig_conv_plotly3d_ternary fig_conv_plotly3d_ternary fig_conv_plotly3d_ternary fig_conv_plotly3d_ternary fig_conv_plotly3d_ternary fig_conv_plotly3d_ternary

Binary System Using matplotlib

Running this cell plots the binary convex hull using matplotlib.

fig, ax = action.plot_convex_hull_binary(
              cgen=None,
              show_max=0.2,
              label_stable=True,
              vmax=0.2,
              bottom_margin=0.02,
          )
fig    # to show plot in jupyter
  • cgen: Which generation’s data to plot up to. If None, data will be plotted up to the latest generation.
  • show_max: The maximum formation energy to display on the plot
  • label_stable: Whether to display the labels (compositions) of stable structures
  • vmax: The maximum hull distance in the color bar
  • bottom_margin: Bottom margin of y-axis

fig_convplotmat fig_convplotmat

Ternary System Using matplotlib

If exploring a ternary system, running this cell will generate a convex hull plot using matplotlib.

fig, ax = action.plot_convex_hull_ternary(
              cgen=None,
              show_max=0.2,
              label_stable=True,
              vmax=0.2,
          )
fig    # to show plot in jupyter
  • cgen: Which generation’s data to plot up to. If None, data will be plotted up to the latest generation.
  • show_max: The maximum formation energy to display on the plot
  • label_stable: Whether to display the labels (compositions) of stable structures
  • vmax: The maximum hull distance in the color bar

For example, the following plot can be obtained.

fig_convplotmat fig_convplotmat

Interface

2025 July 12, updated

CrySPY supports multiple structure optimizers:

At least one optimizer is required.

Algorithm Compatibility

  • 1.4.2: EA-vc supports VASP
RSEAEA-vcBOLAQA
VASP✓✓✓✓✓
Quantum Espresso✓✓✓✓✓
OpenMX✓✓×✓×
soiap✓✓×✓✓
LAMMPS✓✓×✓×
ASE✓✓✓✓×
Interactive (ASE)✓✓✓××

Option Compatibility

energy_step_flagstruc_step_flagforce_step_flagstress_step_flag
VASP✓✓✓✓
Quantum Espresso✓✓✓✓
OpenMX××××
soiap✓✓✓✓
LAMMPS××××
ASE××××

Subsections of Search Algorithms

Random Search (RS)

under construction

Evolutionary Algorithm (EA)

2025 April 2

Background

Evolutionary algorithms (EAs) are metaheuristic methods inspired by the theory of evolution. EA can effectively generate new structures (offspring) by inheriting the local environments of the stable structures (parents) explored so far. Oganov group’s USPEX is a well-known software, and there are others such as XtalOpt. For example, there are previous studies such as the following papers.

  • T. S. Bush, C. R. A. Catlow, and P. D. Battle, J. Mater. Chem. 5, 1269 (1995).
  • A. R. Oganov and C. W. Glass, J. Chem. Phys. 124, 244704 (2006).
  • A. R. Oganov, A. O. Lyakhov, and M. Valle, Acc. Chem. Res. 44, 227 (2011).
  • A. O. Lyakhov, A. R. Oganov, H. T. Stokes, and Q. Zhu, Comput. Phys. Commun. 184, 1172 (2013).

fig_EA_pes fig_EA_pes

Procedure

  1. Initialize population
  2. Evaluate fitness
  3. Natural selection
  4. Select parents
  5. Create next generation
  6. Repeat from step 2: Evaluate fitness

Initialize Population

In the first generation, a set of random structures is generated according to the number specified by n_pop. tot_struc is not used in EA or EA-vc.

Evaluate Fitness

Currently, energy is the only property that can be used as fitness in CrySPY. By setting fit_reverse = False, the algorithm is configured to search for the minimum value. The fit_reverse setting is designed for future cases where fitness may be based on properties other than energy.

Natural Selection

DFT calculations occasionally fail and produce extremely unreasonable energy values. emax_ea and emin_ea can be used to filter out structures with unreasonably low (or high) energy values:   $$ \mathrm{emin\_ea} \le E \ (\mathrm{eV/atom}) \le \mathrm{emax\_ea} $$ For example, if emin_ea is set, any structure with an energy lower than that value will be ignored.

In natural selection, the current population and elite individuals preserved from previous generations are first ranked based on fitness. The number of elite individuals used here is specified by n_elite. Only the top n_fittest individuals among the current population and elite individuals are selected, while all others are eliminated. During the natural selection process, duplicates are removed using the StructureMatcher class provided by pymatgen, and then the top n_fittest individuals are selected. n_fittest is often set to about half of n_pop (the population size). Note that in the current implementation, if n_fittest = 0, all individuals are retained. The figure below shows an example of the natural selection process when n_fittest = 5.

fig_EA_natural_selection fig_EA_natural_selection

Select Parents

Two parent selection methods are implemented in CrySPY to select a single parent individual from the candidate parents. Both methods are designed so that individuals with higher fitness have a higher probability of being selected. Setting slct_func = TNM enables tournament selection, while slct_func = RLT enables roulette selection. Tournament selection requires fewer parameters and is easier to use.

Create Next Generation

The next generation consists of offspring produced by evolutionary operations on candidate parents, along with some randomly generated structures. Random structures are added in each generation to maintain diversity and to help escape from local minima.

Evolutionary Operations

Here, we introduce the operations of the fixed-composition EA implemented in CrySPY.

Population Size

The sum of structures from crossover, permutation, strain, and random generation must be equal to n_pop.

  • n_pop = n_crsov + n_perm + n_strain + n_rand

Subsections of Evolutionary Algorithm (EA)

Crossover

Last updated: October 16, 2026

Overview

Crossover is an evolutionary operation that creates a new structure (offspring) by exchanging sliced regions between two parent structures. This promotes structural diversity and enables the inheritance of locally stable features. It is one of the main operators used to explore low-energy configurations in structure search.

How It Works

  1. Select two distinct individuals from the candidate parents
  2. Perform a random translation
  3. Randomly select a lattice vector
  4. Slice the parents near the center
  5. Swap the sliced halves
  6. Select the offspring with more atoms
  7. Adjust the number of atoms near the border
  8. Perform a minimum interatomic distance check
  9. Niggli reduction

fig_EA_crossover fig_EA_crossover

4. Slice the Parents near the Center

The slice point is placed near the center and slightly varied each time.

slice_point = np.clip(np.random.normal(loc=0.5, scale=0.1), 0.3, 0.7)

If any of the subsequent steps fail, the process may be restarted from step 4. However, the number of retries is limited to maxcnt_ea, and if this limit is exceeded, the parent selection step is repeated.

5. Swap the Sliced Halves

When crs_lat is set to random, the lattice vectors of one of the two parent structures are randomly selected. When crs_lat is set to equal, the average of the lattice vectors of the two parent structures is used. The default is random.

6. Select the Offspring with More Atoms

Swapping the sliced parts of the parent structures results in two structures with different numbers of atoms. Temporarily, we select the structure with more atoms.

fig_EA_crossover_natoms fig_EA_crossover_natoms

However, if the composition differs too much from the target, the process restarts from step 4 (Slice the parents near the center). The tolerance for the difference in the number of atoms is set by nat_diff_tole. The default value of nat_diff_tole is 4, which allows a tolerance of ±4 atoms per element. In the figure above, the number of blue atoms is -1 and the number of green atoms is +2 relative to the original composition.

7. Adjust the Number of Atoms near the Border

Deletion

When adjusting the number of atoms, the process starts with atom deletion. The number of green atoms is excessive and needs to be reduced. As illustrated in the figure below, atoms that do not satisfy the minimum interatomic distance defined by mindist are preferentially removed.

fig_EA_crossover_rm_mindist fig_EA_crossover_rm_mindist

As shown below, if atoms that violate the minimum interatomic distance remain after the deletion process, the procedure is restarted from step 4 (Slice the parents near the center).

fig_EA_crossover_rm_mindist2 fig_EA_crossover_rm_mindist2

If there are no atoms violating the minimum interatomic distance but atoms still need to be deleted, atoms are removed in order of increasing distance from the border, as shown in the figure below. Note that, in addition to the central slicing point, positions with internal coordinates of 0 are also considered borders.

fig_EA_crossover_rm_border fig_EA_crossover_rm_border

Addition

When atoms are lacking, the missing atoms are added near the border. The internal coordinate along the selected axis is determined as shown below. Here, mean refers to either the slice point or 0.

coords[axis] = np.random.normal(loc=mean, scale=0.08)

The remaining two components of the coordinate are determined randomly. Atoms are added until the target number is reached, while checking for violations of the minimum interatomic distance.

fig_EA_crossover_addition fig_EA_crossover_addition

9. Niggli Reduction

After adjusting the atom counts and checking the minimum interatomic distances, Niggli reduction is applied to the offspring before saving it. This uses pymatgen’s Structure.get_reduced_structure(reduction_algo="niggli").

Permutation

Last updated: July 7, 2026

Overview

Permutation is an evolutionary operation that generates new structures (offspring) by modifying the atomic arrangement within a single structure. It enables the exploration of alternative configurations without changing the lattice or the overall composition.

How It Works

The positions of atoms of different elements are swapped. The number of swaps can be specified by ntimes, which is set to 1 by default. After performing ntimes swaps, the operation is retried if the resulting structure is identical to the parent. Finally, the minimum interatomic distances are checked.

fig_EA_permutation fig_EA_permutation

Strain

Overview

Strain is an evolutionary operation that generates a new structure (offspring) by applying a small random distortion to the lattice of a parent structure. It helps to explore nearby regions of the configuration space while preserving atomic connectivity and composition. This operator is useful for fine-tuning structural candidates and escaping local minima.

How It Works

The lattice vectors are $ \mathbf{a} $ transformed to $ \mathbf{a}' $ by applying a strain matrix, as follows:

$$ \mathbf{a}' = \begin{pmatrix} 1 + \eta_1 & \frac{1}{2} \eta_6 & \frac{1}{2} \eta_5 \\ \frac{1}{2} \eta_6 & 1 + \eta_2 & \frac{1}{2} \eta_4 \\ \frac{1}{2} \eta_5 & \frac{1}{2} \eta_4 & 1 + \eta_3 \end{pmatrix} \mathbf{a}. $$

Here, $ \eta_i $ are given by a Gaussinan distribution $ \mathcal{N}\left( 0, \ \sigma_{\mathrm{st}}^2 \right) $. $ \sigma_{\mathrm{st}} $ is specified by the input parameter sigma_st (by default, sigma_st = 0.5). As shown in the figure below, the lattice is deformed and then rescaled to restore the original volume. Finally, the minimum interatomic distance constraint is checked.

fig_EA_strain fig_EA_strain

Tournament Selection

Overview

Tournament selection is a method used to choose parent individuals from the candidate parents based on their fitness. It is designed to balance selection pressure and diversity in the population. The figure below shows an example with n_fittest = 10 and t_size = 3.

fig_EA_tournament fig_EA_tournament

How It Works

  1. A fixed number of individuals (t_size) are randomly selected from the candidate parents.
  2. Among them, the individual with the highest fitness (i.e., lowest energy) is chosen as the parent.
  3. This process is repeated until the required number of parents is selected.

Advantages

  • Simple and efficient
  • Requires only one parameter (t_size)
  • Can control selection pressure by adjusting t_size

Notes

  • The default value of t_size is 3.
  • If t_size is small, diversity is promoted.
  • If t_size is large, selection pressure increases, favoring the fittest individuals.
  • Unlike roulette selection, tournament selection never chooses the bottom (t_size - 1 ) individuals from the candidate parents.

Roulette Selection

Overview

Roulette selection is a probabilistic method used to select parent individuals from the candidate parents based on their fitness. In roulette selection, each individual’s chance of being selected is proportional to its fitness.

How It Works

  1. When fit_reverse is set to False (default), corresponding to minimization mode where energy is used as fitness, the fitness values of the candidate parents are multiplied by –1.
  2. The fitness values $ f_i $ are linearly scaled into $ f'_i $ using the following equation, where $ a $ and $ b $ are parameters specified by a_rlt and b_rlt, respectively (with the condition that $ a > b $). $$ f_i' = \frac{a - b}{f_{\mathrm{max}} - f_{\mathrm{min}}} f_i + \frac{b f_{\mathrm{max}} - a f_{\mathrm{min}}}{f_{\mathrm{max}} - f_{\mathrm{min}}} $$
  3. The scaled fitness values $ f_i’ $ are converted into selection probabilities using the following equation:   $$ p_i = \frac{f_i’}{\sum_k f_k’} $$ Each probability $ p_i $ represents the likelihood of selecting the $ i $-th individual.
  4. Parent individuals are then selected one by one according to the probabilities $ p_i $ using roulette wheel sampling, until the required number of parents is obtained.

Advantages

  • All individuals have a non-zero chance of being selected
  • Selection pressure can be adjusted by scaling the fitness values

Notes

  • By default, a_rlt = 10.0 and b_rlt = 1.0
  • Proper scaling of fitness values is important to ensure meaningful selection pressure.The figure below shows examples of $ p_i $ when $ a $ is relatively small (left) and relatively large (right). If $ a $ is too small, the selection pressure becomes weak, making it more difficult to favor individuals with higher fitness.

fig_EA_roulette fig_EA_roulette

Variable-Composition Evolutionary Algorithm (EA-vc)

2025 July 7, updated

Overview

Since CrySPY 1.4.0, a variable-composition EA (EA-vc) has been available as an extension of the fixed-composition EA. Refer to the following page for the supported interfaces (Interface). Although the overall flow is similar to the fixed-composition EA, EA-vc differs in how fitness is evaluated and how offspring are generated in order to handle varying compositions. Here, we describe the parts that have been modified from the original EA.

From version 1.4.1, it is possible to generate structures under the charge neutrality condition.

Procedure

  1. Initialize population
  2. Evaluate fitness
  3. Natural selection
  4. Select parents
  5. Create next generation
  6. Repeat from step 2: Evaluate fitness

Initialize Population

In the first generation, a set of random structures is generated according to the number specified by n_pop. tot_struc is not used in EA or EA-vc. In EA-vc, the number of atoms for each atom type is randomly determined within a user-defined range. The minimum (ll_nat) and maximum (ul_nat) number of atoms per type can be specified in cryspy.in as shown below.

[structure]
atype = Cu Au
ll_nat = 0 0
ul_nat = 8 8

Evaluate Fitness

The convex hull computed from formation energies is used to evaluate the phase stability of different compositions, since directly comparing total energies of structures with different numbers of atoms is not meaningful. Information on formation energy, the convex hull, and phase diagrams can be found online. For example, see Materials Project Documentation. In EA-vc, the fitness is defined as the energy above hull (also referred to as hull distance).

fig_EA-vc_phase_diagram_binary.svg fig_EA-vc_phase_diagram_binary.svg

Formation Energy

Formation energy is calculated based on the reference energies (in eV/atom) of stable pure elements, which are specified as ref_energies in cryspy.in. For example, in the case of the Cu–Au binary system, the ref_energies should contain the per-atom energies (in eV/atom) of fcc-Cu and fcc-Au, in that order. Note that even if a structure with the same composition as ref_energies is found during the structure search and has a total energy lower than the corresponding ref_energies value, the formation energy is still currently calculated based on the original ref_energies values defined in cryspy.in.

Convex Hull

The energy difference between a given structure’s formation energy and the convex hull is called the energy above hull, also known as the hull distance. This value indicates how much higher the formation energy of a structure is compared to the most stable combination of phases at the same composition. Structures with a hull distance of zero are on the convex hull and are thus thermodynamically stable.

Unlike in the fixed-composition EA, EA-vc filters structures based on their per-atom energy when computing the convex hull, using the condition:   $$ \mathrm{emin\_ea} \le E \le \mathrm{emax\_ea} $$ Note that this filtering is based only on the total energy per atom, not on the formation energy.

To compute the convex hull, CrySPY uses the PhaseDiagram class provided by the pymatgen library. Unlike in the case of formation energy, if a structure with the same composition as a pure element has a total energy lower than the corresponding ref_energies value, that structure is used as the reference for computing the convex hull and hull distance.

Natural Selection

As shown in the figure below, EA-vc can produce multiple stable structures (i.e., with a hull distance of 0). In such cases, multiple individuals share the top rank in terms of hull distance. If the number of elite structures specified by n_elite is smaller than the number of equally ranked individuals, the selection becomes non-deterministic. Currently, CrySPY randomly selects n_elite individuals from those with a hull distance less than 0.001 eV/atom. If the number of individuals with a hull distance less than 0.001 eV/atom is smaller than n_elite, elite structures are selected in the usual way, based on fitness ranking. When selecting elite individuals as well, duplicate structures are removed using the StructureMatcher class provided by the pymatgen library. fig_EA-vc_elite.svg fig_EA-vc_elite.svg

Elite individuals are selected based on the best structures from previous generations. However, because hull distance can vary from one generation to the next, the values for elite individuals are recalculated using the current convex hull before natural selection is applied.

As described in the Convex Hull section, emin_ea and emax_ea are not used for natural selection in EA-vc.

Select Parents

The method for selecting parents is the same as in the fixed-composition EA.

Create Next Generation

Evolutionary Operations

The crossover (vc) operation is slightly different from that in the fixed-composition EA, while permutation and strain are the same. EA-vc introduces several new operations to enable compositional variation.

Population Size

The sum of structures from crossover, permutation, strain, addition, elimination, substitution, and random generation must be equal to n_pop.

  • n_pop = n_crsov + n_perm + n_strain + n_add + n_elim + n_subs+ n_rand

Subsections of Variable-Composition Evolutionary Algorithm (EA-vc)

Crossover (vc)

Last updated: October 16, 2026

The variable-composition crossover is almost the same as the fixed-composition version, but it differs in that the adjustment of the number of atoms is minimized.

In step 6 of the fixed-composition crossover, the difference in the number of atoms in each atom type is calculated directly. In contrast, in crossover (vc), the difference is calculated based on the allowed range defined by ll_nat and ul_nat. For example:

ll_nat = [4, 4, 4]
ul_nat = [8, 8, 8]
offspring_nat = [2, 6, 12]
nat_diff = [-2, 0, 4]

If this difference in the number of atoms (nat_diff in the example above) exceeds the allowed tolerance (nat_diff_tole), the operation is retried. Otherwise, the number of atoms is adjusted to fall within the range defined by ll_nat and ul_nat.

Addition

2025 July 7, updated

An atom type whose current count does not exceed the limit specified by ul_nat is randomly selected, and one atom of that type is added at a random position.

From version 1.4.1, the functionality to add multiple atoms has been implemented. The number of atoms to be added is randomly selected from natural numbers up to add_max. The default value is add_max = 5.

  • Add one atom and check whether it satisfies the minimum interatomic distance specified by mindist.
  • If the distance condition is not satisfied, the atom is placed again at a different random position. This process is repeated up to maxcnt_ea times.
  • (since version 1.4.1) Repeat until the randomly determined number of atoms (up to add_max) have been added.
  • If no valid offspring is obtained, the volume is expanded by 10%, and the same procedure is retried up to maxcnt_ea times.
  • If that also fails, the volume is expanded up to 20% and the structure generation is attempted again. If it still fails, the parent is replaced.

fig_EA-vc_addition.svg fig_EA-vc_addition.svg

Elimination

2025 July 7, updated

An atom type whose current count is above the lower limit specified by ll_nat is randomly selected, and one atom of that type is removed.

From version 1.4.1, the functionality to remove multiple atoms has been implemented. The number of atoms to be removed is randomly selected from natural numbers up to elim_max. The default value is elim_max = 5.

fig_EA-vc_elimination.svg fig_EA-vc_elimination.svg

Substitution

2025 July 7, updated

Substitution is an operation in which two different atom types are randomly selected and their positions are substituted.

From version 1.4.1, the functionality to substitute multiple atoms has been implemented. The number of atoms to be substituted is randomly selected from natural numbers up to subs_max. The default value is subs_max = 3.

  • The number of atoms after the substitution is restricted so that it does not fall below the minimum (ll_nat) and does not exceed the maximum (ul_nat) number of atoms.
  • Finally, the minimum interatomic distance specified by mindist is checked, and if there are no issues, the structure is accepted as an offspring.

fig_EA-vc_substitution.svg fig_EA-vc_substitution.svg

LAQA

One of the selection-type algorithms.

fig_LAQA fig_LAQA

fig_LAQA fig_LAQA

Score $ L $

$$ L = -E + w_F \frac{F^2}{2\Delta F} + w_S S. $$
SymbolNote
$$ E $$Energy (eV/atom)
$$ w_F $$Weight of the force term. Default: $ w_F = 0.1$
$$ F $$Averaged norm of the atomic force (eV/Å)
$$ \Delta F $$Absolute difference of $ F $ from the previous step. $ \Delta F = 1$ for the first step. $ \Delta F = 10^{-6}$ if $ \Delta F \le 10^{-6} $.
$$ w_S $$Weight of the stress term. Default: $ w_S = 10.0$
$$ S $$Average of the absolute values of the components of the stress tensor (eV/Å^3).

Reference

Subsections of Structure Generation

struc_mode = crystal

under construction

struc_mode = mol

under construction

struc_mode = mol_bs

CrySPY uses pyxtal in normal molecular crystal structure generation mode (struc_mode = mol). The molecules are arranged to fit a point group at a selected Wykoff position in the space group to keep the symmetry. (Sometimes it takes a long time to generate.)

In mol_bs mode (bs means break symmetry), dummy atoms are placed in Wykoff positions as in ordinary crystals, and then the dummy atoms are replaced by molecules without considering symmetry and rotated randomly. The structure generation is relatively fast.

under construction

Subsections of Features

Logging

2023 July 10

CrySPY 1.2.0 adopts logging library of Python. CrySPY logs are output to both the screen and files(log_cryspy and err_cryspy).

  • log –> screen and log_cryspy
  • error and warning –> screen and err_cryspy

Here is the example:

[2023-07-10 18:40:54,389][cryspy_init][INFO] 


Start CrySPY 1.2.0


[2023-07-10 18:40:54,389][cryspy_init][INFO] # ---------- Read input file, cryspy.in
[2023-07-10 18:40:54,390][read_input][INFO] Save input data in cryspy.stat
[2023-07-10 18:40:54,391][cryspy_init][INFO] # ---------- Initial structure generation
[2023-07-10 18:40:54,391][cryspy_init][INFO] Number of MPI processes: 1
[2023-07-10 18:40:54,391][gen_init_struc][INFO] # ------ mindist
[2023-07-10 18:40:54,395][struc_util][INFO] Cu - Cu: 1.32
[2023-07-10 18:40:54,395][gen_init_struc][INFO] # ------ generate structures
[2023-07-10 18:40:54,481][gen_pyxtal][INFO] Structure ID      0 was generated. Space group:   1 -->   1 P1
[2023-07-10 18:40:54,493][gen_pyxtal][INFO] Structure ID      1 was generated. Space group:  28 -->  28 Pma2
[2023-07-10 18:40:54,498][gen_pyxtal][INFO] Structure ID      2 was generated. Space group:  29 -->  29 Pca2_1
[2023-07-10 18:40:54,704][gen_pyxtal][INFO] Structure ID      3 was generated. Space group: 137 --> 137 P4_2/nmc
[2023-07-10 18:40:54,725][gen_pyxtal][INFO] Structure ID      4 was generated. Space group: 212 --> 214 I4_132
[2023-07-10 18:40:54,800][cryspy_init][INFO] Elapsed time for structure generation: 0:00:00.408367

If you do not want output in the console, run cryspy with the -n option as follows:

cryspy -n

Backup

Last updated: July 15, 2026

CrySPY provides a simple backup function. The following files and directories are backed up.

  • cryspy.in
  • cryspy.stat
  • log_cryspy
  • err_cryspy
  • debug_cryspy
  • cryspy_interactive.ipynb
  • calc_in/
  • data/

Note that work/ is not included in the backup.

  • (v1.5.0 or later) The progress number and unit are appended to the backup directory name. For a manual backup, manual is also appended. The automatic backup interval can be specified using backup_interval.
  • (v1.1.0 or later) The files and directories listed above are copied to a directory named by date and time. Previous backups are not automatically deleted.
  • (v1.0.0) Only one generation is backed up, and older backups are deleted.

Backup Directory Names (v1.5.0 or Later)

In v1.5.0 or later, the progress number and unit at the time of backup are appended to the backup directory name. Backups are stored under backup/. The date and time are placed at the beginning of the directory name using the following formats.

  • Automatic backup: YYYYMMDD_HHMMSS_<progress_number>_<unit>
  • Manual backup: YYYYMMDD_HHMMSS_manual_<progress_number>_<unit>

The progress units are as follows.

  • RS: struc
    • The progress number is the number of structures with registered results.
  • BO and LAQA: select
    • The progress number is the current selection number.
  • EA and EA-vc: gen
    • The progress number is the current generation number.

Examples of backup directory names are shown below.

  • Automatic backup after completing generation 5 in EA: backup/20260715_143052_5_gen/
  • Automatic backup after completing selection 3 in BO: backup/20260715_143052_3_select/
  • Manual backup in generation 5 in EA: backup/20260715_154210_manual_5_gen/
  • Manual backup in selection 3 in BO: backup/20260715_154210_manual_3_select/
  • Manual backup after registering results for 100 structures in RS: backup/20260715_154210_manual_100_struc/

If a manual backup is performed when the progress number and unit cannot be obtained, such as before initialization, the directory name is YYYYMMDD_HHMMSS_manual.

Automatic Backup

In v1.5.0 or later, the automatic backup interval can be specified using backup_interval in the [option] section of cryspy.in.

For example, to set the automatic backup interval to 5, write:

[option]
backup_interval = 5

The following values can be specified for backup_interval.

  • 0: Disable automatic backups.
  • Positive integer: Perform automatic backups at the specified interval.

The default value and interval unit for each algorithm are as follows.

  • RS
    • The default is 0.
    • Automatic backups using backup_interval are not performed.
    • Divide calculations using tot_struc and perform a manual backup after completion.
  • BO and LAQA
    • The default is 1.
    • Automatic backups are performed in units of selections.
    • An automatic backup is performed immediately before proceeding to the next selection.
  • EA and EA-vc
    • The default is 1.
    • Automatic backups are performed in units of generations.
    • An automatic backup is performed immediately before generating the next-generation structures.

When appending structures, a backup is performed before the structures are appended, independently of the periodic backups controlled by backup_interval.

Manual Backup

To perform a manual backup, run cryspy with the -b or --backup option.

cryspy -b

This command performs only the backup without running the normal calculation process.

Clean

2024 Dec. 22 updated

CrySPY has a simple clean (just move files) function. It is useful when you want to start over from the beginning. The following files are cleaned up:

  • cryspy.stat
  • log_cryspy
  • err_cryspy
  • lock_cryspy
  • data/*
  • work/*
  • tmp_gen_struc/*

To clean up, run cryspy with -c or --clean option as:

$ ls
calc_in  cryspy.in  cryspy.stat  data  err_cryspy  log_cryspy
$ cryspy -c
Are you sure you want to clean the data? 'yes' or 'no' [y/n]: y
$ ls
calc_in  cryspy.in  trash
$ ls trash
20230318_100728

Files other than calc_in/* and cryspy.in are moved to trash and grouped into a directory named by date and time. If you do not need them, you can delete them manually.

Loading Initial Structures

Last updated: October 16, 2026

Prepared structures can be used as the initial structures for a search. Setting load_struc_flag = True in the [option] section of cryspy.in loads ./data/pkl_data/init_struc_data.pkl on the first run. The default is False. If fewer structures are loaded than required, the remaining structures are generated randomly.

Usage

[option]
load_struc_flag = True

See Tutorial > Loading Initial Structures for an example that converts three CIF files and loads the resulting data. CrySPY Utility’s pos2pkl.py can convert structure files to init_struc_data.pkl.

Checks During Loading

The following conditions are checked when loading. If a condition is not satisfied, an error is raised and initialization stops.

  • The data in init_struc_data.pkl must be a dictionary.
  • Structure IDs must be consecutive integers starting from 0: for example, 0, 1, and 2 for three structures.
  • Each structure must be a pymatgen Structure object.
  • The number of structures must not exceed the limit below.
AlgorithmMaximum number of structures
EA, EA-vcn_pop
RS, BO, LAQAtot_struc

See Data Format > Initial and Optimized Structure Data for format details.

Atom Types, Atom Counts, and Composition Checks

In RS, BO, LAQA, and EA, the atom types and the number of atoms of each type must match atype and nat. Structures with different atom counts cannot be used, even if their composition ratios are the same.

In EA-vc, the following conditions are checked.

ItemCondition
Atom typesOnly atom types listed in atype are present.
Atom countsEach atom count is within the bounds specified by ll_nat and ul_nat, and the structure contains at least one atom in total.
Composition constraintsAny composition range specified by min_comp or max_comp is satisfied.
Charge neutralityIf charge is specified, neutrality can be achieved with a combination of the specified oxidation states.

See Composition Constraints and Charge Neutrality Condition for details. The loading checks do not enforce mindist, space-group constraints, or cell-volume constraints.

Filling Missing Structures

If fewer structures are loaded than tot_struc or n_pop, the remaining structures are generated randomly. Additional structures receive consecutive IDs following the last loaded ID. The loaded and additional structures are saved together to ./data/pkl_data/init_struc_data.pkl and ./data/init_POSCARS.

Restriction on Interatomic Distances

2024 April 23, updated

You can restrict the interatomic distance in structure generation. Here is an example of [structure] section in the input file to limit minimum interatomic distance for a A-B binary system.

[structure]
natot = 8
atype = A B
nat = 4 4
mindist_1 = 2.0 1.8
mindist_2 = 1.8 1.5

This means that minimum interatomic distances of A-A, A-B, and B-B are limited to 2.0, 1.8, and 1.5 Å, respectively. Structures with interatomic distances shorter than these values are automatically eliminated.

For ternary systems, you will need mindist_1, mindist_2, and mindist_3. Mindist matrix must be a symmetric matrix.

Since CrySPY version 1.4.0, the minimum interatomic distance check is also performed after structure relaxation. This feature was introduced because, with machine learning potentials, structures with nearly overlapping atoms can sometimes be obtained. You can disable this feature by adding the following line to cryspy.in (it is enabled by default):

[option]
check_mindist_opt = False

Example: Na8Cl8

Without mindist

cryspy.in

[basic]
algo = RS
calc_code = VASP
tot_struc = 5
nstage = 2
njob = 2
jobcmd = qsub
jobfile = job_cryspy

[structure]
natot = 16
atype = Na Cl
nat = 8 8

[VASP]
kppvol = 40 80

[option]

log_cryspy

[2024-04-23 13:46:28,598][cryspy_init][INFO] 


Start CrySPY 1.2.3


[2024-04-23 13:46:28,598][cryspy_init][INFO] # ---------- Read input file, cryspy.in
[2024-04-23 13:46:28,598][read_input][INFO] Save input data in cryspy.stat
[2024-04-23 13:46:28,599][gen_init_struc][INFO] # ------ mindist
[2024-04-23 13:46:28,601][struc_util][INFO] Na - Na: 1.66
[2024-04-23 13:46:28,602][struc_util][INFO] Na - Cl: 1.3399999999999999
[2024-04-23 13:46:28,602][struc_util][INFO] Cl - Cl: 1.02
...

fig_mindist fig_mindist

In the default settings of PyXtal, atoms can sometimes be too close to each other, as shown in the figure above, so it is recommended to set the mindist parameter. That would help simplify DFT calculations.

With mindist

cryspy.in

[basic]
algo = RS
calc_code = VASP
tot_struc = 5
nstage = 2
njob = 2
jobcmd = qsub
jobfile = job_cryspy

[structure]
natot = 16
atype = Na Cl
nat = 8 8
mindist_1 = 2.5 1.5
mindist_2 = 1.5 2.5

[VASP]
kppvol = 40 80

[option]

log_cryspy

[2024-04-23 14:06:21,955][cryspy_init][INFO] 


Start CrySPY 1.2.3


[2024-04-23 14:06:21,955][cryspy_init][INFO] # ---------- Read input file, cryspy.in
[2024-04-23 14:06:21,956][read_input][INFO] Save input data in cryspy.stat
[2024-04-23 14:06:21,956][gen_init_struc][INFO] # ------ mindist
[2024-04-23 14:06:21,956][struc_util][INFO] Na - Na: 2.5
[2024-04-23 14:06:21,956][struc_util][INFO] Na - Cl: 1.5
[2024-04-23 14:06:21,956][struc_util][INFO] Cl - Cl: 2.5

In cases like ionic crystals, it is advisable to set up the configuration in such a way that cations and anions are kept apart from each other.

Job File Auto-Rewriting

2025 July 10, updated

In CrySPY job files, the string CrySPY_ID is automatically replaced with the structure ID. When using job schedulers like PBS or SLURM, it is convenient to use the structure ID in the job name. For example, in PBS, #PBS -N Si_CrySPY_ID becomes #PBS -N Si_15. In most cases, job names cannot start with numbers, so it’s good to start with letters like Si_.

Also, since version 1.4.2, it is no longer necessary to write the following command at the end. CrySPY automatically appends it.

sed -i -e '3s/^sub.*/done/' stat_job

For example, if you prepare a job file like this in ./calc_in/job_cryspy (where job_cryspy is the file name specified by jobfile in cryspy.in):

#!/bin/sh
#$ -cwd
#$ -V -S /bin/bash
####$ -V -S /bin/zsh
#$ -N Si8_CrySPY_ID
#$ -pe smp 20
####$ -q ibis1.q
####$ -q ibis2.q

mpirun -np $NSLOTS pw.x < pwscf.in > pwscf.out


if [ -e "CRASH" ]; then
    sed -i -e '3 s/^.*$/skip/' stat_job
    exit 1
fi

For example, if the ID is 15, CrySPY rewrites ./work/15/job_cryspy as follows. The CrySPY_ID in the 5th line is replaced with 15, and the sed command is appended at the end.

#!/bin/sh
#$ -cwd
#$ -V -S /bin/bash
####$ -V -S /bin/zsh
#$ -N Si8_15
#$ -pe smp 20
####$ -q ibis1.q
####$ -q ibis2.q

mpirun -np $NSLOTS pw.x < pwscf.in > pwscf.out


if [ -e "CRASH" ]; then
    sed -i -e '3 s/^.*$/skip/' stat_job
    exit 1
fi

# ---------- CrySPY
sed -i -e '3s/^sub.*/done/' stat_job

Structure Generation with MPI Parallelization

Oct. 21 2023, update

Random structure generation using MPI has been available since version 1.1.0 ( using CrySPY >= 1.2.3 is better). You need to install mpi4py in your Python environment for MPI parallelization. Of course, an MPI library such as Open MPI, Intel MPI, and MPICH is required for your workstation.

Info

Requirements:

  • CrySPY 1.1.0 1.2.3 or later
  • mpi4py
  • MPI library (Open MPI, Intel MPI, MPICH, etc.)
Warning

1.1.0 <= CrySPY <=1.2.2 has a bug. When you use bash (zsh) to run a job with MPI (e.g., jobcmd = zsh, jobfile = job_cryspy), the MPI job does not run. There is no problem when you use a job scheduler (qsub, sbatch). It has already fixed in version 1.2.3.

The figure below shows the relationship between elapsed time and the number of processes for 1000 structures of Si8 with the following setting:

[basic]
algo = RS
calc_code = soiap
tot_struc = 1000
nstage = 1
njob = 2
jobcmd = zsh
jobfile = job_cryspy

[structure]
natot = 8
atype = Si
nat = 8
mindist_1 = 2.2

The structure generation is taking a long time because of a slightly stricter setting like mindset_1 = 2.2. The structure generation was performed 10 times for each number of processes.

fig_MPI fig_MPI

Run

mpiexec -n 4 cryspy -p
Info

Enthalpy

2023/10/18

Info

Requirements:

  • CrySPY 1.2.2 or later
  • VASP or QE

When performing CSP at high pressure, enthalpy results can be collected instead of total energy. Not yet compatible with softwares other than VASP and QE.

E_eV_atom in cryspy_rslt and cryspy_rslt_energy_asc turns into enthalpy (eV/atom). Here is the example of CSP results under 40 GPa pressure for Sr4O4. CsCl-type structure (ID 5) is more stable than NaCl-type (ID 6).

   Spg_num Spg_sym  Spg_num_opt Spg_sym_opt  E_eV_atom  Magmom      Opt
5       26  Pmc2_1          221       Pm-3m  -2.276790     NaN     done
6      225   Fm-3m          225       Fm-3m  -2.244800     NaN     done
1      101  P4_2cm          107        I4mm  -2.181115     NaN     done
4      123  P4/mmm          123      P4/mmm  -2.034509     NaN  not_yet
3       20  C222_1           63        Cmcm  -0.686541     NaN     done
2       75      P4           75          P4  -0.008713     NaN  not_yet
9       51    Pmma           47        Pmmm   0.096430     NaN     done
8       65    Cmmm          123      P4/mmm   1.099657     NaN     done
0      187   P-6m2          187       P-6m2   1.292124     NaN     done
7       53    Pmna           53        Pmna   5.153504     NaN  not_yet

VASP

CrySPY reads energy (enthalpy) from a OSZICAR file. This automatically changes to enthalpy when PSTRESS is set in INCAR_x as follows:

PSTRESS = 400

You do not have to do anything in cryspy.in. energy_step_flag is also supported for enthalpy.

Example: CrySPY utility > examples > qe_Sr4O4_RS_pv_term

QE

Add pv_term = True in the QE section of cryspy.in to use enthalpy:

[QE]
qe_infile = pwscf.in
qe_outfile = pwscf.out
kppvol =  40  80
pv_term = True

Don’t forget to write press in the QE input:

 &cell
    press = 400
 /
Warning

In QE, energy_step_flag is not supported yet for enthalpy.

Interactive Mode

2025 March 6

Info

Requirements:

  • CrySPY 1.4.0 or later
  • Jupyter
  • Structure optimization software compatible with ASE (e.g., machine learning potentials).
  • nglview (optional)

An interactive mode using Jupyter Notebook has been made available to ensure ease of use, even for those unfamiliar with PC clusters or supercomputers. Since the structure optimization calculations are designed for ASE, compatible machine learning potentials can be used.

For detailed usage, please refer to Tutorial > Interactice mode(Jupyter Notebook).

fig_struc_visu fig_struc_visu fig_eplot fig_eplot fig_convplot fig_convplot

fig_conv_plotly3d_ternary fig_conv_plotly3d_ternary fig_conv_plotly3d_ternary fig_conv_plotly3d_ternary fig_conv_plotly3d_ternary fig_conv_plotly3d_ternary

fig_convplotmat fig_convplotmat fig_convplotmat fig_convplotmat

Energy Plot

Last updated: October 16, 2026

Automatic Energy Plot

In EA and in binary or ternary EA-vc searches, plots are automatically generated at the end of each generation by default.

AlgorithmPlotOutput file
EAEnergy plot./data/energy_plot/energy_EA_gen_{gen}.{fig_format}
EA-vc (binary or ternary)Convex hull plot./data/convex_hull/conv_hull_gen_{gen}.{fig_format}

The left figure shows an EA energy plot, and the right figure shows an EA-vc convex hull plot. Both examples are from the end of generation 3.

EA energy plot EA energy plot EA-vc convex hull plot EA-vc convex hull plot

Here, gen is the generation number and fig_format is the image format (svg by default). Plot appearance, including the marker size and image format, can be configured in the [visual] section of cryspy.in. See Input File > [visual] Section for details.

For EA and EA-vc, the output interval can be changed with energy_output_interval in the [option] section. The default value is 1 (every generation); 0 disables automatic output of the energy plot in EA and the convex-hull plot and hull-distance file in EA-vc. The convex hull and hull distances in EA-vc are still calculated every generation. See Input File > [option] Section.

For example plots and input settings, see Tutorial > EA > Analysis and Visualization and Tutorial > EA-vc > Analysis and Visualization.

cryspy-Eplot Command

The cryspy-Eplot command visualizes search results and adjusts plots. Its main capabilities are:

  • Plot energies for RS/EA and convex hulls for EA-vc.
  • Replot with changes to marker size, axis limits and arrangement, image format, and other display settings.
  • Specify the generation range to plot and the reference generation in EA/EA-vc.
  • Plot the allowed region defined by composition constraints.
  • Specify reference compound compositions to plot convex hulls as pseudo-binary or pseudo-ternary systems.

For usage and examples, see Commands > cryspy-Eplot.

Charge Neutrality Condition

Last updated: October 16, 2026

Single-Valence Species

From version 1.4.1, it is possible to impose a charge neutrality condition during structure generation in EA-vc. This can be applied to both random structure generation and structure generation by evolutionary operations.

In cryspy.in, the charge corresponding to each atype is specified as charge.

The example below assumes a Li–Ca–Cl-like combination of charges, assigning hypothetical charges of +1, +2, and −1 to Cu, Ag, and Au, respectively. Cu–Ag–Au is used as a substitute so that the charge neutrality condition can be tested easily with ASE’s lightweight Pure Python EMT calculator, as in the ASE tutorial.

Example of cryspy.in:

...
[structure]
atype = Cu Ag Au
ll_nat = 0 0 0
ul_nat = 10 10 10
charge = 1 2 -1
...

For example, in this case, only structures that satisfy the charge neutrality condition, such as (Cu, Ag, Au) = (4, 0, 4) or (Cu, Ag, Au) = (4, 2, 8), will be generated.

Note that if add_max or elim_max is too small as shown below, there may be no combinations of atom numbers that satisfy the charge neutrality condition when adding or removing atoms, making structure generation impossible.

...
[structure]
atype = Cu Ag Au
ll_nat = 0 0 0
ul_nat = 10 10 10
charge = 1 2 -1
...
...
[EA]
add_max = 1
elim_max = 1

For example, in the above case, if add_max = 1, there are no combinations of atom numbers that satisfy the charge neutrality condition. If add_max = 2, (Cu, Ag, Au) = (1, 0, 1), that is, adding one Cu and one Au atom, satisfies the charge neutrality condition because (+1) + (-1) = 0. If add_max = 3, there are combinations such as (Cu, Ag, Au) = (1, 0, 1) and (0, 1, 2).

The default values of add_max, elim_max, and subs_max are 5, 5, and 3, respectively.

Ternary example with single-valence species Ternary example with single-valence species

Multi-Valence Species

From version 1.5.0, CrySPY supports elements with multiple possible oxidation states. Multiple oxidation states can be specified in charge by enclosing them in parentheses or square brackets.

As in the single-valence example, Cu–Au is used as a substitute for a Fe–O-like system so that the charge neutrality condition can be tested easily with ASE’s lightweight Pure Python EMT calculator. Cu is assigned hypothetical charges of +2 or +3, and Au is assigned a hypothetical charge of −2.

Example cryspy.in:

...
[structure]
atype = Cu Au
ll_nat = 0 0
ul_nat = 8 12
charge = (2 3) -2
...

For example, when the numbers of atoms are (Cu, Au) = (1, 1), charge neutrality is satisfied by assigning Cu a charge of +2. When (Cu, Au) = (2, 3), charge neutrality is satisfied by assigning both Cu atoms a charge of +3.

Even when multiple oxidation states are specified, the element is treated as a single atomic species in atype. Therefore, ll_nat and ul_nat specify the lower and upper limits for the total number of atoms of that element, rather than the number of atoms for each oxidation state.

In addition, the generated structures do not distinguish between species such as Cu²⁺ and Cu³⁺. When checking charge neutrality, CrySPY simply determines whether the composition can be neutralized using any combination of the specified oxidation states.

Binary example with multi-valence species Binary example with multi-valence species

Enumeration and Sampling of Atom-Count Combinations

From v1.5.0, cn_mode in the [structure] section controls how charge-neutral atom-count combinations are determined for random structure generation. This option is used only when charge is specified.

cn_modeBehavior
autoDefault. Uses enumerate if the number of combinations to examine exhaustively is at most max_cn_grid_points; otherwise, uses sample.
enumerateEnumerates charge-neutral atom-count combinations in advance and randomly selects from them. Raises an error if the number of combinations examined exhaustively exceeds the limit.
sampleGenerates charge-neutral atom-count combinations as needed without enumerating all combinations in advance.

During enumeration, the charge-neutrality equation is used to eliminate one atom-count variable. All possible integer combinations of the remaining variables are examined exhaustively. For each combination, the eliminated variable is calculated and checked to ensure that its value is an integer within the atom-count bounds. max_cn_grid_points limits the number of combinations in this exhaustive search. The default is 200000000.

For example, with charge = 1 2 -1 and atom counts from 0 to 10 for each of Cu, Ag, and Au, the Ag atom-count variable is eliminated. Cu and Au each have 11 possible atom counts. For each combination, the Ag atom count is calculated as (Au atom count − Cu atom count) / 2, giving 11 × 11 = 121 combinations to examine exhaustively. For multi-valence species, the count is calculated similarly after internally expanding each oxidation state into a separate species.

For many atom types or wide atom-count ranges, sampling can reduce the computational cost and memory use associated with enumeration.

[structure]
...
charge = 1 2 -1
cn_mode = auto
max_cn_grid_points = 200000000

In enumerate mode, the enumerated atom-count combinations are selected with equal probability. In sample mode, the selection probabilities are not necessarily uniform.

Combining Charge Neutrality with Composition Constraints

From version 1.5.0, min_comp and max_comp can restrict the composition range in addition to imposing charge neutrality. The example below adds composition constraints to the single-valence Cu–Ag–Au example, using the same hypothetical charges of +1, +2, and −1, respectively.

[structure]
atype = Cu Ag Au
ll_nat = 0 0 0
ul_nat = 10 10 10
charge = 1 2 -1
min_comp = 0.0  0.1  0.4
max_comp = 0.3  0.4  0.7

With these charges, neutrality requires the number of Cu atoms plus twice the number of Ag atoms to equal the number of Au atoms. The composition constraints additionally require the fractions of Cu, Ag, and Au to lie within 0.0–0.3, 0.1–0.4, and 0.4–0.7, respectively, including the boundaries.

For example, a structure with atom counts (Cu, Ag, Au) = (4, 0, 4) is charge neutral, but it is excluded by these composition constraints because its Ag fraction is zero. In contrast, (Cu, Ag, Au) = (1, 2, 5) has a total charge of 1 × (+1) + 2 × (+2) + 5 × (−1) = 0, and its composition (0.125, 0.25, 0.625) is also within the allowed range.

The left figure shows the allowed composition region, and the right figure shows search results through generation 3 with both conditions applied.

Allowed composition region used with charge neutrality Allowed composition region used with charge neutrality Search results through generation 3 with charge neutrality and composition constraints Search results through generation 3 with charge neutrality and composition constraints

The blue region represents only the composition constraints. In this example, charge-neutral compositions lie on a line in the ternary diagram. The search is restricted to compositions where this line overlaps the blue region and the atom-count constraints are also satisfied. For details on composition constraints and their plots, see Composition Constraints.

Composition Constraints

Last updated: October 16, 2026

From version 1.5.0, the composition range explored by EA-vc can be restricted. Specify min_comp and max_comp in the [structure] section of cryspy.in. These constraints apply to both random structure generation and structure generation by evolutionary operations. Composition constraints can be used for binary and ternary systems, as well as systems with four or more components. Plots of the allowed composition region and search results are available for binary and ternary systems.

Settings

The composition fraction of each atomic species is its number of atoms divided by the total number of atoms in the cell, and ranges from 0 to 1. For example, atom counts of (Cu, Au) = (2, 6) give a composition of (Cu, Au) = (0.25, 0.75).

min_comp specifies the lower composition bounds, and max_comp specifies the upper bounds. Both must have the same number of entries as atype, in the same order. The boundaries are included in the allowed range.

  • If only min_comp is specified, max_comp is set to 1.0 for every species.
  • If only max_comp is specified, min_comp is set to 0.0 for every species.
  • If both are omitted, no composition constraints are imposed.

While ll_nat and ul_nat restrict the number of atoms of each species, min_comp and max_comp restrict their fractions. When these settings are combined, only combinations of atom counts satisfying all conditions are explored. For a list of input variables, see Input File > [structure] Section.

Binary Example

Example of the [structure] section in cryspy.in:

[structure]
atype = Cu Au
ll_nat = 0 0
ul_nat = 8 8
min_comp = 0.0 0.0
max_comp = 0.6 0.5

Here, the Cu fraction is restricted to at most 0.6, and the Au fraction to at most 0.5. Since the two fractions sum to 1, the Au upper bound of 0.5 gives a Cu lower bound of 0.5, while the Cu upper bound of 0.6 gives an Au lower bound of 0.4. Therefore, only structures with a Cu fraction of 0.5–0.6 and an Au fraction of 0.4–0.5 are generated. For example, atom counts of (Cu, Au) = (4, 4), (3, 2), and (6, 4) satisfy the conditions, whereas (2, 6), (6, 2), and structures containing only Cu or only Au do not.

Changing min_comp and max_comp to the following values gives the same allowed composition range:

min_comp = 0.5 0.4
max_comp = 0.6 0.5

On the first run of CrySPY, the allowed composition range is plotted automatically and saved as ./data/convex_hull/composition_window_1.svg. The 1 in the filename is the generation number to which these composition constraints apply. The file extension follows fig_format in the [visual] section, which defaults to svg. The figure below corresponds to the first input example.

Allowed composition range for the Cu–Au system Allowed composition range for the Cu–Au system

In binary composition-window plots, the species are arranged along the horizontal axis according to axis_order in the [visual] section to match the convex-hull plot. In this figure, the horizontal axis represents the Au fraction. The lower blue band corresponds to the Cu constraint, and the upper orange band to the Au constraint. The range satisfying both is shown with darker colors and dashed lines. In this example, the allowed Au fraction is 0.4–0.5.

The following figure shows search results through generation 3 using these composition constraints.

Cu–Au search results through generation 3 with composition constraints Cu–Au search results through generation 3 with composition constraints

The horizontal axis represents the Au fraction, and the blue region indicates the allowed range of 0.4–0.5.

Ternary Example

Example of the [structure] section in cryspy.in:

[structure]
atype = Cu Ag Au
ll_nat = 0 0 0
ul_nat = 8 8 8
#------- input 1
min_comp = 0.0  0.2  0.2
max_comp = 0.6  0.5  0.7
#------- input 2
#min_comp = 0.4  0.2  0.2
#max_comp = 0.6  0.4  0.4
#------- input 3
#min_comp = 0.6  0.2  0.2
#max_comp = 0.6  0.5  0.7

Input 1 is active in this example. To use input 2 or input 3, comment out the min_comp and max_comp lines for input 1 and remove the leading # from both lines of the desired input.

The composition fractions always sum to 1. The allowed region in a ternary diagram therefore consists of compositions satisfying the lower and upper bounds of every species. As in the binary example, the plot is saved automatically as ./data/convex_hull/composition_window_1.<fig_format> on the first run. The three figures below were drawn for the respective inputs using cryspy-Eplot -c. In each figure, Cu is at the top vertex, Ag at the lower left, and Au at the lower right. Dashed lines mark the specified composition bounds. From left to right, the figures correspond to input 1, input 2, and input 3.

Cu–Ag–Au composition constraints: input 1 Cu–Ag–Au composition constraints: input 1 Cu–Ag–Au composition constraints: input 2 Cu–Ag–Au composition constraints: input 2 Cu–Ag–Au composition constraints: input 3 Cu–Ag–Au composition constraints: input 3

Input 1

The Cu fraction is restricted to 0.0–0.6, Ag to 0.2–0.5, and Au to 0.2–0.7. The blue region represents compositions satisfying all these conditions. For example, atom counts of (Cu, Ag, Au) = (3, 2, 5) give a composition of (0.3, 0.2, 0.5), which satisfies the constraints.

Input 2

The Cu fraction is restricted to 0.4–0.6, and the Ag and Au fractions are each restricted to 0.2–0.4. The allowed region is a triangle with vertices at (Cu, Ag, Au) = (0.6, 0.2, 0.2), (0.4, 0.4, 0.2), and (0.4, 0.2, 0.4). For example, atom counts of (Cu, Ag, Au) = (4, 3, 3) give a composition of (0.4, 0.3, 0.3), which satisfies the constraints.

Input 3

Both Cu bounds are set to 0.6, while Ag is restricted to 0.2–0.5 and Au to 0.2–0.7. Since the Cu fraction is fixed at 0.6, the Ag and Au fractions must sum to 0.4. Their lower bounds are both 0.2, so the only allowed composition is (Cu, Ag, Au) = (0.6, 0.2, 0.2), shown as a blue point. The atom counts are still variable. For example, structures with atom counts of (Cu, Ag, Au) = (3, 1, 1) and (6, 2, 2) have the same composition and both satisfy ll_nat and ul_nat.

Search Results

The following figure shows search results through generation 3 using the composition constraints of input 1. The blue region indicates the allowed composition range.

Cu–Ag–Au search results through generation 3 with composition constraints Cu–Ag–Au search results through generation 3 with composition constraints

Combining Composition Constraints with Charge Neutrality

charge can be used together with composition constraints. Generated structures must then satisfy the atom-count constraints, composition constraints, and charge neutrality condition.

[structure]
atype = Cu Ag Au
ll_nat = 0 0 0
ul_nat = 10 10 10
charge = 1 2 -1
min_comp = 0.0  0.1  0.4
max_comp = 0.3  0.4  0.7

As in the charge neutrality example, Cu, Ag, and Au are assigned hypothetical charges of +1, +2, and −1, respectively. The Cu fraction is restricted to 0.0–0.3, Ag to 0.1–0.4, and Au to 0.4–0.7. For example, atom counts of (Cu, Ag, Au) = (1, 2, 5) give a composition of (0.125, 0.25, 0.625), which satisfies the composition constraints. The total charge is also 1 × (+1) + 2 × (+2) + 5 × (−1) = 0, satisfying charge neutrality.

The left figure shows the allowed composition range, and the right figure shows search results through generation 3 with both composition constraints and charge neutrality applied.

Allowed composition range used with charge neutrality Allowed composition range used with charge neutrality Search results through generation 3 with composition constraints and charge neutrality Search results through generation 3 with composition constraints and charge neutrality

The blue region represents the composition constraints only; it does not include the charge neutrality condition. Generated structures are restricted to compositions within this region that also satisfy charge neutrality.

Checking the Allowed Composition Range

For binary and ternary systems, the first run of CrySPY with composition constraints automatically saves a plot as ./data/convex_hull/composition_window_1.<fig_format>. The number in the filename indicates the generation to which the composition constraints apply.

If min_comp or max_comp is changed during a search, the new constraints apply to parent filtering and structure generation at the next generational change. The plot is saved when CrySPY is run again after the input change, without waiting for the generational change. Its filename uses the current generation number plus one. For example, changing the constraints during generation 3 and running CrySPY again produces ./data/convex_hull/composition_window_4.<fig_format>. The new constraints are applied when generating generation 4.

Changing axis_order or fig_format also saves a plot using the next generation number. Plots are not saved every generation if these settings remain unchanged.

To check the allowed composition region without starting a search, run the following command in the directory containing cryspy.in:

cryspy-Eplot -c

The plot is saved as ./data/convex_hull/composition_window_input.<fig_format>. fig_format and axis_order can be specified in the [visual] section. For details, see cryspy-Eplot and Input File > [visual] Section.

This plot represents the continuous composition region determined by min_comp and max_comp. It does not account for integer atom-count constraints from ll_nat and ul_nat or charge neutrality from charge. Compositions that can actually be generated may therefore occupy only part of the plotted region.

Notes

For each species, min_comp must be less than or equal to max_comp. There must also be a combination of fractions summing to 1, so the sum of min_comp must not exceed 1, and the sum of max_comp must be at least 1.

Even if a continuous composition region exists, structures cannot be generated if no integer atom-count combination within ll_nat and ul_nat satisfies the constraints. When using charge, make sure that combinations satisfying charge neutrality also exist.

If composition constraints are changed during a search, parent and elite candidates for the next generation are filtered using the updated atom-count and composition constraints. If the constraints are so restrictive that all candidates are excluded, the search cannot continue.

Skip Calculations

2025 July 15

Skip During Calculation

When electronic states in DFT calculations fail to converge or when you want to stop calculations for obviously unstable structures, you can skip them using the following procedure:

  1. Stop the job using qdel or similar command
  2. Change the 3rd line of ./work/xxx/stat_job to skip
  3. Run CrySPY as usual

This will discard the structure and proceed to the next calculation.

Skip After Recording in cryspy_rslt (rslt_data.pkl)

CrySPY version 1.4.2 or later

When calculations finish with incorrect electronic states, the energy may be output excessively low and recorded in rslt_data. For example, in the following result, the energy of ID 198 is too low:

cryspy_rslt_energy_asc

     Gen  ...  E_eV_atom  Ef_eV_atom ...
198   10  ...  -5.542899   -1.800631 ...
157    8  ...  -5.598984   -0.356639 ...
186   10  ...  -6.323099   -0.330717 ...
95     5  ...  -6.317931   -0.325549 ...

To cancel this data and skip it, use the command automatically installed from version 1.4.2:

cryspy-skip 198

If you want to skip multiple structures, input multiple IDs:

cryspy-skip 198 157

This will update the data.

For EA or EA-vc

In the case of EA or EA-vc, the structure to be skipped may be registered as an elite structure. Using the cryspy-skip command removes the structures to be skipped from the data stored in elite_struc.pkl and elite_fitness.pkl.

Recalculating Convex Hull for EA-vc

In the case of EA-vc, the energy of the structure to be skipped may affect the convex hull calculation. Therefore, after skipping, recalculate the convex hull using the following command:

cryspy-calc-convex-hull 10

The 10 in the above input represents the generation, and it recalculates and plots the convex hull at generation 10.

Subsections of Input File

File Format

CrySPY uses the configparser module to read input file, cryspy.in . cryspy.in consists of sections, led by a [section] header and followed by name = value or name : value entries. Section names and values are case sensitive, but names are not. Lines beginning with # or ; are ignored and may be used to provide comments. Accepted bool values are 1, yes, true, and on, which cause this method to return True, and 0, no, false, and off, which cause it to return False. These string values for bool are checked in a case-insensitive manner. Some values are given in a space-separated manner.

Info

See configparser in detail.

Note

section name: case sensitive
name: case insensitive
value: case sensitive except for bool

[basic] Section

2025 March 6 updated

NameValueDefaultDescription
algoRS, EA, EA-vc, BO, LAQAAlgorithm
calc_codeVASP, QE, OMX, soiap, LAMMPS, ASECaluculation code for structure optimization
tot_strucintThe total number of structures. Not used in the case of EA or EA-vc.
nstageintThe number of stages
njobintThe number of jobs running at the same time.
jobcmdstrCommand to submit jobs such as qsub and sbatch.
jobfilestrFile name of the job file.

[structure] Section

Last updated: October 16, 2026

NameValueDefaultDescription
struc_modecrystal, mol, mol_bscrystalStructure generation mode
atypeatomic symbol [atomic symbol …]Atom type. e.g. atype = Na Cl.
natint [int …]The number of atoms corresponding to each atype. e.g. nat = 8 8. Not used in EA-vc.
mindist (mindist_?)float [float …]NoneConstraint on minimum interatomic distance [Å]. See Features > Restriction on Interatomic Distances for details.
mindist_factorfloat1.0Scaling factor for mindist.
vol_factorfloat1.1Volume scaling factor.
vol_mufloatNoneMean of the normal distribution used to sample the cell volume [ų]. If specified, vol_sigma is also required.
vol_sigmafloatNoneStandard deviation of the normal distribution for the cell volume [ų], used together with vol_mu.
symprecfloat0.01Precision for symmetry finding.
spgnumall, space group number, 0allConstraint on space group. If all, 1–230. If 0, random structure without space group information (no symmetry).
use_find_wyboolFalseStructure generation with find_wy.

if algo is EA-vc

NameValueDefaultDescription
ll_natint [int …]Lower limit of nat. e.g. ll_nat = 0 0.
ul_natint [int …]Upper limit of nat. e.g. ul_nat = 8 8.
chargeint or grouped intsNoneCharge of each atom type used to impose charge neutrality, specified in the same order as atype. For example, charge = 1 -1 for NaCl. Since version 1.5.0, multiple oxidation states can be grouped in parentheses or square brackets. For example, charge = (2 3) -2 for atype = Fe O. See Charge Neutrality Condition for details.
cn_modeauto, enumerate, sampleauto(since version 1.5.0) Used only when charge is specified. Mode for calculating atom-count combinations that satisfy the charge-neutrality condition.
max_cn_grid_pointsint200_000_000(since version 1.5.0) Used only when charge is specified. Maximum number of combinations examined exhaustively with cn_mode = auto or enumerate after eliminating one atom-count variable using the charge-neutrality equation. If this value is exceeded, auto switches to sampling, while enumerate raises an error. See Charge Neutrality Condition for details, including how combinations are counted for multi-valence species.
min_compfloat [float …]None(since version 1.5.0) Used to impose composition constraints. Specifies the lower bound of the normalized composition (from 0 to 1) for each atom type. Specify one value per atom type in the same order as atype. If only max_comp is specified, min_comp is set to 0.0 for every atom type.
max_compfloat [float …]None(since version 1.5.0) Used to impose composition constraints. Specifies the upper bound of the normalized composition (from 0 to 1) for each atom type. Specify one value per atom type in the same order as atype. If only min_comp is specified, max_comp is set to 1.0 for every atom type.

if struc_mode is mol or mol_bs

Molecular crystal structure generation (struc_mode = mol or mol_bs) is not supported in EA or EA-vc.

NameValueDefaultDescription
mol_filestr [str …]Path of molecule files or molecule names.
nmolint [int …]The number of molecules.
timeout_molfloatNone(removed in version 1.5.0) Time out for molecular structure generation.
rot_molrandom, random_mol, random_wyckoffrandom_wyckoffOnly used in mol_bs. Mode for rotation of molecules.
nrotint20Only used in mol_bs. Maximum number of trials to rotate molecules.
mindist_mol_bs (mindist_mol_bs_?)float [float …]NoneOnly used in mol_bs. Constraint on minimum intermolecular distance [Å].
mindist_mol_bs_factorfloat1.0Only used in mol_bs. Scaling factor for mindist_mol_bs.

if use_find_wy is True or spgnum = 0

NameValueDefaultDescription
fwpathstrNoneOnly used with find_wy. Path of find_wy. If None, fwpath is automatically searched in your $PATH.
minlenfloatOnly used with find_wy or spgnum = 0. Minimum length of lattice vector [Å].
maxlenfloatOnly used with find_wy or spgnum = 0. Maximum length of lattice vector [Å].
danglefloatOnly used with find_wy or spgnum = 0. Delta angle for alpha, beta, and gamma in degree unit.
maxcntint50Only used with find_wy or spgnum = 0. Maximum number of trials to determine atom positions.

[VASP] Section

Last updated: October 12, 2026

[VASP] section is required only if you use VASP (calc_code = VASP)

NameValueDefaultDescription
kppvolint [int …]Target k-point grid density for each stage (number of k-points per Å⁻³ of reciprocal-space volume).
force_gammaboolFalseIf true, force gamma-centered mesh.
vasp_MAGMOMfloat [float …]NoneUsed only for EA-vc. MAGMOM values for each element.
vasp_LDAULint [int …]NoneUsed only for EA-vc. LDAUL values for each element.
vasp_LDAUUfloat [float …]NoneUsed only for EA-vc. LDAUU values for each element.
vasp_LDAUJfloat [float …]NoneUsed only for EA-vc. LDAUJ values for each element.

kppvol and Force Gamma

[QE] Section

[QE] section is required only if you use QE (calc_code = QE)

NameValueDefaultDescription
kppvolint [int …]Target k-point grid density for each stage (number of k-points per Å⁻³ of reciprocal-space volume).
qe_infilestrFile name of QE input file.
qe_outfilestrFile name of QE output file.
pv_termboolFalseIf true, read enthalpy instead of total energy.

kppvol

pv_term

[OMX] Section

[OMX] section is required only if you use OpenMX (calc_code = OMX)

NameValueDefaultDescription
kppvolint [int …]Target k-point grid density for each stage (number of k-points per Å⁻³ of reciprocal-space volume).
OMX_infilestrFile name of OpenMX input file.
OMX_outfilestrFile name of OpenMX output file.
ValenceElectronsstr float float [str float float …]The number of initial charges for up and down spin states.

kppvol

ValenceElectrons

e.g. in NaCl: ValenceElectrons = Na 4.5 4.5 Cl 3.5 3.5.

[soiap] Section

[soiap] section is required only if you use soiap (calc_code = soiap)

NameValueDefaultDescription
soiap_infilestrFile name of soiap input file.
soiap_outfilestrFile name of soiap output file.
soiap_cifstrFile name of soiap CIF-formatted initial structure.

[LAMMPS] Section

[LAMMPS] section is required only if you use LAMMPS (calc_code = LAMMPS)

NameValueDefaultDescription
lammps_infilestrFile name of LAMMPS input file.
lammps_outfilestrFile name of LAMMPS output file.
lammps_potentialstr [str …], NoneNonePotential.
lammps_datastrFile name of LAMMPS data file.

[ASE] Section

[ASE] section is required only if you use ASE (calc_code = ASE)

NameValueDefaultDescription
ase_pythonstrFile name of ASE input file.

[EA] Section

Last updated: October 12, 2026

  • The [EA] section is required when using EA or EA-vc, or when append_struc_ea = True is specified in the [option] section.
  • See also CrySPY > Search algorithms > EA

EA

NameValueDefaultDescription
n_popintPopulation (see also Population Size)
n_crsovintNumber of offspring created by crossover
n_permintNumber of offspring created by permutation
n_strainintNumber of offspring created by strain
n_randintNumber of structures created randomly
n_eliteintNumber of elite individuals (see also Natural Selection)
fit_reverseboolFalseIf False, minimal search (see also Evaluate Fitness)
n_fittestint0Number of individuals that remain natural selection. If set to 0, all individuals are retained.
slct_funcTNM, RLTFunction to select parents
t_sizeint3Tournament size. Used only used slct_func = TNM. (see also Tournament Selection)
a_rltfloat10.0Parameter for linear scaling. Used only with slct_func = RLT. (see also Roulette Selection)
b_rltfloat1.0Parameter for linear scaling. Used only with slct_func = RLT. (see also Roulette Selection)
crs_latequal, randomrandomHow to mix lattice vectors (see also crossover > 5. Swap the sliced halves)
nat_diff_toleint4Tolerance for difference in the number of atoms in crossover. (see also crossover > 6. Select the offspring with more atoms)
ntimesint1Number of times in permutation.
sigma_stfloat0.5Standard deviation for strain.
maxcnt_eaint50Maximum number of trials in EA.
max_parent_attemptsint50(since version 1.5.0) Maximum number of parent-selection attempts per offspring in EA. The initial parent selection is included.
maxgen_eaint0Maximum generation. If set to 0, no upper limit is applied.
emax_eafloatNoneEnergy upper limit (eV/atom) for natural selection.
emin_eafloatNoneEnergy lower limit (eV/atom) for natural selection.

EA-vc

NameValueDefaultDescription
n_addintNumber of offspring created by addition.
add_maxint5(since version 1.4.1) Maximum number of atoms to add in addition
n_elimintNumber of offspring created by elimination.
elim_maxint5(since version 1.4.1) Maximum number of atoms to eliminate in elimination
n_subsintNumber of offspring created by substitution.
subs_maxint3(since version 1.4.1) Maximum number of atoms to substitute in substitution
ref_energiesfloat [float …](since version 1.5.0) Reference energies for formation energy calculation [eV/atom]. Specify one value per atom type in the same order as atype, separated by spaces without parentheses or commas. The number of values must match the number of atom types in atype.
end_pointfloat [float …](deprecated since version 1.5.0) Kept for backward compatibility. Use ref_energies instead. Uses the same units and input format as ref_energies.
emax_eafloatNoneEnergy upper limit (eV/atom) for computing the convex hull.
emin_eafloatNoneEnergy lower limit (eV/atom) for computing the convex hull.

  • The following variables have been moved to the [visual] section since version 1.5.0.
  • cgen was deprecated in version 1.5.0.
  • The default values below apply to versions 1.4.3 and earlier. For version 1.5.0 and later, see the [visual] section.
NameValueDefaultDescription
cgenintNone(in versions 1.4.1–1.4.3) Which generation’s data to plot up to. If None, data will be plotted up to the latest generation.
show_maxfloat0.2When plotting the convex hull, the maximum value of the y-axis (for binary systems) or the maximum hull distance (for ternary systems) is set by show_max.
label_stableboolTrueWhether to show stable compositions when plotting the convex hull.
vmaxfloat0.2Maximum value of the colorbar representing hull distance.
bottom_marginfloat0.02Bottom margin of the y-axis for binary convex hull plot.
fig_formatstrsvgFigure format for convex hull plot: svg, png, or pdf.

[BO] Section

Last updated: October 12, 2026

[BO] section is required only if you use BO (algo = BO)

NameValueDefaultDescription
nselect_bointThe number of structures to be selected at once.
scoreTS, EI, PIAcquisition function.
num_rand_basisint0If 0, Gaussian process. The number of basis function.
cdevfloat0.001Cutoff of deviation for standardization.
dscrptFPStructure descriptor.
max_select_boint0Maximum number of selection.
manual_select_boint [int …]NoneStructure IDs to be selected manually.
emax_bofloatNoneUpper limit of energy in BO.
emin_bofloatNoneLower limit of energy in BO.

if dscrpt is FP

CrySPY 1.3.0 or later

fppath and fp_rmin are obsolete.

NameValueDefaultDescription
fp_rmaxfloat8.0Only used with dscrpt = FP. Maximum cutoff of r in fingerprint.
fp_npointsint20Only used with dscrpt = FP. Number of discretized points for each pair in fingerprint.
fp_sigmafloat0.7Only used with dscrpt = FP. Sigma parameter [Å] in Gaussian smearing function.

CrySPY 1.2.5 or earlyer

NameValueDefaultDescription
fppathstrNoneOnly used with dscrpt = FP. Path of cal_fingerprint. If None, fwpath is automatically searched in your $PATH.
fp_rminfloat0.5Only used with dscrpt = FP. Minimum cutoff of r in fingerprint.
fp_rmaxfloat5.0Only used with dscrpt = FP. Maximum cutoff of r in fingerprint.
fp_npointsint20Only used with dscrpt = FP. Number of discretized points for each pair in fingerprint.
fp_sigmafloat1.0Only used with dscrpt = FP. Sigma parameter [Å] in Gaussian smearing function.

[LAQA] Section

[LAQA] section is required only if you use LAQA (algo = LAQA)

NameValueDefaultDescription
nselect_laqaintThe number of structures to be selected at once.
wffloat0.1Weight of the force term.
wsfloat10.0Weight of the stress term.
Info
Info

If algo = LAQA, the followings are automatically set in the [option] section.

  • force_step_flag = True
  • stress_step_flag = True

Force and stress data are collected step by step. By default, energy and structure data are collected and saved for each selection, at the end of each structure’s optimization run. The number of optimization steps per selection is specified in the calculation code’s input settings, such as nstep in QE or NSW in VASP. The tutorial uses 10 steps per selection. To also collect and save energy and structure data at every step, add the following settings:

[option]
energy_step_flag = True
struc_step_flag = True

[visual] Section

Last updated: October 12, 2026

The [visual] section is available since version 1.5.0.

Common

Common variables for RS, EA, EA-vc.
See also

EA

See also CrySPY > Tutorial > Evolutionary Algorithm (EA) > Analysis and visualization.

NameValueDefaultDescription
ref_genintNone[post-analysis only] Reference generation for plotting. When specified, the plot is generated as of the end of this generation. If not specified, the latest generation is used. Must satisfy plot_max_gen <= ref_gen.
plot_min_genintNone[post-analysis only] Minimum generation for plotting. If not specified (i.e., None), the value is treated as 1.
plot_max_genintNone[post-analysis only] Maximum generation for plotting. If omitted, plotting extends through ref_gen when specified; otherwise, it extends through the latest generation.

EA-vc

See also CrySPY > Tutorial > Variable-composition evolutionary algorithm (EA-vc) > Analysis and visualization for the convex hull plot.

NameValueDefaultDescription
show_maxfloatNoneMaximum hull distance shown in ternary systems.
label_stableboolTrueWhether or not to show stable compositions in the plot.
vmaxfloat0.2Maximum value of the colorbar for the hull distance.
bottom_marginfloat0.04Bottom margin of the y-axis in binary systems.
axis_orderstrNoneSpecifies the axis order: lr or rl in binary systems, and permutations of tlr (lrt, rtl, …) in ternary systems. When terminals is used, specify the axis order with terminal_axis_order.
ref_genintNone[post-analysis only] Reference generation for plotting. When specified, the plot is generated as of the end of this generation. If not specified, the latest generation is used. Must satisfy plot_max_gen <= ref_gen.
plot_min_genintNone[post-analysis only] Minimum generation for plotting. If not specified (i.e., None), the value is treated as 1.
plot_max_genintNone[post-analysis only] Maximum generation for plotting. If omitted, plotting extends through ref_gen when specified; otherwise, it extends through the latest generation.
show_comp_windowboolTrueWhether to show the allowed composition range on the convex hull plot.
ref_gen_compintNone[post-analysis only] Generation from which min_comp and max_comp are taken for the composition-window overlay. If omitted, ref_gen is used when specified; otherwise, the latest generation is used.
terminalsstr str [str]None[post-analysis only] Two or three terminal compositions that define the compound phase diagram in cryspy-Eplot (e.g., Li2O Al2O3). Each terminal composition must have an entry in the phase-diagram data.
terminal_axis_orderstrNone[post-analysis only] Axis order used with terminals. Each letter gives the position of the corresponding terminal in the order specified by terminals (t: top, l: left, r: right). Use lr or rl for two terminals, or a permutation of tlr (lrt, rtl, …) for three terminals. If omitted, lr is used for two terminals and tlr for three.

[option] Section

Last updated: October 16, 2026

For the calculation codes supported by each *_step_flag, see Interface > Option compatibility.

NameValueDefaultDescription
rslt_outalways, cycle, offalways(since version 1.5.0) Specifies when cryspy_rslt and cryspy_rslt_energy_asc are written.
always: Write whenever a structure’s result is recorded.
cycle: Write at the end of each generation in EA/EA-vc or each selection in BO/LAQA (no output in RS).
off: Do not write these text files.
Result pickle data is saved for all settings.
check_mindist_optboolTrueIf True, a mindist constraint is checked after structure relaxation.
stop_chkptint0CrySPY stops at a specified check point.
load_struc_flagboolFalseIf True, load initial structures from ./data/pkl_data/init_struc_data.pkl. Structure IDs must be consecutive integers starting from 0. The maximum number of loaded structures is n_pop for EA/EA-vc and tot_struc otherwise. Exceeding this limit raises an error; any shortfall is filled by random structure generation. See Features > Loading Initial Structures for details.
stop_next_strucboolFalseIf True, CrySPY does not submit jobs for next structures, but jobs for next stage are submitted.
backup_intervalintRS: 0
Other: 1
(since version 1.5.0) Interval between automatic backups in generations for EA/EA-vc or selections for BO/LAQA. Set to 0 to disable automatic backups.
energy_output_intervalint1(since version 1.5.0) Interval in generations for outputting the energy plot in EA and the convex-hull plot and hull-distance file in EA-vc. Set to 0 to disable these automatic outputs. The convex hull and hull distances in EA-vc are still calculated every generation.
recalcint [int …]NoneSpecify structure IDs if you want to recalculate or continue optimization.
append_struc_eaboolFalseIf True, append structures by EA.
energy_step_flagboolFalseIf True, save energy_step_data in ./data/pkl_data/energy_step_data.pkl. In QE, pv_term = True cannot be used together with energy_step_flag = True.
struc_step_flagboolFalseIf True, save struc_step_data in ./data/pkl_data/struc_step_data.pkl.
force_step_flagboolFalseIf True, save force_step_data in ./data/pkl_data/force_step_data.pkl.
stress_step_flagboolFalseIf True, save stress_step_data in ./data/pkl_data/stress_step_data.pkl.
seedintNone(since version 1.5.0) Seed for the random number generator. Must be an integer between 0 and 2**32 - 1.

Kpoint

2024 April 22

CrySPY automatically generates the k-point setting using the pymatgen.io.vasp.Kpoints.automatic_density_by_vol function from pymatgen. An example in cryspy.in with nstage = 2 is as follows:

[VASP]
kppvol = 40 120
  • stage 1: kppvol = 40
  • stage 2: kppvol = 120

kppvol means a grid density per Å${}^{-3} $ of reciprocal cell.
VASP: gamma centered meshes are used for hexagonal cells and face-centered cells; otherwise, Monkhorst-Pack grids are employed.
QE and OMX: only a k-mesh is provided, no offset.

What Is the Appropriate Value for kppvol?

Here are the guidelines. We use VESTA for visualizing crystal structures.

Primitive Cell of Diamond Si

fig_prim_diamond fig_prim_diamond

a = b = c = 3.836 Å

kppvolk-mesh
0[1, 1, 1]
20[4, 4, 4]
40[6, 6, 6]
60[7, 7, 7]
80[7, 7, 7]
100[8, 8, 8]
120[9, 9, 9]
140[9, 9, 9]
160[9, 9, 9]
180[10, 10, 10]
200[10, 10, 10]
400[13, 13, 13]
600[15, 15, 15]
800[17, 17, 17]

Conventional Cell of Diamond Si

fig_conv_diamond fig_conv_diamond

a = b = c = 5.431 Å

kppvolk-mesh
0[1, 1, 1]
20[3, 3, 3]
40[3, 3, 3]
60[4, 4, 4]
80[4, 4 ,4]
100[5, 5, 5]
120[5, 5, 5]
140[6, 6, 6]
160[6, 6, 6]
180[6, 6, 6]
200[6, 6, 6]
400[8, 8, 8]
600[9, 9, 9]
800[10, 10, 10]

Nd2Fe14B

fig_Nd2Fe12B fig_Nd2Fe12B

a = b = 8.804 Å
c = 12.205 Å

kppvolk-mesh
0[1, 1, 1]
20[1, 1, 1]
40[2, 2, 1]
60[2, 2, 2]
80[3, 3 ,2]
100[3, 3, 2]
120[3, 3, 2]
140[3, 3, 2]
160[3, 3, 2]
180[4, 4, 2]
200[4, 4, 3]
400[5, 5, 3]
600[6, 6, 4]
800[6, 6, 4]

Subsections of Data Format

Subsections of Common Data

Initial and Optimized Structure Data

Initial and optimized structure data are saved in init_struc_data.pkl and opt_struc_data.pkl, respectively. pymatgen library is required to analyze these data files.

Data Format

  • type: dict
    • key: structure ID
    • value: structure data
  • string form
    • {0: Structure Summary …,
      1: Structure Summary …,
      …}
  • structure data format

How to Access

import pickle
with open('init_struc_data.pkl', 'rb') as f:
   init_struc_data = pickle.load(f)
with open('opt_struc_data.pkl', 'rb') as f:
   opt_struc_data = pickle.load(f)

# struc_step_data[ID]
#
#

# ---------- structure step data of ID 0
cid = 0      # ID
init_struc_data[cid]    # to show initial structure of ID 0
Structure Summary
Lattice
    abc : 5.727301 5.727301 4.405757
 angles : 90.0 90.0 90.0
 volume : 144.5175386563631
      A : 5.727301 0.0 0.0
      B : 0.0 5.727301 0.0
      C : 0.0 0.0 4.405757
PeriodicSite: Si (0.2506, 5.4767, 1.1014) [0.0438, 0.9562, 0.2500]
PeriodicSite: Si (2.6130, 3.1143, 1.1014) [0.4562, 0.5438, 0.2500]
PeriodicSite: Si (3.1143, 0.2506, 1.1014) [0.5438, 0.0438, 0.2500]
PeriodicSite: Si (5.4767, 2.6130, 1.1014) [0.9562, 0.4562, 0.2500]
PeriodicSite: Si (5.4767, 0.2506, 3.3043) [0.9562, 0.0438, 0.7500]
PeriodicSite: Si (3.1143, 2.6130, 3.3043) [0.5438, 0.4562, 0.7500]
PeriodicSite: Si (2.6130, 5.4767, 3.3043) [0.4562, 0.9562, 0.7500]
PeriodicSite: Si (0.2506, 3.1143, 3.3043) [0.0438, 0.5438, 0.7500]

Result Data

Common result data such as space group, energies, etc. are saved in rslt_data.pkl. pandas library is required to analyze this data file.

Data Format

  • type: pandas.core.frame.DataFrame
    • row lable: structure ID
  • string form
    • see blow

How to Access

import pickle
with open('rslt_data.pkl', 'rb') as f:
   rslt_data = pickle.load(f)


# ---------- sort by Energy
# top 5
rslt_data.sort_values(by=['E_eV_atom']).head(5)
   Spg_num Spg_sym  Spg_num_opt Spg_sym_opt  E_eV_atom  Magmom      Opt
1       98  I4_122           12        C2/m  -3.978441     NaN  not_yet
3       36  Cmc2_1           36      Cmc2_1  -3.520306     NaN  not_yet
2       16    P222           16        P222  -3.348616     NaN  not_yet
4       36  Cmc2_1            4        P2_1  -3.304168     NaN  not_yet
0      139  I4/mmm          139      I4/mmm  -3.000850     NaN     done

Random Search (RS)

Table of Contents

Evolutionary Algorithm (EA)

Table of Contents

Bayesian Optimization (BO)

Table of Contents

LAQA

Table of Contents

Subsections of Optional Data

Energy Step Data

Energy step data is saved in energy_step_data.pkl if you set energy_step_flag = True in [option] section of cryspy.in. NumPy library is required to analyze this data file.

Warning

energy_step_flag = True is currently available only with VASP, QE, and soiap.

Info

In soiap, energy_step_data is collected only if loopa == 1. This is because other data (struc, force, and stress) are output only when loopa == 1. See, https://github.com/nbsato/soiap/blob/master/doc/instructions.md

Data Format

  • type: dict
    • key: structure ID
    • value: list of energy step data in each stage
  • string form
    • {0: [array([-3.4439912 , -3.55040935, -3.66697038, ..]), array([-4.0613393 , -4.05445631, -4.06159641, …]), …],
      1: [array([-2.68209823, -2.69012487, -2.68364907, ..]), array([-2.79140967, -2.79183827, -2.79206508, …]), …],
      …}
  • unit of energy
    • eV/atom

How to Access

import pickle
with open('energy_step_data.pkl', 'rb') as f:
    energy_step_data = pickle.load(f)

# energy_step_data[ID][stage][step]
# energy_step_data[ID][0] <-- stage 1
# energy_step_data[ID][1] <-- stage 2
#
# in LAQA
# energy_step_data[ID][selection][step]
# energy_step_data[ID][0] <-- 1st selection
# energy_step_data[ID][1] <-- 2nd selection

# ---------- energy step data of ID 3, stage 1
cid = 3      # ID
stage = 1    # stage
energy_step_data[cid][stage-1][:10]    # show only 10 enegies in jupyter
array([-3.4439912 , -3.55040935, -3.66697038, -3.77192063, -3.84320717,
       -3.80679245, -3.84633935, -3.87374706, -3.89123193, -3.90422926])

Structure Step Data

Structure step data is saved in struc_step_data.pkl if you set struc_step_flag = True in [option] section of cryspy.in. pymatgen library is required to analyze this data file.

Warning

struc_step_flag = True is currently available only with VASP, QE, and soiap.

Info

struc_step_data includes initial structures. For example, struc_step_data[cid][0][0] is the initial structure of ID = cid.

Data Format

  • type: dict
    • key: structure ID
    • value: list of structure step data in each stage
  • string form
    • {0: [[Structure Summary …, Structure Summary, …], […], …],
      1: [[Structure Summary …, Structure Summary, …], […], …],
      …}
  • structure data format

How to Access

import pickle
with open('struc_step_data.pkl', 'rb') as f:
    struc_step_data = pickle.load(f)

# struc_step_data[ID][stage][step]
# struc_step_data[ID][0] <-- stage 1
# struc_step_data[ID][1] <-- stage 2
#
#
# in LAQA
# struc_step_data[ID][selection][step]
# struc_step_data[ID][0] <-- 1st selection
# struc_step_data[ID][1] <-- 2nd selection

# ---------- structure step data of ID 3, stage 1, step 4
cid = 0      # ID
stage = 1    # stage
step = 0     # step index (start from 0)
struc_step_data[cid][stage-1][step]    # to show initial structure of ID 0 at stage 1 in jupyter
Structure Summary
Lattice
    abc : 5.727301 5.727301 4.405757
 angles : 90.0 90.0 90.0
 volume : 144.5175386563631
      A : 5.727301 0.0 0.0
      B : 0.0 5.727301 0.0
      C : 0.0 0.0 4.405757
PeriodicSite: Si (0.2506, 5.4767, 1.1014) [0.0438, 0.9562, 0.2500]
PeriodicSite: Si (2.6130, 3.1143, 1.1014) [0.4562, 0.5438, 0.2500]
PeriodicSite: Si (3.1143, 0.2506, 1.1014) [0.5438, 0.0438, 0.2500]
PeriodicSite: Si (5.4767, 2.6130, 1.1014) [0.9562, 0.4562, 0.2500]
PeriodicSite: Si (5.4767, 0.2506, 3.3043) [0.9562, 0.0438, 0.7500]
PeriodicSite: Si (3.1143, 2.6130, 3.3043) [0.5438, 0.4562, 0.7500]
PeriodicSite: Si (2.6130, 5.4767, 3.3043) [0.4562, 0.9562, 0.7500]
PeriodicSite: Si (0.2506, 3.1143, 3.3043) [0.0438, 0.5438, 0.7500]

Force Step Data

Force step data is saved in force_step_data.pkl if you set force_step_flag = True in [option] section of cryspy.in. NumPy library is required to analyze this data file.

Warning

force_step_flag = True is currently available only with VASP, QE, and soiap.

Data Format

  • type: dict
    • key: structure ID
    • value: list of force step data in each stage
  • string form
    • {0: [array([[ 0.26314927, -0.26314927, -0. ], […], …[…]]), array([[…], …, […]]), …],
      1: [array([[ 0. , 0. , 0. ], […], …[…]]), array([[…], …, […]]), …],
      …}
  • unit of force
    • eV/Å

How to Access

import pickle
with open('force_step_data.pkl', 'rb') as f:
    force_step_data = pickle.load(f)

# force_step_data[ID][stage][step][atom]
# force_step_data[ID][0] <-- stage 1
# force_step_data[ID][1] <-- stage 2
#
# in LAQA
# force_step_data[ID][selection][step][atom]
# force_step_data[ID][0] <-- 1st selection
# force_step_data[ID][1] <-- 2nd selection

# ---------- force step data of ID 3, stage 1
cid = 0      # ID
stage = 1    # stage
force_step_data[cid][stage-1][:3]    # to show only 3 steps in jupyter 
[array([[ 0.26314927, -0.26314927, -0.        ],
        [-0.26314927,  0.26314927, -0.        ],
        [ 0.26314927,  0.26314927,  0.        ],
        [-0.26314927, -0.26314927, -0.        ],
        [-0.26314927,  0.26314927, -0.        ],
        [ 0.26314927, -0.26314927,  0.        ],
        [-0.26314927, -0.26314927, -0.        ],
        [ 0.26314927,  0.26314927,  0.        ]]),
 array([[-0.12103692,  0.12103692,  0.        ],
        [ 0.12103692, -0.12103692, -0.        ],
        [-0.12103692, -0.12103692, -0.        ],
        [ 0.12103692,  0.12103692,  0.        ],
        [ 0.12103692, -0.12103692, -0.        ],
        [-0.12103692,  0.12103692,  0.        ],
        [ 0.12103692,  0.12103692,  0.        ],
        [-0.12103692, -0.12103692, -0.        ]]),
 array([[-0.29801618,  0.29801618,  0.        ],
        [ 0.29801618, -0.29801618, -0.        ],
        [-0.29801618, -0.29801618, -0.        ],
        [ 0.29801618,  0.29801618,  0.        ],
        [ 0.29801618, -0.29801618, -0.        ],
        [-0.29801618,  0.29801618,  0.        ],
        [ 0.29801618,  0.29801618,  0.        ],
        [-0.29801618, -0.29801618, -0.        ]])]
step = 0     # step index (start from 0)
atom = 2     # atom index (start from 0)
force_step_data[cid][stage-1][step][atom]
array([0.26314927, 0.26314927, 0.        ])

Stress Step Data

Stress step data is saved in stress_step_data.pkl if you set stress_step_flag = True in [option] section of cryspy.in. NumPy library is required to analyze this data file.

Warning

stress_step_flag = True is currently available only with VASP, QE, and soiap.

Data Format

  • type: dict
    • key: structure ID
    • value: list of stress step data in each stage
  • string form
    • {0: [array([[-0.16770062, 0. , 0. ], […], […]]), array([[…], ]…], […]]), …],
      1: [array([[ 0.39260083, -0. , -0. ], […], […]]), array([[…], […], […]]), …],
      …}
  • unit of stress
    • eV/(Å**3)

How to Access

import pickle
with open('stress_step_data.pkl', 'rb') as f:
    stress_step_data = pickle.load(f)

# stress_step_data[ID][stage][step][atom]
# stress_step_data[ID][0] <-- stage 1
# stress_step_data[ID][1] <-- stage 2
#
# in LAQA
# stress_step_data[ID][selection][step][atom]
# stress_step_data[ID][0] <-- 1st selection
# stress_step_data[ID][1] <-- 2nd selection

# ---------- stress step data of ID 3, stage 1
cid = 0      # ID
stage = 1    # stage
stress_step_data[cid][stage-1][:3]    # to show only 3 steps in jupyter 
[array([[-0.16770062,  0.        ,  0.        ],
        [ 0.        , -0.16770062, -0.        ],
        [ 0.        ,  0.        ,  0.21823358]]),
 array([[-0.16020785, -0.        , -0.        ],
        [-0.        , -0.16020785,  0.        ],
        [-0.        ,  0.        ,  0.18646321]]),
 array([[-0.13572003, -0.        ,  0.        ],
        [-0.        , -0.13572003,  0.        ],
        [-0.        ,  0.        ,  0.15953926]])]

Subsections of CrySPY Utility

repeat_cryspy

Link: CrySPY_utility/script/repeat_cryspy

You may find it tedious to run cryspy over and over again. The automated script could help you.
This automated script runs cryspy every 5 minutes by default. The time interval can be adjusted by editing the following part of the script.

    sleep 300    # seconds

Usage

  1. copy repeat_cryspy to the working directory
  2. (optional) edit the time interval in repeat_cryspy
  3. run the script

You can use the nohup command to keep the job running even after logging out.

nohup ./repeat_cryspy &

extract_struc.py (legacy)

Last updated: October 16, 2026

Info

In CrySPY v1.5.0 and later, these features are available through Commands > cryspy-extract-struc. This page describes the standalone utility script.

Link: CrySPY_utility/script/extract_struc.py

Script to extract structures from init_struc_data.pkl or opt_struc_data.pkl. This script can print stucture information and output cif files.

One can specify structure ID(s) using -i option. Top k structures (the k most stable structures) can be extracted using -t option. -a option is for outputting all the structures. (note that many cif files will be output.) Symmetrized cif files can be generated with -s option. When outputting a symmetrized CIF file, you can also specify a tolerance with --tolerance. Structure information is printed with -p. If you use -p option, cif files are not output. You can also read a gzipped file (e.g., opt_struc_data.pkl.gz).

Update History

  • 2024 April 16: –tolerance option, gzip
  • 2023 July 21: –print option

Usage

python3 extract_struc.py -h

or if you put the script in your PATH, you can omit python3

extract_struc.py -h
usage: extract_struc.py [-h] [-p] [-a] [-i [INDEX ...]] [-t TOP] [-r] [-s] [--tolerance TOLERANCE] infile

positional arguments:
  infile                input file

options:
  -h, --help            show this help message and exit
  -p, --print           just print, e.g., extract_struc.py opt_struc_data.pkl -i 7 10 12 -ps
  -a, --all_id          all structures, e.g., extract_struc.py opt_struc_data.pkl -as
  -i [INDEX ...], --index [INDEX ...]
                        structure ID, e.g., extract_struc.py opt_struc_data.pkl -i 7 10 12 -s
  -t TOP, --top TOP     top k structures, e.g. (k = 3), extract_struc.py opt_struc_data.pkl -t 3 -s
  -r, --rank            add rank in file names, e.g., extract_struc.py opt_struc_data.pkl -t 3 -rs
  -s, --symmetrized     symmetrized structure, e.g., extract_struc.py opt_struc_data.pkl -i 7 10 12 -s
  --tolerance TOLERANCE
                        tolerance for symmetrization (default 0.01), e.g., extract_struc.py opt_struc_data.pkl -i 0 1 -s --tolerance 0.01

Examples

Print

The -p option can be used in combination with any option except for -s option.

extract_struc.py -p opt_struc_data.pkl -i 0 1
ID 0
Full Formula (Na8 Cl8)
Reduced Formula: NaCl
abc   :   6.823618   6.823618   7.566454
angles:  90.000000  90.000000  96.650518
pbc   :       True       True       True
Sites (16)
  #  SP           a         b         c
---  ----  --------  --------  --------
  0  Na    0         0         1
  1  Na    0         0         0.5
  2  Na    0.704707  0.295293  0.75
  3  Na    0.295293  0.704707  0.25
  4  Na    0.5       0         1
  5  Na    0.5       0         0.5
  6  Na    0         0.5       0.5
  7  Na    0         0.5       0
  8  Cl    0.5       0.5       0
  9  Cl    0.5       0.5       0.5
 10  Cl    0.484753  0.515247  0.75
 11  Cl    0.515247  0.484753  0.25
 12  Cl    0.828247  0.171753  0.851096
 13  Cl    0.171753  0.828247  0.351096
 14  Cl    0.828247  0.171753  0.648904
 15  Cl    0.171753  0.828247  0.148904

ID 1
Full Formula (Na8 Cl8)
Reduced Formula: NaCl
abc   :   8.145021   8.145021   4.324235
angles:  90.000000  90.000000 120.000000
pbc   :       True       True       True
Sites (16)
  #  SP            a          b         c
---  ----  ---------  ---------  --------
  0  Na     0.666667   0.333333  0.736206
  1  Na     0.666667   0.333333  0.263794
  2  Na     0.913147   0.086853  0.5
  3  Na     0.913147   0.826295  0.5
  4  Na     0.173705   0.086853  0.5
  5  Na     0.77711    0.22289   0
  6  Na     0.77711    0.55422   0
  7  Na     0.44578    0.22289   0
  8  Cl     0.027675   0.423376  0.5
  9  Cl    -0.423376  -0.395701  0.5
 10  Cl     0.395701  -0.027675  0.5
 11  Cl    -0.423376  -0.027675  0.5
 12  Cl     0.395701   0.423376  0.5
 13  Cl     0.027675  -0.395701  0.5
 14  Cl     0.333333   0.666667  0.5
 15  Cl     0          0         0

Structure ID

extract_struc.py opt_struc_data.pkl -i 7 10 12

7.cif, 10.cif, and 12.cif are output.

For symmetrized cif,

extract_struc.py opt_struc_data.pkl -i 7 10 12 -s

2024 April 16
With the tolerance parameter (default 0.01)

extract_struc.py opt_struc_data.pkl -i 7 10 12 -s --tolerance 0.01

Top k Structures

Info

rslt_data.pkl is required in the same directory as the input.

Let us suppose

  • ./data/pkl_data/opt_struc_data.pkl
  • ./data/pkl_data/rslt_data.pkl

and cryspy_rslt_energy_asc file is as follows:

    Spg_num     Spg_sym  Spg_num_opt Spg_sym_opt    E_eV_atom  Magmom      Opt
9       110      I4_1cd          110      I4_1cd -1284.708037     NaN  not_yet
16        4        P2_1            4        P2_1 -1284.693651     NaN     done
97       92    P4_12_12           91      P4_122 -1284.692494     NaN     done
8        57        Pbcm           57        Pbcm -1284.668504     NaN     done
81       19  P2_12_12_1           19  P2_12_12_1 -1284.635684     NaN     done
...

Top k(=3) structures can be extracted with:

extract_struc.py ./data/pkl_data/opt_struc_data.pkl -t 3

In this example, rlst_data.pkl must be in ./data/pkl_data/. 9.cif, 16.cif, and 97.cif are output.

The rank can be included in cif file names with -r option:

extract_struc.py ./data/pkl_data/opt_struc_data.pkl -t 3 -r

1_9.cif, 2_16.cif, and 3_97.cif are output.

For symmetrized cif:

extract_struc.py ./data/pkl_data/opt_struc_data.pkl -t 3 -rs

All the Structures

You should make a directory.

mkdir init_cifs
cd init_cifs
extract_struc.py /path/to/opt_struc_data.pkl -a

For symmetrized cif,

extract_struc.py /path/to/init_struc_data.pkl -as

Gzipped Files

2024 April 16
Gzipped files (end with .gz) can be read:

extract_struc.py opt_struc_data.pkl.gz -i 0 1 -s

print_pkl.py (legacy)

Last updated: October 16, 2026

Info

In CrySPY v1.5.0 and later, use Commands > cryspy-print to inspect pickle files. This page describes the standalone utility script. Some output differs from the command version.

When you want to quickly check the pickled files under data/pkl_data/, using print_pkl.py is convenient.

Usage

python3 print_pkl.py xxxx.pkl

or if you put the script in your PATH, you can omit python3

print_pkl.py xxxx.pkl

Example

print_pkl.py init_struc_data.pkl
Number of structures: 10
dict_keys([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
print_pkl.py input_data.pkl 
[basic]
algo = RS
calc_code = ASE
tot_struc = 10
nstage = 1
njob = 5
jobcmd = zsh
jobfile = job_cryspy

[structure]
struc_mode = crystal
natot = 8
atype = ('Cu', 'Au')
nat = (4, 4)
mindist_factor = 1.0
vol_factor = 1.1
symprec = 0.01
spgnum = all
use_find_wy = False

[option]
stop_chkpt = 0
load_struc_flag = False
stop_next_struc = False
append_struc_ea = False
energy_step_flag = False
struc_step_flag = False
force_step_flag = False
stress_step_flag = False

[ASE]
kpt_flag = False
force_gamma = False
ase_python = ase_in.py
print_pkl.py elite_struc.pkl
Number of structures: 2
dict_keys([3, 6])
print_pkl.py elite_fitness.pkl
{3: -325.79973412221455, 6: -324.8381948581405}

pos2pkl.py

2023 July 23 update

Script to convert structre data into init_struc_data.pkl. The default input format is init_POSCARS. Single structure data such as POSCAR and cif files can be optionally converted. Output is init_struc_data.pkl. Structure data can be added to an already existing init_struc_data.pkl. The structure ID is not taken into account and is newly assigned. If the number of atoms is different, an error is generated.

init_struc_data.pkl can be loaded at the start of the simulation in CrySPY.

You can remove and sort species with -f option. Note that without this option, pymatgen will sort the species in electronegativity order!

Usage

usage: pos2pkl.py [-h] [-s [SINGLE ...]] [-f [FILTER ...]] [-p] [infile ...]

positional arguments:
  infile                input file: init_POSCARS

options:
  -h, --help            show this help message and exit
  -s [SINGLE ...], --single [SINGLE ...]
                        input file: single structure file (POSCAR, cif)
  -f [FILTER ...], --filter [FILTER ...]
                        filter (sort): remove species and sort
  -p, --permit_diff_comp
                        flag for permitting different composition

Examples

init_POSCARS –> init_struc_data.pkl

It can be used to convert init_POSCARS generated by CrySPY to init_struc_data.pkl in another machine such as a supercomputer. Multiple input files can be converted.

python3 pos2pkl.py init_POSCARS

If you put the pos2pkl.py in your PATH, you can omit python3.

pos2pkl.py init_POSCARS
Composition: Na8 Cl8

Converted. The number of structures: 4
Save init_struc_data.pkl

Multiple inputs:

python3 pos2pkl.py init_POSCARS init_POSCARS2 init_POSCARS3
Composition: Na8 Cl8

Converted. The number of structures: 12
Save init_struc_data.pkl

If init_struc_data.pkl already exists in the current directory and you want to append to it:

python3 pos2pkl.py init_POSCARS
init_struc_data.pkl already exists.
Append to init_struc_data.pkl? [y/n]: y

Load init_struc_data
Composition: Na8 Cl8
The number of structures: 12

Converted. The number of structures: 16
Save init_struc_data.pkl

POSCAR or cif –> init_struc_data.pkl

Single structure data such as POSCAR and cif files can also be converted. -s/--single option is required.

python3 pos2pkl.py -s POSCAR test.cif
Composition: Na8 Cl8

Converted. The number of structures: 2
Save init_struc_data.pkl

init_POSCARS, POSCAR –> init_struc_data.pkl

python3 pos2pkl.py init_POSCARS -s POSCAR
Composition: Na8 Cl8

Converted. The number of structures: 5
Save init_struc_data.pkl
Warning

The following is wrong. The init_POSCARS is also treated as a single structure.

python3 pos2pkl.py -s POSCAR init_POSCARS

Filter (Remove and Sort)

Here we consider a cif file with the composition of Sr8 Co8 O20 X4, including 4 dummy atoms (X4). -f/--filter option can be used to remove and sort species. Specify the same as atype in cryspy.in.

python3 pos2pkl.py -s Sr8Co8O20X4.cif -f Sr Co O
Removed species: {'X0+'}
Composition: Sr8 Co8 O20

Converted. The number of structures: 1
Save init_struc_data.pkl

With extract_struc.py you can see how it was registered in init_struc_data.pkl.

python3 extract_struc.py init_struc_data.pkl -pa
ID 0
Full Formula (Sr8 Co8 O20)
Reduced Formula: Sr2Co2O5
...

-f option can allow you to sort.

python3 pos2pkl.py -s Sr8Co8O20X4.cif -f O Co 
Removed species: {'Sr', 'X0+'}
Composition: O20 Co8

Converted. The number of structures: 1
Save init_struc_data.pkl

kpt_check.py

kpt_check.py can check a k-point mesh with a given kppvol. This script supports POSCAR, CONTCAR, and init_struc_data.pkl. pymatgen library is required.

After generating initial structures, you can try to see how much the value of kppvol should be.

Usage

python3 kpt_check.py -h

or if you put the script in your PATH, you can omit python3

kpt_check.py -h
usage: kpt_check.py [-h] [-w] [-n NSTRUC] infile kppvol

positional arguments:
  infile                input file: POSCAR, CONTCAR, or init_struc_data.pkl
  kppvol                kppvol

options:
  -h, --help            show this help message and exit
  -w, --write           write KPOINTS
  -n NSTRUC, --nstruc NSTRUC
                        number of structure to check

Example

POSCAR with a Given kppvol

kpt_check.py POSCAR 100
a = 10.689217
b = 10.689217
c = 10.730846
    Lattice vector
10.689217 0.000000 0.000000
0.000000 10.689217 0.000000
0.000000 0.000000 10.730846

kppvol:  100
k-points:  [2, 2, 2]

Write KPOINTS File

You can generate a KPOINTS file using -w option.

kpt_check.py -w POSCAR 100
$ cat KPOINTS
pymatgen 4.7.6+ generated KPOINTS with grid density = 607 / atom
0
Monkhorst
2 2 2

Check K-Point Meshes for init_struc_data.pkl

In checking k-point meshes for init_struc_data.pkl, first five structures are automatically checked in the default setting. You can change the number of structures using -n option.

kpt_check.py -n 3 init_struc_data.pkl 100
# ---------- 0th structure
a = 8.0343076893
b = 8.03430768936
c = 9.1723323373
    Lattice vector
8.034308 0.000000 0.000000
-4.017154 6.957915 0.000000
0.000000 0.000000 9.172332

kppvol:  100
k-points:  [3, 3, 3]


# ---------- 1th structure
a = 9.8451944096
b = 9.84519440959
c = 6.8764313585
    Lattice vector
9.845194 0.000000 0.000000
-4.922597 8.526188 0.000000
0.000000 0.000000 6.876431

kppvol:  100
k-points:  [3, 3, 4]


# ---------- 2th structure
a = 7.5760383679
b = 7.57603836797
c = 6.6507478296
    Lattice vector
7.576038 0.000000 0.000000
-3.788019 6.561042 0.000000
0.000000 0.000000 6.650748

kppvol:  100
k-points:  [4, 4, 4]

Subsections of FAQ

Can I Change njob in the Middle of the Simulation?

2024 May 7

Can I Change njob in the Middle of the Simulation?

Yes, you can change whenever you want.

Below is an example of how the behavior changes when you reduce njob.

Warning

In CriSPY version 1.2.3 and earlier, there is a bug, so it is recommended to avoid reducing njobs.

Currently, with njob = 4, jobs for structures with IDs 0, 1, 2, and 3 are running.
Let’s say we chage njob from 4 to 2.

$ cryspy
[2024-04-28 18:27:41,847][cryspy_restart][INFO] 


Restart CrySPY 1.2.4


[2024-04-28 18:27:41,848][read_input][INFO] Changed njob from 4 to 2
[2024-04-28 18:27:42,335][ctrl_job][INFO] # ---------- job status
[2024-04-28 18:27:42,335][ctrl_job][INFO] ID      0: still queueing or running
[2024-04-28 18:27:42,335][ctrl_job][INFO] ID      1: still queueing or running

We reduced njob to 2, so we checked IDs 0, 1 and ignored IDs 2, 3.

$ cryspy
[2024-04-28 18:29:25,250][cryspy_restart][INFO] 


Restart CrySPY 1.2.4


[2024-04-28 18:29:25,744][ctrl_job][INFO] # ---------- job status
[2024-04-28 18:29:25,744][ctrl_job][INFO] ID      0: Stage 1 Done!
[2024-04-28 18:29:25,757][ctrl_job][INFO]     submitted job, ID      0 Stage 2
[2024-04-28 18:29:25,758][ctrl_job][INFO] ID      1: Stage 1 Done!
[2024-04-28 18:29:25,767][ctrl_job][INFO]     submitted job, ID      1 Stage 2

Once the jobs for IDs 1 and 2 are finished, we will then proceed to check the next two jobs (IDs 2 and 3).

$ cryspy
[2024-04-28 18:31:30,830][cryspy_restart][INFO]


Restart CrySPY 1.2.4


[2024-04-28 18:31:31,329][ctrl_job][INFO] # ---------- job status
[2024-04-28 18:31:31,329][ctrl_job][INFO] ID      0: Stage 2 Done!
[2024-04-28 18:31:31,329][collect_vasp][WARNING]     Structure ID 0, could not obtain energy from OSZICAR
[2024-04-28 18:31:31,333][ctrl_job][INFO]     collect results: E = nan eV/atom
[2024-04-28 18:31:31,341][ctrl_job][INFO] ID      1: Stage 2 Done!
[2024-04-28 18:31:31,341][collect_vasp][WARNING]     Structure ID 1, could not obtain energy from OSZICAR
[2024-04-28 18:31:31,342][ctrl_job][INFO]     collect results: E = nan eV/atom
[2024-04-28 18:31:31,347][cryspy][INFO] 

recheck 1

[2024-04-28 18:31:31,347][ctrl_job][INFO] # ---------- job status
[2024-04-28 18:31:31,347][ctrl_job][INFO] ID      2: Stage 1 Done!
[2024-04-28 18:31:31,358][ctrl_job][INFO]     submitted job, ID      2 Stage 2
[2024-04-28 18:31:31,358][ctrl_job][INFO] ID      3: Stage 1 Done!
[2024-04-28 18:31:31,368][ctrl_job][INFO]     submitted job, ID      3 Stage 2

Logo

PNG (Transparent Background)

logo_png1 logo_png1

logo_png2 logo_png2

logo_png3 logo_png3

logo_png4 logo_png4

JPG

logo_jpg1 logo_jpg1

logo_jpg2 logo_jpg2

logo_jpg3 logo_jpg3

logo_jpg4 logo_jpg4