Skip to content

Latest commit

 

History

History
455 lines (358 loc) · 11.3 KB

File metadata and controls

455 lines (358 loc) · 11.3 KB

Architecture

This document describes the technical architecture of Atoms_Rust, including module structure, data flow, and design decisions.


Overview

Atoms_Rust is organized as a Rust library with multiple binary front-ends, following the principle of separation of concerns between physics, rendering, and user interaction.

graph TB
    subgraph "Application Layer"
        RT[realtime.rs<br/>3D Realtime]
        RAY[raytracer.rs<br/>GPU Rendering]
        A2D[atom_2d.rs<br/>2D Simulation]
        W2D[wave_2d.rs<br/>Wave Viz]
    end

    subgraph "Library Layer"
        LIB[lib.rs<br/>Public API]
    end

    subgraph "Core Modules"
        PHYS[physics/<br/>Quantum Mechanics]
        REND[render/<br/>GPU Utilities]
        CAM[camera/<br/>Navigation]
    end

    RT --> LIB
    RAY --> LIB
    A2D --> LIB
    W2D --> LIB

    LIB --> PHYS
    LIB --> REND
    LIB --> CAM

    style LIB fill:#e1f5fe
    style PHYS fill:#fff3e0
    style REND fill:#e8f5e9
    style CAM fill:#fce4ec
Loading

Directory Structure

src/
├── lib.rs                 # Library entry point, re-exports
├── constants.rs           # Physical constants (a₀, ħ, mₑ)
│
├── physics/               # Core physics calculations
│   ├── mod.rs             # Module exports
│   ├── polynomials.rs     # Laguerre & Legendre polynomials
│   ├── sampling.rs        # CDF-based probability sampling
│   └── color.rs           # Inferno colormap implementation
│
├── render/                # Rendering utilities
│   ├── mod.rs             # Module exports
│   ├── instanced.rs       # Instanced particle rendering
│   └── shaders.rs         # GLSL shader code
│
├── camera/                # Camera controllers
│   ├── mod.rs             # Module exports
│   └── orbit.rs           # Orbit camera implementation
│
└── bin/                   # Executable binaries
    ├── realtime.rs        # 3D realtime visualizer
    ├── raytracer.rs       # GPU raytracing mode
    ├── atom_2d.rs         # 2D atom simulation
    └── wave_2d.rs         # 2D wave visualization

Module Details

Physics Module (src/physics/)

The physics module contains all quantum mechanical calculations.

classDiagram
    class Sampler {
        -Vec~f64~ r_cdf
        -Vec~f64~ theta_cdf
        -f64 r_max
        -i32 last_n
        -i32 last_l
        -i32 last_m
        +new() Sampler
        +prepare(n, l, m) void
        +sample_r(n, l, rng) f32
        +sample_theta(l, m, rng) f32
        -build_r_cdf(n, l) void
        -build_theta_cdf(l, m) void
    }

    class Polynomials {
        +laguerre(n, l, rho) f64
        +legendre(l, m, x) f64
        +factorial(n) f64
        +tgamma_int(n) f64
    }

    class ColorMaps {
        +inferno(r, theta, phi, n, l, m) Color
        +inferno_scaled(r, theta, phi, n, l, m) Color
        +inferno_log(r, theta, phi, n, l, m) Color
        +heatmap_fire(value) Color
        +calculate_probability_flow(pos, n, l, m) Vec3
    }

    Sampler --> Polynomials : uses
    ColorMaps --> Polynomials : uses
Loading

polynomials.rs

Mathematical functions for quantum mechanics:

Function Description Complexity
laguerre(n, l, rho) Associated Laguerre polynomial $L_{n-l-1}^{2l+1}$ O(k) where k = n-l-1
legendre(l, m, x) Associated Legendre polynomial $P_l^m$ O(l)
factorial(n) Integer factorial O(n)
tgamma_int(n) Gamma function for integers O(n)

sampling.rs

Probability sampling implementation:

Struct/Function Description
Sampler Caches CDF tables for efficient sampling
sample_r() Sample radial distance from $r^2
sample_theta() Sample polar angle from $\sin\theta
sample_phi() Uniform azimuthal sampling
spherical_to_cartesian() Coordinate conversion

color.rs

Color mapping for visualization:

Function Description
inferno() Standard probability density to color
inferno_scaled() Scaled version for realtime (matches C++)
inferno_log() Log-compressed for raytracer
heatmap_fire() Fire color gradient implementation
calculate_probability_flow() Probability current velocity

Render Module (src/render/)

GPU rendering utilities.

classDiagram
    class ParticleInstance {
        +[f32;3] position
        +f32 _padding
        +[f32;4] color
        +f32 scale
        +[f32;3] _padding2
        +new(pos, color, scale) ParticleInstance
    }

    class ParticleBatch {
        -Vec~ParticleInstance~ instances
        -f32 sphere_radius
        +new(capacity, radius) ParticleBatch
        +add(pos, color) void
        +clear() void
        +len() usize
        +is_empty() bool
    }

    class Shaders {
        <<constant>>
        INSTANCED_VERTEX_SHADER
        INSTANCED_FRAGMENT_SHADER
        POINT_VERTEX_SHADER
        POINT_FRAGMENT_SHADER
        RAYTRACER_VERTEX_SHADER
        RAYTRACER_FRAGMENT_SHADER
    }

    ParticleBatch --> ParticleInstance : contains
Loading

Shader Types

Shader Purpose
INSTANCED_* Instanced sphere rendering with lighting
POINT_* Point sprites with fake sphere shading
RAYTRACER_* SSBO-based GPU raytracing

Camera Module (src/camera/)

Camera controllers for 3D navigation.

classDiagram
    class OrbitCamera {
        +Vec3 target
        +f32 radius
        +f32 azimuth
        +f32 elevation
        +f32 orbit_speed
        +f32 pan_speed
        +f32 zoom_speed
        +bool dragging
        +Vec2 last_mouse_pos
        +new() OrbitCamera
        +with_radius(r) OrbitCamera
        +with_target(t) OrbitCamera
        +position() Vec3
        +forward() Vec3
        +right() Vec3
        +up() Vec3
        +update() void
        +reset() void
    }
Loading

Data Flow

Particle Generation Pipeline

flowchart TD
    START[User Input: n, l, m] --> PREPARE[Sampler::prepare]
    PREPARE --> BUILD_R[Build radial CDF<br/>4096 points]
    BUILD_R --> BUILD_THETA[Build angular CDF<br/>2048 points]
    BUILD_THETA --> LOOP[Particle Loop]

    subgraph LOOP [Per Particle]
        SAMPLE_R[Sample r from CDF] --> SAMPLE_THETA[Sample θ from CDF]
        SAMPLE_THETA --> SAMPLE_PHI[Sample φ uniformly]
        SAMPLE_PHI --> CART[spherical_to_cartesian]
        CART --> COLOR[inferno color]
    end

    LOOP --> STORE[Store Particle]
    STORE --> LOOP
    STORE --> RENDER[Render Loop]
Loading

Frame Rendering Sequence

sequenceDiagram
    participant Main as Main Loop
    participant Input as Input Handler
    participant Camera as OrbitCamera
    participant Sampler as Sampler
    participant Physics as Physics Engine
    participant GPU as GPU Renderer

    Main->>Input: Poll events
    Input->>Camera: Update camera

    alt Quantum numbers changed
        Main->>Sampler: prepare(n, l, m)
        loop N particles
            Main->>Sampler: sample_r/theta/phi()
            Main->>Physics: spherical_to_cartesian()
            Main->>Physics: inferno() color
        end
    end

    Main->>Physics: calculate_probability_flow()

    loop All particles
        Main->>GPU: draw_sphere(pos, color)
    end

    Main->>Main: next_frame().await
Loading

Design Decisions

1. Library + Multiple Binaries

Decision: Separate library from executables

Rationale:

  • Code reuse between visualization modes
  • Allows external crates to use the physics engine
  • Clear separation of concerns

2. CDF Caching

Decision: Cache CDF tables in Sampler struct

Rationale:

  • Building CDF tables is O(N) where N ≈ 4000
  • Sampling from cached CDF is O(log N)
  • Same (n, l, m) often used for many frames

3. Parallel Particle Updates

Decision: Use rayon for parallel iteration

particles.par_iter_mut().for_each(|p| {
    p.vel = calculate_probability_flow(p.pos, n, l, m);
    // Update position...
});

Rationale:

  • Particle updates are independent
  • Linear speedup with core count
  • Minimal synchronization overhead

4. Pre-allocation

Decision: Use Vec::with_capacity() everywhere

let mut particles: Vec<Particle> = Vec::with_capacity(num_particles);

Rationale:

  • Eliminates reallocation during runtime
  • Improves cache locality
  • Reduces memory fragmentation

Performance Characteristics

Memory Layout

Particle struct:
┌─────────────────────────────────────────────┐
│ pos: Vec3 (12 bytes) │ vel: Vec3 (12 bytes) │
├──────────────────────┴──────────────────────┤
│ color: Color (16 bytes)                     │
├─────────────────────────────────────────────┤
│ r: f32 (4 bytes) │ theta: f32 (4 bytes)     │
└─────────────────────────────────────────────┘
Total: 48 bytes per particle

Complexity Analysis

Operation Complexity Notes
Build CDF O(N) N = 4096 for r, 2048 for θ
Sample from CDF O(log N) Binary search
Particle update O(1) Per particle
Total frame update O(P × log N) P = particle count
Render O(P) Per particle draw call

Bottlenecks

pie title Frame Time Distribution
    "GPU Draw Calls" : 60
    "Particle Updates" : 25
    "CDF Sampling" : 10
    "Color Calculation" : 5
Loading

Extending the Codebase

Adding a New Visualization Mode

  1. Create new binary in src/bin/
  2. Import library functions:
    use atoms_rust::{
        inferno, sample_phi, spherical_to_cartesian,
        OrbitCamera, Sampler,
    };
  3. Implement custom rendering logic
  4. Add to Cargo.toml:
    [[bin]]
    name = "your_visualizer"
    path = "src/bin/your_visualizer.rs"

Adding New Physics Functions

  1. Add to appropriate module in src/physics/
  2. Export from mod.rs
  3. Add to lib.rs re-exports
  4. Document with rustdoc and LaTeX

Dependencies

graph LR
    subgraph "Direct Dependencies"
        MQ[macroquad 0.4<br/>Game framework]
        RAND[rand 0.8<br/>Random numbers]
        RAYON[rayon 1.10<br/>Parallelism]
        ERR[thiserror 1.0<br/>Error types]
    end

    subgraph "Dev Dependencies"
        CRIT[criterion 0.5<br/>Benchmarking]
    end

    ATOMS[Atoms_Rust] --> MQ
    ATOMS --> RAND
    ATOMS --> RAYON
    ATOMS --> ERR
    ATOMS -.-> CRIT
Loading

Dependency Purposes

Crate Purpose
macroquad Cross-platform rendering, input handling
rand Random number generation for sampling
rayon Parallel iterator for particle updates
thiserror Derive error types

Build Configuration

# Cargo.toml release profile
[profile.release]
opt-level = 3      # Maximum optimization
lto = true          # Link-time optimization

This configuration ensures:

  • Maximum runtime performance
  • Smaller binary size
  • Dead code elimination