Zombie PDE Solver

repository·main·Indexed 43 days ago

https://github.com/rohan-sawhney/zombie

A C++17 header-only library with Python bindings for solving partial differential equations (PDEs) using grid-free Monte Carlo methods, such as Walk on Spheres. It supports Laplace, Poisson, and Screened Poisson equations with Dirichlet, Neumann, and Robin boundary conditions, working directly with boundary representations to avoid volume meshing.

Tokens
2.2K
Snippets
7
Records
12
Agent score
5%

What's inside Zombie

  1. Overview of the Zombie 2D Demo

    main

    The Zombie 2D Demo is a reference application for solving 2D Partial Differential Equations (PDEs). It reads model problems defined in JSON format to build geometry and PDE data, then evaluates solutions on a regular output grid.

    Supported equations:

    • Laplace
    • Poisson
    • Screened Poisson

    Supported boundary conditions:

    • Dirichlet
    • Neumann
    • Robin

    Supported solvers:

    • wos (Walk on Spheres)
    • wost (Walk on Stars)
    • bvc (Boundary Value Caching)
    • rws (Reverse Walk on Stars)
  2. Overview of Zombie

    main

    Zombie is a C++17 header-only library with Python bindings designed for solving partial differential equations (PDEs) using Walk on Spheres-style Monte Carlo methods.

    Unlike traditional solvers, Zombie is grid-free; it queries the original boundary representation directly rather than requiring a volume mesh. This makes it ideal for problems where creating a mesh is expensive or unnecessary. It is primarily intended as a clear reference implementation for research purposes.

  3. Available Solver Families

    main

    Zombie provides several solver families depending on the boundary conditions and noise reduction requirements:

    • Walk on Spheres: For Dirichlet conditions.
    • Walk on Stars: For Neumann and Robin conditions.
    • Boundary Value Caching: For noise reduction.
    • Reverse Walk on Stars: For noise reduction.
  4. Supported PDEs and Boundary Conditions

    main

    Zombie supports scalar and vector-valued PDEs in 2D and 3D.

    Supported Equations:

    • Laplace
    • Poisson
    • Screened Poisson (currently uses a constant absorption coefficient)

    Supported Boundary Conditions:

    • Dirichlet: Prescribed solution value.
    • Neumann: Prescribed normal derivative.
    • Robin: A linear combination of the solution value and the normal derivative.

    Note: Boundary conditions may be mixed across the same boundary. For exterior problems, a Kelvin transform can be used.

  5. The Zombie Core Workflow

    main

    Whether using C++ or Python, solving a PDE with Zombie follows a consistent four-step conceptual workflow:

    1. Define geometric queries: Implement queries for the domain boundary, specifically distance, intersection, and projection queries.
    2. Define PDE data: Specify the source term, screening, and boundary conditions (Dirichlet, Neumann, or Robin).
    3. Choose sample/evaluation points: Select the locations where you want to estimate the solution and its spatial gradient.
    4. Execute solver: Choose a solver, run the random walks, and write or visualize the resulting values.
  6. Create Custom Model Problems

    main

    To create a custom model problem, follow these steps:

    1. Prepare Assets: Use a 2D illustration tool to create:

      • Boundary geometry (exported as SVG).
      • A reflecting boundary indicator mask (exported as PNG). In this mask, white indicates a Neumann or Robin boundary, and black indicates a Dirichlet boundary.
      • Boundary and source textures (exported as PNG or PFM).
      • Important: Ensure the canvas size matches the square bounding box of your boundary geometry.
    2. Convert Geometry: Use the svg2obj.py script to convert your SVG geometry into an OBJ file.

    3. Configure JSON: Create a JSON configuration file mapping these assets to the modelProblem keys as described in the configuration guide.

    ./svg2obj.py engine/data/geometry.svg --normalize --auto_orient_curves
  7. Compile Zombie from source on Mac & Linux

    main

    To build the C++ library from source, clone the repository, initialize submodules, and use CMake to build.

    git clone https://github.com/rohan-sawhney/zombie.git
    cd zombie && git submodule update --init --recursive
    mkdir build && cd build && cmake ..
    make -j4
  8. Configure a Model Problem via JSON

    main

    Model problems are defined using JSON files that combine solver settings, PDE data, and output configurations.

    Key configuration sections:

    • solverType: Selects the algorithm (wos, wost, bvc, or rws).
    • deviceBackend: Specifies the compute backend (e.g., cuda).
    • solver: Parameters for the specific algorithm (e.g., nWalks, maxWalkLength, russianRouletteThreshold).
    • modelProblem: Defines the physical problem, including paths to geometry (OBJ), isReflectingBoundary mask, and texture files for boundary values (absorbingBoundaryValue, reflectingBoundaryValue) and sourceValue.
    • output: Controls the result format, including solutionFile path, gridRes, and colormap settings (colormap, colormapMinVal, colormapMaxVal).

    Note on File Formats: You can use PNG or PFM files for textures and outputs. Use PFM for arbitrary floating-point values; PNGs are limited to the 0-255 range and will clip values.

    {
        "solverType": "wost",
        "deviceBackend": "cuda",
        "solver": {
            "nWalks": 128,
            "maxWalkLength": 1024,
            "epsilonShellForAbsorbingBoundary": 1e-3,
            "epsilonShellForReflectingBoundary": 1e-3,
            "russianRouletteThreshold": 0.99,
            "splittingThreshold": 1.5,
            "ignoreAbsorbingBoundaryContribution": false,
            "ignoreReflectingBoundaryContribution": true,
            "ignoreSourceContribution": true,
            "disablePersistentThreads": false
        },
        "modelProblem": {
            "geometry": "demo/model_problems/engine/data/geometry.obj",
            "isReflectingBoundary": "demo/model_problems/engine/data/is_reflecting_boundary.pfm",
            "absorbingBoundaryValue": "demo/model_problems/engine/data/absorbing_boundary_value.pfm",
            "reflectingBoundaryValue": "demo/model_problems/engine/data/reflecting_boundary_value.pfm",
            "sourceValue": "demo/model_problems/engine/data/source_value.pfm",
            "robinCoeff": 0.0,
            "absorptionCoeff": 0.0,
            "solveDoubleSided": false,
            "solveExterior": false,
            "domainIsWatertight": true,
            "useSdfForAbsorbingBoundary": false
        },
        "output": {
            "solutionFile": "demo/model_problems/engine/solutions/wost.pfm",
            "gridRes": 256,
            "boundaryDistanceMask": 1e-2,
            "saveDebug": false,
            "saveColormapped": true,
            "colormap": "turbo",
            "colormapMinVal": 0.0,
            "colormapMaxVal": 1.1
        }
    }