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