Skip to content

Commit 3d41713

Browse files
Merge branch 'develop' into systemtests/add-timeout-support
2 parents b5af34e + bd8ae8e commit 3d41713

File tree

101 files changed

+3716
-0
lines changed

Some content is hidden

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

101 files changed

+3716
-0
lines changed

changelog-entries/660.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Added a new Partitioned Water Hammer tutorial including 1D–3D, 3D–1D, 1D–1D, and 3D–3D coupling configurations using OpenFOAM and Nutils [#660](https://github.com/precice/tutorials/pull/660)

changelog-entries/677.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Added a new Partitioned Pipe Multiscale tutorial including 1D–3D, 3D–1D, 1D–1D, and 3D–3D coupling configurations using OpenFOAM and Nutils [#677](https://github.com/precice/tutorials/pull/677)
Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
---
2+
title: Partitioned Pipe — Geometric Axial Multiscale
3+
keywords: OpenFOAM, Nutils, preCICE, geometric multiscale, fluid
4+
summary: The Partitioned Pipe — Geometric Axial Multiscale tutorial couples a 1D pipe model with a 3D CFD pipe using preCICE.
5+
---
6+
7+
{% note %}
8+
Get the [case files of this tutorial](https://github.com/precice/tutorials/tree/develop/partitioned-pipe-multiscale), as continuously rendered here, or see the [latest released version](https://github.com/precice/tutorials/tree/master/partitioned-pipe-multiscale) (if there is already one). Read how in the [tutorials introduction](https://precice.org/tutorials.html).
9+
{% endnote %}
10+
11+
## Setup
12+
13+
We solve a simple **partitioned pipe problem** using a 1D–3D coupling approach.
14+
In this tutorial, the computational domain is split into two coupled regions: a 1D pipe section and a 3D pipe section.
15+
The coupling is performed using **preCICE**.
16+
17+
In addition to the 1D–3D setup, this tutorial also includes configurations for **1D–1D** and **3D–3D** coupling.
18+
These variants can be beneficial for validation studies, solver comparisons, or for investigating the influence of model dimensionality.
19+
20+
In the following, $\mathrm{1D}$ denotes the reduced-order domain (e.g., a Nutils solver) and $\mathrm{3D}$ denotes the full 3D CFD domain (e.g., OpenFOAM).
21+
22+
The problem consists of a straight pipe of length $L = 40 \mathrm{m}$ and diameter $D = 10 \mathrm{m}$. We partition the domain at $z_c = 20 \mathrm{m}$, where the coupling interface is located. The pipe axis is aligned with the z-axis.
23+
The **1D domain** solves the flow equations using Nutils, while the **3D domain** is solved using OpenFOAM.
24+
Both solvers are coupled via preCICE by exchanging the **pressure** and **axial velocity** at the interface.
25+
26+
Two coupling directions are possible:
27+
28+
- **1D → 3D**: The 1D solver provides the interface velocity to the 3D solver, which responds with pressure.
29+
- **3D → 1D**: The 3D solver provides the velocity, and the 1D solver returns the pressure.
30+
31+
The global outlet (end of the rightmost domain) is set to $p_{\mathrm{out}} = 0 \mathrm{Pa}$.
32+
33+
For the **3D → 1D** coupling, the 3D inlet velocity is prescribed as a **parabolic (Poiseuille)** profile with a bulk velocity of $u_{\mathrm{in}} = 0.1 \mathrm{m/s}$
34+
implemented using a `codedFixedValue` boundary condition. This ensures a physically realistic velocity distribution consistent with the 1D model.
35+
36+
For the **1D → 3D** coupling, the inlet velocity is set to $u_{\mathrm{in}} = 0.1 \mathrm{m/s}$.
37+
38+
## Configuration
39+
40+
preCICE configuration for the 1D-3D simulation (image generated using the [precice-config-visualizer](https://precice.org/tooling-config-visualization.html)):
41+
42+
![preCICE configuration visualization 1D-3D](images/tutorials-partitioned-pipe-multiscale-1d3d-config.png)
43+
44+
preCICE configuration for the 3D-1D simulation:
45+
46+
![preCICE configuration visualization 3D-1D](images/tutorials-partitioned-pipe-multiscale-3d1d-config.png)
47+
48+
## Available solvers
49+
50+
- OpenFOAM (**pimpleFoam**). An incompressible/transient OpenFOAM solver. See the [OpenFOAM adapter documentation](https://precice.org/adapter-openfoam-overview.html).
51+
- Nutils. A Python-based finite element framework. For more information, see the [Nutils adapter documentation](https://precice.org/adapter-nutils.html)
52+
53+
## Running the Simulation
54+
55+
First, select which coupling you want to run. This sets the correct `precice-config.xml` symlink (by default, set to `1d3d`):
56+
57+
```bash
58+
# Choose one configuration
59+
./setcase.sh 1d3d
60+
# or
61+
./setcase.sh 3d1d
62+
# or
63+
./setcase.sh 1d1d
64+
# or
65+
./setcase.sh 3d3d
66+
```
67+
68+
Open **two terminals** and start the corresponding participants for your chosen setup.
69+
70+
### Example A — 1D → 3D coupling
71+
72+
Terminal 1:
73+
74+
```bash
75+
cd fluid1d-left-nutils
76+
./run.sh
77+
```
78+
79+
Terminal 2:
80+
81+
```bash
82+
cd fluid3d-right-openfoam
83+
./run.sh
84+
```
85+
86+
### Example B — 3D → 1D coupling
87+
88+
Run `./setcase.sh 3d1d` and then navigate to the respective directories.
89+
90+
Terminal 1:
91+
92+
```bash
93+
cd fluid3d-left-openfoam
94+
./run.sh
95+
```
96+
97+
Terminal 2:
98+
99+
```bash
100+
cd fluid1d-right-nutils
101+
./run.sh
102+
```
103+
104+
## Visualization
105+
106+
The output of the coupled simulation is written into the folders `fluid1d-left-nutils`, `fluid1d-right-nutils`, `fluid3d-left-openfoam`, and `fluid3d-right-openfoam`, depending on which coupling direction (`1d3d` or `3d1d`) you selected.
107+
108+
### 3D domain (OpenFOAM)
109+
110+
For the 3D participant, all simulation results are stored in the time directories inside the respective case folder (e.g., `fluid3d-right-openfoam/`).
111+
You can visualize the flow field and pressure distribution using **ParaView** by opening the case file:
112+
113+
```bash
114+
paraview fluid3d-right-openfoam/fluid3d-right-openfoam.foam
115+
```
116+
117+
or, for the left domain if applicable:
118+
119+
```bash
120+
paraview fluid3d-left-openfoam/fluid3d-left-openfoam.foam
121+
```
122+
123+
Typical fields to inspect include:
124+
125+
- `p` – pressure
126+
- `U` – velocity
127+
128+
We also record pressure and velocity at fixed points each time step using the OpenFOAM `probes` function object.
129+
130+
**Probe setup (excerpt):**
131+
132+
```c
133+
#includeEtc "caseDicts/postProcessing/probes/probes.cfg"
134+
135+
fields (p U);
136+
probeLocations
137+
(
138+
(0 0 20)
139+
(0 0 40)
140+
);
141+
// For the left 3D domain use instead:
142+
// probeLocations ((0 0 0) (0 0 20));
143+
```
144+
145+
**Output location:**
146+
147+
- `fluid3d-right-openfoam/postProcessing/probes/0/p`
148+
- `fluid3d-right-openfoam/postProcessing/probes/0/U`
149+
150+
In addition to point probes, the 3D participant samples the **axial pressure distribution** along the pipe centerline using `sampleDict`. This provides the spatial pressure variation along the pipe and allows direct comparison with the 1D solution at the latest time step.
151+
152+
The tutorial includes a `sampleDict` in the 3D cases:
153+
154+
- `fluid3d-left-openfoam/system/sampleDict`
155+
- `fluid3d-right-openfoam/system/sampleDict`
156+
157+
**sampleDict (excerpt):**
158+
159+
```cpp
160+
FoamFile
161+
{
162+
version 2.0;
163+
format ascii;
164+
class dictionary;
165+
location "system";
166+
object sampleDict;
167+
}
168+
169+
type sets;
170+
libs ("libsampling.so");
171+
172+
setFormat raw;
173+
174+
sets
175+
(
176+
centerline
177+
{
178+
type uniform;
179+
axis z;
180+
start (0 0 0);
181+
end (0 0 20);
182+
nPoints 200;
183+
}
184+
);
185+
186+
fields (p);
187+
```
188+
189+
The sampling is executed automatically during the run.
190+
191+
**Output location:**
192+
193+
```text
194+
postProcessing/sampleDict/<latestTime>/centerline_p.xy
195+
```
196+
197+
The file contains two columns:
198+
199+
1. axial coordinate `z`
200+
2. pressure `p`
201+
202+
### 1D domain (Nutils)
203+
204+
The 1D solver writes a `probes.txt` with semicolon-separated time series:
205+
206+
```text
207+
time; p_in; u_in; p_out; u_out; p_mid; u_mid
208+
```
209+
210+
where:
211+
212+
- `p_in`, `u_in` → pressure and velocity at the inlet of the 1D domain
213+
- `p_out`, `u_out` → pressure and velocity at the outlet of the 1D domain
214+
- `p_mid`, `u_mid` → pressure and velocity at the midpoint of the 1D domain
215+
216+
The 1D solver also writes a `final_fields.txt` with space-separated values:
217+
218+
```text
219+
x u p
220+
```
221+
222+
They correspond to the axial position, velocity and pressure at the last time-step, i.e., at $t = 5 \mathrm{s}$.
223+
224+
### Plotting axial pressure distribution (optional)
225+
226+
To reproduce the axial pressure distribution shown in the figure below, a helper script is provided:
227+
228+
```bash
229+
python plot-pressure-distribution.py
230+
```
231+
232+
By default, the script uses the `1d3d` case.
233+
234+
You can also specify the coupling configuration explicitly:
235+
236+
```bash
237+
python plot-pressure-distribution.py 1d3d
238+
```
239+
240+
```bash
241+
python plot-pressure-distribution.py 3d1d
242+
```
243+
244+
```bash
245+
python plot-pressure-distribution.py 1d1d
246+
```
247+
248+
```bash
249+
python plot-pressure-distribution.py 3d3d
250+
```
251+
252+
Allowed cases are:
253+
254+
- `1d3d`
255+
- `3d1d`
256+
- `1d1d`
257+
- `3d3d`
258+
259+
Depending on the selected case, the script reads:
260+
261+
- `final_fields.txt` from the 1D Nutils solver
262+
- `centerline_p.xy` from the 3D OpenFOAM participant
263+
264+
and combines both datasets to plot the pressure distribution along the coupled pipe.
265+
266+
By default, the figures are saved to:
267+
268+
```text
269+
images/pressure_distribution_<case>.png
270+
```
271+
272+
### Example visualization
273+
274+
![Pressure distribution along the main axis in the 3D-1D Coupled Pipe](images/tutorials-partitioned-pipe-multiscale-3d1d-pressure-distribution.png)
275+
276+
**Pressure along the pipe centerline.** The pressure decreases nearly linearly from **≈12.8 Pa** at the 3D inlet to **0 Pa** at the 1D outlet, consistent with steady, laminar Poiseuille flow. The 3D (0–20 m) and 1D (20–40 m) sections connect smoothly at the coupling interface.
277+
278+
![Velocity at the 3D coupling interface in the 3D-1D Coupled Pipe](images/tutorials-partitioned-pipe-multiscale-3d1d-velocityProfileInterface3d.png)
279+
280+
**Parabolic velocity profile at the 3D outlet / coupling interface (z = 20 m).**
281+
The profile is Poiseuille-like with a bulk velocity of **0.1 m/s**; consequently the **centerline velocity is ≈ 0.2 m/s** (≈ 2 × bulk) and vanishes at the wall (no-slip). This is the velocity state at the interface used for coupling to the 1D domain.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/usr/bin/env sh
2+
set -e -u
3+
4+
# shellcheck disable=SC1091
5+
. ../tools/cleaning-tools.sh
6+
7+
clean_tutorial .
8+
clean_precice_logs .
9+
rm -fv ./*.log
10+
rm -fv ./*.vtu
11+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
probes.txt
2+
final_fields.txt
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/usr/bin/env sh
2+
set -e -u
3+
4+
. ../../tools/cleaning-tools.sh
5+
6+
rm -f ./results/Fluid1D_*
7+
rm -f ./probes.txt
8+
rm -f ./final_fields.txt
9+
clean_precice_logs .
10+
clean_case_logs .
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
setuptools # required by nutils
2+
nutils==9
3+
numpy >1, <2
4+
pyprecice~=3.0
5+
matplotlib
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/usr/bin/env bash
2+
set -e -u
3+
4+
. ../../tools/log.sh
5+
exec > >(tee --append "$LOGFILE") 2>&1
6+
7+
python3 -m venv .venv
8+
. .venv/bin/activate
9+
pip install -r requirements.txt && pip freeze > pip-installed-packages.log
10+
11+
NUTILS_RICHOUTPUT=no python3 ../solver-fluid1d-nutils/Fluid1D.py side=Left
12+
13+
close_log
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
probes.txt
2+
final_fields.txt
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/usr/bin/env sh
2+
set -e -u
3+
4+
. ../../tools/cleaning-tools.sh
5+
6+
rm -f ./results/Fluid1D_*
7+
rm -f ./probes.txt
8+
rm -f ./final_fields.txt
9+
clean_precice_logs .
10+
clean_case_logs .

0 commit comments

Comments
 (0)