wolfhece 2.2.15__py3-none-any.whl → 2.2.17__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.
@@ -39,7 +39,7 @@ from .drawing_obj import Element_To_Draw
39
39
  from .PyPalette import wolfpalette
40
40
  from .PyTranslate import _
41
41
  from .gpuview import GRID_N, Rectangle, VectorField
42
- from .pyshields import get_d_cr, get_d_cr_susp, izbach_d_cr, get_Shields_2D_Manning, get_friction_slope_2D_Manning, get_shear_velocity_2D_Manning
42
+ from .pyshields import get_d_cr, get_d_cr_susp, izbach_d_cr, get_Shields_2D_Manning, get_friction_slope_2D_Manning, get_shear_velocity_2D_Manning, get_shear_velocity_2D_Colebrook
43
43
  from .pyviews import WolfViews
44
44
  from .mesh2d.wolf2dprev import prev_parameters_simul, blocks_file
45
45
  from .GraphNotebook import PlotPanel
@@ -76,67 +76,135 @@ from .wolf_array import WolfArray, getkeyblock, header_wolf, WolfArrayMB, WolfAr
76
76
  from .mesh2d import wolf2dprev
77
77
  from .PyVertexvectors import vector, zone, Zones
78
78
 
79
+ from numba import jit, njit
79
80
 
80
81
  def outside_domain(val):
81
82
  """ Test if a value is outside the calculated domain """
82
83
  return val[0][0] is np.ma.masked or val[1][0] =='-'
83
84
 
84
- def q_splitting(q_left, q_right):
85
- """ Splitting of the normal flow between two nodes """
85
+ @jit(nopython=True, nogil=True, cache=True)
86
+ def splitting_rule(q_left:float, q_right:float) -> float:
87
+ """ Ponderation factor - Splitting at border between two nodes
86
88
 
89
+ :return: factor of the left node (0.5 = equal splitting)
90
+ """
91
+ epsilon = 1.e-100
92
+ prod_q = q_left * q_right # product of the two flows
93
+ sum_q = q_left + q_right # sum of the two flows
94
+ if prod_q > 0.:
95
+ # The 2 flows are in the same direction
96
+ if q_left > 0.:
97
+ # left is the upstream node
98
+ return 1.
99
+ else:
100
+ # right is the upstream node
101
+ return 0.
102
+ elif prod_q < 0.:
103
+ # The 2 flows are in opposite direction
104
+ if q_left > 0.:
105
+ if sum_q > 0.:
106
+ # The sum is positive, the left node is the upstream node
107
+ return 1.
108
+ elif sum_q < 0.:
109
+ # The sum is negative, the right node is the upstream node
110
+ return 0.
111
+ else:
112
+ # The sum is null, the flow is centered between the two nodes
113
+ return 0.5
114
+ elif q_left < 0.:
115
+ # CONFLICTING FLOWS
116
+ return 0.5
117
+ else:
118
+ # should not be possible
119
+ raise ValueError("Splitting rule: q_left is null but product is negative")
120
+ else:
121
+ # One flow is null or the product is so small that it is considered as null.
122
+ # FYI, in the GPU code, we compare to espilon.
123
+ if q_left>epsilon:
124
+ # left is the upstream node
125
+ return 1.
126
+ elif q_right<-epsilon:
127
+ # right is the upstream node
128
+ return 0.
129
+ else:
130
+ # The flow is centered between the two nodes
131
+ return .5
132
+
133
+ @jit(nopython=True, nogil=True, cache=True)
134
+ def q_splitting(q_left:float, q_right:float) -> float:
135
+ """ Splitting of the normal flow between two nodes """
136
+ #FIXME : use splitting_rule ?
137
+ epsilon = 1.e-100
87
138
  prod_q = q_left * q_right
88
- sum_q = q_left + q_right
139
+ sum_q = q_left + q_right
89
140
  if prod_q > 0.:
90
141
  if q_left > 0.:
91
142
  return q_left
92
143
  else:
93
144
  return q_right
94
145
  elif prod_q < 0.:
95
- if sum_q > 0.:
96
- return q_left
97
- elif sum_q < 0.:
98
- return q_right
146
+ if q_left > 0.:
147
+ if sum_q > 0.:
148
+ return q_left
149
+ elif sum_q < 0.:
150
+ return q_right
151
+ else:
152
+ return 0.
153
+ elif q_left < 0.:
154
+ # CONFLICTING FLOWS
155
+ return sum_q / 2.
99
156
  else:
100
- return 0.
157
+ # should not be possible
158
+ raise ValueError("Splitting rule: q_left is null but product is negative")
101
159
  else:
102
- if q_left<0.:
103
- return 0.
104
- elif q_right<0.:
105
- return 0.
160
+ if q_left>epsilon:
161
+ # Left is the upstream node
162
+ return q_left
163
+ elif q_right<-epsilon:
164
+ # right is the upstream node
165
+ return q_right
106
166
  else:
107
167
  return sum_q / 2.
108
168
 
109
- def u_splitting(q_left, q_right, h_left, h_right):
169
+ @jit(nopython=True, nogil=True, cache=True)
170
+ def u_splitting(q_left:float, q_right:float, h_left:float, h_right:float) -> float:
110
171
  """ Splitting of the normal flow velocity between two nodes """
111
-
172
+ #FIXME : use splitting_rule ?
173
+ epsilon = 1.e-100
112
174
  prod_q = q_left * q_right
113
- sum_q = q_left + q_right
175
+ sum_q = q_left + q_right
114
176
  if prod_q > 0.:
115
177
  if q_left > 0.:
116
178
  return q_left/h_left
117
179
  else:
118
180
  return q_right/h_right
119
181
  elif prod_q < 0.:
120
- if sum_q > 0.:
121
- return q_left/h_left
122
- elif sum_q < 0.:
123
- return q_right/h_right
182
+ if q_left > 0.:
183
+ if sum_q > 0.:
184
+ return q_left/h_left
185
+ elif sum_q < 0.:
186
+ return q_right/h_right
187
+ else:
188
+ return 0.
189
+ elif q_left < 0.:
190
+ return (q_left/h_left + q_right/h_right) / 2.
124
191
  else:
125
- return 0.
192
+ # should not be possible
193
+ raise ValueError("Splitting rule: q_left is null but product is negative")
126
194
  else:
127
- if q_left<0.:
128
- return 0.
129
- elif q_right<0.:
130
- return 0.
195
+ if q_left>epsilon:
196
+ return q_left / h_left
197
+ elif q_right<-epsilon:
198
+ return q_right / h_right
131
199
  else:
132
200
  return (q_left/h_left + q_right/h_right) / 2.
133
201
 
134
202
  def _process_danger_map_chunk(chunk):
135
203
  import pickle
136
- obj, start, end, every = chunk
204
+ obj, start, end, every, hmin = chunk
137
205
  # Create a new instance of the class for each chunk
138
206
  new:Wolfresults_2D = pickle.loads(pickle.dumps(obj))
139
- return new.danger_map(start, end, every)
207
+ return new.danger_map(start, end, every, None, hmin)
140
208
 
141
209
  class Props_Res_2D(wx.Frame):
142
210
  """
@@ -1507,6 +1575,7 @@ class OneWolfResult:
1507
1575
  """
1508
1576
  def __init__(self, idx:int=0, parent = None):
1509
1577
 
1578
+ self.parent:"Wolfresults_2D"
1510
1579
  self.parent = parent
1511
1580
 
1512
1581
  self.wx_exists = wx.GetApp() is not None
@@ -1539,6 +1608,13 @@ class OneWolfResult:
1539
1608
  self._sedimentdensity = 2.65
1540
1609
  self._force_update_shields = True # Force la MAJ du Shields si le diametre ou la densité change
1541
1610
 
1611
+ self._is_manning_strickler = True
1612
+ self._is_colebrook = False
1613
+
1614
+ self._has_turbulence_model = False
1615
+ self._cmu = 0.09
1616
+ self._cnu = 0.08
1617
+
1542
1618
  # self.mngselection = SelectionData(self.current)
1543
1619
 
1544
1620
  @property
@@ -1658,12 +1734,24 @@ class OneWolfResult:
1658
1734
  elif which==views_2D.HEAD:
1659
1735
  self._current=(self.qx**2.+self.qy**2.)**.5/self.waterdepth/(2.*9.81)+self.waterdepth+self.top
1660
1736
  nullvalue = self.qx.nullvalue
1737
+
1661
1738
  elif which==views_2D.KINETIC_ENERGY:
1662
1739
  self._current=self.k
1663
1740
  nullvalue = self.k.nullvalue
1664
1741
  elif which==views_2D.EPSILON:
1665
1742
  self._current=self.eps
1666
1743
  nullvalue = self.eps.nullvalue
1744
+
1745
+ elif which==views_2D.TURB_VISC_2D:
1746
+
1747
+ self._current = self.k**2./self.eps * self._cmu
1748
+ nullvalue = self.k.nullvalue
1749
+
1750
+ elif which==views_2D.TURB_VISC_3D:
1751
+ self.U_Shear = self.get_u_shear()
1752
+ self._current = self.U_Shear * self.waterdepth * self._cnu
1753
+ nullvalue = self.waterdepth.nullvalue
1754
+
1667
1755
  elif which==views_2D.VECTOR_FIELD_Q:
1668
1756
  self._current=(self.qx**2.+self.qy**2.)**.5
1669
1757
  nullvalue = self.qx.nullvalue
@@ -1966,7 +2054,12 @@ class OneWolfResult:
1966
2054
  qnorm = (self.qx**2.+self.qy**2.)**.5
1967
2055
  qnorm.array.mask=self.waterdepth.array.mask
1968
2056
 
1969
- _u_shear = np.asarray([get_shear_velocity_2D_Manning(qnorm.array[i,j],
2057
+ if self._is_manning_strickler:
2058
+ _u_shear = np.asarray([get_shear_velocity_2D_Manning(qnorm.array[i,j],
2059
+ self.waterdepth.array[i,j],
2060
+ self.rough_n.array.data[i,j]) for i,j in ij])
2061
+ elif self._is_colebrook:
2062
+ _u_shear = np.asarray([get_shear_velocity_2D_Colebrook(qnorm.array[i,j],
1970
2063
  self.waterdepth.array[i,j],
1971
2064
  self.rough_n.array.data[i,j]) for i,j in ij])
1972
2065
 
@@ -1974,9 +2067,16 @@ class OneWolfResult:
1974
2067
 
1975
2068
  return u_shear
1976
2069
 
2070
+ if not (self._is_manning_strickler or self._is_colebrook):
2071
+ logging.error(_('Surface friction is not Manning-Strickler or Colebrook.'))
2072
+ logging.error(_('Cannot compute shear velocity or Program it... in get_u_shear'))
2073
+ ret = WolfArray(mold=self.waterdepth)
2074
+ ret.array.fill(0.)
2075
+ return ret
2076
+
1977
2077
  logging.info(_('Computing shear velocity'))
1978
2078
  u_shear = compute()
1979
- logging.info(_('End of computing shear velocity'))
2079
+ # logging.info(_('End of computing shear velocity'))
1980
2080
 
1981
2081
  return u_shear
1982
2082
 
@@ -2207,118 +2307,194 @@ class Wolfresults_2D(Element_To_Draw):
2207
2307
  if fname is not None:
2208
2308
 
2209
2309
  if loader is not None:
2310
+ # Used for GPU results
2210
2311
  if loader(fname) <0:
2211
2312
  self.loaded = False
2212
2313
  logging.error(_('Error while loading results - Abort !'))
2213
2314
  return
2214
2315
 
2215
2316
  else:
2216
- parts=splitext(fname)
2217
- if len(parts)>1:
2218
- self.filename = parts[0]
2219
- else:
2220
- self.filename = fname
2221
-
2222
- self.filenamegen=self.filename
2223
- self._dll_tools = Tools2DFortran(self.filenamegen) # DLL de calculs de la classe Tools2DFortran
2224
-
2225
- if exists(self.filename + '.trl'):
2226
- with open(self.filename + '.trl') as f:
2227
- trl=f.read().splitlines()
2228
- self.translx=float(trl[1])
2229
- self.transly=float(trl[2])
2230
-
2231
- self.myblocks={}
2232
- self.read_param_simul()
2233
-
2234
- if exists(self.filename+'.head') or exists(join(dirname(self.filename),'bloc1.head')):
2235
- # wolfpy.r2d_init(self.filename.ljust(255).encode('ansi'))
2236
- # nb_blocks = wolfpy.r2d_nbblocks()
2237
-
2238
- nb_blocks = self._dll_tools.r2D_get_number_of_blocks()
2239
- for i in range(nb_blocks):
2240
- curblock = OneWolfResult(i, parent=self)
2241
- self.myblocks[getkeyblock(i)] = curblock
2242
-
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)
2245
-
2246
- curhead = self.head_blocks[getkeyblock(i)]=header_wolf()
2247
- curhead.nbx = nbx
2248
- curhead.nby = nby
2249
- curhead.origx = ox
2250
- curhead.origy = oy
2251
- curhead.dx = dx
2252
- curhead.dy = dy
2253
- curhead.translx = self.translx
2254
- curhead.transly = self.transly
2255
-
2256
- self.myblocks[getkeyblock(i)].waterdepth.dx = dx
2257
- self.myblocks[getkeyblock(i)].waterdepth.dy = dy
2258
- self.myblocks[getkeyblock(i)].waterdepth.nbx = nbx
2259
- self.myblocks[getkeyblock(i)].waterdepth.nby = nby
2260
- self.myblocks[getkeyblock(i)].waterdepth.origx = ox
2261
- self.myblocks[getkeyblock(i)].waterdepth.origy = oy
2262
- self.myblocks[getkeyblock(i)].waterdepth.translx = self.translx
2263
- self.myblocks[getkeyblock(i)].waterdepth.transly = self.transly
2264
-
2265
- self.myblocks[getkeyblock(i)].top.dx = dx
2266
- self.myblocks[getkeyblock(i)].top.dy = dy
2267
- self.myblocks[getkeyblock(i)].top.nbx = nbx
2268
- self.myblocks[getkeyblock(i)].top.nby = nby
2269
- self.myblocks[getkeyblock(i)].top.origx = ox
2270
- self.myblocks[getkeyblock(i)].top.origy = oy
2271
- self.myblocks[getkeyblock(i)].top.translx = self.translx
2272
- self.myblocks[getkeyblock(i)].top.transly = self.transly
2273
-
2274
- self.myblocks[getkeyblock(i)].qx.dx = dx
2275
- self.myblocks[getkeyblock(i)].qx.dy = dy
2276
- self.myblocks[getkeyblock(i)].qx.nbx = nbx
2277
- self.myblocks[getkeyblock(i)].qx.nby = nby
2278
- self.myblocks[getkeyblock(i)].qx.origx = ox
2279
- self.myblocks[getkeyblock(i)].qx.origy = oy
2280
- self.myblocks[getkeyblock(i)].qx.translx = self.translx
2281
- self.myblocks[getkeyblock(i)].qx.transly = self.transly
2282
-
2283
- self.myblocks[getkeyblock(i)].qy.dx = dx
2284
- self.myblocks[getkeyblock(i)].qy.dy = dy
2285
- self.myblocks[getkeyblock(i)].qy.nbx = nbx
2286
- self.myblocks[getkeyblock(i)].qy.nby = nby
2287
- self.myblocks[getkeyblock(i)].qy.origx = ox
2288
- self.myblocks[getkeyblock(i)].qy.origy = oy
2289
- self.myblocks[getkeyblock(i)].qy.translx = self.translx
2290
- self.myblocks[getkeyblock(i)].qy.transly = self.transly
2291
-
2292
- self.myblocks[getkeyblock(i)].rough_n.dx = dx
2293
- self.myblocks[getkeyblock(i)].rough_n.dy = dy
2294
- self.myblocks[getkeyblock(i)].rough_n.nbx = nbx
2295
- self.myblocks[getkeyblock(i)].rough_n.nby = nby
2296
- self.myblocks[getkeyblock(i)].rough_n.origx = ox
2297
- self.myblocks[getkeyblock(i)].rough_n.origy = oy
2298
- self.myblocks[getkeyblock(i)].rough_n.translx = self.translx
2299
- self.myblocks[getkeyblock(i)].rough_n.transly = self.transly
2300
-
2301
- else:
2302
- nb_blocks = self.myblocfile.nb_blocks
2303
-
2304
- for i in range(nb_blocks):
2305
- #print(f"Reading block {getkeyblock(i)}")
2306
- curblock = OneWolfResult(i, parent = self)
2307
- self.myblocks[getkeyblock(i)] = curblock
2308
- curblock.waterdepth.set_header(self.mymnap.head_blocks[getkeyblock(i)])
2309
- curblock.top.set_header(self.mymnap.head_blocks[getkeyblock(i)])
2310
- curblock.qx.set_header(self.mymnap.head_blocks[getkeyblock(i)])
2311
- curblock.qy.set_header(self.mymnap.head_blocks[getkeyblock(i)])
2312
- curblock.rough_n.set_header(self.mymnap.head_blocks[getkeyblock(i)])
2313
-
2314
- self.allocate_ressources()
2315
- self.read_topography()
2316
- self.read_ini_mb()
2317
-
2318
- self.loaded_rough = False
2317
+ self._loader_CPU2D(fname)
2318
+ # # We are here for "classic" CPU results
2319
+ # parts=splitext(fname)
2320
+ # if len(parts)>1:
2321
+ # self.filename = parts[0]
2322
+ # else:
2323
+ # self.filename = fname
2324
+
2325
+ # self.filenamegen=self.filename
2326
+ # self._dll_tools = Tools2DFortran(self.filenamegen) # DLL de calculs de la classe Tools2DFortran
2327
+
2328
+ # if exists(self.filename + '.trl'):
2329
+ # with open(self.filename + '.trl') as f:
2330
+ # trl=f.read().splitlines()
2331
+ # self.translx=float(trl[1])
2332
+ # self.transly=float(trl[2])
2333
+
2334
+ # self.myblocks={}
2335
+ # self.read_param_simul()
2336
+
2337
+ # if exists(self.filename+'.head') or exists(join(dirname(self.filename),'bloc1.head')):
2338
+ # # wolfpy.r2d_init(self.filename.ljust(255).encode('ansi'))
2339
+ # # nb_blocks = wolfpy.r2d_nbblocks()
2340
+
2341
+ # nb_blocks = self._dll_tools.r2D_get_number_of_blocks()
2342
+ # for i in range(nb_blocks):
2343
+ # curblock = OneWolfResult(i, parent=self)
2344
+ # self.myblocks[getkeyblock(i)] = curblock
2345
+
2346
+ # # nbx,nby,dx,dy,ox,oy,tx,ty = wolfpy.r2d_hblock(i+1)
2347
+ # nbx, nby,dx,dy,ox,oy,tx,ty = self._dll_tools.r2D_get_header_one_block(i+1)
2348
+
2349
+ # curhead = self.head_blocks[getkeyblock(i)]=header_wolf()
2350
+ # curhead.nbx = nbx
2351
+ # curhead.nby = nby
2352
+ # curhead.origx = ox
2353
+ # curhead.origy = oy
2354
+ # curhead.dx = dx
2355
+ # curhead.dy = dy
2356
+ # curhead.translx = self.translx
2357
+ # curhead.transly = self.transly
2358
+
2359
+ # curblock.waterdepth.dx = dx
2360
+ # curblock.waterdepth.dy = dy
2361
+ # curblock.waterdepth.nbx = nbx
2362
+ # curblock.waterdepth.nby = nby
2363
+ # curblock.waterdepth.origx = ox
2364
+ # curblock.waterdepth.origy = oy
2365
+ # curblock.waterdepth.translx = self.translx
2366
+ # curblock.waterdepth.transly = self.transly
2367
+
2368
+ # curblock.top.dx = dx
2369
+ # curblock.top.dy = dy
2370
+ # curblock.top.nbx = nbx
2371
+ # curblock.top.nby = nby
2372
+ # curblock.top.origx = ox
2373
+ # curblock.top.origy = oy
2374
+ # curblock.top.translx = self.translx
2375
+ # curblock.top.transly = self.transly
2376
+
2377
+ # curblock.qx.dx = dx
2378
+ # curblock.qx.dy = dy
2379
+ # curblock.qx.nbx = nbx
2380
+ # curblock.qx.nby = nby
2381
+ # curblock.qx.origx = ox
2382
+ # curblock.qx.origy = oy
2383
+ # curblock.qx.translx = self.translx
2384
+ # curblock.qx.transly = self.transly
2385
+
2386
+ # curblock.qy.dx = dx
2387
+ # curblock.qy.dy = dy
2388
+ # curblock.qy.nbx = nbx
2389
+ # curblock.qy.nby = nby
2390
+ # curblock.qy.origx = ox
2391
+ # curblock.qy.origy = oy
2392
+ # curblock.qy.translx = self.translx
2393
+ # curblock.qy.transly = self.transly
2394
+
2395
+ # curblock.rough_n.dx = dx
2396
+ # curblock.rough_n.dy = dy
2397
+ # curblock.rough_n.nbx = nbx
2398
+ # curblock.rough_n.nby = nby
2399
+ # curblock.rough_n.origx = ox
2400
+ # curblock.rough_n.origy = oy
2401
+ # curblock.rough_n.translx = self.translx
2402
+ # curblock.rough_n.transly = self.transly
2403
+
2404
+ # curblock.eps.dx = dx
2405
+ # curblock.eps.dy = dy
2406
+ # curblock.eps.nbx = nbx
2407
+ # curblock.eps.nby = nby
2408
+ # curblock.eps.origx = ox
2409
+ # curblock.eps.origy = oy
2410
+ # curblock.eps.translx = self.translx
2411
+ # curblock.eps.transly = self.transly
2412
+
2413
+ # curblock.k.dx = dx
2414
+ # curblock.k.dy = dy
2415
+ # curblock.k.nbx = nbx
2416
+ # curblock.k.nby = nby
2417
+ # curblock.k.origx = ox
2418
+ # curblock.k.origy = oy
2419
+ # curblock.k.translx = self.translx
2420
+ # curblock.k.transly = self.transly
2421
+
2422
+ # curblock._is_manning_strickler = self.myparam.blocks[i].is_Manning_surface_friction
2423
+ # curblock._is_colebrook = self.myparam.blocks[i].is_Colebrook_surface_friction
2424
+ # curblock._has_turbulence_model = self.myparam.blocks[i].has_turbulence
2425
+
2426
+ # _param_turb = self.myparam.blocks[i].get_params_turbulence()
2427
+ # if 'cmu' in _param_turb:
2428
+ # curblock._cmu = _param_turb['cmu']
2429
+ # if 'cnu' in _param_turb:
2430
+ # curblock._cnu = _param_turb['cnu']
2431
+
2432
+ # else:
2433
+ # nb_blocks = self.myblocfile.nb_blocks
2434
+
2435
+ # for i in range(nb_blocks):
2436
+ # #print(f"Reading block {getkeyblock(i)}")
2437
+ # curblock = OneWolfResult(i, parent = self)
2438
+ # self.myblocks[getkeyblock(i)] = curblock
2439
+ # curblock.waterdepth.set_header(self.mymnap.head_blocks[getkeyblock(i)])
2440
+ # curblock.top.set_header(self.mymnap.head_blocks[getkeyblock(i)])
2441
+ # curblock.qx.set_header(self.mymnap.head_blocks[getkeyblock(i)])
2442
+ # curblock.qy.set_header(self.mymnap.head_blocks[getkeyblock(i)])
2443
+ # curblock.rough_n.set_header(self.mymnap.head_blocks[getkeyblock(i)])
2444
+ # curblock.eps.set_header(self.mymnap.head_blocks[getkeyblock(i)])
2445
+ # curblock.k.set_header(self.mymnap.head_blocks[getkeyblock(i)])
2446
+
2447
+ # curblock._is_manning_strickler = self.myparam.blocks[i].is_Manning_surface_friction
2448
+ # curblock._is_colebrook = self.myparam.blocks[i].is_Colebrook_surface_friction
2449
+ # curblock._has_turbulence_model = self.myparam.blocks[i].has_turbulence
2450
+
2451
+ # _param_turb = self.myparam.blocks[i].get_params_turbulence()
2452
+ # if 'cmu' in _param_turb:
2453
+ # curblock._cmu = _param_turb['cmu']
2454
+ # if 'cnu' in _param_turb:
2455
+ # curblock._cnu = _param_turb['cnu']
2456
+
2457
+ # self.allocate_ressources()
2458
+ # self.read_topography()
2459
+ # self.read_ini_mb()
2460
+
2461
+ # self.loaded_rough = False
2319
2462
  else:
2320
2463
  self.myblocks={}
2321
2464
 
2465
+ self._post_loader()
2466
+ # self.nbx = 1
2467
+ # self.nby = 1
2468
+
2469
+ # ox=9999999.
2470
+ # oy=9999999.
2471
+ # ex=-9999999.
2472
+ # ey=-9999999.
2473
+ # for curblock in self.myblocks.values():
2474
+ # curhead=curblock.waterdepth.get_header(False)
2475
+ # ox=min(ox,curhead.origx)
2476
+ # oy=min(oy,curhead.origy)
2477
+ # ex=max(ex,curhead.origx+float(curhead.nbx)*curhead.dx)
2478
+ # ey=max(ey,curhead.origy+float(curhead.nby)*curhead.dy)
2479
+ # self.dx = ex-ox
2480
+ # self.dy = ey-oy
2481
+ # self.origx = ox
2482
+ # self.origy = oy
2483
+
2484
+ # self._nb_results = None
2485
+ # self.timesteps = []
2486
+ # self.times = []
2487
+
2488
+ # self.properties:Props_Res_2D = None
2489
+ # self.set_properties()
2490
+
2491
+ # self.mngselection = SelectionDataMB(self)
2492
+ # self.myops = None
2493
+ # self._active_blocks = 0
2494
+
2495
+ def _post_loader(self):
2496
+ """ Post loader for CPU/GPU results """
2497
+
2322
2498
  self.nbx = 1
2323
2499
  self.nby = 1
2324
2500
 
@@ -2348,6 +2524,188 @@ class Wolfresults_2D(Element_To_Draw):
2348
2524
  self.myops = None
2349
2525
  self._active_blocks = 0
2350
2526
 
2527
+ def _loader_CPU2D(self, fname:str) -> int:
2528
+ """ Loader for CPU results """
2529
+
2530
+ # We are here for "classic" CPU results
2531
+ parts=splitext(fname)
2532
+ if len(parts)>1:
2533
+ self.filename = parts[0]
2534
+ else:
2535
+ self.filename = fname
2536
+
2537
+ self.filenamegen=self.filename
2538
+ self._dll_tools = Tools2DFortran(self.filenamegen) # DLL de calculs de la classe Tools2DFortran
2539
+
2540
+ if exists(self.filename + '.trl'):
2541
+ with open(self.filename + '.trl') as f:
2542
+ trl=f.read().splitlines()
2543
+ self.translx=float(trl[1])
2544
+ self.transly=float(trl[2])
2545
+
2546
+ self.myblocks={}
2547
+ self.read_param_simul()
2548
+
2549
+ if exists(self.filename+'.head') or exists(join(dirname(self.filename),'bloc1.head')):
2550
+ # wolfpy.r2d_init(self.filename.ljust(255).encode('ansi'))
2551
+ # nb_blocks = wolfpy.r2d_nbblocks()
2552
+
2553
+ nb_blocks = self._dll_tools.r2D_get_number_of_blocks()
2554
+ for i in range(nb_blocks):
2555
+ curblock = OneWolfResult(i, parent=self)
2556
+ self.myblocks[getkeyblock(i)] = curblock
2557
+
2558
+ # nbx,nby,dx,dy,ox,oy,tx,ty = wolfpy.r2d_hblock(i+1)
2559
+ nbx, nby,dx,dy,ox,oy,tx,ty = self._dll_tools.r2D_get_header_one_block(i+1)
2560
+
2561
+ curhead = self.head_blocks[getkeyblock(i)]=header_wolf()
2562
+ curhead.nbx = nbx
2563
+ curhead.nby = nby
2564
+ curhead.origx = ox
2565
+ curhead.origy = oy
2566
+ curhead.dx = dx
2567
+ curhead.dy = dy
2568
+ curhead.translx = self.translx
2569
+ curhead.transly = self.transly
2570
+
2571
+ curblock.waterdepth.dx = dx
2572
+ curblock.waterdepth.dy = dy
2573
+ curblock.waterdepth.nbx = nbx
2574
+ curblock.waterdepth.nby = nby
2575
+ curblock.waterdepth.origx = ox
2576
+ curblock.waterdepth.origy = oy
2577
+ curblock.waterdepth.translx = self.translx
2578
+ curblock.waterdepth.transly = self.transly
2579
+
2580
+ curblock.top.dx = dx
2581
+ curblock.top.dy = dy
2582
+ curblock.top.nbx = nbx
2583
+ curblock.top.nby = nby
2584
+ curblock.top.origx = ox
2585
+ curblock.top.origy = oy
2586
+ curblock.top.translx = self.translx
2587
+ curblock.top.transly = self.transly
2588
+
2589
+ curblock.qx.dx = dx
2590
+ curblock.qx.dy = dy
2591
+ curblock.qx.nbx = nbx
2592
+ curblock.qx.nby = nby
2593
+ curblock.qx.origx = ox
2594
+ curblock.qx.origy = oy
2595
+ curblock.qx.translx = self.translx
2596
+ curblock.qx.transly = self.transly
2597
+
2598
+ curblock.qy.dx = dx
2599
+ curblock.qy.dy = dy
2600
+ curblock.qy.nbx = nbx
2601
+ curblock.qy.nby = nby
2602
+ curblock.qy.origx = ox
2603
+ curblock.qy.origy = oy
2604
+ curblock.qy.translx = self.translx
2605
+ curblock.qy.transly = self.transly
2606
+
2607
+ curblock.rough_n.dx = dx
2608
+ curblock.rough_n.dy = dy
2609
+ curblock.rough_n.nbx = nbx
2610
+ curblock.rough_n.nby = nby
2611
+ curblock.rough_n.origx = ox
2612
+ curblock.rough_n.origy = oy
2613
+ curblock.rough_n.translx = self.translx
2614
+ curblock.rough_n.transly = self.transly
2615
+
2616
+ curblock.eps.dx = dx
2617
+ curblock.eps.dy = dy
2618
+ curblock.eps.nbx = nbx
2619
+ curblock.eps.nby = nby
2620
+ curblock.eps.origx = ox
2621
+ curblock.eps.origy = oy
2622
+ curblock.eps.translx = self.translx
2623
+ curblock.eps.transly = self.transly
2624
+
2625
+ curblock.k.dx = dx
2626
+ curblock.k.dy = dy
2627
+ curblock.k.nbx = nbx
2628
+ curblock.k.nby = nby
2629
+ curblock.k.origx = ox
2630
+ curblock.k.origy = oy
2631
+ curblock.k.translx = self.translx
2632
+ curblock.k.transly = self.transly
2633
+
2634
+ curblock._is_manning_strickler = self.myparam.blocks[i].is_Manning_surface_friction
2635
+ curblock._is_colebrook = self.myparam.blocks[i].is_Colebrook_surface_friction
2636
+ curblock._has_turbulence_model = self.myparam.blocks[i].has_turbulence
2637
+
2638
+ _param_turb = self.myparam.blocks[i].get_params_turbulence()
2639
+ if 'cmu' in _param_turb:
2640
+ curblock._cmu = _param_turb['cmu']
2641
+ if 'cnu' in _param_turb:
2642
+ curblock._cnu = _param_turb['cnu']
2643
+
2644
+ else:
2645
+ nb_blocks = self.myblocfile.nb_blocks
2646
+
2647
+ for i in range(nb_blocks):
2648
+ #print(f"Reading block {getkeyblock(i)}")
2649
+ curblock = OneWolfResult(i, parent = self)
2650
+ self.myblocks[getkeyblock(i)] = curblock
2651
+ curblock.waterdepth.set_header(self.mymnap.head_blocks[getkeyblock(i)])
2652
+ curblock.top.set_header(self.mymnap.head_blocks[getkeyblock(i)])
2653
+ curblock.qx.set_header(self.mymnap.head_blocks[getkeyblock(i)])
2654
+ curblock.qy.set_header(self.mymnap.head_blocks[getkeyblock(i)])
2655
+ curblock.rough_n.set_header(self.mymnap.head_blocks[getkeyblock(i)])
2656
+ curblock.eps.set_header(self.mymnap.head_blocks[getkeyblock(i)])
2657
+ curblock.k.set_header(self.mymnap.head_blocks[getkeyblock(i)])
2658
+
2659
+ curblock._is_manning_strickler = self.myparam.blocks[i].is_Manning_surface_friction
2660
+ curblock._is_colebrook = self.myparam.blocks[i].is_Colebrook_surface_friction
2661
+ curblock._has_turbulence_model = self.myparam.blocks[i].has_turbulence
2662
+
2663
+ _param_turb = self.myparam.blocks[i].get_params_turbulence()
2664
+ if 'cmu' in _param_turb:
2665
+ curblock._cmu = _param_turb['cmu']
2666
+ if 'cnu' in _param_turb:
2667
+ curblock._cnu = _param_turb['cnu']
2668
+
2669
+ self.allocate_ressources()
2670
+ self.read_topography()
2671
+ self.read_ini_mb()
2672
+
2673
+ self.loaded_rough = False
2674
+
2675
+ def __getstate__(self):
2676
+ """Get the state of the object for pickling"""
2677
+ state = self.__dict__.copy()
2678
+ # Remove unpicklable attributes
2679
+
2680
+ topop = ['mapviewer',
2681
+ 'properties',
2682
+ 'mngselection',
2683
+ 'myops',
2684
+ '_dll_tools',
2685
+ 'myparam',
2686
+ 'myblocfile',
2687
+ 'mymnap']
2688
+
2689
+ for cur_pop in topop:
2690
+ if cur_pop in state:
2691
+ state.pop(cur_pop)
2692
+ return state
2693
+
2694
+ def __setstate__(self, state):
2695
+ """Set the state of the object after unpickling"""
2696
+ # Restore the state of the object
2697
+ self.__dict__.update(state)
2698
+ # Reinitialize any attributes that were removed during pickling
2699
+ self.mapviewer = None
2700
+ self.properties = None
2701
+ self.mngselection = None
2702
+ self.myops = None
2703
+
2704
+ if not 'isGPU' in list(state.keys()):
2705
+ self._loader_CPU2D(self.filenamegen)
2706
+ self._post_loader()
2707
+ self._dll_tools = Tools2DFortran(self.filenamegen)
2708
+
2351
2709
  @property
2352
2710
  def all_dt(self):
2353
2711
  #FIXME : defined in GPU version --> to be implemented for CPU version
@@ -2832,7 +3190,6 @@ class Wolfresults_2D(Element_To_Draw):
2832
3190
  self.myparam.read_file(self.filename)
2833
3191
 
2834
3192
  self.myblocfile = blocks_file(self)
2835
- # self.myblocfile.read_file()
2836
3193
 
2837
3194
  self.mymnap = WolfArrayMNAP(self.filename)
2838
3195
 
@@ -2864,7 +3221,7 @@ class Wolfresults_2D(Element_To_Draw):
2864
3221
  for curblock in self.myblocks.values():
2865
3222
  curblock.filter_independent_zones(n_largest)
2866
3223
 
2867
- def set_currentview(self, which=None, force_wx=False, force_updatepal:bool=False):
3224
+ def set_currentview(self, which:views_2D = None, force_wx:bool = False, force_updatepal:bool=False):
2868
3225
  """
2869
3226
  Set the current view --> see 'views_2D' for supported values
2870
3227
 
@@ -2895,11 +3252,14 @@ class Wolfresults_2D(Element_To_Draw):
2895
3252
  self.plotting=True
2896
3253
  self.mimic_plotdata()
2897
3254
 
2898
- if which in VIEWS_SEDIMENTARY:
3255
+ if which in VIEWS_SEDIMENTARY + [views_2D.TURB_VISC_3D, views_2D.U_SHEAR]:
2899
3256
 
2900
3257
  if not self.loaded_rough:
2901
3258
  self.read_roughness_param()
2902
3259
 
3260
+ if which in [views_2D.KINETIC_ENERGY, views_2D.TURB_VISC_2D, views_2D.TURB_VISC_3D, views_2D.EPSILON]:
3261
+ self.read_oneresult(self.current_result)
3262
+
2903
3263
  for curblock in self.myblocks.values():
2904
3264
  curblock.set_current(which)
2905
3265
 
@@ -2933,6 +3293,8 @@ class Wolfresults_2D(Element_To_Draw):
2933
3293
  if self.mapviewer is not None:
2934
3294
  self.reset_plot()
2935
3295
  self.mapviewer.Refresh()
3296
+ else:
3297
+ logging.error(_('Unknown view - {}'.format(which)))
2936
3298
 
2937
3299
  def allocate_ressources(self):
2938
3300
  """Allocation de l'espace mémoire utile pour le stockage des résultats de chaque bloc"""
@@ -4976,7 +5338,10 @@ class Wolfresults_2D(Element_To_Draw):
4976
5338
  self.get_working_array()
4977
5339
  self.updatepalette(whichpal)
4978
5340
 
4979
- def danger_map(self, start:int=0, end:int=-1, every:int=1, callback=None) -> Union[tuple[WolfArray, WolfArray, WolfArray, WolfArray], tuple[WolfArrayMB, WolfArrayMB, WolfArrayMB, WolfArrayMB]]:
5341
+ def danger_map(self, start:int=0, end:int=-1,
5342
+ every:int=1, callback=None,
5343
+ hmin:float = None) -> Union[tuple[WolfArray, WolfArray, WolfArray, WolfArray, WolfArray, WolfArray],
5344
+ tuple[WolfArrayMB, WolfArrayMB, WolfArrayMB, WolfArrayMB, WolfArrayMB, WolfArrayMB]]:
4980
5345
  """
4981
5346
  Create Danger Maps
4982
5347
 
@@ -4985,13 +5350,22 @@ class Wolfresults_2D(Element_To_Draw):
4985
5350
  :param every: step interval
4986
5351
  :param callback: optional callback to update progress
4987
5352
 
4988
- :return : tuple of WolfArray or WolfArrayMB - H, U_norm, Q_norm, Z, Head
5353
+ :return : tuple of WolfArray or WolfArrayMB - H, U_norm, Q_norm, Z, Head, Time_of_arrival, Time_of_maximum
4989
5354
  """
4990
5355
 
5356
+ DEFAULT_TOA = 0.
5357
+
5358
+ if hmin is None:
5359
+ hmin = self.epsilon
5360
+
4991
5361
  # Number of time steps
4992
5362
  number_of_time_steps = self.get_nbresults()
4993
5363
  if end ==-1:
4994
- end = number_of_time_steps
5364
+ end = number_of_time_steps - 1
5365
+
5366
+ if end > number_of_time_steps:
5367
+ logging.warning("End time step is greater than the number of time steps. Setting end to the last time step.")
5368
+ end = number_of_time_steps - 1
4995
5369
 
4996
5370
  # Init Danger Maps basde on results type
4997
5371
  # If only one block --> WolfArray
@@ -5002,7 +5376,16 @@ class Wolfresults_2D(Element_To_Draw):
5002
5376
  danger_map_matrix_z = self.as_WolfArray(copyarray=True)
5003
5377
  danger_map_matrix_head= self.as_WolfArray(copyarray=True)
5004
5378
 
5005
- danger = [danger_map_matrix_h, danger_map_matrix_v, danger_map_matrix_mom, danger_map_matrix_z, danger_map_matrix_head]
5379
+ danger_map_matrix_toa = self.as_WolfArray(copyarray=True)
5380
+ danger_map_matrix_tom = self.as_WolfArray(copyarray=True)
5381
+
5382
+ danger = [danger_map_matrix_h,
5383
+ danger_map_matrix_v,
5384
+ danger_map_matrix_mom,
5385
+ danger_map_matrix_z,
5386
+ danger_map_matrix_head,
5387
+ danger_map_matrix_toa,
5388
+ danger_map_matrix_tom]
5006
5389
 
5007
5390
  for curdanger in danger:
5008
5391
  curdanger.nullvalue = 0.
@@ -5013,12 +5396,15 @@ class Wolfresults_2D(Element_To_Draw):
5013
5396
  #add the end
5014
5397
  if end not in to_compute:
5015
5398
  to_compute = np.append(to_compute, end)
5399
+
5016
5400
  for time_step in tqdm(to_compute):
5017
5401
 
5018
5402
  if callback is not None:
5019
- callback(time_step, "Step {} / {}".format(time_step+1, end))
5403
+ callback(time_step, "Step {} / {}".format(int(time_step+1), int(end)))
5020
5404
 
5021
- self.read_oneresult(time_step+1)
5405
+ self.read_oneresult(time_step)
5406
+
5407
+ cur_time = self.times[time_step]
5022
5408
 
5023
5409
  if self.nb_blocks>1:
5024
5410
  for curblock in self.myblocks.keys():
@@ -5042,14 +5428,23 @@ class Wolfresults_2D(Element_To_Draw):
5042
5428
  z[ij] = wd.array[ij] + top.array[ij]
5043
5429
  head[ij]= z[ij] + v[ij]**2./2/9.81
5044
5430
 
5431
+ # Fill the time of arrival
5432
+ danger_map_matrix_toa[curblock].array[(danger_map_matrix_toa.array == DEFAULT_TOA) & (wd.array > hmin)] = cur_time
5433
+
5434
+ # Fill the time of maximum
5435
+ # Searching where wd > h_max
5436
+ ij_h = np.where((danger_map_matrix_h[curblock].array < wd.array) & (~wd.array.mask))
5437
+ danger_map_matrix_tom[curblock].array[ij_h] = cur_time
5438
+
5045
5439
  # Comparison
5046
5440
  for curdanger, curcomp in zip(danger, [wd.array, v, mom, z, head]):
5047
- ij = np.where((curdanger.array < curcomp) & (~wd.array.mask))
5048
- curdanger.array.data[ij] = curcomp[ij]
5049
- curdanger.array.mask[ij] = False
5441
+ ij = np.where((curdanger[curblock].array < curcomp) & (~wd.array.mask))
5442
+ curdanger[curblock].array.data[ij] = curcomp[ij]
5443
+ curdanger[curblock].array.mask[ij] = False
5050
5444
 
5051
5445
  else:
5052
5446
  curblock = getkeyblock(0)
5447
+
5053
5448
  wd = self.get_h_for_block(curblock)
5054
5449
  qx = self.get_qx_for_block(curblock)
5055
5450
  qy = self.get_qy_for_block(curblock)
@@ -5068,8 +5463,16 @@ class Wolfresults_2D(Element_To_Draw):
5068
5463
  z[ij] = wd.array[ij] + top.array[ij]
5069
5464
  head[ij]= z[ij] + v[ij]**2./2/9.81
5070
5465
 
5466
+ # Fill the time of arrival
5467
+ danger_map_matrix_toa.array[(danger_map_matrix_toa.array == DEFAULT_TOA) & (wd.array > hmin)] = cur_time
5468
+
5469
+ # Fill the time of maximum
5470
+ # Searching where wd > h_max
5471
+ ij_h = np.where((danger_map_matrix_h.array < wd.array) & (~wd.array.mask))
5472
+ danger_map_matrix_tom.array[ij_h] = cur_time
5473
+
5071
5474
  # Comparison
5072
- for curdanger, curcomp in zip(danger, [wd.array, v, mom, z, head]):
5475
+ for curdanger, curcomp in zip(danger[:5], [wd.array, v, mom, z, head]):
5073
5476
  ij = np.where((curdanger.array < curcomp) & (~wd.array.mask))
5074
5477
  curdanger.array.data[ij] = curcomp[ij]
5075
5478
  curdanger.array.mask[ij] = False
@@ -5082,37 +5485,30 @@ class Wolfresults_2D(Element_To_Draw):
5082
5485
  danger_map_matrix_mom[i].array.mask[:,:] = danger_map_matrix_h[i].array.mask[:,:]
5083
5486
  danger_map_matrix_z[i].array.mask[:,:] = danger_map_matrix_h[i].array.mask[:,:]
5084
5487
  danger_map_matrix_head[i].array.mask[:,:] = danger_map_matrix_h[i].array.mask[:,:]
5488
+ danger_map_matrix_toa[i].array.mask[:,:] = danger_map_matrix_h[i].array.mask[:,:]
5489
+ danger_map_matrix_tom[i].array.mask[:,:] = danger_map_matrix_h[i].array.mask[:,:]
5085
5490
  else:
5086
5491
  danger_map_matrix_v.array.mask[:,:] = danger_map_matrix_h.array.mask[:,:]
5087
5492
  danger_map_matrix_mom.array.mask[:,:] = danger_map_matrix_h.array.mask[:,:]
5088
5493
  danger_map_matrix_z.array.mask[:,:] = danger_map_matrix_h.array.mask[:,:]
5089
5494
  danger_map_matrix_head.array.mask[:,:] = danger_map_matrix_h.array.mask[:,:]
5090
-
5091
- return (danger_map_matrix_h, danger_map_matrix_v, danger_map_matrix_mom, danger_map_matrix_z, danger_map_matrix_head)
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]]:
5495
+ danger_map_matrix_toa.array.mask[:,:] = danger_map_matrix_h.array.mask[:,:]
5496
+ danger_map_matrix_tom.array.mask[:,:] = danger_map_matrix_h.array.mask[:,:]
5497
+
5498
+ return (danger_map_matrix_h,
5499
+ danger_map_matrix_v,
5500
+ danger_map_matrix_mom,
5501
+ danger_map_matrix_z,
5502
+ danger_map_matrix_head,
5503
+ danger_map_matrix_toa,
5504
+ danger_map_matrix_tom)
5505
+
5506
+ def danger_map_multiprocess(self, start:int=0, end:int=-1,
5507
+ every:int=1,
5508
+ callback=None,
5509
+ hmin:float = None,
5510
+ nb_processors:int = -1) -> Union[tuple[WolfArray, WolfArray, WolfArray, WolfArray, WolfArray, WolfArray],
5511
+ tuple[WolfArrayMB, WolfArrayMB, WolfArrayMB, WolfArrayMB, WolfArrayMB, WolfArrayMB]]:
5116
5512
  """
5117
5513
  Create Danger Maps using multiprocessing
5118
5514
 
@@ -5122,18 +5518,37 @@ class Wolfresults_2D(Element_To_Draw):
5122
5518
  :param callback: optional callback to update progress
5123
5519
  """
5124
5520
 
5521
+ DEFAULT_TOA = 0.
5522
+
5125
5523
  from multiprocessing import Pool, cpu_count
5126
5524
 
5525
+ if hmin is None:
5526
+ hmin = self.epsilon
5527
+
5127
5528
  if nb_processors == -1:
5128
5529
  nb_processors = cpu_count()
5530
+ elif nb_processors > cpu_count():
5531
+ nb_processors = cpu_count()
5532
+ elif nb_processors < 1:
5533
+ nb_processors = 1
5534
+
5535
+ if end == -1:
5536
+ end = self.get_nbresults() - 1
5537
+ if end > self.get_nbresults():
5538
+ logging.warning("End time step is greater than the number of time steps. Setting end to the last time step.")
5539
+ end = self.get_nbresults() - 1
5129
5540
 
5130
5541
  if nb_processors > self.get_nbresults():
5131
- nb_processors = self.get_nbresults()
5542
+ logging.warning('Number of processors is greater than the number of time steps.')
5543
+ nb_processors = int(self.get_nbresults() /4)
5544
+ elif nb_processors > end-start+1:
5545
+ logging.warning('Number of processors is greater than the number of time steps.')
5546
+ nb_processors = int((end-start)/4)
5132
5547
 
5133
- # Split the range of time steps into chunks for multiprocessing
5134
- if end == -1:
5135
- end = self.get_nbresults()
5548
+ if nb_processors < 1:
5549
+ nb_processors = 1
5136
5550
 
5551
+ # Create a list of chunks
5137
5552
  starts = [start + i * every for i in range(nb_processors)]
5138
5553
  ends = [end - i * every for i in range(nb_processors-1,-1,-1)]
5139
5554
 
@@ -5148,7 +5563,18 @@ class Wolfresults_2D(Element_To_Draw):
5148
5563
  if starts[i] >= ends[i]:
5149
5564
  ends[i] = starts[i] + every
5150
5565
 
5151
- chunks = [(self, start + i * every, end - (nb_processors - i) * every + 1, nb_processors) for i in range(min(nb_processors, len(starts)))]
5566
+ # clip ends to end
5567
+ for i in range(len(ends)):
5568
+ if ends[i] > end:
5569
+ ends[i] = end
5570
+
5571
+ everys = [min(nb_processors, (_end - _start)) for _start, _end in zip(starts, ends)]
5572
+
5573
+ chunks = [(self,
5574
+ starts[i],
5575
+ ends[i],
5576
+ everys[i],
5577
+ hmin) for i in range(min(nb_processors, len(starts)))]
5152
5578
 
5153
5579
  # Create a pool of workers
5154
5580
  with Pool(processes=nb_processors) as pool:
@@ -5160,7 +5586,16 @@ class Wolfresults_2D(Element_To_Draw):
5160
5586
  danger_map_matrix_z = self.as_WolfArray(copyarray=True)
5161
5587
  danger_map_matrix_head= self.as_WolfArray(copyarray=True)
5162
5588
 
5163
- danger = [danger_map_matrix_h, danger_map_matrix_v, danger_map_matrix_mom, danger_map_matrix_z, danger_map_matrix_head]
5589
+ danger_map_matrix_toa = self.as_WolfArray(copyarray=True)
5590
+ danger_map_matrix_tom = self.as_WolfArray(copyarray=True)
5591
+
5592
+ danger = [danger_map_matrix_h,
5593
+ danger_map_matrix_v,
5594
+ danger_map_matrix_mom,
5595
+ danger_map_matrix_z,
5596
+ danger_map_matrix_head,
5597
+ danger_map_matrix_toa,
5598
+ danger_map_matrix_tom]
5164
5599
 
5165
5600
  for curdanger in danger:
5166
5601
  curdanger.nullvalue = 0.
@@ -5169,16 +5604,89 @@ class Wolfresults_2D(Element_To_Draw):
5169
5604
 
5170
5605
  if self.nb_blocks>1:
5171
5606
  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)
5607
+
5608
+ for i in range(self.nb_blocks):
5609
+
5610
+ # time of arrival
5611
+ # Store if the value is DEFAULT_TOA and the new value is > 0
5612
+ # Other cases correspond to an lower TOA
5613
+
5614
+ danger_toa = danger_map_matrix_toa[i].array
5615
+ res_toa = result[5][i].array
5616
+
5617
+ ij = np.where((danger_toa.data == DEFAULT_TOA) & (res_toa.data > 0.))
5618
+ danger_toa.data[ij] = res_toa.data[ij]
5619
+ danger_toa.mask[ij] = False
5620
+
5621
+ # time of peak
5622
+ # Le temps de pic n'a pas encore été atteint et un valeur existe --> on prend
5623
+ danger_tom = danger_map_matrix_tom[i].array
5624
+ danger_h = danger_map_matrix_h[i].array
5625
+ res_tom = result[6][i].array
5626
+ res_h = result[0][i].array
5627
+
5628
+ # Le temps de pic a été initialisé et une autre valeur existe --> on prend le temps où la hauteur est max
5629
+ ij = np.where((danger_tom.data > 0.) & (danger_h.data == res_h.data) & (~res_tom.mask))
5630
+ danger_tom.data[ij] = np.minimum(res_tom.data[ij], danger_tom.data[ij])
5631
+ danger_tom.mask[ij] = False
5632
+
5633
+ # Le temps de pic a été initialisé et une autre valeur existe --> on prend le temps où la hauteur est max
5634
+ ij = np.where((danger_tom.data > 0.) & (danger_h.data < res_h.data) & (~res_tom.mask))
5635
+ danger_tom.data[ij] = res_tom.data[ij]
5636
+ danger_tom.mask[ij] = False
5637
+ danger_h.data[ij] = res_h.data[ij]
5638
+
5639
+ ij = np.where(((danger_tom.data == 0.) & (res_tom.data > 0.)))
5640
+ danger_tom.data[ij] = res_tom.data[ij]
5641
+ danger_h.data[ij] = res_h.data[ij]
5642
+ danger_tom.mask[ij] = False
5643
+
5644
+ # for i in range(self.nb_blocks):
5645
+ for idx, curdanger in enumerate(danger[:5]):
5646
+
5647
+ curdanger[i].array.data[:,:] = np.maximum(curdanger[i].array.data, result[idx][i].array.data)
5648
+ curdanger[i].array.mask[:,:] = np.logical_or(curdanger[i].array.mask, result[idx][i].array.mask)
5176
5649
  else:
5177
5650
  for result in results:
5178
- for idx, curdanger in enumerate(danger):
5651
+ # time of arrival
5652
+ # Store if the value is DEFAULT_TOA and the new value is > 0
5653
+ # Other cases correspond to an lower TOA
5654
+
5655
+ danger_toa = danger_map_matrix_toa.array
5656
+ res_toa = result[5].array
5657
+
5658
+ ij = np.where((danger_toa.data == DEFAULT_TOA) & (res_toa.data > 0.))
5659
+ danger_toa.data[ij] = res_toa.data[ij]
5660
+ danger_toa.mask[ij] = False
5661
+
5662
+ # time of peak
5663
+ # Le temps de pic n'a pas encore été atteint et un valeur existe --> on prend
5664
+ danger_tom = danger_map_matrix_tom.array
5665
+ danger_h = danger_map_matrix_h.array
5666
+ res_tom = result[6].array
5667
+ res_h = result[0].array
5668
+
5669
+ # Le temps de pic a été initialisé et une autre valeur existe --> on prend le temps où la hauteur est max
5670
+ ij = np.where((danger_tom.data > 0.) & (danger_h.data == res_h.data) & (~res_tom.mask))
5671
+ danger_tom.data[ij] = np.minimum(res_tom.data[ij], danger_tom.data[ij])
5672
+ danger_tom.mask[ij] = False
5673
+
5674
+ # Le temps de pic a été initialisé et une autre valeur existe --> on prend le temps où la hauteur est max
5675
+ ij = np.where((danger_tom.data > 0.) & (danger_h.data < res_h.data) & (~res_tom.mask))
5676
+ danger_tom.data[ij] = res_tom.data[ij]
5677
+ danger_tom.mask[ij] = False
5678
+ danger_h.data[ij] = res_h.data[ij]
5679
+
5680
+ ij = np.where(((danger_tom.data == 0.) & (res_tom.data > 0.)))
5681
+ danger_tom.data[ij] = res_tom.data[ij]
5682
+ danger_h.data[ij] = res_h.data[ij]
5683
+ danger_tom.mask[ij] = False
5684
+
5685
+ for idx, curdanger in enumerate(danger[:5]):
5179
5686
  curdanger.array.data[:,:] = np.maximum(curdanger.array.data, result[idx].array.data)
5180
5687
  curdanger.array.mask[:,:] = np.logical_or(curdanger.array.mask, result[idx].array.mask)
5181
5688
 
5689
+
5182
5690
  danger_map_matrix_h.mask_lower(self.epsilon)
5183
5691
 
5184
5692
  if self.nb_blocks>1:
@@ -5187,13 +5695,20 @@ class Wolfresults_2D(Element_To_Draw):
5187
5695
  danger_map_matrix_mom[i].array.mask[:,:] = danger_map_matrix_h[i].array.mask[:,:]
5188
5696
  danger_map_matrix_z[i].array.mask[:,:] = danger_map_matrix_h[i].array.mask[:,:]
5189
5697
  danger_map_matrix_head[i].array.mask[:,:] = danger_map_matrix_h[i].array.mask[:,:]
5698
+ danger_map_matrix_toa[i].array.mask[:,:] = danger_map_matrix_h[i].array.mask[:,:]
5699
+ danger_map_matrix_tom[i].array.mask[:,:] = danger_map_matrix_h[i].array.mask[:,:]
5190
5700
  else:
5191
5701
  danger_map_matrix_v.array.mask[:,:] = danger_map_matrix_h.array.mask[:,:]
5192
5702
  danger_map_matrix_mom.array.mask[:,:] = danger_map_matrix_h.array.mask[:,:]
5193
5703
  danger_map_matrix_z.array.mask[:,:] = danger_map_matrix_h.array.mask[:,:]
5194
5704
  danger_map_matrix_head.array.mask[:,:] = danger_map_matrix_h.array.mask[:,:]
5705
+ danger_map_matrix_toa.array.mask[:,:] = danger_map_matrix_h.array.mask[:,:]
5706
+ danger_map_matrix_tom.array.mask[:,:] = danger_map_matrix_h.array.mask[:,:]
5195
5707
 
5196
- return (danger_map_matrix_h, danger_map_matrix_v, danger_map_matrix_mom, danger_map_matrix_z, danger_map_matrix_head)
5708
+ return (danger_map_matrix_h, danger_map_matrix_v,
5709
+ danger_map_matrix_mom, danger_map_matrix_z,
5710
+ danger_map_matrix_head,
5711
+ danger_map_matrix_toa, danger_map_matrix_tom)
5197
5712
 
5198
5713
  def danger_map_only_h(self, start:int=0, end:int=-1, every:int=1) -> WolfArray:
5199
5714
  """