Tutorial: Contact Angle Analysis (Slicing Method)

This tutorial explains how to compute the contact angle of a droplet using the slicing method in wetting_angle_kit.


1. Overview

The slicing method divides the droplet into slices (along the z-axis) and fits a geometric model (e.g. spherical) to the liquid–solid interface profile. This is ideal for studying the evolution of the angle along a trajectory.


2. Requirements

Before running the example, ensure you have installed:

pip install wetting-angle-kit ase numpy

Example trajectory:

tests/trajectories/traj_spherical_drop_4k.lammpstrj

3. Example Code

# Import necessary modules
from wetting_angle_kit.parsers import LammpsDumpParser, LammpsDumpWaterFinder
from wetting_angle_kit.analysis import SlicingTrajectoryAnalyzer

# --- Step 1: Define the trajectory file ---
filename = "../../tests/trajectories/traj_spherical_drop_4k.lammpstrj"

# --- Step 2: Initialize the water molecule finder ---
wat_find = LammpsDumpWaterFinder(
    filename,
    particle_type_wall={3},  # Wall particle types
    oxygen_type=1,  # Oxygen atom type
    hydrogen_type=2,
)  # Hydrogen atom type

# --- Step 3: Identify oxygen atom indices ---
oxygen_indices = wat_find.get_water_oxygen_ids(frame_index=0)
print("Number of water molecules:", len(oxygen_indices))

# --- Step 4: Initialize the parser ---
parser = LammpsDumpParser(filename)

# --- Step 5: Create the contact angle analyzer ---
# Using the slicing method with a spherical model
analyzer = SlicingTrajectoryAnalyzer(
    parser=parser,
    atom_indices=oxygen_indices,
    droplet_geometry="spherical",  # Geometry fitting model
    delta_gamma=20,  # Azimuthal step (deg) for spherical slicing
)

# --- Step 6: Run the analysis ---
results = analyzer.analyze([1])  # Analyze frame 1

# --- Step 7: Display results ---
print("Mean contact angle (°):", results.mean_angle)
print("Std contact angle (°):", results.std_angle)
print("Frames analyzed:", results.frames)

4. Expected Output

After running the example, you’ll see something like:

Number of water molecules: 1320
Mean contact angle (°): 94.46
Std contact angle (°): 0.0
Frames analyzed: [1]

The standard deviation is reported as 0.0 because the example only analyzes a single frame. std_angle is computed across frames — pass a multi-frame frame_range (e.g. range(0, 50)) to see a non-zero spread.

analyze returns a SlicingResults dataclass with the following convenience attributes:

  • mean_angle — mean contact angle (°) across the analyzed frames.

  • std_angle — standard deviation across frames.

  • per_frame_mean_angles — array of per-frame mean angles (one per slice aggregated to a single number).

  • frames — list of frame indices that were processed.

  • angles / surfaces / popts — raw per-frame data passed directly to SlicingTrajectoryPlotter for visualization.

  • method_metadata — method-specific info (e.g. number of frames per angle value).


5. Tips

  • Use droplet_geometry='spherical' for droplets and droplet_geometry='cylinder_y' for cylindrical droplet on the y axis or 'cylinder_x' for cylinder on the x axis.

  • Adjust delta_gamma for the spherical mode (azimuthal step in degrees between successive slices — smaller = more slices, more detail, more cost). For very small droplets, also raise points_per_angstrom (default 1.0) on the analyzer to densify the per-ray sampling used by the interface fit.

  • To analyze multiple frames:

results = analyzer.analyze(range(0, 50, 10))
  • Output files include raw interface data and optional plots (if enabled).