diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
new file mode 100644
index 0000000..155bd8c
--- /dev/null
+++ b/.devcontainer/Dockerfile
@@ -0,0 +1,170 @@
+# Stage 1: base image
+FROM nvidia/cuda:12.8.0-devel-ubuntu24.04 AS base
+ENV DEBIAN_FRONTEND=noninteractive
+
+# set labels
+LABEL version="1.0"
+LABEL description="DEM-Engine Development and Production Environment"
+ARG CUDA_VERSION=12.8.0
+ARG UBUNTU_VERSION=24.04
+ARG CMAKE_BUILD_TYPE=Release
+ARG BUILD_JOBS=0
+
+# basic dependencies
+RUN apt-get update && apt-get install -y --no-install-recommends \
+ build-essential \
+ cmake \
+ ninja-build \
+ git \
+ ca-certificates \
+ && rm -rf /var/lib/apt/lists/*
+
+# CUDA environment variables
+ENV CUDA_HOME=/usr/local/cuda-12.8
+ENV LD_LIBRARY_PATH=${CUDA_HOME}/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
+ENV CPATH=/usr/local/cuda-12.8/targets/x86_64-linux/include
+ENV PATH=/usr/local/cuda-12.8/bin:/usr/local/cuda-12.8/lib64/cmake:${CUDA_HOME}/bin:${PATH}
+
+# Stage 2: dependencies
+FROM base AS deps
+
+# necessary libraries
+RUN apt-get update && apt-get install -y --no-install-recommends \
+ libeigen3-dev \
+ libboost-dev \
+ libboost-filesystem-dev \
+ libboost-system-dev \
+ libboost-thread-dev \
+ && rm -rf /var/lib/apt/lists/*
+
+# Stage 3: CUDA headers preparation
+FROM base AS cuda-headers
+
+# copy CUDA headers from the base image
+RUN mkdir -p /cuda-headers && \
+ cd /usr/local/cuda-12.8/include && \
+ cp -r \
+ cuda.h \
+ cuda_runtime*.h \
+ curand*.h \
+ device_*.h \
+ driver_types.h \
+ vector_types.h \
+ library_types.h \
+ surface_types.h \
+ texture_types.h \
+ channel_descriptor.h \
+ builtin_types.h \
+ cuda_fp16.h \
+ cuda_fp16.hpp \
+ sm_*.h \
+ cuda_device_runtime_api.h \
+ cuda_texture_types.h \
+ cuda_surface_types.h \
+ crt \
+ /cuda-headers/
+
+# Stage 4: build environment
+FROM deps AS builder
+WORKDIR /workspace/DEM-Engine
+
+# copy CMake configuration files
+COPY CMakeLists.txt /workspace/DEM-Engine/
+COPY cmake /workspace/DEM-Engine/cmake
+
+# copy source code
+COPY src /workspace/DEM-Engine/src
+COPY data /workspace/DEM-Engine/data
+COPY thirdparty /workspace/DEM-Engine/thirdparty
+
+# build the project
+RUN mkdir build && cd build && \
+ cmake -G Ninja \
+ -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE:-Release} \
+ .. && \
+ ninja -j${BUILD_JOBS:-$(nproc)}
+
+# Stage 5: runtime image
+FROM nvidia/cuda:12.8.0-runtime-ubuntu24.04 AS runtime-base
+ENV DEBIAN_FRONTEND=noninteractive
+
+# necessary runtime libraries
+RUN apt-get update && apt-get install -y --no-install-recommends \
+ libgomp1 \
+ libboost-filesystem1.83.0 \
+ libboost-system1.83.0 \
+ libboost-thread1.83.0 \
+ && rm -rf /var/lib/apt/lists/*
+
+# CUDA environment variables for runtime
+ENV CUDA_HOME=/usr/local/cuda-12.8
+ENV LD_LIBRARY_PATH=${CUDA_HOME}/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
+
+# Stage 6: production image
+FROM runtime-base AS production
+
+# copy CUDA headers from the cuda-headers stage
+COPY --from=cuda-headers /cuda-headers /usr/local/cuda-12.8/include
+
+# copy jitify library
+COPY --from=builder /workspace/DEM-Engine/thirdparty /workspace/DEM-Engine/thirdparty
+
+# create directory structure
+RUN mkdir -p /workspace/DEM-Engine/build/output \
+ /workspace/DEM-Engine/output
+
+COPY --from=base /usr/local/cuda-12.8/include /usr/local/cuda-12.8/include
+
+# copy files from building stage
+COPY --from=builder /workspace/DEM-Engine/build/bin /workspace/DEM-Engine/build/bin
+COPY --from=builder /workspace/DEM-Engine/build/DEM /workspace/DEM-Engine/build/DEM
+COPY --from=builder /workspace/DEM-Engine/build/kernel /workspace/DEM-Engine/build/kernel
+
+# set working directory
+WORKDIR /workspace/DEM-Engine
+
+# create a wrapper script to ensure correct working directory
+RUN echo '#!/bin/bash\ncd /workspace/DEM-Engine\nexec "$@"' > /usr/local/bin/dem-wrapper.sh && \
+ chmod +x /usr/local/bin/dem-wrapper.sh
+
+# set environment variables
+ENV CUDA_PATH=/usr/local/cuda-12.8
+ENV CUDA_INC_PATH=/usr/local/cuda-12.8/include
+ENV JITIFY_PATH=/workspace/DEM-Engine/thirdparty/jitify
+ENV PATH=/workspace/DEM-Engine/build/bin:${PATH}
+ENV OMP_NUM_THREADS=8
+
+ENTRYPOINT ["/usr/local/bin/dem-wrapper.sh"]
+CMD ["/bin/bash"]
+
+# Stage 7: development image
+FROM deps AS development
+
+# debug and development tools
+RUN apt-get update && apt-get install -y --no-install-recommends \
+ gdb \
+ valgrind \
+ vim \
+ htop \
+ curl \
+ wget \
+ python3-minimal \
+ python3-pip \
+ python3-numpy \
+ python3-matplotlib \
+ python3-pandas \
+ python3-h5py \
+ && rm -rf /var/lib/apt/lists/*
+
+# copy source code
+COPY . /workspace/DEM-Engine
+WORKDIR /workspace/DEM-Engine
+
+# create build directory
+RUN mkdir -p build
+
+# set development environment variables
+ENV CMAKE_BUILD_TYPE=Debug
+ENV OMP_NUM_THREADS=8
+
+CMD ["/bin/bash"]
diff --git a/.devcontainer/README.md b/.devcontainer/README.md
new file mode 100644
index 0000000..9d34151
--- /dev/null
+++ b/.devcontainer/README.md
@@ -0,0 +1,73 @@
+# Docker Support
+__Run DEM-Engine in a containerized environment__
+
+## Quick start
+Make sure to initialize the submodule before using image.
+
+```
+git submodule init
+git submodule update
+```
+
+DEM-Engine provides Docker images for both development and production use:
+
+
Production Image: Optimized runtime environment with pre-built binaries
+
+Development Image: Full build environment with debugging tools
+
+```
+# Build and run the production image
+docker-compose -f .devcontainer/docker-compose.yml up deme-production
+
+# Or start a development environment
+docker-compose -f .devcontainer/docker-compose.yml run --rm deme-dev
+```
+
+## Tips
+### Customize output directory & demo
+There are two ways to customize the output directory and demo execution:
+
+#### 1. Modify docker-compose.yml
+Edit the `docker-compose.yml` file to change default settings:
+```
+volumes:
+ - ../output:/workspace/DEM-Engine/build/output # change this line to your desired output directory
+command: ["/workspace/DEM-Engine/build/bin/DEMdemo_Mixer"] # replace with your production command
+```
+#### 2. Override via Command Line
+Use command-line overrides for more flexibility without modifying files:
+
+```
+# Run specific demos by overriding the command
+docker-compose -f .devcontainer/docker-compose.yml run --rm deme-production \
+ /workspace/DEM-Engine/build/bin/DEMdemo_BallDrop
+
+# Run with custom output directory
+docker-compose -f .devcontainer/docker-compose.yml run --rm \
+ -v $(pwd)/my_output:/workspace/DEM-Engine/build/output \
+ deme-production /workspace/DEM-Engine/build/bin/DEMdemo_RotatingDrum
+
+# Run with both custom output directory AND specific demo
+docker-compose -f .devcontainer/docker-compose.yml run --rm \
+ -v $(pwd)/results/experiment1:/workspace/DEM-Engine/build/output \
+ deme-production /workspace/DEM-Engine/build/bin/DEMdemo_ConePenetration
+```
+
+### Organizing output files
+
+Based on the current mount configuration, consider using nested directories in your demo scripts for better organization:
+
+```
+path out_dir = current_path() / "output" / "DemoOutput_Mixer";
+```
+
+## Volume Mounts
+The development container uses several volumes for persistence:
+
+deme-build-cache: Caches build artifacts
+deme-ccache: Compiler cache for faster rebuilds
+deme-vscode-extensions: VSCode extensions
+
+
+
+
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
new file mode 100644
index 0000000..03da7ad
--- /dev/null
+++ b/.devcontainer/devcontainer.json
@@ -0,0 +1,127 @@
+{
+ "name": "DEM-Engine Development",
+ "dockerComposeFile": "docker-compose.yml",
+ "service": "deme-dev",
+ "workspaceFolder": "/workspace/DEM-Engine",
+
+ "features": {
+ // Only essential features
+ "ghcr.io/devcontainers/features/common-utils:2": {
+ "installZsh": true,
+ "configureZshAsDefaultShell": true,
+ "installOhMyZsh": true,
+ "upgradePackages": false
+ }
+ },
+
+ "customizations": {
+ "vscode": {
+ "extensions": [
+ // C++ development
+ "ms-vscode.cpptools",
+ "ms-vscode.cpptools-extension-pack",
+ "ms-vscode.cmake-tools",
+ "ms-vscode.makefile-tools",
+
+ // CUDA support
+ "nvidia.nsight-vscode-edition",
+
+ // Python support
+ "ms-python.python",
+ "ms-python.vscode-pylance",
+ "ms-python.debugpy",
+
+ // Docker support
+ "ms-azuretools.vscode-docker",
+
+ // Visualization
+ "echatroner.rainbow-csv"
+ ],
+
+ "settings": {
+ // Terminal
+ "terminal.integrated.defaultProfile.linux": "zsh",
+
+ // CMake - optimized for DEM-Engine
+ "cmake.configureOnOpen": false, // Manual control
+ "cmake.buildDirectory": "${workspaceFolder}/build",
+ "cmake.generator": "Ninja",
+ "cmake.configureArgs": [
+ "-DCMAKE_BUILD_TYPE=${env:CMAKE_BUILD_TYPE}",
+ "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON",
+ "-DCMAKE_CUDA_ARCHITECTURES=native" // Auto-detect GPU
+ ],
+ "cmake.parallelJobs": 0, // Use all cores
+
+ // C++
+ "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools",
+ "C_Cpp.default.cppStandard": "c++17",
+ "C_Cpp.formatting": "clangFormat",
+ "C_Cpp.autocompleteAddParentheses": true,
+
+ // File associations
+ "files.associations": {
+ "*.cu": "cuda-cpp",
+ "*.cuh": "cuda-cpp"
+ },
+
+ // Python
+ "python.defaultInterpreterPath": "/usr/bin/python3",
+
+ // Editor
+ "editor.formatOnSave": false, // Only format manually
+ "editor.rulers": [100], // Single ruler at 100
+ "editor.minimap.enabled": false, // Save screen space
+
+ // Performance optimizations
+ "files.watcherExclude": {
+ "**/build/**": true,
+ "**/output/**": true,
+ "**/.git/**": true,
+ "**/thirdparty/**": true
+ },
+
+ "search.exclude": {
+ "**/build": true,
+ "**/output": true,
+ "**/thirdparty": true,
+ "**/*.o": true,
+ "**/*.so": true
+ },
+
+ // Disable telemetry for privacy
+ "telemetry.telemetryLevel": "off"
+ }
+ }
+ },
+
+ // Optimized mounts - only essential ones
+ "mounts": [
+ // Cache build artifacts
+ "source=deme-build-cache,target=/workspace/DEM-Engine/build,type=volume",
+ // Persist extensions
+ "source=deme-vscode-extensions,target=/root/.vscode-server/extensions,type=volume"
+ ],
+
+ // Simplified lifecycle commands
+ "postCreateCommand": "echo '🚀 DEM-Engine Dev Environment Ready' && nvcc --version",
+
+ "postStartCommand": "git config --global --add safe.directory /workspace/DEM-Engine",
+
+ // Only forward ports you actually use
+ "forwardPorts": [],
+
+ // Environment variables
+ "containerEnv": {
+ "CUDA_VISIBLE_DEVICES": "all",
+ "NVIDIA_DRIVER_CAPABILITIES": "all"
+ },
+
+ "remoteUser": "root",
+
+ "remoteEnv": {
+ "CMAKE_BUILD_TYPE": "${localEnv:CMAKE_BUILD_TYPE:Debug}",
+ "OMP_NUM_THREADS": "${localEnv:OMP_NUM_THREADS:8}",
+ "CUDA_LAUNCH_BLOCKING": "${localEnv:CUDA_LAUNCH_BLOCKING:0}"
+ }
+}
\ No newline at end of file
diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml
new file mode 100644
index 0000000..c247f57
--- /dev/null
+++ b/.devcontainer/docker-compose.yml
@@ -0,0 +1,55 @@
+services:
+ # production service
+ deme-production:
+ build:
+ context: ..
+ dockerfile: .devcontainer/Dockerfile
+ target: production
+ image: deme:production
+ runtime: nvidia
+ environment:
+ - NVIDIA_VISIBLE_DEVICES=all
+ volumes:
+ - ..:/workspace/DEM-Engine
+ - ../output:/workspace/DEM-Engine/build/output # change this line to your desired output directory
+ command: ["/workspace/DEM-Engine/build/bin/DEMdemo_Mixer"] # replace with your production command
+
+ # develop service
+ deme-dev:
+ build:
+ context: ..
+ dockerfile: .devcontainer/Dockerfile
+ target: development
+ image: deme:development
+ runtime: nvidia
+ environment:
+ - NVIDIA_VISIBLE_DEVICES=all
+ volumes:
+ - ..:/workspace/DEM-Engine
+ - ../output:/workspace/DEM-Engine/build/output
+ - deme-build-cache:/workspace/DEM-Engine/build
+ - deme-ccache:/root/.ccache
+ - deme-vscode-extensions:/root/.vscode-server/extensions
+ stdin_open: true
+ tty: true
+ command: ["/bin/bash"]
+ cap_add:
+ - SYS_PTRACE # gdb debugging
+ - SYS_ADMIN # advanced debugging
+ security_opt:
+ - seccomp:unconfined # strace debugging
+ privileged: false
+ # extra options
+ shm_size: '2gb' # allow larger shared memory
+ ulimits:
+ memlock:
+ soft: -1
+ hard: -1
+ stack:
+ soft: 67108864
+ hard: 67108864
+
+volumes:
+ deme-build-cache:
+ deme-ccache:
+ deme-vscode-extensions:
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 3b3e392..fd8b407 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -10,3 +10,5 @@
- Joined: April 2023
- Shlok Sabarwal
- Joined: June 2023
+- Peize Li (李沛泽)
+ - Joined: June 2025