zoomy-core 0.1.11__tar.gz → 0.1.14__tar.gz

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.

Potentially problematic release.


This version of zoomy-core might be problematic. Click here for more details.

Files changed (69) hide show
  1. zoomy_core-0.1.14/PKG-INFO +52 -0
  2. zoomy_core-0.1.14/README.md +4 -0
  3. zoomy_core-0.1.14/fvm/__init__.py +0 -0
  4. zoomy_core-0.1.14/mesh/__init__.py +0 -0
  5. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/mesh/mesh.py +4 -1
  6. zoomy_core-0.1.14/misc/__init__.py +0 -0
  7. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/misc/io.py +23 -14
  8. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/misc/misc.py +5 -0
  9. zoomy_core-0.1.14/model/__init__.py +0 -0
  10. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/model/basemodel.py +1 -0
  11. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/model/model.py +3 -1
  12. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/model/models/basismatrices.py +6 -2
  13. zoomy_core-0.1.14/postprocessing/__init__.py +0 -0
  14. zoomy_core-0.1.14/postprocessing/plotting.py +244 -0
  15. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/postprocessing/postprocessing.py +4 -1
  16. zoomy_core-0.1.14/preprocessing/__init__.py +0 -0
  17. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/preprocessing/openfoam_moments.py +2 -1
  18. {zoomy_core-0.1.11 → zoomy_core-0.1.14}/pyproject.toml +2 -3
  19. zoomy_core-0.1.14/transformation/__init__.py +0 -0
  20. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/transformation/to_amrex.py +4 -1
  21. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/transformation/to_c.py +5 -1
  22. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/transformation/to_numpy.py +17 -14
  23. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/transformation/to_openfoam.py +5 -1
  24. zoomy_core-0.1.14/zoomy_core.egg-info/PKG-INFO +52 -0
  25. zoomy_core-0.1.14/zoomy_core.egg-info/SOURCES.txt +60 -0
  26. zoomy_core-0.1.14/zoomy_core.egg-info/top_level.txt +9 -0
  27. zoomy_core-0.1.11/PKG-INFO +0 -225
  28. zoomy_core-0.1.11/README.md +0 -177
  29. zoomy_core-0.1.11/library/zoomy_core/__init__.py +0 -7
  30. zoomy_core-0.1.11/library/zoomy_core/model/models/core.py +0 -564
  31. zoomy_core-0.1.11/library/zoomy_core.egg-info/PKG-INFO +0 -225
  32. zoomy_core-0.1.11/library/zoomy_core.egg-info/SOURCES.txt +0 -54
  33. zoomy_core-0.1.11/library/zoomy_core.egg-info/top_level.txt +0 -1
  34. {zoomy_core-0.1.11 → zoomy_core-0.1.14}/LICENSE +0 -0
  35. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/decorators/decorators.py +0 -0
  36. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/fvm/flux.py +0 -0
  37. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/fvm/nonconservative_flux.py +0 -0
  38. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/fvm/ode.py +0 -0
  39. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/fvm/solver_numpy.py +0 -0
  40. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/fvm/timestepping.py +0 -0
  41. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/mesh/mesh_extrude.py +0 -0
  42. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/mesh/mesh_util.py +0 -0
  43. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/misc/custom_types.py +0 -0
  44. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/misc/interpolation.py +0 -0
  45. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/misc/logger_config.py +0 -0
  46. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/model/analysis.py +0 -0
  47. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/model/basefunction.py +0 -0
  48. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/model/boundary_conditions.py +0 -0
  49. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/model/initial_conditions.py +0 -0
  50. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/model/models/GN.py +0 -0
  51. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/model/models/advection.py +0 -0
  52. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/model/models/basisfunctions.py +0 -0
  53. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/model/models/coupled_constrained.py +0 -0
  54. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/model/models/poisson.py +0 -0
  55. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/model/models/shallow_moments.py +0 -0
  56. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/model/models/shallow_moments_sediment.py +0 -0
  57. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/model/models/shallow_moments_topo.py +0 -0
  58. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/model/models/shallow_moments_variants.py +0 -0
  59. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/model/models/shallow_water.py +0 -0
  60. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/model/models/shallow_water_topo.py +0 -0
  61. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/model/models/shear_shallow_flow.py +0 -0
  62. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/model/models/sme_turbulent.py +0 -0
  63. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/model/models/vam.py +0 -0
  64. {zoomy_core-0.1.11 → zoomy_core-0.1.14}/setup.cfg +0 -0
  65. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/transformation/helpers.py +0 -0
  66. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/transformation/to_jax.py +0 -0
  67. {zoomy_core-0.1.11/library/zoomy_core → zoomy_core-0.1.14}/transformation/to_ufl.py +0 -0
  68. {zoomy_core-0.1.11/library → zoomy_core-0.1.14}/zoomy_core.egg-info/dependency_links.txt +0 -0
  69. {zoomy_core-0.1.11/library → zoomy_core-0.1.14}/zoomy_core.egg-info/requires.txt +0 -0
@@ -0,0 +1,52 @@
1
+ Metadata-Version: 2.4
2
+ Name: zoomy_core
3
+ Version: 0.1.14
4
+ Summary: A simulation software for dimensionally-reduced free surface flows.
5
+ Author-email: Ingo Steldermann <steldermann@mbd.rwth-aachen.de>
6
+ License: GNU
7
+ Project-URL: Homepage, https://github.com/mbd-rwth/Zoomy
8
+ Project-URL: Documentation, https://mbd-rwth.github.io/Zoomy
9
+ Project-URL: Source, https://github.com/mbd-rwth/Zoomy
10
+ Project-URL: Issues, https://github.com/mbd-rwth/Zoomy/issues
11
+ Keywords: simulation,shallow flow,free surface flow,shallow moments,shallow water,VAM
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Framework :: Jupyter
16
+ Requires-Python: >=3.9
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: attrs
20
+ Requires-Dist: sympy>=1.14
21
+ Requires-Dist: numpy
22
+ Requires-Dist: scipy
23
+ Requires-Dist: loguru
24
+ Requires-Dist: h5py
25
+ Requires-Dist: matplotlib
26
+ Requires-Dist: meshio
27
+ Requires-Dist: pytest
28
+ Provides-Extra: gui
29
+ Requires-Dist: pyvista; extra == "gui"
30
+ Requires-Dist: trame; extra == "gui"
31
+ Requires-Dist: trame-vtk; extra == "gui"
32
+ Requires-Dist: trame-vuetify; extra == "gui"
33
+ Requires-Dist: panel; extra == "gui"
34
+ Provides-Extra: coupling
35
+ Requires-Dist: precice; extra == "coupling"
36
+ Provides-Extra: testing
37
+ Requires-Dist: swashes; extra == "testing"
38
+ Requires-Dist: pyswashes; extra == "testing"
39
+ Provides-Extra: mesh
40
+ Requires-Dist: gmsh; extra == "mesh"
41
+ Requires-Dist: python-gmsh; extra == "mesh"
42
+ Requires-Dist: rasterio; extra == "mesh"
43
+ Provides-Extra: dev
44
+ Requires-Dist: watchfiles; extra == "dev"
45
+ Requires-Dist: Cython; extra == "dev"
46
+ Requires-Dist: pytest-html; extra == "dev"
47
+ Dynamic: license-file
48
+
49
+ # zoomy-core
50
+
51
+ This repository is a submodule of the the [Zoomy Lab](https://github.com/ZoomyLab/Zoomy) repository.
52
+
@@ -0,0 +1,4 @@
1
+ # zoomy-core
2
+
3
+ This repository is a submodule of the the [Zoomy Lab](https://github.com/ZoomyLab/Zoomy) repository.
4
+
File without changes
File without changes
@@ -34,6 +34,8 @@ import zoomy_core.mesh.mesh_util as mesh_util
34
34
  from zoomy_core.mesh.mesh_util import compute_subvolume, get_extruded_mesh_type
35
35
  from zoomy_core.misc.custom_types import CArray, FArray, IArray
36
36
  from zoomy_core.model.boundary_conditions import Periodic
37
+ from zoomy_core.misc import misc as misc
38
+
37
39
 
38
40
  # petsc4py.init(sys.argv)
39
41
 
@@ -1061,7 +1063,8 @@ class Mesh:
1061
1063
  raise RuntimeError(
1062
1064
  "Mesh.write_to_hdf5() requires h5py, which is not available."
1063
1065
  )
1064
- main_dir = os.getenv("ZOOMY_DIR")
1066
+ main_dir = misc.get_main_directory()
1067
+
1065
1068
  with h5py.File(os.path.join(main_dir, filepath), "w") as f:
1066
1069
  mesh = f.create_group("mesh")
1067
1070
  mesh.create_dataset("dimension", data=self.dimension)
File without changes
@@ -21,11 +21,13 @@ except ImportError:
21
21
  from zoomy_core.mesh.mesh import Mesh
22
22
  import zoomy_core.mesh.mesh_util as mesh_util
23
23
  from zoomy_core.misc.misc import Zstruct, Settings
24
+ from zoomy_core.misc import misc as misc
24
25
  from zoomy_core.misc.logger_config import logger
25
26
 
26
27
 
27
28
  def init_output_directory(path, clean):
28
- main_dir = os.getenv("ZOOMY_DIR")
29
+ main_dir = misc.get_main_directory()
30
+
29
31
  path = os.path.join(main_dir, path)
30
32
  os.makedirs(path, exist_ok=True)
31
33
  if clean:
@@ -81,14 +83,16 @@ def load_hdf5_to_dict(group):
81
83
 
82
84
 
83
85
  def save_settings(settings):
84
- main_dir = os.getenv("ZOOMY_DIR")
86
+ main_dir = misc.get_main_directory()
87
+
85
88
  filepath = os.path.join(main_dir, settings.output.directory)
86
89
  with h5py.File(os.path.join(filepath, "settings.h5"), "w") as f:
87
90
  write_dict_to_hdf5(f, settings.as_dict(recursive=True))
88
91
 
89
92
 
90
93
  def load_settings(filepath):
91
- main_dir = os.getenv("ZOOMY_DIR")
94
+ main_dir = misc.get_main_directory()
95
+
92
96
  filepath = os.path.join(main_dir, filepath)
93
97
  with h5py.File(os.path.join(filepath, "settings.h5"), "r") as f:
94
98
  d = load_hdf5_to_dict(f)
@@ -98,7 +102,8 @@ def load_settings(filepath):
98
102
 
99
103
 
100
104
  def load_settings2(filepath):
101
- main_dir = os.getenv("ZOOMY_DIR")
105
+ main_dir = misc.get_main_directory()
106
+
102
107
  filepath = os.path.join(main_dir, filepath)
103
108
  with h5py.File(os.path.join(filepath, "settings.h5"), "r") as f:
104
109
  model = f["model"]
@@ -156,7 +161,8 @@ def load_settings2(filepath):
156
161
 
157
162
 
158
163
  def clean_files(filepath, filename=".vtk"):
159
- main_dir = os.getenv("ZOOMY_DIR")
164
+ main_dir = misc.get_main_directory()
165
+
160
166
  abs_filepath = os.path.join(main_dir, filepath)
161
167
  if os.path.exists(abs_filepath):
162
168
  for file in os.listdir(abs_filepath):
@@ -166,7 +172,8 @@ def clean_files(filepath, filename=".vtk"):
166
172
 
167
173
  def _save_fields_to_hdf5(filepath, i_snapshot, time, Q, Qaux=None, overwrite=True):
168
174
  i_snap = int(i_snapshot)
169
- main_dir = os.getenv("ZOOMY_DIR")
175
+ main_dir = misc.get_main_directory()
176
+
170
177
  filepath = os.path.join(main_dir, filepath)
171
178
  with h5py.File(filepath, "a") as f:
172
179
  if i_snap == 0 and not "fields" in f.keys():
@@ -191,7 +198,8 @@ def _save_fields_to_hdf5(filepath, i_snapshot, time, Q, Qaux=None, overwrite=Tru
191
198
  def get_save_fields_simple(_filepath, write_all, overwrite=True):
192
199
  def _save_hdf5(i_snapshot, time, Q, Qaux):
193
200
  i_snap = int(i_snapshot)
194
- main_dir = os.getenv("ZOOMY_DIR")
201
+ main_dir = misc.get_main_directory()
202
+
195
203
  filepath = os.path.join(main_dir, _filepath)
196
204
 
197
205
  with h5py.File(filepath, "a") as f:
@@ -218,7 +226,8 @@ def get_save_fields_simple(_filepath, write_all, overwrite=True):
218
226
 
219
227
  def _save_hdf5(_filepath, i_snapshot, time, Q, Qaux, overwrite=True):
220
228
  i_snap = int(i_snapshot)
221
- main_dir = os.getenv("ZOOMY_DIR")
229
+ main_dir = misc.get_main_directory()
230
+
222
231
  filepath = os.path.join(main_dir, _filepath)
223
232
 
224
233
  with h5py.File(filepath, "a") as f:
@@ -277,7 +286,8 @@ def load_mesh_from_hdf5(filepath):
277
286
 
278
287
 
279
288
  def load_fields_from_hdf5(filepath, i_snapshot=-1):
280
- main_dir = os.getenv("ZOOMY_DIR")
289
+ main_dir = misc.get_main_directory()
290
+
281
291
  filepath = os.path.join(main_dir, filepath)
282
292
  with h5py.File(filepath, "r") as f:
283
293
  fields = f["fields"]
@@ -293,7 +303,8 @@ def load_fields_from_hdf5(filepath, i_snapshot=-1):
293
303
 
294
304
 
295
305
  def load_timeline_of_fields_from_hdf5(filepath):
296
- main_dir = os.getenv("ZOOMY_DIR")
306
+ main_dir = misc.get_main_directory()
307
+
297
308
  filepath = os.path.join(main_dir, filepath)
298
309
  l_time = []
299
310
  l_Q = []
@@ -370,8 +381,7 @@ def generate_vtk(
370
381
  filename="out",
371
382
  warp=False,
372
383
  ):
373
- # main_dir = os.getenv("ZOOMY_DIR")
374
- main_dir = ""
384
+ main_dir = misc.get_main_directory()
375
385
  abs_filepath = os.path.join(main_dir, filepath)
376
386
  path = os.path.dirname(abs_filepath)
377
387
  full_filepath_out = os.path.join(path, filename)
@@ -431,9 +441,8 @@ def generate_vtk(
431
441
  "time": time,
432
442
  }
433
443
  )
434
-
435
444
  # finalize vtk
436
- with open(os.path.join(path, f"{full_filepath_out}.vtk.series"), "w") as f:
445
+ with open(os.path.join(path, f"{filename}.vtk.series"), "w") as f:
437
446
  json.dump(vtk_timestamp_file, f)
438
447
 
439
448
  file.close()
@@ -16,6 +16,11 @@ from zoomy_core.misc.logger_config import logger
16
16
 
17
17
 
18
18
 
19
+ def get_main_directory():
20
+ main_dir = os.getenv("ZOOMY_DIR")
21
+ if main_dir is None:
22
+ main_dir = ""
23
+ return main_dir
19
24
 
20
25
 
21
26
 
File without changes
@@ -355,6 +355,7 @@ class Model:
355
355
  # self.n_variables, self.n_variables, self.dimension
356
356
  # )
357
357
  JacF = ZArray(sympy.derive_by_array(self.flux(), self.variables.get_list()))
358
+ JacF_d = ZArray.zeros(*JacF.shape)
358
359
  for d in range(self.dimension):
359
360
  JacF_d = JacF[:, :, d]
360
361
  JacF_d = ZArray(JacF_d.tomatrix().T)
@@ -10,6 +10,7 @@ from zoomy_core.model.models.advection import Advection
10
10
  import zoomy_core.model.initial_conditions as IC
11
11
  import zoomy_core.model.boundary_conditions as BC
12
12
  from zoomy_core.mesh.fvm_mesh import Mesh
13
+ from zoomy_core.misc import misc as misc
13
14
 
14
15
 
15
16
  def create_default_mesh_and_model(
@@ -20,7 +21,8 @@ def create_default_mesh_and_model(
20
21
  parameters: Union[int, list, dict] = 0,
21
22
  settings: dict = {},
22
23
  ):
23
- main_dir = os.getenv("ZOOMY_DIR")
24
+ main_dir = misc.get_main_directory()
25
+
24
26
  assert main_dir != ""
25
27
  ic = IC.Constant()
26
28
 
@@ -5,9 +5,11 @@ from sympy import integrate, diff, Matrix
5
5
  from sympy.abc import z
6
6
  from time import time as get_time
7
7
 
8
+
8
9
  from scipy.optimize import least_squares as lsq
9
10
 
10
11
  from zoomy_core.model.models.basisfunctions import Legendre_shifted
12
+ from zoomy_core.misc import misc as misc
11
13
 
12
14
 
13
15
  class Basismatrices:
@@ -18,7 +20,8 @@ class Basismatrices:
18
20
  self.cache_subdir = f"basismatrices/{basis.name}/{basis.level}"
19
21
 
20
22
  def load_cached_matrices(self):
21
- main_dir = os.getenv("ZOOMY_DIR")
23
+ main_dir = misc.get_main_directory()
24
+
22
25
  path = os.path.join(os.path.join(main_dir, self.cache_dir), self.cache_subdir)
23
26
  failed = False
24
27
  try:
@@ -37,7 +40,8 @@ class Basismatrices:
37
40
  return failed
38
41
 
39
42
  def save_cached_matrices(self):
40
- main_dir = os.getenv("ZOOMY_DIR")
43
+ main_dir = misc.get_main_directory()
44
+
41
45
  path = os.path.join(os.path.join(main_dir, self.cache_dir), self.cache_subdir)
42
46
  os.makedirs(path, exist_ok=True)
43
47
  np.save(os.path.join(path, "phib"), self.phib)
File without changes
@@ -0,0 +1,244 @@
1
+ import os
2
+ import json
3
+ import meshio
4
+ import numpy as np
5
+ import matplotlib.pyplot as plt
6
+ from matplotlib.collections import PolyCollection
7
+
8
+
9
+ # ---------- I/O ----------
10
+
11
+
12
+ def read_vtk_or_series(path, index=0, verbose=True):
13
+ """Read either .vtk or .vtk.series (relative paths handled)."""
14
+ path = os.path.abspath(path)
15
+
16
+ if path.endswith(".vtk"):
17
+ if verbose:
18
+ print(f"📁 Reading single VTK file: {path}")
19
+ return meshio.read(path)
20
+
21
+ if path.endswith(".vtk.series"):
22
+ with open(path, "r") as f:
23
+ series = json.load(f)
24
+
25
+ entries = series.get("files", [])
26
+ files, times = [], []
27
+ for e in entries:
28
+ fname = e.get("name") or e.get("filename") or e.get("file")
29
+ if fname:
30
+ files.append(fname)
31
+ times.append(e.get("time", None))
32
+
33
+ if not files:
34
+ raise ValueError("No valid file entries found in .vtk.series.")
35
+
36
+ n_files = len(files)
37
+ if verbose:
38
+ print(f"📂 Loaded VTK series: {path}")
39
+ print(f" • Available indices: {n_files}")
40
+ if any(t is not None for t in times):
41
+ print(" • Time values:", [t for t in times if t is not None])
42
+ print(f" • Reading index {index}")
43
+
44
+ if not (0 <= index < n_files):
45
+ raise IndexError(f"Index {index} out of range (0..{n_files - 1})")
46
+
47
+ base_dir = os.path.dirname(path)
48
+ file_path = os.path.join(base_dir, files[index])
49
+ return meshio.read(file_path)
50
+
51
+ raise ValueError("Expected a .vtk or .vtk.series file")
52
+
53
+
54
+ # ---------- Field listing ----------
55
+
56
+
57
+ def list_available_fields(mesh, print_out=True):
58
+ """List all available point and cell fields."""
59
+ fields = {
60
+ "point_data": list(mesh.point_data.keys()),
61
+ "cell_data": list(mesh.cell_data_dict.keys()),
62
+ }
63
+
64
+ if print_out:
65
+ print("\n📊 Available fields:")
66
+ if fields["point_data"]:
67
+ print(" • Point data:")
68
+ for name in fields["point_data"]:
69
+ arr = mesh.point_data[name]
70
+ print(f" - {name} ({arr.shape})")
71
+ else:
72
+ print(" • Point data: none")
73
+
74
+ if fields["cell_data"]:
75
+ print(" • Cell data:")
76
+ for name in fields["cell_data"]:
77
+ entry = mesh.cell_data_dict[name]
78
+ types = ", ".join(entry.keys())
79
+ print(f" - {name} (types: {types})")
80
+ else:
81
+ print(" • Cell data: none")
82
+ print()
83
+
84
+ return fields
85
+
86
+
87
+ # ---------- Cell helpers ----------
88
+
89
+
90
+ def get_cell_block(mesh, types):
91
+ for block in mesh.cells:
92
+ if block.type in types:
93
+ return block
94
+ return None
95
+
96
+
97
+ def get_cell_field_for_block(mesh, field_name, cell_block):
98
+ """Get cell-centered data for the specified block."""
99
+ if cell_block is None:
100
+ return None
101
+ ctype = cell_block.type
102
+ if field_name is not None:
103
+ field = mesh.cell_data_dict.get(field_name)
104
+ if field is None:
105
+ return None
106
+ return field.get(ctype)
107
+ for name, mapping in mesh.cell_data_dict.items():
108
+ if ctype in mapping:
109
+ return mapping[ctype]
110
+ return None
111
+
112
+
113
+ # ---------- 1D Plotting ----------
114
+
115
+
116
+ def plot_1d_mesh(mesh, ax, field_name=None, **_):
117
+ """
118
+ Plot a 1D mesh as a line plot on the given Axes.
119
+ Returns (vmin, vmax) for consistency.
120
+ """
121
+ points = mesh.points
122
+ x = points[:, 0]
123
+
124
+ line_block = get_cell_block(mesh, ("line", "line3"))
125
+ if line_block is not None:
126
+ connectivity = line_block.data
127
+ unique_order = []
128
+ for conn in connectivity:
129
+ for i in conn:
130
+ if i not in unique_order:
131
+ unique_order.append(i)
132
+ x = x[unique_order]
133
+
134
+ y = None
135
+ field_data = get_cell_field_for_block(mesh, field_name, line_block)
136
+ if field_data is not None:
137
+ cell_centers = np.array(
138
+ [np.mean(mesh.points[cell, 0]) for cell in line_block.data]
139
+ )
140
+ y = np.interp(x, cell_centers, field_data)
141
+ elif field_name and field_name in mesh.point_data:
142
+ y = mesh.point_data[field_name]
143
+ elif mesh.point_data:
144
+ field_name, y = next(iter(mesh.point_data.items()))
145
+
146
+ if y is None:
147
+ y = np.zeros_like(x)
148
+ field_name = field_name or "default"
149
+
150
+ ax.plot(x, y, "-o", markersize=3)
151
+ return float(np.min(y)), float(np.max(y))
152
+
153
+
154
+ # ---------- 2D Plotting ----------
155
+
156
+
157
+ def plot_2d_mesh(
158
+ mesh,
159
+ ax,
160
+ field_name=None,
161
+ show_legend=True,
162
+ legend_location="right",
163
+ cmap="viridis",
164
+ ):
165
+ """
166
+ Plot a 2D mesh (unstructured) using meshio connectivity.
167
+ Adds polygons to the provided Axes.
168
+ Returns (vmin, vmax).
169
+ """
170
+ points = mesh.points[:, :2]
171
+ cell_block = get_cell_block(mesh, ("triangle", "quad", "polygon"))
172
+ if cell_block is None:
173
+ raise ValueError("No 2D cells found.")
174
+
175
+ connectivity = cell_block.data
176
+ field_data = get_cell_field_for_block(mesh, field_name, cell_block)
177
+ if field_data is None:
178
+ field_data = np.zeros(len(connectivity))
179
+ field_name = field_name or "default"
180
+
181
+ polygons = [points[cell] for cell in connectivity]
182
+ vmin, vmax = float(field_data.min()), float(field_data.max())
183
+ if vmin == vmax:
184
+ vmin, vmax = vmin - 0.5, vmax + 0.5
185
+
186
+ coll = PolyCollection(
187
+ polygons,
188
+ array=field_data,
189
+ cmap=cmap,
190
+ norm=plt.Normalize(vmin=vmin, vmax=vmax),
191
+ edgecolors="k",
192
+ linewidths=0.2,
193
+ )
194
+ ax.add_collection(coll)
195
+ ax.autoscale()
196
+ ax.set_aspect("equal")
197
+
198
+ if show_legend:
199
+ if legend_location == "bottom":
200
+ cbar = plt.colorbar(
201
+ coll, ax=ax, orientation="horizontal", fraction=0.05, pad=0.05
202
+ )
203
+ else: # right
204
+ cbar = plt.colorbar(coll, ax=ax)
205
+ cbar.set_label(field_name)
206
+
207
+ return vmin, vmax
208
+
209
+
210
+ # ---------- Auto Dispatch ----------
211
+
212
+
213
+ def plot_mesh(
214
+ mesh,
215
+ ax,
216
+ field_name=None,
217
+ show_legend=True,
218
+ legend_location="right",
219
+ ):
220
+ """
221
+ Auto-detect mesh type (1D or 2D) and plot on the provided Axes.
222
+ Returns (vmin, vmax).
223
+ """
224
+ has_2d = get_cell_block(mesh, ("triangle", "quad", "polygon")) is not None
225
+ has_1d = get_cell_block(mesh, ("line", "line3")) is not None
226
+
227
+ if has_2d:
228
+ return plot_2d_mesh(mesh, ax, field_name, show_legend, legend_location)
229
+ elif has_1d:
230
+ return plot_1d_mesh(mesh, ax, field_name)
231
+ else:
232
+ raise ValueError(f"Unsupported mesh types: {[c.type for c in mesh.cells]}")
233
+
234
+
235
+ # # ---------- Example ----------
236
+
237
+ # if __name__ == "__main__":
238
+ # mesh = read_vtk_or_series("outputs/swe/out.vtk.series", index=0)
239
+ # list_available_fields(mesh)
240
+
241
+ # fig, ax = plt.subplots(figsize=(5, 4))
242
+ # vmin, vmax = plot_mesh(mesh, ax, field_name=None, show_legend=True, legend_location="right")
243
+ # print(f"Color range: {vmin:.3g} – {vmax:.3g}")
244
+ # plt.show()
@@ -12,6 +12,8 @@ import zoomy_core.mesh.mesh as petscMesh
12
12
  import zoomy_core.misc.io as io
13
13
  from zoomy_core.misc.logger_config import logger
14
14
  from zoomy_core.transformation.to_numpy import NumpyRuntimeModel
15
+ from zoomy_core.misc import misc as misc
16
+
15
17
 
16
18
  def vtk_project_2d_to_3d(
17
19
  model, settings, start_at_time=0, scale_h=1.0, filename='out_3d'
@@ -19,7 +21,8 @@ def vtk_project_2d_to_3d(
19
21
  if not _HAVE_H5PY:
20
22
  raise ImportError("h5py is required for vtk_project_2d_to_3d function.")
21
23
  Nz = model.number_of_points_3d
22
- main_dir = os.getenv("ZOOMY_DIR")
24
+ main_dir = misc.get_main_directory()
25
+
23
26
  path_to_simulation = os.path.join(main_dir, os.path.join(settings.output.directory, f"{settings.output.filename}.h5"))
24
27
  sim = h5py.File(path_to_simulation, "r")
25
28
  settings = io.load_settings(settings.output.directory)
File without changes
@@ -21,7 +21,8 @@ from zoomy_core.misc.io import _save_fields_to_hdf5 as save_fields_to_hdf5
21
21
  import zoomy_core.misc.io as io
22
22
 
23
23
 
24
- main_dir = os.getenv("ZOOMY_DIR")
24
+ main_dir = misc.get_main_directory()
25
+
25
26
 
26
27
 
27
28
  def load_file(filename):
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
 
6
6
  [project]
7
7
  name = "zoomy_core"
8
- version = "0.1.11"
8
+ version = "0.1.14"
9
9
  description = "A simulation software for dimensionally-reduced free surface flows."
10
10
  readme = "README.md"
11
11
  requires-python = ">=3.9"
@@ -71,7 +71,6 @@ Issues = "https://github.com/mbd-rwth/Zoomy/issues"
71
71
 
72
72
 
73
73
  [tool.setuptools.packages.find]
74
- where = ["library"]
75
- include = ["zoomy_core*"]
74
+ include = ["*"]
76
75
 
77
76
 
File without changes
@@ -4,6 +4,8 @@ import sympy as sp
4
4
  from copy import deepcopy
5
5
 
6
6
  from zoomy_core.misc.misc import Zstruct
7
+ from zoomy_core.misc import misc as misc
8
+
7
9
  from zoomy_core.model.sympy2c import create_module
8
10
  from zoomy_core.transformation.helpers import regularize_denominator, substitute_sympy_attributes_with_symbol_matrix
9
11
 
@@ -230,7 +232,8 @@ class AmrexPrinter(CXX11CodePrinter):
230
232
  def write_code(model, settings):
231
233
  printer = AmrexPrinter(model)
232
234
  expr = printer.create_model(model)
233
- main_dir = os.getenv("ZOOMY_DIR")
235
+ main_dir = misc.get_main_directory()
236
+
234
237
  path = os.path.join(main_dir, settings.output.directory, ".amrex_interface")
235
238
  os.makedirs(path, exist_ok=True)
236
239
  path = os.path.join(path, "Model.h")
@@ -4,6 +4,9 @@ import textwrap
4
4
  import sympy as sp
5
5
  from sympy.printing.cxx import CXX11CodePrinter
6
6
 
7
+ from zoomy_core.misc import misc as misc
8
+
9
+
7
10
  class CPrinter(CXX11CodePrinter):
8
11
  """
9
12
  Convert SymPy expressions to C code.
@@ -173,7 +176,8 @@ inline double* {name}(
173
176
  def write_code(model, settings):
174
177
  printer = CPrinter(model)
175
178
  code = printer.create_model(model)
176
- main_dir = os.getenv("ZOOMY_DIR")
179
+ main_dir = misc.get_main_directory()
180
+
177
181
  path = os.path.join(main_dir, settings.output.directory, ".c_interface")
178
182
  os.makedirs(path, exist_ok=True)
179
183
  file_path = os.path.join(path, "Model.H")
@@ -50,39 +50,42 @@ class NumpyRuntimeModel:
50
50
  def __attrs_post_init__(self):
51
51
  model = self.model
52
52
 
53
+ modules = [self.module]
54
+ if self.printer:
55
+ modules.append(self.printer)
53
56
 
54
- flux=model._flux.lambdify(modules=[self.module, self.printer])
55
- dflux=model._dflux.lambdify(modules=[self.module, self.printer])
57
+ flux=model._flux.lambdify(modules=modules)
58
+ dflux=model._dflux.lambdify(modules=modules)
56
59
  nonconservative_matrix=model._nonconservative_matrix.lambdify(
57
- modules=[self.module, self.printer]
60
+ modules=modules
58
61
  )
59
62
  quasilinear_matrix=model._quasilinear_matrix.lambdify(
60
- modules=[self.module, self.printer]
63
+ modules=modules
61
64
  )
62
65
  eigenvalues=model._eigenvalues.lambdify(
63
- modules=[self.module, self.printer]
66
+ modules=modules
64
67
  )
65
68
  left_eigenvectors=model._left_eigenvectors.lambdify(
66
- modules=[self.module, self.printer]
69
+ modules=modules
67
70
  )
68
71
  right_eigenvectors=model._right_eigenvectors.lambdify(
69
- modules=[self.module, self.printer]
72
+ modules=modules
70
73
  )
71
- source=model._source.lambdify(modules=[self.module, self.printer])
74
+ source=model._source.lambdify(modules=modules)
72
75
  source_jacobian_wrt_variables=model._source_jacobian_wrt_variables.lambdify(
73
- modules=[self.module, self.printer]
76
+ modules=modules
74
77
  )
75
78
  source_jacobian_wrt_aux_variables=model._source_jacobian_wrt_aux_variables.lambdify(
76
- modules=[self.module, self.printer]
79
+ modules=modules
77
80
  )
78
- residual=model._residual.lambdify(modules=[self.module, self.printer])
81
+ residual=model._residual.lambdify(modules=modules)
79
82
  project_2d_to_3d=model._project_2d_to_3d.lambdify(
80
- modules=[self.module, self.printer]
83
+ modules=modules
81
84
  )
82
85
  project_3d_to_2d=model._project_3d_to_2d.lambdify(
83
- modules=[self.module, self.printer]
86
+ modules=modules
84
87
  )
85
- bcs = model._boundary_conditions.lambdify(modules=[self.module, self.printer])
88
+ bcs = model._boundary_conditions.lambdify(modules=modules)
86
89
 
87
90
 
88
91
  # --- Assign frozen fields -------------------------------------