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

@@ -1,1018 +0,0 @@
1
- # import numpy as np
2
- # import os
3
- # import logging
4
-
5
-
6
- # from library.solver.baseclass import BaseYaml
7
- # from library.solver.models.base import *
8
- # from library.solver.boundary_conditions import *
9
- # import library.solver.initial_condition as initial_condition
10
- # import library.solver.smm_model as smm
11
- # import library.solver.smm_model_hyperbolic as smmh
12
- # import library.solver.smm_model_exner as smm_exner
13
- # import library.solver.smm_model_exner_hyperbolic as smm_exner_hyper
14
-
15
- # import sympy
16
- # from sympy import Symbol, Matrix, lambdify
17
- # from sympy import zeros, ones
18
-
19
- # main_dir = os.getenv("SMPYTHON")
20
-
21
-
22
- # class ShallowWater(Model):
23
- # yaml_tag = "!ShallowWater"
24
-
25
- # def set_default_default_parameters(self):
26
- # super().set_default_default_parameters()
27
- # self.n_variables = 2
28
-
29
- # def set_runtime_variables(self):
30
- # super().set_runtime_variables()
31
-
32
- # def flux(self, Q):
33
- # h = Q[0]
34
- # hu = Q[1]
35
- # u = hu / h
36
- # return np.array([hu, hu * u + self.g * self.ez * h * h / 2]).reshape(
37
- # 2, 1, Q.shape[1]
38
- # )
39
-
40
- # def flux_jacobian(self, Q):
41
- # out = np.zeros((Q.shape[0], Q.shape[0], self.dimension, Q.shape[1]))
42
- # h = Q[0]
43
- # u = Q[1] / Q[0]
44
- # # dF1_dh=0
45
- # # dF1_dhu
46
- # out[0, 1, 0] = 1.0
47
- # # dF2_dh
48
- # out[1, 0, 0] = -u * u + self.g * h
49
- # # dF2_dhu
50
- # out[1, 1, 0] = 2 * u
51
- # return out
52
-
53
- # def eigenvalues(self, Q, nij):
54
- # imaginary = False
55
- # h = Q[0]
56
- # hu = Q[1]
57
- # u = hu / h
58
- # assert (h > 0).all()
59
- # c = np.sqrt(self.g * h)
60
- # return np.array([u - c, u + c]), imaginary
61
-
62
- # def rhs(self, t, Q, **kwargs):
63
- # output = np.zeros_like(Q)
64
- # # Topography
65
- # dHdx = kwargs["aux_variables"]["dHdx"]
66
- # h = Q[0]
67
- # output[1] = h * self.g * (self.ex - self.ez * dHdx)
68
-
69
- # # Friction
70
- # for friction in self.friction_models:
71
- # output += getattr(self, friction)(t, Q, **kwargs)
72
-
73
- # return output
74
-
75
- # def rhs_jacobian(self, t, Q, **kwargs):
76
- # # vectorized or single element?
77
- # if len(Q.shape) == 2:
78
- # output = np.zeros((Q.shape[0], Q.shape[0], Q.shape[1]))
79
-
80
- # # Topography
81
- # dHdx = kwargs["aux_variables"]["dHdx"]
82
- # h = Q[0]
83
- # # dR1_dh=0
84
- # # dR1_dhu=0
85
- # # dR2_dh
86
- # output[1, 0] = self.g * (self.ex - self.ez * dHdx)
87
- # # dR2_dhu=0
88
-
89
- # # Friction
90
- # for friction in self.friction_models:
91
- # output += getattr(self, friction + "_jacobian")(t, Q, **kwargs)
92
-
93
- # return output
94
-
95
- # def newtonian(self, t, Q, **kwargs):
96
- # output = np.zeros_like(Q)
97
- # h = Q[0]
98
- # u = Q[1] / Q[0]
99
- # nu = self.parameters["nu"]
100
- # output[1] = -nu * u
101
- # return output
102
-
103
- # def newtonian_jacobian(self, t, Q, **kwargs):
104
- # # vectorized?
105
- # if len(Q.shape) == 2:
106
- # output = np.zeros((Q.shape[0], Q.shape[0], Q.shape[1]))
107
- # else:
108
- # output = np.zeros((Q.shape[0], Q.shape[0]))
109
- # nu = self.parameters["nu"]
110
- # h = Q[0]
111
- # u_inv = Q[0] / Q[1]
112
- # # dR1_dh=0
113
- # # dR1_dhu=0
114
- # # dR2_dh
115
- # output[1, 0] = nu * u_inv * u_inv
116
- # # dR2_dhu=0
117
- # output[1, 1] = -nu / h
118
- # return output
119
-
120
- # def manning(
121
- # self, t, Q, **kwargs
122
- # ): # Manning Friction defined as per: https://agupubs.onlinelibrary.wiley.com/doi/full/10.1002/wrcr.20366
123
- # output = np.zeros_like(Q)
124
- # h = Q[0]
125
- # u = Q[1] / Q[0]
126
- # nu = self.parameters["nu"]
127
- # output[1] = -self.g * (nu**2) * Q[1] * np.abs(Q[1]) / Q[0] ** (7 / 3)
128
- # return output
129
-
130
- # def primitive_variables(self, Q):
131
- # h = Q[0]
132
- # hu = Q[1]
133
- # u = hu / h
134
- # return np.array([h, u])
135
-
136
- # def conservative_variables(self, U):
137
- # h = U[0]
138
- # u = U[1]
139
- # return np.array([h, h * u])
140
-
141
-
142
- # class ShallowWaterWithBottom(Model):
143
- # yaml_tag = "!ShallowWaterWithBottom"
144
-
145
- # def set_default_default_parameters(self):
146
- # super().set_default_default_parameters()
147
- # self.n_variables = 3
148
-
149
- # def set_runtime_variables(self):
150
- # super().set_runtime_variables()
151
-
152
- # def flux(self, Q):
153
- # h = Q[0]
154
- # hu = Q[1]
155
- # h = np.where(h <= 0.0, 0.0, h)
156
- # u = np.where(h <= 0.0, 0.0, hu / h)
157
- # return np.array([hu, hu * u + self.g * self.ez * h * h / 2, np.zeros_like(h)])
158
-
159
- # def flux_jacobian(self, Q):
160
- # out = np.zeros((Q.shape[0], Q.shape[0], self.dimension, Q.shape[1]))
161
- # h = Q[0]
162
- # hu = Q[1]
163
- # h = np.where(h <= 0.0, 0.0, h)
164
- # u = np.where(h <= 0.0, 0.0, hu / h)
165
- # # dF1_dh=0
166
- # # dF1_dhu
167
- # out[0, 1, 0] = 1.0
168
- # # dF1_dh_b = 0
169
- # # dF2_dh
170
- # out[1, 0, 0] = -u * u + self.g * h
171
- # # dF2_dhu
172
- # out[1, 1, 0] = 2 * u
173
- # # dF2_dh_b = 0
174
- # # dF3_dh =0
175
- # # dF3_du = 0
176
- # # dF3_dh_b =0
177
- # return out
178
-
179
- # def eigenvalues(self, Q, nij):
180
- # imaginary = False
181
- # h = Q[0]
182
- # hu = Q[1]
183
- # h = np.where(h <= 0, 0.0, h)
184
- # u = np.where(h <= 0, 0.0, hu / h)
185
- # # assert (h > 0).all()
186
- # c = np.sqrt(self.g * h)
187
- # return np.array([u - c, np.zeros_like(u), u + c]), imaginary
188
-
189
- # def nonconservative_matrix(self, Q, **kwargs):
190
- # result = np.zeros((Q.shape[0], Q.shape[0], self.dimension, Q.shape[1]))
191
- # h = Q[0]
192
- # h = np.where(h <= 0, 0.0, h)
193
- # result[1, 2] = -h * self.g * self.ez
194
- # return result
195
-
196
- # # def nonconservative_matrix(self, Q, **kwargs):
197
- # # result = np.zeros((Q.shape[0], Q.shape[0], Q.shape[1]))
198
- # # h = Q[0]
199
- # # h = np.where(h <= 0, 0.0, h)
200
- # # result[1, 2] = -h * self.g * self.ez
201
- # # return result
202
-
203
- # def rhs(self, t, Q, **kwargs):
204
- # output = np.zeros_like(Q)
205
- # # Topography
206
- # h = Q[0]
207
- # h = np.where(h <= 0, 0.0, h)
208
- # output[1] = h * self.g * self.ex
209
-
210
- # # Friction
211
- # for friction in self.friction_models:
212
- # output += getattr(self, friction)(t, Q, **kwargs)
213
-
214
- # return output
215
-
216
- # def rhs_jacobian(self, t, Q, **kwargs):
217
- # out = np.zeros((Q.shape[0], Q.shape[0], self.dimension, Q.shape[1]))
218
- # h = Q[0]
219
- # hu = Q[1]
220
- # # h = np.where(h <= 0.0, 0.0, h)
221
- # # u = np.where(h <= 0.0, 0.0, hu / h)
222
-
223
- # # Topography
224
- # out[1, 0, 0] = self.g * self.ex
225
- # # Friction
226
- # for friction in self.friction_models:
227
- # out += getattr(self, friction + "_jacobian")(t, Q, **kwargs)
228
-
229
- # return out
230
-
231
- # def newtonian(self, t, Q, **kwargs):
232
- # output = np.zeros_like(Q)
233
- # h = Q[0]
234
- # hu = Q[1]
235
- # h = np.where(h <= 0.0, 0.0, h)
236
- # u = np.where(h <= 0.0, 0.0, hu / h)
237
- # nu = self.parameters["nu"]
238
- # output[1] = -nu * u
239
- # return output
240
-
241
- # def newtonian_jacobian(self, t, Q, **kwargs):
242
- # out = np.zeros((Q.shape[0], Q.shape[0], self.dimension, Q.shape[1]))
243
- # h = Q[0]
244
- # hu = Q[1]
245
- # nu = self.parameters["nu"]
246
- # out[1, 0, 0] = +nu * hu / h / h
247
- # out[1, 1, 0] = -nu / h
248
- # return out
249
-
250
- # def primitive_variables(self, Q):
251
- # h = Q[0]
252
- # hu = Q[1]
253
- # h_b = Q[2]
254
- # h = Q[0]
255
- # hu = Q[1]
256
- # h = np.where(h <= 0, 0.0, h)
257
- # u = np.where(h <= 0, 0.0, hu / h)
258
- # return np.array([h, u, h_b])
259
-
260
- # def conservative_variables(self, U):
261
- # h = U[0]
262
- # u = U[1]
263
- # h_b = U[2]
264
- # return np.array([h, h * u, h_b])
265
-
266
-
267
- # class ShallowWaterWithBottom2d(Model2d):
268
- # yaml_tag = "!ShallowWaterWithBottom2d"
269
- # dimension = 2
270
-
271
- # def set_default_default_parameters(self):
272
- # super().set_default_default_parameters()
273
- # self.n_variables = 4
274
-
275
- # def set_runtime_variables(self):
276
- # super().set_runtime_variables()
277
-
278
- # def flux(self, Q):
279
- # h = Q[0]
280
- # hu = Q[1]
281
- # hv = Q[2]
282
- # h = np.where(h <= 0.0, 0.0, h)
283
- # u = np.where(h <= 0.0, 0.0, hu / h)
284
- # v = np.where(h <= 0.0, 0.0, hv / h)
285
- # return np.arraw(
286
- # [
287
- # [hu, hu * u + self.g * h * h / 2, hu * v, np.zeros_like(h)],
288
- # [hv, hv * u, hv * v + self.g * h * h / 2, np.zeros_like(h)],
289
- # ]
290
- # ).swapaxes(0, 1)
291
-
292
- # def flux_jacobian(self, Q):
293
- # h = Q[0]
294
- # hu = Q[1]
295
- # hv = Q[2]
296
- # h = np.where(h <= 0.0, 0.0, h)
297
- # u = np.where(h <= 0.0, 0.0, hu / h)
298
- # v = np.where(h <= 0.0, 0.0, hv / h)
299
- # c = self.g * h
300
- # zero = np.zeros_like(h)
301
- # one = np.ones_like(h)
302
- # A_x = np.array(
303
- # [
304
- # [zero, one, zero, zero],
305
- # [-(u**2) + c, 2 * u, zero, zero],
306
- # [-u * v, v, u, zero],
307
- # [zero, zero, zero, zero],
308
- # ]
309
- # )
310
- # A_y = np.array(
311
- # [
312
- # [zero, zero, one, zero],
313
- # [-u * v, v, u, zero],
314
- # [-(v**2) + c, zero, 2 * v, zero],
315
- # [zero, zero, zero, zero],
316
- # ]
317
- # )
318
- # A = np.zeros((Q.shape[0], Q.shape[0], 2, Q.shape[1]))
319
- # A[:, :, 0, :] = A_x
320
- # A[:, :, 1, :] = A_y
321
- # return A
322
-
323
- # def eigenvalues(self, Q, nij):
324
- # imaginary = False
325
- # h = Q[0]
326
- # hu = Q[1]
327
- # hv = Q[2]
328
- # h = np.where(h <= 0.0, 0.0, h)
329
- # u = np.where(h <= 0.0, 0.0, hu / h)
330
- # v = np.where(h <= 0.0, 0.0, hv / h)
331
- # un = u * nij[0] + v * nij[1]
332
- # c = np.sqrt(self.g * h)
333
- # return np.array([un - c, np.zeros_like(h), un + c]), imaginary
334
-
335
- # def eigensystem(self, Q, nij):
336
- # imaginary = False
337
- # h = Q[0]
338
- # hu = Q[1]
339
- # hv = Q[2]
340
- # h = np.where(h <= 0.0, 0.0, h)
341
- # u = np.where(h <= 0.0, 0.0, hu / h)
342
- # v = np.where(h <= 0.0, 0.0, hv / h)
343
- # c = np.sqrt(self.g * h)
344
- # zero = np.zeros_like(h)
345
- # one = np.ones_like(h)
346
- # eps = 10 ** (-18) * one
347
- # ev_x = np.array([zero, u, u - c, u + c])
348
- # R_x = np.array(
349
- # [
350
- # [-(c**2), zero, one, one],
351
- # [zero, zero, -c + u, c + u],
352
- # [-(c**2) * v, one, v, v],
353
- # [c**2 - u**2, zero, zero, zero],
354
- # ]
355
- # )
356
- # iR_x = np.array(
357
- # [
358
- # [zero, zero, zero, 1.0 / (c**2 - u**2 + eps)],
359
- # [-v, zero, one, zero],
360
- # [
361
- # (c + u) / (2 * c + eps),
362
- # -1.0 / (2 * c + eps),
363
- # zero,
364
- # c / (2 * c - 2 * u + eps),
365
- # ],
366
- # [
367
- # (c - u) / (2 * c + eps),
368
- # 1.0 / (2 * c + eps),
369
- # zero,
370
- # c / (2 * (c + u + eps)),
371
- # ],
372
- # ]
373
- # )
374
- # ev_y = np.array([zero, v, v - c, v + c])
375
- # R_y = np.array(
376
- # [
377
- # [-(c**2), zero, -one, one],
378
- # [-(c**2) * u, one, -u, u],
379
- # [zero, zero, c - v, c + v],
380
- # [c**2 - v**2, zero, zero, zero],
381
- # ]
382
- # )
383
- # iR_y = np.array(
384
- # [
385
- # [zero, zero, zero, 1.0 / (c**2 - v**2 + eps)],
386
- # [-u, one, zero, zero],
387
- # [
388
- # -(c + v) / (2 * c + eps),
389
- # zero,
390
- # 1.0 / (2 * c + eps),
391
- # -c / (2 * c - 2 * v + eps),
392
- # ],
393
- # [
394
- # (c - v) / (2 * c + eps),
395
- # zero,
396
- # 1.0 / (2 * c + eps),
397
- # c / (2 * (c + v) + eps),
398
- # ],
399
- # ]
400
- # )
401
- # ev = np.zeros((Q.shape[0], 2, Q.shape[1]))
402
- # R = np.zeros((Q.shape[0], Q.shape[0], 2, Q.shape[1]))
403
- # iR = np.zeros((Q.shape[0], Q.shape[0], 2, Q.shape[1]))
404
- # ev[:, 0, :] = ev_x
405
- # ev[:, 1, :] = ev_y
406
- # R[:, :, 0, :] = R_x
407
- # R[:, :, 1, :] = R_y
408
- # iR[:, :, 0, :] = iR_x
409
- # iR[:, :, 1, :] = iR_y
410
-
411
- # ev = np.einsum("ik..., k... -> i...", ev, nij)
412
- # R = np.einsum("ijk..., k... -> ij...", R, nij)
413
- # iR = np.einsum("ijk..., k... -> ij...", iR, nij)
414
- # A_rec = R[:, :, 0] @ np.diag(ev[:, 0]) @ iR[:, :, 0]
415
- # err = np.linalg.norm(
416
- # np.einsum("ijk..., k... -> ij...", self.quasilinear_matrix(Q), nij)[:, :, 0]
417
- # - A_rec
418
- # )
419
- # return ev, R, iR, err
420
-
421
- # def nonconservative_matrix(self, Q, **kwargs):
422
- # result = np.zeros((Q.shape[0], Q.shape[0], self.dimension, Q.shape[1]))
423
- # h = Q[0]
424
- # h = np.where(h <= 0, 0.0, h)
425
- # result[1, 3, 0] = -h * self.g * self.ez
426
- # result[2, 3, 1] = -h * self.g * self.ez
427
- # return result
428
-
429
- # def rhs(self, t, Q, **kwargs):
430
- # output = np.zeros_like(Q)
431
- # # Topography
432
- # h = Q[0]
433
- # h = np.where(h <= 0, 0.0, h)
434
- # output[1] = h * self.g * self.ex
435
- # output[2] = h * self.g * self.ey
436
-
437
- # # Friction
438
- # for friction in self.friction_models:
439
- # output += getattr(self, friction)(t, Q, **kwargs)
440
-
441
- # return output
442
-
443
- # def rhs_jacobian(self, t, Q, **kwargs):
444
- # out = np.zeros((Q.shape[0], Q.shape[0], Q.shape[1]))
445
- # h = Q[0]
446
- # hu = Q[1]
447
- # # h = np.where(h <= 0.0, 0.0, h)
448
- # # u = np.where(h <= 0.0, 0.0, hu / h)
449
-
450
- # # Topography
451
- # out[1, 0] = self.g * self.ex
452
- # out[2, 0] = self.g * self.ey
453
- # # Friction
454
- # for friction in self.friction_models:
455
- # out += getattr(self, friction + "_jacobian")(t, Q, **kwargs)
456
-
457
- # return out
458
-
459
- # def newtonian(self, t, Q, **kwargs):
460
- # output = np.zeros_like(Q)
461
- # h = Q[0]
462
- # hu = Q[1]
463
- # hv = Q[2]
464
- # h = np.where(h <= 0.0, 0.0, h)
465
- # u = np.where(h <= 0.0, 0.0, hu / h)
466
- # v = np.where(h <= 0.0, 0.0, hv / h)
467
- # nu = self.parameters["nu"]
468
- # output[1] = -nu * u
469
- # output[2] = -nu * v
470
- # return output
471
-
472
- # def newtonian_jacobian(self, t, Q, **kwargs):
473
- # out = np.zeros((Q.shape[0], Q.shape[0], Q.shape[1]))
474
- # h = Q[0]
475
- # hu = Q[1]
476
- # hv = Q[2]
477
- # nu = self.parameters["nu"]
478
- # out[1, 0] = +nu * hu / h / h
479
- # out[1, 1] = -nu / h
480
- # out[2, 0] = +nu * hv / h / h
481
- # out[2, 2] = -nu / h
482
- # return out
483
-
484
- # def bc_chezy(self, t, Q, **kwargs):
485
- # output = np.zeros_like(Q)
486
- # h = Q[0]
487
- # hu = Q[1]
488
- # hv = Q[2]
489
- # h = np.where(h <= 0.0, 0.0, h)
490
- # u = np.where(h <= 0.0, 0.0, hu / h)
491
- # v = np.where(h <= 0.0, 0.0, hv / h)
492
- # # C = kwargs["aux_variables"]["ChezyCoef"]
493
- # C = kwargs["model"].parameters["ChezyCoef"]
494
- # u_sq = np.sqrt(u**2 + v**2)
495
- # output[1] = -1.0 / C**2 * u * u_sq
496
- # output[2] = -1.0 / C**2 * v * u_sq
497
- # return output
498
-
499
- # def bc_chezy_jacobian(self, t, Q, **kwargs):
500
- # out = np.zeros((Q.shape[0], Q.shape[0], Q.shape[1]))
501
- # h = Q[0]
502
- # hu = Q[1]
503
- # hv = Q[2]
504
- # h = np.where(h <= 0.0, 0.0, h)
505
- # u = np.where(h <= 0.0, 0.0, hu / h)
506
- # v = np.where(h <= 0.0, 0.0, hv / h)
507
- # C = kwargs["model"].parameters["ChezyCoef"]
508
- # # C = kwargs["aux_variables"]["ChezyCoef"]
509
- # u_sq = np.sqrt(u**2 + v**2)
510
- # eps = 10 ** (-10)
511
- # out[1, 0] = +1.0 / C**2 * 2 * u * u_sq / h
512
- # out[1, 1] = -1.0 / C**2 * (u / h / (u_sq + eps) * u + u_sq / h)
513
- # out[1, 2] = -1.0 / C**2 * (u / h / (u_sq + eps) * v)
514
- # out[2, 0] = +1.0 / C**2 * 2 * v * u_sq / h
515
- # out[2, 1] = -1.0 / C**2 * (v / h / (u_sq + eps) * u)
516
- # out[2, 2] = -1.0 / C**2 * (v / h / (u_sq + eps) * v + u_sq / h)
517
- # return out
518
-
519
- # def newtonian_jacobian(self, t, Q, **kwargs):
520
- # out = np.zeros((Q.shape[0], Q.shape[0], Q.shape[1]))
521
- # h = Q[0]
522
- # hu = Q[1]
523
- # hv = Q[2]
524
- # nu = self.parameters["nu"]
525
- # out[1, 0] = +nu * hu / h / h
526
- # out[1, 1] = -nu / h
527
- # out[2, 0] = +nu * hv / h / h
528
- # out[2, 2] = -nu / h
529
- # return out
530
-
531
- # def primitive_variables(self, Q):
532
- # h = Q[0]
533
- # hu = Q[1]
534
- # hv = Q[2]
535
- # h_b = Q[3]
536
- # h = np.where(h <= 0.0, 0.0, h)
537
- # u = np.where(h <= 0.0, 0.0, hu / h)
538
- # v = np.where(h <= 0.0, 0.0, hv / h)
539
- # return np.array([h, u, v, h_b])
540
-
541
- # def conservative_variables(self, U):
542
- # h = U[0]
543
- # u = U[1]
544
- # v = U[2]
545
- # h_b = U[3]
546
- # return np.array([h, h * u, h * v, h_b])
547
-
548
- # def compute_Q_in_normal_transverse(self, Q_, n_, **kwargs):
549
- # assert Q_.shape[1] == 1
550
- # Q = np.array(Q_[:, 0])
551
- # n = np.array(n_[:, 0])
552
- # dim = self.dimension
553
- # offset = 1
554
- # assert dim == 2
555
- # result = np.array(Q)
556
- # mom = np.zeros((offset, dim))
557
- # for d in range(dim):
558
- # mom[:, d] = Q[1 + d * offset : 1 + (d + 1) * offset]
559
- # mom_normal = np.einsum("ik... ,k... -> i...", mom, n[:dim])
560
- # n_trans = np.cross(np.array([n[0], n[1], 0.0]), np.array([0.0, 0.0, 1.0]))
561
- # mom_trans = np.einsum("ik... ,k... -> i...", mom, n_trans[:dim])
562
- # result[1 : 1 + offset] = mom_normal
563
- # result[1 + offset : 1 + 2 * offset] = mom_trans
564
- # return result
565
-
566
- # def compute_Q_in_x_y(self, Q_, n_, **kwargs):
567
- # assert Q_.shape[1] == 1
568
- # Q = np.array(Q_[:, 0])
569
- # n = np.array(n_[:, 0])
570
- # n = np.array([n[0], n[1], 0.0])
571
- # dim = self.dimension
572
- # offset = 1
573
- # assert dim == 2
574
- # result = np.array(Q)
575
- # mom = np.zeros((offset, dim))
576
- # mom_normal = Q[1 : 1 + offset]
577
- # mom_trans = Q[1 + offset : 1 + 2 * offset]
578
- # n_trans = np.cross(n, np.array([0.0, 0.0, 1.0]))
579
- # nx = np.array([1.0, 0.0, 0.0])
580
- # ny = np.array([0.0, 1.0, 0.0])
581
- # result[1 : 1 + offset] = mom_normal * np.dot(n, nx)
582
- # result[1 : 1 + offset] += mom_trans * np.dot(n_trans, nx)
583
- # result[1 + offset : 1 + 2 * offset] = mom_normal * np.dot(n, ny)
584
- # result[1 + offset : 1 + 2 * offset] += mom_trans * np.dot(n_trans, ny)
585
- # return result
586
-
587
-
588
- # class ShallowWater2d(Model2d):
589
- # yaml_tag = "!ShallowWater2d"
590
-
591
- # def set_default_default_parameters(self):
592
- # super().set_default_default_parameters()
593
- # self.n_variables = 3
594
-
595
- # def set_runtime_variables(self):
596
- # super().set_runtime_variables()
597
-
598
- # def flux(self, Q):
599
- # h = Q[0]
600
- # hu = Q[1]
601
- # hv = Q[2]
602
- # u = hu / h
603
- # v = hv / h
604
- # return np.array(
605
- # [
606
- # [hu, hu * u + self.g * h * h / 2, hu * v],
607
- # [hv, hv * u, hv * v + self.g * h * h / 2],
608
- # ]
609
- # ).swapaxes(0, 1)
610
-
611
- # def flux_jacobian(self, Q):
612
- # h = Q[0]
613
- # hu = Q[1]
614
- # hv = Q[2]
615
- # u = hu / h
616
- # v = hv / h
617
-
618
- # result = np.zeros((3, 3, 2))
619
- # dfdq = np.array([[0, 1, 0], [-(u**2) + self.g * h, 2 * u, 0], [-u * v, v, u]])
620
- # dgdq = np.array([[0, 0, 1], [-u * v, v, u], [-(v**2) + self.g * h, 0, 2 * v]])
621
- # result[:, :, 0] = dfdq
622
- # result[:, :, 1] = dgdq
623
- # return result
624
-
625
- # def eigenvalues(self, Q, nij):
626
- # imaginary = False
627
- # # evs = np.zeros_like(Q)
628
- # # for i in range(Q.shape[1]):
629
- # # evs[:,i] = np.linalg.eigvals(np.dot(self.flux_jacobian(Q[:,i]), nij.flatten()))
630
- # # return evs, imaginary
631
- # h = Q[0]
632
- # hu = Q[1]
633
- # hv = Q[2]
634
- # u = hu / h
635
- # v = hv / h
636
- # un = u + v
637
- # assert (h > 0).all()
638
- # c = np.sqrt(self.g * h)
639
- # return np.array([un - c, un, un + c]), imaginary
640
-
641
- # def rhs(self, t, Q, **kwargs):
642
- # output = np.zeros_like(Q)
643
- # # Topography
644
- # h = Q[0]
645
- # output[1] = h * self.g * self.ex
646
- # output[2] = h * self.g * self.ey
647
-
648
- # # Friction
649
- # for friction in self.friction_models:
650
- # output += getattr(self, friction)(t, Q, **kwargs)
651
-
652
- # return output
653
-
654
- # def rhs_jacobian(self, t, Q, **kwargs):
655
- # out = np.zeros((Q.shape[0], Q.shape[0], Q.shape[1]))
656
- # h = Q[0]
657
- # hu = Q[1]
658
-
659
- # # Topography
660
- # out[1, 0] = self.g * self.ex
661
- # out[2, 0] = self.g * self.ey
662
- # # Friction
663
- # for friction in self.friction_models:
664
- # out += getattr(self, friction + "_jacobian")(t, Q, **kwargs)
665
-
666
- # return out
667
-
668
- # def newtonian(self, t, Q, **kwargs):
669
- # output = np.zeros_like(Q)
670
- # h = Q[0]
671
- # u = Q[1] / h
672
- # v = Q[2] / h
673
- # nu = self.parameters["nu"]
674
- # output[1] = -nu * u
675
- # output[2] = -nu * v
676
- # return output
677
-
678
- # def newtonian_jacobian(self, t, Q, **kwargs):
679
- # out = np.zeros((Q.shape[0], Q.shape[0], Q.shape[1]))
680
- # h = Q[0]
681
- # hu = Q[1]
682
- # hv = Q[2]
683
- # nu = self.parameters["nu"]
684
- # out[1, 0] = +nu * hu / h / h
685
- # out[1, 1] = -nu / h
686
- # out[2, 0] = +nu * hv / h / h
687
- # out[2, 2] = -nu / h
688
- # return out
689
-
690
- # def primitive_variables(self, Q):
691
- # h = Q[0]
692
- # hu = Q[1]
693
- # hv = Q[2]
694
- # u = hu / h
695
- # v = hv / h
696
- # return np.array([h, u, v])
697
-
698
- # def conservative_variables(self, U):
699
- # h = U[0]
700
- # u = U[1]
701
- # v = U[2]
702
- # return np.array([h, h * u, h * v])
703
-
704
-
705
- # class ShallowWaterSympy(Model):
706
- # yaml_tag = "!ShallowWaterSympy"
707
-
708
- # def set_default_default_parameters(self):
709
- # super().set_default_default_parameters()
710
- # self.n_variables = 2
711
-
712
- # def set_runtime_variables(self):
713
- # super().set_runtime_variables()
714
- # self.initialize_sympy_model()
715
-
716
- # def initialize_sympy_model(self):
717
- # numEquations = 1
718
- # h = sympy.symbols("h")
719
- # halpha = Matrix([sympy.symbols("halpha%d" % i) for i in range(numEquations)])
720
- # Q = Matrix([h, *(halpha)])
721
-
722
- # def f():
723
- # flux = Matrix([0 for i in range(Q.shape[0])])
724
- # h = Q[0]
725
- # hu = Q[1]
726
- # flux[0] = hu
727
- # flux[1] = hu**2 / h + self.g * self.ez * h * h / 2
728
- # return flux
729
-
730
- # def jac_f():
731
- # return f().jacobian(Q)
732
-
733
- # def rhs():
734
- # output = Matrix([0 for i in range(Q.shape[0])])
735
- # h = Q[0]
736
- # for friction in self.friction_models:
737
- # output += getattr(self, friction)
738
- # return output
739
-
740
- # def jac_rhs():
741
- # return rhs().jacobian(Q)
742
-
743
- # def newtonian():
744
- # result = flux = Matrix([0 for i in range(Q.shape[0])])
745
- # h = Q[0]
746
- # hu = Q[1]
747
- # nu = self.parameters["nu"]
748
- # result[1] = -nu * hu / h
749
- # return result
750
-
751
- # self.EVs = simplify(jac_f().eigenvals())
752
- # self.F = lambdify(Q, f(), "numpy")
753
- # self.JacF = lambdify(Q, jac_f(), "numpy")
754
- # self.rhs = lambdify(Q, rhs(), "numpy")
755
- # self.Jac_rhs = lambdify(Q, jac_rhs(), "numpy")
756
-
757
- # def flux(self, Q):
758
- # return self.F(*Q)
759
-
760
- # def flux_jacobian(self, Q):
761
- # return self.JacF(*Q)
762
-
763
- # def eigenvalues(self, Q, nij):
764
- # imaginary = False
765
- # h = Q[0]
766
- # hu = Q[1]
767
- # u = hu / h
768
- # assert (h > 0).all()
769
- # c = np.sqrt(self.g * h)
770
- # return np.array([u - c, u + c]), imaginary
771
-
772
- # def rhs(self, t, Q, **kwargs):
773
- # output = np.zeros_like(Q)
774
- # # Topography
775
- # dHdx = kwargs["aux_variables"]["dHdx"]
776
- # h = Q[0]
777
- # output[1] = h * self.g * (self.ex - self.ez * dHdx)
778
-
779
- # # Friction
780
- # for friction in self.friction_models:
781
- # output += getattr(self, friction)(t, Q, **kwargs)
782
-
783
- # return output
784
-
785
- # def rhs_jacobian(self, t, Q, **kwargs):
786
- # # vectorized or single element?
787
- # if len(Q.shape) == 2:
788
- # output = np.zeros((Q.shape[0], Q.shape[0], Q.shape[1]))
789
-
790
- # # Topography
791
- # dHdx = kwargs["aux_variables"]["dHdx"]
792
- # h = Q[0]
793
- # # dR1_dh=0
794
- # # dR1_dhu=0
795
- # # dR2_dh
796
- # output[1, 0] = self.g * (self.ex - self.ez * dHdx)
797
- # # dR2_dhu=0
798
-
799
- # # Friction
800
- # for friction in self.friction_models:
801
- # output += getattr(self, friction + "_jacobian")(t, Q, **kwargs)
802
-
803
- # return output
804
-
805
- # def newtonian(self, t, Q, **kwargs):
806
- # output = np.zeros_like(Q)
807
- # h = Q[0]
808
- # u = Q[1] / Q[0]
809
- # nu = self.parameters["nu"]
810
- # output[1] = -nu * u
811
- # return output
812
-
813
- # def newtonian_jacobian(self, t, Q, **kwargs):
814
- # # vectorized?
815
- # if len(Q.shape) == 2:
816
- # output = np.zeros((Q.shape[0], Q.shape[0], Q.shape[1]))
817
- # else:
818
- # output = np.zeros((Q.shape[0], Q.shape[0]))
819
- # nu = self.parameters["nu"]
820
- # h = Q[0]
821
- # u_inv = Q[0] / Q[1]
822
- # # dR1_dh=0
823
- # # dR1_dhu=0
824
- # # dR2_dh
825
- # output[1, 0] = nu * u_inv * u_inv
826
- # # dR2_dhu=0
827
- # output[1, 1] = -nu / h
828
- # return output
829
-
830
- # def manning(
831
- # self, t, Q, **kwargs
832
- # ): # Manning Friction defined as per: https://agupubs.onlinelibrary.wiley.com/doi/full/10.1002/wrcr.20366
833
- # output = np.zeros_like(Q)
834
- # h = Q[0]
835
- # u = Q[1] / Q[0]
836
- # nu = self.parameters["nu"]
837
- # output[1] = -self.g * (nu**2) * Q[1] * np.abs(Q[1]) / Q[0] ** (7 / 3)
838
- # return output
839
-
840
- # def primitive_variables(self, Q):
841
- # h = Q[0]
842
- # hu = Q[1]
843
- # u = hu / h
844
- # return np.array([h, u])
845
-
846
- # def conservative_variables(self, U):
847
- # h = U[0]
848
- # u = U[1]
849
- # return np.array([h, h * u])
850
-
851
-
852
- # class ShallowWaterExner(Model):
853
- # yaml_tag = "!ShallowWaterExner"
854
-
855
- # def set_default_default_parameters(self):
856
- # super().set_default_default_parameters()
857
- # self.n_variables = 3
858
- # self.parameters = {
859
- # "sediment_density": 1580,
860
- # "water_density": 1000,
861
- # "sediment_dia": 0.0039,
862
- # "critical_shield": 0.047,
863
- # "manning": 0.0365,
864
- # "porosity": 0.47,
865
- # }
866
-
867
- # def set_runtime_variables(self):
868
- # super().set_runtime_variables()
869
-
870
- # def characteristic_discharge(self):
871
- # return self.parameters["sediment_dia"] * np.sqrt(
872
- # self.g
873
- # * self.parameters["sediment_dia"]
874
- # * (
875
- # self.parameters["sediment_density"] / self.parameters["water_density"]
876
- # - 1
877
- # )
878
- # )
879
-
880
- # def flux(self, Q):
881
- # h = Q[0]
882
- # hu = Q[1]
883
- # u = hu / h
884
-
885
- # q = self.characteristic_discharge()
886
- # S_f = (self.parameters["manning"] ** 2) * u * np.abs(u) / h ** (4 / 3)
887
- # tau = self.parameters["water_density"] * self.g * h * S_f
888
- # theta = (
889
- # np.abs(tau)
890
- # * (self.parameters["sediment_dia"] ** 2)
891
- # / (
892
- # self.g
893
- # * (
894
- # self.parameters["sediment_density"]
895
- # - self.parameters["water_density"]
896
- # )
897
- # * self.parameters["sediment_dia"] ** 3
898
- # )
899
- # )
900
-
901
- # theta_flag = np.array(theta >= self.parameters["critical_shield"], dtype=float)
902
- # delta = (theta_flag * (theta - self.parameters["critical_shield"])) ** 1.5
903
-
904
- # # delta = np.abs(theta - self.critical_shield)**1.5
905
-
906
- # q_b = q * np.sign(tau) * (8 / (1 - self.parameters["porosity"])) * delta
907
-
908
- # return np.array([hu, hu * u + self.g * h * h / 2, q_b])
909
-
910
- # def flux_jacobian(self, Q):
911
- # out = np.zeros((Q.shape[0], Q.shape[0], Q.shape[1]))
912
- # h = Q[0]
913
- # u = Q[1] / Q[0]
914
- # S_f = (self.parameters["manning"] ** 2) * u * np.abs(u) / h ** (4 / 3)
915
- # tau = self.parameters["water_density"] * self.g * h * S_f
916
- # theta = (
917
- # np.abs(tau)
918
- # * (self.parameters["sediment_dia"] ** 2)
919
- # / (
920
- # self.g
921
- # * (
922
- # self.parameters["sediment_density"]
923
- # - self.parameters["water_density"]
924
- # )
925
- # * self.parameters["sediment_dia"] ** 3
926
- # )
927
- # )
928
- # q = self.characteristic_discharge()
929
-
930
- # theta_flag = np.array(theta >= self.parameters["critical_shield"], dtype=float)
931
- # delta = (theta_flag * (theta - self.parameters["critical_shield"])) ** 0.5
932
-
933
- # # delta = np.abs(theta - self.critical_shield)**0.5
934
-
935
- # dq = (
936
- # q
937
- # * 24
938
- # * (self.parameters["manning"] ** 2)
939
- # * delta
940
- # * u
941
- # / (
942
- # (1 - self.parameters["porosity"])
943
- # * (
944
- # (
945
- # self.parameters["sediment_density"]
946
- # / self.parameters["water_density"]
947
- # )
948
- # - 1
949
- # )
950
- # * self.parameters["sediment_dia"]
951
- # * (h ** (4 / 3))
952
- # )
953
- # )
954
- # dh = (-7 / 6) * u * dq
955
-
956
- # out[0, 1] = 1
957
- # out[1, 0] = self.g * h - u**2
958
- # out[1, 1] = 2 * u
959
- # # out[1,2] = self.g * h
960
- # out[2, 0] = dh
961
- # out[2, 1] = dq
962
-
963
- # return out
964
-
965
- # def nonconservative_matrix(self, Q, **kwargs):
966
- # h = Q[0]
967
- # NC = np.zeros((Q.shape[0], Q.shape[0], Q.shape[1]))
968
- # NC[1, 2] = -self.g * h
969
- # return NC
970
-
971
- # def rhs(self, t, Q, **kwargs):
972
- # output = np.zeros_like(Q)
973
- # h = Q[0]
974
- # u = Q[1] / Q[0]
975
- # output[1] = (
976
- # -self.g * self.parameters["manning"] ** 2 * np.abs(u) * u / h ** (1 / 3)
977
- # )
978
-
979
- # return output
980
-
981
- # def rhs_jacobian(self, t, Q, **kwargs):
982
- # h = Q[0]
983
- # u = Q[1] / Q[0]
984
-
985
- # if len(Q.shape) == 2:
986
- # output = np.zeros((Q.shape[0], Q.shape[0], Q.shape[1]))
987
- # else:
988
- # output = np.zeros((Q.shape[0], Q.shape[0]))
989
-
990
- # output[1, 0] = (
991
- # (7 / 3)
992
- # * self.g
993
- # * (self.parameters["manning"] ** 2)
994
- # * u
995
- # * np.abs(u)
996
- # / h ** (4 / 3)
997
- # )
998
- # output[1, 1] = (
999
- # -self.g
1000
- # * (self.parameters["manning"] ** 2)
1001
- # * (np.abs(u) + (u * u / np.abs(u)))
1002
- # / h ** (4 / 3)
1003
- # )
1004
-
1005
- # return output
1006
-
1007
- # def primitive_variables(self, Q):
1008
- # h = Q[0]
1009
- # hu = Q[1]
1010
- # u = hu / h
1011
- # b = Q[2]
1012
- # return np.array([h, u, b])
1013
-
1014
- # def conservative_variables(self, U):
1015
- # h = U[0]
1016
- # u = U[1]
1017
- # b = U[2]
1018
- # return np.array([h, h * u, b])