Skip to main content

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

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

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

Project details


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.2.tar.gz (32.5 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.2-py3-none-any.whl (29.2 kB view details)

Uploaded Python 3

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

Hashes for growpal-0.1.2.tar.gz
Algorithm Hash digest
SHA256 03153d49049902f9a2ecd1ff4718f3d0a97be975bf752e48038a7bc1ad6bd470
MD5 aef33e300556f5b2f998338e155eb26d
BLAKE2b-256 fc446111acffbb9372f545452bccd4efa184abfaf1b101b424ce5218080c602b

See more details on using hashes here.

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

Hashes for growpal-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 b513b4fa87104cd479825d5d44fd8f6a5f437265026c0eac3b267c855d9b3a22
MD5 62a5c7d604b854fb0d5f6b5515a5c95a
BLAKE2b-256 b5f87951cb17c787656865a5e77b53b3a5c70e8bb48687df4fdd076c398cc489

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page