Molecular dynamics simulation and visualization of protein structures using Warp and Polyscope. The codebase provides a modular framework for simulating and visualizing protein dynamics with GPU acceleration. The example demonstrates visualization of the tumor suppressor protein 1TUP.
3D_protein/
├── run_simulation.py # Main entry point (run from here)
├── requirements.txt
├── data/
│ └── 1TUP.cif # Example protein structure (Tumor Suppressor P53)
├── src/
│ ├── simulation/ # Simulation engine
│ │ ├── __init__.py
│ │ └── engine.py # Langevin dynamics, Warp kernels, analyze_structure, render_frame
│ └── visualization/ # Polyscope visualization
│ ├── __init__.py
│ └── polyscope_viz.py
└── scripts/
└── run_simulation_only.py # Run simulation without visualization
-
src/simulation/– Core simulation enginerun_simulation(),analyze_structure(),render_frame()- GPU-accelerated Warp kernels for bond, non-bonded, and Langevin integration
-
src/visualization/– Polyscope-based visualizationvisualize_simulation(),prepare_visualization_data(),setup_polyscope_visualization()- Before/after comparison and animated trajectory playback
-
run_simulation.py– Main entry point; run from project root to execute the full pipeline
Create and activate a virtual environment, then install dependencies:
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
pip install -r requirements.txtImportant: Run all commands below with this venv activated (or use .venv/bin/python explicitly). Otherwise you may get ModuleNotFoundError: No module named 'warp' because the system Python doesn’t have warp-lang installed.
Run the complete simulation and visualization pipeline:
python run_simulation.pyThis will:
- Load the protein structure from
data/1TUP.cif - Run the molecular dynamics simulation
- Generate
protein_simulation.usdin the project root - Launch an interactive Polyscope visualization window
Run only the simulation (no visualization):
python scripts/run_simulation_only.pyThis generates the USD file but does not launch the visualization.
Run only the visualization (requires pre-computed trajectory):
from src.simulation import run_simulation
from src.visualization import visualize_simulation
trajectory, forces, chains_data = run_simulation(
filename='data/1TUP.cif',
n_steps=200,
dt=0.002
)
visualize_simulation(trajectory, forces, chains_data)Import from the src package:
import warp as wp
from src.simulation import run_simulation, analyze_structure
from src.visualization import visualize_simulation, prepare_visualization_data
wp.init()
trajectory, forces, chains_data = run_simulation(
filename='data/your_protein.cif',
n_steps=500,
dt=0.001,
output_usd='output.usd',
device='cuda'
)
visualize_simulation(
trajectory=trajectory,
forces=forces,
chains_data=chains_data,
screenshot_path='comparison.png'
)def run_simulation(
filename: str = '1TUP.cif',
n_steps: int = 200,
dt: float = 0.002,
output_usd: str = "protein_simulation.usd",
device: str = "cpu"
) -> tuple:
"""Returns (trajectory, forces_history, chains_data). Call wp.init() first."""def visualize_simulation(
trajectory: np.ndarray,
forces: np.ndarray,
chains_data: List[Dict[str, Any]],
screenshot_path: str = None
) -> None:
"""Main function to visualize a protein simulation."""This project implements a basic coarse-grained molecular dynamics simulation to demonstrate high-performance physics simulation using NVIDIA Warp. The primary goal is to showcase how Warp can be used to write differentiable, GPU-accelerated simulation kernels in Python.
The motion of particles is governed by overdamped Langevin dynamics, which approximates the behavior of particles in a solvent where viscous drag dominates inertia:
Where:
-
$r_i$ is the position of particle$i$ -
$\gamma$ is the friction coefficient -
$k_B T$ is the thermal energy -
$\xi(t)$ is a Gaussian random noise vector (Brownian motion)
The simulation includes several force terms to model molecular interactions:
Harmonic Bonds: Maintains the connectivity of the protein chain. $$ F_{bond} = -k_{bond} (r - r_0) \hat{r} $$
Lennard-Jones Potential: Models the van der Waals forces (short-range repulsion and long-range attraction). $$ F_{LJ} = \frac{24\epsilon}{r} \left[ 2\left(\frac{\sigma}{r}\right)^{12} - \left(\frac{\sigma}{r}\right)^6 \right] \hat{r} $$
Electrostatics (Coulomb): Models the attraction and repulsion between charged residues (e.g., DNA- and Protein+). $$ F_{elec} = k_{coulomb} \frac{q_i q_j}{r^2} \hat{r} $$
Note: This is a simplified coarse-grained model (1 bead per residue) intended for visualization and performance demonstration, not for rigorous biophysical predictions.
The codebase follows best practices for modular Python development:
- Clear APIs: All functions have docstrings with type hints
- Reusable Components: Functions can be imported and used independently
- Separation of Concerns: Simulation, visualization, and execution are separate modules
- No Side Effects: Modules don't execute code on import
- Proper Initialization:
wp.init()is called by the user or main script, not at module level
protein_simulation.usd: USD format file containing the full simulation trajectoryoutput images/before_after_comparison.png: Screenshot comparing initial and final conformations