-
-
Notifications
You must be signed in to change notification settings - Fork 163
Water Hammer Tutorial #660
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 2 commits
Commits
Show all changes
59 commits
Select commit
Hold shift + click to select a range
2486383
Water Hammer Tutorial
franiqui 23f2f8d
Changed files
franiqui 47e2198
Update thermodynamicProperties
franiqui ee3036d
Update fvSchemes
franiqui b602a51
Update fvSolution
franiqui a722414
Update probes
franiqui 8348272
Update thermodynamicProperties
franiqui 3a49db6
Update fvSchemes
franiqui 02bc955
Update fvSolution
franiqui e59daa4
Update probes
franiqui caba83e
Update probesDict
franiqui 647cc1b
Update thermodynamicProperties
franiqui 359966d
Update fvSchemes
franiqui a9ebbdf
Update fvSolution
franiqui 516a4ba
Update probes
franiqui ec8a328
Update probesDict
franiqui f9b3a5d
Update thermodynamicProperties
franiqui d8e9408
Update fvSchemes
franiqui 8d7204e
Update fvSolution
franiqui 2618cbe
Update probes
franiqui 65fb3d3
Update probesDict
franiqui eba2d5e
Update and rename README.md to README.txt
franiqui 43e14b7
Remove obsolete plot files
franiqui e79dafa
Update precice-config.xml for 3D–3D case
franiqui e01128c
Refactor/update
franiqui 877d12e
Restore water-hammer files from before e01128cd8
franiqui bdd79ea
Deleted ENTIRE Water Hammer case
franiqui e02da82
STARTED AGAIN TUTORIAL
franiqui 2f31599
Changed participant name Fluid1DLeft
franiqui 88cc0c6
Changed ymin and ymax of 3D cases
franiqui 18c0427
Water Hammer Tutorial - New structure with only 1D-3D coupling
franiqui 1d5c577
Updated structure on the Water Hammer tutorial
franiqui 4bd38d1
Updated clean.sh and run.sh to work in the current tutorial structure
franiqui d671761
Suggested changes
franiqui 2d679a9
Suggested Changes and Updated solver-fluid1d/ directory
franiqui 4d59e72
Merge branch 'develop' into WaterHammerTutorial
MakisH d767ee0
Use configuration reader in dumux-adapter (#713)
Fujikawas 2503017
Adapt system tests setup for fenics-adapter (#712)
MakisH a54b756
Addition of 1d-1d and 3d-3d
franiqui 8e9fae7
Modification of multiscale-spread-profile to multiscale-cross-section…
franiqui 75382aa
Merge branch 'develop' into WaterHammerTutorial
franiqui 8eb95b0
Severity > debug & point to files in README.md
franiqui 903a819
Merge branch 'WaterHammerTutorial' of github.com:franiqui/tutorials i…
franiqui bf826ac
In line equations
franiqui 46be037
Addition of visualization scripts
franiqui 7bea75d
Addition of visualization script to plot outlet pressure in README.md
franiqui 9a89090
Addition of PR to changelog-entries
franiqui e5f87d1
Update changelog entry
MakisH 264de16
Rename watchpoint.txt to probes.txt
MakisH f2ca8b7
Minor fixes in plot-pressure.py
MakisH f3aeadc
Suggested changes
franiqui 86bdd2a
Merge branch 'develop' into WaterHammerTutorial
MakisH 7de2f87
Update water-hammer/fluid1d-left-nutils/run.sh
franiqui 6cf4471
Update water-hammer/fluid1d-right-nutils/run.sh
franiqui d572cec
Fixing of plot-pressure.py
franiqui b2b6433
Updated README.md
franiqui d75b21c
Removal of \, on README
franiqui 7f4c366
Fix of plot-pressure.py
franiqui 2ffe048
Minor tweaks in the README
MakisH File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| --- | ||
| title: Partitioned Water Hammer | ||
| keywords: OpenFOAM, python, preCICE, multiscale, fluid, FSI, transient | ||
| summary: The Partitioned Water Hammer tutorial simulates unsteady pressure wave propagation in pipe systems using different 1D and 3D configurations coupled via preCICE. | ||
| --- | ||
|
|
||
| ## Setup | ||
|
|
||
| This tutorial demonstrates how to model the **water hammer phenomenon** — a transient pressure surge caused by a rapid change in flow — using **partitioned coupling** with [preCICE](https://precice.org). | ||
|
|
||
| It supports multiple configurations: | ||
|
|
||
| - **1D–1D**: Python solvers on both sides | ||
| - **1D–3D**: Python 1D solver coupled to OpenFOAM | ||
| - **3D–3D**: OpenFOAM solvers on both sides | ||
|
|
||
| We exchange: | ||
|
|
||
| - **Velocity** from downstream to upstream | ||
| - **Pressure** from upstream to downstream | ||
|
|
||
| This allows realistic simulation of pressure wave propagation. | ||
|
|
||
| ## Folder structure | ||
|
|
||
| ```bash | ||
| water-hammer/ | ||
| ├── case-1d/ # Monolithic 1D simulation | ||
| | └── fluid1d-python-uncoupled/ | ||
| ├── case-3d/ # Monolithic 3D simulation | ||
| │ └── fluid3d-openfoam-uncoupled/ | ||
| ├── case-1d-1d/ # Partitioned 1D–1D simulation | ||
| │ ├── fluid1dleft-python/ | ||
| │ └── fluid1dright-python/ | ||
| ├── case-1d-3d/ # Partitioned 1D–3D simulation | ||
| │ ├── fluid1d-python/ | ||
| │ └── fluid3d-openfoam/ | ||
| ├── case-3d-3d/ # Partitioned 3D–3D simulation | ||
| │ ├── fluid3d-openfoam-left/ | ||
| │ └── fluid3d-openfoam-right/ | ||
| ├── results/ # Output data and plots | ||
| └── README.md # This file | ||
| ``` | ||
|
|
||
| ## How to use | ||
|
|
||
| ### 1D–1D Coupling (Python–Python) | ||
|
|
||
| In two different terminals execute | ||
|
|
||
| ```bash | ||
| cd case-1d-1d/fluid1dleft-python && ./run.sh | ||
| ``` | ||
|
|
||
| ```bash | ||
| cd case-1d-1d/fluid1dright-python && ./run.sh | ||
| ``` | ||
|
|
||
| ### 3D-3D Coupling (OpenFOAM-OpenFOAM) | ||
|
|
||
| In two different terminals execute | ||
|
|
||
| ```bash | ||
| cd case-3d-3d/fluid3d-openfoam-left && ./run.sh | ||
| ``` | ||
|
|
||
| ```bash | ||
| cd case-3d-3d/fluid3d-openfoam-right && ./run.sh | ||
| ``` | ||
|
|
||
| ### 1D-3D Coupling (Python-OpenFOAM) | ||
|
|
||
| In two different terminals execute | ||
|
|
||
| ```bash | ||
| cd case-1d-3d/fluid1d-python && ./run.sh | ||
| ``` | ||
|
|
||
| ```bash | ||
| cd case-1d-3d/fluid3d-openfoam && ./run.sh | ||
| ``` | ||
|
|
||
| ### 1D (Monolithic, Python) | ||
|
|
||
| In one terminal, execute | ||
|
|
||
| ```bash | ||
| cd case-1d/fluid1d-python-uncoupled && ./run.sh | ||
| ``` | ||
|
|
||
| ### 3D (Monolithic, OpenFOAM) | ||
|
|
||
| In one terminal, execute | ||
|
|
||
| ```bash | ||
| cd case-3d/fluid3d-openfoam-uncoupled && ./run.sh | ||
| ``` | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| #!/usr/bin/env sh | ||
| set -e -u | ||
|
|
||
| # shellcheck disable=SC1091 | ||
| . ../../tools/cleaning-tools.sh | ||
|
|
||
| clean_tutorial . | ||
| clean_precice_logs . | ||
| rm -fv ./*.log | ||
| rm -fv ./*.vtu | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,147 @@ | ||
| import numpy as np | ||
| import matplotlib.pyplot as plt | ||
| import treelog | ||
| from nutils import mesh, function, solver, cli | ||
| import precice | ||
|
|
||
|
|
||
| def main(nelems=200, dt=.005, refdensity=1e3, refpressure=101325.0, psi=1e-6, viscosity=1e-3, theta=0.5): | ||
|
|
||
| # --- preCICE initialization --- | ||
|
|
||
| participant_name = "Fluid1DLeft" | ||
| config_file_name = "../precice-config.xml" | ||
| solver_process_index = 0 | ||
| solver_process_size = 1 | ||
| participant = precice.Participant(participant_name, config_file_name, solver_process_index, solver_process_size) | ||
| mesh_name = "Fluid1DLeft-Mesh" | ||
| velocity_name = "Velocity" | ||
| pressure_name = "Pressure" | ||
| positions = [[0.0, 500.0, 0.0]] | ||
| vertex_ids = participant.set_mesh_vertices(mesh_name, positions) | ||
|
|
||
| participant.initialize() | ||
| precice_dt = participant.get_max_time_step_size() | ||
|
|
||
| # --- Nutils domain setup --- | ||
|
|
||
| domain, geom = mesh.rectilinear([np.linspace(0, 500, nelems + 1)]) # 1D domain from 0 to 500 with nelems elements | ||
|
|
||
| ns = function.Namespace() | ||
| ns.x = geom | ||
| ns.dt = dt | ||
| ns.θ = theta | ||
| ns.ρref = refdensity | ||
| ns.pref = refpressure | ||
| ns.pin = 98100 # Inlet pressure (Pa) | ||
| ns.μ = viscosity | ||
| ns.ψ = psi | ||
|
|
||
| # Define basis functions: velocity (vector, degree 2), density (scalar, degree 1) | ||
| ns.ubasis, ns.ρbasis = function.chain([ | ||
| domain.basis('std', degree=2).vector(domain.ndims), | ||
| domain.basis('std', degree=1) | ||
| ]) | ||
|
|
||
| # Define trial and previous-step functions | ||
| ns.u_i = 'ubasis_ni ?lhs_n' | ||
| ns.u0_i = 'ubasis_ni ?lhs0_n' | ||
| ns.ρ = 'ρref + ρbasis_n ?lhs_n' | ||
| ns.ρ0 = 'ρref + ρbasis_n ?lhs0_n' | ||
| ns.p = 'pref + (ρ - ρref) / ψ' | ||
| ns.utheta_i = 'θ u_i + (1 - θ) u0_i' | ||
| ns.ρtheta = 'θ ρ + (1 - θ) ρ0' | ||
|
|
||
| # Cauchy stress tensor: viscous + pressure | ||
| ns.σ_ij = 'μ (utheta_i,j + utheta_j,i) - p δ_ij' | ||
|
|
||
| # --- Weak form residuals --- | ||
|
|
||
| # Mass conservation | ||
| res = domain.integral( | ||
| 'ρbasis_n ((ρ - ρ0) / dt + (ρtheta utheta_k)_,k) d:x' @ ns, | ||
| degree=4 | ||
| ) | ||
|
|
||
| # Momentum conservation: unsteady + convective + diffusive terms | ||
| res += domain.integral( | ||
| '(ubasis_ni (((ρ u_i - ρ0 u0_i) / dt) + (ρtheta utheta_i utheta_j)_,j) + ubasis_ni,j σ_ij) d:x' @ ns, | ||
| degree=4 | ||
| ) | ||
|
|
||
| # Weakly enforced inlet pressure boundary condition | ||
| res += domain.boundary['left'].integral( | ||
| 'pin ubasis_ni n_i d:x' @ ns, | ||
| degree=4 | ||
| ) | ||
|
|
||
| # Initial condition | ||
| lhs0 = np.zeros(res.shape) | ||
|
|
||
| # Time-stepping | ||
| t = 0.0 | ||
| timestep = 0 | ||
| bezier = domain.sample('bezier', 2) | ||
|
|
||
| f = open("watchpoint.txt", "w") | ||
|
|
||
| # --- Time loop with preCICE coupling --- | ||
| while participant.is_coupling_ongoing(): | ||
|
|
||
| # Read velocity data from other solver via preCICE | ||
| u_read = participant.read_data(mesh_name, velocity_name, vertex_ids, precice_dt) | ||
|
|
||
| # Constrain outlet velocity to match coupled value | ||
| stringintegral = f'(u_0 - ({u_read[0][1]}))^2 d:x' | ||
| sqr = domain.boundary['right'].integral(stringintegral @ ns, degree=4) | ||
| cons = solver.optimize('lhs', sqr, droptol=1e-14) | ||
|
|
||
| # Write checkpoint if required by preCICE | ||
| if participant.requires_writing_checkpoint(): | ||
| lhscheckpoint = lhs0 | ||
|
|
||
| # Solve nonlinear system (Newton's method) | ||
| with treelog.context('stokes'): | ||
| lhs = solver.newton( | ||
| 'lhs', | ||
| residual=res, | ||
| constrain=cons, | ||
| arguments=dict(lhs0=lhs0), | ||
| lhs0=lhs0 | ||
| ).solve(1e-08) | ||
|
|
||
| # Evaluate fields for visualization/debugging | ||
| x, p, u, ρ = bezier.eval(['x_i', 'p', 'u_i', 'ρ'] @ ns, arguments=dict(lhs=lhs)) | ||
|
|
||
| # Send pressure at the right boundary to the other solver | ||
| write_press = [[p[-1]]] | ||
| participant.write_data(mesh_name, pressure_name, vertex_ids, write_press) | ||
|
|
||
| # Advance in pseudo-time | ||
| participant.advance(precice_dt) | ||
| precice_dt = participant.get_max_time_step_size() | ||
|
|
||
| # Restore checkpoint if needed | ||
| if participant.requires_reading_checkpoint(): | ||
| lhs0 = lhscheckpoint | ||
| else: | ||
| # Update old solution | ||
| lhs0 = lhs | ||
| timestep += timestep | ||
|
|
||
| # Save probe values (time, inlet pressure, inlet velocity, outlet | ||
| # pressure, outlet velocity, pressure at the middle, velocity at the | ||
| # middle) | ||
| x, p, ρ, u = bezier.eval(['x_i', 'p', 'ρ', 'u_i'] @ ns, lhs=lhs) | ||
| f.write("%e; %e; %e; %e; %e; %e; %e\n" % (t, p[0], u[0], p[-1], u[-1], p[199], u[199])) | ||
| f.flush() | ||
|
|
||
| t += precice_dt # advance pseudo-time | ||
|
|
||
| # Finalize preCICE | ||
| participant.finalize() | ||
| f.close() | ||
|
|
||
|
|
||
| if __name__ == '__main__': | ||
| cli.run(main) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| #!/usr/bin/env sh | ||
| set -e -u | ||
|
|
||
| . ../../../tools/cleaning-tools.sh | ||
|
|
||
| rm -f ./results/Fluid1D_* | ||
| clean_precice_logs . | ||
| clean_case_logs . |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| setuptools # required by nutils | ||
| nutils==9 | ||
| numpy >1, <2 | ||
| pyprecice~=3.0 | ||
| matplotlib | ||
| treelog |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| #!/usr/bin/env bash | ||
| set -e -u | ||
|
|
||
| . ../../../tools/log.sh | ||
| exec > >(tee --append "$LOGFILE") 2>&1 | ||
|
|
||
| python3 -m venv .venv | ||
| . .venv/bin/activate | ||
| pip install -r requirements.txt && pip freeze > pip-installed-packages.log | ||
|
|
||
| NUTILS_RICHOUTPUT=no python3 Fluid1D.py | ||
|
|
||
| close_log |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.