Création d’un canal et/ou d’une rampe rugueuse
Import des modules
[ ]:
# import _add_path # for debugging purposes only - must be removed in production
import pandas as pd
from wolfhece import is_enough
if not is_enough('2.2.56'):
raise ImportError("This code requires wolfhece version 2.2.56 or higher. -- try pip install wolfhece --upgrade")
from wolfhece.channel_rough_ramp import Channel, RoughRamp, BreachElement
from wolfhece.PyVertexvectors import vector
from wolfhece.wolf_array import WolfArray, header_wolf
import numpy as np
from unittest import TestCase, main
import matplotlib.pyplot as plt
Création d’un canal sur base d’une trace et d’une section en travers
Dans cet exemple, on souhaite obtenir un canal d’un section transversale constante selon une trace évoluant en altimétrie.
La forme du canal est définie de façon relative, c’est-à-dire que la fond du canal sera positionné à l’altitude locale définie par la trace.
La trace est définie d’amont vers l’aval. De cette manière, logiquement, la gauche et la droite respectent les standards habituels de “rive gauche” et “rive droite”.
La trace n’est pas nécessairement située au milieu de la section. Conventionnellement, la trace est associée à l’abscisse “0.0” de la section.
[2]:
%matplotlib inline
#%matplotlib widget # Uncomment this line to use interactive widgets in Jupyter Notebook
# Create a channel
channel = Channel()
# Define the channel trace
trace = vector('channel_trace')
trace.add_vertices_from_array(np.asarray([[0.,0.,15.],
[10,10,14.],
[10,20,13.],
[20,35,13.],
[25,45,10.],
])) # The elevation changes along the trace
width_left = 1.5
width_right = 1.0
slope_left = 2.0
slope_right = 3.0
zmax = 3.0
zmin = 0.0
# Define the channel shape
shape = vector('channel_shape')
shape.add_vertices_from_array(np.asarray([[-11., zmax],
[-9., 2.5],
[-7., 2.],
[-width_right - 2. / slope_right, 2.],
[-width_right, zmin],
[0.,zmin],
[width_left, zmin],
[width_left + 2. / slope_left, 2.],
[7., 2.5],
[9., 2.5],
[11., zmax]]))
# Define the sampling distance along the channel and across the channel
ds = 1.0
# Create the channel triangulation
channel.create_from_shape(trace, shape, ds)
# Plot the channel triangulation
tri = channel.triangulation
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
tri.plot_matplotlib_3D(ax)
ax.set_aspect('equal')
plt.show()
# Interpolate the channel triangulation onto a WolfArray
h = header_wolf.make(orig = (-10, -10), d = (0.5, 0.5), nb = (100,100))
a = WolfArray(srcheader=h)
a.array[:,:] = 0.0 # Fill the array with a constant value of 0.0
a.interpolate_on_triangulation(tri.pts, tri.tri, keep = 'above') # Interpolate the triangulation points onto the array
# The "keep" argument is set to 'above' to retain all values above the array.
# Other options for "keep" are 'all' or 'below'.
# If "all" is used, no filtering is performed and all values are kept.
# If "below" is used, only values below the array are retained.
fig, ax = a.plot_matplotlib()
plt.show()
Création d’une rampe rugueuse sur base d’une trace, de pentes et d’altitudes min et max
La trace est définie d’amont vers l’aval.
De cette manière, logiquement, la gauche et la droite respectent les standards habituels de “rive gauche” et “rive droite”.
Une rampe rugueuse a les propriétés suivantes :
une largeur à gauche de la trace
une largeur à droite de la trace
une pente de remontée vers la rive gauche
une pente de remontée vers la rive droite
La trace n’est donc pas nécessairement située au milieu de la rampe, sauf si les deux largeurs sont identiques.
[4]:
ramp = RoughRamp() # Create a RoughRamp object
trace = vector('ramp_trace') # Create a vector for the ramp trace
trace.add_vertices_from_array(np.asarray([[0.,0.,0.],
[10,10,0.]])) # Add vertices to the trace vector
# Define the slopes and widths for the ramp
width_left = 1.5 # No width at the top of the ramp
width_right = 1.5 # No width at the bottom of the ramp
slope_left = 2.0 # Slope of the ramp - upstream side -- slope défined as dZ / dX
slope_right = 5.0
# Create the ramp triangulation with zmin and zmax
zmin = 0.0 # Minimum z-coordinate for the ramp
zmax = 10.0 # Maximum z-coordinate for the ramp
ds = 0.5 # Distance between vertices in the ramp trace
ramp.create_from_slopes(trace,
slope_left, slope_right,
width_left, width_right,
zmin, zmax,
ds)
tri = ramp.triangulation # Get the triangulation object from the ramp
zones = ramp.zones # Get the "Zones" instance from the ramp triangulation
%matplotlib inline
# Plotting the triangulation in 3D
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
tri.plot_matplotlib_3D(ax)
ax.set_aspect('equal')
fig.show()
# Plotting the dike trace and zones in 2D
fig, ax = plt.subplots()
zones.plot_matplotlib(ax)
trace.myprop.color = (255,0,0)
trace.myprop.width = 2.0
trace.plot_matplotlib(ax)
ax.set_aspect('equal')
plt.show()
C:\Users\pierre\AppData\Local\Temp\ipykernel_44068\2917410520.py:34: UserWarning: FigureCanvasAgg is non-interactive, and thus cannot be shown
fig.show()
Création d’une rampe rugueuse sur base d’une forme de section
On définit ici:
une trace
une forme de section transversale de la rampe
La routine “create_from_shape” va ensuite distribuer au mieux la forme selon la trace.
[5]:
ramp = RoughRamp()
trace = vector('ramp_trace')
shape = vector('ramp_shape')
trace.add_vertices_from_array(np.asarray([[0.,0.,10.],
[10,10,10.],
[10,20,10.],
[20,35,10.],
[0,35,10.]]))
width_left = 0.0
width_right = 0.0
slope_left = 0.5
slope_right = 0.5
zmax = 3.0
zmin = 0.0
shape.add_vertices_from_array(np.asarray([[-(zmax - zmin) / slope_left, zmax],
[0.,zmin],
[(zmax - zmin) / slope_right,zmax]]))
ds = 0.5
ramp.create_from_shape(trace, shape, ds)
tri = ramp.triangulation
zones = ramp.zones
%matplotlib inline
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
tri.plot_matplotlib_3D(ax)
ax.set_aspect('equal')
fig.show()
# Plotting the dike trace and zones in 2D
fig, ax = plt.subplots()
zones.plot_matplotlib(ax)
trace.myprop.color = (255,0,0)
trace.myprop.width = 2.0
trace.plot_matplotlib(ax)
ax.set_aspect('equal')
plt.show()
C:\Users\pierre\AppData\Local\Temp\ipykernel_44068\278541980.py:36: UserWarning: FigureCanvasAgg is non-interactive, and thus cannot be shown
fig.show()
Même approche mais avec une largeur au fond non-nulle
[8]:
ramp = RoughRamp()
trace = vector('ramp_trace')
shape = vector('ramp_shape')
trace.add_vertices_from_array(np.asarray([[0.,0.,10.],
[10,10,10.],
[10,20,10.],
[20,35,10.],
[0,55,10.]])) # The trace has the same elevation at each vertex
width_left = 5.0
width_right = 5.0
slope_left = 1.0
slope_right = 1.0
zmax = 10.0
zmin = 0.0
shape.add_vertices_from_array(np.asarray([[-width_left - (zmax - zmin) / slope_left, zmax],
[-width_right, zmin],
[0.,zmin],
[width_left, zmin],
[width_left + (zmax-zmin) / slope_right, zmax]]))
ds = 0.5
ramp.create_from_shape(trace, shape, ds)
tri = ramp.triangulation
zones = ramp.zones
%matplotlib inline
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
tri.plot_matplotlib_3D(ax)
ax.set_aspect('equal')
# Plotting the dike trace and zones in 2D
fig, ax = plt.subplots()
zones.plot_matplotlib(ax)
trace.myprop.color = (255,0,0)
trace.myprop.width = 2.0
trace.plot_matplotlib(ax)
ax.set_aspect('equal')
plt.show()
Ajout d’éléments de rugosité
Il est possible d’ajouter des éléments de rugosité.
Pour ce faire, il faut définir :
la trace en plan de la rugosité souhaitée
la section en travers
les brèches éventuelles pour les faibles débits
[9]:
# Default horizontal trace of roughness elements along a ramp.
# Defined in a (x, y) plane with z=0.
# The real element will be rotated and translated along the ramp trace.
shape_rough = vector(name='ramp_shape_rough')
shape_rough.add_vertices_from_array(np.array([[-10.0, 0.0],
[0.0, 2.0],
[10.0, 0.0]]))
# Cross-section of the roughness elements.
# Defined in a (s, z) plane and relative to z = 0.0.
# The real elements will be translated according to the ramp elelvation at each position.
z_max = 0.6
cs_rough = vector(name='ramp_cs_rough')
cs_rough.add_vertices_from_array(np.array([[-0.5, 0.0],
[-0.5, z_max],
[0.0, z_max],
[0.5, z_max],
[0.5, 0.0]]))
# Generic breach element definition.
# The position is defined along the curvilinear abscissa of the rough trace.
breach = BreachElement(curvilinear_position=10.0,
width=1.0,
depth=0.2)
# Add rough elements along the ramp trace with specified spacing and breach elements.
ramp.add_rough_elements_along_trace(shape_rough,
cs_rough,
spacing= 10.0,
breach= breach,
decal_each= 6.0, # Offset each breach element by 2.0 units along the rough trace
reset= True)
zones = ramp.zones
%matplotlib inline
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
for tri in ramp.triangulations_rough:
tri.plot_matplotlib_3D(ax)
for tri in ramp.triangulations_below:
tri.plot_matplotlib_3D(ax)
ax.set_aspect('equal')
plt.show()
[ ]:
h = header_wolf.make(orig = (-10, -10), d = (0.5, 0.5), nb = (100,200))
a = WolfArray(srcheader=h)
a.array[:,:] = 0.0 # Fill the array with a constant value of 0.0
tris, keeps = ramp.triangulations # Get the list of triangulations and corresponding "keep" options (above/below)
a.interpolate_on_triangulations(tris, keep = keeps) # Interpolate the triangulation points onto the array
# The "keep" argument is set to 'above' to retain all values above the array.
# "below" is used for the breaches.
fig, ax = a.plot_matplotlib()
plt.show()