Growth Pattern Algorithm
Project description
GrowPAL
Growth Pattern Algorithm with diversity-preserving selection for global optimization of atomic clusters.
GrowPAL implements a progressive-growth strategy for exploring potential energy surfaces (PESs) of atomic clusters. Its key innovation is incorporating unsupervised structural classification into the selection stage, preserving morphological diversity across growth steps rather than selecting exclusively by energy.
Table of Contents
- Background
- How It Works
- Installation
- Dependencies
- Module Overview
- Usage
- Examples
- Key Results
- Citation
- Authors
- License
Background
Global optimization algorithms based on progressive growth exploit structural correlations between neighboring cluster sizes and incorporate information obtained during earlier stages of the search. However, selection schemes based exclusively on energy may reduce structural diversity when multiple competing funnels are present.
The organization of potential energy surfaces into competing funnels — regions of configuration space that converge toward distinct structural motifs, separated by significant energy barriers — is a fundamental feature of cluster energy landscapes. For example, in the LJ75–LJ78 size range the global minimum corresponds to a decahedral Marks structure, while a competing icosahedral funnel contains many low-energy local minima of comparable energy. Algorithms that rank structures solely by energy tend to oversample the dominant funnel, restricting access to alternative regions of the PES.
GrowPAL integrating data-driven structural classification with the growth-based framework. Structural descriptors and hierarchical clustering are used to preserve representatives from distinct morphological families throughout the growth process, enabling simultaneous exploration of multiple regions of configuration space.
This package is a continuation of the original GrowPAL algorithm (López-Castro, Ortiz-Chi, Merino, J. Chem. Theory Comput. 2024, 20, 4939–4948), which established the growth strategy and demonstrated its efficiency for LJ clusters up to 74 atoms. The present version introduces the diversity-preserving selection scheme that extends the method and find the correct global minima for LJ clusters up to 130 atoms.
How It Works
Each growth iteration comprises four stages:
-
Structure generation. From each seed cluster of size N, candidate structures of size N+1 are generated by systematic interstitial insertion. Internal triangles are identified, a new atom is placed at each inequivalent triangle centroid (symmetry-equivalent sites are filtered), and the cluster is radially expanded around the insertion point. Each seed generates as many candidates as there are inequivalent internal triangles.
-
Structural discrimination. Duplicate and near-duplicate structures are removed via a two-stage USR-based filter (
deduplicate_by_usrinaegon.libdisc_usr): a Manhattan-distance prefilter followed by a k-d tree neighborhood search. Two structures are considered redundant when their L1 descriptor distance falls below a threshold (default 0.99). -
MBTR descriptor computation. Each surviving structure is represented by a combined Many-Body Tensor Representation vector encoding two-body (k=2, pairwise distances) and three-body (k=3, angular correlations) information, computed over 100 grid points with Gaussian broadenings of 0.01 Å (distances) and 0.01 rad (angles). For monoatomic systems a fast Numba-compiled path is used; for multi-species systems the DScribe library is used instead.
-
Clustering-based selection. Descriptor vectors are partitioned by agglomerative Ward clustering with a k-NN connectivity constraint. The
selection_countlowest-energy structures from each cluster are retained as seeds for the next iteration. Thisselection_countparameter controls the trade-off between computational cost and search thoroughness: larger values increase population diversity and improve recovery of challenging global minima at the expense of more local optimizations.
The algorithm is fully deterministic: repeated runs with identical inputs produce byte-for-byte identical results.
Installation
pip install growpal
This automatically installs all required packages: aegon (which brings in ase, numpy, scipy, py3Dmol, numba) and dscribe (which brings in scikit-learn, joblib).
Requires Python >= 3.10.
Google Colab
!pip install growpal
Dependencies
| Package | Role |
|---|---|
| aegon | Cluster manipulation, energy optimization (LJ, Sutton-Chen), USR discrimination, and reference databases |
| dscribe | MBTR descriptor computation for multi-species systems |
| numba | JIT-compiled MBTR kernels and USR routines for monoatomic systems |
| scikit-learn | Agglomerative Ward clustering |
| scipy | L-BFGS-B optimization, k-d tree, sparse connectivity graph |
| ASE | Atomic structure representation (Atoms objects) |
| joblib | Parallel intra-cluster selection |
Module Overview
| Module | Description |
|---|---|
libgrowpal.py |
Core growth engine: adjacency detection, interstitial atom placement at triangle centroids, focused radial expansion, and parallel processing via multiprocessing.Pool |
libdescriptors.py |
MBTR descriptor computation: fast Numba path for monoatomic systems (mbtr_comb_fast), and DScribe path for multi-species systems (mbtr_comb_dscribe) |
libclustering.py |
Agglomerative Ward clustering with optional k-NN connectivity constraint for scalability to large structure pools |
libselect_clustering.py |
Main selection interface: computes descriptors, clusters, and returns the lowest-energy representatives from each morphological family |
Usage
from growpal.libgrowpal import growpal_parallel
from growpal.libselect_clustering import select_by_clustering
# Grow a list of N-atom clusters to N+1
candidates = growpal_parallel(poscarlist, specie='Mo', dtol=1.2, n_cores=2)
# Select preserving morphological diversity
selected = select_by_clustering(candidates, selection_count=160, n_clusters=8)
The selection_count parameter (analogous to N·f in the manuscript) controls population diversity. Higher values improve recovery of difficult global minima at the cost of more local optimizations per iteration.
Examples
1. Load and visualize a Sutton-Chen cluster (Google Colab)
The SC database in aegon covers 10 transition metals (Al, Ag, Au, Cu, Ir, Ni, Pb, Pd, Pt, Rh) for cluster sizes up to 90 atoms, using the original Sutton-Chen parameterization.
from aegon.libdata_sc import get_sc_cluster
from aegon.libcalc_sc import SUTTON_CHEN_PARAMS
from aegon.libgcolab import viewmol_ASE
mol = get_sc_cluster(58, symbol='Pb') # ASE Atoms object
print(mol.info['i']) # cluster ID
print(mol.info['e']) # energy in eV
params = SUTTON_CHEN_PARAMS['Pb']
epsilon = params['epsilon']
print(mol.info['e'] / epsilon) # energy in epsilon units
viewmol_ASE(mol)
2. Load and visualize a Lennard-Jones cluster (Google Colab)
The LJ database in aegon covers cluster sizes from 5 to 130 atoms (ε = 1 eV, equilibrium distance 2^(1/6) σ = 3 Å). All stored minima were validated against the Wales reference database.
from aegon.libdata_lj import get_lj_cluster
from aegon.libgcolab import viewmol_ASE
atoms = get_lj_cluster(30)
viewmol_ASE(atoms)
print("%s Energy=%f" % (atoms.info['i'], atoms.info['e']))
3. Run a GrowPAL optimization (Lennard-Jones potential)
Prepare an initial .xyz file with seed structures for the starting size:
4
-6.00000000 Td
Mo 1.060660202 -1.060660202 1.060660202
Mo -1.060660202 1.060660202 1.060660202
Mo 1.060660202 1.060660202 -1.060660202
Mo -1.060660202 -1.060660202 -1.060660202
Then run the growth loop:
import os
from aegon.libutils import readxyzs, writexyzs, rename, cutter_energy
from aegon.libcalc_lj import opt_LJ_parallel
from aegon.libdisc_usr import deduplicate_by_usr
from growpal.libgrowpal import growpal_parallel, display_info
from growpal.libselect_clustering import select_by_clustering
nproc = 2
growatom = 'Mo'
ecut = 50.0
molecu0 = False
if __name__ == "__main__":
for iii in range(4, 10 + 1):
base_name = 'LJ' + str(iii).zfill(3)
if os.path.isfile(base_name + '.xyz'):
print("%s exists" % base_name)
anterior = base_name + '.xyz'
continue
if not molecu0:
molecu0 = readxyzs(anterior)
molecu0 = rename(molecu0, base_name, 5)
molecu1 = growpal_parallel(molecu0, growatom, dtol=1.2, n_cores=nproc)
# Optimize and filter duplicates
molecu0 = opt_LJ_parallel(molecu1, n_jobs=nproc)
molecu1 = deduplicate_by_usr(molecu0, tols=0.99, tole=0.1, mono=True)
molecu1 = cutter_energy(molecu1, ecut)
molecu0 = select_by_clustering(molecu1, selection_count=160, n_clusters=8)
display_info(molecu0[0:5], base_name)
writexyzs(molecu0, base_name + '.xyz')
4. Verify LJ results against the reference database
from aegon.libcalc_lj import lj_energy
from aegon.libdata_lj import get_lj_cluster
from aegon.libutils import readxyzs
import os
ii = 4
file = 'LJ' + str(ii).zfill(3) + '.xyz'
while os.path.isfile(file):
mol = readxyzs(file)
nm = len(mol)
efili = lj_energy(mol[0].get_positions())
etrue = get_lj_cluster(ii).info['e']
deltae = efili - etrue
print('%s (%s) %11.6f %5.2f' % (file, f"{nm:02d}", efili, deltae))
ii += 1
file = 'LJ' + str(ii).zfill(3) + '.xyz'
5. Compare Sutton-Chen energies between two metals
import numpy as np
from aegon.libcalc_sc import SUTTON_CHEN_PARAMS
from aegon.libdata_sc import get_sc_cluster
metal_type1, metal_type2 = 'Pt', 'Au'
epsilon1 = SUTTON_CHEN_PARAMS[metal_type1]['epsilon']
epsilon2 = SUTTON_CHEN_PARAMS[metal_type2]['epsilon']
for i in range(4, 80 + 1):
atoms1 = get_sc_cluster(i, symbol=metal_type1)
atoms2 = get_sc_cluster(i, symbol=metal_type2)
e1 = atoms1.info['e'] / epsilon1
e2 = atoms2.info['e'] / epsilon2
deltae = np.abs(e1 - e2)
print("%9s vs. %9s dE=%f" % (atoms1.info['i'], atoms2.info['i'], deltae))
Key Results
Lennard-Jones clusters (10–130 atoms)
- All reported global minima recovered, including the challenging LJ75–LJ78, LJ98 (tetrahedral, Td symmetry), and LJ102–LJ104 cases.
- Recovery of LJ98 required 1288 seed structures; genealogical analysis shows that its growth pathway passes through an intermediate at LJ55 that lies 8.4 eV above the putative global minimum — a structure that would be discarded by any purely energy-based selection.
- The
selection_countparameter controls search thoroughness: larger values explore harder cases at the cost of more local optimizations. - Efficiency comparison for LJ41: GrowPAL requires ~12,000 local optimizations vs. ~34,000 for SCG and ~118,000 for SFAEA (LJ38).
Sutton-Chen clusters (5–90 atoms, 10 metals)
- Nine parameter sets benchmarked (Al, Ag, Au, Cu, Ir, Ni, Pb, Pd, Pt, Rh); all previously reported global minima reproduced.
- New putative global minima identified for:
- Palladium (n–m = 12-7): N = 26 (D3h, –0.092 eV vs. prior), 29 (Cs, –0.181 eV vs. prior), 37 (C2v), and 62 (Cs)
- Aluminum (n–m = 7-6): N = 12 and 20
- First complete datasets of putative global minima provided for the unexplored n–m = 10-7 and 14-6 parameterizations (5–90 atoms).
Citation
If you use GrowPAL in your research, please cite:
Gutiérrez-Campos I., Merino G., Ortiz-Chi F. Morphological Diversity as a Selection Principle in Growth-Based Global Optimization.
For the original GrowPAL growth algorithm:
López-Castro C., Ortiz-Chi F., Merino G. An Efficient Growth Pattern Algorithm (GrowPAL) for Cluster Structure Prediction. J. Chem. Theory Comput. 2024, 20, 4939–4948.
Authors
- Isaac Gutiérrez-Campos — Departamento de Física Aplicada, Cinvestav-IPN, Mérida, México
- Gabriel Merino — Departamento de Física Aplicada, Cinvestav-IPN, Mérida, México
- Filiberto Ortiz-Chi — Secihti-Departamento de Física Aplicada, Cinvestav-IPN, Mérida, México
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file growpal-0.1.2.tar.gz.
File metadata
- Download URL: growpal-0.1.2.tar.gz
- Upload date:
- Size: 32.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
03153d49049902f9a2ecd1ff4718f3d0a97be975bf752e48038a7bc1ad6bd470
|
|
| MD5 |
aef33e300556f5b2f998338e155eb26d
|
|
| BLAKE2b-256 |
fc446111acffbb9372f545452bccd4efa184abfaf1b101b424ce5218080c602b
|
File details
Details for the file growpal-0.1.2-py3-none-any.whl.
File metadata
- Download URL: growpal-0.1.2-py3-none-any.whl
- Upload date:
- Size: 29.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b513b4fa87104cd479825d5d44fd8f6a5f437265026c0eac3b267c855d9b3a22
|
|
| MD5 |
62a5c7d604b854fb0d5f6b5515a5c95a
|
|
| BLAKE2b-256 |
b5f87951cb17c787656865a5e77b53b3a5c70e8bb48687df4fdd076c398cc489
|