Skip to content

Commit aed0d74

Browse files
wilfonbasbryngelsonTempanandrdbz
authored
Moving EL Bubbles with MPI Decomposition (#1290)
Co-authored-by: Spencer Bryngelson <sbryngelson@gmail.com> Co-authored-by: Temp <temp@Temps-MacBook-Air.local> Co-authored-by: anandrdbz <62814442+anandrdbz@users.noreply.github.com>
1 parent db240d6 commit aed0d74

117 files changed

Lines changed: 9735 additions & 3043 deletions

File tree

Some content is hidden

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

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,7 @@ examples/*/workloads/
7777
examples/*/run-*/
7878
examples/*/logs/
7979
examples/**/*.f90
80-
!examples/3D_lag_bubbles_shbubcollapse/input/lag_bubbles.dat
81-
!examples/3D_lag_bubbles_bubblescreen/input/lag_bubbles.dat
80+
examples/**/*.csv
8281
workloads/
8382

8483
benchmarks/*batch/*/

docs/documentation/case.md

Lines changed: 58 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,22 @@ Setup: Only requires specifying `files_dir` and filename pattern via `file_exten
276276
Implementation: All variables and file handling are managed in the `case.py` file of the simulation.
277277
Usage: Ideal for initializing simulations from lower-dimensional solutions, enabling users to add perturbations or modifications to the base extruded fields for flow instability studies.
278278

279+
The following parameters support hardcoded initial conditions that read interface data from files:
280+
281+
| Parameter | Type | Description |
282+
| ---: | :---: | :--- |
283+
| `interface_file` | String | Path to interface geometry data file |
284+
| `normFac` | Real | Interface normalization factor |
285+
| `normMag` | Real | Interface normal magnitude |
286+
| `g0_ic` | Real | Gravitational acceleration for the interfacial IC pressure field |
287+
| `p0_ic` | Real | Reference pressure at the interface |
288+
289+
These parameters are only read by the file-based hardcoded-IC patches (`hcid = 304` and `305` in `src/common/include/3dHardcodedIC.fpp`); they are ignored otherwise.
290+
291+
- `interface_file` gives the path to a text file that supplies the interface-position field \f$h(i,j)\f$ used to place the material interface. The run aborts if the file is not found.
292+
- `normMag` and `normFac` rescale and offset the raw interface data, \f$h \leftarrow \texttt{normMag}\,h + \texttt{normFac}\f$. Each is applied only when set (defaults leave the data unchanged).
293+
- `p0_ic` and `g0_ic` set the initial (hydrostatic) pressure field about the interface, \f$p = p_{0} + \rho\, g_{0}\,\big(h - x\big)\f$, where \f$x\f$ is the coordinate normal to the interface.
294+
279295
#### Parameter Descriptions
280296

281297
- `num_patches` defines the total number of patches defined in the domain.
@@ -930,23 +946,33 @@ When ``polytropic = 'F'``, the gas compression is modeled as non-polytropic due
930946

931947
#### 9.2 Volume-Averaged Bubble Model
932948

933-
| Parameter | Type | Description |
934-
| ---: | :---: | :--- |
935-
| `bubbles_lagrange` | Logical | Lagrangian subgrid bubble model switch |
936-
| `nBubs_glb` | Integer | Global number of bubbles |
937-
| `solver_approach` | Integer | 1: One-way coupling, 2: two-way coupling |
938-
| `cluster_type` | Integer | Method to find p_inf |
939-
| `pressure_corrector` | Logical | Cell pressure correction term |
940-
| `smooth_type` | Integer | Smoothing function. 1: Gaussian, 2:Delta 3x3 |
941-
| `heatTransfer_model` | Logical | Activates the interface heat transfer model |
942-
| `massTransfer_model` | Logical | Activates the interface mass transfer model |
943-
| `write_bubbles` | Logical | Write files to track the bubble evolution each time step |
944-
| `write_bubbles_stats` | Logical | Write the maximum and minimum radius of each bubble |
945-
| `epsilonb` | Real | Standard deviation scaling for the gaussian function |
946-
| `charwidth` | Real | Domain virtual depth (z direction, for 2D simulations) |
947-
| `valmaxvoid` | Real | Maximum void fraction permitted |
948-
949-
- `nBubs_glb` Total number of bubbles. Their initial conditions need to be specified in the ./input/lag_bubbles.dat file. See the example cases for additional information.
949+
| Parameter | Type | Description |
950+
| ---: | :---: | :--- |
951+
| `bubbles_lagrange` | Logical | Lagrangian subgrid bubble model switch |
952+
| `nBubs_glb` | Integer | Global number of bubbles |
953+
| `solver_approach` | Integer | 1: One-way coupling, 2: two-way coupling |
954+
| `cluster_type` | Integer | Method to find p_inf |
955+
| `pressure_corrector` | Logical | Cell pressure correction term |
956+
| `smooth_type` | Integer | Smoothing function. 1: Gaussian, 2:Delta 3x3 |
957+
| `heatTransfer_model` | Logical | Activates the interface heat transfer model |
958+
| `massTransfer_model` | Logical | Activates the interface mass transfer model |
959+
| `write_bubbles` | Logical | Write files to track the bubble evolution each time step |
960+
| `write_bubbles_stats` | Logical | Write the maximum and minimum radius of each bubble |
961+
| `write_void_evol` | Logical | Write stats about the void fraction evolution over time |
962+
| `epsilonb` | Real | Standard deviation scaling for the gaussian function |
963+
| `charwidth` | Real | Domain virtual depth (z direction, for 2D simulations) |
964+
| `charNz` | Integer | Number of cells in the virtual depth direction |
965+
| `valmaxvoid` | Real | Maximum void fraction permitted |
966+
| `vel_model` | Integer | Model for translational motion (default 0, disabled) |
967+
| `drag_model` | Integer | Model for drag force (default 0, disabled) |
968+
| `gravity_force` | Logical | Enable gravity force (default false) |
969+
| `pressure_force` | Logical | Enable pressure force (default true) |
970+
| `input_path` | String | Path to bubble input file (default: `./input/lag_bubbles.dat`) |
971+
| `kahan_summation` | Logical | Use Kahan compensated summation when accumulating the void fraction |
972+
973+
- `nBubs_glb` Total number of bubbles. Their initial conditions are read from the file given by `input_path`.
974+
975+
- `input_path` Path to the bubble input file (default `./input/lag_bubbles.dat`). Each row specifies the initial state of one bubble, with columns `xPosition/x0 yPosition/x0 zPosition/x0 xVel/c0 yVel/c0 zVel/c0 radius/x0 interfaceVelocity/c0`. See `examples/3D_lagrange_shbubcollapse/input/lag_bubbles.dat` for a checked-in example, or the other Lagrange example cases (e.g. `examples/2D_lagrange_bubblescreen/case.py`), which generate this file programmatically.
950976

951977
- `solver_approach` Specifies the Euler-Lagrange coupling method: [1] enables a one-way coupling approach, where the bubbles do not influence the Eulerian field. [2] activates the two-way coupling approach based on \cite Maeda18, where the effect of the bubbles is added in the Eulerian field as source terms.
952978

@@ -958,6 +984,14 @@ When ``polytropic = 'F'``, the gas compression is modeled as non-polytropic due
958984

959985
- `massTransfer_model` Activates the mass transfer model at the bubble's interface based on (\cite Preston07).
960986

987+
- `vel_model` activates translational motion of the bubbles (\cite Wilfong26): [1] tracer bubbles, which are advected with the local carrier velocity \f$\underline{u}\f$ so that \f$\dot{\underline{x}}_b = \underline{u}(\underline{x}_b)\f$; [2] Newton's second law, which integrates \f$m_b \ddot{\underline{x}}_b = \underline{F}_D + \underline{F}_p + \underline{F}_g\f$, where \f$m_b\f$ is the bubble mass and the right-hand side collects the drag, pressure, and gravity forces below. The carrier velocity at the bubble is interpolated with a Lagrange polynomial of order set by `fd_order`, which must be specified when `vel_model > 0`.
988+
989+
- `drag_model` selects the drag force \f$\underline{F}_D\f$ acting on the slip velocity \f$\underline{u}_{\rm rel} = \underline{u}_b - \underline{u}\f$, with bubble radius \f$a\f$ and Reynolds number \f$Re\f$: [0] no drag (default); [1] free-slip drag (clean-interface creeping-flow limit, \cite Hadamard1911, \cite Rybczynski1911), \f$\underline{F}_D = -4\pi a\,\underline{u}_{\rm rel}/Re\f$; [2] no-slip Stokes drag (rigid sphere, \cite Stokes1851), \f$\underline{F}_D = -6\pi a\,\underline{u}_{\rm rel}/Re\f$; [3] Levich drag (clean bubble at high \f$Re\f$, \cite Levich1962), \f$\underline{F}_D = -12\pi a\,\underline{u}_{\rm rel}/Re\f$. See \cite Magnaudet2000 for a review of these bubble-drag regimes.
990+
- `pressure_force` (default true) enables the pressure-gradient force \f$\underline{F}_p = -V_b\,\nabla p\f$, where \f$V_b = \frac{4}{3}\pi a^3\f$ is the bubble volume.
991+
- `gravity_force` (default false) enables the body force \f$\underline{F}_g = m_b\,\underline{g}\f$, with \f$\underline{g}\f$ the acceleration set by the body-force parameters.
992+
993+
- `kahan_summation` uses Kahan compensated summation when smearing the bubble contributions onto the Eulerian void fraction, reducing the round-off sensitivity of the accumulation to the summation order. It is not compatible with `--mixed` precision builds.
994+
961995
### 10. Velocity Field Setup {#sec-velocity-field-setup}
962996

963997
| Parameter | Type | Description |
@@ -1286,14 +1320,14 @@ Boundary is at polar angle \f$\theta = \mathrm{atan2}(y - y_{\mathrm{centroid}},
12861320

12871321
### Immersed Boundary Patch Types {#immersed-boundary-patch-types}
12881322

1289-
| # | Name | Dim. |
1290-
| ---: | :----: | :--- |
1291-
| 2 | 2D Circle | 2 |
1292-
| 3 | 2D Rectangle | 2 |
1293-
| 4 | 2D Airfoil | 2 |
1294-
| 8 | 3D Sphere | 3 |
1323+
| # | Name | Dim. | Notes |
1324+
| ---: | :----: | :---: | :--- |
1325+
| 2 | 2D Circle | 2 | |
1326+
| 3 | 2D Rectangle | 2 | |
1327+
| 4 | 2D Airfoil | 2 | |
1328+
| 8 | 3D Sphere | 3 | |
12951329
| 10 | 3D Cylinder | 3 | `length_x` sets the axial length of the cylinder. |
1296-
| 11 | 3D Airfoil | 3 |
1330+
| 11 | 3D Airfoil | 3 | |
12971331

12981332
### Acoustic Supports {#acoustic-supports}
12991333

docs/documentation/equations.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,25 @@ with \f$\sigma = \varepsilon_b \max(\Delta x^{1/3}_\text{cell},\;R_\text{bubble}
522522

523523
Each bubble is tracked individually with Keller-Miksis dynamics and 4th-order adaptive Runge-Kutta time integration.
524524

525+
**Translational motion (`vel_model > 0`):**
526+
527+
Bubbles may also translate through the carrier flow. Let \f$\mathbf{x}_b\f$ be the bubble position, \f$\mathbf{u}_b\f$ its velocity, \f$a\f$ its radius, and \f$\mathbf{u}_l(\mathbf{x}_b)\f$ the carrier velocity interpolated to the bubble location (a Lagrange polynomial of order `fd_order`, which must be set when `vel_model > 0`).
528+
529+
- **Tracer bubbles (`vel_model = 1`)** follow the local carrier velocity:
530+
\f[\frac{d\mathbf{x}_b}{dt} = \mathbf{u}_l(\mathbf{x}_b).\f]
531+
532+
- **Newton's second law (`vel_model = 2`)** integrates the bubble momentum:
533+
\f[m_b\,\frac{d\mathbf{u}_b}{dt} = \mathbf{F}_D + \mathbf{F}_p + \mathbf{F}_g, \qquad \frac{d\mathbf{x}_b}{dt} = \mathbf{u}_b,\f]
534+
with bubble mass \f$m_b\f$ and forces acting on the slip velocity \f$\mathbf{u}_\text{rel} = \mathbf{u}_b - \mathbf{u}_l\f$:
535+
536+
| Force | `case.py` control | Non-dimensional form |
537+
|---|---|---|
538+
| Drag \f$\mathbf{F}_D\f$ | `drag_model` | \f$-\,c_D\,\pi\,a\,\mathbf{u}_\text{rel} / \text{Re}\f$, with \f$c_D = 4\f$ free-slip (\cite Hadamard1911; \cite Rybczynski1911), \f$c_D = 6\f$ no-slip Stokes (\cite Stokes1851), \f$c_D = 12\f$ Levich (\cite Levich1962) |
539+
| Pressure \f$\mathbf{F}_p\f$ | `pressure_force` | \f$-V_b\,\nabla p\f$, with bubble volume \f$V_b = \frac{4}{3}\pi a^3\f$ |
540+
| Gravity \f$\mathbf{F}_g\f$ | `gravity_force` | \f$m_b\,\mathbf{g}\f$, with \f$\mathbf{g}\f$ the body-force acceleration |
541+
542+
Here \f$\text{Re}\f$ is the mixture Reynolds number — the same `fluid_pp%%Re(1)` that scales the viscous stress tensor (@ref sec-two-viscosities) — so the drag scales with the liquid viscosity. The three drag models increase in magnitude free-slip \f$<\f$ no-slip \f$<\f$ Levich; see \cite Magnaudet2000 for a review of these bubble-drag regimes.
543+
525544
---
526545

527546
## 7. Fluid-Structure Interaction

docs/references.bib

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,3 +670,47 @@ @article{Papanastasiou87
670670
year = {1987},
671671
doi = {10.1122/1.549926}
672672
}
673+
674+
@article{Stokes1851,
675+
author = {G. G. Stokes},
676+
title = {On the effect of the internal friction of fluids on the motion of pendulums},
677+
journal = {Transactions of the Cambridge Philosophical Society},
678+
volume = {9},
679+
pages = {8--106},
680+
year = {1851}
681+
}
682+
683+
@article{Hadamard1911,
684+
author = {J. Hadamard},
685+
title = {Mouvement permanent lent d'une sph{\`e}re liquide et visqueuse dans un liquide visqueux},
686+
journal = {Comptes Rendus de l'Acad{\'e}mie des Sciences},
687+
volume = {152},
688+
pages = {1735--1738},
689+
year = {1911}
690+
}
691+
692+
@article{Rybczynski1911,
693+
author = {W. Rybczynski},
694+
title = {{\"U}ber die fortschreitende Bewegung einer fl{\"u}ssigen Kugel in einem z{\"a}hen Medium},
695+
journal = {Bulletin International de l'Acad{\'e}mie des Sciences de Cracovie, S{\'e}rie A},
696+
pages = {40--46},
697+
year = {1911}
698+
}
699+
700+
@book{Levich1962,
701+
author = {V. G. Levich},
702+
title = {Physicochemical Hydrodynamics},
703+
publisher = {Prentice-Hall},
704+
address = {Englewood Cliffs, NJ},
705+
year = {1962}
706+
}
707+
708+
@article{Magnaudet2000,
709+
author = {J. Magnaudet and I. Eames},
710+
title = {The motion of high-{R}eynolds-number bubbles in inhomogeneous flows},
711+
journal = {Annual Review of Fluid Mechanics},
712+
volume = {32},
713+
pages = {659--708},
714+
year = {2000},
715+
doi = {10.1146/annurev.fluid.32.1.659}
716+
}

examples/2D_lagrange_bubblescreen/case.py

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#!/usr/bin/env python3
22
import json
33
import math
4+
import os
5+
import random
46

57
# Bubble screen
68
# Description: A planar acoustic wave interacts with a bubble cloud
@@ -56,6 +58,75 @@
5658

5759
dt = 7.5e-9 # constant time-step - sec
5860

61+
62+
def generate_bubble_cloud():
63+
"""Generate bubble cloud with log-normal size distribution"""
64+
# Bubble properties
65+
void_fraction = 4e-5
66+
mean_radius = 10e-6 # 10 μm in meters
67+
shape_param = 0.3 # shape parameter for log-normal distribution
68+
69+
# Domain: 5mm x 5mm x 5mm cube centered at origin
70+
box_size = 5.0e-3 # 5 mm in meters
71+
72+
# Convert to nondimensional units
73+
mean_radius_nd = mean_radius / x0 # in units of x0
74+
box_size_nd = box_size / x0
75+
76+
# Log-normal distribution parameters
77+
# For log-normal: sigma is the shape parameter (std dev of log(r))
78+
# mean = exp(mu + sigma^2/2)
79+
# Solving: mean_radius = exp(mu + sigma^2/2)
80+
sigma = shape_param
81+
mu = math.log(mean_radius_nd) - sigma**2 / 2
82+
83+
# Set random seed for reproducibility
84+
random.seed(42)
85+
86+
# Calculate box volume
87+
box_volume = box_size_nd**3
88+
89+
# Estimate initial number of bubbles
90+
# Average volume per bubble: (4/3)*pi*r_mean^3
91+
mean_vol_per_bubble = (4.0 / 3.0) * math.pi * math.exp(mu + sigma**2 / 2.0) ** 3
92+
n_bubbles_estimate = int(void_fraction * box_volume / mean_vol_per_bubble)
93+
94+
# Generate bubble radii using log-normal distribution
95+
# Python's random.lognormvariate generates from lognormal(mu, sigma)
96+
radii = [random.lognormvariate(mu, sigma) for _ in range(n_bubbles_estimate)]
97+
98+
# Adjust radii to match target void fraction
99+
current_void = sum((4.0 / 3.0) * math.pi * r**3 for r in radii) / box_volume
100+
if current_void > 0:
101+
scale_factor = (void_fraction / current_void) ** (1.0 / 3.0)
102+
radii = [r * scale_factor for r in radii]
103+
104+
n_bubbles = len(radii)
105+
106+
# Generate random positions in the cube
107+
box_half = box_size_nd / 2.0
108+
positions = [(random.uniform(-box_half, box_half), random.uniform(-box_half, box_half), random.uniform(-box_half, box_half)) for _ in range(n_bubbles)]
109+
110+
# Create output directory if needed
111+
input_dir = os.path.join(os.path.dirname(__file__), "input")
112+
os.makedirs(input_dir, exist_ok=True)
113+
114+
# Write bubble file
115+
bubble_file = os.path.join(input_dir, "lag_bubbles.dat")
116+
with open(bubble_file, "w") as f:
117+
for i in range(n_bubbles):
118+
# Format: x y z vx vy vz radius interface_velocity
119+
# All velocities are zero at initialization
120+
x, y, z = positions[i]
121+
r = radii[i]
122+
f.write(f"{x:.6e}\t{y:.6e}\t{z:.6e}\t0.0\t0.0\t0.0\t{r:.6e}\t0.0\n")
123+
124+
return n_bubbles
125+
126+
127+
# Generate bubble cloud
128+
nBubs = generate_bubble_cloud()
129+
59130
# Configuring case dictionary
60131
print(
61132
json.dumps(
@@ -75,7 +146,7 @@
75146
"dt": dt * (c0 / x0),
76147
"t_step_start": 0,
77148
"t_step_stop": 3000,
78-
"t_step_save": 500,
149+
"t_step_save": 30,
79150
# Simulation Algorithm Parameters
80151
"model_eqns": "5eq",
81152
"time_stepper": "rk3",
@@ -130,7 +201,7 @@
130201
"bubble_model": "keller_miksis", # Keller-Miksis model
131202
"thermal": 3,
132203
"polytropic": "F",
133-
"lag_params%nBubs_glb": 1194, # Number of bubbles
204+
"lag_params%nBubs_glb": nBubs, # Number of bubbles
134205
"lag_params%solver_approach": 2,
135206
"lag_params%cluster_type": 2,
136207
"lag_params%pressure_corrector": "T",
@@ -141,6 +212,8 @@
141212
"lag_params%valmaxvoid": 0.9,
142213
"lag_params%write_bubbles": "F",
143214
"lag_params%write_bubbles_stats": "F",
215+
"lag_params%charwidth": 5e-3 / x0,
216+
"lag_params%charNz": Ny,
144217
# Bubble parameters
145218
"bub_pp%R0ref": 1.0,
146219
"bub_pp%p0ref": 1.0,
@@ -169,6 +242,7 @@
169242
"fluid_pp(2)%gamma": 1.0 / (gam_g - 1.0),
170243
"fluid_pp(2)%pi_inf": 0.0e00,
171244
"fluid_pp(2)%Re(1)": 1.0 / (mu_g / (rho0 * c0 * x0)),
172-
}
245+
},
246+
indent=4,
173247
)
174248
)

examples/2D_lagrange_bubblescreen/input/README.txt

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)