DPM Parallel Computing and Performance -- MPI Distribution, Load Balancing, and Speed Optimization
#+CATEGORY: cfd
#+TAGS: DPM parallel MPI load-balancing performance optimization GPU speedup scaling
#+MATURITY: growing
DPM Parallel Computing and Performance Optimization
As parcel counts grow beyond ~100,000, or when transient tracking requires thousands of time steps, computational cost becomes the primary constraint. This page covers parallel DPM distribution (MPI), GPU acceleration (Fluent 2024 R1), load balancing, and practical speed optimization.
How DPM Parallelizes
Domain decomposition (mesh-based)
Fluent partitions the mesh across MPI ranks. Each rank tracks the parcels that are currently in its subdomain. When a parcel crosses a partition boundary, Fluent transfers particle data between ranks.
Parcel distribution (load-balanced)
By default, parcels are assigned to the rank that owns the cell where the parcel was injected. As parcels move, they are transferred between ranks. This can cause load imbalance if one rank has significantly more parcels than others.
MPI Parallel Setup
Launching parallel Fluent
# Linux/macOS
fluent 3d -t8 -mpi=intel -ssh
# Windows (from Fluent Launcher)
# Set "Number of Compute Processes" = 8
# Select MPI: Intel MPI (recommended) or Microsoft MPI
The -t8 flag launches 8 compute processes. Fluent also launches a host process (-tn-1 compute + 1 host).
DPM parallel settings
parallel/set/dpm-distribution method
> cell-based (parcels follow cell ownership -- default)
> load-balanced (rebalance parcels across ranks)
parallel/set/dpm-load-balance interval
> 10 (rebalance every 10 DPM iterations)
Load balancing
Without load balancing, if most parcels are injected near one wall (owned by Rank 0), Rank 0 handles 90% of the DPM work while other ranks are idle.
With load balancing, Fluent periodically redistributes parcels so each rank has a similar count. The cost: inter-rank communication to transfer parcel data.
| Scenario | Recommended |
| ---------- | ------------- |
| Uniform injection (surface injection over whole domain) | Cell-based is fine |
| Localized injection (point source near one partition) | Load-balanced |
| Many small injections spread across mesh | Cell-based is fine |
| DDPM or DEM (all parcels interact) | Load-balanced with frequent rebalancing |
Practical Speedup Guidelines
Expected parallel scaling
| Cores | Speedup (DPM-dominated) | Speedup (flow-dominated, 2M cells) |
| ------- | ------------------------- | ------------------------------------- |
| 1 | 1.0x | 1.0x |
| 4 | 3.5--4.0x | 3.0--3.5x |
| 8 | 6.5--7.5x | 5.0--6.5x |
| 16 | 12--14x | 8--11x |
| 32 | 20--25x | 12--18x |
| 64 | 30--40x | 18--28x |
| 128+ | Diminishing returns | Communication-dominated |
DPM scales better than the flow solver because parcel tracking is embarrassingly parallel. Beyond 64 cores, communication overhead dominates and scaling degrades.
Amdahl's law estimate
If DPM takes 80% of the total run time and flow takes 20%:
- DPM speedup with 16 cores = 14x
- Flow speedup with 16 cores = 10x
- Total speedup = =1 / (0.2/10 + 0.8/14) = 1 / (0.02 + 0.057) = 13x=
GPU Acceleration (Fluent 2024 R1)
Fluent 2024 R1 supports GPU-accelerated DPM for NVIDIA GPUs (compute capability \geq 7.0: V100, A100, RTX 30/40 series).
Enabling GPU DPM
# Launch Fluent with GPU
fluent 3d -t8 -gpu -gpu_node=0
# In Fluent:
parallel/gpu/set yes
solve/set/dpm-gpu yes
GPU acceleration scope
| Feature | GPU accelerated? |
| --------- | ----------------- |
| Particle force calculation | Yes |
| Particle position integration | Yes |
| DRW stochastic tracking | Yes |
| DPM source terms to flow | Yes (with limitations) |
| DPM sample file writing | No (CPU) |
| UDF execution | No (UDFs run on CPU) |
Limitations
- UDFs compiled for CPU cannot be used with GPU DPM (CUDA compilation required)
- Brownian force UDF must be rewritten in CUDA or run on CPU
- GPU memory limits the number of parcels that can be tracked simultaneously
Recommendation for shisha
If you have access to a GPU (A100 or better), GPU DPM can provide 5--20x speedup for the particle tracking portion. However, the Brownian UDF and DPM sample file operations still run on CPU, so the end-to-end speedup is typically 3--8x.
Mesh Partitioning for DPM
Partition methods
| Method | When to use |
| -------- | ------------- |
| metis | Default; good for most meshes |
| scotch | Alternative to metis; sometimes better load balance |
| zoltan | Advanced; supports dynamic repartitioning |
| manual | Specific needs (e.g., ensure injection surface on one rank) |
DPM-aware partitioning
parallel/partition/mesh/method metis
parallel/partition/mesh/quality (check partition quality)
parallel/partition/smooth (smooth partition boundaries)
For surface injection on a specific wall: ensure the wall is entirely within one partition to avoid parcel-transfer overhead at injection time.
Memory Optimization
Parcel memory footprint
Each tracked parcel consumes approximately:
| Component | Memory |
| ----------- | -------- |
| Position (3D) | 24 bytes |
| Velocity (3D) | 24 bytes |
| Diameter, mass, temperature | 24 bytes |
| Cell/thread pointers | 16 bytes |
| History data (if enabled) | 32+ bytes per step |
| Total per parcel | ~128 bytes (no history) |
100,000 parcels \approx 12.8 MB. 10 million parcels \approx 1.28 GB.
Tips to reduce memory
1. Disable trajectory recording unless needed 2. Reduce DPM history depth 3. Use fewer parcels with larger parcel mass (statistical convergence must still hold) 4. Delete parcels at walls as soon as they are trapped (don't keep data)
Profiling and Bottleneck Diagnosis
Built-in timer
solve/set/timer yes
report/system/timer
Fluent reports wall-clock time per iteration broken down by component:
- Flow solve
- DPM tracking
- DPM source calculation
- Data I/O
Identifying the bottleneck
| If timer shows... | Action |
| ------------------- | -------- |
| DPM tracking > 80% of time | Add cores; GPU acceleration; reduce parcel count |
| DPM source > 20% of time | Couple less frequently (every 5 iterations instead of every 1) |
| I/O > 10% of time | Reduce output frequency; write less data |
| Flow solve > 80% of time | Improve mesh; use AMG solver; reduce grid size |
Performance Checklist for Shisha Transient
For the anticipated transient shisha simulation:
- [ ] Launch with 8--16 cores (or GPU if available)
- [ ] Partition mesh so injection surface is on a single rank
- [ ] Use load-balanced DPM distribution (injection is localized)
- [ ] Set =\Delta t = 0.001= s, 1000 time steps = 1 second of simulation
- [ ] Disable trajectory recording (use sample files instead)
- [ ] Run Brownian UDF on CPU; GPU only if rewritten in CUDA
- [ ] Monitor wall-clock time per step to estimate total runtime
- [ ] Budget: 1 second of puff simulation \approx 2--8 hours on 8 cores