wolfhece 2.1.100__py3-none-any.whl → 2.1.102__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.
@@ -0,0 +1,647 @@
1
+ import logging
2
+ from pathlib import Path
3
+ import numpy as np
4
+ from typing import Union, Literal
5
+ import matplotlib.pyplot as plt
6
+
7
+ from ..wolf_array import WOLF_ARRAY_FULL_LOGICAL, WOLF_ARRAY_FULL_SINGLE, WOLF_ARRAY_FULL_INTEGER, WOLF_ARRAY_FULL_INTEGER8, WOLF_ARRAY_FULL_UINTEGER8
8
+ from ..wolf_array import WolfArray, header_wolf
9
+ from ..PyTranslate import _
10
+ from ..PyVertexvectors import vector, zone, Zones
11
+ from wolfgpu.simple_simulation import SimpleSimulation
12
+
13
+ class infiltration_GPU():
14
+ def __init__(self, parent:"Sim_2D_GPU") -> None:
15
+ self.parent:"Sim_2D_GPU" = parent
16
+
17
+ @property
18
+ def infiltrations_chronology(self) -> list[float]:
19
+ chronos = self.parent.sim.infiltrations_chronology
20
+ if len(chronos) == 0:
21
+ return []
22
+ else:
23
+ return [[cur[0]]+cur[1] for cur in chronos]
24
+
25
+ @infiltrations_chronology.setter
26
+ def infiltrations_chronology(self, value:np.ndarray) -> None:
27
+
28
+ simple_chronology = [(cur[0], list(cur[1:])) for cur in value]
29
+ self.parent.sim.infiltrations_chronology = simple_chronology
30
+
31
+ @property
32
+ def nb_steps(self) -> int:
33
+ chronos = self.parent.sim.infiltrations_chronology
34
+ if len(chronos) == 0:
35
+ return 0
36
+ else:
37
+ return len(chronos)
38
+
39
+ @property
40
+ def nb_zones(self) -> Zones:
41
+ chronos = self.parent.sim.infiltrations_chronology
42
+ if len(chronos) == 0:
43
+ return 0
44
+ else:
45
+ if len(chronos[0]) == 0:
46
+ return 0
47
+ else:
48
+ return len(chronos[0][1])
49
+
50
+ def plot_plt(self, figax=None, show=True):
51
+ """ Plot the infiltration data """
52
+
53
+ if figax is None:
54
+ fig, ax = plt.subplots(1, 1)
55
+ else:
56
+ fig,ax = figax
57
+
58
+ chronos = self.parent.sim.infiltrations_chronology
59
+ times = [cur[0] for cur in chronos]
60
+
61
+ for zone in range(self.nb_zones):
62
+ ax.plot(times, [cur[1][zone] for cur in chronos], label=f'Zone {zone+1}')
63
+
64
+ ax.set_xlabel(_('Time [s]'))
65
+ ax.set_ylabel(_('Infiltration [$m^3/s$]'))
66
+ ax.legend()
67
+ fig.tight_layout()
68
+
69
+ if show:
70
+ fig.show()
71
+
72
+ return fig,ax
73
+
74
+
75
+ class Sim_2D_GPU():
76
+ """ Simulation 2D GPU -- Interface """
77
+
78
+ def __init__(self, directory:Union[str,Path] = '') -> None:
79
+
80
+ try:
81
+ from wolfgpu.simple_simulation import SimpleSimulation
82
+ except:
83
+ logging.error(_("Unable to import wolfgpu.simple_simulation.SimpleSimulation. Please install wolfgpu package or add a symlink to the wolfgpu package in the wolfhece directory"))
84
+
85
+ self.dir = Path(directory)
86
+ self._sim = None
87
+ self._cached_arrays = {}
88
+ self.magnetic_grid:header_wolf = None
89
+
90
+ if (self.dir /'parameters.json').exists():
91
+ self._sim = SimpleSimulation.load(self.dir)
92
+ self.infiltration = infiltration_GPU(self)
93
+
94
+ # Fine arrays with type
95
+ self.files_array={'Characteristics':[
96
+ ('nap','Mask [-]',WOLF_ARRAY_FULL_UINTEGER8),
97
+ ('bathymetry','Bed Elevation [m]',WOLF_ARRAY_FULL_SINGLE),
98
+ ('manning','Roughness coefficient [law dependent]',WOLF_ARRAY_FULL_SINGLE),
99
+ ('infiltration_zones','Infiltration zone [-]',WOLF_ARRAY_FULL_INTEGER),
100
+ ('h','Initial water depth [m]',WOLF_ARRAY_FULL_SINGLE),
101
+ ('qx','Initial discharge along X [m^2/s]',WOLF_ARRAY_FULL_SINGLE),
102
+ ('qy','Initial discharge along Y [m^2/s]',WOLF_ARRAY_FULL_SINGLE),
103
+ ('bridge_roof','Bridge/Culvert (roof el.) [m]',WOLF_ARRAY_FULL_SINGLE),
104
+ ]}
105
+
106
+ self.files_ic=['Initial water depth [m]','Initial discharge along X [m^2/s]','Initial discharge along Y [m^2/s]']
107
+
108
+ # Files for the simulation
109
+ self.files_others={'Generic file':[
110
+ ('parameters.json','Parametric file'),
111
+ ]}
112
+
113
+ pass
114
+
115
+ @property
116
+ def boundary_condition(self):
117
+ return self.sim.boundary_condition
118
+
119
+ @property
120
+ def is_loaded(self) -> bool:
121
+ return self.sim is not None
122
+
123
+ def unload(self) -> None:
124
+ """ Unload the simulation """
125
+ if self.is_loaded:
126
+ del self._sim
127
+ self._sim = None
128
+
129
+ @property
130
+ def sim(self) -> SimpleSimulation:
131
+ return self._sim
132
+
133
+ @sim.setter
134
+ def sim(self, value:SimpleSimulation) -> None:
135
+ self._sim = value
136
+
137
+ def __str__(self) -> str:
138
+ ret = f"Simulation 2D GPU: {self.dir.name}\n"
139
+ if self.is_loaded:
140
+ ret += str(self.sim)
141
+ return ret
142
+
143
+ def __repr__(self) -> str:
144
+ return self.__str__()
145
+
146
+ def _get_name_arrays(self) -> list[str]:
147
+ """ Get the name of the arrays """
148
+ return [cur[0] for cur in self.files_array['Characteristics']]
149
+
150
+ def _get_description_arrays(self) -> list[str]:
151
+ """ Get the description of the arrays """
152
+ return [cur[1] for cur in self.files_array['Characteristics']]
153
+
154
+ def get_header(self) -> header_wolf:
155
+ """ Get the header of the simulation """
156
+ if self.is_loaded:
157
+ new_header = header_wolf()
158
+ new_header.nbx = self.sim.param_nx
159
+ new_header.nby = self.sim.param_ny
160
+ new_header.dx = self.sim.param_dx
161
+ new_header.dy = self.sim.param_dy
162
+ new_header.origx = self.sim.param_base_coord_ll_x
163
+ new_header.origy = self.sim.param_base_coord_ll_y
164
+
165
+ return new_header
166
+ else:
167
+ return None
168
+
169
+ def __getitem__(self, key:Literal['nap', 'bathymetry', 'manning', 'infiltration_zones', 'h', 'qx', 'qy', 'bridge_roof']) -> WolfArray:
170
+ """ Get an array from the simulation """
171
+
172
+ if self.is_loaded:
173
+ if key in self._get_name_arrays():
174
+ descr = self._get_description_arrays()[self._get_name_arrays().index(key)]
175
+
176
+ if key not in self._cached_arrays:
177
+ locarray = WolfArray(srcheader=self.get_header(),
178
+ np_source=self.sim.__getattribute__(key),
179
+ idx= descr,
180
+ nullvalue=self.nullvalues[key],
181
+ whichtype=self.files_array['Characteristics'][self._get_name_arrays().index(key)][2],
182
+ masknull=False)
183
+ locarray.loaded = True
184
+ locarray.filename = str(self.dir / f"{key}.npy")
185
+
186
+ self._cached_arrays[key] = locarray
187
+ return locarray
188
+ else:
189
+ return self._cached_arrays[key]
190
+ else:
191
+ return None
192
+ else:
193
+ return None
194
+
195
+ def get_arraysasdict(self) -> dict[str,WolfArray]:
196
+ """ Get all the arrays from the simulation """
197
+
198
+ ret= {key:self[key] for key in self._get_name_arrays()}
199
+ self.mimic_mask(ret['nap'], [cur for key,cur in ret.items() if key != 'nap'])
200
+
201
+ return ret
202
+
203
+
204
+ def mimic_mask(self, source:WolfArray, dest:list[WolfArray]):
205
+ """ Mimic the mask """
206
+
207
+ for cur in dest:
208
+ cur.array.mask[:,:] = source.array.mask[:,:]
209
+ cur.set_nullvalue_in_mask()
210
+
211
+ def create_arrays_from(self, source:WolfArray):
212
+ """ Create arrays from a source """
213
+
214
+ if self.is_loaded:
215
+ logging.error(_("Simulation exists, cannot create arrays from source or delete simulation first !"))
216
+ else:
217
+ try:
218
+ self._sim = SimpleSimulation(source.nbx, source.nby)
219
+ self._sim.param_dx = source.dx
220
+ self._sim.param_dy = source.dy
221
+ self._sim.param_base_coord_ll_x = source.origx
222
+ self._sim.param_base_coord_ll_y = source.origy
223
+ self.infiltration = infiltration_GPU(self)
224
+ except Exception as e:
225
+ logging.error(_("Unable to create simulation -- {e}"))
226
+ return
227
+
228
+ # Float32 arrays
229
+ loc_array = np.zeros((source.nbx, source.nby), dtype=np.float32)
230
+ self.sim.h = loc_array.copy()
231
+ self.sim.qx = loc_array.copy()
232
+ self.sim.qy = loc_array.copy()
233
+
234
+ self.sim.manning = loc_array.copy()
235
+ self.sim.manning[np.logical_not(source.array.mask)] = 0.04
236
+
237
+ loc_array[source.array.mask] = 99999.
238
+ self.sim.bathymetry = loc_array.copy()
239
+
240
+ # UInteger8 arrays
241
+ loc_array = np.ones((source.nbx, source.nby), dtype=np.uint8)
242
+ loc_array[source.array.mask] = 0
243
+ self.sim.nap = loc_array.copy()
244
+
245
+ # Integer arrays
246
+ loc_array = np.zeros((source.nbx, source.nby), dtype=np.int32)
247
+ self.sim.infiltration_zones = loc_array.copy()
248
+
249
+
250
+ def create_from_vector(self, vector:vector, dx:float, dy:float):
251
+ """ Create a simulation from a vector """
252
+
253
+ if vector is None:
254
+ logging.warning(_("Vector is None"))
255
+ return None
256
+ elif self.magnetic_grid is None:
257
+ logging.error(_("Magnetic grid not set"))
258
+ return None
259
+ else:
260
+ vector.find_minmax()
261
+ xmin, ymin = vector.xmin, vector.ymin
262
+ xmax, ymax = vector.xmax, vector.ymax
263
+
264
+ xmin, ymin = self.align2grid(xmin, ymin)
265
+ xmax, ymax = self.align2grid(xmax, ymax)
266
+
267
+ xmin -= 2*dx
268
+ ymin -= 2*dy
269
+ xmax += 2*dx
270
+ ymax += 2*dy
271
+
272
+ src_header = header_wolf()
273
+ src_header.dx = dx
274
+ src_header.dy = dy
275
+ src_header.origx = xmin
276
+ src_header.origy = ymin
277
+ src_header.nbx = int((xmax-xmin)/src_header.dx)
278
+ src_header.nby = int((ymax-ymin)/src_header.dy)
279
+
280
+ tmp_array = WolfArray(srcheader=src_header)
281
+ ij = tmp_array.get_ij_inside_polygon(vector, usemask=False)
282
+
283
+ tmp_array.mask_reset()
284
+ tmp_array.mask_outsidepoly(vector)
285
+ self.create_arrays_from(tmp_array)
286
+
287
+ def create_from_array(self, array:WolfArray):
288
+ """ Create a simulation from an array """
289
+ if array is None:
290
+ logging.warning(_("Array is None"))
291
+ return None
292
+ else:
293
+ self.create_arrays_from(array)
294
+
295
+ def create_from_header(self, header:header_wolf) -> 'Sim_2D_GPU':
296
+ """ Create a simulation from a header """
297
+ if header is None:
298
+ logging.warning(_("Header is None"))
299
+ return None
300
+ else:
301
+ tmp_array = WolfArray(srcheader=header)
302
+ tmp_array.array[:,0] = 0
303
+ tmp_array.array[0,:] = 0
304
+ tmp_array.array[-1,:] = 0
305
+ tmp_array.array[:,-1] = 0
306
+ tmp_array.masknull()
307
+ self.create_arrays_from(tmp_array)
308
+
309
+ def set_mesh_size(self, dx, dy):
310
+ """ Set the mesh size """
311
+ if self.is_loaded:
312
+ self.sim.param_dx = dx
313
+ self.sim.param_dy = dy
314
+ else:
315
+ logging.error(_("Simulation not loaded"))
316
+
317
+ def set_magnetic_grid(self, dx:float, dy:float, origx:float, origy:float):
318
+ """
319
+ Définition de la grille magnétique
320
+
321
+ :param dx: taille de maille selon X
322
+ :type dx: float
323
+ :param dy: taille de maille selon Y
324
+ :type dy: float
325
+ :param origx: origine selon X (coordonnée du noeud d'intersection)
326
+ :type origx: float
327
+ :param origy: origine selon Y (coordonnée du noeud d'intersection)
328
+ :type origy: float
329
+ """
330
+
331
+ self.magnetic_grid = header_wolf()
332
+ self.magnetic_grid.dx = dx
333
+ self.magnetic_grid.dy = dy
334
+
335
+ self.magnetic_grid.origx = origx
336
+ self.magnetic_grid.origy = origy
337
+
338
+ def align2grid(self, x:float, y:float):
339
+ """ Alignement sur la grille magnétique """
340
+
341
+ if self.magnetic_grid is None:
342
+ return x,y
343
+
344
+ x, y = self.magnetic_grid.align2grid(x, y)
345
+
346
+ return x,y
347
+
348
+ @property
349
+ def nullvalues(self) -> dict[str,int]:
350
+ """ Define null values for the arrays """
351
+
352
+ return {'nap':0, 'bathymetry':99999., 'manning':0, 'infiltration_zones':0, 'h':0., 'qx':0., 'qy':0., 'bridge_roof':99999.}
353
+
354
+ def verify_files(self):
355
+ """ Verify the files """
356
+
357
+ if self.is_loaded:
358
+ header = self.get_header()
359
+ ref_mask= self.sim.nap == 0
360
+ for cur in self.files_array['Characteristics']:
361
+ tmparray = self.sim.__getattribute__(cur[0])
362
+ if tmparray is None:
363
+ logging.error(_("Missing array: {0}".format(cur[0])))
364
+ return False
365
+ if tmparray.shape != (header.nbx, header.nby):
366
+ logging.error(_("Bad shape for array {0}".format(cur[0])))
367
+ return False
368
+ if np.any(tmparray[np.logical_not(ref_mask)] == self.nullvalues[cur[0]]):
369
+ logging.error(_("Null value found in array {0}".format(cur[0])))
370
+ return False
371
+ return True
372
+ else:
373
+ return False
374
+
375
+
376
+ def get_wizard_text(self, lang:str = 'en') -> str:
377
+ """ Get the wizard text """
378
+
379
+ wizard_steps_page1 =[
380
+ '',
381
+ '',
382
+ '',
383
+ _('Welcome to the wizard'),
384
+ '',
385
+ '',
386
+ '',
387
+ _('This wizard will guide you through the creation\nof a new simple GPU WOLF2D model'),
388
+ '',
389
+ ]
390
+
391
+ wizard_steps_page2 = [
392
+ _('First of all, you need to define the model domain'),
393
+ '',
394
+ _('You can create a new polygon or select an existing one'),
395
+ '',
396
+ _('You can also create a polygon from a footprint by defining : \n - the origin (ox, oy)\n - the resolution (dx, dy)\n - the number of nodes along X and Y (nbx, nby)'),
397
+ '',
398
+ _('Or you can use a mask from the active array (e.g. a topography array)'),
399
+ "",
400
+ _('Remember that the extrnal contour cells will be forced as masked'),
401
+ ]
402
+
403
+
404
+ wizard_steps_page3 = [
405
+ _('If you are working with a polygon, you must set the magnetic grid'),
406
+ '',
407
+ _('The magnetic grid is a virtual grid on which the array bounds are aligned'),
408
+ '',
409
+ _('The xmin, ymin, xmax, ymax of the polygon will be aligned on the magnetic grid'),
410
+ '',
411
+ _('It could be useful to have consistent boundaries between different simulations\n(e.g. successive river reaches)'),
412
+ ]
413
+
414
+
415
+ wizard_steps_page4 = [
416
+ _('Then the model will be meshed and the arrays will be created'),
417
+ '',
418
+ _('Meshing is the process of creating the mesh of the model'),
419
+ '',
420
+ _('The mesh is the grid of nodes and elements on which the model will be solved'),
421
+ '',
422
+ _('Resulting mesh is stored in the NAP.npy file'),
423
+ '',
424
+ _('1 is an active cell and 0 is an inactive cell'),
425
+ ]
426
+
427
+ wizard_steps_page5 = [
428
+ _('Then you can modify the arrays'),
429
+ '',
430
+ _('Arrays are the main data of the model'),
431
+ '',
432
+ _('They are created from the meshing results (bathymetry, manning, h, qx, qy, infiltration_zones)'),
433
+ '',
434
+ _('They are stored in the binary files\nExtensions .npy'),
435
+ '',
436
+ _('Specific types are used for each array :'),
437
+ _(' - nap : Unsigned integer - 8 bits'),
438
+ _(' - bathymetry, manning, h, qx, qy : Float 32 bits (Single precision)'),
439
+ _(' - infiltration_zones : Signed integer - 16 bits'),
440
+ '',
441
+ _('Arrays can be edited in the GUI'),
442
+ ]
443
+
444
+ wizard_steps_page6 = [
445
+ _('Set the boundary conditions'),
446
+ '',
447
+ _('You can set the boundary conditions for the model'),
448
+ '',
449
+ _('Borders of the NAP array are identified as boundaries'),
450
+ '',
451
+ _('By mouse, you can select borders one by one (right click), or by using dynamic rectangle (right click and drag)'),
452
+ '',
453
+ _('Select type and values for the selected borders in the BC Manager associated to the simulation'),
454
+ ]
455
+
456
+ wizard_steps_page7 = [
457
+ _('Set the infiltrations'),
458
+ '',
459
+ _('Infiltrations must be defined spatially and temporally'),
460
+ '',
461
+ _('Spatially, you must edit the infiltration zones array and set an index for the cells in each zone'),
462
+ '',
463
+ _('Temporally, you must define the chronology of the infiltrations of each zone'),
464
+ '',
465
+ _('The discharge is defined in m3/s'),
466
+
467
+ ]
468
+
469
+ wizard_steps_page8 = [
470
+ _('Set the parameters'),
471
+ '',
472
+ _('You can set the parameters for the model'),
473
+ ]
474
+
475
+ wizard_steps_page9 = [
476
+ _('Check errors and write the files'),
477
+ '',
478
+ _('The warnings and errors are displayed in the text area'),
479
+ '',
480
+ _('You can write the files if no errors are found'),
481
+ ]
482
+
483
+ wizard_steps_page10 = [
484
+ _('Run the code'),
485
+ '',
486
+ _('You can run the code in a subprocess or manually (more flexible to choose cli options)'),
487
+ ]
488
+
489
+ wizard_steps_page11 = [
490
+ _('View/Check the results'),
491
+ ]
492
+
493
+ wizard_steps_page12 = [
494
+ _('That\'s all folks !'),
495
+ ]
496
+
497
+ return [wizard_steps_page1, wizard_steps_page2, wizard_steps_page3, wizard_steps_page4, wizard_steps_page5, wizard_steps_page6, wizard_steps_page7, wizard_steps_page8, wizard_steps_page9, wizard_steps_page10, wizard_steps_page11, wizard_steps_page12]
498
+
499
+ def bc2txt(self) -> str:
500
+ """" Get the text for the boundary conditions Manager """
501
+
502
+ txt = str(len(self.boundary_condition)) +"\n"
503
+ for curbc in self.boundary_condition:
504
+ txt += f"{curbc.i}\t{curbc.j}\t{curbc.direction.value}\t{curbc.ntype.value}\t{curbc.val}\n"
505
+
506
+ return txt
507
+
508
+ def check_infiltration(self) -> str:
509
+ """
510
+ Informations sur les zones d'infiltration :
511
+ - nombre de zones dans la simulation
512
+ - nombre de cellules de chaque zone
513
+ - première maille de chaque zone
514
+ - nombre de temps énumérés dans le fichier .fil
515
+ - Warning si le nombre de zones est différent entre les fichiers .inf et .fil
516
+
517
+ """
518
+
519
+ ret = _('inside file') + '\n'
520
+ ret += ('-----------') + '\n'
521
+
522
+ inf = self.sim.infiltration_zones
523
+
524
+ maxinf = inf.max()
525
+ ret += _('Maximum infiltration zone : ') + str(maxinf) + '\n'
526
+ for i in range(1,maxinf+1):
527
+
528
+ nb = np.sum(inf == i)
529
+ if nb>0:
530
+ indices = np.where(inf == i)
531
+ ret += f"Zone {i} : {nb} cells -- Indices (i,j) of the zone's first cell ({indices[0][0]+1} ; {indices[1][0]+1}) (1-based)\n"
532
+ else:
533
+ ret += f"Zone {i} : 0 cells\n"
534
+
535
+ ret += '\n'
536
+
537
+ ret += _('inside chronology') + '\n'
538
+ ret += ('-----------------') + '\n'
539
+
540
+ ret += f"Zones : {self.infiltration.nb_zones}" + '\n'
541
+ ret += f"Time steps : {self.infiltration.nb_steps}" + '\n'
542
+
543
+ if maxinf != self.infiltration.nb_zones:
544
+ ret += _('Warning : number of zones in chronology and array are different') + '\n'
545
+
546
+ return ret
547
+
548
+ def check_environment(self) -> list[str]:
549
+ # Info on Python Environment and wolfgpu Path and version
550
+ # -------------------------------------------------------
551
+
552
+ import sys
553
+ # Python Environment
554
+ ret = []
555
+ ret.append(' - Python version : {}'.format(sys.version))
556
+ ret.append(' - Python path : {}'.format(sys.executable))
557
+ ret.append(' - Python version info : {}'.format(sys.version_info))
558
+
559
+ # Test if wolfgpu.exe exists in script directory
560
+ # wolfgpu Path and version
561
+ PythonPath = Path(sys.executable)
562
+ site_packages = PythonPath.parent.parent / 'Lib' / 'site-packages'
563
+ wolfgpu_path = PythonPath.parent / 'wolfgpu.exe'
564
+ if wolfgpu_path.exists():
565
+ ret.append(' - Wolfgpu.exe found in : {}'.format(wolfgpu_path))
566
+ else:
567
+ ret.append(' - Wolfgpu.exe not found !')
568
+
569
+ if (site_packages / 'wolfgpu').exists():
570
+ ret.append(' - Wolfgpu package found in : {}'.format(site_packages / 'wolfgpu'))
571
+ else:
572
+ ret.append(' - Wolfgpu package not found in : {}!'.format(site_packages))
573
+
574
+ return ret
575
+
576
+ def run(self, limit_dryuploops:int= -1):
577
+ """ run the simulation in a subprocess """
578
+ from subprocess import run, Popen
579
+
580
+ if self.is_loaded:
581
+ if limit_dryuploops > 0:
582
+ Popen(['wolfgpu', '-quickrun', str(self.dir), '-limit_dryuploops', str(limit_dryuploops)], shell=False)
583
+ else:
584
+ Popen(['wolfgpu', '-quickrun', str(self.dir)], shell=False)
585
+ pass
586
+ else:
587
+ logging.error(_("Simulation not loaded"))
588
+
589
+ def write_initial_condition_from_record(self, recpath:Path = None, id_rec:int = None, destpath:Path = None):
590
+ """ Write the initial condition from a record
591
+
592
+ :param recpath: the path to the records. if None, the default path is used and 'simul_gpu_results' as result directory.
593
+ :param id_rec: the index of the record you want to start from.
594
+ :param destpath: the path where to save the initial condition. If None, the current path is used.
595
+
596
+ """
597
+
598
+ if self.is_loaded:
599
+ self.sim.write_initial_condition_from_record(recpath, id_rec, destpath)
600
+ else:
601
+ logging.error(_("Simulation not loaded"))
602
+
603
+ def copy2dir(self, destpath:Path):
604
+ """ Copy the simulation to a directory """
605
+
606
+ if self.is_loaded:
607
+ try:
608
+ self.sim.save(destpath)
609
+ except Exception as e:
610
+ logging.error(_("Unable to copy simulation -- {e}"))
611
+ else:
612
+ logging.error(_("Simulation not loaded"))
613
+
614
+
615
+ def reload_ic(self):
616
+ """ Reload the initial conditions from the disk and store ir in the same memory space. """
617
+ tmp = np.load(self.dir / "h.npy")
618
+ self.sim._h[:,:]= tmp[:,:]
619
+
620
+ tmp = np.load(self.dir / "qx.npy")
621
+ self.sim._qx[:,:]= tmp[:,:]
622
+
623
+ tmp = np.load(self.dir / "qy.npy")
624
+ self.sim._qy[:,:]= tmp[:,:]
625
+
626
+ def reload_all(self):
627
+ """ Reload all the data from the disk and store them in the same memory space. """
628
+ tmp = np.load(self.dir / "h.npy")
629
+ self.sim._h[:,:] = tmp[:,:]
630
+
631
+ tmp = np.load(self.dir / "qx.npy")
632
+ self.sim._qx[:,:] = tmp[:,:]
633
+
634
+ tmp = np.load(self.dir / "qy.npy")
635
+ self.sim._qy[:,:]= tmp[:,:]
636
+
637
+ tmp = np.load(self.dir / "bathymetry.npy")
638
+ self.sim._bathymetry[:,:]= tmp[:,:]
639
+
640
+ tmp = np.load(self.dir / "manning.npy")
641
+ self.sim._manning[:,:]= tmp[:,:]
642
+
643
+ tmp = np.load(self.dir / "infiltration_zones.npy")
644
+ self.sim._infiltration_zones[:,:]= tmp[:,:]
645
+
646
+ tmp = np.load(self.dir / "NAP.npy")
647
+ self.sim._nap[:,:]= tmp[:,:]