Skip to content

Instantly share code, notes, and snippets.

@hpcdisrespecter
Last active March 20, 2025 12:42
Show Gist options
  • Save hpcdisrespecter/a6747ed87743cd39a27e53df540857cf to your computer and use it in GitHub Desktop.
Save hpcdisrespecter/a6747ed87743cd39a27e53df540857cf to your computer and use it in GitHub Desktop.
Center and pad cartesian POSCAR
#!/bin/bash
if [ $# -ne 2 ]; then
echo "Usage: $0 <file> <amount>"
exit 1
fi
if [ "$2" -lt 0 ]; then
echo "Amount must be positive"
exit 1
fi
if [ ! -f "$1" ]; then
echo "File not found"
exit 1
fi
file=$1
padding=$2
cp "$file" "$file".bak # backup the original file
title=$(sed -n '1p' "$file")
scale=$(sed -n '2p' "$file")
atoms=$(sed -n '6p' "$file")
atom_counts=$(sed -n '7p' "$file")
coord_type=$(sed -n '8p' "$file")
if [[ ! $coord_type =~ [Cc]artesian ]]; then
echo "Not cartesian coordinates"
exit 1
fi
# Find current system bounds
max_x=$(awk 'NR>8 {print $1}' "$file" | sort -nr | head -n 1)
max_y=$(awk 'NR>8 {print $2}' "$file" | sort -nr | head -n 1)
max_z=$(awk 'NR>8 {print $3}' "$file" | sort -nr | head -n 1)
min_x=$(awk 'NR>8 {print $1}' "$file" | sort -n | head -n 1)
min_y=$(awk 'NR>8 {print $2}' "$file" | sort -n | head -n 1)
min_z=$(awk 'NR>8 {print $3}' "$file" | sort -n | head -n 1)
# Calculate required shifts to center the system
shift_x=$(echo "scale=6; $padding - $min_x" | bc)
shift_y=$(echo "scale=6; $padding - $min_y" | bc)
shift_z=$(echo "scale=6; $padding - $min_z" | bc)
# Calculate new cell dimensions (original size + padding on both sides)
cell_x=$(echo "scale=6; ($max_x - $min_x) + 2*$padding" | bc)
cell_y=$(echo "scale=6; ($max_y - $min_y) + 2*$padding" | bc)
cell_z=$(echo "scale=6; ($max_z - $min_z) + 2*$padding" | bc)
# Shift coordinates using individual shifts for each dimension
new_coords=$(awk -v sx="$shift_x" -v sy="$shift_y" -v sz="$shift_z" 'NR>8 {printf "%-.6f %-.6f %-.6f\n", $1+sx, $2+sy, $3+sz}' "$file")
# Create new cell with proper dimensions
new_cell=$(printf "%-.6f %-.6f %-.6f\n%-.6f %-.6f %-.6f\n%-.6f %-.6f %-.6f\n" \
"$cell_x" 0 0 \
0 "$cell_y" 0 \
0 0 "$cell_z")
# Write the new file
cat > "$file" <<EOF
$title
$scale
$new_cell
$atoms
$atom_counts
$coord_type
$new_coords
EOF
echo "File $file centered and padded by $padding Å on each side."
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment