=======================================
Pure horizontal jet
=======================================
A pure horizontal jet is the simplest test case, which is also investigated in
numerous experimental studies. The ``config.toml`` file looks like this:
.. literalinclude:: config.toml
:language: toml
|
We run the example from the command line as
.. code-block::
python -m effluent config.toml
|
or from within python as
.. code-block:: python
import effluent
effluent.run("config.toml") # Alternatively, just pass a dict
|
This produces an output file named ``out.csv``:
.. literalinclude:: out.csv
|
We load the output data using `pandas `_
.. plot::
:context: reset
:include-source:
import pandas as pd
df = pd.read_csv("out.csv")
|
and plot the centerline and plume boundary using `matplotlib `_
.. plot::
:context:
:include-source:
import matplotlib.pyplot as plt
x = df.x.values
center = df.z.values
upper = df.z.values + df.radius.values
lower = df.z.values - df.radius.values
plt.plot(x, center, color='k', linewidth=2, label='Centerline')
plt.plot(x, upper, color='k', linewidth=.5)
plt.plot(x, lower, color='k', linewidth=.5)
plt.fill_between(x, lower, upper, color="#e0e0e0",
label='Plume extent')
plt.xlabel('Distance from pipe outlet (m)')
plt.ylabel('Depth below surface (m)')
plt.gcf().set_size_inches(8, 3)
plt.gca().set_aspect('equal')
plt.legend()
plt.tight_layout()
|
Tracer concentration is proportional to plume speed and cross-sectional
area. Here is one way of visualizing the concentration evolution:
.. plot::
:context: close-figs
:include-source:
import numpy as np
# Extract data
x = df.x.values
z = df.z.values
r = df.radius.values
element_volume = df.u.values * (r ** 2)
dilution = element_volume / element_volume[0]
# Plot plume dilution factor
xx, zz = np.meshgrid(
np.linspace(x[0], x[-1], 100),
np.linspace(z[-1] - r[-1], z[-1] + r[-1], 100),
)
rr = np.interp(xx, x, r)
dilu = np.interp(xx, x, dilution)
dilu[(z[0] - rr > zz) | (zz > z[0] + rr)] = np.nan
plt.pcolormesh(xx, zz, dilu, cmap='gray', clim=(1, 7))
# Set visual plot properties
cbar = plt.colorbar()
cbar.ax.set_ylabel('Dilution factor')
plt.xlabel('Distance from pipe outlet (m)')
plt.ylabel('Depth below surface (m)')
plt.gca().set_aspect('equal')
plt.gcf().set_size_inches(8, 3)
|
The plume edges are defined using the top-hat profile, as described in
:doc:`../../algorithm`. If desired, we can visualize the plume as a gaussian
profile instead. In a round gaussian plume, the centerline concentration is
twice as large as the corresponding top-hat mean concentration. The top-hat
radius equals the gaussian radius times the square root of two.
.. plot::
:context: close-figs
:include-source:
# Plot fuzzy plume
depth = df.z.values[0]
cm = 2 * np.interp(xx, x, 1 / dilution)
conc = cm * np.exp(-(zz - depth)**2 / (0.5 * rr**2))
dilu = 1 / (conc + 1e-7)
plt.pcolormesh(xx, zz, dilu, cmap='gray', clim=(1, 20))
# Plot centerline and edges
rad_gauss = df.radius.values / np.sqrt(2)
lgauss = df.z.values - rad_gauss
ugauss = df.z.values + rad_gauss
plt.plot(x, lgauss, color='r', linewidth=.5, label='Gaussian radius')
plt.plot(x, ugauss, color='r', linewidth=.5)
plt.plot(x, upper, color='k', linewidth=.5, label='Top-hat radius')
plt.plot(x, lower, color='k', linewidth=.5)
# Set visual plot properties
cbar = plt.colorbar()
cbar.ax.set_ylabel('Dilution factor')
plt.xlabel('Distance from pipe outlet (m)')
plt.ylabel('Depth below surface (m)')
plt.gca().set_aspect('equal')
plt.gcf().set_size_inches(8, 3)
plt.legend()
The assumption of gaussian distribution is invalid close to the plume outlet.
A correct representation requires a model of the *Zone of Flow Establishment*.
This is currently not implemented.