Skip to content

Commit c0792ec

Browse files
authored
Add Herschel-Bulkley non-Newtonian viscosity model (#1545)
1 parent 087c3ce commit c0792ec

62 files changed

Lines changed: 4986 additions & 104 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ MFC is a SPEChpc benchmark candidate, part of the JSC JUPITER Early Access Progr
148148
* Euler-Lagrange particle tracking
149149
* Quadrature-based moment methods (QBMM)
150150
* Viscous effects (high-order accurate representations)
151+
* Newtonian and non-Newtonian rheology (Herschel-Bulkley: power-law, Bingham, and yield-stress fluids)
151152
* Hypoelastic and hyperelastic material models
152153
* Ideal and stiffened gas equations of state
153154
* Body forces

docs/documentation/case.md

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1101,7 +1101,48 @@ This boundary condition can be used for fixed-temperature (isothermal) walls at
11011101

11021102

11031103

1104-
### 19. GPU Performance (NVIDIA UVM)
1104+
### 19. Non-Newtonian (Herschel-Bulkley) Viscosity {#sec-non-newtonian}
1105+
1106+
| Parameter | Type | Description |
1107+
| ---: | :----: | :--- |
1108+
| `fluid_pp(i)%%non_newtonian` | Logical | Enable Herschel-Bulkley non-Newtonian viscosity for fluid \f$i\f$. |
1109+
| `fluid_pp(i)%%K` | Real | Consistency index \f$K\f$. |
1110+
| `fluid_pp(i)%%nn` | Real | Flow index \f$n\f$ (\f$n<1\f$ shear-thinning, \f$n>1\f$ shear-thickening). |
1111+
| `fluid_pp(i)%%tau0` | Real | Yield stress \f$\tau_0\f$; set to 0 for pure power-law. |
1112+
| `fluid_pp(i)%%hb_m` | Real | Papanastasiou regularization parameter \f$m\f$; required when `tau0 > 0`. |
1113+
| `fluid_pp(i)%%mu_min` | Real | Lower viscosity clamp \f$\mu_{\min}\f$. |
1114+
| `fluid_pp(i)%%mu_max` | Real | Upper viscosity clamp \f$\mu_{\max}\f$ (required). |
1115+
| `fluid_pp(i)%%mu_bulk` | Real | Reserved; non-Newtonian bulk viscosity is not yet supported. The validator rejects it on a non-Newtonian fluid; on a Newtonian fluid it is accepted and ignored. |
1116+
1117+
The effective dynamic viscosity is computed from the Papanastasiou-regularized Herschel-Bulkley model:
1118+
1119+
\f[
1120+
\mu_{\rm eff}(\dot\gamma) = \frac{\tau_0}{\dot\gamma}\!\left(1 - e^{-m\,\dot\gamma}\right) + K\,\dot\gamma^{n-1},
1121+
\qquad
1122+
\dot\gamma = \sqrt{2\,D_{ij}D_{ij}},
1123+
\f]
1124+
1125+
where \f$D_{ij} = \frac{1}{2}(\partial_i u_j + \partial_j u_i)\f$ is the strain-rate tensor and \f$\dot\gamma\f$ is the scalar shear rate.
1126+
The result is clamped to \f$[\mu_{\min},\,\mu_{\max}]\f$.
1127+
1128+
Special cases:
1129+
1130+
- `tau0 = 0`: pure power-law fluid, \f$\mu_{\rm eff} = K\,\dot\gamma^{n-1}\f$.
1131+
- `tau0 = 0`, `nn = 1`: Newtonian fluid with constant viscosity \f$\mu = K\f$.
1132+
- `tau0 > 0`, `nn = 1`: Bingham plastic.
1133+
1134+
Usage notes:
1135+
1136+
- Requires `viscous = T`. `fluid_pp(i)%%Re(1)` must be set (use `1.0/K` to register the fluid as viscous; the HB model overrides \f$\mu_{\rm eff}\f$ cell-by-cell). `fluid_pp(i)%%Re(2)` (bulk viscosity) must not be set for a non-Newtonian fluid.
1137+
- `mu_max` is required; `mu_min` is inactive if omitted (no lower clamp applied).
1138+
- Positivity requirements: `K`, `nn`, and `mu_max` must be positive; `mu_min` and `hb_m` must be positive when set; `tau0` must be non-negative.
1139+
- Requires `model_eqns = 2` or `3` and is incompatible with `igr`.
1140+
- Supported only with `riemann_solver = 1` (HLL) or `riemann_solver = 2` (HLLC).
1141+
- The HB parameters (`K`, `nn`, `tau0`, `hb_m`, `mu_min`, `mu_max`, `mu_bulk`) may only be set on a fluid with `non_newtonian = T`; the validator rejects them otherwise.
1142+
- All HB parameters are non-dimensional (scaled by \f$\rho_{\rm ref} U_{\rm ref} L_{\rm ref}\f$), so \f$1/\mu_{\rm eff}\f$ equals the local effective Reynolds number.
1143+
- For cylindrical geometry (`cyl_coord = T`) the shear rate uses the grid-direction strain components; curvature corrections to \f$\dot\gamma\f$ are not yet included.
1144+
1145+
### 20. GPU Performance (NVIDIA UVM)
11051146

11061147
| Parameter | Type | Description |
11071148
| ---: | :---: | :--- |

docs/documentation/equations.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,14 @@ and similarly for all other components. Cylindrical coordinate formulations incl
387387

388388
Input parameters: `Re_inv` (shear and volume Reynolds numbers per fluid).
389389

390+
**Non-Newtonian viscosity (`fluid_pp(i)%%non_newtonian = .true.`):**
391+
392+
Per-fluid Herschel-Bulkley rheology with Papanastasiou regularization (\cite Papanastasiou87) replaces the constant viscosity with a shear-rate-dependent effective viscosity, recomputed from the local strain-rate tensor at every time step:
393+
394+
\f[\mu_{\rm eff}(\dot\gamma) = \frac{\tau_0}{\dot\gamma}\left(1 - e^{-m\,\dot\gamma}\right) + K\,\dot\gamma^{\,n-1}, \qquad \dot\gamma = \sqrt{2\,\mathbf{D}:\mathbf{D}}\f]
395+
396+
This covers power-law shear-thinning/thickening (\f$\tau_0 = 0\f$), Bingham plastic (\f$n = 1,\ \tau_0 > 0\f$), and general Herschel-Bulkley yield-stress fluids. The mixture rule above applies with \f$1/\text{Re}_j = \mu_{{\rm eff},j}\f$ evaluated at the local shear rate; Newtonian and non-Newtonian fluids can be mixed. Supported with the HLL and HLLC Riemann solvers, including immersed boundaries. See @ref sec-non-newtonian "the case documentation" for parameters, constraints, and validated example cases.
397+
390398
---
391399

392400
## 5. Cylindrical Coordinates (`cyl_coord = .true.`) (\cite Wilfong26 Sec. 2.3)

docs/module_categories.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"category": "Physics Models",
1616
"modules": [
1717
"m_viscous",
18+
"m_hb_function",
1819
"m_surface_tension",
1920
"m_bubbles",
2021
"m_bubbles_EE",

docs/references.bib

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,3 +659,14 @@ @article{Xu2019
659659
year = {2019},
660660
doi = {10.1063/1.5116374}
661661
}
662+
663+
@article{Papanastasiou87,
664+
author = {Papanastasiou, Tasos C.},
665+
title = {Flows of Materials with Yield},
666+
journal = {Journal of Rheology},
667+
volume = {31},
668+
number = {5},
669+
pages = {385--404},
670+
year = {1987},
671+
doi = {10.1122/1.549926}
672+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# 2D Bingham (Yield-Stress) Poiseuille Channel
2+
3+
Validates the **yield-stress term** of MFC's Herschel-Bulkley non-Newtonian
4+
viscosity against a closed-form analytic Poiseuille profile. Demonstrates the
5+
Bingham regime (`nn = 1`, `tau0 > 0`): a rigid **plug** of uniform velocity forms
6+
near the centerline, where the shear stress falls below the yield stress.
7+
8+
## Regime and parameters
9+
10+
Single Papanastasiou-regularized Herschel-Bulkley fluid with unit flow index, so
11+
`K = mu` is a plain Newtonian consistency and the only non-Newtonian effect is the
12+
yield stress:
13+
14+
| Parameter | Value | Role |
15+
|-----------|-------|------|
16+
| `fluid_pp(1)%K` | `5.0e-2` | `n = 1` -> plain dynamic viscosity `mu` |
17+
| `fluid_pp(1)%nn` | `1.0` | flow index = 1 (Bingham, no power-law) |
18+
| `fluid_pp(1)%tau0`| `4.0e-3` | yield stress -> plug half-width `y0 = 0.4 H` |
19+
| `fluid_pp(1)%hb_m`| `1.0e4` | sharp Papanastasiou yield regularization |
20+
| `fluid_pp(1)%mu_min`/`mu_max` | `1e-6` / `1.0` | viscosity clamp (rigid plug) |
21+
22+
Driven by `g_x = 0.1`, `rho = 1`, `pres = 10`, giving `tau_w = rho*g*H = 1e-2`,
23+
`u_plug ~ 3.6e-3` and Mach ~1e-3. Channel `L_y = 0.2`, `H = 0.1`, no-slip walls,
24+
periodic in `x`.
25+
26+
## Governing physics and analytic solution
27+
28+
The shear stress is `tau = rho*g*(H - y)`; the fluid only flows where `|tau| > tau0`.
29+
With `n = 1`, `K = mu`, `tau_w = rho*g*H > tau0`:
30+
31+
plug half-width : y0 = tau0/(rho*g)
32+
sheared region : u(y) = (1/(2*mu*rho*g)) *
33+
[ (tau_w - tau0)^2 - (rho*g*(H-y) - tau0)^2 ] (|y-H| >= y0)
34+
plug : u_plug = (1/(2*mu*rho*g)) * (tau_w - tau0)^2 (|y-H| < y0)
35+
36+
The signature of a correct yield term is the flat plug of uniform velocity within
37+
`|y - H| < y0`. Requires `tau_w > tau0` for any flow.
38+
39+
## How to run
40+
41+
./mfc.sh run examples/2D_bingham_poiseuille_nn/case.py -n 2
42+
python examples/2D_bingham_poiseuille_nn/compare_analytic.py
43+
44+
## Validation result
45+
46+
Relative L2 error vs. the analytic Bingham profile: **2.5%** (2-rank run, steady
47+
state confirmed). A plug forms at the centerline with half-width matching the
48+
analytic `y0 = tau0/(rho*g) = 0.4 H`.
49+
50+
## References
51+
52+
- Papanastasiou, T. C. (1987). Flows of materials with yield. *J. Rheol.* 31, 385.
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#!/usr/bin/env python3
2+
"""
3+
2D Bingham (Herschel-Bulkley with flow index n = 1, yield stress tau0 > 0)
4+
Poiseuille channel.
5+
6+
Validation case for the YIELD-STRESS term of the non-Newtonian (Herschel-Bulkley)
7+
viscosity. The companion examples/2D_poiseuille_nn validates the power-law term
8+
(tau0 = 0); this case isolates the yield term by fixing n = 1 (so K = mu is a plain
9+
Newtonian consistency) and turning on tau0 > 0. The signature of a correct yield
10+
term is a rigid PLUG of uniform velocity near the centerline, where the shear
11+
stress |tau| = rho*g*(H - y) drops below tau0 and the fluid stops yielding.
12+
13+
A constant body acceleration g_x drives a fully-developed channel flow between two
14+
stationary no-slip walls (y = 0, L_y; half-height H = L_y/2, centerline y = H).
15+
The steady Bingham profile (n = 1, K = mu, tau_w = rho*g*H):
16+
17+
plug half-width from centerline : y0 = tau0/(rho*g)
18+
sheared region (0 <= y <= H - y0) : u(y) = (1/(2*mu*rho*g)) *
19+
[ (tau_w - tau0)^2 - (rho*g*(H-y) - tau0)^2 ]
20+
plug (H - y0 <= y <= H) : u_plug = (1/(2*mu*rho*g)) * (tau_w - tau0)^2
21+
upper half mirrors about y = H.
22+
23+
Requires tau_w = rho*g*H > tau0 for any flow.
24+
25+
Parameters (nondimensional MFC units):
26+
rho = 1.0, H = 0.1 (L_y = 0.2)
27+
g_x = 0.1 -> tau_w = rho*g*H = 1.0e-2
28+
tau0 = 4.0e-3 -> y0 = tau0/(rho*g) = 4.0e-2 = 0.4 H (clear plug + shear)
29+
K = mu = 5.0e-2 (n = 1 Bingham consistency; short diffusive time t_d = H^2 rho/mu = 0.2)
30+
hb_m = 1.0e4 (sharp Papanastasiou yield; uncapped plug mu = tau0*hb_m = 40)
31+
mu_min = 1e-6, mu_max = 1.0 (plug viscosity = 20*K, effectively rigid plug;
32+
kept modest because the explicit viscous timestep scales as 1/mu_max)
33+
pres = 10 -> sound speed ~3.74; u_plug ~ 3.6e-3 => Mach ~1e-3 (low Mach)
34+
grid: m = 24 (x, periodic; >= 24 for a 2-rank y-split WENO5 decomposition),
35+
n = 63 (y resolution of the plug; the viscous CFL dt ~ dy^2 rho/mu_max
36+
makes a finer grid prohibitively slow for an explicit solver), L_x = L_y = 0.2
37+
cfl_adap_dt, cfl_target = 0.3, t_stop = 1.5 (~7.5 diffusive times t_d = 0.2)
38+
39+
Compare with compare_analytic.py.
40+
"""
41+
42+
import json
43+
44+
# Channel / fluid parameters
45+
L_x = 0.2
46+
L_y = 0.2
47+
rho = 1.0
48+
pres = 10.0
49+
K = 5.0e-2 # n = 1 -> K is the plain dynamic viscosity mu
50+
nn = 1.0
51+
tau0 = 4.0e-3
52+
g_x = 0.1
53+
54+
# Configuring case dictionary
55+
print(
56+
json.dumps(
57+
{
58+
# Logistics
59+
"run_time_info": "T",
60+
# Computational Domain Parameters
61+
"x_domain%beg": 0.0,
62+
"x_domain%end": L_x,
63+
"y_domain%beg": 0.0,
64+
"y_domain%end": L_y,
65+
"m": 24,
66+
"n": 63,
67+
"p": 0,
68+
"cfl_adap_dt": "T",
69+
"cfl_target": 0.3,
70+
"n_start": 0,
71+
"t_save": 0.15,
72+
"t_stop": 1.5,
73+
# Simulation Algorithm Parameters
74+
"num_patches": 1,
75+
"model_eqns": 2,
76+
"alt_soundspeed": "F",
77+
"num_fluids": 1,
78+
"mpp_lim": "F",
79+
"mixture_err": "T",
80+
"time_stepper": 3,
81+
"weno_order": 5,
82+
"weno_eps": 1e-16,
83+
"mapped_weno": "T",
84+
"weno_Re_flux": "T",
85+
"mp_weno": "T",
86+
"weno_avg": "T",
87+
"riemann_solver": 2,
88+
"wave_speeds": 1,
89+
"avg_state": 2,
90+
# x: periodic channel; y: stationary no-slip walls
91+
"bc_x%beg": -1,
92+
"bc_x%end": -1,
93+
"bc_y%beg": -16,
94+
"bc_y%end": -16,
95+
"viscous": "T",
96+
# Constant body acceleration in +x: accel = g_x + k_x*sin(w_x*t - p_x)
97+
"bf_x": "T",
98+
"g_x": g_x,
99+
"k_x": 0.0,
100+
"w_x": 0.0,
101+
"p_x": 0.0,
102+
# Formatted Database Files Structure Parameters
103+
"format": 1,
104+
"precision": 2,
105+
"prim_vars_wrt": "T",
106+
"fd_order": 4,
107+
"parallel_io": "T",
108+
# Patch 1: full domain, quiescent
109+
"patch_icpp(1)%geometry": 3,
110+
"patch_icpp(1)%x_centroid": 0.5 * L_x,
111+
"patch_icpp(1)%y_centroid": 0.5 * L_y,
112+
"patch_icpp(1)%length_x": L_x,
113+
"patch_icpp(1)%length_y": L_y,
114+
"patch_icpp(1)%vel(1)": 0.0,
115+
"patch_icpp(1)%vel(2)": 0.0,
116+
"patch_icpp(1)%pres": pres,
117+
"patch_icpp(1)%alpha_rho(1)": rho,
118+
"patch_icpp(1)%alpha(1)": 1.0,
119+
# Fluids Physical Parameters: single Bingham (HB with n = 1, tau0 > 0) fluid
120+
"fluid_pp(1)%gamma": 1.0 / (1.4 - 1.0),
121+
"fluid_pp(1)%pi_inf": 0.0,
122+
"fluid_pp(1)%Re(1)": 1.0 / K,
123+
"fluid_pp(1)%non_newtonian": "T",
124+
"fluid_pp(1)%K": K,
125+
"fluid_pp(1)%nn": nn,
126+
"fluid_pp(1)%tau0": tau0,
127+
"fluid_pp(1)%hb_m": 1.0e4,
128+
"fluid_pp(1)%mu_min": 1e-6,
129+
"fluid_pp(1)%mu_max": 1.0,
130+
}
131+
)
132+
)

0 commit comments

Comments
 (0)