From 89d5d2abf946335cb27fae9ea5a310d71f008a3d Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 19 Mar 2026 19:25:15 -0400 Subject: [PATCH] Add MDvis.ipynb visualization notebook --- MDvis.ipynb | 245 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 MDvis.ipynb diff --git a/MDvis.ipynb b/MDvis.ipynb new file mode 100644 index 0000000..8562b20 --- /dev/null +++ b/MDvis.ipynb @@ -0,0 +1,245 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "intro", + "metadata": {}, + "source": [ + "# SimpleMD — In-Notebook Visualization\n", + "\n", + "This notebook runs a short Lennard-Jones simulation and visualizes the particle trajectory using [py3Dmol](https://github.com/3dmol/3Dmol.js), which renders interactively in VS Code, Jupyter, and Google Colab.\n", + "\n", + "For more advanced visualization (depth cueing, rendering), see the VMD instructions in the SimpleMD manual (Ch. 5).\n", + "\n", + "**Controls**\n", + "- Drag to rotate\n", + "- Scroll to zoom\n", + "- Right-click drag to pan" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "colab-setup", + "metadata": {}, + "outputs": [], + "source": [ + "# --- Google Colab only: clone the repo and install py3Dmol ---\n", + "# Skip this cell if running locally.\n", + "import sys\n", + "if 'google.colab' in sys.modules:\n", + " !git clone https://github.com/emfurst/SimpleMD.git\n", + " %cd SimpleMD\n", + " !pip install py3Dmol --quiet" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "imports", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import py3Dmol\n", + "import CHEG231MD as md" + ] + }, + { + "cell_type": "markdown", + "id": "sim-header", + "metadata": {}, + "source": [ + "## Run the simulation\n", + "\n", + "Set up and equilibrate, then run a short production trajectory.\n", + "Adjust `nn`, `rho`, and `vmax` to explore different conditions." + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "run-sim", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Equilibrated: T* = 0.614 P* = -0.392\n" + ] + } + ], + "source": [ + "nn = 5 # particles per side (N = nn^3)\n", + "rho = 0.4 # reduced number density\n", + "vmax = 1.5 # initial max velocity\n", + "\n", + "sim = md.MDSimulation(nn, rho, vmax)\n", + "\n", + "# Equilibration\n", + "for _ in range(200):\n", + " sim.move()\n", + "print(f\"Equilibrated: T* = {sim.T:.3f} P* = {sim.P:.3f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "write-traj", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Wrote trajectory to MDvis.xyz (T* = 0.836, P* = -0.122)\n" + ] + } + ], + "source": [ + "XYZ_FILE = \"MDvis.xyz\"\n", + "\n", + "def write_frame(f, sim, timestep):\n", + " f.write(f\"{sim.N}\\n\")\n", + " f.write(f\"Timestep: {timestep}\\n\")\n", + " for row in sim.x:\n", + " f.write(f\"Ar {row[0]:.6f} {row[1]:.6f} {row[2]:.6f}\\n\")\n", + "\n", + "# Production run — write every 5th frame\n", + "with open(XYZ_FILE, \"w\") as f:\n", + " for t in range(1, 501):\n", + " sim.move()\n", + " if t % 10 == 0:\n", + " write_frame(f, sim, t)\n", + "\n", + "print(f\"Wrote trajectory to {XYZ_FILE} (T* = {sim.T:.3f}, P* = {sim.P:.3f})\")" + ] + }, + { + "cell_type": "markdown", + "id": "vis-header", + "metadata": {}, + "source": [ + "## Animated trajectory\n", + "\n", + "The viewer below plays through all saved frames.\n", + "The wireframe box shows the periodic simulation cell." + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "id": "animate", + "metadata": {}, + "outputs": [ + { + "data": { + "application/3dmoljs_load.v0": "
\n

3Dmol.js failed to load for some reason. Please check your browser console for error messages.

\n
\n", + "text/html": [ + "
\n", + "

3Dmol.js failed to load for some reason. Please check your browser console for error messages.

\n", + "
\n", + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "with open(XYZ_FILE) as f:\n", + " xyz = f.read()\n", + "\n", + "view = py3Dmol.view(width=600, height=450)\n", + "view.addModelsAsFrames(xyz, \"xyz\")\n", + "view.setStyle({\"sphere\": {\"radius\": 0.5, \"color\": \"red\", \"opacity\": 1}})\n", + "view.setBackgroundColor(\"white\")\n", + "\n", + "# Draw the periodic simulation box\n", + "c = sim.L / 2\n", + "view.addBox({\"center\": {\"x\": c, \"y\": c, \"z\": c},\n", + " \"dimensions\": {\"w\": sim.L, \"h\": sim.L, \"d\": sim.L},\n", + " \"color\": \"white\", \"opacity\": 0.5, \"wireframe\": False})\n", + "\n", + "view.zoomTo()\n", + "view.animate({\"loop\": \"forward\", \"interval\": 100})\n", + "view.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c6cd4574", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.11" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}