wolfhece 2.0.55__py3-none-any.whl → 2.1.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/PyGui.py CHANGED
@@ -3,14 +3,15 @@ from os.path import exists, join, isdir, isfile, dirname, normpath, splitext
3
3
  from pathlib import Path
4
4
  import numpy.ma as ma
5
5
  import wx
6
+ import wx.adv
6
7
  from wx.lib.busy import BusyInfo
7
8
  import logging
8
9
  from pathlib import Path
9
10
 
10
11
  from .apps.splashscreen import WolfLauncher
11
- from .wolf_array import WOLF_ARRAY_FULL_LOGICAL, WOLF_ARRAY_MB_SINGLE, WolfArray, getkeyblock, WolfArray_Sim2D, WOLF_ARRAY_FULL_INTEGER16, WOLF_ARRAY_MB_INTEGER
12
+ from .wolf_array import WOLF_ARRAY_FULL_LOGICAL, WOLF_ARRAY_MB_SINGLE, WolfArray, getkeyblock, WOLF_ARRAY_FULL_INTEGER16, WOLF_ARRAY_MB_INTEGER
12
13
  from .PyTranslate import _
13
- from .PyDraw import WolfMapViewer,imagetexture
14
+ from .PyDraw import WolfMapViewer,imagetexture, draw_type
14
15
 
15
16
  from .hydrometry.kiwis_wolfgui import hydrometry_wolfgui
16
17
 
@@ -27,6 +28,11 @@ from .hydrology.forcedexchanges import forced_exchanges
27
28
  from .PyParams import Wolf_Param
28
29
  from .picc import Picc_data, Cadaster_data
29
30
  from .wolf_zi_db import ZI_Databse_Elt, PlansTerrier
31
+ from .CpGrid import CpGrid
32
+
33
+
34
+ GEOM_GROUP_NAME = _('Block geometry')
35
+ MAGN_GROUP_NAME = _('Magnetic grid')
30
36
 
31
37
  # FIXME : Is it necessary to override wx.Frame ? WolfMapManager is a wx.Frame.
32
38
  # Is it sufficient to run a wx.App ?
@@ -156,6 +162,7 @@ class MapManager(GenMapManager):
156
162
  self.picc = Picc_data(data_dir=Path(r'data/PICC'), mapviewer=self.mapviewer)
157
163
  self.cadaster = Cadaster_data(data_dir=Path(r'data/Cadaster'), mapviewer=self.mapviewer)
158
164
  self.landmaps = PlansTerrier(mapviewer=self.mapviewer, parent = self, idx='LandMaps', plotted=True)
165
+ self.mapviewer.menu_walous()
159
166
 
160
167
  self.mapviewer.add_object(which='other',
161
168
  newobj=self.SPWhydrometry,
@@ -339,190 +346,490 @@ class HydrologyModel(GenMapManager):
339
346
  self.mainparams.Hide()
340
347
  self.basinparams.Hide()
341
348
 
349
+
350
+ class Wolf2DPartArrays():
351
+
352
+ def __init__(self, sim:prev_sim2D, mapviewer:WolfMapViewer) -> None:
353
+
354
+ self.wx_exists = wx.App.Get() is not None # test if wx App is running
355
+ self.sim = sim
356
+ self._gui = None
357
+ self.mapviewer = mapviewer
358
+
359
+ self._cur_list = None
360
+
361
+ if self.wx_exists:
362
+ self.setup_gui()
363
+
364
+ def setup_gui(self):
365
+ """
366
+ Create the GUI
367
+
368
+ A listbox in the upper part of the window will list the different part arrays.
369
+
370
+ When a part array is selected, the listbox on the left will list the files
371
+ associated with the selected part array. The listbox on the right will list
372
+ the blocks associated with the selected file.
373
+
374
+ """
375
+
376
+ self._gui = wx.Frame(None, title="Part Arrays", size=(400, 600))
377
+
378
+ self._panel = wx.Panel(self._gui)
379
+
380
+ sizer_vert = wx.BoxSizer(wx.VERTICAL)
381
+ sizer_hor = wx.BoxSizer(wx.HORIZONTAL)
382
+ sizer_vert_left = wx.BoxSizer(wx.VERTICAL)
383
+ sizer_vert_right = wx.BoxSizer(wx.VERTICAL)
384
+ sizer_btns = wx.BoxSizer(wx.HORIZONTAL)
385
+
386
+ sizer_hor.Add(sizer_vert_left, 1, wx.EXPAND)
387
+ sizer_hor.Add(sizer_vert_right, 1, wx.EXPAND)
388
+
389
+ self._lists = wx.ListBox(self._panel,
390
+ choices = [_("Topography"),
391
+ _("Friction"),
392
+ _("Water depth"),
393
+ _("Discharge X"),
394
+ _("Discharge Y"),
395
+ _("Buildings"),
396
+ _("Bridges"),
397
+ _("Infiltration")],
398
+ style= wx.LB_SINGLE | wx.LB_HSCROLL | wx.LB_NEEDED_SB)
399
+
400
+ self._lists.Bind(wx.EVT_LISTBOX, self.on_list)
401
+
402
+ sizer_vert.Add(self._lists, 0, wx.EXPAND)
403
+ sizer_vert.Add(sizer_hor, 1, wx.EXPAND)
404
+
405
+ self._list_files = wx.ListBox(self._panel,
406
+ style=wx.LB_SINGLE,
407
+ choices = [])
408
+
409
+ self._list_files.Bind(wx.EVT_LISTBOX, self.on_list_files)
410
+
411
+ self._list_blocks = wx.ListBox(self._panel,
412
+ style=wx.LB_MULTIPLE,
413
+ choices = [str(i+1) for i in range(self.sim.nb_blocks)])
414
+
415
+ self._list_blocks.Bind(wx.EVT_LISTBOX, self.on_list_blocks)
416
+
417
+
418
+ self_btn_addfile = wx.Button(self._panel, label=_("Add file"))
419
+ self_btn_addfile.Bind(wx.EVT_BUTTON, self.on_addfile)
420
+ self_btn_addfile.SetToolTipString(_("Add a file to the selected part array"))
421
+
422
+ self_btn_delfile = wx.Button(self._panel, label=_("Delete file"))
423
+ self_btn_delfile.Bind(wx.EVT_BUTTON, self.on_delfile)
424
+ self_btn_delfile.SetToolTipString(_("Delete the selected file from the selected part array"))
425
+
426
+ self._btn_apply = wx.Button(self._panel, label=_("Apply"))
427
+ self._btn_apply.Bind(wx.EVT_BUTTON, self.on_apply)
428
+ self._btn_apply.SetToolTipString(_("Apply the values in the grid to the in-memory simulation (without writing to disk)"))
429
+
430
+ self._btn_toviewer = wx.Button(self._panel, label=_("To viewer"))
431
+ self._btn_toviewer.Bind(wx.EVT_BUTTON, self.on_toviewer)
432
+
433
+ sizer_btns.Add(self_btn_addfile, 1, wx.EXPAND | wx.ALL, 2)
434
+ sizer_btns.Add(self_btn_delfile, 1, wx.EXPAND | wx.ALL, 2)
435
+ sizer_btns.Add(self._btn_apply, 2, wx.EXPAND | wx.ALL, 2)
436
+ sizer_btns.Add(self._btn_toviewer, 2, wx.EXPAND | wx.ALL, 2)
437
+
438
+ sizer_vert.Add(sizer_btns, 0, wx.EXPAND)
439
+
440
+ sizer_vert_left.Add(self._list_files, 1, wx.EXPAND)
441
+ sizer_vert_right.Add(self._list_blocks, 1, wx.EXPAND)
442
+
443
+
444
+ self._panel.SetSizer(sizer_vert)
445
+ self._panel.SetAutoLayout(1)
446
+
447
+
448
+ def on_toviewer(self, event):
449
+ """ Add the selected array to the mapviewer """
450
+
451
+ if self.mapviewer is None:
452
+ logging.error("No mapviewer created")
453
+ return
454
+
455
+ selected = self._list_files.GetSelection()
456
+
457
+ if selected != wx.NOT_FOUND:
458
+
459
+ fpath = Path(self.sim.filenamegen).parent / self._cur_list[selected][0]
460
+ locarray = WolfArray(fpath)
461
+
462
+ try:
463
+
464
+ self.mapviewer.add_object(which='array',
465
+ newobj=locarray,
466
+ id=fpath.name,
467
+ ToCheck=True)
468
+
469
+ self.mapviewer.Refresh()
470
+
471
+ except:
472
+ logging.error(_(f"Can't add {fpath} to the mapviewer"))
473
+
474
+
475
+ def on_list(self, event):
476
+ """ When a part array is selected """
477
+
478
+ selected = self._lists.GetSelection()
479
+
480
+ if selected == 0:
481
+ self._cur_list = self.sim.part_arrays._topography
482
+
483
+ elif selected == 1:
484
+ self._cur_list = self.sim.part_arrays._friction
485
+
486
+ elif selected == 2:
487
+ self._cur_list = self.sim.part_arrays._watedepth
488
+
489
+ elif selected == 3:
490
+ self._cur_list = self.sim.part_arrays._dischargeX
491
+
492
+ elif selected == 4:
493
+ self._cur_list = self.sim.part_arrays._dischargeY
494
+
495
+ elif selected == 5:
496
+ self._cur_list = self.sim.part_arrays._buildings
497
+
498
+ elif selected == 6:
499
+ self._cur_list = self.sim.part_arrays._bridges
500
+
501
+ elif selected == 7:
502
+ self._cur_list = self.sim.part_arrays._infiltration
503
+
504
+ self._list_files.Set([cur[0] for cur in self._cur_list])
505
+
506
+ def on_list_files(self, event):
507
+ """ When a file is selected """
508
+
509
+ selected = self._list_files.GetSelection()
510
+
511
+ self._list_blocks.Set([str(i+1) for i in range(self.sim.nb_blocks)])
512
+
513
+ for i in self._cur_list[selected][2]:
514
+ self._list_blocks.SetSelection(i-1)
515
+
516
+ def on_list_blocks(self, event):
517
+ pass
518
+
519
+ def on_addfile(self, event):
520
+ """ Add a file to the selected part array """
521
+
522
+ dlg = wx.FileDialog(self._gui, _("Choose a file"), "", "", "All files (*.bin)|*.bin", wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
523
+
524
+ if dlg.ShowModal() == wx.ID_OK:
525
+
526
+ file = Path(dlg.GetPath())
527
+
528
+ head = file / '.txt'
529
+
530
+ if head.exists():
531
+ locarray = WolfArray(file)
532
+
533
+ relative = file.relative_to(self.sim.filenamegen)
534
+
535
+ self._cur_list.append([relative, locarray.get_header(), [1]])
536
+ self._list_files.Set([cur[0] for cur in self._cur_list])
537
+
538
+ def on_delfile(self, event):
539
+ """ Delete the selected file """
540
+
541
+ selected = self._list_files.GetSelection()
542
+
543
+ if selected != wx.NOT_FOUND:
544
+
545
+ dlg = wx.MessageDialog(self._gui, _("Are you sure you want to delete this file ?"), _("Delete file"), wx.YES_NO | wx.ICON_QUESTION)
546
+ if dlg.ShowModal() == wx.ID_YES:
547
+ self._cur_list.pop(selected)
548
+ self._list_files.Set([cur[0] for cur in self._cur_list])
549
+
550
+ dlg.Destroy()
551
+
552
+ def on_apply(self, event):
553
+
554
+ selected = self._list_files.GetSelection()
555
+
556
+ if selected != wx.NOT_FOUND:
557
+
558
+ self._cur_list[selected][2] = [int(i) for i in self._list_blocks.GetSelections()]
559
+
560
+ def Show(self):
561
+
562
+ if self._gui is not None:
563
+ self._gui.Show()
564
+ else:
565
+ logging.error("No GUI created")
566
+
567
+ class Wolf2DInfiltration():
568
+
569
+ def __init__(self, sim:prev_sim2D = None):
570
+
571
+ self.wx_exists = wx.App.Get() is not None # test if wx App is running
572
+ self.sim = sim
573
+ self._gui = None
574
+
575
+ if self.wx_exists:
576
+ self.setup_gui()
577
+
578
+ @property
579
+ def number_of_infiltration(self):
580
+
581
+ return self.sim.infiltration.nb_zones
582
+
583
+ def setup_gui(self):
584
+
585
+ if not self.wx_exists:
586
+ logging.error("You can't create a GUI outside a wx.App")
587
+
588
+ self._gui = wx.Frame(None, title="Infiltration", size=(600, 400))
589
+
590
+ self._panel = wx.Panel(self._gui)
591
+
592
+ sizer_hor = wx.BoxSizer(wx.HORIZONTAL)
593
+ sizer_vert = wx.BoxSizer(wx.VERTICAL)
594
+ sizer_btns = wx.BoxSizer(wx.HORIZONTAL)
595
+
596
+ self._grid = CpGrid(self._panel,wx.ID_ANY, wx.WANTS_CHARS)
597
+ self._grid.CreateGrid(10, 3)
598
+
599
+ self._btn_apply = wx.Button(self._panel, label=_("Apply"))
600
+ self._btn_apply.Bind(wx.EVT_BUTTON, self.on_apply)
601
+ self._btn_apply.SetToolTipString(_("Apply the values in the grid to the in-memory simulation (without writing to disk)"))
602
+
603
+ self._btn_check = wx.Button(self._panel, label=_("Check"))
604
+ self._btn_check.Bind(wx.EVT_BUTTON, self.on_check)
605
+ self._btn_check.SetToolTipString(_("Check the consistency of the in-memory simulation (.fil and .inf files)"))
606
+
607
+ self._btn_reload = wx.Button(self._panel, label=_("Reload"))
608
+ self._btn_reload.Bind(wx.EVT_BUTTON, self.on_reload)
609
+ self._btn_reload.SetToolTipString(_("Reload the values from the in-memory simulation"))
610
+
611
+ self._btn_plot = wx.Button(self._panel, label=_("Plot"))
612
+ self._btn_plot.Bind(wx.EVT_BUTTON, self.on_plot)
613
+ self._btn_plot.SetToolTipString(_("Plot the discharges"))
614
+
615
+ self._btn_plus = wx.Button(self._panel, label="+")
616
+ self._btn_plus.Bind(wx.EVT_BUTTON, self.on_plus)
617
+ self._btn_plus.SetToolTipString(_("Add zone(s) or step(s)"))
618
+
619
+ self._btn_minus = wx.Button(self._panel, label="-")
620
+ self._btn_minus.Bind(wx.EVT_BUTTON, self.on_minus)
621
+ self._btn_minus.SetToolTipString(_("Remove zone(s) or step(s)"))
622
+
623
+ self._btn_adjust = wx.Button(self._panel, label=_("Adjust"))
624
+ self._btn_adjust.Bind(wx.EVT_BUTTON, self.on_adjust)
625
+ self._btn_adjust.SetToolTipString(_("Adjust the number of rows and columns of the grid"))
626
+
627
+ sizer_btns.Add(self._btn_apply, 2, wx.EXPAND | wx.ALL, 2)
628
+ sizer_btns.Add(self._btn_check, 2, wx.EXPAND | wx.ALL, 2)
629
+ sizer_btns.Add(self._btn_reload, 2, wx.EXPAND | wx.ALL, 2)
630
+ sizer_btns.Add(self._btn_plot, 2, wx.EXPAND | wx.ALL, 2)
631
+ sizer_btns.Add(self._btn_plus, 1, wx.EXPAND | wx.ALL, 2)
632
+ sizer_btns.Add(self._btn_minus, 1, wx.EXPAND | wx.ALL, 2)
633
+ sizer_btns.Add(self._btn_adjust, 2, wx.EXPAND | wx.ALL, 2)
634
+
635
+ self._txt_info = wx.TextCtrl(self._panel, style=wx.TE_MULTILINE|wx.TE_READONLY)
636
+
637
+ sizer_vert.Add(self._grid, 1, wx.EXPAND)
638
+ sizer_vert.Add(sizer_btns, 0, wx.EXPAND)
639
+ sizer_vert.Add(self._txt_info, 1, wx.EXPAND)
640
+
641
+ sizer_hor.Add(sizer_vert, 1, wx.EXPAND)
642
+
643
+ self._panel.SetSizer(sizer_hor)
644
+ self._panel.SetAutoLayout(1)
645
+
646
+ def on_apply(self, event):
647
+
648
+ i_max = 0
649
+ while self._grid.GetCellValue(i_max, 0) != "" and i_max < self._grid.GetNumberRows()-1:
650
+ i_max += 1
651
+
652
+ j_max = 1
653
+ while self._grid.GetCellValue(0, j_max) != "" and j_max < self._grid.GetNumberCols()-1:
654
+ j_max += 1
655
+
656
+ chronos = np.zeros((i_max, j_max), dtype=np.float64)
657
+
658
+ for i in range(i_max+1):
659
+ for j in range(j_max+1):
660
+ chronos[i,j] = self._grid.GetCellValue(i, j)
661
+
662
+ self.sim.infiltration.infiltrations_chronology = chronos
663
+ self._btn_check(1)
664
+
665
+
666
+ def _fillgrid(self):
667
+ """ Fill the CpGrid """
668
+
669
+ if self.sim is None:
670
+ logging.error("No simulation loaded")
671
+ return
672
+
673
+ grid = self._grid
674
+
675
+ nb_steps = self.sim.infiltration.nb_steps
676
+ nb_zones = self.sim.infiltration.nb_zones
677
+
678
+ chronos = self.sim.infiltration.infiltrations_chronology
679
+
680
+ if nb_steps > grid.GetNumberRows():
681
+ grid.AppendRows(nb_steps - grid.GetNumberRows())
682
+
683
+ if nb_zones > grid.GetNumberCols()-1:
684
+ grid.AppendCols(nb_zones+1 - grid.GetNumberCols())
685
+
686
+ grid.ClearGrid()
687
+
688
+ grid.SetColLabelValue(0, _("Time"))
689
+ for i in range(1,nb_zones+1):
690
+ grid.SetColLabelValue(i, f"Zone {i}")
691
+
692
+ for i in range(nb_steps):
693
+ for j in range(nb_zones+1):
694
+ grid.SetCellValue(i, j, str(chronos[i][j]))
695
+
696
+ def on_adjust(self, event):
697
+ """ Adjust the number of rows and columns of the CpGrid """
698
+
699
+ nb_steps = self.sim.infiltration.nb_steps
700
+ nb_zones = self.sim.infiltration.nb_zones
701
+
702
+ if self._grid.GetNumberCols() < nb_zones+1:
703
+ self._grid.AppendCols(nb_zones+1-self._grid.GetNumberCols())
704
+ elif self._grid.GetNumberCols() > nb_zones+1:
705
+ self._grid.DeleteCols(nb_zones, self._grid.GetNumberCols()-nb_zones-1)
706
+
707
+ if self._grid.GetNumberRows() < nb_steps:
708
+ self._grid.AppendRows(nb_steps-self._grid.GetNumberRows())
709
+ elif self._grid.GetNumberRows() > nb_steps:
710
+ self._grid.DeleteRows(nb_steps, self._grid.GetNumberRows()-nb_steps)
711
+
712
+ self._btn_check.SetBackgroundColour(wx.NullColour)
713
+
714
+ def on_plus(self, event):
715
+ """ Add a zone or steps"""
716
+
717
+ nb_zones = 0
718
+ nb_steps = 0
719
+
720
+ dlg = wx.NumberEntryDialog(self._gui, _('Number of zones to add'), _('Add zones'), _('Add'), value = 1, min=0, max=1000)
721
+ if dlg.ShowModal() == wx.ID_OK:
722
+ nb_zones = int(dlg.GetValue())
723
+
724
+ dlg.Destroy()
725
+
726
+ dlg = wx.NumberEntryDialog(self._gui, _('Number of steps to add'), _('Add steps'), _('Add'), value = 1, min=0, max=1000)
727
+ if dlg.ShowModal() == wx.ID_OK:
728
+ nb_steps = int(dlg.GetValue())
729
+
730
+ dlg.Destroy()
731
+
732
+ self._fillgrid()
733
+
734
+ self._grid.AppendCols(nb_zones)
735
+ self._grid.AppendRows(nb_steps)
736
+
737
+ self._btn_check.SetBackgroundColour(wx.NullColour)
738
+
739
+ def on_minus(self, event):
740
+ """ Remove a zone or steps"""
741
+
742
+ nb_zones = 0
743
+ nb_steps = 0
744
+
745
+ dlg = wx.NumberEntryDialog(self._gui, _('Number of zones to remove'), _('Remove zones'), _('Remove'), value = 0, min=0, max=self._grid.GetNumberCols())
746
+ if dlg.ShowModal() == wx.ID_OK:
747
+ nb_zones = int(dlg.GetValue())
748
+
749
+ dlg.Destroy()
750
+
751
+ dlg = wx.NumberEntryDialog(self._gui, _('Number of steps to remove'), _('Remove steps'), _('Remove'), value=0, min=0, max=self._grid.GetNumberRows())
752
+ if dlg.ShowModal() == wx.ID_OK:
753
+ nb_steps = int(dlg.GetValue())
754
+
755
+ dlg.Destroy()
756
+
757
+ self._fillgrid()
758
+
759
+ self._grid.DeleteCols(nb_zones)
760
+ self._grid.DeleteRows(nb_steps)
761
+
762
+ self._btn_check.SetBackgroundColour(wx.NullColour)
763
+
764
+ def on_check(self, event):
765
+
766
+ if self.sim is None:
767
+ self._txt_info.SetValue("No simulation loaded")
768
+ return
769
+
770
+ ret = self.sim.check_infiltration()
771
+ self._txt_info.SetValue(ret)
772
+
773
+ if "Warning" in ret:
774
+ self._btn_check.SetBackgroundColour(wx.RED)
775
+ else:
776
+ self._btn_check.SetBackgroundColour(wx.GREEN)
777
+
778
+ def on_reload(self, event):
779
+
780
+ self._fillgrid()
781
+
782
+ def on_plot(self, event):
783
+
784
+ if self.sim is None:
785
+ self._txt_info.SetValue("No simulation loaded")
786
+ return
787
+
788
+ self.sim.infiltration.plot_plt()
789
+
790
+ self._btn_check.SetBackgroundColour(wx.NullColour)
791
+
792
+ def Show(self):
793
+
794
+ if self._gui is not None:
795
+ self._fillgrid()
796
+ self._gui.Show()
797
+ else:
798
+ logging.error("No GUI created")
799
+
342
800
  class Wolf2DModel(GenMapManager):
343
801
 
344
802
  mydir:str
803
+ sim:prev_sim2D
804
+
345
805
  # A path to the beacon file (not just the filename)
346
806
  filenamegen:str
347
- files_others:dict
348
- files_fine_array:dict
349
- files_MB_array:dict
350
- files_vectors:dict
351
- mainparams:Wolf_Param
352
807
 
353
808
  # When updating these, pay attention to the fact they are heavliy intertwined.
354
809
  # - Boundary conditions coordinates must coincide with cell borders
355
810
 
356
- myparam: prev_parameters_simul # Parameters of the simulation
357
- mynap: np.ndarray # Active cells in the simulation (-1 == active; 0 == inactive)
358
- napbin: WolfArray_Sim2D
359
- mysuxy: prev_suxsuy # Coordinates of cells border acting as limits of simulation
360
- xyfile: xy_file
361
- myinfil: prev_infiltration # Infiltration
362
-
363
- top: WolfArray_Sim2D # Sim2D will wire their masks onto self.napbin.array.mask
364
- frot: WolfArray_Sim2D
365
- hbin: WolfArray_Sim2D
366
- qxbin: WolfArray_Sim2D
367
- qybin: WolfArray_Sim2D
368
- zbin: WolfArray_Sim2D
369
- topinifine: WolfArray_Sim2D
370
-
371
- hbinb: WolfArrayMB # Initial condition: water height (multibloc)
372
- qxbinb: WolfArrayMB # Initial condition: discharge horizontal (multibloc)
373
- qybinb: WolfArrayMB # Initial condition: discharge vertical (multibloc)
374
- topini: WolfArrayMB # Bathymetry (multibloc)
375
-
376
- # A WolfArrayMB with several Zones that makes its contour
377
- # The MNAP is the multiblock NAP. It's a big array covering the
378
- # all the arrays of each block. It is used as a NAP but also as an
379
- # index from one block's border to another block's border (so it's
380
- # not filled with zero and ones only but also with block-indices)
381
- # The MNAP array is a *result* array.
382
- mymnap: WolfArrayMNAP
383
- myblocfile: bloc_file
384
-
385
- xyzones: Zones # A link to self.xyfile.myzones FIXME replace that with a property
386
- curmask: np.ndarray # A link to self.napbin.array.mask
387
- fines_array: list[WolfArray_Sim2D] # list containing: napbin, top, frot, inf, hbin, qxbin, qybin
388
-
389
811
  SPWstations:SPWMIGaugingStations
390
812
  DCENNstations:SPWDCENNGaugingStations
391
813
 
392
- def _from_params(self, base_file, myparam: prev_parameters_simul):
393
- """ This is a __init__ helper. This will be used in the constructor
394
- to create a mono-block model from scratch (i.e. not reading from disk;
395
- providing base matrices).
814
+ @property
815
+ def mymnap(self):
816
+ return self.sim.mymnap
817
+
818
+ @property
819
+ def xyzones(self):
820
+ return self.sim.xyfile.myzones
821
+
822
+ @property
823
+ def mysuxsuy(self):
824
+ return self.sim.sux_suy
825
+
826
+ @property
827
+ def blocfile(self):
828
+ return self.sim.bloc_description
396
829
 
397
- @base_file Directroy where the model should reside.
398
- @myparam The parameters to build the model with.
830
+ def __init__(self, *args, dir:str='', **kw):
399
831
  """
400
- assert isdir(Path(base_file).parent), \
401
- f"When creating from parameters you must give a path containing the generic final name, prepended by a an existing directory (you gave a directory: {base_file} which doesn't exist)"
402
-
403
- self.mydir = Path(base_file).parent.as_posix()
404
- self.filenamegen = Path(base_file).name
405
-
406
- if len(myparam.my_param_blocks) == 0:
407
- myparam.my_param_blocks.append(prev_parameters_blocks())
408
-
409
- self.myparam = myparam
410
- self.myparam.parent = self
411
-
412
- self.mynap= np.ones([self.myparam.nxfin, self.myparam.nyfin], order='F', dtype=np.int16)
413
-
414
- self.mysuxy = prev_suxsuy(self)
415
- self.xyfile = xy_file(self)
416
- self.xyzones = self.xyfile.myzones
417
- self.myinfil=prev_infiltration(self)
418
- self.myblocfile=bloc_file(self)
419
-
420
- general = zone(name='General',parent=self.myblocfile.my_vec_blocks)
421
- # FIXME Line None should be removed but then it fails on some ellipsis later on.
422
- external_border = bloc_external_border(is2D=True, name='external border', lines=None) ##< vecteur du contour externe
423
- general.add_vector(external_border)
424
- self.myblocfile.my_vec_blocks.add_zone(general)
425
-
426
- myextents = zone(name='Blocks extents',parent=self.myblocfile.my_vec_blocks)
427
- self.myblocfile.my_vec_blocks.add_zone(myextents)
428
- self.myblocfile.interior = True
429
-
430
-
431
- header = self.get_header()
432
-
433
- self.napbin = WolfArray_Sim2D(whichtype=WOLF_ARRAY_FULL_LOGICAL,
434
- preload=True,
435
- srcheader=header,
436
- masksrc=None)
437
-
438
- # FIXME NAPBIN is special, it is np.int16
439
- # should it be handled by `whichtype ???`
440
- # masksrc = None avoid snake eating his own tail
441
- d = np.zeros_like(self.napbin.array.data, dtype=np.int16)
442
- self.napbin.array = ma.MaskedArray(d, np.zeros_like(d,dtype=bool))
443
-
444
- # Warning! Without hardening, a write to a masked array
445
- # will *clear* the mask. But then one is facing another issue.
446
- # If one wants to write into the array, it has to unmask it. But
447
- # if the mask is shared, then that will unmask every arrays that
448
- # share the mask.
449
- self.napbin.array.harden_mask()
450
- self.napbin.filename = self.filenamegen+'.napbin'
451
- self.curmask = self.napbin.array.mask
452
-
453
- def wire_wolf_array(filename,
454
- whichtype=WOLF_ARRAY_FULL_SINGLE,
455
- preload=False,
456
- srcheader=header,
457
- masksrc=self.curmask,
458
- nullvalue=-99999):
459
-
460
- wa = WolfArray_Sim2D(
461
- fname = filename,
462
- whichtype=whichtype,
463
- preload=preload,
464
- masksrc=masksrc,
465
- srcheader=srcheader,
466
- nullvalue=nullvalue)
467
-
468
- # Warning! This is the only way I have found working to
469
- # share a mask between several arrays. So, to do that
470
- # one must pass the mask in the constructor call.
471
- # (replacing the mask with wa.array.mask == ... won't
472
- # do !).
473
- # Other issue: hardening the mask really means: "harden the
474
- # mask applied to this array". So if one hardens the mask
475
- # for one array, it will not protect the other arrays
476
- # sharing the mask. So hardening must be done on all arrays.
477
- wa.array = ma.MaskedArray(
478
- np.ones((wa.nbx, wa.nby), order='F', dtype=np.float32)*float(wa.nullvalue),
479
- mask = masksrc)
480
- wa.array.harden_mask() # See note about sharing hardened masks
481
- return wa
482
-
483
- self.top = wire_wolf_array(self.filenamegen+'.top')
484
- self.topinifine = wire_wolf_array(self.filenamegen+'.topinifine')
485
- self.frot = wire_wolf_array(self.filenamegen+'.frot')
486
- self.hbin = wire_wolf_array(self.filenamegen+'.hbin')
487
- self.qxbin = wire_wolf_array(self.filenamegen+'.qxbin')
488
- self.qybin = wire_wolf_array(self.filenamegen+'.qybin')
489
- self.zbin = wire_wolf_array(self.filenamegen+'.zbin')
490
-
491
- # FIXME Why is inf not a WolfArray_Sim2D like the others ?
492
- self.inf = self.myinfil.myarray
493
- self.myinfil.masksrc=self.curmask
494
- self.myinfil.myarray.add_ops_sel()
495
-
496
-
497
- # def _init_multibloc(self, mapviewer=None):
498
- # # FIXME MultiBlock come after processing by WolfCli
499
- # # This code is not yet tested
500
-
501
- # self.mymnap= WolfArrayMNAP()
502
- # self.mymnap.mapviewer=mapviewer
503
- # self.mymnap.add_ops_sel()
504
-
505
- # self.hbinb = WolfArrayMB(whichtype=WOLF_ARRAY_MB_SINGLE,preload=False,mapviewer=mapviewer)
506
- # self.hbinb.filename = self.filenamegen+'.hbinb'
507
- # # get_header_MB will pick its information from the mnap array.
508
- # self.hbinb.set_header(self.get_header_MB())
509
-
510
- # self.qxbinb = WolfArrayMB( whichtype=WOLF_ARRAY_MB_SINGLE,preload=False,mapviewer=mapviewer)
511
- # self.qxbinb.filename = self.filenamegen+'.qxbinb'
512
- # self.qxbinb.set_header(self.get_header_MB())
513
-
514
- # self.qybinb = WolfArrayMB(whichtype=WOLF_ARRAY_MB_SINGLE,preload=False,mapviewer=mapviewer)
515
- # self.qybinb.filename = self.filenamegen+'.qybinb'
516
- # self.qybinb.set_header(self.get_header_MB())
517
-
518
- # self.topini = WolfArrayMB(whichtype=WOLF_ARRAY_MB_SINGLE,preload=False,mapviewer=mapviewer)
519
- # self.topini.filename = self.filenamegen+'.topini'
520
- # self.topini.set_header(self.get_header_MB())
521
-
522
-
523
- def __init__(self, *args, dir:str='', from_params: Union[None,prev_parameters_simul]=None, **kw):
524
- """ @dir: directory containing the simulation, the
525
- base file name (e.g. "simul") will be autodetected.
832
+ :param dir: directory containing the simulation, the base file name (e.g. "simul") will be autodetected.
526
833
  If you create a model from scracth, then you must provide
527
834
  the base file name as well (e.g. "d:/mywolfsim/sim")
528
835
 
@@ -533,12 +840,11 @@ class Wolf2DModel(GenMapManager):
533
840
 
534
841
  super(Wolf2DModel, self).__init__(*args, **kw)
535
842
 
536
- self.SPWstations=SPWMIGaugingStations()
537
- self.DCENNstations=SPWDCENNGaugingStations()
843
+ self._ref_block = None
538
844
 
539
- if from_params is not None:
540
- self._from_params(base_file=dir, myparam=from_params)
541
- return
845
+ # Gauging stations - SPW
846
+ self.SPWstations = SPWMIGaugingStations()
847
+ self.DCENNstations = SPWDCENNGaugingStations()
542
848
 
543
849
  if dir != '':
544
850
  # Either a directory or a file "/_/_/_/dir/simul" for example.
@@ -547,6 +853,8 @@ class Wolf2DModel(GenMapManager):
547
853
 
548
854
  if dir=='':
549
855
  if self.wx_exists:
856
+ # Propose a dialog window to choose the directory
857
+
550
858
  idir=wx.DirDialog(None,"Choose Directory")
551
859
  if idir.ShowModal() == wx.ID_CANCEL:
552
860
  self.setup_mapviewer(title='Blank 2D model',wolfparent=self)
@@ -562,7 +870,7 @@ class Wolf2DModel(GenMapManager):
562
870
  self.mydir=normpath(dir)
563
871
 
564
872
  if self.wx_exists:
565
- wait_dlg, wait_cursor = BusyInfo(_('Opening 2D model')), wx.BusyCursor()
873
+
566
874
  self.setup_mapviewer(title='2D model : '+self.mydir, wolfparent=self)
567
875
 
568
876
  try:
@@ -583,6 +891,7 @@ class Wolf2DModel(GenMapManager):
583
891
 
584
892
  self.filenamegen=""
585
893
  second_choice = None
894
+
586
895
  #recherche du nom générique --> sans extension
587
896
  scandir_obj = scandir(self.mydir)
588
897
  for curfile in scandir_obj:
@@ -607,340 +916,1437 @@ class Wolf2DModel(GenMapManager):
607
916
  self.filenamegen = second_choice
608
917
  else:
609
918
  logging.info(_(f"The provided directory doesn't seem to be a Wolf simulation"))
919
+ self.filenamegen = str(Path(self.mydir) /'newsim')
610
920
 
611
921
 
612
922
  logging.info(_(f'Generic file is : {self.filenamegen}'))
613
923
  logging.info(_('Creating GUI'))
614
924
 
615
- self.files_others={'Generic file':[
616
- ('','First parametric file - historical'),
617
- ('.par','Parametric file - multiblocks')],
618
- 'Characteristics':[
619
- ('.fil','Infiltration hydrographs [m³/s]'),
620
- ('.mnap','Resulting mesh [-]'),
621
- ('.trl','Translation to real world [m]')
622
- ]}
623
-
624
- self.files_vectors={'Block file':[
625
- ('.bloc','Blocks geometry')],
626
- 'Borders':[
627
- ('.sux','X borders'),
628
- ('.suy','Y borders')],
629
- 'Contour':[
630
- ('.xy','General perimeter')
631
- ]}
632
-
633
- self.files_MB_array={'Initial Conditions':[
634
- ('.topini','Bed elevation [m]',WOLF_ARRAY_MB_SINGLE),
635
- ('.hbinb','Water depth [m]',WOLF_ARRAY_MB_SINGLE),
636
- ('.qxbinb','Discharge X [m²/s]',WOLF_ARRAY_MB_SINGLE),
637
- ('.qybinb','Discharge Y [m²/s]',WOLF_ARRAY_MB_SINGLE),
638
- ('.frotini','Roughness coeff',WOLF_ARRAY_MB_SINGLE)
639
- ]}
640
-
641
- self.files_fine_array={'Characteristics':[
642
- ('.napbin','Mask [-]',WOLF_ARRAY_FULL_LOGICAL),
643
- ('.top','Bed Elevation [m]',WOLF_ARRAY_FULL_SINGLE),
644
- ('.topini_fine','Bed Elevation - computed [m]',WOLF_ARRAY_FULL_SINGLE),
645
- ('.frot','Roughness coefficient [law dependent]',WOLF_ARRAY_FULL_SINGLE),
646
- ('.inf','Infiltration zone [-]', WOLF_ARRAY_FULL_INTEGER),
647
- ('.hbin','Initial water depth [m]',WOLF_ARRAY_FULL_SINGLE),
648
- ('.qxbin','Initial discharge along X [m^2/s]',WOLF_ARRAY_FULL_SINGLE),
649
- ('.qybin','Initial discharge along Y [m^2/s]',WOLF_ARRAY_FULL_SINGLE)
650
- ]}
925
+ # Initilisation d'une simulation 2D sur base des fichiers
926
+ self.sim = prev_sim2D(self.filenamegen)
651
927
 
928
+ # Liste des objets à ajouter au GUI
652
929
  self.fines_array=[]
653
930
 
654
- logging.info(_('Importing global parameters'))
655
- self.myparam=prev_parameters_simul(self)
656
- self.myparam.read_file()
931
+ logging.info(_('Treating arrays'))
657
932
 
658
- logging.info(_('Reading mask'))
659
- self.mynap = self.read_fine_nap()
933
+ self._add_arrays_to_mapviewer()
934
+ self._add_vectors_to_mapviewer()
660
935
 
661
- logging.info(_('Reading sux-suy'))
662
- self.mysuxy = prev_suxsuy(self)
663
- self.mysuxy.read_file()
936
+ logging.info(_('Zooming'))
937
+ self.mapviewer.findminmax(True)
938
+ self.mapviewer.Autoscale(False)
664
939
 
665
- logging.info(_('Reading xy'))
666
- self.xyfile = xy_file(self)
667
- self.xyzones = self.xyfile.myzones
940
+ self.show_properties()
668
941
 
669
- logging.info(_('Reading infiltration'))
670
- self.myinfil=prev_infiltration(self)
671
- try:
672
- self.myinfil.read_file()
673
- self.myinfil.read_array()
674
- except Exception as ex:
675
- logging.error(_("Error while reading infinltration file (.INF, .FIL) -- Check you files -- Continuing but without infiltration or Bad positioning"))
676
- self.myinfil=prev_infiltration(self)
942
+ if self.wx_exists:
943
+ self.mapviewer.add_object(which='other',newobj=self.SPWstations,ToCheck=False,id='SPW-MI stations')
944
+ self.mapviewer.add_object(which='other',newobj=self.DCENNstations,ToCheck=False,id='SPW-DCENN stations')
677
945
 
678
- logging.info(_('Reading blocks'))
679
- self.myblocfile=bloc_file(self)
680
- self.myblocfile.read_file()
946
+ logging.info(_('Adapting menu'))
947
+ self.mapviewer.menu_sim2D()
681
948
 
682
- logging.info(_('Reading MNAP'))
683
- self.mymnap= WolfArrayMNAP(self.filenamegen)
949
+ logging.info(_('Verifying files'))
950
+ self.sim.verify_files()
684
951
 
685
- # self.cont_sauv:Zones
686
- # self.filaire:Zones
952
+ logging.info(_('Model loaded !!'))
687
953
 
688
- logging.info(_('Treating arrays'))
954
+ except Exception as ex:
955
+ logging.error(str(ex), exc_info=True)
689
956
 
690
- #fine resolution
691
- self.napbin = WolfArray_Sim2D(fname=self.filenamegen+'.napbin',
692
- whichtype=WOLF_ARRAY_FULL_LOGICAL,
693
- preload=True,
694
- mapviewer=self.mapviewer,
695
- srcheader=self.get_header())
696
-
697
- self.curmask = self.napbin.array.mask
957
+ @property
958
+ def writing_mode(self):
959
+ return self.sim.parameters._writing_mode
698
960
 
961
+ @property
962
+ def writing_frequency(self):
963
+ return self.sim.parameters._writing_frequency
699
964
 
700
- self.top = WolfArray_Sim2D(fname=self.filenamegen+'.top',
701
- whichtype=WOLF_ARRAY_FULL_SINGLE,
702
- preload=False,
703
- mapviewer=self.mapviewer,
704
- masksrc=self.curmask,
705
- srcheader=self.get_header())
965
+ @property
966
+ def dx_fine(self):
967
+ return self.sim.parameters._fine_mesh_dx
706
968
 
969
+ @property
970
+ def dy_fine(self):
971
+ return self.sim.parameters._fine_mesh_dy
707
972
 
708
- self.topinifine = WolfArray_Sim2D(fname=self.filenamegen+'.topini_fine',
709
- whichtype=WOLF_ARRAY_FULL_SINGLE,
710
- preload=False,
711
- mapviewer=self.mapviewer,
712
- masksrc=self.curmask,
713
- srcheader=self.get_header())
973
+ def _dx_block(self, idx):
974
+ return self.sim.bloc_description.my_blocks[idx].dx
714
975
 
976
+ def _dy_block(self, idx):
977
+ return self.sim.bloc_description.my_blocks[idx].dy
715
978
 
716
- self.frot = WolfArray_Sim2D(fname=self.filenamegen+'.frot',
717
- whichtype=WOLF_ARRAY_FULL_SINGLE,
718
- preload=False,
719
- mapviewer=self.mapviewer,
720
- masksrc=self.curmask,
721
- srcheader=self.get_header())
979
+ @property
980
+ def scheme_rk(self):
981
+ return self.sim.parameters._scheme_rk
722
982
 
723
983
 
724
- self.inf = self.myinfil.myarray
725
- self.myinfil.myarray.mapviewer=self.mapviewer
726
- self.myinfil.masksrc=self.curmask
727
- self.myinfil.myarray.add_ops_sel()
984
+ def _add_arrays_to_mapviewer(self, force_reload=False):
985
+ """ Add arrays to the mapviewer """
728
986
 
729
- self.hbin = WolfArray_Sim2D(fname=self.filenamegen+'.hbin',
730
- whichtype=WOLF_ARRAY_FULL_SINGLE,
731
- preload=False,
732
- mapviewer=self.mapviewer,
733
- masksrc=self.curmask,
734
- srcheader=self.get_header())
987
+ # Mono-blocks
988
+ # ------------
735
989
 
990
+ fines = self.sim.files_fine_array['Characteristics']
736
991
 
737
- self.qxbin = WolfArray_Sim2D(fname=self.filenamegen+'.qxbin',
738
- whichtype=WOLF_ARRAY_FULL_SINGLE,
739
- preload=False,
740
- mapviewer=self.mapviewer,
741
- masksrc=self.curmask,
742
- srcheader=self.get_header())
992
+ existing_id = self.mapviewer.get_list_keys(drawing_type=draw_type.ARRAYS, checked_state=None)
743
993
 
994
+ for ext, name, wolftype in fines:
744
995
 
745
- self.qybin = WolfArray_Sim2D(fname=self.filenamegen+'.qybin',
746
- whichtype=WOLF_ARRAY_FULL_SINGLE,
747
- preload=False,
748
- mapviewer=self.mapviewer,
749
- masksrc=self.curmask,
750
- srcheader=self.get_header())
996
+ locarray = self.sim.get_wolf_array(ext)
751
997
 
998
+ if locarray is not None:
752
999
 
753
- #altitude de surface libre --> si le fichier n'existe pas, la matrice est créée sur base de l'addition de la topo et de la hauteur
754
- # cf surcharge de la lecture dans WolfArray_Sim2D
755
- self.zbin = WolfArray_Sim2D(fname=self.filenamegen+'.zbin',
756
- whichtype=WOLF_ARRAY_FULL_SINGLE,
757
- preload=False,
758
- mapviewer=self.mapviewer,
759
- masksrc=self.curmask,
760
- srcheader=self.get_header())
1000
+ if name.lower() not in existing_id:
761
1001
 
1002
+ # locarray.nullvalue = 99999.
762
1003
 
763
- self.fines_array.append(self.napbin)
764
- self.fines_array.append(self.top)
765
- self.fines_array.append(self.frot)
766
- self.fines_array.append(self.inf)
767
- self.fines_array.append(self.hbin)
768
- self.fines_array.append(self.qxbin)
769
- self.fines_array.append(self.qybin)
1004
+ self.mapviewer.add_object(which='array',
1005
+ ToCheck=False,
1006
+ newobj=locarray,
1007
+ id=name.lower())
1008
+ elif force_reload:
1009
+ self.sim.force_reload(locarray)
770
1010
 
771
- #MB resolution
772
- self.hbinb = WolfArrayMB(fname=self.filenamegen+'.hbinb',
773
- whichtype=WOLF_ARRAY_MB_SINGLE,
774
- preload=True,
775
- mapviewer=self.mapviewer)
1011
+ if locarray.plotted:
1012
+ locarray.reset_plot()
776
1013
 
777
- self.hbinb.set_header(self.get_header_MB())
1014
+ locarray = self.sim.zbin
1015
+ name = _('Water level [m]')
1016
+ if locarray is not None:
778
1017
 
779
- self.qxbinb = WolfArrayMB(fname=self.filenamegen+'.qxbinb',
780
- whichtype=WOLF_ARRAY_MB_SINGLE,
781
- preload=False,
782
- mapviewer=self.mapviewer)
1018
+ if name.lower() not in existing_id:
783
1019
 
784
- self.qxbinb.set_header(self.get_header_MB())
1020
+ # locarray.nullvalue = 99999.
785
1021
 
786
- self.qybinb = WolfArrayMB(fname=self.filenamegen+'.qybinb',
787
- whichtype=WOLF_ARRAY_MB_SINGLE,
788
- preload=False,
789
- mapviewer=self.mapviewer)
1022
+ self.mapviewer.add_object(which='array',
1023
+ ToCheck=False,
1024
+ newobj=locarray,
1025
+ id=name.lower())
790
1026
 
791
- self.qybinb.set_header(self.get_header_MB())
1027
+ elif force_reload:
792
1028
 
793
- self.topini = WolfArrayMB(fname=self.filenamegen+'.topini',
794
- whichtype=WOLF_ARRAY_MB_SINGLE,
795
- preload=True,
796
- mapviewer=self.mapviewer)
1029
+ self.sim.force_reload(locarray)
797
1030
 
798
- self.topini.set_header(self.get_header_MB())
799
- self.zbinb = self.topini + self.hbinb
800
- self.zbinb.loaded=True
1031
+ if locarray.checked:
1032
+ locarray.reset_plot()
801
1033
 
1034
+ # Multi-blocks
1035
+ # ------------
802
1036
 
1037
+ # MNAP
1038
+ multiblocks = self.sim.files_MB_array['Characteristics']
803
1039
 
804
- if self.wx_exists:
805
- logging.info(_('Adding arrays to GUI'))
806
-
807
- self.mymnap.mapviewer=self.mapviewer
808
- self.mymnap.add_ops_sel()
809
-
810
- self.mapviewer.add_object(which='array',newobj=self.napbin,id='mask - fine',ToCheck=True)
811
- self.mapviewer.add_object(which='array',newobj=self.top,id='bed elevation - fine',ToCheck=False)
812
- self.mapviewer.add_object(which='array',newobj=self.topinifine,id='bed elevation - computed',ToCheck=False)
813
- self.mapviewer.add_object(which='array',newobj=self.frot,id='manning roughness - fine',ToCheck=False)
814
- self.mapviewer.add_object(which='array',newobj=self.inf,id='infiltration',ToCheck=False)
815
- self.mapviewer.add_object(which='array',newobj=self.mymnap,id='mnap',ToCheck=False)
816
- self.mapviewer.add_object(which='array',newobj=self.hbin,id='H - IC',ToCheck=False)
817
- self.mapviewer.add_object(which='array',newobj=self.qxbin,id='QX - IC',ToCheck=False)
818
- self.mapviewer.add_object(which='array',newobj=self.qybin,id='QY - IC',ToCheck=False)
819
- self.mapviewer.add_object(which='array',newobj=self.zbin,id='Water level - IC',ToCheck=False)
820
- self.mapviewer.add_object(which='array',newobj=self.qxbinb,id='QX - IC - MB',ToCheck=False)
821
- self.mapviewer.add_object(which='array',newobj=self.qybinb,id='QY - IC - MB',ToCheck=False)
822
- self.mapviewer.add_object(which='array',newobj=self.topini,id='bed elevation - MB',ToCheck=False)
823
- self.mapviewer.add_object(which='array',newobj=self.zbinb,id='water level - IC - MB',ToCheck=False)
824
-
825
- #vectors
826
- logging.info(_('Adding vectors to GUI'))
827
- self.mapviewer.add_object(which='array',newobj=self.hbinb,id='H - IC - MB',ToCheck=False)
828
- self.mapviewer.add_object(which='vector',newobj=self.xyzones,id='XY',ToCheck=True)
829
- self.mapviewer.add_object(which='vector',newobj=self.mysuxy.myborders,id='Borders',ToCheck=False)
830
- self.mapviewer.add_object(which='vector',newobj=self.myblocfile.my_vec_blocks,id='Blocks',ToCheck=False)
1040
+ for ext, name, wolftype in multiblocks:
831
1041
 
832
- self.mapviewer.add_object(which='other',newobj=self.SPWstations,ToCheck=False,id='SPW-MI stations')
833
- self.mapviewer.add_object(which='other',newobj=self.DCENNstations,ToCheck=False,id='SPW-DCENN stations')
1042
+ locarray = self.sim.get_wolf_array(ext)
834
1043
 
835
- logging.info(_('Zooming'))
836
- self.mapviewer.findminmax(True)
837
- self.mapviewer.Autoscale(False)
1044
+ if locarray is not None:
838
1045
 
839
- self.mysuxy.myborders.prep_listogl()
840
- self.myblocfile.my_vec_blocks.prep_listogl()
1046
+ if name.lower() not in existing_id:
841
1047
 
842
- #Fichiers de paramètres
843
- # self.mainparams=Wolf_Param(self.allviews,filename=self.mydir+'\\Main_model.param',title="Model parameters",DestroyAtClosing=False)
844
- # self.mainparams.Hide()
1048
+ # locarray.nullvalue = 99999.
845
1049
 
846
- logging.info(_('Adapting menu'))
847
- self.mapviewer.menu_sim2D()
1050
+ self.mapviewer.add_object(which='array',
1051
+ ToCheck=False,
1052
+ newobj=locarray,
1053
+ id=name.lower())
1054
+ elif force_reload:
1055
+ self.sim.force_reload(locarray)
848
1056
 
849
- logging.info(_('Verifying files'))
1057
+ if locarray.checked:
1058
+ locarray.reset_plot()
850
1059
 
851
- self.verify_files()
852
1060
 
853
- except Exception as ex:
854
- logging.error(str(ex), exc_info=True)
855
- finally:
856
- if self.wx_exists:
857
- del wait_cursor
858
- del wait_dlg
1061
+ multiblocks = self.sim.files_MB_array['Initial Conditions']
859
1062
 
1063
+ for ext, name, wolftype in multiblocks:
860
1064
 
861
- def verify_files(self):
862
- """
863
- Vérification de la présence des en-têtes dans les différents fichiers
864
- """
1065
+ locarray = self.sim.get_wolf_array(ext)
865
1066
 
866
- fhead = self.get_header()
867
- mbhead = self.get_header_MB()
1067
+ if locarray is not None:
868
1068
 
869
- fine = self.files_fine_array['Characteristics']
870
- for curextent,text,wolftype in fine:
871
- fname = self.filenamegen + curextent
872
- if exists(fname):
873
- fname += '.txt'
874
- fhead.write_txt_header(fname, wolftype, forceupdate=True)
1069
+ if name.lower() not in existing_id:
875
1070
 
876
- mb = self.files_MB_array['Initial Conditions']
877
- for curextent,text,wolftype in mb:
878
- fname = self.filenamegen + curextent
879
- if exists(fname):
880
- fname += '.txt'
881
- mbhead.write_txt_header(fname, wolftype, forceupdate=True)
1071
+ # locarray.nullvalue = 99999.
882
1072
 
883
- fname = self.filenamegen + '.lst'
884
- if not exists(fname):
885
- with open(fname,'w') as f:
886
- f.write('0\n')
1073
+ self.mapviewer.add_object(which='array',
1074
+ ToCheck=False,
1075
+ newobj=locarray,
1076
+ id=name.lower())
1077
+ elif force_reload:
1078
+ self.sim.force_reload(locarray)
887
1079
 
888
- def mimic_mask(self,source:WolfArray_Sim2D):
1080
+ if locarray.checked:
1081
+ locarray.reset_plot()
889
1082
 
890
- logging.info(_('Copying mask to all arrays'))
891
- self.curmask = source.array.mask
1083
+ locarray = self.sim.zbinb
1084
+ name = _('MB - Water level [m]')
1085
+ if locarray is not None:
892
1086
 
893
- for curarray in self.fines_array:
894
- curarray:WolfArray_Sim2D
895
- if curarray is not source and curarray.loaded:
896
- curarray.copy_mask_log(self.curmask)
1087
+ if name.lower() not in existing_id:
897
1088
 
898
- logging.info(_('Updating mask array and .nap file'))
899
- self.napbin.array.data[np.where(np.logical_not(self.curmask))] = -1
900
- self.napbin.write_all()
1089
+ # locarray.nullvalue = 99999.
901
1090
 
902
- def extend_bed_elevation(self):
903
- """
904
- Extension du modèle topographique
905
- """
906
- if not self.wx_exists:
907
- raise Warning('Must be operated by GUI --> Nothing will be done !! or generalize the source code :-) ')
1091
+ self.mapviewer.add_object(which='array',
1092
+ ToCheck=False,
1093
+ newobj=locarray,
1094
+ id=name.lower())
1095
+ elif force_reload:
908
1096
 
909
- dlg = wx.MessageDialog(self,_('Do you want to autocomplete elevation from external file?'),style=wx.YES_NO|wx.YES_DEFAULT)
910
- ret=dlg.ShowModal()
911
- dlg.Destroy()
1097
+ self.sim.force_reload(locarray)
912
1098
 
913
- if ret == wx.ID_NO:
914
- logging.info(_('Nothing to do !'))
915
- return
1099
+ if locarray.checked:
1100
+ locarray.reset_plot()
916
1101
 
917
- if not self.top.loaded:
918
- self.top.check_plot()
919
- self.top.copy_mask_log(self.curmask)
920
- self.top.loaded=True
921
1102
 
922
- filterArray = "bin (*.bin)|*.bin|all (*.*)|*.*"
923
- fdlg = wx.FileDialog(self, "Choose file", wildcard=filterArray, style=wx.FD_OPEN)
924
- if fdlg.ShowModal() != wx.ID_OK:
925
- fdlg.Destroy()
926
- return
1103
+ def _add_vectors_to_mapviewer(self):
1104
+ """ Add vectors to the mapviewer """
927
1105
 
928
- filename = fdlg.GetPath()
929
- fdlg.Destroy()
1106
+ existing_id = self.mapviewer.get_list_keys(drawing_type=draw_type.ARRAYS, checked_state=False)
930
1107
 
931
- logging.info(_('Importing data from file'))
932
- newtop = WolfArray(fname=filename,mapviewer=self.mapviewer)
1108
+ # for key, values in self.sim.files_vectors.items():
1109
+ values = self.sim.files_vectors['Block file']
933
1110
 
934
- logging.info(_('Finding nodes -- plotting disabled for speed'))
935
- self.top.mngselection.hideselection = True
936
- self.top.mngselection.condition_select(2,0., usemask=True)
1111
+ for cur in values:
937
1112
 
938
- if len(self.top.mngselection.myselection)>0:
939
- newtop.mngselection.myselection = self.top.mngselection.myselection
940
- newtop.mngselection.hideselection = True
941
- newtop.mngselection.update_nb_nodes_sections()
1113
+ ext, name = cur
942
1114
 
943
- logging.info(_('Copying values'))
1115
+ if Path(self.filenamegen+ext).exists():
1116
+
1117
+ if name not in existing_id:
1118
+
1119
+ locZones = self.sim.get_Zones_from_extension(ext)
1120
+
1121
+ if locZones is not None:
1122
+
1123
+ assert isinstance(locZones, Zones), 'locZones is not a Zones object'
1124
+
1125
+ self.mapviewer.add_object(which='vector',
1126
+ ToCheck=False if ext != '.bloc' else True,
1127
+ newobj=locZones,
1128
+ id=name)
1129
+
1130
+ # We must set the parent of the "Zones" object to permit access to the mapviewer
1131
+ # prep_listogl() is called to prepare the display of the zones and "mapviewer" is needed
1132
+ if self.sim.bloc_description is not None:
1133
+ self.sim.bloc_description.my_vec_blocks.parent = self
1134
+ self.sim.bloc_description.my_vec_blocks.set_mapviewer()
1135
+ self.sim.bloc_description.my_vec_blocks.prep_listogl()
1136
+
1137
+ # self.sim.sux_suy.myborders.parent = self
1138
+ # self.sim.sux_suy.myborders.set_mapviewer()
1139
+ # self.sim.sux_suy.myborders.prep_listogl()
1140
+
1141
+
1142
+ def mimic_mask(self, source:WolfArray):
1143
+ """ Copy the mask of the source array to all arrays in the model. """
1144
+
1145
+ self.som.mime_mask(source)
1146
+
1147
+ def show_properties(self):
1148
+ """
1149
+ Show the properties of the model
1150
+ """
1151
+
1152
+ if self.wx_exists:
1153
+
1154
+ # Création d'un wx Frame pour les paramètres
1155
+ self._prop_frame = wx.Frame(self,
1156
+ title=_('Parameters') + self.filenamegen,
1157
+ size=(650, 800),
1158
+ style = wx.DEFAULT_FRAME_STYLE)
1159
+
1160
+ # add a panel
1161
+ self._panel = wx.Panel(self._prop_frame)
1162
+
1163
+ # Set sizers
1164
+ #
1165
+ # The panel is decomposed in three parts:
1166
+ # - List of toogle buttons + properties
1167
+ # - Buttons to add/remove blocks/update structure
1168
+ # - Information zone (multiline text)
1169
+
1170
+ self._sizer_gen = wx.BoxSizer(wx.HORIZONTAL)
1171
+
1172
+ self._sizer_run_results = wx.BoxSizer(wx.VERTICAL)
1173
+
1174
+ self._sizer_principal = wx.BoxSizer(wx.VERTICAL)
1175
+
1176
+ self._sizer_properties = wx.BoxSizer(wx.HORIZONTAL)
1177
+
1178
+ self._sizer_btnsblocks = wx.BoxSizer(wx.VERTICAL)
1179
+
1180
+ self._sizer_btnsactions = wx.BoxSizer(wx.HORIZONTAL)
1181
+ self._sizer_btnsactions_left = wx.BoxSizer(wx.VERTICAL)
1182
+ self._sizer_btnsactions_right = wx.BoxSizer(wx.VERTICAL)
1183
+
1184
+ self._sizer_btnsactions.Add(self._sizer_btnsactions_left, 1, wx.EXPAND)
1185
+ self._sizer_btnsactions.Add(self._sizer_btnsactions_right, 1, wx.EXPAND)
1186
+
1187
+ self._sizer_btns_creation = wx.BoxSizer(wx.HORIZONTAL)
1188
+
1189
+ # Buttons
1190
+ # ********
1191
+
1192
+ # Boundary conditions
1193
+ # ---------------------
1194
+
1195
+ self._btn_bc = wx.Button(self._panel, label=_('BCs'))
1196
+ self._btn_bc.SetToolTip(_('Set the boundary conditions'))
1197
+ self._btn_bc.Bind(wx.EVT_BUTTON, self._set_bc)
1198
+
1199
+ self._sizer_run_results.Add(self._btn_bc, 1, wx.EXPAND)
1200
+
1201
+ # Infiltration
1202
+ # --------------
1203
+
1204
+ self._btn_infiltration = wx.Button(self._panel, label=_('Infiltration'))
1205
+ self._btn_infiltration.SetToolTip(_('Set the infiltration'))
1206
+ self._btn_infiltration.Bind(wx.EVT_BUTTON, self._set_infiltration)
1207
+
1208
+ self._sizer_run_results.Add(self._btn_infiltration, 1, wx.EXPAND)
1209
+
1210
+ # Part arrays
1211
+ # ------------
1212
+
1213
+ self._btn_part_arrays = wx.Button(self._panel, label=_('Part arrays'))
1214
+ self._btn_part_arrays.SetToolTip(_('Set the part arrays'))
1215
+ self._btn_part_arrays.Bind(wx.EVT_BUTTON, self._set_part_arrays)
1216
+
1217
+ self._sizer_run_results.Add(self._btn_part_arrays, 1, wx.EXPAND)
1218
+
1219
+ # Check
1220
+ # -----
1221
+
1222
+ self._btn_checkerrors = wx.Button(self._panel, label=_('Check errors'))
1223
+ self._btn_checkerrors.SetToolTip(_('Check the errors in the model'))
1224
+ self._btn_checkerrors.Bind(wx.EVT_BUTTON, self._check_errors)
1225
+
1226
+ self._sizer_run_results.Add(self._btn_checkerrors, 1, wx.EXPAND)
1227
+
1228
+ # Write files
1229
+ # ------------
1230
+
1231
+ self._btn_write = wx.Button(self._panel, label=_('Write files'))
1232
+ self._btn_write.SetToolTip(_('Write the files to disk'))
1233
+ self._btn_write.Bind(wx.EVT_BUTTON, self._write_files)
1234
+
1235
+ self._sizer_run_results.Add(self._btn_write, 1, wx.EXPAND)
1236
+
1237
+ # Run simulation
1238
+ # ---------------
1239
+
1240
+ self._btn_run = wx.Button(self._panel, label=_('Run'))
1241
+ self._btn_run.SetToolTip(_('Run the simulation - wolfcli.exe code'))
1242
+ self._btn_run.Bind(wx.EVT_BUTTON, self._run)
1243
+
1244
+ self._sizer_run_results.Add(self._btn_run, 1, wx.EXPAND)
1245
+
1246
+ # Results
1247
+ # --------
1248
+
1249
+ self._btn_results = wx.Button(self._panel, label=_('Results'))
1250
+ self._btn_results.SetToolTip(_('Display the results of the simulation'))
1251
+ self._btn_results.Bind(wx.EVT_BUTTON, self._results)
1252
+
1253
+ self._sizer_run_results.Add(self._btn_results, 1, wx.EXPAND)
1254
+
1255
+ # Result as IC
1256
+ # ------------
1257
+
1258
+ self._btn_rs2ic = wx.Button(self._panel, label=_('Results as IC'))
1259
+ self._btn_rs2ic.SetToolTip(_('Set one result as initial conditions'))
1260
+ self._btn_rs2ic.Bind(wx.EVT_BUTTON, self._results2ic)
1261
+
1262
+ self._sizer_run_results.Add(self._btn_rs2ic, 1, wx.EXPAND)
1263
+
1264
+ # Copy 2 GPU
1265
+ # -----------
1266
+
1267
+ self._btn_copy2gpu = wx.Button(self._panel, label=_('Copy 2 GPU'))
1268
+ self._btn_copy2gpu.SetToolTip(_('Copy/Convert the simulation to the GPU framework'))
1269
+ self._btn_copy2gpu.Bind(wx.EVT_BUTTON, self._copy2gpu)
1270
+
1271
+ self._sizer_run_results.Add(self._btn_copy2gpu, 1, wx.EXPAND)
1272
+
1273
+ # Wizard
1274
+ # ------
1275
+
1276
+ self._btn_wizard = wx.Button(self._panel, label=_('Wizard'))
1277
+ self._btn_wizard.SetToolTip(_('Launch the wizard to create a new model'))
1278
+ self._btn_wizard.Bind(wx.EVT_BUTTON, self._wizard)
1279
+
1280
+ self._sizer_principal.Add(self._btn_wizard, 1, wx.EXPAND)
1281
+
1282
+ # Creation
1283
+ # ---------
1284
+
1285
+ self._btn_fromvector = wx.Button(self._panel, label=_('Create From vector'))
1286
+ self._btn_fromarray = wx.Button(self._panel, label=_('Create From array'))
1287
+ self._btn_fromfootprint = wx.Button(self._panel, label=_('Create From footprint'))
1288
+
1289
+ self._btn_fromvector.SetToolTip(_('Create a simulation from an existing polygon'))
1290
+ self._btn_fromarray.SetToolTip(_('Create a simulation from the active array'))
1291
+ self._btn_fromfootprint.SetToolTip(_('Create a simulation from the footprint (ox, oy, nbx, nby, dy, dy)'))
1292
+
1293
+ self.Bind(wx.EVT_BUTTON, self._create_from_vector, self._btn_fromvector)
1294
+ self.Bind(wx.EVT_BUTTON, self._create_from_array, self._btn_fromarray)
1295
+ self.Bind(wx.EVT_BUTTON, self._create_from_footprint, self._btn_fromfootprint)
1296
+
1297
+ self._sizer_btns_creation.Add(self._btn_fromvector, 1, wx.EXPAND)
1298
+ self._sizer_btns_creation.Add(self._btn_fromarray, 1, wx.EXPAND)
1299
+ self._sizer_btns_creation.Add(self._btn_fromfootprint, 1, wx.EXPAND)
1300
+
1301
+ self._sizer_principal.Add(self._sizer_btns_creation, 1, wx.EXPAND)
1302
+
1303
+
1304
+ self._sizer_magn_res = wx.BoxSizer(wx.HORIZONTAL)
1305
+
1306
+ # Magnetic grid
1307
+ # -------------
1308
+
1309
+ self._btn_magnetic_grid = wx.Button(self._panel, label=_('Magnetic grid'))
1310
+ self._btn_magnetic_grid.SetToolTip(_('Set a magnetic grid for the model'))
1311
+ self._btn_magnetic_grid.Bind(wx.EVT_BUTTON, self._set_magnetic_grid)
1312
+
1313
+ self._sizer_magn_res.Add(self._btn_magnetic_grid, 1, wx.EXPAND)
1314
+
1315
+ # Resolution
1316
+ # -----------
1317
+
1318
+ self._btn_set_fine_res = wx.Button(self._panel, label=_('Set fine resolution'))
1319
+ self._btn_set_fine_res.SetToolTip(_('Set the fine resolution of the model'))
1320
+ self._btn_set_fine_res.Bind(wx.EVT_BUTTON, self._choose_fine_resolution)
1321
+
1322
+ self._sizer_magn_res.Add(self._btn_set_fine_res, 1, wx.EXPAND)
1323
+
1324
+
1325
+ # Chesk Translation
1326
+ # -----------------
1327
+
1328
+ self._chk_translation = wx.CheckBox(self._panel, label=_('Shift to (0., 0.)'), style=wx.ALIGN_CENTER)
1329
+ self._chk_translation.SetToolTip(_('Shift the global coordinates to (0., 0.) and define shifting parameters'))
1330
+ self._chk_translation.SetValue(True)
1331
+
1332
+ self._sizer_magn_res.Add(self._chk_translation, 1, wx.EXPAND)
1333
+
1334
+ self._sizer_principal.Add(self._sizer_magn_res, 1, wx.EXPAND)
1335
+
1336
+
1337
+ self._sizer_add_mesh_create = wx.BoxSizer(wx.HORIZONTAL)
1338
+
1339
+ # Add blocks
1340
+ # -----------
1341
+
1342
+ self._btn_add_blocks = wx.Button(self._panel, label=_('Add blocks'))
1343
+ self._btn_add_blocks.SetToolTip(_('Add blocks to the model'))
1344
+ self._btn_add_blocks.Bind(wx.EVT_BUTTON, self._add_blocks)
1345
+
1346
+ self._sizer_add_mesh_create.Add(self._btn_add_blocks, 1, wx.EXPAND)
1347
+
1348
+ # Mesher
1349
+ # -------
1350
+
1351
+ self._btn_mesher = wx.Button(self._panel, label=_('Mesher'))
1352
+ self._btn_mesher.SetToolTip(_('Mesh the model -- call to the Fortran code wolfcli.exe'))
1353
+ self._btn_mesher.Bind(wx.EVT_BUTTON, self._mesher)
1354
+
1355
+ self._sizer_add_mesh_create.Add(self._btn_mesher, 1, wx.EXPAND)
1356
+
1357
+ # Create arrays
1358
+ # -------------
1359
+
1360
+ self._btn_create_arrays = wx.Button(self._panel, label=_('Create arrays'))
1361
+ self._btn_create_arrays.SetToolTip(_('Create the fine arrays for the model'))
1362
+ self._btn_create_arrays.Bind(wx.EVT_BUTTON, self._create_arrays)
1363
+
1364
+ self._sizer_add_mesh_create.Add(self._btn_create_arrays, 1, wx.EXPAND)
1365
+
1366
+ self._sizer_principal.Add(self._sizer_add_mesh_create, 1, wx.EXPAND)
1367
+
1368
+ # Apply changes
1369
+ # -------------
1370
+ self._btn_apply = wx.Button(self._panel, label=_('Apply changes'))
1371
+ self._btn_apply.SetToolTip(_('Apply the changes to the memory (not saved on disk)'))
1372
+ self._btn_apply.Bind(wx.EVT_BUTTON, self._apply_changes)
1373
+
1374
+ # Update structure
1375
+ # ----------------
1376
+ self._btn_update_struct = wx.Button(self._panel, label=_('Update structure'))
1377
+ self._btn_update_struct.SetToolTip(_('Update the structure of the model (add/remove blocks)'))
1378
+ self._btn_update_struct.Bind(wx.EVT_BUTTON, self._update_structure)
1379
+
1380
+ # Add/remove blocks
1381
+ # -----------------
1382
+ self._btn_plus = wx.Button(self._panel, label='+')
1383
+ self._btn_plus.SetToolTip(_('Add a block to the model'))
1384
+ self._btn_plus.Bind(wx.EVT_BUTTON, self._add_block)
1385
+
1386
+ self._btn_minus = wx.Button(self._panel, label='-')
1387
+ self._btn_minus.SetToolTip(_('Remove a block from the model'))
1388
+ self._btn_minus.Bind(wx.EVT_BUTTON, self._remove_block)
1389
+
1390
+ # Checkboxes
1391
+ # **********
1392
+
1393
+ # Show all parameters
1394
+ # -------------------
1395
+ self._check_show_all = wx.CheckBox(self._panel, label=_('All parameters'))
1396
+ self._check_show_all.SetToolTip(_('Show all parameters even if they have the default value (default: show only modified parameters)'))
1397
+ self._check_show_all.Bind(wx.EVT_CHECKBOX, self._all_parameters)
1398
+
1399
+ # Force update if multiple blocks are toggled
1400
+ # -------------------------------------------
1401
+ self._check_force = wx.CheckBox(self._panel, label=_('Force update'))
1402
+ self._check_force.SetToolTip(_('Force the update of some parameters in all selected blocks (default: update only the first one - considered as the reference block)'))
1403
+ self._check_force.Bind(wx.EVT_CHECKBOX, self._force_update)
1404
+
1405
+
1406
+ # add widgets to sizers
1407
+ # *********************
1408
+
1409
+ self._sizer_btnsactions_left.Add(self._btn_apply, 1, wx.EXPAND)
1410
+ self._sizer_btnsactions_left.Add(self._btn_update_struct, 1, wx.EXPAND)
1411
+
1412
+ self._sizer_btnsactions_right.Add(self._btn_plus, 1, wx.EXPAND)
1413
+ self._sizer_btnsactions_right.Add(self._btn_minus, 1, wx.EXPAND)
1414
+ self._sizer_btnsactions_right.Add(self._check_show_all, 1, wx.EXPAND)
1415
+ self._sizer_btnsactions_right.Add(self._check_force, 1, wx.EXPAND)
1416
+
1417
+ self._panel.SetSizer(self._sizer_gen)
1418
+
1419
+ self._sizer_principal.Add(self._sizer_properties, 4, wx.EXPAND)
1420
+ self._sizer_principal.Add(self._sizer_btnsactions, 1, wx.EXPAND)
1421
+
1422
+ self._txt_info = wx.TextCtrl(self._panel, style=wx.TE_MULTILINE|wx.TE_READONLY)
1423
+
1424
+ self._sizer_principal.Add(self._txt_info, 2, wx.EXPAND)
1425
+
1426
+ self._sizer_gen.Add(self._sizer_principal, 5, wx.EXPAND)
1427
+ self._sizer_gen.Add(self._sizer_run_results, 1, wx.EXPAND)
1428
+
1429
+
1430
+ # Create the local list of parameters
1431
+ # - for global parameters
1432
+ # - for blocks
1433
+ self._prop_gen = prev_parameters_simul()
1434
+ self._prop_block = prev_parameters_blocks()
1435
+
1436
+ # Create the widget PropertyGridManager for the parameters
1437
+ self._prop_gen._params.ensure_prop(wxparent = self._panel, show_in_active_if_default= False)
1438
+ self._prop_block._params.ensure_prop(wxparent = self._panel, show_in_active_if_default= False)
1439
+
1440
+ # Create the buttons for the blocks and the global parameters
1441
+ self._fill_buttons_genblocks()
1442
+
1443
+ self._sizer_properties.Add(self._sizer_btnsblocks, 1, wx.EXPAND)
1444
+
1445
+ # add the properties to the sizer
1446
+ self._sizer_properties.Add(self._prop_gen._params.prop, 5, wx.EXPAND)
1447
+ self._sizer_properties.Add(self._prop_block._params.prop, 5, wx.EXPAND)
1448
+
1449
+
1450
+ # Hide the block properties
1451
+ self._prop_gen._params.prop.Show()
1452
+ self._prop_block._params.prop.Hide()
1453
+
1454
+
1455
+ # The default view is the global parameters
1456
+ self._show_glob_properties()
1457
+
1458
+ # Show the frame
1459
+ self._prop_frame.Show()
1460
+
1461
+ else:
1462
+ logging.info(_('No GUI available'))
1463
+
1464
+ def _set_bc(self, e:wx.EVT_BUTTON):
1465
+ """ Set the boundary conditions """
1466
+
1467
+ from .mesh2d.bc_manager import BcManager, choose_bc_type
1468
+
1469
+ if self.mapviewer.active_bc is None:
1470
+
1471
+ newbc = BcManager(self,
1472
+ linked_array=self.sim.napbin,
1473
+ version = 1,
1474
+ DestroyAtClosing=True,
1475
+ Callback=self.mapviewer.pop_boundary_manager,
1476
+ mapviewer=self.mapviewer,
1477
+ wolfparent = self)
1478
+
1479
+
1480
+ self.mapviewer.mybc.append(newbc)
1481
+
1482
+ self.mapviewer.active_bc = newbc
1483
+
1484
+ self.mapviewer.Refresh()
1485
+
1486
+ else:
1487
+ self.mapviewer.active_bc.Show()
1488
+
1489
+ def _set_infiltration(self, e:wx.EVT_BUTTON):
1490
+
1491
+ inf_frame = Wolf2DInfiltration(self.sim)
1492
+ inf_frame.Show()
1493
+
1494
+ def _set_part_arrays(self, e:wx.EVT_BUTTON):
1495
+
1496
+ part_frame = Wolf2DPartArrays(self.sim, self.mapviewer)
1497
+ part_frame.Show()
1498
+
1499
+ def add_boundary_condition(self, i: int, j: int, bc_type:BCType_2D, bc_value: float, border:Direction):
1500
+ """ alias """
1501
+
1502
+ self.sim.add_boundary_condition(i, j, bc_type, bc_value, border)
1503
+
1504
+ def reset_boundary_conditions(self):
1505
+ """ Reset the boundary conditions """
1506
+
1507
+ self.sim.parameters.reset_all_boundary_conditions()
1508
+
1509
+
1510
+ def _check_errors(self, e:wx.EVT_BUTTON):
1511
+ """ Check the errors in the model """
1512
+
1513
+ self._txt_info.Clear()
1514
+
1515
+ valid, ret = self.sim.parameters.check_all(1)
1516
+
1517
+ if valid:
1518
+ self._btn_checkerrors.SetBackgroundColour(wx.GREEN)
1519
+ else:
1520
+ self._btn_checkerrors.SetBackgroundColour(wx.RED)
1521
+
1522
+ self._txt_info.AppendText(ret)
1523
+
1524
+
1525
+ def _write_files(self, e:wx.EVT_BUTTON):
1526
+ """ Write the files to disk """
1527
+
1528
+ if self.sim.parameters._mesher_only:
1529
+
1530
+ dlg = wx.MessageDialog(None, _('You have selected "Mesh only" - Do you want to uncheck it ?'), _('Warning'), wx.YES_NO)
1531
+ ret = dlg.ShowModal()
1532
+ dlg.Destroy()
1533
+
1534
+ if ret == wx.ID_YES:
1535
+ self.sim.unset_mesh_only()
1536
+
1537
+ self.sim.save()
1538
+
1539
+
1540
+ def _run(self, e:wx.EVT_BUTTON):
1541
+ """ Run the simulation """
1542
+
1543
+ valid, ret = self.sim.parameters.check_all()
1544
+
1545
+ if not valid:
1546
+ self._txt_info.AppendText(_('\n\nWe can not run the simulation\n\n'))
1547
+ logging.error(_('We can not run the simulation -- Check the errors !'))
1548
+
1549
+ self._btn_checkerrors.SetBackgroundColour(wx.RED)
1550
+
1551
+ return
1552
+
1553
+ self._btn_checkerrors.SetBackgroundColour(wx.GREEN)
1554
+
1555
+ self.sim.run_wolfcli()
1556
+
1557
+ def _results(self, e:wx.EVT_BUTTON):
1558
+ """ Display the results """
1559
+
1560
+ self.mapviewer.add_object(which='res2d',
1561
+ filename=self.filenamegen,
1562
+ id='Results')
1563
+
1564
+ def _results2ic(self, e:wx.EVT_BUTTON):
1565
+ """ Choose one result as initial conditions """
1566
+
1567
+ from .wolfresults_2D import Wolfresults_2D
1568
+ from datetime import timedelta
1569
+
1570
+ myres = Wolfresults_2D(self.filenamegen, plotted=False)
1571
+
1572
+ times, steps = myres.get_times_steps()
1573
+
1574
+ times_hms = [timedelta(seconds=int(curtime), milliseconds=int(curtime-int(curtime))*1000) for curtime in times]
1575
+
1576
+ choices = [_('Last one')] + ['{:3f} [s] - {} [h:m:s] - {} [step index]'.format(curtime, curtimehms, curstep) for curtime, curtimehms, curstep in zip(times, times_hms, steps)]
1577
+
1578
+ dlg = wx.SingleChoiceDialog(None, _('Choose the time step to set as initial conditions'), _('Results as IC'), choices)
1579
+
1580
+ ret = dlg.ShowModal()
1581
+
1582
+ if ret == wx.ID_CANCEL:
1583
+ logging.info(_('Aborting - No time step selected'))
1584
+ return
1585
+
1586
+ idx = dlg.GetSelection() - 1 # -1 because of the first choice is the last one and it is the convention used in the code
1587
+
1588
+ dlg.Destroy()
1589
+
1590
+ as_multiblocks = False # Default value
1591
+
1592
+ if self.sim.is_multiblock:
1593
+
1594
+ dlg = wx.SingleChoiceDialog(None, _('Choose the type of storage'), _('Results as IC'), [_('Multi-blocks'), _('Mono-block')])
1595
+
1596
+ ret = dlg.ShowModal()
1597
+
1598
+ if ret == wx.ID_CANCEL:
1599
+ logging.info(_('Aborting - No storage type selected'))
1600
+ return
1601
+
1602
+ storage = dlg.GetSelection()
1603
+
1604
+ as_multiblocks = storage == 0
1605
+
1606
+ myres.set_hqxqy_as_initial_conditions(idx, as_multiblocks)
1607
+
1608
+ if self.sim.parameters.has_turbulence:
1609
+ myres.set_keps_as_initial_conditions(idx, as_multiblocks)
1610
+
1611
+ # update the arrays
1612
+ self._add_arrays_to_mapviewer(force_reload=True)
1613
+
1614
+ def _copy2gpu(self, e:wx.EVT_BUTTON):
1615
+ """ Click on the button to copy to the GPU """
1616
+
1617
+ if self.sim.nb_blocks > 1:
1618
+ logging.error(_('Multiple blocks defined - Copy to GPU not possible'))
1619
+ self._txt_info.AppendText(_('Multiple blocks defined - Copy to GPU not possible !\n'))
1620
+ self._txt_info.AppendText(_('Please define only one block or convert you simulation manually.\n'))
1621
+ return
1622
+
1623
+ if self.sim.parameters.has_turbulence:
1624
+ logging.error(_('Turbulence is defined - Copy to GPU not yet possible'))
1625
+ self._txt_info.AppendText(_('Turbulence is defined - Copy to GPU not yet possible !\n'))
1626
+ self._txt_info.AppendText(_('Please remove the turbulence or help to implement the turbulence model in the GPU framework.\n'))
1627
+ return
1628
+
1629
+ if self.sim.parameters.blocks[0]._friction_law != 0:
1630
+ logging.error(_('Friction law is not Manning-Strickler or a more sophisticated surface evaluation - Copy to GPU not yet possible'))
1631
+ self._txt_info.AppendText(_('Friction law is not Manning-Strickler or a more sophisticated surface evaluation - Copy to GPU not yet possible !\n'))
1632
+ self._txt_info.AppendText(_('Please change the friction law or help to implement the friction law in the GPU framework.\n'))
1633
+ return
1634
+
1635
+ if self.sim.inf.array.min() < 0:
1636
+ logging.error(_('Negative infiltration zoning values - Copy to GPU not yet possible'))
1637
+ self._txt_info.AppendText(_('Negative infiltration zoning values - Copy to GPU not yet possible !\n'))
1638
+ self._txt_info.AppendText(_('Please change the infiltration mode or help to implement ther variable infiltration in the GPU framework.\n'))
1639
+ return
1640
+
1641
+ dirout = wx.DirDialog(None, _('Choose the output directory for the GPU simulation'))
1642
+
1643
+ if dirout.ShowModal() == wx.ID_CANCEL:
1644
+ return
1645
+
1646
+ gpudir = dirout.GetPath()
1647
+
1648
+ ret = self.sim.copy2gpu(gpudir)
1649
+
1650
+ self._txt_info.AppendText(ret)
1651
+
1652
+ if _('All files copied successfully') in ret:
1653
+ logging.info(_('All files copied successfully'))
1654
+
1655
+
1656
+ def _wizard(self, e:wx.EVT_BUTTON):
1657
+ """ Launch the wizard """
1658
+
1659
+ from wx.adv import Wizard, WizardPageSimple
1660
+
1661
+ wizard_text = self.sim.get_wizard_text()
1662
+
1663
+ self.wizard = Wizard(None, -1, _('Wizard Multiblocks simulation'))
1664
+
1665
+ self.wizard.SetPageSize((400, 300))
1666
+
1667
+ self.wiz_pages:list[WizardPageSimple] = []
1668
+
1669
+ for curpage in wizard_text:
1670
+ self.wiz_pages.append(WizardPageSimple(self.wizard))
1671
+ self.wiz_pages[-1].SetBackgroundColour(wx.Colour(255, 255, 255))
1672
+ self.wiz_pages[-1].SetSizer(wx.BoxSizer(wx.VERTICAL))
1673
+
1674
+ for idx, curpage in enumerate(wizard_text):
1675
+ for curstep in curpage:
1676
+ self.wiz_pages[idx].GetSizer().Add(wx.StaticText(self.wiz_pages[idx], -1, curstep), 0, wx.ALIGN_LEFT)
1677
+
1678
+ for i in range(len(self.wiz_pages)-1):
1679
+ self.wiz_pages[i].Chain(self.wiz_pages[i+1])
1680
+
1681
+
1682
+ ret = self.wizard.RunWizard(self.wiz_pages[0])
1683
+
1684
+ if ret:
1685
+ logging.info(_('Wizard finished'))
1686
+ else:
1687
+ logging.warning(_('Wizard cancelled - Are you sure ?'))
1688
+
1689
+ def _mesher(self, e:wx.EVT_BUTTON):
1690
+ """ Call the mesher """
1691
+
1692
+ if self.nb_blocks == 0:
1693
+ logging.error(_('No block defined -- Please add a block to the model (see "+ button")'))
1694
+ return
1695
+
1696
+ nb_vert = [len(self.sim.bloc_description.my_blocks[i].contour.myvertices) for i in range(self.nb_blocks)]
1697
+ nb_vert.sort()
1698
+
1699
+ if nb_vert[0] ==0:
1700
+ logging.error(_(' At least one block is not defined -- Please draw the polygons for each block'))
1701
+ return
1702
+
1703
+ self.sim.translate_origin2zero = self._chk_translation.GetValue()
1704
+ self.sim.mesh()
1705
+
1706
+ self._add_arrays_to_mapviewer()
1707
+ self._add_vectors_to_mapviewer()
1708
+
1709
+ def _create_arrays(self, e:wx.EVT_BUTTON):
1710
+ """ Create the fine arrays """
1711
+
1712
+ if self.nb_blocks == 0:
1713
+ logging.error(_('No block defined -- Please add a block to the model and mesh'))
1714
+ return
1715
+
1716
+ self.sim.create_fine_arrays(with_tubulence= self.sim.parameters.has_turbulence)
1717
+ self.sim.create_sux_suy()
1718
+
1719
+ self._add_arrays_to_mapviewer()
1720
+
1721
+
1722
+ def _add_blocks(self, e:wx.EVT_BUTTON):
1723
+ """ Add blocks to the model """
1724
+
1725
+ dlg = wx.TextEntryDialog(None, _('How many blocks do you want to add ?'), _('Add blocks'), '1', wx.OK | wx.CANCEL | wx.CENTRE)
1726
+
1727
+ dlg.ShowModal()
1728
+
1729
+ if dlg.GetReturnCode() == wx.ID_CANCEL:
1730
+ dlg.Destroy()
1731
+ return
1732
+
1733
+ nb = int(dlg.GetValue())
1734
+
1735
+ dlg.Destroy()
1736
+
1737
+
1738
+ for i in range(nb):
1739
+
1740
+ name = f'Block {self.nb_blocks+1}'
1741
+ # Set the external border as the first block
1742
+ newvec = self.sim.bloc_description.external_border
1743
+ self.sim.add_block(newvec, self.dx_fine, self.dy_fine, name)
1744
+
1745
+
1746
+ self._update_structure(0)
1747
+
1748
+ dlg = wx.MessageDialog(None, _('Block(s) added\n\nYou must define the polygons'), _('Information'), wx.OK)
1749
+
1750
+ pass
1751
+
1752
+ def _create_from_vector(self, e:wx.EVT_BUTTON):
1753
+ """ Create a simulation from a vector """
1754
+
1755
+ if self.mapviewer.active_vector is None:
1756
+ logging.error(_('No active vector defined - Please select or create a vector/polygon as external border'))
1757
+ return
1758
+
1759
+ self.sim.set_external_border_vector(self.mapviewer.active_vector)
1760
+
1761
+ def _create_from_array(self, e:wx.EVT_BUTTON):
1762
+ """ Create a simulation from an array """
1763
+
1764
+ if self.mapviewer.active_array is None:
1765
+ logging.error(_('No active array defined - Please select or create an array as external border'))
1766
+ return
1767
+
1768
+ self.sim.set_external_border_wolfarray(self.mapviewer.active_array)
1769
+ self.sim.set_mesh_fine_size(self.mapviewer.active_array.dx, self.mapviewer.active_array.dy)
1770
+
1771
+ self._show_glob_properties()
1772
+
1773
+ def _create_from_footprint(self, e:wx.EVT_BUTTON):
1774
+ """ Create a simulation from a footprint """
1775
+
1776
+ dlg = wx.TextEntryDialog(None, _('Footprint'), _('Footprint'), 'ox, oy, nbx, nby, dx, dy')
1777
+
1778
+ if dlg.ShowModal() == wx.ID_OK:
1779
+ try:
1780
+ ox, oy, nbx, nby, dx, dy = dlg.GetValue().split(',')
1781
+
1782
+ newhead = header_wolf()
1783
+ newhead.nbx = int(nbx)
1784
+ newhead.nby = int(nby)
1785
+ newhead.dx = float(dx)
1786
+ newhead.dy = float(dy)
1787
+ newhead.origx = float(ox)
1788
+ newhead.origy = float(oy)
1789
+
1790
+ self.sim.set_external_border_header(newhead)
1791
+
1792
+ self.sim.set_mesh_fine_size(float(dx), float(dy))
1793
+ self._show_glob_properties()
1794
+ except:
1795
+ logging.error(_('Invalid footprint'))
1796
+
1797
+ dlg.Destroy()
1798
+
1799
+ def _set_magnetic_grid(self, e:wx.EVT_BUTTON):
1800
+ """ Set the magnetic grid """
1801
+
1802
+ dlg = wx.TextEntryDialog(None, _('Magnetic grid'), _('Magnetic grid'), 'ox, oy, dx, dy')
1803
+
1804
+ if dlg.ShowModal() == wx.ID_OK:
1805
+ try:
1806
+ ox, oy, dx, dy = dlg.GetValue().split(',')
1807
+ self.sim.set_magnetic_grid(float(dx), float(dy), float(ox), float(oy))
1808
+ self._show_glob_properties()
1809
+ except:
1810
+ logging.error(_('Invalid magnetic grid'))
1811
+
1812
+ dlg.Destroy()
1813
+
1814
+ def _choose_fine_resolution(self, e:wx.EVT_BUTTON):
1815
+ """ Choose the fine resolution """
1816
+
1817
+ dlg = wx.TextEntryDialog(None, _('Choose the fine resolution'), _('Fine resolution'), 'dx, dy')
1818
+
1819
+ if dlg.ShowModal() == wx.ID_OK:
1820
+ try:
1821
+ dx, dy = dlg.GetValue().split(',')
1822
+ self.sim.set_mesh_fine_size(float(dx), float(dy))
1823
+ self._show_glob_properties()
1824
+ except:
1825
+ logging.error(_('Invalid fine resolution'))
1826
+
1827
+ dlg.Destroy()
1828
+
1829
+ self._show_glob_properties()
1830
+
1831
+
1832
+ def _add_block(self, e:wx.EVT_BUTTON):
1833
+ """ Add a block to the model """
1834
+
1835
+ newvec = vector()
1836
+ self.sim.add_block(newvec, self.dx_fine, self.dy_fine)
1837
+
1838
+ dlg = wx.MessageDialog(None, _('Block added\nDo not forget to :\n - draw the contour\n - set the spatial resolution if not the same that the fine one'), _('Information'), wx.OK)
1839
+
1840
+ dlg.ShowModal()
1841
+ dlg.Destroy()
1842
+
1843
+ self._update_structure(0)
1844
+
1845
+ pass
1846
+
1847
+ def _remove_block(self, e:wx.EVT_BUTTON):
1848
+ """ Remove a block from the model """
1849
+
1850
+ dlg = wx.MessageDialog(None, _('Are you sure you want to remove the block ?'), _('Warning'), wx.YES_NO)
1851
+
1852
+ if dlg.ShowModal() == wx.ID_YES:
1853
+ dlg.Destroy()
1854
+
1855
+ select = wx.MultiChoiceDialog(None, _('Select the block to remove'), _('Remove block'), [f'Block {idx+1}' for idx in range(self.nb_blocks)])
1856
+
1857
+ if select.ShowModal() == wx.ID_OK:
1858
+ selected = select.GetSelections()
1859
+
1860
+ for idx in selected:
1861
+ self.sim.remove_block(idx)
1862
+
1863
+ dlg = wx.MessageDialog(None, _('Block(s) removed'), _('Information'), wx.OK)
1864
+
1865
+ dlg.ShowModal()
1866
+ dlg.Destroy()
1867
+
1868
+ self._update_structure(0)
1869
+
1870
+ select.Destroy()
1871
+
1872
+ else:
1873
+ dlg.Destroy()
1874
+
1875
+
1876
+ def _update_structure(self, e:wx.EVT_BUTTON):
1877
+ """ Update the structure of the model """
1878
+
1879
+ self._fill_buttons_genblocks()
1880
+ self._show_glob_properties()
1881
+
1882
+
1883
+ def _all_parameters(self, e:wx.EVT_CHECKBOX):
1884
+ """ Show all parameters """
1885
+
1886
+ show_all = self._check_show_all.GetValue()
1887
+
1888
+ if self._prop_block._params.show_in_active_if_default != show_all:
1889
+ self._prop_block._params.show_in_active_if_default = show_all
1890
+ self._prop_block._params.Populate(sorted_groups=True)
1891
+
1892
+ if self._prop_gen._params.show_in_active_if_default != show_all:
1893
+ self._prop_gen._params.show_in_active_if_default = show_all
1894
+ self._prop_gen._params.Populate(sorted_groups=True)
1895
+
1896
+ def _force_update(self, e:wx.EVT_CHECKBOX):
1897
+ """ Force the update """
1898
+ pass
1899
+
1900
+ def _update_layout(self):
1901
+ """ Update the layout of the frame """
1902
+
1903
+ self._panel.Layout()
1904
+ self._prop_frame.Layout()
1905
+
1906
+ def _fill_buttons_genblocks(self):
1907
+ """
1908
+ Fill the buttons for the blocks
1909
+ """
1910
+
1911
+ self._sizer_btnsblocks.Clear(True)
1912
+
1913
+ self._btn_gen = wx.ToggleButton(self._panel, label=_('Global'))
1914
+
1915
+ self._btn_blocks = [wx.ToggleButton(self._panel, label=_('Blocks ')+str(idx)) for idx in range(1, self.nb_blocks+1)]
1916
+
1917
+ self._sizer_btnsblocks.Add(self._btn_gen, 1, wx.EXPAND)
1918
+ for btn in self._btn_blocks:
1919
+ self._sizer_btnsblocks.Add(btn, 1, wx.EXPAND)
1920
+
1921
+ self._btn_gen.Bind(wx.EVT_TOGGLEBUTTON, self.OnToggleGen)
1922
+ for btn in self._btn_blocks:
1923
+ btn.Bind(wx.EVT_TOGGLEBUTTON, self.OnToggleBlock)
1924
+
1925
+ # self._sizer_properties.Clear(True)
1926
+
1927
+ # self._sizer_properties.Add(self._sizer_btnsblocks, 1, wx.EXPAND)
1928
+
1929
+ # # add the properties to the sizer
1930
+ # self._sizer_properties.Add(self._prop_gen._params.prop, 5, wx.EXPAND)
1931
+ # self._sizer_properties.Add(self._prop_block._params.prop, 5, wx.EXPAND)
1932
+
1933
+ self._update_layout()
1934
+
1935
+ def _get_togglestates(self):
1936
+ """ Get the toggle states of the buttons """
1937
+
1938
+ return self._btn_gen.GetValue(), [btn.GetValue() for btn in self._btn_blocks] # True if toggled, False otherwise
1939
+
1940
+
1941
+ def _show_glob_properties(self):
1942
+ """ Show the general properties """
1943
+
1944
+ self._btn_gen.SetValue(True)
1945
+
1946
+ self._prop_gen.copy(self.sim.parameters)
1947
+
1948
+ if self._prop_block._params.prop.IsShown():
1949
+ self._prop_gen._params.prop.Show()
1950
+ self._prop_block._params.prop.Hide()
1951
+
1952
+ self._append_magnetic_grid_to_prop()
1953
+
1954
+ self._txt_info.Clear()
1955
+ self._txt_info.AppendText(_('Global parameters are shown'))
1956
+
1957
+ self._update_layout()
1958
+
1959
+ def _set_default_background(self):
1960
+ """ Set the default background """
1961
+
1962
+ self._btn_gen.SetBackgroundColour(wx.NullColour)
1963
+
1964
+ for btn in self._btn_blocks:
1965
+ btn.SetBackgroundColour(wx.NullColour)
1966
+
1967
+ def _set_color_background(self):
1968
+ """ Set the color background """
1969
+
1970
+ self._set_default_background()
1971
+
1972
+ toggle_gen, toggle_blocks = self._get_togglestates()
1973
+
1974
+ if self._ref_block is None:
1975
+ return
1976
+
1977
+ for btn, idx, toggled in zip(self._btn_blocks, range(self.nb_blocks), toggle_blocks):
1978
+
1979
+ if toggled and idx != self._ref_block:
1980
+
1981
+ color = wx.Colour(255, 0, 0) if self.sim.parameters.blocks[idx] != self.sim.parameters.blocks[self._ref_block] else wx.Colour(0, 255, 0)
1982
+ btn.SetBackgroundColour(color)
1983
+
1984
+ def OnToggleGen(self, e:wx.EVT_TOGGLEBUTTON):
1985
+ """
1986
+ Toggle the global properties
1987
+ """
1988
+
1989
+ toggle_gen, toggle_blocks = self._get_togglestates()
1990
+
1991
+ if toggle_gen:
1992
+ # General is toggled --> untoggle all blocks
1993
+ logging.info(_('General is toggled --> untoggling blocks'))
1994
+ for btn in self._btn_blocks:
1995
+ btn.SetValue(False)
1996
+
1997
+ self._show_glob_properties()
1998
+
1999
+ elif any(toggle_blocks):
2000
+ # At least one block is toggled --> untoggle the general
2001
+ pass
2002
+ else:
2003
+ # No block is toggled --> toggle the general
2004
+ self._show_glob_properties()
2005
+
2006
+ self._set_color_background()
2007
+
2008
+ def OnToggleBlock(self, e:wx.EVT_TOGGLEBUTTON):
2009
+ """
2010
+ Toggle the properties of a block
2011
+ """
2012
+
2013
+ toggle_gen, toggle_blocks = self._get_togglestates()
2014
+
2015
+ if toggle_gen:
2016
+ logging.info(_('General is toggled --> untoggling it'))
2017
+ self._btn_gen.SetValue(False)
2018
+
2019
+ if any(toggle_blocks):
2020
+ # At least one block is toggled --> untoggle the general
2021
+
2022
+ nb = toggle_blocks.count(True)
2023
+
2024
+ if nb == 1:
2025
+ # One block is toggled --> show its properties
2026
+ idx = toggle_blocks.index(True)
2027
+ logging.info(_(f'Block {idx} is toggled'))
2028
+
2029
+ self._prop_block.copy(self.sim.parameters.blocks[idx])
2030
+
2031
+ if self._prop_gen._params.prop.IsShown():
2032
+ self._prop_block._params.prop.Show()
2033
+ self._prop_gen._params.prop.Hide()
2034
+
2035
+ self._txt_info.Clear()
2036
+ self._txt_info.AppendText(_(f'Block {idx+1} parameters are shown'))
2037
+
2038
+ self._ref_block = idx
2039
+
2040
+ self._append_geometry_block_to_prop(idx)
2041
+
2042
+ else:
2043
+ # test is ref block is toggled
2044
+ if not toggle_blocks[self._ref_block]:
2045
+ self._ref_block = toggle_blocks.index(True)
2046
+ logging.info(_('Changing reference block to ') + str(self._ref_block+1))
2047
+ self._prop_block.copy(self.sim.parameters.blocks[self._ref_block])
2048
+
2049
+
2050
+ # multiple blocks are toggled
2051
+ # --> Find the difference
2052
+ # The first one is the "reference"
2053
+ self._txt_info.Clear()
2054
+ chain = _('Multiple blocks are toggled')
2055
+ self._txt_info.AppendText(chain + '\n')
2056
+ self._txt_info.AppendText('-'*len(chain) + '\n\n')
2057
+
2058
+ self._txt_info.AppendText(_('Differences between the blocks') + '\n')
2059
+ self._txt_info.AppendText(_(' - Reference block : ') + str(self._ref_block+1) + '\n')
2060
+
2061
+ idx_comp = [idx+1 for idx in range(self.nb_blocks) if idx != self._ref_block and toggle_blocks[idx]]
2062
+ self._txt_info.AppendText(_(' - Other blocks : ') + str(idx_comp) + '\n\n')
2063
+
2064
+ others = [self.sim.parameters.blocks[idx] for idx in range(self.nb_blocks) if idx != self._ref_block and toggle_blocks[idx]]
2065
+
2066
+ self._txt_info.AppendText(self._prop_block.diff_print(others))
2067
+
2068
+ dx_dy = [(idx, self._dx_block(idx),self._dy_block(idx)) for idx in range(self.nb_blocks) if idx != self._ref_block and toggle_blocks[idx]]
2069
+
2070
+ dx_ref = self._dx_block(self._ref_block)
2071
+ dy_ref = self._dy_block(self._ref_block)
2072
+
2073
+ self._txt_info.AppendText('\n')
2074
+
2075
+ for idx, dx, dy in dx_dy:
2076
+ if dx != dx_ref or dy != dy_ref:
2077
+ self._txt_info.AppendText(_(f'Block {idx+1} has different resolution)') + '\n')
2078
+ self._txt_info.AppendText(_(f' - dx : {dx} (ref : {dx_ref})') + '\n')
2079
+ self._txt_info.AppendText(_(f' - dy : {dy} (ref : {dy_ref})') + '\n\n')
2080
+
2081
+ else:
2082
+ self._show_glob_properties()
2083
+
2084
+ self._set_color_background()
2085
+
2086
+ self._update_layout()
2087
+
2088
+ def _append_magnetic_grid_to_prop(self):
2089
+ """ Append the magnetic grid to the properties """
2090
+
2091
+ self._prop_gen._params.add_param(MAGN_GROUP_NAME,
2092
+ 'Dx',
2093
+ 0.,
2094
+ Type_Param.Float,
2095
+ _('Spatial resolution of the magnetic grid along X-axis'),
2096
+ whichdict='All'
2097
+ )
2098
+ self._prop_gen._params.add_param(MAGN_GROUP_NAME,
2099
+ 'Dy',
2100
+ 0.,
2101
+ Type_Param.Float,
2102
+ _('Spatial resolution of the magnetic grid along Y-axis'),
2103
+ whichdict='All'
2104
+ )
2105
+
2106
+ self._prop_gen._params.add_param(MAGN_GROUP_NAME,
2107
+ 'Ox',
2108
+ -99999.,
2109
+ Type_Param.Float,
2110
+ _('Origin of the magnetic grid along X-axis'),
2111
+ whichdict='All'
2112
+ )
2113
+
2114
+ self._prop_gen._params.add_param(MAGN_GROUP_NAME,
2115
+ 'Oy',
2116
+ -99999.,
2117
+ Type_Param.Float,
2118
+ _('Origin of the magnetic grid along Y-axis'),
2119
+ whichdict='All'
2120
+ )
2121
+
2122
+ if self.sim.magnetic_grid is None:
2123
+ self.sim.set_magnetic_grid(1., 1., 0., 0.)
2124
+
2125
+ self._prop_gen._params[(MAGN_GROUP_NAME, 'Dx')] = self.sim.magnetic_grid.dx
2126
+ self._prop_gen._params[(MAGN_GROUP_NAME, 'Dy')] = self.sim.magnetic_grid.dy
2127
+
2128
+ self._prop_gen._params[(MAGN_GROUP_NAME, 'Ox')] = self.sim.magnetic_grid.origx
2129
+ self._prop_gen._params[(MAGN_GROUP_NAME, 'Oy')] = self.sim.magnetic_grid.origy
2130
+
2131
+ self._prop_gen._params.Populate(sorted_groups=True)
2132
+
2133
+ def _append_geometry_block_to_prop(self, idx:int):
2134
+ """ Append the geometry of the block to the properties """
2135
+
2136
+ self._prop_block._params.add_param(GEOM_GROUP_NAME,
2137
+ _('Dx'),
2138
+ 0.,
2139
+ Type_Param.Float,
2140
+ _('Spatial resolution of the block along X-axis'),
2141
+ whichdict='All'
2142
+ )
2143
+ self._prop_block._params.add_param(GEOM_GROUP_NAME,
2144
+ _('Dy'),
2145
+ 0.,
2146
+ Type_Param.Float,
2147
+ _('Spatial resolution of the block along Y-axis'),
2148
+ whichdict='All'
2149
+ )
2150
+
2151
+ self._prop_block._params.add_param(GEOM_GROUP_NAME,
2152
+ _('X min (info)'),
2153
+ -99999.,
2154
+ Type_Param.Float,
2155
+ _('Origin of the block along X-axis'),
2156
+ whichdict='All'
2157
+ )
2158
+
2159
+ self._prop_block._params.add_param(GEOM_GROUP_NAME,
2160
+ _('Y min (info)'),
2161
+ -99999.,
2162
+ Type_Param.Float,
2163
+ _('Origin of the block along X-axis'),
2164
+ whichdict='All'
2165
+ )
2166
+
2167
+ self._prop_block._params.add_param(GEOM_GROUP_NAME,
2168
+ _('X max (info)'),
2169
+ 99999.,
2170
+ Type_Param.Float,
2171
+ _('End of the block along X-axis'),
2172
+ whichdict='All'
2173
+ )
2174
+
2175
+ self._prop_block._params.add_param(GEOM_GROUP_NAME,
2176
+ _('Y max (info)'),
2177
+ 99999.,
2178
+ Type_Param.Float,
2179
+ _('End of the block along X-axis'),
2180
+ whichdict='All'
2181
+ )
2182
+
2183
+
2184
+ self._prop_block._params.add_param(GEOM_GROUP_NAME,
2185
+ _('Associated polygon (info)'),
2186
+ '',
2187
+ Type_Param.String,
2188
+ _('Name of the polygon associated to the block'),
2189
+ whichdict='All'
2190
+ )
2191
+
2192
+ self._prop_block._params[(GEOM_GROUP_NAME, _('Dx'))] = self._dx_block(idx)
2193
+ self._prop_block._params[(GEOM_GROUP_NAME, _('Dy'))] = self._dy_block(idx)
2194
+ self._prop_block._params[(GEOM_GROUP_NAME, _('X min (info)'))]= self.sim.bloc_description[idx+1].xmin
2195
+ self._prop_block._params[(GEOM_GROUP_NAME, _('Y min (info)'))]= self.sim.bloc_description[idx+1].ymin
2196
+ self._prop_block._params[(GEOM_GROUP_NAME, _('X max (info)'))]= self.sim.bloc_description[idx+1].xmax
2197
+ self._prop_block._params[(GEOM_GROUP_NAME, _('Y max (info)'))]= self.sim.bloc_description[idx+1].ymax
2198
+ self._prop_block._params[(GEOM_GROUP_NAME, _('Associated polygon (info)'))]= self.sim.bloc_description[idx+1].contour.myname
2199
+
2200
+ self._prop_block._params.Populate(sorted_groups=True)
2201
+
2202
+ def _apply_changes(self, e:wx.EVT_BUTTON):
2203
+ """
2204
+ Apply the changes to the parameters
2205
+ """
2206
+
2207
+ toggle_gen, toggle_blocks = self._get_togglestates()
2208
+
2209
+ if toggle_gen:
2210
+ self._prop_gen.apply_changes_to_memory()
2211
+
2212
+ self.sim.parameters._set_debug_params(self._prop_gen._get_debug_params())
2213
+ self.sim.parameters._set_general_params(self._prop_gen._get_general_params())
2214
+
2215
+ mag_dx = self._prop_gen._params[(MAGN_GROUP_NAME, 'Dx')]
2216
+ mag_dy = self._prop_gen._params[(MAGN_GROUP_NAME, 'Dy')]
2217
+ mag_ox = self._prop_gen._params[(MAGN_GROUP_NAME, 'Ox')]
2218
+ mag_oy = self._prop_gen._params[(MAGN_GROUP_NAME, 'Oy')]
2219
+
2220
+ if mag_dx != self.sim.magnetic_grid.dx or mag_dy != self.sim.magnetic_grid.dy or mag_ox != self.sim.magnetic_grid.origx or mag_oy != self.sim.magnetic_grid.origy:
2221
+
2222
+ dlg = wx.MessageDialog(None, _('Do you want to update the magnetic grid?'), _('Update magnetic grid'), wx.YES_NO)
2223
+
2224
+ if dlg.ShowModal() == wx.ID_YES:
2225
+
2226
+ self.sim.set_magnetic_grid(mag_dx, mag_dy, mag_ox, mag_oy)
2227
+
2228
+ dlg.Destroy()
2229
+
2230
+
2231
+ elif any(toggle_blocks):
2232
+
2233
+ nb = toggle_blocks.count(True)
2234
+
2235
+ if nb == 1:
2236
+
2237
+ idx = self._ref_block
2238
+
2239
+ dx = self._prop_gen._params[(GEOM_GROUP_NAME, _('Dx'))]
2240
+ dy = self._prop_gen._params[(GEOM_GROUP_NAME, _('Dy'))]
2241
+
2242
+ self.sim.bloc_description[idx+1].set_dx_dy(dx, dy)
2243
+
2244
+ self._prop_block.apply_changes_to_memory()
2245
+
2246
+ self.sim.parameters.blocks[idx]._set_debug_params(self._prop_block._get_debug_params())
2247
+ self.sim.parameters.blocks[idx]._set_general_params(self._prop_block._get_general_params())
2248
+
2249
+ else:
2250
+
2251
+ dx = self._prop_gen._params[(GEOM_GROUP_NAME, _('Dx'))]
2252
+ dy = self._prop_gen._params[(GEOM_GROUP_NAME, _('Dy'))]
2253
+
2254
+ self._prop_block.apply_changes_to_memory()
2255
+
2256
+ force = self._check_force.GetValue()
2257
+
2258
+ if not force:
2259
+ logging.info(_('No force update - Apply to the reference block only'))
2260
+
2261
+ idx = self._ref_block
2262
+ self.sim.parameters.blocks[idx]._set_debug_params(self._prop_block._get_debug_params())
2263
+ self.sim.parameters.blocks[idx]._set_general_params(self._prop_block._get_general_params())
2264
+
2265
+ self.sim.bloc_description[idx+1].set_dx_dy(dx, dy)
2266
+
2267
+ else:
2268
+ groups = self._prop_block.gen_groups + self._prop_block.debug_groups
2269
+ names = self._prop_block.gen_names + self._prop_block.debug_names
2270
+
2271
+ choices = ['{} - {}'.format(GEOM_GROUP_NAME, _('Dx')), '{} - {}'.format(GEOM_GROUP_NAME, _('Dy'))] + [f'{group} - {name}' for group, name in zip(groups, names) if NOT_USED not in group]
2272
+
2273
+ dlg = wx.MultiChoiceDialog(self,
2274
+ _('Which parameters should be updated in all blocks?'),
2275
+ _('Parameters'),
2276
+ choices = choices,
2277
+ style = wx.CHOICEDLG_STYLE | wx.OK | wx.CANCEL)
2278
+
2279
+ if dlg.ShowModal() == wx.ID_OK:
2280
+ selections = dlg.GetSelections()
2281
+ for sel in selections:
2282
+ group, name = choices[sel].split(' - ')
2283
+
2284
+ if group == GEOM_GROUP_NAME:
2285
+ if name == _('Dx'):
2286
+ for idx in range(self.nb_blocks):
2287
+ if toggle_blocks[idx]:
2288
+ self.sim.bloc_description.my_blocks[idx+1].dx = dx
2289
+ elif name == _('Dy'):
2290
+ for idx in range(self.nb_blocks):
2291
+ if toggle_blocks[idx]:
2292
+ self.sim.bloc_description.my_blocks[idx+1].dy = dy
2293
+ else:
2294
+
2295
+ for idx in range(self.nb_blocks):
2296
+ if toggle_blocks[idx]:
2297
+ # idx+1 because the blocks are 1-indexed in the __getitem__ method
2298
+ self.sim[idx+1].set_parameter(group, name, self._prop_block._params[(group, name)])
2299
+ dlg.Destroy()
2300
+
2301
+ self._prop_block._params.Populate(sorted_groups=True)
2302
+
2303
+
2304
+ self._txt_info.Clear()
2305
+ self._txt_info.AppendText(_('Changes applied'))
2306
+
2307
+
2308
+ def extend_bed_elevation(self):
2309
+ """
2310
+ Extension du modèle topographique
2311
+ """
2312
+ if not self.wx_exists:
2313
+ raise Warning('Must be operated by GUI --> Nothing will be done !! or generalize the source code :-) ')
2314
+
2315
+ dlg = wx.MessageDialog(self,_('Do you want to autocomplete elevation from external file?'),style=wx.YES_NO|wx.YES_DEFAULT)
2316
+ ret=dlg.ShowModal()
2317
+ dlg.Destroy()
2318
+
2319
+ if ret == wx.ID_NO:
2320
+ logging.info(_('Nothing to do !'))
2321
+ return
2322
+
2323
+ if not self.top.loaded:
2324
+ self.top.check_plot()
2325
+ self.top.copy_mask_log(self.curmask)
2326
+ self.top.loaded=True
2327
+
2328
+ filterArray = "bin (*.bin)|*.bin|all (*.*)|*.*"
2329
+ fdlg = wx.FileDialog(self, "Choose file", wildcard=filterArray, style=wx.FD_OPEN)
2330
+ if fdlg.ShowModal() != wx.ID_OK:
2331
+ fdlg.Destroy()
2332
+ return
2333
+
2334
+ filename = fdlg.GetPath()
2335
+ fdlg.Destroy()
2336
+
2337
+ logging.info(_('Importing data from file'))
2338
+ newtop = WolfArray(fname=filename,mapviewer=self.mapviewer)
2339
+
2340
+ logging.info(_('Finding nodes -- plotting disabled for speed'))
2341
+ self.top.mngselection.hideselection = True
2342
+ self.top.mngselection.condition_select(2,0., usemask=True)
2343
+
2344
+ if len(self.top.mngselection.myselection)>0:
2345
+ newtop.mngselection.myselection = self.top.mngselection.myselection
2346
+ newtop.mngselection.hideselection = True
2347
+ newtop.mngselection.update_nb_nodes_selection()
2348
+
2349
+ logging.info(_('Copying values'))
944
2350
  z = newtop.mngselection.get_values_sel()
945
2351
  logging.info(_('Pasting values'))
946
2352
  self.top.set_values_sel(self.top.mngselection.myselection, z, False)
@@ -1091,14 +2497,18 @@ class Wolf2DModel(GenMapManager):
1091
2497
  curarray.copy_mask_log(self.curmask)
1092
2498
  curarray.mngselection.myselection=[]
1093
2499
  curarray.mngselection.hideselection = False
1094
- curarray.mngselection.update_nb_nodes_sections()
2500
+ curarray.mngselection.update_nb_nodes_selection()
1095
2501
  curarray.reset_plot()
1096
2502
 
1097
2503
  logging.info('')
1098
2504
  logging.info(_('Do not forget to save your changes to files !'))
1099
2505
  logging.info('')
1100
2506
 
1101
- def set_type_ic(self,which=2,dialog=True):
2507
+
2508
+
2509
+
2510
+ def set_type_ic(self, which:Literal[1,2,3]=2, dialog:bool=True):
2511
+ """ Définition du type de conditions initiales """
1102
2512
 
1103
2513
  if (not self.wx_exists) and dialog:
1104
2514
  raise Warning('Must be operated by GUI --> Nothing will be done !! or generalize the source code :-) ')
@@ -1116,130 +2526,37 @@ class Wolf2DModel(GenMapManager):
1116
2526
  if which<1 or which>3:
1117
2527
  return
1118
2528
 
1119
- self.myparam.ntyperead = which
1120
- self.myparam.write_file()
2529
+ self.sim.parameters._initial_cond_reading_mode = which
2530
+ self.sim.parameters.write_file()
1121
2531
 
1122
- def replace_external_contour(self,newvec:vector,interior):
2532
+
2533
+ def replace_external_contour(self, newvec:vector, interior:bool):
2534
+ """ Remplacement du contour externe """
1123
2535
 
1124
2536
  logging.info(_('Copying extrenal contour'))
1125
2537
 
1126
2538
  logging.info(_(' ... in .bloc'))
1127
2539
  ext_zone:zone
1128
- ext_zone = self.myblocfile.my_vec_blocks.myzones[0]
2540
+ ext_zone = self.sim.bloc_description.my_vec_blocks.myzones[0]
1129
2541
  ext_zone.myvectors[0] = newvec
1130
2542
 
1131
2543
  logging.info(_(' ... in xy --> Fortran will update this file after internal meshing process'))
1132
2544
  self.xyzones.myzones[0].myvectors[0] = newvec
1133
2545
 
1134
- self.myblocfile.my_vec_blocks.reset_listogl()
1135
- self.myblocfile.my_vec_blocks.prep_listogl()
1136
-
1137
- logging.info(_('Updating .bloc file'))
1138
- self.myblocfile.interior=interior
1139
- self.myblocfile.my_vec_blocks.find_minmax(True)
1140
- self.myblocfile.update_nbmax()
1141
- self.myblocfile.write_file()
1142
-
1143
- def write_bloc_file(self):
2546
+ self.sim.bloc_description.my_vec_blocks.reset_listogl()
2547
+ self.sim.bloc_description.my_vec_blocks.prep_listogl()
1144
2548
 
1145
2549
  logging.info(_('Updating .bloc file'))
1146
- self.myblocfile.my_vec_blocks.find_minmax(True)
1147
- self.myblocfile.write_file()
1148
-
1149
- def get_header_MB(self, abs=False):
1150
- """Renvoi d'un header avec les infos multi-blocs"""
1151
- myheader:header_wolf
1152
- myheader = self.mymnap.get_header(abs=abs)
1153
- for curblock in self.mymnap.myblocks.values():
1154
- myheader.head_blocks[getkeyblock(curblock.blockindex)] = curblock.get_header(abs=abs)
1155
- return myheader
1156
-
1157
- def get_header(self, abs=False):
1158
- """
1159
- Renvoi d'un header de matrice "fine" non MB
1160
-
1161
- @param abs: If True, the header will be absolute, if False, it will be relative
1162
- @type abs: bool
1163
-
1164
- @return: header_wolf
1165
- """
1166
-
1167
- curhead = header_wolf()
1168
-
1169
- curhead.nbx = self.myparam.nxfin
1170
- curhead.nby = self.myparam.nyfin
1171
-
1172
- curhead.dx = self.myparam.dxfin
1173
- curhead.dy = self.myparam.dyfin
1174
-
1175
- if abs:
1176
- curhead.origx = self.myparam.xminfin + self.myparam.translx
1177
- curhead.origy = self.myparam.yminfin + self.myparam.transly
1178
-
1179
- curhead.translx = 0.
1180
- curhead.transly = 0.
1181
-
1182
- else:
1183
-
1184
- curhead.origx = self.myparam.xminfin
1185
- curhead.origy = self.myparam.yminfin
1186
-
1187
- curhead.translx = self.myparam.translx
1188
- curhead.transly = self.myparam.transly
1189
-
1190
- return curhead
1191
-
1192
- def read_fine_array(self, which:str=''):
1193
- """
1194
- Lecture d'une matrice fine
1195
-
1196
- @param which: suffixe du fichier
1197
- @type which: str
1198
- """
2550
+ self.sim.bloc_description.interior=interior
2551
+ self.sim.bloc_description.my_vec_blocks.find_minmax(True)
2552
+ self.sim.bloc_description.write_file()
1199
2553
 
1200
- if Path(self.filenamegen + which).exists():
1201
- myarray = WolfArray(fname = self.filenamegen + which)
1202
-
1203
- else:
1204
- logging.error(f"File {self.filenamegen + which} does not exist")
1205
- myarray = None
1206
-
1207
- # myarray.set_header(self.get_header())
1208
- # myarray.filename = self.filenamegen+which
1209
- # myarray.read_data()
1210
-
1211
- return myarray
1212
-
1213
- def read_MB_array(self, which:str=''):
1214
- """
1215
- Lecture d'une matrice MB
1216
-
1217
- @param which: suffixe du fichier
1218
- @type which: str
1219
- """
1220
-
1221
- myarray =WolfArrayMB()
1222
- myarray.set_header(self.get_header_MB())
1223
- myarray.filename = self.filenamegen+which
1224
- myarray.read_data()
1225
-
1226
- return myarray
1227
-
1228
- def read_fine_nap(self) -> np.ndarray:
1229
- """Lecture de la matrice nap sur le maillage fin"""
1230
- nbx=self.myparam.nxfin
1231
- nby=self.myparam.nyfin
1232
-
1233
- with open(self.filenamegen +'.napbin', 'rb') as f:
1234
- mynap = np.frombuffer(f.read(nbx*nby*2), dtype=np.int16).copy()
1235
- mynap=np.abs(mynap)
1236
-
1237
- return mynap.reshape([nbx,nby], order='F')
1238
2554
 
1239
2555
  def transfer_ic(self,vector):
1240
2556
  """
1241
2557
  Transfert de conditions initiales
1242
2558
  """
2559
+
1243
2560
  if not self.wx_exists:
1244
2561
  raise Warning('Must be operated by GUI --> Nothing will be done !! or generalize the source code :-) ')
1245
2562
 
@@ -1285,158 +2602,104 @@ class Wolf2DModel(GenMapManager):
1285
2602
 
1286
2603
  pass
1287
2604
 
1288
- @property
1289
- def is_multiblock(self):
1290
- return self.myblocfile.nb_blocks>1
1291
-
1292
- @property
1293
- def nb_blocks(self):
1294
- return self.myblocfile.nb_blocks
1295
-
1296
- def help_files(self):
1297
-
1298
- ret= _('Text files\n')
1299
- ret+= ('----------\n')
1300
2605
 
1301
- for key, val in self.files_others['Characteristics']:
1302
- ret += f"{val} : {key}\n"
1303
2606
 
1304
- ret +='\n\n'
2607
+ # **********
2608
+ # DEPRECATED
2609
+ # **********
1305
2610
 
1306
- ret += _('Fine array - monoblock\n')
1307
- ret += ('----------------------\n')
2611
+ @property
2612
+ def is_multiblock(self):
2613
+ """ Deprecated, use the property from the infiltration object """
1308
2614
 
1309
- for key, val, dtype in self.files_fine_array['Characteristics']:
2615
+ return self.sim.is_multiblock
1310
2616
 
1311
- if dtype == WOLF_ARRAY_FULL_LOGICAL:
1312
- ret += f"{val} : {key} [int16]\n"
1313
- elif dtype == WOLF_ARRAY_FULL_INTEGER:
1314
- ret += f"{val} : {key} [int32]\n"
1315
- elif dtype == WOLF_ARRAY_FULL_SINGLE:
1316
- ret += f"{val} : {key} [float32]\n"
1317
- else:
1318
- ret += f"{val} : {key} error - check code\n"
2617
+ @property
2618
+ def nb_blocks(self):
2619
+ """ Deprecated, use the property from the infiltration object """
1319
2620
 
1320
- ret +='\n\n'
2621
+ return self.sim.nb_blocks
1321
2622
 
1322
- ret += _('Multiblock arrays\n')
1323
- ret += ('-----------------\n')
2623
+ def help_files(self):
2624
+ """
2625
+ Aide sur les fichiers
1324
2626
 
1325
- for key, val, dtype in self.files_MB_array['Initial Conditions']:
2627
+ Deprecated, use the method from the infiltration object
2628
+ """
1326
2629
 
1327
- if dtype == WOLF_ARRAY_MB_INTEGER:
1328
- ret += f"{val} : {key} [int32]\n"
1329
- elif dtype == WOLF_ARRAY_MB_SINGLE:
1330
- ret += f"{val} : {key} [float32]\n"
1331
- else:
1332
- ret += f"{val} : {key} error - check code\n"
2630
+ return self.sim.help_files()
1333
2631
 
1334
- return ret
1335
2632
 
1336
2633
  def check_infiltration(self):
2634
+ """ Vérification des zones d'infiltration
1337
2635
 
1338
- ret = _('inside .inf binary file') + '\n'
1339
- ret += ('-----------------------') + '\n'
1340
-
1341
- inf = self.read_fine_array('.inf')
1342
-
1343
- maxinf = inf.array.data.max()
1344
- ret += _('Maximum infiltration zone : ') + str(maxinf) + '\n'
1345
- for i in range(1,maxinf+1):
1346
-
1347
- nb = np.sum(inf.array.data == i)
1348
- if nb>0:
1349
- indices = np.where(inf.array.data == i)
1350
- 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"
1351
- else:
1352
- ret += f"Zone {i} : 0 cells\n"
1353
-
1354
- ret += '\n'
1355
-
1356
- ret += _('inside .fil text file') + '\n'
1357
- ret += ('----------------------') + '\n'
1358
-
1359
- ret += f"Zones {self.myinfil.nb_zones}" + '\n'
1360
- ret += f"Time steps {self.myinfil.nb_steps}" + '\n'
1361
-
1362
- if maxinf != self.myinfil.nb_zones:
1363
- ret += _('Warning : number of zones in .inf and .fil files are different') + '\n'
2636
+ Deprecated, use the method from the infiltration object
2637
+ """
1364
2638
 
1365
- return ret
2639
+ return self.sim.check_infiltration()
1366
2640
 
1367
2641
 
1368
2642
  def copy2gpu(self, dirout:str=''):
1369
2643
  """
1370
2644
  Copie des matrices pour le code GPU
1371
- """
1372
2645
 
1373
- def to_absolute(array:WolfArray):
1374
- array.origx += array.translx
1375
- array.origy += array.transly
1376
- array.translx = 0.
1377
- array.transly = 0.
2646
+ Deprecated, use the method from the simulation object
2647
+ """
1378
2648
 
1379
- ret = ''
2649
+ return self.sim.copy2gpu(dirout)
1380
2650
 
1381
- dirout = Path(dirout)
1382
- makedirs(dirout, exist_ok=True)
2651
+ def write_bloc_file(self):
2652
+ """ Mise à jour du fichier de blocs """
1383
2653
 
1384
- inf = self.read_fine_array('.inf')
1385
- to_absolute(inf)
1386
- inf.write_all(dirout / 'infiltration_zones.npy')
1387
- del(inf)
2654
+ logging.info(_('Updating .bloc file'))
2655
+ self.sim.bloc_description.modify_extent()
2656
+ self.sim.bloc_description.write_file()
1388
2657
 
1389
- ret += '.inf --> infiltration_zones.npy [np.int32]\n'
1390
2658
 
1391
- frot = self.read_fine_array('.frot')
1392
- to_absolute(frot)
1393
- frot.write_all(dirout / 'manning.npy')
1394
- del(frot)
2659
+ def get_header_MB(self, abs=False):
2660
+ """Renvoi d'un header avec les infos multi-blocs
1395
2661
 
1396
- ret += '.frot --> manning.npy [np.float32]\n'
2662
+ :param abs: If True, the header will be absolute, if False, it will be relative
2663
+ :type abs: bool
1397
2664
 
1398
- hbin = self.read_fine_array('.hbin')
1399
- to_absolute(hbin)
1400
- hbin.write_all(dirout / 'h.npy')
1401
- del(hbin)
2665
+ :return: header_wolf
2666
+ """
1402
2667
 
1403
- ret += '.hbin --> h.npy [np.float32]\n'
2668
+ return self.sim.get_header_MB(abs)
1404
2669
 
1405
- qxbin = self.read_fine_array('.qxbin')
1406
- to_absolute(qxbin)
1407
- qxbin.write_all(dirout / 'qx.npy')
1408
- del(qxbin)
2670
+ def get_header(self, abs=False):
2671
+ """
2672
+ Renvoi d'un header de matrice "fine" non MB
1409
2673
 
1410
- ret += '.qxbin --> qx.npy [np.float32]\n'
2674
+ :param abs: If True, the header will be absolute, if False, it will be relative
2675
+ :type abs: bool
1411
2676
 
1412
- qybin = self.read_fine_array('.qybin')
1413
- to_absolute(qybin)
1414
- qybin.write_all(dirout / 'qy.npy')
1415
- del(qybin)
2677
+ :return: header_wolf
2678
+ """
1416
2679
 
1417
- ret += '.qybin --> qy.npy [np.float32]\n'
2680
+ self.sim.get_header(abs)
1418
2681
 
1419
- nap = self.read_fine_array('.napbin')
1420
- napgpu = np.zeros_like(nap.array.data, dtype = np.uint8)
1421
- napgpu[np.where(nap.array.data != 0)] = 1
1422
- np.save(dirout / 'nap.npy', napgpu)
2682
+ def read_fine_array(self, which:str=''):
2683
+ """
2684
+ Lecture d'une matrice fine
1423
2685
 
1424
- ret += '.napbin --> nap.npy [np.uint8]\n'
2686
+ :param which: suffixe du fichier
2687
+ :type which: str
2688
+ """
1425
2689
 
1426
- top = self.read_fine_array('.top')
1427
- to_absolute(top)
1428
- top.array.data[np.where(napgpu != 1)] = 99999.
1429
- top.nullvalue = 99999.
1430
- top.write_all(dirout / 'bathymetry.npy')
2690
+ return self.sim.read_fine_array(which)
1431
2691
 
1432
- ret += '.top --> bathymetry.npy [np.float32]\n'
1433
- ret += _('Force a value 99999. outside nap')
2692
+ def read_MB_array(self, which:str=''):
2693
+ """
2694
+ Lecture d'une matrice MB
1434
2695
 
1435
- nb = np.sum(top.array.data != 99999.)
1436
- assert nb == np.sum(napgpu == 1), 'Error in couting active cells'
2696
+ :param which: suffixe du fichier
2697
+ :type which: str
2698
+ """
1437
2699
 
1438
- ret += f'\n{nb} active cells in bathymetry.npy'
2700
+ return self.sim.read_MB_array(which)
1439
2701
 
1440
- del(top)
2702
+ def read_fine_nap(self) -> np.ndarray:
2703
+ """Lecture de la matrice nap sur le maillage fin"""
1441
2704
 
1442
- return ret
2705
+ return self.sim.read_fine_array('.napbin')