Random structure generation
Generate ensembles of amorphous structures by constrained random sequential placement with automated minimum separation distances derived from Shannon ionic radii.
How it works
Atoms are placed sequentially into a cubic cell. Each atom must satisfy pair-specific minimum interatomic distances computed automatically from Shannon ionic radii and bonding-type classification. No manual parameter tuning is required.
Automated minsep
For each element pair, the bond type is classified and the appropriate radii are used:
Bond type |
Radii source |
Scale factor |
Example |
|---|---|---|---|
Ionic (M-O, M-Cl) |
Shannon ionic (CN-aware) |
0.80 |
In-O: (0.80+1.40)*0.80 = 1.76 |
Metallic (M-M) |
Metallic radii |
0.85 |
Al-Al: (1.43+1.43)*0.85 = 2.43 |
M-M in oxide |
max(metallic, sqrt(2)*d(M-O)*0.85) |
cap 2.80 |
In-In: max(2.84, 2.64) = 2.80 |
Metalloid (Si-Si) in oxide |
max(metallic, sqrt(2)*d(Si-O)*0.85) |
cap 2.80 |
Si-Si: max(1.99, 2.12) = 2.12 |
Small anion (O-O) |
Shannon ionic |
0.80 |
O-O: (1.40+1.40)*0.80 = 2.24 |
Large anion (Cl-Cl) |
Shannon ionic |
0.70 |
Cl-Cl: (1.81+1.81)*0.70 = 2.53 |
When --target-cn is provided, CN-specific Shannon radii are used (e.g. Si CN=4: 0.26 A vs CN=6: 0.40 A), giving tighter minsep values.
Bond-type classifier
The classifier uses an element-type rule (nonmetal / metalloid / metal membership) with a Pauling electronegativity refinement: when the type rule would call a pair “ionic” but the Pauling Δχ is below 1.0, the pair is reclassified as covalent. This catches predominantly-covalent compounds whose Shannon ionic radii would otherwise give unrealistically small distances:
Pair |
Δχ |
Type rule |
Final class |
Why it matters |
|---|---|---|---|---|
Ga–As |
0.37 |
ionic (metal+metalloid) |
covalent |
Shannon radii would give minsep ≈ 0.68 Å — atomic overlap |
In–P |
0.41 |
ionic |
covalent |
III–V semiconductor |
Si–C |
0.65 |
ionic |
covalent |
Carbide |
B–N |
1.00 |
ionic |
ionic (at threshold) |
Sits right on the cutoff; Shannon radii give reasonable BN minsep |
Ga–N |
1.23 |
ionic |
ionic |
Stays ionic |
Li–F |
3.00 |
ionic |
ionic |
Stays ionic (clearly ionic) |
The Δχ refinement is applied to the metalloid–nonmetal, metalloid–metal, and metal–nonmetal branches. The metallic branch (metal–metal) and the pure-covalent branch (nonmetal–nonmetal, metalloid–metalloid) are unaffected because the type rule already gives the correct answer there. The 1.0 threshold is empirical — it cleanly separates III–V/II–VI semiconductors and carbides (covalent character ≥ 70% by Pauling’s formula) from the polar-ionic borderline cases (GaN, ZnO, BeO) where Shannon ionic radii give sensible minsep values.
The bond classifier is exposed as amorphgen.utils.radii.classify_bond(sym_a, sym_b) for inspection.
Citations. The electronegativity scale follows Pauling’s original definition from bond-dissociation energies (Pauling 1932) as standardised in his textbook (Pauling 1960), with the specific numerical values used in AmorphGen taken from Allred’s 1961 thermochemical revision — the values now in the CRC Handbook and most chemistry textbooks. References:
Pauling, L. J. Am. Chem. Soc. 54, 3570–3582 (1932) — original EN derivation.
Pauling, L. The Nature of the Chemical Bond, 3rd ed., Cornell Univ. Press (1960) — textbook scale.
Allred, A. L. J. Inorg. Nucl. Chem. 17, 215–221 (1961) — revised values used in the code (
PAULING_ENtable inamorphgen/utils/radii.py).
Edge cases at the classifier boundary
The Δχ = 1.0 threshold sits exactly where chemistry genuinely gets ambiguous — bonds with Δχ in the ~0.85–1.15 band have mixed ionic/covalent character. Testing the 50-system JOSS validation set, 54 of 55 cation–anion pairs (98%) agree between the per-pair Pauling classifier and the per-composition material-class radii bucket. The disagreement, and a few other compounds outside the 50-set that sit at the boundary, are listed below:
System |
Pair |
Δχ |
Material class expects |
Pauling rule says |
Reality |
|---|---|---|---|---|---|
MgH₂ |
Mg–H |
0.89 |
ionic (hydride) |
covalent |
Rutile structure — predominantly ionic |
MnS |
Mn–S |
1.03 |
covalent (chalcogenide) |
ionic |
α-MnS is rocksalt — ionic-leaning |
TiC |
Ti–C |
1.01 |
covalent (carbide) |
ionic |
Rocksalt interstitial carbide — mixed bonding |
BN |
B–N |
1.00 |
ionic (nitride) |
ionic (stays — strict |
Sits exactly on cutoff |
These disagreements are benign: the bond classifier governs which radii produce the per-pair minsep, while the material classifier governs which radii produce the density estimate. The two answer different questions, and any modest inconsistency at the boundary is absorbed by the subsequent MLIP relaxation. If you generate one of these systems and the auto-derived density looks off (typically ±15–20% from experiment), set --target-density explicitly to bypass the auto path for that composition.
Automated density
Cell volume is estimated by class-aware sphere packing: the composition is classified into a material class, each element is given a radius from the table appropriate to that class’s bonding (Shannon ionic, Cordero covalent, or Goldschmidt metallic), and the cell is sized so the spheres fill it to the class’s packing factor. Cation oxidation states — needed to select the right Shannon radius — are assigned automatically by charge balance, using a joint solver that resolves multivalent cations in mixed-cation / mixed-anion compounds (e.g. FeTiO3 -> Fe2+/Ti4+, SrTiO3 -> Sr2+/Ti4+) and sums the balance over every anion-former (oxynitrides, oxyfluorides).
Material class |
Radius source |
Packing factor |
Examples |
|---|---|---|---|
|
Shannon ionic CN6 |
0.66 |
TiO2, SnO2, RuO2, IrO2 |
|
Shannon ionic CN6 |
0.63 |
ZrO2, HfO2, CeO2, ThO2, UO2 |
|
Shannon ionic CN6 |
0.62 |
AlN, GaN, Si3N4, TiN |
|
Shannon ionic CN6 |
0.60 |
V2O5, Nb2O5, MoO3, WO3 (OS ≥ 5) |
|
Goldschmidt (cation) + Cordero (C) |
0.60 |
TiC, WC, ZrC |
|
Goldschmidt metallic |
0.60 |
NiTi, CuZr, brass, pure metals |
|
Shannon ionic CN6 |
0.58 |
LiF, NaCl, Li2ZrCl6 |
|
Shannon ionic CN6 |
0.55 |
LiH, MgH2, NaAlH4 |
|
Shannon ionic CN6 |
0.52 |
In2O3, Al2O3, Ga2O3, MgO, ZnO |
|
Shannon ionic CN6 |
0.52 |
ZrN, HfN, ScN (large cation) |
|
Shannon ionic CN6 |
0.50 |
SiO2, GeO2, B2O3 |
|
Cordero covalent |
0.50 |
TiB2, MgB2, ZrB2 |
|
Cordero covalent |
0.35 |
BeO (small polarizing cation) |
|
Cordero covalent |
0.32 |
GaAs, InP, InAs |
|
Cordero covalent |
0.32 |
SiC, B4C |
|
Cordero covalent |
0.30 |
Si, Ge, C |
|
Cordero covalent |
0.30 |
ZnS, CdTe, GeTe |
|
Cordero covalent |
0.28 |
a-Se, a-Te, a-As, a-Sb, a-P |
The dioxide split (rutile vs fluorite) and the small- vs large-cation nitride
split are decided by a cation-radius rule; high_valent_oxide is gated on
oxidation state ≥ 5. Compositions that match no specific class fall back to a
generic packing factor of 0.52 (Shannon ionic).
Density is the weakest-calibrated part of the auto chain — it sizes a sensible
starting cell, but a subsequent MLIP cell relaxation will correct it. Use
--target-density to set the density explicitly when the experimental value is
known.
Coordination-aware placement — “SC” (optional)
With --target-cn, AmorphGen uses SC (“Seed-Coordinate”) placement: each new atom is added as a bonded neighbour of an existing under-coordinated site — the seed — by placing it within that seed’s bonding shell (minsep ≤ d ≤ dmax), which coordinates it. Over-coordinating a neighbour is rejected. This builds short-range order directly into the placement instead of relying on relaxation alone, giving more physical structures.
Where the name comes from. SC is the placement half of the Seed-Coordinate-Anneal (SCA) algorithm of Youn et al., Comput. Mater. Sci. (2014). AmorphGen factors the Anneal step out into its own stages — the MLIP geometry optimisation (--relax) and the melt-quench / hybrid workflow — so the placement step is just Seed-Coordinate (hence “SC”, not “SCA”).
Disable with --no-sc to fall back to plain random rejection sampling (no coordination bias).
Transparency: the auto-derive log line
Every --random-gen run writes a single one-line summary at the top of random_gen.log capturing every chemistry-informed decision the auto chain made — so you can see why a particular minsep / density / target CN was used without reading the code. Example for Ga₂O₃:
[auto-derive] Ga16O24 → metal_oxide, OS{Ga:+3}, CN{Ga:5}, minsep{Ga-Ga:2.43 metallic | Ga-O:1.62 ionic Δχ=1.63 | O-O:2.24 anion-pack}, ρ=4.44 g/cm³ L=8.25 Å
Each field:
Field |
What it means |
|---|---|
|
Composition routed to the |
|
Cation oxidation state inferred from charge balance against the anion |
|
Target coordination auto-detected per cation |
|
Per-pair: bond class + Pauling Δχ (shown only when the ionic classification is at stake) + minsep value in Å |
|
Auto-estimated mass density and cubic cell length |
The line is grep-friendly: grep "auto-derive" random_gen.log retrieves it as a single line per generation run. Bond classes shown are ionic, covalent, metallic, and anion-pack (same-element nonmetal pairs use a separate anion-packing scale factor — see “Bond-type classifier” above).
CLI examples
# Formula format (In2O3 * 16 formula units = 80 atoms)
amorphgen --random-gen --composition "In2O3*16" --n-structures 20
# Atom count format (equivalent)
amorphgen --random-gen --composition In=32,O=48 --n-structures 20
# With target CN and density
amorphgen --random-gen --composition "SiO2*16" --n-structures 20 \
--target-cn Si=4,O=2 --target-density 2.2
# With relaxation
amorphgen --random-gen --composition "In2O3*8" --n-structures 10 \
--relax --model mace-mpa-0 --cell-filter none
Python API
from amorphgen import generate_random, batch_random
# Single structure (auto minsep, auto density from Shannon radii)
atoms = generate_random(
composition={"In": 16, "O": 24}, # atom counts (Python API)
seed=42,
)
# Batch generation (20 structures of SiO2)
paths = batch_random(
composition={"Si": 16, "O": 32},
n_structures=20,
target_density=2.2, # optional, auto if omitted
target_cn={"Si": 4, "O": 2}, # optional, auto if omitted
)
Note: The Python API takes atom counts as a dict. The CLI also accepts formula format:
--composition "SiO2*16"is equivalent to{"Si": 16, "O": 32}.
Accessing radii data
from amorphgen.utils.radii import get_ionic_radius, classify_bond, default_minsep
# Shannon ionic radius
get_ionic_radius("In", cn=6) # 0.80 A
get_ionic_radius("In", cn=4) # 0.62 A
# Bond classification
classify_bond("In", "O") # "ionic"
classify_bond("Si", "Si") # "covalent"
# Auto minsep for a composition
ms = default_minsep(["In", "O"], target_cn={"In": 4})
# {"In-In": 3.11, "In-O": 1.72, "O-O": 2.24}
See Random structure generation for the full API reference.