wolfhece 2.1.99__py3-none-any.whl → 2.1.101__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.
Files changed (35) hide show
  1. wolfhece/PyDraw.py +220 -29
  2. wolfhece/PyGui.py +1039 -53
  3. wolfhece/PyVertexvectors.py +2 -2
  4. wolfhece/Results2DGPU.py +37 -13
  5. wolfhece/acceptability/Parallels.py +2 -2
  6. wolfhece/acceptability/_add_path.py +23 -0
  7. wolfhece/acceptability/acceptability.py +594 -563
  8. wolfhece/acceptability/acceptability_gui.py +564 -331
  9. wolfhece/acceptability/cli.py +307 -120
  10. wolfhece/acceptability/func.py +1754 -1597
  11. wolfhece/apps/version.py +1 -1
  12. wolfhece/bernoulli/losses.py +76 -23
  13. wolfhece/bernoulli/losses_jax.py +143 -0
  14. wolfhece/bernoulli/pipe.py +7 -2
  15. wolfhece/gpuview.py +4 -1
  16. wolfhece/libs/__init__.py +11 -10
  17. wolfhece/libs/wolfogl.cp310-win_amd64.pyd +0 -0
  18. wolfhece/math_parser/__init__.py +4 -4
  19. wolfhece/math_parser/calculator.py +51 -9
  20. wolfhece/mesh2d/bc_manager.py +25 -2
  21. wolfhece/mesh2d/gpu_2d.py +644 -0
  22. wolfhece/mesh2d/simple_2d.py +2817 -0
  23. wolfhece/mesh2d/wolf2dprev.py +5 -2
  24. wolfhece/pidcontroller.py +131 -0
  25. wolfhece/pywalous.py +7 -7
  26. wolfhece/scenario/config_manager.py +98 -21
  27. wolfhece/wolf_array.py +391 -176
  28. wolfhece/wolf_vrt.py +108 -7
  29. wolfhece/wolfresults_2D.py +113 -6
  30. wolfhece/xyz_file.py +91 -51
  31. {wolfhece-2.1.99.dist-info → wolfhece-2.1.101.dist-info}/METADATA +3 -1
  32. {wolfhece-2.1.99.dist-info → wolfhece-2.1.101.dist-info}/RECORD +35 -30
  33. {wolfhece-2.1.99.dist-info → wolfhece-2.1.101.dist-info}/WHEEL +1 -1
  34. {wolfhece-2.1.99.dist-info → wolfhece-2.1.101.dist-info}/entry_points.txt +0 -0
  35. {wolfhece-2.1.99.dist-info → wolfhece-2.1.101.dist-info}/top_level.txt +0 -0
@@ -40,7 +40,7 @@ from ..PyVertex import getIfromRGB
40
40
  from ..PyTranslate import _
41
41
  from ..CpGrid import CpGrid
42
42
  from ..GraphNotebook import PlotPanel
43
- from ..PyParams import Wolf_Param, new_json
43
+ from ..PyParams import Wolf_Param, new_json, key_Param, Type_Param
44
44
  from .cst_2D_boundary_conditions import BCType_2D, Direction, BCType_2D_To_BCType_2D_GPU
45
45
 
46
46
  PREV_INFILTRATION_NULL = 0 #PAS D'INFILTRATION
@@ -8100,9 +8100,12 @@ class prev_infiltration():
8100
8100
 
8101
8101
  sequence, nb_zones = self._infiltrations_chronology.shape
8102
8102
  for zone in range(1,nb_zones):
8103
- ax.plot(self._infiltrations_chronology[:, 0], self._infiltrations_chronology[:, zone], label=f'Infil {zone}')
8103
+ ax.plot(self._infiltrations_chronology[:, 0], self._infiltrations_chronology[:, zone], label=f'Zone {zone}')
8104
8104
 
8105
+ ax.set_xlabel(_('Time [s]'))
8106
+ ax.set_ylabel(_('Infiltration [$m^3/s$]'))
8105
8107
  ax.legend()
8108
+ fig.tight_layout()
8106
8109
 
8107
8110
  if show:
8108
8111
  fig.show()
@@ -0,0 +1,131 @@
1
+ import numpy as np
2
+
3
+ class PIDController:
4
+ """
5
+ Tuning a PID controller -- https://dewesoft.com/blog/what-is-pid-controller
6
+
7
+ Tuning the PID parameters Kp, Ki and Kd is crucial in PID controller design.
8
+ Tuning must be customized for each of the many PID applications.
9
+ Key tuning parameters include:
10
+
11
+ - Proportional Gain (Kp): This parameter determines the proportion of
12
+ the error signal contributing to the controller output. A higher
13
+ Kp value results in a stronger response to the current error.
14
+ Too high a Kp can lead to oscillations or instability, while too
15
+ low a value can result in a sluggish response.
16
+
17
+ - Integral Gain (Ki): The integral term considers the accumulation
18
+ of past errors and amplifies them over time. It helps eliminate
19
+ steady-state error by continuously adjusting the control signal.
20
+ A higher Ki value helps reduce steady-state error but can lead
21
+ to overshoot or instability if set too high.
22
+
23
+ - Derivative Gain (Kd): The derivative term predicts the future behavior
24
+ of the error based on its current rate of change. It helps dampen
25
+ oscillations by counteracting rapid changes in the error signal.
26
+ Increasing Kd enhances damping and reduces overshoot, but too high
27
+ a value can lead to instability or sensitivity to noise.
28
+
29
+ The tuning process involves adjusting these parameters to achieve
30
+ desired system performance, such as stability, responsiveness,
31
+ and minimal overshoot. Several methods are used for PID tuning,
32
+ including manual tuning, Ziegler-Nichols method, and optimization
33
+ algorithms. Let’s take a closer look at each of these methods:
34
+
35
+ In manual tuning, the engineer adjusts the parameters based on their
36
+ understanding of the system dynamics and the desired performance criteria.
37
+ This method involves iteratively tweaking the parameters while observing
38
+ the system's response until satisfactory performance is achieved.
39
+
40
+ The Ziegler-Nichols Method provides a systematic approach to PID
41
+ tuning based on step response experiments. The integral and derivative
42
+ gains are set to zero and gradually increased until the system oscillates
43
+ at a constant amplitude. The proportional gain and oscillation period
44
+ are determined from the oscillation period and amplitude, which are
45
+ then used to calculate suitable PID parameters. Several other tuning
46
+ methods exist, including Cohen-Coon, Lambda, and Dead Time.
47
+
48
+ Optimization algorithms such as gradient descent, genetic algorithms,
49
+ or particle swarm optimization automatically search for optimal PID
50
+ parameters based on specified performance criteria and system models.
51
+
52
+ PID tuning is a critical step in control system design. It ensures
53
+ that the controller effectively regulates the system while meeting
54
+ performance requirements.
55
+ """
56
+
57
+ def __init__(self, kp, ki, kd):
58
+ """
59
+ Initialize the PID controller with given coefficients.
60
+
61
+ :params kp (float): Proportional gain coefficient.
62
+ :params ki (float): Integral gain coefficient.
63
+ :params kd (float): Derivative gain coefficient.
64
+ """
65
+
66
+ self.kp = kp
67
+ self.ki = ki
68
+ self.kd = kd
69
+ self.error_sum = 0
70
+ self.last_error = 0
71
+
72
+ def calculate(self, setpoint, feedback):
73
+ """ Compute the PID response.
74
+
75
+ :param setpoint: Objective value to achieve.
76
+ :type setpoint: float
77
+ :param feedback: Current measured value.
78
+ :type feedback: float
79
+ :return: PID control output.
80
+ :rtype: float
81
+ """
82
+
83
+ error = setpoint - feedback
84
+ self.error_sum += error
85
+ error_diff = error - self.last_error
86
+ self.last_error = error
87
+
88
+ p = self.kp * error
89
+ i = self.ki * self.error_sum
90
+ d = self.kd * error_diff
91
+
92
+ return p + i + d
93
+
94
+ if __name__ == "__main__":
95
+
96
+ import matplotlib.pyplot as plt
97
+
98
+ # Create a PIDController instance
99
+ pid_controller = PIDController(kp=0.5, ki=0.1, kd=.5)
100
+
101
+ # Define time range and step size
102
+ t_start = 0
103
+ t_end = 10
104
+ dt = 0.1
105
+
106
+ # Initialize lists to store time and output values
107
+ time = []
108
+ output = []
109
+ measures = [1]
110
+
111
+ # Simulate the system over time
112
+ for t in np.arange(t_start, t_end, dt):
113
+ # Calculate the output using the PID controller
114
+ setpoint = 10 # Example setpoint
115
+ control_signal = pid_controller.calculate(setpoint, measures[-1])
116
+
117
+ # Simulate the system dynamics
118
+ # In a real-world application, this would be replaced by actual measurements
119
+ measures.append(measures[-1] + .4 * control_signal)
120
+
121
+ # Store the time and output values
122
+ time.append(t)
123
+ output.append(control_signal)
124
+
125
+ # Plot the output over time
126
+ plt.plot(time, measures[1:], label='System Output')
127
+ plt.xlabel('Time')
128
+ plt.ylabel('Output')
129
+ plt.title('PID Controller Output')
130
+ plt.grid(True)
131
+ plt.show()
wolfhece/pywalous.py CHANGED
@@ -130,13 +130,13 @@ def update_palette_walous(which:Literal['MAJ_NIV1', 'MAJ_NIV2'], pal:wolfpalette
130
130
  return 0
131
131
 
132
132
 
133
- WALOUS2MANNING_MAJ_NIV1 = {1.: 0.04,
134
- 2.: 0.02,
135
- 3.: 0.02,
136
- 4.: 0.03,
137
- 5.: 0.025,
138
- 6.: 0.04,
139
- 7.: 0.05}
133
+ WALOUS2MANNING_MAJ_NIV1 = {1.: 0.04, # Production primaire
134
+ 2.: 0.02, # Production secondaire
135
+ 3.: 0.02, # Production tertiaire
136
+ 4.: 0.03, # Réseaux de transport, Logistique et réseaux d'utilité publique
137
+ 5.: 0.025,# Usage résidentiel
138
+ 6.: 0.04, # Autres usages
139
+ 7.: 0.05} # Zones naturelles
140
140
 
141
141
  WALOUS2MANNING_MAJ_NIV2 = {11.: 0.04, # Agriculture
142
142
  12.: 0.04, # Sylviculture
@@ -202,14 +202,15 @@ class Config_Manager_2D_GPU:
202
202
  Gestionnaire de configurations 2D - code GPU
203
203
  """
204
204
 
205
- def __init__(self, workingdir:str = '', mapviewer:WolfMapViewer = None) -> None:
205
+ def __init__(self, workingdir:str = '', mapviewer:WolfMapViewer = None, python_venv:Path = None) -> None:
206
206
  """
207
207
  Recherche de toutes les modélisation dans un répertoire et ses sous-répertoires
208
208
  """
209
209
  self.wx_exists = wx.App.Get() is not None
210
210
 
211
- self.workingdir = ''
212
- self.wolfcli = ''
211
+ self.workingdir:Path = None
212
+ self.wolfgpu:Path = None
213
+ self._py_env:Path = python_venv
213
214
 
214
215
  if workingdir == '':
215
216
  if self.wx_exists:
@@ -228,6 +229,7 @@ class Config_Manager_2D_GPU:
228
229
  logging.error(_('Directory does not exist !'))
229
230
  return
230
231
 
232
+ self.find_wolfgpu()
231
233
  self.workingdir = Path(workingdir)
232
234
  self.mapviewer = mapviewer
233
235
 
@@ -239,6 +241,33 @@ class Config_Manager_2D_GPU:
239
241
 
240
242
  self.load_data()
241
243
 
244
+ def find_wolfgpu(self):
245
+ """ Find the wolfgpu Path from wolfgpu package"""
246
+
247
+ import importlib.util
248
+ import sys
249
+
250
+ if self._py_env is None:
251
+ self._py_env = Path(sys.executable).parent
252
+
253
+ # Find wolfgpu.exe in script directory
254
+ candidate = self._py_env / 'wolfgpu.exe'
255
+
256
+ if candidate.exists():
257
+ self.wolfgpu = candidate
258
+ return
259
+
260
+ candidate = self._py_env / 'Scripts' / 'wolfgpu.exe'
261
+
262
+ if candidate.exists():
263
+ self.wolfgpu = candidate
264
+ return
265
+ else:
266
+ logging.error(_('WOLFGPU not found !'))
267
+ self.wolfgpu = None
268
+ self._py_env = None
269
+
270
+
242
271
  def _test_ui(self):
243
272
  """ Test if the UI is available """
244
273
 
@@ -1142,7 +1171,7 @@ class Config_Manager_2D_GPU:
1142
1171
  quit = True
1143
1172
 
1144
1173
  if quit:
1145
- logging.error(_('Bas assembly operation -- Simulation creation aborted !'))
1174
+ logging.error(_('Bad assembly operation -- Simulation creation aborted !'))
1146
1175
  return
1147
1176
 
1148
1177
  bat = WolfArray(str(dir / '__bathymetry.tif'))
@@ -1263,25 +1292,35 @@ class Config_Manager_2D_GPU:
1263
1292
  logging.info(cursim.check_errors())
1264
1293
  logging.info(_('Simulation {} created !'.format(curdir)))
1265
1294
 
1266
-
1267
1295
  with open(curdir / 'quickrun.bat', 'w', encoding='utf-8') as f:
1296
+ f.write("@echo off\n")
1297
+ f.write("\n")
1268
1298
  f.write(str(curdir.drive) + '\n')
1269
1299
  f.write('cd {}\n'.format(str(curdir.parent)))
1270
- f.write('wolfgpu -quickrun ' + str(curdir.name) + '\n')
1271
-
1272
- # f.write("from pathlib import Path\n")
1273
- # f.write("from wolfgpu.simple_simulation import SimpleSimulation\n")
1274
- # f.write("from wolfgpu.SimulationRunner import SimulationRunner\n")
1275
- # f.write("from wolfgpu.glsimulation import ResultsStore\n\n")
1276
- # f.write("def main():\n")
1277
- # f.write("\tsim = SimpleSimulation.load(Path(__file__).parent)\n")
1278
- # f.write("\tresult_store:ResultsStore = SimulationRunner.quick_run(sim, Path(__file__).parent)")
1279
- # f.write("\n\nif __name__ == '__main__':\n")
1280
- # f.write("\tmain()\n")
1300
+ f.write("\n")
1301
+ f.write("WOLFGPU_PARAMS=-quickrun " + str(curdir.name) + "\n")
1302
+ f.write("\n")
1303
+ f.write("where wolfgpu.exe\n")
1304
+ f.write("IF %ERRORLEVEL%==0 (\n")
1305
+ f.write("wolfgpu %WOLFGPU_PARAMS%\n")
1306
+ f.write("goto :end\n")
1307
+ f.write(")\n")
1308
+ f.write("\n")
1309
+ f.write("echo -------------------------------\n")
1310
+ f.write("echo ERROR !!!\n")
1311
+ f.write("echo -------------------------------\n")
1312
+ f.write("echo I can't find wolfgpu.exe.\n")
1313
+ f.write("echo It is normally installed in the 'Scripts' subdirectory of your python\n")
1314
+ f.write("echo directory (or environment).\n")
1315
+ f.write("echo This 'Scripts' subdirectory must be available on the PATH environment variable.\n")
1316
+ f.write("echo I am now going to try to run wolfgpu as a regular python module\n")
1317
+ f.write("echo -------------------------------\n")
1318
+ f.write("pause\n")
1319
+ f.write("python -m wolfgpu.cli %WOLFGPU_PARAMS%\n")
1320
+ f.write(":end\n")
1281
1321
 
1282
1322
  allsims.append(curdir / 'quickrun.bat')
1283
1323
 
1284
-
1285
1324
  logging.info(_('Simulation creation finished !'))
1286
1325
  logging.warning(_('Do not forget to update/set the boundary conditions if not set by scripts !'))
1287
1326
 
@@ -1303,10 +1342,24 @@ class Config_Manager_2D_GPU:
1303
1342
  with open(path, 'w', encoding='utf-8') as f:
1304
1343
  f.write(batch)
1305
1344
 
1345
+ if self.wolfgpu is None:
1346
+ logging.warning('****************************************************')
1347
+ logging.warning(_('Wolfgpu.exe not found !'))
1348
+ logging.warning(_('It is normally installed in the "Scripts" subdirectory of your python directory (or environment).'))
1349
+ logging.warning(_('This "Scripts" subdirectory must be available on the PATH environment variable.'))
1350
+ logging.warning('****************************************************')
1351
+ else:
1352
+ logging.info('****************************************************')
1353
+ logging.info(_('Wolfgpu.exe found in {}!').format(self.wolfgpu))
1354
+ logging.info(_('You can now run the simulations !'))
1355
+ logging.info(_('Do not forget to activate your Python virtual environment if you are using one !'))
1356
+ logging.info('****************************************************')
1357
+
1306
1358
  return batch
1307
1359
 
1308
1360
  def run_batch(self, batch:Path):
1309
1361
  """ run a batch file in a subprocess """
1362
+
1310
1363
  if not batch.exists():
1311
1364
  logging.error(_('Batch file {} does not exist !'.format(batch)))
1312
1365
  return
@@ -1763,9 +1816,33 @@ class UI_Manager_2D_GPU():
1763
1816
 
1764
1817
  log = self._parent.check_consistency()
1765
1818
  if log =='':
1766
- self._txtctrl.WriteText(_("All is fine !"))
1819
+ self._txtctrl.WriteText(_("All is fine !\n\n"))
1767
1820
  else:
1768
- self._txtctrl.WriteText(log)
1821
+ self._txtctrl.WriteText(log +"\n\n")
1822
+
1823
+ # Info on Python Environment and wolfgpu Path and version
1824
+ # -------------------------------------------------------
1825
+
1826
+ import sys
1827
+ # Python Environment
1828
+ self._txtctrl.write(_('Python Environment\n'))
1829
+ self._txtctrl.write('-------------------\n')
1830
+ self._txtctrl.write('Python version : {}\n'.format(sys.version))
1831
+ self._txtctrl.write('Python path : {}\n'.format(sys.executable))
1832
+ self._txtctrl.write('Python version info : {}\n'.format(sys.version_info))
1833
+
1834
+ # Test if wolfgpu.exe exists in script directory
1835
+ # wolfgpu Path and version
1836
+ self._txtctrl.write('\nWolfgpu Path and version\n')
1837
+ self._txtctrl.write('------------------------\n')
1838
+
1839
+ wolfgpu = self._parent.wolfgpu
1840
+ if wolfgpu.exists():
1841
+ self._txtctrl.write('Wolfgpu.exe found in : {}\n'.format(self._parent.wolfgpu.parent))
1842
+ else:
1843
+ self._txtctrl.write('Wolfgpu.exe not found !\n')
1844
+ self._parent.wolfgpu = None
1845
+
1769
1846
 
1770
1847
  def choice_hydrograph(self) -> list[int]:
1771
1848
 
@@ -1975,7 +2052,7 @@ class UI_Manager_2D_GPU():
1975
2052
  try:
1976
2053
  if curwp.Shown:
1977
2054
  cursim.from_wolfparam(curwp)
1978
- cursim.save_json()
2055
+ cursim._save_json()
1979
2056
  except Exception as e:
1980
2057
  self._wp[cursim] = None
1981
2058
  logging.debug(_('Error while saving parameters for simulation {}'.format(cursim.path.name)))
@@ -1989,7 +2066,7 @@ class UI_Manager_2D_GPU():
1989
2066
  try:
1990
2067
  if curwp.Shown:
1991
2068
  cursim.from_wolfparam(curwp)
1992
- cursim.save_json()
2069
+ cursim._save_json()
1993
2070
  except Exception as e:
1994
2071
  self._wp[cursim] = None
1995
2072
  logging.debug(_('Error while saving parameters for simulation {}'.format(cursim.path.name)))