Skip to content
Back to skills

2583 Cfl Coupling 454e7618

ASecurity

Comprehensive guide for combining multiple stability constraints in time-dependent simulations.

  • 9 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 11, 2026
documentationpythongoreacttesting

Works with

  • cli

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 2583-cfl_coupling_454e7618 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 2583 Cfl Coupling 454e7618?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 2583 Cfl Coupling 454e7618
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-2583-cfl-coupling-454e7618/badge)](https://www.skillsdirectory.com/skills/tools-only-2583-cfl-coupling-454e7618)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# 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

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.