Examples

Example 1: Solvating a Crystal

Pack water around a periclase (MgO) crystal:

from water_packer import WaterPacker
from molecular_builder import create_bulk_crystal

# Create MgO crystal using molecular-builder
mgo = create_bulk_crystal("periclase", [15.0, 15.0, 15.0])

# Pack water with Mg-O specific distance
packer = WaterPacker(
    pairwise_distances={
        ('O', 'Mg'): 2.0,  # Water O to Mg distance
    },
    water_density=1.0,
    seed=42
)

solvated = packer.pack(mgo)
Solvated Periclase Crystal

Example 2: Reproducible Packing

Generate identical structures using seeds:

# Run 1
packer1 = WaterPacker(seed=123)
result1 = packer1.pack(box, n_waters=50)

# Run 2 - identical to run 1
packer2 = WaterPacker(seed=123)
result2 = packer2.pack(box, n_waters=50)

import numpy as np
assert np.allclose(
    result1.get_positions(),
    result2.get_positions()
)
Reproducible Solvation Box

Example 3: Auto-calculate Water Count

Let the packer determine how many waters fit:

packer = WaterPacker(water_density=1.0)

# n_waters=None → use density to calculate
result = packer.pack(substrate)

print(f"Auto-packed {(len(result) - len(substrate))//3} waters")
Auto-packed Water Box

Example 4: Complex Surfaces (Brucite)

Packing water around a Brucite (Mg(OH)2) slab with H-termination:

from water_packer import pack_with_relaxation
# ... setup brucite slab ...

# Use relaxation to fit waters into tight surface grooves
result = pack_with_relaxation(packer, brucite, n_waters=32)
Solvated Brucite Slab