wolfhece 2.1.128__py3-none-any.whl → 2.2.1__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/PyDraw.py +109 -46
- wolfhece/PyGui.py +3 -0
- wolfhece/PyGuiHydrology.py +24 -24
- wolfhece/PyPalette.py +27 -11
- wolfhece/PyParams.py +5 -1
- wolfhece/PyVertexvectors.py +52 -7
- wolfhece/Results2DGPU.py +17 -0
- wolfhece/acceptability/acceptability_gui.py +29 -18
- wolfhece/acceptability/func.py +23 -21
- wolfhece/apps/version.py +2 -2
- wolfhece/eikonal.py +1 -1
- wolfhece/hydrology/Catchment.py +113 -12
- wolfhece/hydrology/Comparison.py +54 -52
- wolfhece/hydrology/Optimisation.py +309 -178
- wolfhece/hydrology/PostProcessHydrology.py +6 -3
- wolfhece/hydrology/RetentionBasin.py +21 -14
- wolfhece/hydrology/SubBasin.py +128 -12
- wolfhece/hydrology/constant.py +3 -0
- wolfhece/hydrology/cst_exchanges.py +364 -38
- wolfhece/hydrology/plot_hydrology.py +34 -18
- wolfhece/hydrology/read.py +16 -6
- wolfhece/lagrangian/particle_system_ui.py +1 -1
- wolfhece/lagrangian/particles.py +1 -1
- wolfhece/lazviewer/processing/estimate_normals/estimate_normals.cp310-win_amd64.pyd +0 -0
- wolfhece/lazviewer/vfuncsdir/vfuncs.cp310-win_amd64.pyd +0 -0
- wolfhece/lazviewer/viewer/viewer.exe +0 -0
- wolfhece/lazviewer/viewer/viewer_np1_23_5.exe +0 -0
- wolfhece/libs/WolfDll.dll +0 -0
- wolfhece/libs/Wolf_tools.dll +0 -0
- wolfhece/libs/get_infos.cp310-win_amd64.pyd +0 -0
- wolfhece/libs/verify_wolf.cp310-win_amd64.pyd +0 -0
- wolfhece/libs/wolfogl.cp310-win_amd64.pyd +0 -0
- wolfhece/radar/wolfradar.py +75 -22
- wolfhece/shapes/__init__.py +0 -0
- wolfhece/shapes/circle.py +335 -0
- wolfhece/tools2d_dll.py +359 -0
- wolfhece/wolf_array.py +3 -2
- wolfhece/wolfresults_2D.py +162 -33
- {wolfhece-2.1.128.dist-info → wolfhece-2.2.1.dist-info}/METADATA +15 -9
- {wolfhece-2.1.128.dist-info → wolfhece-2.2.1.dist-info}/RECORD +43 -39
- wolfhece/libs/wolfpy.cp310-win_amd64.pyd +0 -0
- {wolfhece-2.1.128.dist-info → wolfhece-2.2.1.dist-info}/WHEEL +0 -0
- {wolfhece-2.1.128.dist-info → wolfhece-2.2.1.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.1.128.dist-info → wolfhece-2.2.1.dist-info}/top_level.txt +0 -0
wolfhece/tools2d_dll.py
ADDED
@@ -0,0 +1,359 @@
|
|
1
|
+
from pathlib import Path
|
2
|
+
import numpy as np
|
3
|
+
import ctypes as ct
|
4
|
+
import logging
|
5
|
+
|
6
|
+
from .wolf_array import header_wolf, getkeyblock
|
7
|
+
|
8
|
+
try:
|
9
|
+
import pefile
|
10
|
+
except ImportError:
|
11
|
+
logging.warning("pefile module not found. Exported functions will not be listed.")
|
12
|
+
|
13
|
+
|
14
|
+
class Tools2DFortran:
|
15
|
+
"""
|
16
|
+
Fortran routines/functions available in "2d_cpu_tools.f90" in Wolf_OO
|
17
|
+
|
18
|
+
Ref : https://docs.python.org/3/library/ctypes.html et https://gcc.gnu.org/onlinedocs/gfortran/Interoperability-with-C.html
|
19
|
+
Ref : https://stackoverflow.com/questions/59330863/cant-import-dll-module-in-python
|
20
|
+
"""
|
21
|
+
|
22
|
+
def __init__(self, fn_simul:str | Path, debugmode:bool = False, path_to_dll:Path = None):
|
23
|
+
|
24
|
+
if debugmode:
|
25
|
+
if path_to_dll is None:
|
26
|
+
self.dll_file = Path(__file__).parent / "libs" / "Wolf_tools_debug.dll"
|
27
|
+
else:
|
28
|
+
self.dll_file = path_to_dll / "Wolf_tools_debug.dll"
|
29
|
+
else:
|
30
|
+
if path_to_dll is None:
|
31
|
+
self.dll_file = Path(__file__).parent / "libs" / "Wolf_tools.dll"
|
32
|
+
else:
|
33
|
+
self.dll_file = path_to_dll / "Wolf_tools.dll"
|
34
|
+
|
35
|
+
self.dll_file = self.dll_file.absolute()
|
36
|
+
|
37
|
+
if not Path(self.dll_file).exists():
|
38
|
+
logging.error(f"File {self.dll_file} does not exist.")
|
39
|
+
return
|
40
|
+
|
41
|
+
# Load the DLL
|
42
|
+
try:
|
43
|
+
self.lib = ct.CDLL(str(self.dll_file))
|
44
|
+
except OSError as e:
|
45
|
+
logging.error(f"Could not load the DLL: {e}")
|
46
|
+
return
|
47
|
+
|
48
|
+
fn_simul = Path(fn_simul).absolute()
|
49
|
+
|
50
|
+
self.fn_simul = str(fn_simul)
|
51
|
+
|
52
|
+
if not Path(self.fn_simul).exists():
|
53
|
+
logging.error(f"File {self.fn_simul} does not exist.")
|
54
|
+
return
|
55
|
+
|
56
|
+
# Convert to ANSI encoding - this is important for Fortran on Windows and Latin-1 encoding
|
57
|
+
self.fn_simul = self.fn_simul.encode('ansi')
|
58
|
+
|
59
|
+
# res2D_init
|
60
|
+
self.lib.r2D_init.restype = None
|
61
|
+
self.lib.r2D_init.argtypes = [ct.c_char_p, ct.c_int]
|
62
|
+
|
63
|
+
self.lib.r2D_nbblocks.restype = ct.c_int
|
64
|
+
self.lib.r2D_nbblocks.argtypes = []
|
65
|
+
|
66
|
+
self.lib.r2D_header_block.restype = ct.c_int
|
67
|
+
self.lib.r2D_header_block.argtypes = [
|
68
|
+
ct.POINTER(ct.c_int), # nbx
|
69
|
+
ct.POINTER(ct.c_int), # nby
|
70
|
+
ct.POINTER(ct.c_double), # ox
|
71
|
+
ct.POINTER(ct.c_double), # oy
|
72
|
+
ct.POINTER(ct.c_double), # tx
|
73
|
+
ct.POINTER(ct.c_double), # ty
|
74
|
+
ct.POINTER(ct.c_double), # dx
|
75
|
+
ct.POINTER(ct.c_double), # dy
|
76
|
+
ct.c_int # which_block
|
77
|
+
]
|
78
|
+
|
79
|
+
self.lib.r2D_getsizes.restype = None
|
80
|
+
self.lib.r2D_getsizes.argtypes = [
|
81
|
+
ct.POINTER(ct.c_int), # nbx
|
82
|
+
ct.POINTER(ct.c_int), # nby
|
83
|
+
ct.c_int # which_block
|
84
|
+
]
|
85
|
+
|
86
|
+
self.lib.r2D_getnbresults.restype = ct.c_int
|
87
|
+
self.lib.r2D_getnbresults.argtypes = []
|
88
|
+
|
89
|
+
self.lib.r2D_getresults.restype = None
|
90
|
+
self.lib.r2D_getresults.argtypes = [
|
91
|
+
ct.c_int, # which
|
92
|
+
ct.c_int, # nbx
|
93
|
+
ct.c_int, # nby
|
94
|
+
ct.POINTER(ct.c_float), # waterdepth
|
95
|
+
ct.POINTER(ct.c_float), # qx
|
96
|
+
ct.POINTER(ct.c_float), # qy
|
97
|
+
ct.c_int # which_block
|
98
|
+
]
|
99
|
+
|
100
|
+
self.lib.r2D_getturbresults.restype = None
|
101
|
+
self.lib.r2D_getturbresults.argtypes = [
|
102
|
+
ct.c_int, # which
|
103
|
+
ct.c_int, # nbx
|
104
|
+
ct.c_int, # nby
|
105
|
+
ct.POINTER(ct.c_float), # k
|
106
|
+
ct.POINTER(ct.c_float), # e
|
107
|
+
ct.c_int # which_block
|
108
|
+
]
|
109
|
+
|
110
|
+
self.lib.r2D_get_times_steps.restype = None
|
111
|
+
self.lib.r2D_get_times_steps.argtypes = [
|
112
|
+
ct.POINTER(ct.c_float), # times
|
113
|
+
ct.POINTER(ct.c_int), # steps
|
114
|
+
ct.c_int # nb
|
115
|
+
]
|
116
|
+
|
117
|
+
self.lib.r2D_get_conv_border.restype = None
|
118
|
+
self.lib.r2D_get_conv_border.argtypes = [
|
119
|
+
ct.c_char_p, # ptr_fnsim
|
120
|
+
ct.c_char_p, # ptr_fnvec
|
121
|
+
ct.c_int, # simul_type
|
122
|
+
ct.c_char_p, # ptr_fnres
|
123
|
+
ct.c_char_p, # ptr_fncut
|
124
|
+
ct.c_int, # len_fnsim
|
125
|
+
ct.c_int, # len_fnvec
|
126
|
+
ct.c_int, # len_fnres
|
127
|
+
ct.c_int # len_fncut
|
128
|
+
]
|
129
|
+
|
130
|
+
|
131
|
+
def _list_exported_functions(self):
|
132
|
+
"""
|
133
|
+
Fortran routines/functions available in
|
134
|
+
"""
|
135
|
+
|
136
|
+
pe = pefile.PE(self.dll_file)
|
137
|
+
|
138
|
+
if not hasattr(pe, 'DIRECTORY_ENTRY_EXPORT'):
|
139
|
+
print("No exported functions found.")
|
140
|
+
return
|
141
|
+
|
142
|
+
for exp in pe.DIRECTORY_ENTRY_EXPORT.symbols:
|
143
|
+
print(f"Function: {exp.name.decode('utf-8') if exp.name else 'None'}, Address: {hex(exp.address)}")
|
144
|
+
|
145
|
+
def _r2D_init(self):
|
146
|
+
"""
|
147
|
+
Alias for the Fortran function r2D_init.
|
148
|
+
|
149
|
+
subroutine r2D_init(ptr_path, len_path) bind(C, name="r2d_init")
|
150
|
+
!DEC$ ATTRIBUTES DLLEXPORT :: r2d_init
|
151
|
+
type(c_ptr), value, intent(in) :: ptr_path
|
152
|
+
integer(c_int), value, intent(in) :: len_path
|
153
|
+
|
154
|
+
end subroutine
|
155
|
+
"""
|
156
|
+
self.lib.r2D_init(self.fn_simul, ct.c_int(len(self.fn_simul)))
|
157
|
+
|
158
|
+
def r2D_get_number_of_blocks(self):
|
159
|
+
"""
|
160
|
+
Alias for the Fortran function r2D_nbblocks.
|
161
|
+
|
162
|
+
function r2D_nbblocks() result(nb_blocks) bind(C, name="r2D_nbblocks")
|
163
|
+
!DEC$ ATTRIBUTES DLLEXPORT :: r2D_nbblocks
|
164
|
+
integer(c_int) :: nb_blocks
|
165
|
+
|
166
|
+
end function
|
167
|
+
"""
|
168
|
+
self._r2D_init()
|
169
|
+
nb_blocks = self.lib.r2D_nbblocks()
|
170
|
+
return nb_blocks
|
171
|
+
|
172
|
+
def r2D_get_header_one_block(self, which_block:int):
|
173
|
+
"""
|
174
|
+
Alias for the Fortran function r2D_header_block.
|
175
|
+
|
176
|
+
function r2D_header_block(nbx, nby, dx,dy,ox,oy,tx,ty,which_block) result(ret) bind(C, name="r2D_header_block")
|
177
|
+
!DEC$ ATTRIBUTES DLLEXPORT :: r2D_header_block
|
178
|
+
!DEC$ attributes REFERENCE :: nbx, nby
|
179
|
+
!DEC$ attributes REFERENCE :: dx, dy, ox, oy, tx, ty
|
180
|
+
!DEC$ attributes VALUE :: which_block
|
181
|
+
integer(c_int) :: nbx,nby, ret
|
182
|
+
double precision :: ox,oy,tx,ty,dx,dy
|
183
|
+
integer(c_int), intent(in) :: which_block
|
184
|
+
|
185
|
+
end function
|
186
|
+
"""
|
187
|
+
|
188
|
+
self._r2D_init()
|
189
|
+
nbx = ct.c_int()
|
190
|
+
nby = ct.c_int()
|
191
|
+
ox = ct.c_double()
|
192
|
+
oy = ct.c_double()
|
193
|
+
tx = ct.c_double()
|
194
|
+
ty = ct.c_double()
|
195
|
+
dx = ct.c_double()
|
196
|
+
dy = ct.c_double()
|
197
|
+
self.lib.r2D_header_block(ct.byref(nbx), ct.byref(nby), ct.byref(dx), ct.byref(dy),
|
198
|
+
ct.byref(ox), ct.byref(oy), ct.byref(tx), ct.byref(ty), ct.c_int(which_block))
|
199
|
+
|
200
|
+
return (nbx.value, nby.value, dx.value, dy.value, ox.value, oy.value, tx.value, ty.value)
|
201
|
+
|
202
|
+
def _r2D_get_header_block_python(self, which_block:int) -> header_wolf:
|
203
|
+
""" Return a header_wolf object with the header of the block number which_block."""
|
204
|
+
nbx, nby, dx, dy, ox, oy, tx, ty = self.r2D_get_header_one_block(which_block)
|
205
|
+
newhead = header_wolf()
|
206
|
+
newhead.nbx = nbx
|
207
|
+
newhead.nby = nby
|
208
|
+
newhead.dx = dx
|
209
|
+
newhead.dy = dy
|
210
|
+
newhead.origin = ox, oy
|
211
|
+
newhead.translation = tx, ty
|
212
|
+
|
213
|
+
return newhead
|
214
|
+
|
215
|
+
def r2D_get_header_allblocks(self):
|
216
|
+
|
217
|
+
nbblocks = self.r2D_get_number_of_blocks()
|
218
|
+
blocks = {}
|
219
|
+
|
220
|
+
for i in range(1, nbblocks+1):
|
221
|
+
key = getkeyblock(i, addone=False)
|
222
|
+
blocks[key] = self._r2D_get_header_block_python(i)
|
223
|
+
|
224
|
+
return blocks
|
225
|
+
|
226
|
+
def r2D_get_shape(self, which_block:int):
|
227
|
+
"""
|
228
|
+
Alias for the Fortran function r2D_getsizes.
|
229
|
+
|
230
|
+
subroutine r2D_getsizes(nbx,nby,which_block) bind(C, name="r2D_getsizes")
|
231
|
+
!DEC$ ATTRIBUTES DLLEXPORT :: r2D_getsizes
|
232
|
+
integer(c_int), intent(out) :: nbx,nby
|
233
|
+
integer(c_int), intent(in) :: which_block
|
234
|
+
|
235
|
+
end subroutine
|
236
|
+
"""
|
237
|
+
|
238
|
+
self._r2D_init()
|
239
|
+
nbx = ct.c_int()
|
240
|
+
nby = ct.c_int()
|
241
|
+
self.lib.r2D_getsizes(ct.byref(nbx), ct.byref(nby), ct.c_int(which_block))
|
242
|
+
|
243
|
+
return nbx.value, nby.value
|
244
|
+
|
245
|
+
|
246
|
+
def r2D_get_number_of_results(self):
|
247
|
+
"""
|
248
|
+
Alias for the Fortran function r2D_getnbresults.
|
249
|
+
|
250
|
+
function r2D_getnbresults() result(nb) bind(C, name="r2D_getnbresults")
|
251
|
+
!DEC$ ATTRIBUTES DLLEXPORT :: r2D_getnbresults
|
252
|
+
integer(c_int) :: nb
|
253
|
+
|
254
|
+
end function
|
255
|
+
"""
|
256
|
+
|
257
|
+
self._r2D_init()
|
258
|
+
nb = self.lib.r2D_getnbresults()
|
259
|
+
return nb
|
260
|
+
|
261
|
+
def r2D_get_one_result(self, which:int, which_block:int):
|
262
|
+
"""
|
263
|
+
Alias for the Fortran function r2D_getresults.
|
264
|
+
|
265
|
+
subroutine r2D_getresults(which,nbx,nby,waterdepth,qx,qy,which_block) bind(C, name="r2D_getresults")
|
266
|
+
!DEC$ ATTRIBUTES DLLEXPORT :: r2D_getresults
|
267
|
+
integer(c_int), intent(in) :: nbx,nby,which
|
268
|
+
integer(c_int), intent(in) :: which_block
|
269
|
+
real, dimension(nbx,nby), intent(out) :: waterdepth,qx,qy
|
270
|
+
|
271
|
+
end subroutine
|
272
|
+
"""
|
273
|
+
|
274
|
+
self._r2D_init()
|
275
|
+
|
276
|
+
nbx, nby = self.r2D_get_shape(which_block)
|
277
|
+
waterdepth = np.zeros((nbx, nby), dtype=np.float32, order='F')
|
278
|
+
qx = np.zeros((nbx, nby), dtype=np.float32, order='F')
|
279
|
+
qy = np.zeros((nbx, nby), dtype=np.float32, order='F')
|
280
|
+
|
281
|
+
self.lib.r2D_getresults(ct.c_int(which), ct.c_int(nbx), ct.c_int(nby),
|
282
|
+
waterdepth.ctypes.data_as(ct.POINTER(ct.c_float)),
|
283
|
+
qx.ctypes.data_as(ct.POINTER(ct.c_float)),
|
284
|
+
qy.ctypes.data_as(ct.POINTER(ct.c_float)),
|
285
|
+
ct.c_int(which_block))
|
286
|
+
|
287
|
+
return waterdepth, qx, qy
|
288
|
+
|
289
|
+
def r2D_get_one_turbulent_result(self, which:int, which_block:int):
|
290
|
+
"""
|
291
|
+
Alias for the Fortran function r2D_getturbresults.
|
292
|
+
|
293
|
+
subroutine r2D_getturbresults(which,nbx,nby,k,e,which_block) bind(C, name="r2D_getturbresults")
|
294
|
+
!DEC$ ATTRIBUTES DLLEXPORT :: r2D_getturbresults
|
295
|
+
integer(c_int), intent(in) :: nbx,nby,which
|
296
|
+
integer(c_int), intent(in) :: which_block
|
297
|
+
real, dimension(nbx,nby), intent(out) :: k,e
|
298
|
+
|
299
|
+
end subroutine
|
300
|
+
"""
|
301
|
+
|
302
|
+
self._r2D_init()
|
303
|
+
|
304
|
+
nbx, nby = self.r2D_get_shape(which_block)
|
305
|
+
k = np.zeros((nbx, nby), dtype=np.float32, order='F')
|
306
|
+
e = np.zeros((nbx, nby), dtype=np.float32, order='F')
|
307
|
+
self.lib.r2D_getturbresults(ct.c_int(which), ct.c_int(nbx), ct.c_int(nby),
|
308
|
+
k.ctypes.data_as(ct.POINTER(ct.c_float)),
|
309
|
+
e.ctypes.data_as(ct.POINTER(ct.c_float)),
|
310
|
+
ct.c_int(which_block))
|
311
|
+
|
312
|
+
return k, e
|
313
|
+
|
314
|
+
def r2D_get_times_steps(self):
|
315
|
+
"""
|
316
|
+
Alias for the Fortran function get_times_steps.
|
317
|
+
|
318
|
+
subroutine get_times_steps(times, steps, nb) bind(C, name="get_times_steps")
|
319
|
+
!DEC$ ATTRIBUTES DLLEXPORT :: r2D_gettimes_steps
|
320
|
+
integer(c_int), intent(in) :: nb
|
321
|
+
real, dimension(nb), intent(out) :: times
|
322
|
+
integer, dimension(nb), intent(out) :: steps
|
323
|
+
|
324
|
+
end subroutine
|
325
|
+
"""
|
326
|
+
|
327
|
+
self._r2D_init()
|
328
|
+
nb = self.r2D_get_number_of_results()
|
329
|
+
times = np.zeros((nb), dtype=np.float32, order='F')
|
330
|
+
steps = np.zeros((nb), dtype=np.int32, order='F')
|
331
|
+
self.lib.r2D_get_times_steps(times.ctypes.data_as(ct.POINTER(ct.c_float)),
|
332
|
+
steps.ctypes.data_as(ct.POINTER(ct.c_int)),
|
333
|
+
ct.c_int(nb))
|
334
|
+
return times, steps
|
335
|
+
|
336
|
+
def r2D_create_convergence_border(self, vec:str='', simtype:int=0, res:str='', cutcell:str=''):
|
337
|
+
"""
|
338
|
+
Alias for the Fortran function get_conv_border.
|
339
|
+
|
340
|
+
subroutine get_conv_border(ptr_fnsim, ptr_fnvec, simul_type, ptr_fnres, ptr_fncut, len_fnsim, len_fnvec, len_fnres, len_fncut) bind(C, name="get_conv_border")
|
341
|
+
!DEC$ ATTRIBUTES DLLEXPORT :: r2D_get_conv_border
|
342
|
+
type(c_ptr), value, intent(in) :: ptr_fnsim, ptr_fnvec, ptr_fnres, ptr_fncut
|
343
|
+
integer(c_int), value, intent(in) :: len_fnsim, len_fnvec, len_fnres, len_fncut
|
344
|
+
|
345
|
+
end subroutine
|
346
|
+
"""
|
347
|
+
|
348
|
+
fn_vec = str(vec).encode('ansi')
|
349
|
+
fn_res = str(res).encode('ansi')
|
350
|
+
fn_cutcell = str(cutcell).encode('ansi')
|
351
|
+
|
352
|
+
self._r2D_init()
|
353
|
+
self.lib.r2D_get_conv_border(self.fn_simul, fn_vec, simtype, fn_res, fn_cutcell,
|
354
|
+
ct.c_int(len(self.fn_simul)),
|
355
|
+
ct.c_int(len(fn_vec)),
|
356
|
+
ct.c_int(len(fn_res)),
|
357
|
+
ct.c_int(len(fn_cutcell)))
|
358
|
+
|
359
|
+
return 0
|
wolfhece/wolf_array.py
CHANGED
@@ -6058,7 +6058,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
6058
6058
|
Statistics on Selected data or the whole array if no selection
|
6059
6059
|
|
6060
6060
|
:param inside_polygon: vector or Polygon to select data inside the polygon
|
6061
|
-
:return: mean, std, median, sum, values
|
6061
|
+
:return: mean, std, median, sum, volume (sum*dx*dy), values
|
6062
6062
|
"""
|
6063
6063
|
|
6064
6064
|
if inside_polygon is not None:
|
@@ -6074,8 +6074,9 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
6074
6074
|
std = np.std(vals)
|
6075
6075
|
median = np.median(vals)
|
6076
6076
|
sum = np.sum(vals)
|
6077
|
+
vol = sum * self.dx * self.dy
|
6077
6078
|
|
6078
|
-
return {_('Mean'): mean, _('Std'): std, _('Median'): median, _('Sum'): sum, _('Values'): vals}
|
6079
|
+
return {_('Mean'): mean, _('Std'): std, _('Median'): median, _('Sum'): sum, _('Volume'): vol, _('Values'): vals}
|
6079
6080
|
|
6080
6081
|
def export_geotif(self, outdir:str= '', extent:str= '', EPSG:int = 31370):
|
6081
6082
|
"""
|
wolfhece/wolfresults_2D.py
CHANGED
@@ -45,31 +45,32 @@ from .mesh2d.wolf2dprev import prev_parameters_simul, blocks_file
|
|
45
45
|
from .GraphNotebook import PlotPanel
|
46
46
|
from .CpGrid import CpGrid
|
47
47
|
from .matplotlib_fig import Matplotlib_Figure
|
48
|
+
from .tools2d_dll import Tools2DFortran
|
48
49
|
|
49
50
|
|
50
|
-
try:
|
51
|
-
|
52
|
-
except Exception as ex:
|
53
|
-
|
54
|
-
|
55
|
-
|
51
|
+
# try:
|
52
|
+
# from .libs import wolfpy
|
53
|
+
# except Exception as ex:
|
54
|
+
# # This convoluted error handling is here to catch an issue
|
55
|
+
# # which was difficult to track down: wolfpy was there
|
56
|
+
# # but its DLL were not available.
|
56
57
|
|
57
|
-
|
58
|
-
|
58
|
+
# from importlib.util import find_spec
|
59
|
+
# s = find_spec('wolfhece.libs.wolfpy')
|
59
60
|
|
60
|
-
|
61
|
-
|
62
|
-
|
61
|
+
# # Not too sure about this find_spec. If the root
|
62
|
+
# # directory is not the good one, the import search may
|
63
|
+
# # end up in the site packages, loading the wrong wolfpy.
|
63
64
|
|
64
|
-
|
65
|
-
|
66
|
-
|
65
|
+
# base = Path(__file__).parent.parts
|
66
|
+
# package = Path(s.origin).parent.parts
|
67
|
+
# is_submodule = (len(base) <= len(package)) and all(i==j for i, j in zip(base, package))
|
67
68
|
|
68
|
-
|
69
|
-
|
70
|
-
|
69
|
+
# if is_submodule:
|
70
|
+
# msg = _("wolfpy was found but we were not able to load it. It may be an issue with its DLL dependencies")
|
71
|
+
# msg += _("The actual error was: {}").format(str(ex))
|
71
72
|
|
72
|
-
|
73
|
+
# raise Exception(msg)
|
73
74
|
|
74
75
|
from .wolf_array import WolfArray, getkeyblock, header_wolf, WolfArrayMB, WolfArrayMNAP, header_wolf, SelectionData, SelectionDataMB, VERSION_RGB
|
75
76
|
from .mesh2d import wolf2dprev
|
@@ -130,6 +131,12 @@ def u_splitting(q_left, q_right, h_left, h_right):
|
|
130
131
|
else:
|
131
132
|
return (q_left/h_left + q_right/h_right) / 2.
|
132
133
|
|
134
|
+
def _process_danger_map_chunk(chunk):
|
135
|
+
import pickle
|
136
|
+
obj, start, end, every = chunk
|
137
|
+
# Create a new instance of the class for each chunk
|
138
|
+
new:Wolfresults_2D = pickle.loads(pickle.dumps(obj))
|
139
|
+
return new.danger_map(start, end, every)
|
133
140
|
|
134
141
|
class Props_Res_2D(wx.Frame):
|
135
142
|
"""
|
@@ -2213,6 +2220,7 @@ class Wolfresults_2D(Element_To_Draw):
|
|
2213
2220
|
self.filename = fname
|
2214
2221
|
|
2215
2222
|
self.filenamegen=self.filename
|
2223
|
+
self._dll_tools = Tools2DFortran(self.filenamegen) # DLL de calculs de la classe Tools2DFortran
|
2216
2224
|
|
2217
2225
|
if exists(self.filename + '.trl'):
|
2218
2226
|
with open(self.filename + '.trl') as f:
|
@@ -2224,14 +2232,16 @@ class Wolfresults_2D(Element_To_Draw):
|
|
2224
2232
|
self.read_param_simul()
|
2225
2233
|
|
2226
2234
|
if exists(self.filename+'.head') or exists(join(dirname(self.filename),'bloc1.head')):
|
2227
|
-
wolfpy.r2d_init(self.filename.ljust(255).encode('ansi'))
|
2228
|
-
nb_blocks = wolfpy.r2d_nbblocks()
|
2235
|
+
# wolfpy.r2d_init(self.filename.ljust(255).encode('ansi'))
|
2236
|
+
# nb_blocks = wolfpy.r2d_nbblocks()
|
2229
2237
|
|
2238
|
+
nb_blocks = self._dll_tools.r2D_get_number_of_blocks()
|
2230
2239
|
for i in range(nb_blocks):
|
2231
2240
|
curblock = OneWolfResult(i, parent=self)
|
2232
2241
|
self.myblocks[getkeyblock(i)] = curblock
|
2233
2242
|
|
2234
|
-
nbx,nby,dx,dy,ox,oy,tx,ty = wolfpy.r2d_hblock(i+1)
|
2243
|
+
# nbx,nby,dx,dy,ox,oy,tx,ty = wolfpy.r2d_hblock(i+1)
|
2244
|
+
nbx, nby,dx,dy,ox,oy,tx,ty = self._dll_tools.r2D_get_header_one_block(i+1)
|
2235
2245
|
|
2236
2246
|
curhead = self.head_blocks[getkeyblock(i)]=header_wolf()
|
2237
2247
|
curhead.nbx = nbx
|
@@ -2745,8 +2755,10 @@ class Wolfresults_2D(Element_To_Draw):
|
|
2745
2755
|
if nb == 0:
|
2746
2756
|
self.times, self.timesteps = [],[]
|
2747
2757
|
else:
|
2748
|
-
wolfpy.r2d_init(self.filename.ljust(255).encode('ansi'))
|
2749
|
-
self.times, self.timesteps = wolfpy.get_times_steps(nb)
|
2758
|
+
# wolfpy.r2d_init(self.filename.ljust(255).encode('ansi'))
|
2759
|
+
# self.times, self.timesteps = wolfpy.get_times_steps(nb)
|
2760
|
+
|
2761
|
+
self.times, self.timesteps = self._dll_tools.r2D_get_times_steps()
|
2750
2762
|
|
2751
2763
|
return self.times, self.timesteps
|
2752
2764
|
|
@@ -2996,8 +3008,10 @@ class Wolfresults_2D(Element_To_Draw):
|
|
2996
3008
|
"""Récupération du nombre de pas sauvegardés --> utilisation de la librairie Fortran"""
|
2997
3009
|
|
2998
3010
|
if exists(self.filename+'.head'):
|
2999
|
-
wolfpy.r2d_init(self.filename.ljust(255).encode('ansi'))
|
3000
|
-
nb = wolfpy.r2d_getnbresults()
|
3011
|
+
# wolfpy.r2d_init(self.filename.ljust(255).encode('ansi'))
|
3012
|
+
# nb = wolfpy.r2d_getnbresults()
|
3013
|
+
|
3014
|
+
nb = self._dll_tools.r2D_get_number_of_results()
|
3001
3015
|
self._nb_results = nb
|
3002
3016
|
|
3003
3017
|
if force_update_timessteps:
|
@@ -3021,8 +3035,12 @@ class Wolfresults_2D(Element_To_Draw):
|
|
3021
3035
|
nby = block.waterdepth.nby
|
3022
3036
|
|
3023
3037
|
# Fortran is 1-based --> which_step+1
|
3024
|
-
block.waterdepth.array, block.qx.array, block.qy.array = wolfpy.r2d_getresults(which_step+1, nbx, nby, whichblock)
|
3025
|
-
block.k.array, block.eps.array = wolfpy.r2d_getturbresults(which_step+1, nbx, nby, whichblock)
|
3038
|
+
# block.waterdepth.array, block.qx.array, block.qy.array = wolfpy.r2d_getresults(which_step+1, nbx, nby, whichblock)
|
3039
|
+
# block.k.array, block.eps.array = wolfpy.r2d_getturbresults(which_step+1, nbx, nby, whichblock)
|
3040
|
+
|
3041
|
+
block.waterdepth.array, block.qx.array, block.qy.array = self._dll_tools.r2D_get_one_result(which_step+1, whichblock)
|
3042
|
+
block.k.array, block.eps.array = self._dll_tools.r2D_get_one_turbulent_result(which_step+1, whichblock)
|
3043
|
+
|
3026
3044
|
block._force_update_shields = True
|
3027
3045
|
|
3028
3046
|
def _read_oneblockresult_withoutmask_only_h(self, which_step:int=-1,whichblock:int=-1):
|
@@ -3040,7 +3058,9 @@ class Wolfresults_2D(Element_To_Draw):
|
|
3040
3058
|
nby = block.waterdepth.nby
|
3041
3059
|
|
3042
3060
|
# Fortran is 1-based --> which_step+1
|
3043
|
-
block.waterdepth.array, block.qx.array, block.qy.array = wolfpy.r2d_getresults(which_step+1, nbx, nby, whichblock)
|
3061
|
+
# block.waterdepth.array, block.qx.array, block.qy.array = wolfpy.r2d_getresults(which_step+1, nbx, nby, whichblock)
|
3062
|
+
|
3063
|
+
block.waterdepth.array, block.qx.array, block.qy.array = self._dll_tools.r2D_get_one_result(which_step+1, whichblock)
|
3044
3064
|
block._force_update_shields = True
|
3045
3065
|
|
3046
3066
|
def read_oneblockresult(self, which_step:int=-1, whichblock:int=-1):
|
@@ -3114,7 +3134,7 @@ class Wolfresults_2D(Element_To_Draw):
|
|
3114
3134
|
|
3115
3135
|
if exists(self.filename+'.head'):
|
3116
3136
|
logging.info(_('Reading from results - step :{}'.format(which+1)))
|
3117
|
-
wolfpy.r2d_init(self.filename.ljust(255).encode('ansi'))
|
3137
|
+
# wolfpy.r2d_init(self.filename.ljust(255).encode('ansi'))
|
3118
3138
|
for i in range(self.nb_blocks):
|
3119
3139
|
self.read_oneblockresult(which, i+1)
|
3120
3140
|
else:
|
@@ -3137,7 +3157,7 @@ class Wolfresults_2D(Element_To_Draw):
|
|
3137
3157
|
|
3138
3158
|
if exists(self.filename+'.head'):
|
3139
3159
|
logging.info(_('Reading from results - step :{}'.format(which+1)))
|
3140
|
-
wolfpy.r2d_init(self.filename.ljust(255).encode('ansi'))
|
3160
|
+
# wolfpy.r2d_init(self.filename.ljust(255).encode('ansi'))
|
3141
3161
|
for i in range(self.nb_blocks):
|
3142
3162
|
self._read_oneblockresult_only_h(which, i+1)
|
3143
3163
|
else:
|
@@ -3175,7 +3195,7 @@ class Wolfresults_2D(Element_To_Draw):
|
|
3175
3195
|
if exists(self.filename+'.head'):
|
3176
3196
|
|
3177
3197
|
logging.info(_('Reading result step :{}'.format(self.current_result)))
|
3178
|
-
wolfpy.r2d_init(self.filename.ljust(255).encode('ansi'))
|
3198
|
+
# wolfpy.r2d_init(self.filename.ljust(255).encode('ansi'))
|
3179
3199
|
|
3180
3200
|
for i in range(self.nb_blocks):
|
3181
3201
|
self.read_oneblockresult(self.current_result, i+1)
|
@@ -4989,7 +5009,11 @@ class Wolfresults_2D(Element_To_Draw):
|
|
4989
5009
|
curdanger.reset()
|
4990
5010
|
curdanger.mask_reset()
|
4991
5011
|
|
4992
|
-
|
5012
|
+
to_compute = np.arange(start, end, every)
|
5013
|
+
#add the end
|
5014
|
+
if end not in to_compute:
|
5015
|
+
to_compute = np.append(to_compute, end)
|
5016
|
+
for time_step in tqdm(to_compute):
|
4993
5017
|
|
4994
5018
|
if callback is not None:
|
4995
5019
|
callback(time_step, "Step {} / {}".format(time_step+1, end))
|
@@ -5066,6 +5090,111 @@ class Wolfresults_2D(Element_To_Draw):
|
|
5066
5090
|
|
5067
5091
|
return (danger_map_matrix_h, danger_map_matrix_v, danger_map_matrix_mom, danger_map_matrix_z, danger_map_matrix_head)
|
5068
5092
|
|
5093
|
+
def __getstate__(self):
|
5094
|
+
"""Get the state of the object for pickling"""
|
5095
|
+
state = self.__dict__.copy()
|
5096
|
+
# Remove unpicklable attributes
|
5097
|
+
|
5098
|
+
topop = ['mapviewer', 'properties', 'mngselection', 'myops']
|
5099
|
+
|
5100
|
+
for cur_pop in topop:
|
5101
|
+
if cur_pop in state:
|
5102
|
+
state.pop(cur_pop)
|
5103
|
+
return state
|
5104
|
+
|
5105
|
+
def __setstate__(self, state):
|
5106
|
+
"""Set the state of the object after unpickling"""
|
5107
|
+
# Restore the state of the object
|
5108
|
+
self.__dict__.update(state)
|
5109
|
+
# Reinitialize any attributes that were removed during pickling
|
5110
|
+
self.mapviewer = None
|
5111
|
+
self.properties = None
|
5112
|
+
self.mngselection = None
|
5113
|
+
self.myops = None
|
5114
|
+
|
5115
|
+
def danger_map_multiprocess(self, start:int=0, end:int=-1, every:int=1, callback=None, nb_processors:int = -1) -> Union[tuple[WolfArray, WolfArray, WolfArray, WolfArray], tuple[WolfArrayMB, WolfArrayMB, WolfArrayMB, WolfArrayMB]]:
|
5116
|
+
"""
|
5117
|
+
Create Danger Maps using multiprocessing
|
5118
|
+
|
5119
|
+
:param start: start time step - 0-based
|
5120
|
+
:param end: end time step - 0-based
|
5121
|
+
:param every: step interval
|
5122
|
+
:param callback: optional callback to update progress
|
5123
|
+
"""
|
5124
|
+
|
5125
|
+
from multiprocessing import Pool, cpu_count
|
5126
|
+
|
5127
|
+
if nb_processors == -1:
|
5128
|
+
nb_processors = cpu_count()
|
5129
|
+
|
5130
|
+
if nb_processors > self.get_nbresults():
|
5131
|
+
nb_processors = self.get_nbresults()
|
5132
|
+
|
5133
|
+
# Split the range of time steps into chunks for multiprocessing
|
5134
|
+
if end == -1:
|
5135
|
+
end = self.get_nbresults()
|
5136
|
+
|
5137
|
+
starts = [start + i * every for i in range(nb_processors)]
|
5138
|
+
ends = [end - i * every for i in range(nb_processors-1,-1,-1)]
|
5139
|
+
|
5140
|
+
# pop all start above end
|
5141
|
+
for i in range(nb_processors-1,0,-1):
|
5142
|
+
if starts[i] >= end:
|
5143
|
+
starts.pop(i)
|
5144
|
+
ends.pop(i)
|
5145
|
+
|
5146
|
+
# set end above start
|
5147
|
+
for i in range(len(starts)):
|
5148
|
+
if starts[i] >= ends[i]:
|
5149
|
+
ends[i] = starts[i] + every
|
5150
|
+
|
5151
|
+
chunks = [(self, start + i * every, end - (nb_processors - i) * every + 1, nb_processors) for i in range(min(nb_processors, len(starts)))]
|
5152
|
+
|
5153
|
+
# Create a pool of workers
|
5154
|
+
with Pool(processes=nb_processors) as pool:
|
5155
|
+
results = pool.map(_process_danger_map_chunk, chunks)
|
5156
|
+
|
5157
|
+
danger_map_matrix_h = self.as_WolfArray(copyarray=True)
|
5158
|
+
danger_map_matrix_v = self.as_WolfArray(copyarray=True)
|
5159
|
+
danger_map_matrix_mom = self.as_WolfArray(copyarray=True)
|
5160
|
+
danger_map_matrix_z = self.as_WolfArray(copyarray=True)
|
5161
|
+
danger_map_matrix_head= self.as_WolfArray(copyarray=True)
|
5162
|
+
|
5163
|
+
danger = [danger_map_matrix_h, danger_map_matrix_v, danger_map_matrix_mom, danger_map_matrix_z, danger_map_matrix_head]
|
5164
|
+
|
5165
|
+
for curdanger in danger:
|
5166
|
+
curdanger.nullvalue = 0.
|
5167
|
+
curdanger.reset()
|
5168
|
+
curdanger.mask_reset()
|
5169
|
+
|
5170
|
+
if self.nb_blocks>1:
|
5171
|
+
for result in results:
|
5172
|
+
for idx, curdanger in enumerate(danger):
|
5173
|
+
for i in range(self.nb_blocks):
|
5174
|
+
curdanger[i].array.data = np.maximum(curdanger[i].array.data, result[idx][i].array.data)
|
5175
|
+
curdanger[i].array.mask = np.logical_or(curdanger[i].array.mask, result[idx][i].array.mask)
|
5176
|
+
else:
|
5177
|
+
for result in results:
|
5178
|
+
for idx, curdanger in enumerate(danger):
|
5179
|
+
curdanger.array.data[:,:] = np.maximum(curdanger.array.data, result[idx].array.data)
|
5180
|
+
curdanger.array.mask[:,:] = np.logical_or(curdanger.array.mask, result[idx].array.mask)
|
5181
|
+
|
5182
|
+
danger_map_matrix_h.mask_lower(self.epsilon)
|
5183
|
+
|
5184
|
+
if self.nb_blocks>1:
|
5185
|
+
for i in range(self.nb_blocks):
|
5186
|
+
danger_map_matrix_v[i].array.mask[:,:] = danger_map_matrix_h[i].array.mask[:,:]
|
5187
|
+
danger_map_matrix_mom[i].array.mask[:,:] = danger_map_matrix_h[i].array.mask[:,:]
|
5188
|
+
danger_map_matrix_z[i].array.mask[:,:] = danger_map_matrix_h[i].array.mask[:,:]
|
5189
|
+
danger_map_matrix_head[i].array.mask[:,:] = danger_map_matrix_h[i].array.mask[:,:]
|
5190
|
+
else:
|
5191
|
+
danger_map_matrix_v.array.mask[:,:] = danger_map_matrix_h.array.mask[:,:]
|
5192
|
+
danger_map_matrix_mom.array.mask[:,:] = danger_map_matrix_h.array.mask[:,:]
|
5193
|
+
danger_map_matrix_z.array.mask[:,:] = danger_map_matrix_h.array.mask[:,:]
|
5194
|
+
danger_map_matrix_head.array.mask[:,:] = danger_map_matrix_h.array.mask[:,:]
|
5195
|
+
|
5196
|
+
return (danger_map_matrix_h, danger_map_matrix_v, danger_map_matrix_mom, danger_map_matrix_z, danger_map_matrix_head)
|
5197
|
+
|
5069
5198
|
def danger_map_only_h(self, start:int=0, end:int=-1, every:int=1) -> WolfArray:
|
5070
5199
|
"""
|
5071
5200
|
Create Danger Maps
|
@@ -5431,7 +5560,7 @@ class Wolfresults_2D(Element_To_Draw):
|
|
5431
5560
|
curavg.mask_reset()
|
5432
5561
|
|
5433
5562
|
for time_step in tqdm(range(start, end, every)):
|
5434
|
-
|
5563
|
+
|
5435
5564
|
if callback is not None:
|
5436
5565
|
callback(time_step, "Step {} / {}".format(time_step+1, end))
|
5437
5566
|
|