zoomy-core 0.1.0__py3-none-any.whl → 0.1.2__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.

Potentially problematic release.


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

Files changed (57) hide show
  1. zoomy_core/decorators/decorators.py +25 -0
  2. zoomy_core/fvm/flux.py +97 -0
  3. zoomy_core/fvm/nonconservative_flux.py +97 -0
  4. zoomy_core/fvm/ode.py +55 -0
  5. zoomy_core/fvm/solver_numpy.py +305 -0
  6. zoomy_core/fvm/timestepping.py +13 -0
  7. zoomy_core/mesh/gmsh_loader.py +301 -0
  8. zoomy_core/mesh/mesh.py +1192 -0
  9. zoomy_core/mesh/mesh_extrude.py +168 -0
  10. zoomy_core/mesh/mesh_util.py +487 -0
  11. zoomy_core/misc/custom_types.py +6 -0
  12. zoomy_core/misc/gui.py +61 -0
  13. zoomy_core/misc/interpolation.py +140 -0
  14. zoomy_core/misc/io.py +401 -0
  15. zoomy_core/misc/logger_config.py +18 -0
  16. zoomy_core/misc/misc.py +216 -0
  17. zoomy_core/misc/static_class.py +94 -0
  18. zoomy_core/model/analysis.py +147 -0
  19. zoomy_core/model/basefunction.py +113 -0
  20. zoomy_core/model/basemodel.py +512 -0
  21. zoomy_core/model/boundary_conditions.py +193 -0
  22. zoomy_core/model/initial_conditions.py +171 -0
  23. zoomy_core/model/model.py +63 -0
  24. zoomy_core/model/models/GN.py +70 -0
  25. zoomy_core/model/models/advection.py +53 -0
  26. zoomy_core/model/models/basisfunctions.py +181 -0
  27. zoomy_core/model/models/basismatrices.py +377 -0
  28. zoomy_core/model/models/core.py +564 -0
  29. zoomy_core/model/models/coupled_constrained.py +60 -0
  30. zoomy_core/model/models/old_smm copy.py +867 -0
  31. zoomy_core/model/models/poisson.py +41 -0
  32. zoomy_core/model/models/shallow_moments.py +757 -0
  33. zoomy_core/model/models/shallow_moments_sediment.py +378 -0
  34. zoomy_core/model/models/shallow_moments_topo.py +423 -0
  35. zoomy_core/model/models/shallow_moments_variants.py +1509 -0
  36. zoomy_core/model/models/shallow_water.py +266 -0
  37. zoomy_core/model/models/shallow_water_topo.py +111 -0
  38. zoomy_core/model/models/shear_shallow_flow.py +594 -0
  39. zoomy_core/model/models/sme_turbulent.py +613 -0
  40. zoomy_core/model/models/swe_old.py +1018 -0
  41. zoomy_core/model/models/vam.py +455 -0
  42. zoomy_core/postprocessing/postprocessing.py +72 -0
  43. zoomy_core/preprocessing/openfoam_moments.py +452 -0
  44. zoomy_core/transformation/helpers.py +25 -0
  45. zoomy_core/transformation/to_amrex.py +238 -0
  46. zoomy_core/transformation/to_c.py +181 -0
  47. zoomy_core/transformation/to_jax.py +14 -0
  48. zoomy_core/transformation/to_numpy.py +115 -0
  49. zoomy_core/transformation/to_openfoam.py +254 -0
  50. zoomy_core/transformation/to_ufl.py +67 -0
  51. {zoomy_core-0.1.0.dist-info → zoomy_core-0.1.2.dist-info}/METADATA +1 -1
  52. zoomy_core-0.1.2.dist-info/RECORD +55 -0
  53. zoomy_core-0.1.2.dist-info/top_level.txt +1 -0
  54. zoomy_core-0.1.0.dist-info/RECORD +0 -5
  55. zoomy_core-0.1.0.dist-info/top_level.txt +0 -1
  56. {zoomy_core-0.1.0.dist-info → zoomy_core-0.1.2.dist-info}/WHEEL +0 -0
  57. {zoomy_core-0.1.0.dist-info → zoomy_core-0.1.2.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,377 @@
1
+ import os
2
+ import numpy as np
3
+ import sympy
4
+ from sympy import integrate, diff, Matrix
5
+ from sympy.abc import z
6
+ from time import time as get_time
7
+
8
+ from scipy.optimize import least_squares as lsq
9
+
10
+ from library.zoomy_core.model.models.basisfunctions import Legendre_shifted
11
+
12
+
13
+ class Basismatrices:
14
+ def __init__(self, basis=Legendre_shifted(), use_cache=True, cache_path=".cache"):
15
+ self.basisfunctions = basis
16
+ self.use_cache = use_cache
17
+ self.cache_dir = cache_path
18
+ self.cache_subdir = f"basismatrices/{basis.name}/{basis.level}"
19
+
20
+ def load_cached_matrices(self):
21
+ main_dir = os.getenv("ZOOMY_DIR")
22
+ path = os.path.join(os.path.join(main_dir, self.cache_dir), self.cache_subdir)
23
+ failed = False
24
+ try:
25
+ self.phib = np.load(os.path.join(path, "phib.npy"))
26
+ self.M = np.load(os.path.join(path, "M.npy"))
27
+ self.A = np.load(os.path.join(path, "A.npy"))
28
+ self.B = np.load(os.path.join(path, "B.npy"))
29
+ self.D = np.load(os.path.join(path, "D.npy"))
30
+ self.Dxi = np.load(os.path.join(path, "Dxi.npy"))
31
+ self.Dxi2 = np.load(os.path.join(path, "Dxi2.npy"))
32
+ self.DD = np.load(os.path.join(path, "DD.npy"))
33
+ self.D1 = np.load(os.path.join(path, "D1.npy"))
34
+ self.DT = np.load(os.path.join(path, "DT.npy"))
35
+ except:
36
+ failed = True
37
+ return failed
38
+
39
+ def save_cached_matrices(self):
40
+ main_dir = os.getenv("ZOOMY_DIR")
41
+ path = os.path.join(os.path.join(main_dir, self.cache_dir), self.cache_subdir)
42
+ os.makedirs(path, exist_ok=True)
43
+ np.save(os.path.join(path, "phib"), self.phib)
44
+ np.save(os.path.join(path, "M"), self.M)
45
+ np.save(os.path.join(path, "A"), self.A)
46
+ np.save(os.path.join(path, "B"), self.B)
47
+ np.save(os.path.join(path, "D"), self.D)
48
+ np.save(os.path.join(path, "Dxi"), self.Dxi)
49
+ np.save(os.path.join(path, "Dxi2"), self.Dxi2)
50
+ np.save(os.path.join(path, "DD"), self.DD)
51
+ np.save(os.path.join(path, "D1"), self.D1)
52
+ np.save(os.path.join(path, "DT"), self.DT)
53
+
54
+
55
+
56
+ def _compute_matrices(self, level):
57
+ start = get_time()
58
+ # object is key here, as we need to have a symbolic representation of the fractions.
59
+ self.phib = np.empty((level + 1), dtype=object)
60
+ self.M = np.empty((level + 1, level + 1), dtype=object)
61
+ self.A = np.empty((level + 1, level + 1, level + 1), dtype=object)
62
+ self.B = np.empty((level + 1, level + 1, level + 1), dtype=object)
63
+ self.D = np.empty((level + 1, level + 1), dtype=object)
64
+ self.Dxi = np.empty((level + 1, level + 1), dtype=object)
65
+ self.Dxi2 = np.empty((level + 1, level + 1), dtype=object)
66
+
67
+ self.DD = np.empty((level + 1, level + 1), dtype=object)
68
+ self.D1 = np.empty((level + 1, level + 1), dtype=object)
69
+ self.DT = np.empty((level + 1, level + 1, level + 1), dtype=object)
70
+
71
+ for k in range(level + 1):
72
+ self.phib[k] = self._phib(k)
73
+ for i in range(level + 1):
74
+ self.M[k, i] = self._M(k, i)
75
+ self.D[k, i] = self._D(k, i)
76
+ self.Dxi[k, i] = self._Dxi(k, i)
77
+ self.Dxi2[k, i] = self._Dxi2(k, i)
78
+
79
+ self.DD[k, i] = self._DD(k, i)
80
+ self.D1[k, i] = self._D1(k, i)
81
+ for j in range(level + 1):
82
+ self.A[k, i, j] = self._A(k, i, j)
83
+ self.B[k, i, j] = self._B(k, i, j)
84
+ self.DT[k, i, j] = self._DT(k, i, j)
85
+
86
+
87
+ def compute_matrices(self, level):
88
+ failed = True
89
+ if self.use_cache:
90
+ failed = self.load_cached_matrices()
91
+ if failed or (not self.use_cache):
92
+ self._compute_matrices(level)
93
+ self.save_cached_matrices()
94
+
95
+ def enforce_boundary_conditions_lsq(self, rhs=np.zeros(2), dim=1):
96
+ level = len(self.basisfunctions.basis) - 1
97
+ constraint_bottom = [self.basisfunctions.eval(i, 0.0) for i in range(level + 1)]
98
+ constraint_top = [
99
+ diff(self.basisfunctions.eval(i, z), z).subs(z, 1.0)
100
+ for i in range(level + 1)
101
+ ]
102
+ A = Matrix([constraint_bottom, constraint_top])
103
+
104
+ I = np.linspace(0, level, 1 + level, dtype=int)
105
+ I_enforce = I[1:]
106
+ rhs = np.zeros(2)
107
+ # rhs = np.zeros(level)
108
+ I_free = np.delete(I, I_enforce)
109
+ A_enforce = A[:, list(I_enforce)]
110
+ A_free = np.array(A[:, list(I_free)], dtype=float)
111
+ AtA = A_enforce.T @ A_enforce
112
+ reg = 10 ** (-6)
113
+ A_enforce_inv = np.array((AtA + reg * np.eye(AtA.shape[0])).inv(), dtype=float)
114
+
115
+ def f_1d(Q):
116
+ for i, q in enumerate(Q.T):
117
+ # alpha_enforce = q[I_enforce+1]
118
+ alpha_free = q[I_free + 1]
119
+ b = rhs - np.dot(A_free, alpha_free)
120
+ # b = rhs
121
+ result = np.dot(A_enforce_inv, A_enforce.T @ b)
122
+ alpha = 1.0
123
+ Q[I_enforce + 1, i] = (1 - alpha) * Q[I_enforce + 1, i] + (
124
+ alpha
125
+ ) * result
126
+ return Q
127
+
128
+ def f_2d(Q):
129
+ i1 = [[0] + [i + 1 for i in range(1 + level)]]
130
+ i2 = [[0] + [i + 1 + 1 + level for i in range(1 + level)]]
131
+ Q1 = Q[i1]
132
+ Q2 = Q[i2]
133
+ Q1 = f_1d(Q1)
134
+ Q2 = f_1d(Q2)
135
+ Q[i1] = Q1
136
+ Q[i2] = Q2
137
+ return Q
138
+
139
+ if dim == 1:
140
+ return f_1d
141
+ elif dim == 2:
142
+ return f_2d
143
+ else:
144
+ assert False
145
+
146
+ def enforce_boundary_conditions_lsq2(self, rhs=np.zeros(2), dim=1):
147
+ level = len(self.basisfunctions.basis) - 1
148
+ constraint_bottom = [self.basisfunctions.eval(i, 0.0) for i in range(level + 1)]
149
+ constraint_top = [
150
+ diff(self.basisfunctions.eval(i, z), z).subs(z, 1.0)
151
+ for i in range(level + 1)
152
+ ]
153
+ A = Matrix([constraint_bottom, constraint_top])
154
+
155
+ I = np.linspace(0, level, 1 + level, dtype=int)
156
+ I_enforce = I[1:]
157
+ rhs = np.zeros(2)
158
+ # rhs = np.zeros(level)
159
+ I_free = np.delete(I, I_enforce)
160
+ A_enforce = A[:, list(I_enforce)]
161
+ A_free = np.array(A[:, list(I_free)], dtype=float)
162
+
163
+ def obj(alpha0, lam):
164
+ def f(alpha):
165
+ return np.sum((alpha - alpha0) ** 2) + lam * np.sum(
166
+ np.array(np.dot(A, alpha) ** 2, dtype=float)
167
+ )
168
+
169
+ return f
170
+
171
+ def f_1d(Q):
172
+ for i, q in enumerate(Q.T):
173
+ h = q[0]
174
+ alpha = q[1:] / h
175
+ f = obj(alpha, 0.1)
176
+ result = lsq(f, alpha)
177
+ Q[1:, i] = h * result.z
178
+ return Q
179
+
180
+ def f_2d(Q):
181
+ i1 = [[0] + [i + 1 for i in range(1 + level)]]
182
+ i2 = [[0] + [i + 1 + 1 + level for i in range(1 + level)]]
183
+ Q1 = Q[i1]
184
+ Q2 = Q[i2]
185
+ Q1 = f_1d(Q1)
186
+ Q2 = f_1d(Q2)
187
+ Q[i1] = Q1
188
+ Q[i2] = Q2
189
+ return Q
190
+
191
+ if dim == 1:
192
+ return f_1d
193
+ elif dim == 2:
194
+ return f_2d
195
+ else:
196
+ assert False
197
+
198
+ def enforce_boundary_conditions(
199
+ self, enforced_basis=[-2, -1], rhs=np.zeros(2), dim=1
200
+ ):
201
+ level = len(self.basisfunctions.basis) - 1
202
+ constraint_bottom = [self.basisfunctions.eval(i, 0.0) for i in range(level + 1)]
203
+ constraint_top = [
204
+ diff(self.basisfunctions.eval(i, z), z).subs(z, 1.0)
205
+ for i in range(level + 1)
206
+ ]
207
+ A = Matrix([constraint_bottom, constraint_top][: len(enforced_basis)])
208
+
209
+ # test to only constrain bottom
210
+ # A = Matrix([constraint_bottom])
211
+ # enforced_basis = [-1]
212
+ # rhs=np.zeros(1)
213
+
214
+ I = np.linspace(0, level, 1 + level, dtype=int)
215
+ I_enforce = I[enforced_basis]
216
+ I_free = np.delete(I, I_enforce)
217
+ A_enforce = A[:, list(I_enforce)]
218
+ A_free = np.array(A[:, list(I_free)], dtype=float)
219
+ A_enforce_inv = np.array(A_enforce.inv(), dtype=float)
220
+
221
+ def f_1d(Q):
222
+ for i, q in enumerate(Q.T):
223
+ alpha_enforce = q[I_enforce + 1]
224
+ alpha_free = q[I_free + 1]
225
+ b = rhs - np.dot(A_free, alpha_free)
226
+ result = np.dot(A_enforce_inv, b)
227
+ alpha = 1.0
228
+ Q[I_enforce + 1, i] = (1 - alpha) * Q[I_enforce + 1, i] + (
229
+ alpha
230
+ ) * result
231
+ return Q
232
+
233
+ def f_2d(Q):
234
+ i1 = [[0] + [i + 1 for i in range(1 + level)]]
235
+ i2 = [[0] + [i + 1 + 1 + level for i in range(1 + level)]]
236
+ Q1 = Q[i1]
237
+ Q2 = Q[i2]
238
+ Q1 = f_1d(Q1)
239
+ Q2 = f_1d(Q2)
240
+ Q[i1] = Q1
241
+ Q[i2] = Q2
242
+ return Q
243
+
244
+ if dim == 1:
245
+ return f_1d
246
+ elif dim == 2:
247
+ return f_2d
248
+ else:
249
+ assert False
250
+
251
+ """
252
+ Compute phi_k(@xi=0)
253
+ """
254
+
255
+ def _phib(self, k):
256
+ return self.basisfunctions.eval(k, self.basisfunctions.bounds()[0])
257
+
258
+ """
259
+ Compute <phi_k, phi_i>
260
+ """
261
+
262
+ def _M(self, k, i):
263
+ return integrate(
264
+ self.basisfunctions.weight(z) * self.basisfunctions.eval(k, z) * self.basisfunctions.eval(i, z), (z, self.basisfunctions.bounds()[0], self.basisfunctions.bounds()[1])
265
+ )
266
+
267
+ """
268
+ Compute <phi_k, phi_i, phi_j>
269
+ """
270
+
271
+ def _A(self, k, i, j):
272
+ return integrate(
273
+ self.basisfunctions.weight(z) * self.basisfunctions.eval(k, z)
274
+ * self.basisfunctions.eval(i, z)
275
+ * self.basisfunctions.eval(j, z),
276
+ (z, self.basisfunctions.bounds()[0], self.basisfunctions.bounds()[1]),
277
+ )
278
+
279
+ """
280
+ Compute <(phi')_k, phi_j, int(phi)_j>
281
+ """
282
+
283
+ def _B(self, k, i, j):
284
+ return integrate(
285
+ self.basisfunctions.weight(z) * diff(self.basisfunctions.eval(k, z), z)
286
+ * integrate(self.basisfunctions.eval(j, z), z)
287
+ * self.basisfunctions.eval(i, z),
288
+ (z, self.basisfunctions.bounds()[0], self.basisfunctions.bounds()[1]),
289
+ )
290
+
291
+ """
292
+ Compute <(phi')_k, (phi')_j>
293
+ """
294
+
295
+ def _D(self, k, i):
296
+ return integrate(
297
+ self.basisfunctions.weight(z) * diff(self.basisfunctions.eval(k, z), z)
298
+ * diff(self.basisfunctions.eval(i, z), z),
299
+ (z, self.basisfunctions.bounds()[0], self.basisfunctions.bounds()[1]),
300
+ )
301
+
302
+ """
303
+ Compute <(phi')_k, (phi')_j * xi>
304
+ """
305
+ def _Dxi(self, k, i):
306
+ return integrate(
307
+ self.basisfunctions.weight(z) * diff(self.basisfunctions.eval(k, z), z)
308
+ * diff(self.basisfunctions.eval(i, z), z) * z,
309
+ (z, self.basisfunctions.bounds()[0], self.basisfunctions.bounds()[1]),
310
+ )
311
+ """
312
+ Compute <(phi')_k, (phi')_j * xi**2>
313
+ """
314
+ def _Dxi2(self, k, i):
315
+ return integrate(
316
+ self.basisfunctions.weight(z) * diff(self.basisfunctions.eval(k, z), z)
317
+ * diff(self.basisfunctions.eval(i, z), z) * z * z,
318
+ (z, self.basisfunctions.bounds()[0], self.basisfunctions.bounds()[1]),
319
+ )
320
+
321
+ """
322
+ Compute <(phi)_k, (phi')_j>
323
+ """
324
+
325
+ def _D1(self, k, i):
326
+ return integrate(
327
+ self.basisfunctions.weight(z) * self.basisfunctions.eval(k, z) * diff(self.basisfunctions.eval(i, z), z),
328
+ (z, self.basisfunctions.bounds()[0], self.basisfunctions.bounds()[1]),
329
+ )
330
+
331
+ """
332
+ Compute <(phi)_k, (phi'')_j>
333
+ """
334
+
335
+ def _DD(self, k, i):
336
+ return integrate(
337
+ self.basisfunctions.weight(z) * self.basisfunctions.eval(k, z)
338
+ * diff(diff(self.basisfunctions.eval(i, z), z), z),
339
+ (z, self.basisfunctions.bounds()[0], self.basisfunctions.bounds()[1]),
340
+ )
341
+
342
+ """
343
+
344
+ Compute <(phi')_k, (phi')_j>
345
+ """
346
+
347
+ def _DT(self, k, i, j):
348
+ return integrate(
349
+ self.basisfunctions.weight(z) * diff(self.basisfunctions.eval(k, z), z)
350
+ * diff(self.basisfunctions.eval(i, z), z)
351
+ * self.basisfunctions.eval(j, z),
352
+ (z, self.basisfunctions.bounds()[0], self.basisfunctions.bounds()[1]),
353
+ )
354
+
355
+
356
+ class BasisNoHOM(Basismatrices):
357
+ def _A(self, k, i, j):
358
+ count = 0
359
+ # count += float(k > 0)
360
+ count += float(i > 0)
361
+ count += float(j > 0)
362
+ # if count > 1:
363
+ if (i == 0 and j == k) or (j == 0 and i == k) or (k == 0 and i == j):
364
+ return super()._A(k, i, j)
365
+ return 0
366
+
367
+ def _B(self, k, i, j):
368
+ count = 0
369
+ # count += float(k > 0)
370
+ count += float(i > 0)
371
+ count += float(j > 0)
372
+ # if count > 1:
373
+ # if not (i==0 or j==0):
374
+ if (i == 0 and j == k) or (j == 0 and i == k) or (k == 0 and i == j):
375
+ return super()._B(k, i, j)
376
+ return 0
377
+ # return super()._B(k, i, j)