Back to skills
SKILL.md
2583 Cfl Coupling 454e7618
ASecurityComprehensive guide for combining multiple stability constraints in time-dependent simulations.
- 9 stars
- 0 votes
- 0 copies
- 1 view
- Added October 11, 2026
Works with
Security analysis
100/100npx -y skills add tools-only/X-Skills --skill 2583-cfl_coupling_454e7618 --agent claude-codeAre you the author of 2583 Cfl Coupling 454e7618?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/tools-only-2583-cfl-coupling-454e7618)# CFL Coupling and Limits
Comprehensive guide for combining multiple stability constraints in time-dependent simulations.
## Fundamental Stability Limits
### Advection (CFL) Limit
For advection equation: ∂u/∂t + v·∇u = 0
```
dt_adv ≤ C_adv × dx / |v_max|
C_adv depends on scheme:
- First-order upwind: C_adv = 1.0
- Second-order central: C_adv = 1.0 (with proper time stepping)
- Third-order upwind: C_adv ≈ 0.87
- Fourth-order central: C_adv ≈ 0.72
- WENO5: C_adv ≈ 0.5-1.0 (depends on smoothness)
```
### Diffusion (Fourier) Limit
For diffusion equation: ∂u/∂t = D∇²u
```
dt_diff ≤ C_diff × dx² / D
In 1D: C_diff = 0.5 (explicit Euler)
In 2D: C_diff = 0.25 (explicit Euler)
In 3D: C_diff = 0.167 (explicit Euler)
Higher-order time stepping:
- RK4: C_diff up to ~2.8/dim
- DuFort-Frankel: unconditionally stable
- Implicit: no limit (but accuracy limits apply)
```
### Reaction Limit
For stiff reactions: du/dt = R(u)
```
dt_react ≤ C_react / |λ_max|
Where λ_max is the largest eigenvalue of the reaction Jacobian.
For simple cases:
- First-order kinetics: λ = k (rate constant)
- Combustion: λ can be 10⁶ - 10¹² (very stiff!)
```
### Acoustic/Pressure Wave Limit
For compressible flow:
```
dt_acoustic ≤ dx / c
Where c = sound speed = sqrt(γP/ρ) or sqrt(K/ρ)
```
## Combining Multiple Limits
### Minimum Rule
The most conservative approach:
```
dt_limit = min(dt_adv, dt_diff, dt_react, dt_acoustic, ...)
dt = safety × dt_limit
```
**Safety factor:**
| Situation | Safety |
|-----------|--------|
| Conservative | 0.5 |
| Normal | 0.8 |
| Aggressive | 0.95 |
| Testing | 0.99 |
### Harmonic Mean (Less Conservative)
For coupled physics where limits interact:
```
1/dt_limit = 1/dt_adv + 1/dt_diff
Equivalent to: dt_limit = (dt_adv × dt_diff) / (dt_adv + dt_diff)
```
### Dimensional Coupling
In 2D/3D with different grid spacings:
```
1/dt_adv = |v_x|/dx + |v_y|/dy + |v_z|/dz
1/dt_diff = D × (1/dx² + 1/dy² + 1/dz²)
```
## Specific Physics Cases
### Advection-Diffusion
```
∂u/∂t + v·∇u = D∇²u
Two limits apply:
- CFL: dt ≤ dx / |v|
- Fourier: dt ≤ dx² / (2D)
Peclet number: Pe = |v| × L / D
- Pe >> 1: advection-dominated, CFL limits
- Pe << 1: diffusion-dominated, Fourier limits
- Pe ~ 1: both matter, use minimum
```
### Phase-Field with Diffusion
```
Allen-Cahn: ∂φ/∂t = M(ε²∇²φ - f'(φ))
Diffusion limit: dt ≤ dx² / (2Mε²)
Reaction limit: dt ≤ 1 / (M × max|f''(φ)|)
Interface width: W ~ ε
Resolution: dx ≤ W/3 for 3 points in interface
```
### Navier-Stokes (Incompressible)
```
Advection: dt_adv ≤ dx / |u_max|
Viscous: dt_visc ≤ dx² / (2ν)
Re = |u|L/ν
- High Re: dt_adv dominates
- Low Re: dt_visc may dominate (unusual for simulations)
```
### Elastodynamics
```
Wave speed: c = sqrt(E/ρ) or sqrt((λ+2μ)/ρ)
CFL: dt ≤ dx / c
For explicit schemes, this is typically the limiting factor.
```
## Practical Computation
### Algorithm for dt Selection
```python
def compute_dt_limit(physics_params, grid):
"""Compute stable time step from all constraints."""
limits = []
# Advection
if 'velocity' in physics_params:
v_max = np.max(np.abs(physics_params['velocity']))
dx_min = grid.min_spacing()
dt_adv = 0.8 * dx_min / v_max
limits.append(('advection', dt_adv))
# Diffusion
if 'diffusivity' in physics_params:
D = physics_params['diffusivity']
dx_min = grid.min_spacing()
dim = grid.dimension
dt_diff = 0.4 * dx_min**2 / (dim * D)
limits.append(('diffusion', dt_diff))
# Reaction
if 'reaction_rate' in physics_params:
k_max = physics_params['reaction_rate']
dt_react = 0.5 / k_max
limits.append(('reaction', dt_react))
# Find limiting constraint
dt_limit = min(dt for name, dt in limits)
limiting = [name for name, dt in limits if dt == dt_limit][0]
return dt_limit, limiting, limits
```
### Adaptive Recomputation
When to recompute dt:
| Event | Recompute? | Reason |
|-------|------------|--------|
| Start of simulation | Yes | Initial conditions |
| Each time step | Optional | If parameters change |
| Mesh refinement | Yes | dx changed |
| Material change | Yes | D, k changed |
| Large velocity change | Yes | CFL may change |
### Anisotropic Meshes
For grids with dx ≠ dy ≠ dz:
```
CFL (advection):
dt_adv ≤ 1 / (|v_x|/dx + |v_y|/dy + |v_z|/dz)
Fourier (diffusion):
dt_diff ≤ 0.5 / (D × (1/dx² + 1/dy² + 1/dz²))
```
**Critical:** Use the smallest spacing, not the average!
## Special Situations
### Locally Varying Properties
When D, v, or k vary in space:
```
Use maximum over all cells:
v_max = max over cells of |v(x)|
D_max = max over cells of D(x)
```
Or use local time stepping (more advanced).
### Implicit-Explicit (IMEX) Methods
When some terms are implicit:
```
Explicit part: CFL limit applies
Implicit part: No stability limit
Example (advection-diffusion):
- Implicit diffusion: removes dt_diff constraint
- Explicit advection: CFL still applies
dt ≤ dx / |v| (only advection matters)
```
### Adaptive Mesh Refinement (AMR)
With multiple mesh levels:
```
Level 0: dx_0, dt_0 (coarse)
Level 1: dx_1 = dx_0/2, dt_1 = dt_0/2
Level 2: dx_2 = dx_0/4, dt_2 = dt_0/4
...
Subcycling: Fine levels take multiple steps per coarse step.
```
## Common Pitfalls
### Pitfall 1: Forgetting a Limit
```
Problem: Only checked CFL, forgot Fourier limit
Result: Instability when diffusion dominates
Fix: Always compute ALL relevant limits
```
### Pitfall 2: Using Average Instead of Minimum
```
Problem: dt = (dt_adv + dt_diff) / 2
Result: Too large dt, instability
Fix: dt = min(dt_adv, dt_diff)
```
### Pitfall 3: Ignoring Anisotropy
```
Problem: Used dx_avg instead of min(dx, dy, dz)
Result: dt too large in refined direction
Fix: Use minimum spacing in each limit formula
```
### Pitfall 4: Not Recomputing After Changes
```
Problem: Fixed dt throughout simulation
Result: Instability when parameters change
Fix: Recompute dt when physics changes significantly
```
## Diagnostics and Monitoring
### Courant Number Monitoring
```
C = v × dt / dx
Should be: C ≤ C_max (typically ~0.5-0.9)
If C > 1: Likely unstable
If C << 0.1: Inefficient, could use larger dt
```
### Fourier Number Monitoring
```
F = D × dt / dx²
Should be: F ≤ F_max (typically ~0.25-0.5 in 2D)
If F > 0.5/dim: Likely unstable (explicit)
If F << 0.01: Very conservative, check if needed
```
### Stability Margin
```
margin = dt_limit / dt_used
Healthy: margin ≥ 1.1 (10% safety)
Warning: margin = 1.0-1.1 (borderline)
Danger: margin < 1.0 (unstable!)
```
## Quick Reference
### Common Limits Table
| Physics | Limit Formula | Typical C |
|---------|---------------|-----------|
| Advection | C × dx / v | 0.5-0.9 |
| Diffusion (1D) | C × dx² / D | 0.5 |
| Diffusion (2D) | C × dx² / D | 0.25 |
| Diffusion (3D) | C × dx² / D | 0.167 |
| Sound waves | dx / c | 0.9 |
| Stiff reaction | 1 / λ_max | 0.1-0.5 |
| Phase-field | dx² / (Mε²) | 0.1-0.25 |
### Combined Example
```
Problem: 2D advection-diffusion with reaction
v = 1.0 m/s, D = 0.01 m²/s, k = 100 /s
dx = 0.01 m
dt_adv = 0.8 × 0.01 / 1.0 = 0.008 s
dt_diff = 0.25 × 0.01² / 0.01 = 0.0025 s
dt_react = 0.5 / 100 = 0.005 s
dt_limit = min(0.008, 0.0025, 0.005) = 0.0025 s
Limiting factor: diffusion
```
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.