wolfhece 2.2.15__py3-none-any.whl → 2.2.16__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wolfhece/Model1D.py +12 -12
- wolfhece/PyDraw.py +1 -1
- wolfhece/PyGui.py +9 -1
- wolfhece/__init__.py +1 -1
- wolfhece/apps/version.py +1 -1
- wolfhece/apps/wolf.py +1 -1
- wolfhece/assets/__init__.py +0 -1
- wolfhece/assets/mesh.py +685 -0
- wolfhece/friction_law.py +3 -3
- wolfhece/hydrology/SubBasin.py +154 -154
- wolfhece/hydrometry/kiwis.py +55 -16
- wolfhece/hydrometry/kiwis_wolfgui.py +8 -7
- wolfhece/lazviewer/laz_viewer.py +4 -4
- wolfhece/mesh2d/wolf2dprev.py +23 -0
- wolfhece/pyshields.py +38 -2
- wolfhece/wolf_array.py +19 -16
- wolfhece/wolfresults_2D.py +220 -74
- {wolfhece-2.2.15.dist-info → wolfhece-2.2.16.dist-info}/METADATA +2 -3
- {wolfhece-2.2.15.dist-info → wolfhece-2.2.16.dist-info}/RECORD +22 -21
- {wolfhece-2.2.15.dist-info → wolfhece-2.2.16.dist-info}/WHEEL +0 -0
- {wolfhece-2.2.15.dist-info → wolfhece-2.2.16.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.2.15.dist-info → wolfhece-2.2.16.dist-info}/top_level.txt +0 -0
wolfhece/assets/mesh.py
ADDED
@@ -0,0 +1,685 @@
|
|
1
|
+
from matplotlib import pyplot as plt
|
2
|
+
from matplotlib.axes import Axes
|
3
|
+
from matplotlib.figure import Figure
|
4
|
+
import numpy as np
|
5
|
+
|
6
|
+
from ..wolf_array import header_wolf
|
7
|
+
from ..wolfresults_2D import q_splitting, u_splitting, splitting_rule
|
8
|
+
|
9
|
+
class Mesh2D(header_wolf):
|
10
|
+
|
11
|
+
def __init__(self, src_header:header_wolf):
|
12
|
+
|
13
|
+
self.set_origin(src_header.origx, src_header.origy)
|
14
|
+
self.set_resolution(src_header.dx, src_header.dy)
|
15
|
+
self.set_translation(src_header.translx, src_header.transly)
|
16
|
+
self.shape = src_header.shape
|
17
|
+
self._factor = None
|
18
|
+
|
19
|
+
def plot_cells(self, ax:Axes=None, color='black', **kwargs):
|
20
|
+
""" Plot the grid of the mesh.
|
21
|
+
"""
|
22
|
+
|
23
|
+
if ax is None:
|
24
|
+
fig, ax = plt.subplots()
|
25
|
+
else:
|
26
|
+
fig = ax.figure
|
27
|
+
|
28
|
+
[xmin, xmax], [ymin, ymax] = self.get_bounds()
|
29
|
+
|
30
|
+
for y in np.linspace(ymin, ymax, endpoint=True, num=self.nby + 1):
|
31
|
+
ax.plot([xmin, xmax], [y, y], color=color, **kwargs)
|
32
|
+
|
33
|
+
for x in np.linspace(xmin, xmax, endpoint=True, num=self.nbx + 1):
|
34
|
+
ax.plot([x, x], [ymin, ymax], color=color, **kwargs)
|
35
|
+
|
36
|
+
self.set_aspect_labels(ax=ax, **kwargs)
|
37
|
+
return fig, ax
|
38
|
+
|
39
|
+
def plot_center_cells(self, ax:Axes=None, color='black', linestyle='--', **kwargs):
|
40
|
+
""" Plot lines centered to the cells.
|
41
|
+
"""
|
42
|
+
|
43
|
+
if ax is None:
|
44
|
+
fig, ax = plt.subplots()
|
45
|
+
else:
|
46
|
+
fig = ax.figure
|
47
|
+
|
48
|
+
[xmin, xmax], [ymin, ymax] = self.get_bounds()
|
49
|
+
|
50
|
+
for y in np.linspace(ymin + self.dy/2., ymax - self.dy/2., endpoint=True, num=self.nby):
|
51
|
+
ax.plot([xmin, xmax], [y, y], color=color, linestyle=linestyle, **kwargs)
|
52
|
+
|
53
|
+
for x in np.linspace(xmin + self.dx/2., xmax - self.dx/2., endpoint=True, num=self.nbx):
|
54
|
+
ax.plot([x, x], [ymin, ymax], color=color, linestyle=linestyle, **kwargs)
|
55
|
+
|
56
|
+
self.set_aspect_labels(ax=ax, **kwargs)
|
57
|
+
return fig, ax
|
58
|
+
|
59
|
+
def set_ticks_as_dxdy(self, ax:Axes=None, **kwargs):
|
60
|
+
""" Set the ticks of the axis as the dx and dy of the mesh.
|
61
|
+
"""
|
62
|
+
|
63
|
+
if ax is None:
|
64
|
+
fig, ax = plt.subplots()
|
65
|
+
else:
|
66
|
+
fig = ax.figure
|
67
|
+
|
68
|
+
[xmin, xmax], [ymin, ymax] = self.get_bounds()
|
69
|
+
|
70
|
+
x_ticks = ['ox + tx', r'+$\Delta x$'] + [f'+{i}$\Delta x$' for i in range(2,self.nbx+1)]
|
71
|
+
y_ticks = ['oy + ty', r'+$\Delta y$'] + [f'{+i}$\Delta y$' for i in range(2,self.nby+1)]
|
72
|
+
|
73
|
+
ax.set_xticks(np.linspace(xmin, xmax, endpoint=True, num=self.nbx + 1))
|
74
|
+
ax.set_yticks(np.linspace(ymin, ymax, endpoint=True, num=self.nby + 1))
|
75
|
+
ax.set_xticklabels(x_ticks)
|
76
|
+
ax.set_yticklabels(y_ticks)
|
77
|
+
|
78
|
+
return fig, ax
|
79
|
+
|
80
|
+
def plot_circle_at_centers(self, ax:Axes=None, color='black', radius:float=None, **kwargs):
|
81
|
+
""" Plot circles at the center of the cells.
|
82
|
+
"""
|
83
|
+
|
84
|
+
if radius is None:
|
85
|
+
radius = 0.1 * self.dx
|
86
|
+
|
87
|
+
if ax is None:
|
88
|
+
fig, ax = plt.subplots()
|
89
|
+
else:
|
90
|
+
fig = ax.figure
|
91
|
+
|
92
|
+
[xmin, xmax], [ymin, ymax] = self.get_bounds()
|
93
|
+
|
94
|
+
for y in np.linspace(ymin + self.dy/2., ymax - self.dy/2., endpoint=True, num=self.nby):
|
95
|
+
for x in np.linspace(xmin + self.dx/2., xmax - self.dx/2., endpoint=True, num=self.nbx):
|
96
|
+
circle = plt.Circle((x, y), radius=radius, color=color, **kwargs)
|
97
|
+
ax.add_artist(circle)
|
98
|
+
|
99
|
+
self.set_aspect_labels(ax=ax, **kwargs)
|
100
|
+
|
101
|
+
return fig, ax
|
102
|
+
|
103
|
+
def plot_indices_at_centers(self, ax:Axes=None, Fortran_type:bool = True, **kwargs):
|
104
|
+
""" Plot the indices of the cells at the center of the cells.
|
105
|
+
"""
|
106
|
+
|
107
|
+
if ax is None:
|
108
|
+
fig, ax = plt.subplots()
|
109
|
+
else:
|
110
|
+
fig = ax.figure
|
111
|
+
|
112
|
+
[xmin, xmax], [ymin, ymax] = self.get_bounds()
|
113
|
+
|
114
|
+
for y in np.linspace(ymin + self.dy/2., ymax - self.dy/2., endpoint=True, num=self.nby):
|
115
|
+
for x in np.linspace(xmin + self.dx/2., xmax - self.dx/2., endpoint=True, num=self.nbx):
|
116
|
+
i,j = self.xy2ij(x, y)
|
117
|
+
|
118
|
+
if Fortran_type:
|
119
|
+
i+=1
|
120
|
+
j+=1
|
121
|
+
|
122
|
+
ax.text(x, y, f'({i},{j})', horizontalalignment='center', verticalalignment='center', **kwargs)
|
123
|
+
|
124
|
+
self.set_aspect_labels(ax=ax, **kwargs)
|
125
|
+
|
126
|
+
return fig, ax
|
127
|
+
|
128
|
+
def plot_indices_at_bordersX(self, ax:Axes=None, Fortran_type:bool = True, **kwargs):
|
129
|
+
""" Plot the indices of the cells at the borders of the cells.
|
130
|
+
"""
|
131
|
+
|
132
|
+
if ax is None:
|
133
|
+
fig, ax = plt.subplots()
|
134
|
+
else:
|
135
|
+
fig = ax.figure
|
136
|
+
|
137
|
+
[xmin, xmax], [ymin, ymax] = self.get_bounds()
|
138
|
+
|
139
|
+
for y in np.linspace(ymin + self.dy/2., ymax - self.dy/2., endpoint=True, num=self.nby):
|
140
|
+
for x in np.linspace(xmin, xmax, endpoint=True, num=self.nbx + 1):
|
141
|
+
i,j = self.xy2ij(x, y)
|
142
|
+
|
143
|
+
if Fortran_type:
|
144
|
+
i+=1
|
145
|
+
j+=1
|
146
|
+
|
147
|
+
ax.text(x, y, f'({i},{j})', horizontalalignment='center', verticalalignment='center', **kwargs)
|
148
|
+
|
149
|
+
def plot_indices_at_bordersY(self, ax:Axes=None, Fortran_type:bool = True, **kwargs):
|
150
|
+
""" Plot the indices of the cells at the borders of the cells.
|
151
|
+
"""
|
152
|
+
|
153
|
+
if ax is None:
|
154
|
+
fig, ax = plt.subplots()
|
155
|
+
else:
|
156
|
+
fig = ax.figure
|
157
|
+
|
158
|
+
[xmin, xmax], [ymin, ymax] = self.get_bounds()
|
159
|
+
|
160
|
+
for y in np.linspace(ymin, ymax, endpoint=True, num=self.nby + 1):
|
161
|
+
for x in np.linspace(xmin + self.dx/2., xmax - self.dx/2., endpoint=True, num=self.nbx):
|
162
|
+
i,j = self.xy2ij(x, y)
|
163
|
+
|
164
|
+
if Fortran_type:
|
165
|
+
i+=1
|
166
|
+
j+=1
|
167
|
+
|
168
|
+
ax.text(x, y, f'({i},{j})', horizontalalignment='center', verticalalignment='center', **kwargs)
|
169
|
+
|
170
|
+
self.set_aspect_labels(ax=ax, **kwargs)
|
171
|
+
|
172
|
+
return fig, ax
|
173
|
+
|
174
|
+
def plot_Xarrows_at_center(self, ax:Axes=None,
|
175
|
+
randomize:bool=False,
|
176
|
+
amplitude:np.ndarray=None,
|
177
|
+
color='black', **kwargs):
|
178
|
+
""" Plot arrows at the center of the cells.
|
179
|
+
"""
|
180
|
+
|
181
|
+
if ax is None:
|
182
|
+
fig, ax = plt.subplots()
|
183
|
+
else:
|
184
|
+
fig = ax.figure
|
185
|
+
|
186
|
+
[xmin, xmax], [ymin, ymax] = self.get_bounds()
|
187
|
+
|
188
|
+
if amplitude is None:
|
189
|
+
amplitude = np.ones((self.nbx, self.nby)) * 0.2 * self.dx
|
190
|
+
else:
|
191
|
+
amplitude = self.scale_amplitude(amplitude)
|
192
|
+
|
193
|
+
for y in np.linspace(ymin + self.dy/2., ymax - self.dy/2., endpoint=True, num=self.nby):
|
194
|
+
for x in np.linspace(xmin + self.dx/2., xmax - self.dx/2., endpoint=True, num=self.nbx):
|
195
|
+
|
196
|
+
i,j = self.xy2ij(x, y)
|
197
|
+
if randomize:
|
198
|
+
dx = np.random.uniform(-0.5, 0.5) * self.dx
|
199
|
+
amplitude[i,j] = dx
|
200
|
+
else:
|
201
|
+
dx = amplitude[i,j]
|
202
|
+
|
203
|
+
ax.arrow(x - dx/2., y, dx, 0,
|
204
|
+
head_width=0.1 * self.dx, head_length=0.1 * self.dy,
|
205
|
+
fc=color, ec=color)
|
206
|
+
|
207
|
+
self.set_aspect_labels(ax=ax, **kwargs)
|
208
|
+
|
209
|
+
return fig, ax, amplitude
|
210
|
+
|
211
|
+
def plot_Yarrows_at_center(self, ax:Axes=None,
|
212
|
+
randomize:bool=False,
|
213
|
+
amplitude:np.ndarray=None,
|
214
|
+
color='black', **kwargs):
|
215
|
+
""" Plot arrows at the center of the cells.
|
216
|
+
"""
|
217
|
+
|
218
|
+
if ax is None:
|
219
|
+
fig, ax = plt.subplots()
|
220
|
+
else:
|
221
|
+
fig = ax.figure
|
222
|
+
|
223
|
+
[xmin, xmax], [ymin, ymax] = self.get_bounds()
|
224
|
+
|
225
|
+
if amplitude is None:
|
226
|
+
amplitude = np.ones((self.nbx, self.nby)) * 0.2 * self.dy
|
227
|
+
else:
|
228
|
+
amplitude = self.scale_amplitude(amplitude)
|
229
|
+
|
230
|
+
for y in np.linspace(ymin + self.dy/2., ymax - self.dy/2., endpoint=True, num=self.nby):
|
231
|
+
for x in np.linspace(xmin + self.dx/2., xmax - self.dx/2., endpoint=True, num=self.nbx):
|
232
|
+
|
233
|
+
i,j = self.xy2ij(x, y)
|
234
|
+
if randomize:
|
235
|
+
dy = np.random.uniform(-0.5, 0.5) * self.dy
|
236
|
+
amplitude[i,j] = dy
|
237
|
+
else:
|
238
|
+
dy = amplitude[i,j]
|
239
|
+
|
240
|
+
ax.arrow(x, y - dy/2., 0, dy,
|
241
|
+
head_width=0.1 * self.dx, head_length=0.1 * self.dy,
|
242
|
+
fc=color, ec=color)
|
243
|
+
|
244
|
+
self.set_aspect_labels(ax=ax, **kwargs)
|
245
|
+
|
246
|
+
return fig, ax, amplitude
|
247
|
+
|
248
|
+
def plot_Xarrows_at_borders(self, ax:Axes=None,
|
249
|
+
randomize:bool=False,
|
250
|
+
amplitudeX:np.ndarray=None,
|
251
|
+
amplitudeY:np.ndarray=None,
|
252
|
+
color='black', **kwargs):
|
253
|
+
""" Plot arrows at the borders of the cells.
|
254
|
+
"""
|
255
|
+
|
256
|
+
if ax is None:
|
257
|
+
fig, ax = plt.subplots()
|
258
|
+
else:
|
259
|
+
fig = ax.figure
|
260
|
+
|
261
|
+
[xmin, xmax], [ymin, ymax] = self.get_bounds()
|
262
|
+
|
263
|
+
if amplitudeX is None:
|
264
|
+
amplitudeX = np.ones((self.nbx+1, self.nby)) * 0.2 * self.dx
|
265
|
+
else:
|
266
|
+
if self._factor is not None:
|
267
|
+
amplitudeX *= self._factor
|
268
|
+
|
269
|
+
if amplitudeY is None:
|
270
|
+
amplitudeY = np.ones((self.nbx, self.nby+1)) * 0.2 * self.dy
|
271
|
+
else:
|
272
|
+
if self._factor is not None:
|
273
|
+
amplitudeY *= self._factor
|
274
|
+
|
275
|
+
for y in np.linspace(ymin + self.dy/2., ymax - self.dy/2., endpoint=True, num=self.nby):
|
276
|
+
for x in np.linspace(xmin, xmax, endpoint=True, num=self.nbx + 1):
|
277
|
+
|
278
|
+
i,j = self.xy2ij(x, y)
|
279
|
+
if randomize:
|
280
|
+
dx = np.random.uniform(-0.5, 0.5) * self.dx
|
281
|
+
amplitudeX[i,j] = dx
|
282
|
+
else:
|
283
|
+
dx = amplitudeX[i,j]
|
284
|
+
|
285
|
+
if dx != 0.:
|
286
|
+
ax.arrow(x - dx/2., y, dx, 0,
|
287
|
+
head_width=0.1 * self.dx, head_length=0.1 * self.dy,
|
288
|
+
fc=color, ec=color)
|
289
|
+
|
290
|
+
for y in np.linspace(ymin, ymax, endpoint=True, num=self.nby+1):
|
291
|
+
for x in np.linspace(xmin + self.dx/2., xmax - self.dx/2., endpoint=True, num=self.nbx):
|
292
|
+
|
293
|
+
i,j = self.xy2ij(x, y)
|
294
|
+
if randomize:
|
295
|
+
dx = np.random.uniform(-0.5, 0.5) * self.dy
|
296
|
+
amplitudeY[i,j] = dx
|
297
|
+
else:
|
298
|
+
dx = amplitudeY[i,j]
|
299
|
+
|
300
|
+
if dx != 0.:
|
301
|
+
ax.arrow(x - dx, y, dx, 0,
|
302
|
+
head_width=0.1 * self.dx, head_length=0.1 * self.dy,
|
303
|
+
fc=color, ec=color)
|
304
|
+
|
305
|
+
self.set_aspect_labels(ax=ax, **kwargs)
|
306
|
+
|
307
|
+
return fig, ax, amplitudeX, amplitudeY
|
308
|
+
|
309
|
+
def plot_Yarrows_at_borders(self, ax:Axes=None,
|
310
|
+
randomize:bool=False,
|
311
|
+
amplitudeX:np.ndarray=None,
|
312
|
+
amplitudeY:np.ndarray=None,
|
313
|
+
color='black', **kwargs):
|
314
|
+
""" Plot arrows at the borders of the cells.
|
315
|
+
"""
|
316
|
+
|
317
|
+
if ax is None:
|
318
|
+
fig, ax = plt.subplots()
|
319
|
+
else:
|
320
|
+
fig = ax.figure
|
321
|
+
|
322
|
+
[xmin, xmax], [ymin, ymax] = self.get_bounds()
|
323
|
+
|
324
|
+
if amplitudeX is None:
|
325
|
+
amplitudeX = np.ones((self.nbx+1, self.nby)) * 0.2 * self.dx
|
326
|
+
else:
|
327
|
+
if self._factor is not None:
|
328
|
+
amplitudeX *= self._factor
|
329
|
+
|
330
|
+
if amplitudeY is None:
|
331
|
+
amplitudeY = np.ones((self.nbx, self.nby+1)) * 0.2 * self.dy
|
332
|
+
else:
|
333
|
+
if self._factor is not None:
|
334
|
+
amplitudeY *= self._factor
|
335
|
+
|
336
|
+
for y in np.linspace(ymin, ymax, endpoint=True, num=self.nby + 1):
|
337
|
+
for x in np.linspace(xmin + self.dx/2., xmax - self.dx/2., endpoint=True, num=self.nbx):
|
338
|
+
|
339
|
+
i,j = self.xy2ij(x, y)
|
340
|
+
if randomize:
|
341
|
+
dy = np.random.uniform(-0.5, 0.5) * self.dy
|
342
|
+
amplitudeY[i,j] = dy
|
343
|
+
else:
|
344
|
+
dy = amplitudeY[i,j]
|
345
|
+
|
346
|
+
if dy != 0.:
|
347
|
+
ax.arrow(x, y - dy/2., 0, dy,
|
348
|
+
head_width=0.1 * self.dx, head_length=0.1 * self.dy,
|
349
|
+
fc=color, ec=color)
|
350
|
+
|
351
|
+
for y in np.linspace(ymin + self.dy/2., ymax - self.dy/2., endpoint=True, num=self.nby):
|
352
|
+
for x in np.linspace(xmin, xmax, endpoint=True, num=self.nbx + 1):
|
353
|
+
|
354
|
+
i,j = self.xy2ij(x, y)
|
355
|
+
if randomize:
|
356
|
+
dy = np.random.uniform(-0.5, 0.5) * self.dx
|
357
|
+
amplitudeX[i,j] = dy
|
358
|
+
else:
|
359
|
+
dy = amplitudeX[i,j]
|
360
|
+
|
361
|
+
if dy != 0.:
|
362
|
+
ax.arrow(x, y - dy/2., 0., dy,
|
363
|
+
head_width=0.1 * self.dx, head_length=0.1 * self.dy,
|
364
|
+
fc=color, ec=color)
|
365
|
+
|
366
|
+
self.set_aspect_labels(ax=ax, **kwargs)
|
367
|
+
|
368
|
+
return fig, ax, amplitudeX, amplitudeY
|
369
|
+
|
370
|
+
def plot_normal_arrows_at_borders(self, ax:Axes=None, color='black', **kwargs):
|
371
|
+
""" Plot arrows at the borders of the cells.
|
372
|
+
"""
|
373
|
+
|
374
|
+
if ax is None:
|
375
|
+
fig, ax = plt.subplots()
|
376
|
+
else:
|
377
|
+
fig = ax.figure
|
378
|
+
|
379
|
+
[xmin, xmax], [ymin, ymax] = self.get_bounds()
|
380
|
+
|
381
|
+
for y in np.linspace(ymin + self.dy/2., ymax - self.dy/2., endpoint=True, num=self.nby):
|
382
|
+
for x in np.linspace(xmin, xmax, endpoint=True, num=self.nbx+1):
|
383
|
+
ax.arrow(x - 0.1 * self.dx, y, 0.2 * self.dx, 0,
|
384
|
+
head_width=0.1 * self.dx, head_length=0.1 * self.dy,
|
385
|
+
fc=color, ec=color)
|
386
|
+
|
387
|
+
for y in np.linspace(ymin, ymax, endpoint=True, num=self.nby+1):
|
388
|
+
for x in np.linspace(xmin + self.dx/2., xmax - self.dx/2., endpoint=True, num=self.nbx):
|
389
|
+
ax.arrow(x, y - 0.1 * self.dy, 0., 0.2 * self.dy,
|
390
|
+
head_width=0.1 * self.dx, head_length=0.1 * self.dy,
|
391
|
+
fc=color, ec=color)
|
392
|
+
|
393
|
+
self.set_aspect_labels(ax=ax, **kwargs)
|
394
|
+
|
395
|
+
return fig, ax
|
396
|
+
|
397
|
+
def scale_axes(self, ax:Axes=None, factor:float = 0.1, **kwargs):
|
398
|
+
""" Scale the axes of the plot to fit the data.
|
399
|
+
"""
|
400
|
+
# augmenter légèrement la taille visible sans
|
401
|
+
# ajouter de ticks
|
402
|
+
ticksX = ax.get_xticks()
|
403
|
+
ticksY = ax.get_yticks()
|
404
|
+
ticklabelsX = ax.get_xticklabels()
|
405
|
+
ticklabelsY = ax.get_yticklabels()
|
406
|
+
|
407
|
+
deltaX = ticksX[-1] - ticksX[0]
|
408
|
+
deltaY = ticksY[-1] - ticksY[0]
|
409
|
+
ax.set_xlim(ticksX[0] - factor * deltaX, ticksX[-1] + factor * deltaX)
|
410
|
+
ax.set_ylim(ticksY[0] - factor * deltaY, ticksY[-1] + factor * deltaY)
|
411
|
+
|
412
|
+
ax.set_xticks(ticksX)
|
413
|
+
ax.set_yticks(ticksY)
|
414
|
+
ax.set_xticklabels(ticklabelsX) #, rotation=45)
|
415
|
+
ax.set_yticklabels(ticklabelsY) #, rotation=45)
|
416
|
+
|
417
|
+
# remove up border and right border
|
418
|
+
ax.spines['top'].set_visible(False)
|
419
|
+
ax.spines['right'].set_visible(False)
|
420
|
+
|
421
|
+
return ax.figure, ax
|
422
|
+
|
423
|
+
def plot_reconstructed_values_at_borders(self, ax:Axes=None,
|
424
|
+
colors=['green', 'blue', 'red', 'brown'],
|
425
|
+
radius:float = None, **kwargs):
|
426
|
+
""" Plot 4 small circles on each side of the border.
|
427
|
+
"""
|
428
|
+
|
429
|
+
if radius is None:
|
430
|
+
radius = 0.02 * self.dx
|
431
|
+
|
432
|
+
if ax is None:
|
433
|
+
fig, ax = plt.subplots()
|
434
|
+
else:
|
435
|
+
fig = ax.figure
|
436
|
+
|
437
|
+
[xmin, xmax], [ymin, ymax] = self.get_bounds()
|
438
|
+
|
439
|
+
deltay = self.dy / 6.
|
440
|
+
for y in np.linspace(ymin + self.dy/2., ymax - self.dy/2., endpoint=True, num=self.nby):
|
441
|
+
x = xmin
|
442
|
+
for i in range(4):
|
443
|
+
ax.add_artist(plt.Circle((x+.1*self.dx, y - 1.5*deltay + i*deltay),
|
444
|
+
radius=radius, color=colors[-i-1], **kwargs))
|
445
|
+
x = xmax
|
446
|
+
for i in range(4):
|
447
|
+
ax.add_artist(plt.Circle((x-.1*self.dx, y - 1.5*deltay + i*deltay),
|
448
|
+
radius=radius, color=colors[-i-1], **kwargs))
|
449
|
+
|
450
|
+
for x in np.linspace(xmin + self.dx, xmax - self.dx, endpoint=True, num=self.nbx-1):
|
451
|
+
for i in range(4):
|
452
|
+
ax.add_artist(plt.Circle((x+.1*self.dx, y - 1.5*deltay + i*deltay),
|
453
|
+
radius=radius, color=colors[-i-1], **kwargs))
|
454
|
+
ax.add_artist(plt.Circle((x-.1*self.dx, y - 1.5*deltay + i*deltay),
|
455
|
+
radius=radius, color=colors[-i-1], **kwargs))
|
456
|
+
|
457
|
+
for x in np.linspace(xmin + self.dx/2., xmax - self.dx/2., endpoint=True, num=self.nbx):
|
458
|
+
y = ymin
|
459
|
+
for i in range(4):
|
460
|
+
ax.add_artist(plt.Circle((x - 1.5*deltay + i*deltay, y+.1*self.dy),
|
461
|
+
radius=radius, color=colors[i], **kwargs))
|
462
|
+
y = ymax
|
463
|
+
for i in range(4):
|
464
|
+
ax.add_artist(plt.Circle((x - 1.5*deltay + i*deltay, y-.1*self.dy),
|
465
|
+
radius=radius, color=colors[i], **kwargs))
|
466
|
+
|
467
|
+
for y in np.linspace(ymin + self.dy, ymax - self.dy, endpoint=True, num=self.nby-1):
|
468
|
+
for i in range(4):
|
469
|
+
ax.add_artist(plt.Circle((x - 1.5*deltay + i*deltay, y+.1*self.dy),
|
470
|
+
radius=radius, color=colors[i], **kwargs))
|
471
|
+
ax.add_artist(plt.Circle((x - 1.5*deltay + i*deltay, y-.1*self.dy),
|
472
|
+
radius=radius, color=colors[i], **kwargs))
|
473
|
+
|
474
|
+
self.set_aspect_labels(ax=ax, **kwargs)
|
475
|
+
|
476
|
+
def plot_splitted_values_at_borders(self, ax:Axes=None,
|
477
|
+
qx:np.ndarray=None,
|
478
|
+
qy:np.ndarray=None,
|
479
|
+
colors=['green', 'blue', 'red', 'brown'],
|
480
|
+
radius:float = None, **kwargs):
|
481
|
+
""" Plot 4 small circles on each side of the border.
|
482
|
+
"""
|
483
|
+
|
484
|
+
split_x = self.zeros_bordersX()
|
485
|
+
split_y = self.zeros_bordersY()
|
486
|
+
|
487
|
+
for i in range(1, self.nbx):
|
488
|
+
for j in range(self.nby):
|
489
|
+
split_x[i,j] = splitting_rule(qx[i-1,j], qx[i,j])
|
490
|
+
for i in range(self.nbx):
|
491
|
+
for j in range(1, self.nby):
|
492
|
+
split_y[i,j] = splitting_rule(qy[i,j-1], qy[i,j])
|
493
|
+
|
494
|
+
if radius is None:
|
495
|
+
radius = 0.02 * self.dx
|
496
|
+
|
497
|
+
if ax is None:
|
498
|
+
fig, ax = plt.subplots()
|
499
|
+
else:
|
500
|
+
fig = ax.figure
|
501
|
+
|
502
|
+
[xmin, xmax], [ymin, ymax] = self.get_bounds()
|
503
|
+
|
504
|
+
deltay = self.dy / 6.
|
505
|
+
|
506
|
+
# X borders
|
507
|
+
for y in np.linspace(ymin + self.dy/2., ymax - self.dy/2., endpoint=True, num=self.nby):
|
508
|
+
x = xmin
|
509
|
+
i,j = self.xy2ij(x, y)
|
510
|
+
for i_unk in range(4):
|
511
|
+
ax.add_artist(plt.Circle((x+.1*self.dx, y - 1.5*deltay + i_unk*deltay),
|
512
|
+
radius=radius, color=colors[-i_unk-1], **kwargs))
|
513
|
+
x = xmax
|
514
|
+
i,j = self.xy2ij(x, y)
|
515
|
+
for i_unk in range(4):
|
516
|
+
ax.add_artist(plt.Circle((x-.1*self.dx, y - 1.5*deltay + i_unk*deltay),
|
517
|
+
radius=radius, color=colors[-i_unk-1], **kwargs))
|
518
|
+
|
519
|
+
for x in np.linspace(xmin + self.dx, xmax - self.dx, endpoint=True, num=self.nbx-1):
|
520
|
+
i,j = self.xy2ij(x, y)
|
521
|
+
|
522
|
+
pond = split_x[i,j]
|
523
|
+
if pond == 0.5:
|
524
|
+
for i_unk in range(4):
|
525
|
+
ax.add_artist(plt.Circle((x+.1*self.dx, y - 1.5*deltay + i_unk*deltay),
|
526
|
+
radius=radius, color=colors[-i_unk-1], **kwargs))
|
527
|
+
ax.add_artist(plt.Circle((x-.1*self.dx, y - 1.5*deltay + i_unk*deltay),
|
528
|
+
radius=radius, color=colors[-i_unk-1], **kwargs))
|
529
|
+
elif pond == 1.0:
|
530
|
+
# left is upstream
|
531
|
+
for i_unk in [1,2]:
|
532
|
+
ax.add_artist(plt.Circle((x-.1*self.dx, y - 1.5*deltay + i_unk*deltay),
|
533
|
+
radius=radius, color=colors[-i_unk-1], **kwargs))
|
534
|
+
for i_unk in [0,3]:
|
535
|
+
ax.add_artist(plt.Circle((x+.1*self.dx, y - 1.5*deltay + i_unk*deltay),
|
536
|
+
radius=radius, color=colors[-i_unk-1], **kwargs))
|
537
|
+
elif pond == 0.0:
|
538
|
+
# right is upstream
|
539
|
+
for i_unk in [0,3]:
|
540
|
+
ax.add_artist(plt.Circle((x-.1*self.dx, y - 1.5*deltay + i_unk*deltay),
|
541
|
+
radius=radius, color=colors[-i_unk-1], **kwargs))
|
542
|
+
for i_unk in [1,2]:
|
543
|
+
ax.add_artist(plt.Circle((x+.1*self.dx, y - 1.5*deltay + i_unk*deltay),
|
544
|
+
radius=radius, color=colors[-i_unk-1], **kwargs))
|
545
|
+
|
546
|
+
# Y borders
|
547
|
+
for x in np.linspace(xmin + self.dx/2., xmax - self.dx/2., endpoint=True, num=self.nbx):
|
548
|
+
y = ymin
|
549
|
+
i,j = self.xy2ij(x, y)
|
550
|
+
for i_unk in range(4):
|
551
|
+
ax.add_artist(plt.Circle((x - 1.5*deltay + i_unk*deltay, y+.1*self.dy),
|
552
|
+
radius=radius, color=colors[i_unk], **kwargs))
|
553
|
+
y = ymax
|
554
|
+
i,j = self.xy2ij(x, y)
|
555
|
+
for i_unk in range(4):
|
556
|
+
ax.add_artist(plt.Circle((x - 1.5*deltay + i_unk*deltay, y-.1*self.dy),
|
557
|
+
radius=radius, color=colors[i_unk], **kwargs))
|
558
|
+
|
559
|
+
for y in np.linspace(ymin + self.dy, ymax - self.dy, endpoint=True, num=self.nby-1):
|
560
|
+
i,j = self.xy2ij(x, y)
|
561
|
+
pond = split_y[i,j]
|
562
|
+
if pond == 0.5:
|
563
|
+
for i_unk in range(4):
|
564
|
+
ax.add_artist(plt.Circle((x - 1.5*deltay + i_unk*deltay, y+.1*self.dy),
|
565
|
+
radius=radius, color=colors[i_unk], **kwargs))
|
566
|
+
ax.add_artist(plt.Circle((x - 1.5*deltay + i_unk*deltay, y-.1*self.dy),
|
567
|
+
radius=radius, color=colors[i_unk], **kwargs))
|
568
|
+
elif pond == 1.0:
|
569
|
+
for i_unk in [1,2]:
|
570
|
+
ax.add_artist(plt.Circle((x - 1.5*deltay + i_unk*deltay, y-.1*self.dy),
|
571
|
+
radius=radius, color=colors[i_unk], **kwargs))
|
572
|
+
for i_unk in [0,3]:
|
573
|
+
ax.add_artist(plt.Circle((x - 1.5*deltay + i_unk*deltay, y+.1*self.dy),
|
574
|
+
radius=radius, color=colors[i_unk], **kwargs))
|
575
|
+
elif pond == 0.0:
|
576
|
+
for i_unk in [0,3]:
|
577
|
+
ax.add_artist(plt.Circle((x - 1.5*deltay + i_unk*deltay, y-.1*self.dy),
|
578
|
+
radius=radius, color=colors[i_unk], **kwargs))
|
579
|
+
for i_unk in [1,2]:
|
580
|
+
ax.add_artist(plt.Circle((x - 1.5*deltay + i_unk*deltay, y+.1*self.dy),
|
581
|
+
radius=radius, color=colors[i_unk], **kwargs))
|
582
|
+
|
583
|
+
|
584
|
+
self.set_aspect_labels(ax=ax, **kwargs)
|
585
|
+
|
586
|
+
def set_aspect_labels(self, ax:Axes=None, **kwargs):
|
587
|
+
""" Set the aspect of the plot to be equal.
|
588
|
+
"""
|
589
|
+
if ax is None:
|
590
|
+
fig, ax = plt.subplots()
|
591
|
+
else:
|
592
|
+
fig = ax.figure
|
593
|
+
|
594
|
+
[xmin, xmax], [ymin, ymax] = self.get_bounds()
|
595
|
+
|
596
|
+
ax.set_aspect('equal')
|
597
|
+
ax.set_xlim(xmin, xmax)
|
598
|
+
ax.set_ylim(ymin, ymax)
|
599
|
+
ax.set_xlabel('X (m)')
|
600
|
+
ax.set_ylabel('Y (m)')
|
601
|
+
return fig, ax
|
602
|
+
|
603
|
+
def zeros(self):
|
604
|
+
""" Return a 2D array of zeros with the shape of the mesh.
|
605
|
+
"""
|
606
|
+
return np.zeros((self.nbx, self.nby))
|
607
|
+
|
608
|
+
def ones(self):
|
609
|
+
""" Return a 2D array of ones with the shape of the mesh.
|
610
|
+
"""
|
611
|
+
return np.ones((self.nbx, self.nby))
|
612
|
+
|
613
|
+
def zeros_bordersX(self):
|
614
|
+
""" Return a 2D array of zeros with the shape of the mesh + 1 in x direction.
|
615
|
+
"""
|
616
|
+
return np.zeros((self.nbx+1, self.nby))
|
617
|
+
|
618
|
+
def zeros_bordersY(self):
|
619
|
+
""" Return a 2D array of zeros with the shape of the mesh + 1 in y direction.
|
620
|
+
"""
|
621
|
+
return np.zeros((self.nbx, self.nby+1))
|
622
|
+
|
623
|
+
def ones_bordersX(self):
|
624
|
+
""" Return a 2D array of ones with the shape of the mesh + 1 in x direction.
|
625
|
+
"""
|
626
|
+
return np.ones((self.nbx+1, self.nby))
|
627
|
+
|
628
|
+
def ones_bordersY(self):
|
629
|
+
""" Return a 2D array of ones with the shape of the mesh + 1 in y direction.
|
630
|
+
"""
|
631
|
+
return np.ones((self.nbx, self.nby+1))
|
632
|
+
|
633
|
+
def apply_splitting_X(self, q:np.ndarray):
|
634
|
+
""" Apply the splitting rule to the X direction.
|
635
|
+
"""
|
636
|
+
q_borderX = self.zeros_bordersX()
|
637
|
+
for i in range(1,self.nbx):
|
638
|
+
for j in range(self.nby):
|
639
|
+
q_borderX[i,j] = q_splitting(q[i-1,j], q[i,j])
|
640
|
+
return q_borderX
|
641
|
+
|
642
|
+
def apply_splitting_Y(self, q:np.ndarray):
|
643
|
+
""" Apply the splitting rule to the Y direction.
|
644
|
+
"""
|
645
|
+
q_borderY = self.zeros_bordersY()
|
646
|
+
for i in range(self.nbx):
|
647
|
+
for j in range(1,self.nby):
|
648
|
+
q_borderY[i,j] = q_splitting(q[i,j-1], q[i,j])
|
649
|
+
return q_borderY
|
650
|
+
|
651
|
+
def scale_amplitude(self, amplitude:np.ndarray, factor:float = None):
|
652
|
+
""" Scale the amplitude of the arrows.
|
653
|
+
"""
|
654
|
+
|
655
|
+
if self._factor is not None:
|
656
|
+
return amplitude * self._factor
|
657
|
+
|
658
|
+
if factor is not None:
|
659
|
+
return amplitude * factor
|
660
|
+
|
661
|
+
factor = min(self.dx, self.dy) * .5 / np.max(amplitude)
|
662
|
+
self._factor = factor
|
663
|
+
|
664
|
+
return amplitude * factor
|
665
|
+
|
666
|
+
def plot_outside_domain(self, ax:Axes=None, color='black', **kwargs):
|
667
|
+
""" Plot a hashed zone outside of the domain.
|
668
|
+
"""
|
669
|
+
if ax is None:
|
670
|
+
fig, ax = plt.subplots()
|
671
|
+
else:
|
672
|
+
fig = ax.figure
|
673
|
+
|
674
|
+
[xmin, xmax], [ymin, ymax] = self.get_bounds()
|
675
|
+
|
676
|
+
# Create a rectangle outside the domain
|
677
|
+
rect = plt.Rectangle((xmin-self.dx, ymin-self.dy), xmax - xmin + 2.*self.dx, ymax - ymin + 2.*self.dy,
|
678
|
+
color=color, alpha=0.2, hatch='//', **kwargs)
|
679
|
+
ax.add_patch(rect)
|
680
|
+
|
681
|
+
rect2 = plt.Rectangle((xmin, ymin), xmax - xmin, ymax - ymin,
|
682
|
+
color='white', alpha=1., hatch='', **kwargs)
|
683
|
+
ax.add_patch(rect2)
|
684
|
+
|
685
|
+
return fig, ax
|