Skip to main content

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

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:

  1. 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.

  2. Structural discrimination. Duplicate and near-duplicate structures are removed via a two-stage USR-based filter (deduplicate_by_usr in aegon.discrimination.cluster_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).

  3. 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.

  4. Clustering-based selection. Descriptor vectors are partitioned by agglomerative Ward clustering with a k-NN connectivity constraint. The selection_count lowest-energy structures from each cluster are retained as seeds for the next iteration. This selection_count parameter 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, joblib), molsympy (symmetry-inequivalent-site detection used by the growth engine itself), scikit-learn (Ward clustering), and dscribe (MBTR descriptors for multi-species systems).

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
molsympy Symmetry-inequivalent internal-triangle detection (get_inequivalent), used directly by libgrowpal.py's interstitial-insertion step
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.data.sc import get_sc_cluster
from aegon.optimization.potentials.sc import SUTTON_CHEN_PARAMS
from aegon.io.gcolab 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.data.lj import get_lj_cluster
from aegon.io.gcolab 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 LJ004.xyz file with seed structures for the starting size:

file = 'LJ004.xyz'
input_text = """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
"""
with open(file, "w") as f: f.write(input_text)

Then run the growth loop:

import os
from aegon.io.xyz                     import readxyzs, writexyzs
from aegon.population                 import rename, cutter_energy
from aegon.optimization.potentials.lj import opt_LJ_parallel
from aegon.discrimination.cluster_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.optimization.potentials.lj import lj_energy
from aegon.data.lj import get_lj_cluster
from aegon.io.xyz 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.optimization.potentials.sc import SUTTON_CHEN_PARAMS
from aegon.data.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, 90 + 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_count parameter 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 (nm = 12-7): N = 26 (D3h, –0.092 eV vs. prior), 29 (Cs, –0.181 eV vs. prior), 37 (C2v), and 62 (Cs)
    • Aluminum (nm = 7-6): N = 12 and 20
  • First complete datasets of putative global minima provided for the unexplored nm = 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

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

growpal-0.1.3.tar.gz (22.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

growpal-0.1.3-py3-none-any.whl (17.9 kB view details)

Uploaded Python 3

File details

Details for the file growpal-0.1.3.tar.gz.

File metadata

  • Download URL: growpal-0.1.3.tar.gz
  • Upload date:
  • Size: 22.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.0

File hashes

Hashes for growpal-0.1.3.tar.gz
Algorithm Hash digest
SHA256 666f3e7c58eb70a1e0812710a0014ac20a901a933e1e6096ad0d88a863325533
MD5 328331185109b35ba576ebf845e1ea2d
BLAKE2b-256 cdc6922a33d27838322cc24a4eb3fefa1c44a3a88ff6674a684e2f05b16fc683

See more details on using hashes here.

File details

Details for the file growpal-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: growpal-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 17.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.0

File hashes

Hashes for growpal-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 3637ffbb60ef0948409f38204a1d9437e21f90df899f581872d6ca87891157a7
MD5 627a06268533c3f8c7f093263a6abe66
BLAKE2b-256 69a1cb3bb5a589579754cfb34ec48007e55c8050325eb3c4ea3bc992b4bd2e14

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.6

2 files

0.1.5

2 files

0.1.4

2 files

This release

0.1.3 This release

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

0.0.9

2 files

0.0.8

2 files

0.0.7

2 files

0.0.6

2 files

0.0.5

2 files

0.0.4

2 files

0.0.3

2 files

0.0.2

2 files

0.0.1

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page