diff --git a/build_arbd_docs.py b/build_arbd_docs.py
new file mode 100644
index 0000000000000000000000000000000000000000..8f1f0a34cc9bc70bde99d559965a5059ec556fc1
--- /dev/null
+++ b/build_arbd_docs.py
@@ -0,0 +1,644 @@
+#!/usr/bin/env python3
+"""
+Documentation synchronization and build script for arbdmodel.
+
+This script:
+1. Synchronizes content from multiple repositories:
+   - API code from arbdmodel-simple
+   - Tutorials from arbdmodel-introduction
+2. Generates Jupyter Book documentation structure
+3. Builds the final documentation site
+"""
+
+import os
+import sys
+import shutil
+import subprocess
+from pathlib import Path
+import argparse
+import yaml
+import glob
+import re
+import importlib
+
+# Path configuration - update these to match your local setup
+ARBDMODEL_PATH = Path("/Users/pinyili/Documents/research/arbdmodel-simple")
+TUTORIALS_PATH = Path("/Users/pinyili/Documents/research/arbdmodel-introduction")
+DOCS_DIR = Path("arbdmodel-docs")
+BUILD_DIR = DOCS_DIR / "_build"
+
+# Define the structure of documentation sections and modules
+DOCUMENTATION_STRUCTURE = {
+    "Core": [
+        "arbdmodel.core_objects",
+        "arbdmodel.model",
+        "arbdmodel.sim_config",
+    ],
+    "Polymer Modeling": [
+        "arbdmodel.polymer",
+        "arbdmodel.fjc_polymer_model",
+        "arbdmodel.hps_polymer_model",
+        "arbdmodel.kh_polymer_model",
+        "arbdmodel.mpipi_polymer",
+        "arbdmodel.onck_polymer_model",
+        "arbdmodel.sali_polymer_model",
+        "arbdmodel.ssdna_two_bead",
+    ],
+    "RigidBody Models": [
+        "arbdmodel.structure_from_pdb",
+        "arbdmodel.structure_rigidbody",
+        "arbdmodel.mesh_process_volume",
+        "arbdmodel.mesh_process_surface",
+        "arbdmodel.mesh_rigidbody",
+        "arbdmodel.simplearbd",
+    ],
+    "Interaction Potentials": [
+        "arbdmodel.interactions",
+        "arbdmodel.ibi",
+    ],
+    "Simulation Engines": [
+        "arbdmodel.engine",
+        "arbdmodel.parmed_bd",
+    ],
+    "Shape-Based Models": [
+        "arbdmodel.shape_cg",
+    ],
+    "Utilities": [
+        "arbdmodel.coords",
+        "arbdmodel.grid",
+        "arbdmodel.logger",
+        "arbdmodel.version",
+        "arbdmodel.binary_manager",
+    ]
+}
+
+# Tutorial notebook files relative to TUTORIALS_PATH
+TUTORIAL_NOTEBOOKS = [
+    "1-basics.ipynb",
+    "2-polymer-objects.ipynb",
+    "3-iterative-boltzmann-inversion/3-ibi.ipynb",
+    "4-rigid-bodies/4-rigid-bodies.ipynb"
+]
+
+def setup_environment():
+    """Ensure the Python path includes both repositories."""
+    # Make arbdmodel available for import
+    sys.path.insert(0, str(ARBDMODEL_PATH))
+    sys.path.insert(0, str(TUTORIALS_PATH))
+    
+    # Set Python path environment variable for subprocess calls
+    os.environ["PYTHONPATH"] = f"{str(ARBDMODEL_PATH)}:{str(TUTORIALS_PATH)}:{os.environ.get('PYTHONPATH', '')}"
+    
+    # Verify the import works
+    try:
+        import arbdmodel
+        print(f"Successfully imported arbdmodel from {ARBDMODEL_PATH}")
+    except ImportError as e:
+        print(f"Error importing arbdmodel: {e}")
+        print("Please check your path configuration and verify arbdmodel is properly installed.")
+        sys.exit(1)
+
+def sync_tutorial_files():
+    """Copy tutorial notebooks and supporting files from the tutorials repository."""
+    print("\nSynchronizing tutorial files...")
+    
+    # Create the tutorials directory
+    tutorials_output_dir = DOCS_DIR / "tutorials"
+    tutorials_output_dir.mkdir(exist_ok=True, parents=True)
+    
+    # Copy main tutorial notebooks
+    for notebook_path in TUTORIAL_NOTEBOOKS:
+        src_path = TUTORIALS_PATH / notebook_path
+        
+        # Create target directory if notebook is in a subdirectory
+        target_dir = tutorials_output_dir
+        if '/' in notebook_path:
+            subdir = notebook_path.split('/')[0]
+            target_dir = tutorials_output_dir / subdir
+            target_dir.mkdir(exist_ok=True)
+        
+        # Copy the notebook
+        target_path = target_dir / Path(notebook_path).name
+        
+        if src_path.exists():
+            shutil.copy2(src_path, target_path)
+            print(f"Copied: {src_path} -> {target_path}")
+        else:
+            print(f"Warning: Tutorial notebook not found: {src_path}")
+    
+    # Copy supporting files for tutorials
+    # This recursively copies directories that contain resources needed by the notebooks
+    resource_dirs = [
+        "4-rigid-bodies/grids",
+        "4-rigid-bodies/0-initial"
+    ]
+    
+    for resource_dir in resource_dirs:
+        src_dir = TUTORIALS_PATH / resource_dir
+        if src_dir.exists() and src_dir.is_dir():
+            target_dir = tutorials_output_dir / resource_dir
+            if target_dir.exists():
+                shutil.rmtree(target_dir)
+            shutil.copytree(src_dir, target_dir)
+            print(f"Copied directory: {src_dir} -> {target_dir}")
+        else:
+            print(f"Warning: Resource directory not found: {src_dir}")
+    
+    # Copy individual resource files needed by tutorials
+    resource_files = [
+        "4-rigid-bodies/*.pdb",
+        "4-rigid-bodies/*.psf",
+        "4-rigid-bodies/*.tcl"
+    ]
+    
+    for pattern in resource_files:
+        for src_file in glob.glob(str(TUTORIALS_PATH / pattern)):
+            src_path = Path(src_file)
+            rel_path = src_path.relative_to(TUTORIALS_PATH)
+            target_path = tutorials_output_dir / rel_path
+            
+            # Make sure the target directory exists
+            target_path.parent.mkdir(exist_ok=True, parents=True)
+            
+            # Copy the file
+            shutil.copy2(src_path, target_path)
+            print(f"Copied resource: {src_path} -> {target_path}")
+    
+    print("Tutorial files synchronized.")
+    return tutorials_output_dir
+
+def generate_api_docs():
+    """Generate API documentation markdown files."""
+    print("\nGenerating API documentation...")
+    
+    # Create the API documentation directory
+    api_dir = DOCS_DIR / "api"
+    api_dir.mkdir(exist_ok=True, parents=True)
+    
+    # Process each module category
+    category_indices = {}
+    for category, modules in DOCUMENTATION_STRUCTURE.items():
+        print(f"Generating documentation for category: {category}")
+        
+        # Create category directory
+        category_dir = api_dir / category.lower().replace(' ', '_')
+        category_dir.mkdir(exist_ok=True, parents=True)
+        
+        # Process modules in this category
+        module_files = []
+        for module_name in modules:
+            try:
+                # Import the module
+                module = __import__(module_name, fromlist=[""])
+                
+                # Create an API documentation file for this module
+                module_path = create_module_doc(module, module_name, category_dir)
+                if module_path:
+                    module_files.append(module_path)
+            except ImportError as e:
+                print(f"Warning: Could not import module {module_name}: {e}")
+            except Exception as e:
+                print(f"Error processing module {module_name}: {e}")
+        
+        # Create a category index
+        if module_files:
+            index_path = create_category_index(category, module_files, category_dir)
+            category_indices[category] = str(index_path.relative_to(DOCS_DIR))
+    
+    # Create main API index
+    api_index_path = create_api_index(api_dir, category_indices)
+    
+    print(f"API documentation generated at {api_dir}")
+    return category_indices, api_index_path
+
+def create_module_doc(module, module_name, output_dir):
+    """Create a markdown documentation file for a module."""
+    # Extract the simple module name
+    simple_name = module_name.split('.')[-1]
+    
+    # Generate content
+    content = [
+        f"# {simple_name}",
+        "",
+    ]
+    
+    # Add module docstring
+    if module.__doc__:
+        content.append(module.__doc__.strip())
+        content.append("")
+    else:
+        content.append(f"Module documentation for `{module_name}`.")
+        content.append("")
+    
+    # Add version if available
+    if hasattr(module, "__version__"):
+        content.append(f"**Version:** {module.__version__}")
+        content.append("")
+    
+    # Add auto-documentation directive
+    content.extend([
+        "```{eval-rst}",
+        f".. automodule:: {module_name}",
+        "   :members:",
+        "   :undoc-members:",
+        "   :show-inheritance:",
+        "```",
+        ""
+    ])
+    
+    # Write to file
+    output_path = output_dir / f"{simple_name}.md"
+    with open(output_path, 'w') as f:
+        f.write('\n'.join(content))
+    
+    print(f"  Created module doc: {output_path}")
+    return output_path
+
+def create_category_index(category, module_files, category_dir):
+    """Create an index page for a category of modules."""
+    # Build index content
+    content = [
+        f"# {category}",
+        "",
+        f"This section documents the {category.lower()} components of the arbdmodel package.",
+        "",
+        "## Modules",
+        "",
+    ]
+    
+    # Add links to each module
+    for module_path in sorted(module_files, key=lambda p: p.name):
+        # Extract the module name
+        module_name = module_path.stem
+        
+        # Create entry with relative path
+        rel_path = module_path.name
+        
+        # Try to add a brief description
+        try:
+            # Extract first line of docstring
+            with open(module_path, 'r') as f:
+                file_content = f.read()
+                first_line = re.search(r'# .*?\n\n(.*?)\n', file_content)
+                brief_desc = first_line.group(1) if first_line else ""
+        except:
+            brief_desc = ""
+        
+        content.append(f"- [{module_name}]({rel_path}): {brief_desc}")
+    
+    # Write index file
+    index_path = category_dir / "index.md"
+    with open(index_path, 'w') as f:
+        f.write('\n'.join(content))
+    
+    print(f"  Created category index: {index_path}")
+    return index_path
+
+def create_api_index(api_dir, category_indices):
+    """Create the main API index page."""
+    content = [
+        "# API Reference",
+        "",
+        "This section provides detailed documentation for the ARBD Model Python API.",
+        "",
+        "## Module Categories",
+        "",
+    ]
+    
+    # Add links to category indices
+    for category, path in sorted(category_indices.items()):
+        content.append(f"- [{category}]({path})")
+    
+    # Write index file
+    index_path = api_dir / "index.md"
+    with open(index_path, 'w') as f:
+        f.write('\n'.join(content))
+    
+    print(f"Created API index: {index_path}")
+    return index_path
+
+def create_tutorials_index(tutorials_dir):
+    """Create an index page for tutorials."""
+    content = [
+        "# Tutorials",
+        "",
+        "This section contains tutorials and examples for working with the arbdmodel package.",
+        "",
+        "## Available Tutorials",
+        "",
+    ]
+    
+    # Find all notebook files in the tutorials directory
+    notebook_paths = []
+    for root, _, files in os.walk(tutorials_dir):
+        root_path = Path(root)
+        for file in files:
+            if file.endswith('.ipynb'):
+                rel_path = root_path.relative_to(tutorials_dir)
+                if str(rel_path) == '.':
+                    notebook_paths.append(file)
+                else:
+                    notebook_paths.append(str(rel_path / file))
+    
+    # Group notebooks by directory
+    grouped_notebooks = {}
+    for path in notebook_paths:
+        parts = str(path).split('/')
+        if len(parts) > 1:
+            # Notebook is in a subdirectory
+            subdir = parts[0]
+            if subdir not in grouped_notebooks:
+                grouped_notebooks[subdir] = []
+            grouped_notebooks[subdir].append((parts[-1], path))
+        else:
+            # Top-level notebook
+            if 'top' not in grouped_notebooks:
+                grouped_notebooks['top'] = []
+            grouped_notebooks['top'].append((path, path))
+    
+    # Add links to tutorials grouped by directory
+    for group, notebooks in sorted(grouped_notebooks.items()):
+        if group != 'top':
+            content.append(f"### {group.capitalize()}")
+            content.append("")
+        
+        for name, path in sorted(notebooks):
+            # Extract title from notebook name
+            title = name.replace('.ipynb', '').replace('-', ' ').title()
+            # If the notebook name starts with a number and dash, extract just the title part
+            if re.match(r'^\d+-', title):
+                title = ' '.join(title.split(' ')[1:])
+            
+            content.append(f"- [{title}]({path})")
+        
+        content.append("")
+    
+    # Write index file
+    index_path = tutorials_dir / "index.md"
+    with open(index_path, 'w') as f:
+        f.write('\n'.join(content))
+    
+    print(f"Created tutorials index: {index_path}")
+    return index_path
+
+def create_intro_page():
+    """Create the introduction/landing page for the documentation."""
+    content = [
+        "# ARBD Model Documentation",
+        "",
+        "Welcome to the documentation for the ARBD Model package!",
+        "",
+        "## Overview",
+        "",
+        "ARBD Model is a comprehensive package for coarse-grained molecular modeling and simulation of biomolecular systems. It provides tools for creating and simulating a variety of molecular models, including polymer systems, protein structures, and rigid bodies.",
+        "",
+        "## Features",
+        "",
+        "- **Polymer Modeling**: Create and simulate various polymer models including flexible chain models, hydrophobicity-based models, and specialized DNA models.",
+        "- **Rigid Body Simulation**: Simulate molecular structures as rigid bodies with accurate hydrodynamic properties.",
+        "- **Shape-Based Models**: Generate coarse-grained models based on the shape of molecular structures.",
+        "- **Interaction Potentials**: Wide range of interaction potentials, including the ability to develop custom potentials using Iterative Boltzmann Inversion (IBI).",
+        "- **Simulation Engines**: Multiple simulation engine options for different modeling needs.",
+        "",
+        "## Getting Started",
+        "",
+        "To get started, check out the [Tutorials](tutorials/index) section for examples and walkthroughs.",
+        "",
+        "## Python API Reference",
+        "",
+        "For detailed documentation of the Python API, see the [API Reference](api/index) section.",
+        "",
+    ]
+    
+    intro_path = DOCS_DIR / "intro.md"
+    with open(intro_path, 'w') as f:
+        f.write('\n'.join(content))
+    
+    print(f"Created introduction page: {intro_path}")
+    return intro_path
+
+def create_jupyter_book_files(category_indices):
+    """Create the _toc.yml and _config.yml files for Jupyter Book."""
+    # Table of Contents
+    toc = {
+        "format": "jb-book",
+        "root": "intro",
+        "parts": [
+            {
+                "caption": "Getting Started",
+                "chapters": [
+                    # Removed "intro" as chapter since it's already the root
+                    {"file": "tutorials/index"}
+                ]
+            },
+            {
+                "caption": "API Reference",
+                "chapters": [
+                    {"file": "api/index"},
+                ]
+            }
+        ]
+    }
+    
+    # Add API categories to the TOC
+    api_part = toc["parts"][1]
+    for category, path in sorted(category_indices.items()):
+        api_part["chapters"].append({"file": path})
+    
+    # Write TOC file
+    toc_path = DOCS_DIR / "_toc.yml"
+    with open(toc_path, 'w') as f:
+        yaml.dump(toc, f, sort_keys=False)
+    
+    # Configuration
+    config = {
+        "title": "ARBD Model Documentation",
+        "author": "ARBD Model Team",
+        "logo": "",
+        "execute": {
+            "execute_notebooks": "auto"
+        },
+        "repository": {
+            "url": "https://github.com/username/arbdmodel-docs",
+            "path_to_book": "docs",
+            "branch": "main"
+        },
+        "html": {
+            "use_issues_button": True,
+            "use_repository_button": True,
+            "use_edit_page_button": True
+        },
+        # Prevent duplicate registrations of file extensions
+        "parse": {
+            "myst_enable_extensions": [
+                "colon_fence",
+                "deflist",
+                "dollarmath",
+                "substitution"
+            ],
+            "myst_heading_anchors": 3
+        },
+        "sphinx": {
+            "extra_extensions": [
+                "sphinx.ext.autodoc",
+                "sphinx.ext.viewcode",
+                "sphinx.ext.napoleon",
+                "sphinx_inline_tabs",
+                "sphinx_proof",
+                "sphinx_examples",
+                # Removed myst_parser as it's already included by jupyter-book
+                "sphinx.ext.mathjax",
+                "hoverxref.extension"
+            ],
+            "config": {
+                "autodoc_typehints": "description",
+                "html_theme_options": {
+                    "show_navbar_depth": 2
+                },
+                "add_module_names": False,
+                # Moved myst configurations to the parse section to avoid conflicts
+                "intersphinx_mapping": {
+                    "python": ["https://docs.python.org/3", None],
+                    "numpy": ["https://numpy.org/doc/stable", None],
+                    "scipy": ["https://docs.scipy.org/doc/scipy", None]
+                },
+                "hoverxref_intersphinx": ["python", "numpy", "scipy"]
+            }
+        }
+    }
+    
+    # Write configuration file
+    config_path = DOCS_DIR / "_config.yml"
+    with open(config_path, 'w') as f:
+        yaml.dump(config, f, sort_keys=False)
+    
+    print(f"Created Jupyter Book files: {toc_path}, {config_path}")
+
+def build_docs():
+    """Build the documentation using Jupyter Book."""
+    try:
+        print("\nBuilding documentation...")
+        result = subprocess.run(['jupyter-book', 'build', str(DOCS_DIR)], 
+                                check=True, capture_output=True, text=True)
+        print(result.stdout)
+        print(f"\nDocumentation successfully built. You can view it at: {BUILD_DIR}/html/index.html")
+        return True
+    except subprocess.CalledProcessError as e:
+        print(f"Error building documentation: {e}")
+        print(e.stdout)
+        print(e.stderr)
+        return False
+    except FileNotFoundError:
+        print("Could not find jupyter-book. Make sure it is installed and in your PATH.")
+        print("Install with: pip install jupyter-book")
+        return False
+
+def check_dependencies():
+    """Check if required packages are installed."""
+    required_packages = [
+        'jupyter-book',
+        'matplotlib',
+        'numpy',
+        'sphinx-inline-tabs',
+        'sphinx-examples',
+        'sphinx-proof',
+        'sphinx-hoverxref'
+    ]
+    
+    missing_packages = []
+    for package in required_packages:
+        try:
+            # Try different import strategies
+            package_name = package.replace('-', '_')
+            
+            # Method 1: Try direct import
+            try:
+                module_name = package_name.split('.')[0]
+                __import__(module_name)
+                continue
+            except ImportError:
+                pass
+            
+            # Method 2: Try using importlib
+            try:
+                importlib.import_module(package_name)
+                continue
+            except ImportError:
+                pass
+                
+            # Method 3: Check if package is installed using subprocess
+            try:
+                result = subprocess.run([sys.executable, '-m', 'pip', 'show', package], 
+                                       capture_output=True, text=True)
+                if result.returncode == 0:
+                    continue
+            except Exception:
+                pass
+                
+            # If all methods fail, consider the package missing
+            missing_packages.append(package)
+                
+        except Exception as e:
+            print(f"Error checking for {package}: {e}")
+            missing_packages.append(package)
+    
+    if missing_packages:
+        print("The following required packages are missing:")
+        for package in missing_packages:
+            print(f"  - {package}")
+        print("\nPlease install them using:")
+        print(f"pip install {' '.join(missing_packages)}")
+        
+        response = input("\nDo you want to continue anyway? (y/n): ")
+        if response.lower() not in ('y', 'yes'):
+            sys.exit(1)
+
+def main():
+    """Main function to synchronize content and build documentation."""
+    parser = argparse.ArgumentParser(description="Sync and build ARBD Model documentation")
+    parser.add_argument('--no-sync', action='store_true', help='Skip synchronization of content')
+    parser.add_argument('--no-build', action='store_true', help='Skip building the documentation')
+    parser.add_argument('--clean', action='store_true', help='Clean existing documentation directory')
+    args = parser.parse_args()
+    
+    # Check dependencies
+    check_dependencies()
+    
+    # Set up environment
+    setup_environment()
+    
+    # Clean documentation directory if requested
+    if args.clean and DOCS_DIR.exists():
+        print(f"Cleaning documentation directory: {DOCS_DIR}")
+        shutil.rmtree(DOCS_DIR)
+    
+    # Create docs directory if it doesn't exist
+    DOCS_DIR.mkdir(exist_ok=True, parents=True)
+    
+    if not args.no_sync:
+        # Synchronize content from repositories
+        tutorials_dir = sync_tutorial_files()
+        
+        # Create tutorials index
+        create_tutorials_index(tutorials_dir)
+        
+        # Generate API documentation
+        category_indices, api_index = generate_api_docs()
+        
+        # Create intro page
+        create_intro_page()
+        
+        # Create Jupyter Book files
+        create_jupyter_book_files(category_indices)
+    
+    # Build documentation if requested
+    if not args.no_build:
+        build_docs()
+    else:
+        print("\nSkipping documentation build. To build later, run:")
+        print(f"jupyter-book build {DOCS_DIR}")
+    
+    print("\nDocumentation process completed.")
+
+if __name__ == "__main__":
+    main()