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.
Files changed (57) hide show
  1. decorators/decorators.py +25 -0
  2. fvm/__init__.py +0 -0
  3. fvm/flux.py +52 -0
  4. fvm/nonconservative_flux.py +97 -0
  5. fvm/ode.py +55 -0
  6. fvm/solver_numpy.py +297 -0
  7. fvm/timestepping.py +13 -0
  8. mesh/__init__.py +0 -0
  9. mesh/mesh.py +1239 -0
  10. mesh/mesh_extrude.py +168 -0
  11. mesh/mesh_util.py +487 -0
  12. misc/__init__.py +0 -0
  13. misc/custom_types.py +6 -0
  14. misc/interpolation.py +140 -0
  15. misc/io.py +448 -0
  16. misc/logger_config.py +18 -0
  17. misc/misc.py +218 -0
  18. model/__init__.py +0 -0
  19. model/analysis.py +147 -0
  20. model/basefunction.py +113 -0
  21. model/basemodel.py +513 -0
  22. model/boundary_conditions.py +193 -0
  23. model/initial_conditions.py +171 -0
  24. model/model.py +65 -0
  25. model/models/GN.py +70 -0
  26. model/models/advection.py +53 -0
  27. model/models/basisfunctions.py +181 -0
  28. model/models/basismatrices.py +381 -0
  29. model/models/coupled_constrained.py +60 -0
  30. model/models/poisson.py +41 -0
  31. model/models/shallow_moments.py +757 -0
  32. model/models/shallow_moments_sediment.py +378 -0
  33. model/models/shallow_moments_topo.py +423 -0
  34. model/models/shallow_moments_variants.py +1509 -0
  35. model/models/shallow_water.py +266 -0
  36. model/models/shallow_water_topo.py +111 -0
  37. model/models/shear_shallow_flow.py +594 -0
  38. model/models/sme_turbulent.py +613 -0
  39. model/models/vam.py +455 -0
  40. postprocessing/__init__.py +0 -0
  41. postprocessing/plotting.py +244 -0
  42. postprocessing/postprocessing.py +75 -0
  43. preprocessing/__init__.py +0 -0
  44. preprocessing/openfoam_moments.py +453 -0
  45. transformation/__init__.py +0 -0
  46. transformation/helpers.py +25 -0
  47. transformation/to_amrex.py +241 -0
  48. transformation/to_c.py +185 -0
  49. transformation/to_jax.py +14 -0
  50. transformation/to_numpy.py +118 -0
  51. transformation/to_openfoam.py +258 -0
  52. transformation/to_ufl.py +67 -0
  53. zoomy_core-0.1.14.dist-info/METADATA +52 -0
  54. zoomy_core-0.1.14.dist-info/RECORD +57 -0
  55. zoomy_core-0.1.14.dist-info/WHEEL +5 -0
  56. zoomy_core-0.1.14.dist-info/licenses/LICENSE +674 -0
  57. zoomy_core-0.1.14.dist-info/top_level.txt +8 -0
@@ -0,0 +1,75 @@
1
+ import os
2
+ import numpy as np
3
+
4
+ try:
5
+ import h5py
6
+
7
+ _HAVE_H5PY = True
8
+ except ImportError:
9
+ _HAVE_H5PY = False
10
+
11
+ import zoomy_core.mesh.mesh as petscMesh
12
+ import zoomy_core.misc.io as io
13
+ from zoomy_core.misc.logger_config import logger
14
+ from zoomy_core.transformation.to_numpy import NumpyRuntimeModel
15
+ from zoomy_core.misc import misc as misc
16
+
17
+
18
+ def vtk_project_2d_to_3d(
19
+ model, settings, start_at_time=0, scale_h=1.0, filename='out_3d'
20
+ ):
21
+ if not _HAVE_H5PY:
22
+ raise ImportError("h5py is required for vtk_project_2d_to_3d function.")
23
+ Nz = model.number_of_points_3d
24
+ main_dir = misc.get_main_directory()
25
+
26
+ path_to_simulation = os.path.join(main_dir, os.path.join(settings.output.directory, f"{settings.output.filename}.h5"))
27
+ sim = h5py.File(path_to_simulation, "r")
28
+ settings = io.load_settings(settings.output.directory)
29
+ fields = sim["fields"]
30
+ mesh = petscMesh.Mesh.from_hdf5(path_to_simulation)
31
+ n_snapshots = len(list(fields.keys()))
32
+
33
+ Z = np.linspace(0, 1, Nz)
34
+
35
+ mesh_extr = petscMesh.Mesh.extrude_mesh(mesh, Nz)
36
+ output_path = os.path.join(main_dir, settings.output.directory + f"/{filename}.h5")
37
+ mesh_extr.write_to_hdf5(output_path)
38
+ save_fields = io.get_save_fields_simple(output_path, True)
39
+
40
+ #mesh = GradientMesh.fromMesh(mesh)
41
+ i_count = 0
42
+ pde = NumpyRuntimeModel(model)
43
+ for i_snapshot in range(n_snapshots):
44
+ group_name = "iteration_" + str(i_snapshot)
45
+ group = fields[group_name]
46
+ time = group["time"][()]
47
+ if time < start_at_time:
48
+ continue
49
+ Q = group["Q"][()]
50
+ Qaux = group["Qaux"][()]
51
+
52
+ rhoUVWP = np.zeros((Q.shape[1] * Nz, 6), dtype=float)
53
+
54
+ #for i_elem, (q, qaux) in enumerate(zip(Q.T, Qaux.T)):
55
+ # for iz, z in enumerate(Z):
56
+ # rhoUVWP[i_elem + (iz * mesh.n_cells), :] = pde.project_2d_to_3d(np.array([0, 0, z]), q, qaux, parameters)
57
+
58
+ for iz, z in enumerate(Z):
59
+ Qnew = pde.project_2d_to_3d(z, Q[:, :mesh.n_inner_cells], Qaux[:, :mesh.n_inner_cells], model.parameter_values).T
60
+
61
+ #rhoUVWP[i_elem + (iz * mesh.n_cells), :] = pde.project_2d_to_3d(np.array([0, 0, z]), q, qaux, parameters)
62
+ # rhoUVWP[(iz * mesh.n_inner_cells):((iz+1) * mesh.n_inner_cells), 0] = Q[0, :mesh.n_inner_cells]
63
+ rhoUVWP[(iz * mesh.n_inner_cells):((iz+1) * mesh.n_inner_cells), :] = Qnew[iz, :]
64
+
65
+ # rhoUVWP[mesh.n_inner_cells:mesh.n_inner_cells+mesh.n_inner_cells, 0] = Q[0, :mesh.n_inner_cells]
66
+
67
+ qaux = np.zeros((Q.shape[1]*Nz, 1), dtype=float)
68
+ _ = save_fields(i_snapshot, time, rhoUVWP.T, qaux.T)
69
+ i_count += 1
70
+
71
+ logger.info(f"Converted snapshot {i_snapshot}/{n_snapshots}")
72
+
73
+ io.generate_vtk(output_path, filename=filename)
74
+ logger.info(f"Output is written to: {output_path}/{filename}.*.vtk")
75
+
File without changes
@@ -0,0 +1,453 @@
1
+ try:
2
+ _HAVE_MATPLOTLIB = True
3
+ import matplotlib.pyplot as plt
4
+ except ImportError:
5
+ _HAVE_MATPLOTLIB = False
6
+
7
+ import numpy as np
8
+ from copy import deepcopy
9
+ import os
10
+ from scipy.spatial import KDTree
11
+
12
+ try:
13
+ import pyvista as pv
14
+
15
+ _HAVE_PYVISTA = True
16
+ except ImportError:
17
+ _HAVE_PYVISTA = False
18
+
19
+ from zoomy_core.mesh.fvm_mesh import Mesh
20
+ from zoomy_core.misc.io import _save_fields_to_hdf5 as save_fields_to_hdf5
21
+ import zoomy_core.misc.io as io
22
+
23
+
24
+ main_dir = misc.get_main_directory()
25
+
26
+
27
+
28
+ def load_file(filename):
29
+ if not _HAVE_PYVISTA:
30
+ raise ImportError("pyvista is required for load_file function.")
31
+ reader = pv.get_reader(filename)
32
+ # get(0) gets us the internal (not boundary) data. The boundary data is non-existant anyways in our case
33
+ vtkfile = reader.read().get(0)
34
+ return vtkfile
35
+
36
+
37
+ def get_fields(vtkfile, fieldnames):
38
+ fields = []
39
+ for fieldname in fieldnames:
40
+ # point field)s
41
+ # field = vtkfile.point_data[fieldname]
42
+ field = vtkfile.cell_data[fieldname]
43
+ fields.append(np.array(field))
44
+ return fields
45
+ # return np.array(fields)
46
+
47
+
48
+ def get_coordinates(vtkfile):
49
+ # point coordinates
50
+ # return np.array(vtkfile.points)
51
+ # cell centers
52
+ return vtkfile.cell_centers().points
53
+
54
+
55
+ def get_time(vtkfile):
56
+ return vtkfile.field_data["TimeValue"][0]
57
+
58
+
59
+ def sort_data(coordinates, fields):
60
+ # Sort by z, y, x
61
+ order = np.lexsort((coordinates[:, 0], coordinates[:, 1], coordinates[:, 2]))
62
+ return order
63
+
64
+
65
+ def apply_order(coordinates, fields, order):
66
+ coordinates_copy = np.array(coordinates)
67
+ fields_copy = deepcopy(fields)
68
+ for d in range(coordinates.shape[1]):
69
+ coordinates[:, d] = coordinates_copy[order, d]
70
+ for field, field_copy in zip(fields, fields_copy):
71
+ field[:] = field_copy[order]
72
+ return coordinates, fields
73
+
74
+
75
+ def get_number_of_layers_and_elements_in_plane(coordinates):
76
+ layers = len(np.unique(coordinates[:, 2]))
77
+ n_elements_plane = int(coordinates[:, 0].size / layers)
78
+ return layers, n_elements_plane
79
+
80
+
81
+ def get_layer(data, layer, n_elements_plane):
82
+ return data[layer * n_elements_plane : (layer + 1) * n_elements_plane]
83
+
84
+
85
+ def compute_height(
86
+ alpha, n_layers, n_elements_per_layer, total_height=1.0, threshold=0.5
87
+ ):
88
+ height = np.zeros(n_elements_per_layer)
89
+ active = np.ones(n_elements_per_layer, dtype=bool)
90
+ dh = total_height / n_layers
91
+ for i in range(n_layers):
92
+ alpha_layer = get_layer(alpha, i, n_elements_per_layer)
93
+ height += np.where(np.logical_and((alpha_layer >= threshold), active), dh, 0)
94
+ return height
95
+
96
+
97
+ def extract_faces(mesh):
98
+ faces = []
99
+ i, offset = 0, 0
100
+ cc = mesh.cells # fetch up front
101
+ while i < mesh.n_cells:
102
+ nn = cc[offset]
103
+ faces.append(cc[offset + 1 : offset + 1 + nn])
104
+ offset += nn + 1
105
+ i += 1
106
+ return np.array(faces)
107
+
108
+
109
+ def sort_faces(faces, order):
110
+ for face in faces:
111
+ for i, point in enumerate(face):
112
+ face[i] = order[point]
113
+ faces = faces[order]
114
+ return faces
115
+
116
+
117
+ def add_noslip_layer(U, n_elements_per_layer):
118
+ Unew = np.zeros((U.shape[0] + n_elements_per_layer, U.shape[1]))
119
+ for d in range(U.shape[1]):
120
+ Unew[n_elements_per_layer:, d] = U[:, d]
121
+ return Unew
122
+
123
+
124
+ def extract_velocity_column_at_coordinate(U, n_elements_per_layer, n_layer, coordinate):
125
+ u = np.array(
126
+ [
127
+ get_layer(U[:, 0], i, n_elements_per_layer)[coordinate]
128
+ for i in range(n_layer + 1)
129
+ ]
130
+ )
131
+ v = np.array(
132
+ [
133
+ get_layer(U[:, 1], i, n_elements_per_layer)[coordinate]
134
+ for i in range(n_layer + 1)
135
+ ]
136
+ )
137
+ w = np.array(
138
+ [
139
+ get_layer(U[:, 2], i, n_elements_per_layer)[coordinate]
140
+ for i in range(n_layer + 1)
141
+ ]
142
+ )
143
+ return u, v, w
144
+
145
+
146
+ def shift_integration_interval(xi):
147
+ return (xi + 1) / 2
148
+
149
+
150
+ def plot_basis(basis_generator):
151
+ fig, ax = plt.subplots()
152
+ basis = [basis_generator(n) for n in range(0, 8)]
153
+ X = np.linspace(0, 1, 100)
154
+ for i in range(8):
155
+ ax.plot(basis[i](X), X)
156
+ return fig, ax
157
+
158
+
159
+ def moment_projection(field, n_layers, basis, integration_order=None):
160
+ if integration_order is None:
161
+ integration_order = max(len(basis), n_layers)
162
+ xi, wi = np.polynomial.legendre.leggauss(integration_order)
163
+ xi = shift_integration_interval(xi)
164
+ dz = 1 / (n_layers)
165
+ xp = np.arange(dz / 2, 1 - dz / 2, dz)
166
+ xp = np.insert(xp, 0, 0)
167
+ fp = field
168
+ field_xi = np.interp(xi, xp, fp)
169
+ basis_xi = [basis[i](xi) for i in range(len(basis))]
170
+ projections = np.zeros(len(basis))
171
+ for i in range(len(basis)):
172
+ projections[i] = np.sum(field_xi * basis_xi[i] * wi)
173
+ return projections
174
+
175
+
176
+ def convert_openfoam_to_moments_single(filename, n_levels):
177
+ vtkfile = load_file(filename)
178
+ coordinates = get_coordinates(vtkfile)
179
+ n_layer, n_elements_per_layer = get_number_of_layers_and_elements_in_plane(
180
+ coordinates
181
+ )
182
+ fields = get_fields(vtkfile, ["alpha.water", "U"])
183
+ sort_order = sort_data(coordinates, fields)
184
+ coordinates, fields = apply_order(coordinates, fields, sort_order)
185
+ fields[1] = add_noslip_layer(fields[1], n_elements_per_layer)
186
+ time = get_time(vtkfile)
187
+ Q, basis = compute_shallow_moment_projection(fields, coordinates, n_levels)
188
+ return coordinates, Q, time, basis
189
+
190
+
191
+ def convert_openfoam_to_moments(
192
+ filepath, n_levels, filepath_mesh_for_order, meshtype_order="triganle"
193
+ ):
194
+ filepath_vtk = os.path.join(filepath, "VTK")
195
+ filename = "fields_openfoam.hdf5"
196
+ sort_order = None
197
+
198
+ # file order
199
+ file_number_list = []
200
+ file_start = ""
201
+ for i_file, file in enumerate(os.listdir(filepath_vtk)):
202
+ if file.endswith(".vtm"):
203
+ file_start = file.split("_")[0]
204
+ file_start = file.rsplit("_", 1)[0]
205
+ index = int(file.rsplit("_", 1)[1].split(".")[0])
206
+ # index = int(re.findall(r'\d+', file)[-1])
207
+ file_number_list.append(index)
208
+
209
+ file_number_list.sort()
210
+ print(file_number_list)
211
+
212
+ # first iteration
213
+ file0 = (
214
+ os.path.join(filepath_vtk, file_start) + "_" + str(file_number_list[0]) + ".vtm"
215
+ )
216
+ coordinates, Q, time, basis = convert_openfoam_to_moments_single(file0, n_levels)
217
+ mesh_order = Mesh.load_gmsh(filepath_mesh_for_order, meshtype_order)
218
+ Q, sort_order = sort_fields_by_mesh(mesh_order, coordinates, Q)
219
+ if os.path.exists(os.path.join(filepath, filename)):
220
+ os.remove(os.path.join(filepath, filename))
221
+ save_fields_to_hdf5(filepath, 0, time, Q.T, Qaux=None, filename=filename)
222
+
223
+ # loop iterations
224
+ iter = 1
225
+ total = len(file_number_list)
226
+ print(f"Conversion {iter}/{total} completed.")
227
+ iter += 1
228
+ # loop iterations
229
+ for i, i_file in enumerate(file_number_list[1:]):
230
+ file = os.path.join(filepath_vtk, file_start) + "_" + str(i_file) + ".vtm"
231
+ coordinates, Q, time, basis = convert_openfoam_to_moments_single(file, n_levels)
232
+ Q = apply_order_to_fields(sort_order, Q)
233
+ save_fields_to_hdf5(filepath, i + 1, time, Q.T, Qaux=None, filename=filename)
234
+ print(f"Conversion {iter}/{total} completed.")
235
+ iter += 1
236
+
237
+
238
+ def sort_fields_by_mesh(mesh, coordinates, Q):
239
+ # coordinates are still 3d, while Q is 2d and the mesh is 2d
240
+ n_layers, n_elements_per_layer = get_number_of_layers_and_elements_in_plane(
241
+ coordinates
242
+ )
243
+ coords_2d = coordinates[:n_elements_per_layer, :2]
244
+ coords_ordered = mesh.element_center
245
+ # Construct a KDTree from coords_2d
246
+ tree = KDTree(coords_2d)
247
+
248
+ # Find the indices of the nearest points in coords_2d to the points in coords_ordered
249
+ _, indices = tree.query(coords_ordered)
250
+
251
+ # Use these indices to sort Q and coords_2d
252
+ Q_sorted = Q[:, indices]
253
+ return Q_sorted, indices
254
+
255
+
256
+ def apply_order_to_fields(order, Q):
257
+ return Q[:, order]
258
+
259
+
260
+ def plot_contour(coordinates, field):
261
+ if not _HAVE_MATPLOTLIB:
262
+ raise ImportError("matplotlib is required for plot_contour function.")
263
+ fig, ax = plt.subplots()
264
+ n_layer, n_elements_per_layer = get_number_of_layers_and_elements_in_plane(
265
+ coordinates
266
+ )
267
+ X = get_layer(coordinates[:, 0], 0, n_elements_per_layer)
268
+ Y = get_layer(coordinates[:, 1], 0, n_elements_per_layer)
269
+ # Z = get_layer(fields[1][:, 0], 1, n_elements_per_layer)
270
+ # Z = get_layer(fields[0], 12, n_elements_per_layer)
271
+ # Z = compute_height(fields[0], n_layer, n_elements_per_layer)
272
+ Z = field
273
+ colorbar = ax.tricontourf(X, Y, Z)
274
+ ax.set_aspect("equal")
275
+
276
+ circle = plt.Circle((0.5, 1), radius=0.2, fc="silver", zorder=10, edgecolor="k")
277
+ plt.gca().add_patch(circle)
278
+ fig.colorbar(colorbar)
279
+ return fig, ax
280
+
281
+
282
+ def basis_legendre(i):
283
+ def f(x):
284
+ basis = np.polynomial.legendre.Legendre.basis(i, domain=[0, 1], window=[-1, 1])
285
+ return basis(x) * basis(0)
286
+
287
+ return f
288
+
289
+
290
+ def compute_shallow_moment_projection(
291
+ fields, coordinates, n_levels, basis_generator=basis_legendre
292
+ ):
293
+ n_layers, n_elements_per_layer = get_number_of_layers_and_elements_in_plane(
294
+ coordinates
295
+ )
296
+ height = compute_height(fields[0], n_layers, n_elements_per_layer)
297
+ basis = [basis_generator(n) for n in range(0, n_levels + 1)]
298
+ alphas = np.zeros((n_elements_per_layer, n_levels + 1))
299
+ betas = np.zeros((n_elements_per_layer, n_levels + 1))
300
+ for i in range(n_elements_per_layer):
301
+ u, v, w = extract_velocity_column_at_coordinate(
302
+ fields[1], n_elements_per_layer, n_layers, i
303
+ )
304
+ alphas[i] = moment_projection(u, n_layers + 1, basis)
305
+ betas[i] = moment_projection(v, n_layers + 1, basis)
306
+ return np.concatenate(
307
+ (height.reshape((n_elements_per_layer, 1)), alphas, betas), axis=1
308
+ ).T, basis
309
+
310
+
311
+ def plot_data_vs_moments(fields, coordinates, Q, basis, coordinate_index):
312
+ if _HAVE_MATPLOTLIB is False:
313
+ raise ImportError("matplotlib is required for plot_data_vs_moments function.")
314
+ n_layers, n_elements_per_layer = get_number_of_layers_and_elements_in_plane(
315
+ coordinates
316
+ )
317
+ n_levels = int((Q.shape[0] - 1) / 2) - 1
318
+ X = np.linspace(0, 1, 100)
319
+ U = np.array(
320
+ [basis[i](X) * Q[1 + i, coordinate_index] for i in range(len(basis))]
321
+ ).sum(axis=0)
322
+ V = np.array(
323
+ [
324
+ basis[i](X) * Q[1 + n_levels + 1 + i, coordinate_index]
325
+ for i in range(len(basis))
326
+ ]
327
+ ).sum(axis=0)
328
+ dz = 1 / (n_layers)
329
+ x = np.linspace(dz / 2, 1 - dz / 2, n_layers)
330
+ x = np.insert(x, 0, 0)
331
+ u, v, w = extract_velocity_column_at_coordinate(
332
+ fields[1], n_elements_per_layer, n_layers, coordinate_index
333
+ )
334
+ fig, ax = plt.subplots(2)
335
+ ax[0].plot(U, X)
336
+ ax[0].plot(u, x)
337
+ ax[1].plot(V, X)
338
+ ax[1].plot(v, x)
339
+ return fig, ax
340
+
341
+
342
+ def load_openfoam_file(filepath):
343
+ vtkfile = load_file(filepath)
344
+ coordinates = get_coordinates(vtkfile)
345
+ n_layer, n_elements_per_layer = get_number_of_layers_and_elements_in_plane(
346
+ coordinates
347
+ )
348
+ fields = get_fields(vtkfile, ["alpha.water", "U"])
349
+ sort_order = sort_data(coordinates, fields)
350
+ coordinates, fields = apply_order(coordinates, fields, sort_order)
351
+ fields[1] = add_noslip_layer(fields[1], n_elements_per_layer)
352
+ time = get_time(vtkfile)
353
+ return coordinates, fields, time
354
+
355
+
356
+ def test_load():
357
+ filepath = os.path.join(
358
+ os.path.join(main_dir, "openfoam_data/channelflow_coarse"),
359
+ "channelflow_coarse_0.vtm",
360
+ )
361
+ coordinates, fields, time = load_openfoam_file(filepath)
362
+
363
+
364
+ def test_moment_projection():
365
+ filepath = os.path.join(
366
+ os.path.join(main_dir, "openfoam_data/channelflow_coarse"),
367
+ "channelflow_coarse_0.vtm",
368
+ )
369
+ coordinates, fields, time = load_openfoam_file(filepath)
370
+ Q, basis = compute_shallow_moment_projection(fields, coordinates, 3)
371
+
372
+
373
+ def test_convert_openfoam_single():
374
+ filepath = os.path.join(
375
+ os.path.join(main_dir, "openfoam_data/channelflow_coarse"),
376
+ "channelflow_coarse_0.vtm",
377
+ )
378
+ X, Q, t, basis = convert_openfoam_to_moments_single(filepath, 3)
379
+
380
+
381
+ def test_plots():
382
+ if _HAVE_MATPLOTLIB is False:
383
+ raise ImportError("matplotlib is required for test_plots function.")
384
+ filepath = os.path.join(
385
+ os.path.join(main_dir, "openfoam_data/channelflow_coarse"),
386
+ "channelflow_coarse_0.vtm",
387
+ )
388
+ coordinates, fields, time = load_openfoam_file(filepath)
389
+ X, Q, t, basis = convert_openfoam_to_moments_single(filepath, 3)
390
+ fig, ax = plot_data_vs_moments(fields, coordinates, Q, basis, 0)
391
+ plt.show()
392
+ fig, ax = plot_basis(basis_legendre)
393
+ plt.show()
394
+ fig, ax = plot_contour(coordinates, Q[0])
395
+ plt.show()
396
+
397
+
398
+ def test_sort():
399
+ filepath = os.path.join(
400
+ os.path.join(main_dir, "openfoam_data/channelflow_coarse"),
401
+ "channelflow_coarse_0.vtm",
402
+ )
403
+ filepath_gmsh = os.path.join(
404
+ os.path.join(main_dir, "meshes/channel_openfoam/mesh_coarse_2d.msh")
405
+ )
406
+
407
+ mesh_gmsh = Mesh.load_gmsh(filepath_gmsh, "triangle")
408
+ mesh_gmsh.write_to_hdf5(
409
+ os.path.join(os.path.join(main_dir, "openfoam_data/channelflow_coarse"))
410
+ )
411
+
412
+ filepath_hdf_mesh = os.path.join(
413
+ os.path.join(main_dir, "openfoam_data/channelflow_coarse/mesh.hdf5")
414
+ )
415
+ mesh = Mesh.from_hdf5(filepath_hdf_mesh)
416
+
417
+ coordinates, fields, time = load_openfoam_file(filepath)
418
+ Q, basis = compute_shallow_moment_projection(fields, coordinates, 3)
419
+
420
+ # mesh_comparison = Mesh.load_gmsh(os.path.join(main_dir, 'meshes/channel_openfoam/mesh_coarse_3d.msh'), 'tetra')
421
+
422
+ sort_fields_by_mesh(mesh, coordinates, Q)
423
+
424
+
425
+ def test_convert_openfoam_to_moments(level=0):
426
+ # filepath = os.path.join(main_dir, 'openfoam_data/channelflow_coarse')
427
+ foam_sim = os.getenv("FOAM_SIM")
428
+ filepath = os.path.join(foam_sim, "multiphase/interFoam/RAS/channelflow_mid")
429
+ filepath_target_mesh = os.path.join(
430
+ os.path.join(main_dir, "meshes/simple_openfoam/mesh_2d_mid.msh")
431
+ )
432
+ convert_openfoam_to_moments(
433
+ filepath, level, filepath_target_mesh, meshtype_order="triangle"
434
+ )
435
+
436
+
437
+ if __name__ == "__main__":
438
+ # test_load()
439
+ # test_moment_projection()
440
+ # test_convert_openfoam_single()
441
+ # test_plots()
442
+ # test_sort()
443
+ test_convert_openfoam_to_moments(level=1)
444
+ filepath = os.path.join(main_dir, "openfoam_data/channelflow_mid")
445
+ filepath_mesh = os.path.join(main_dir, "meshes/simple_openfoam/mesh_2d_mid.msh")
446
+ io.generate_vtk(
447
+ filepath,
448
+ filepath_gmsh=filepath_mesh,
449
+ gmsh_mesh_type="triangle",
450
+ filename_fields="fields_openfoam.hdf5",
451
+ filename_out="fields_openfoam_vtk",
452
+ skip_aux=True,
453
+ )
File without changes
@@ -0,0 +1,25 @@
1
+ from sympy import MatrixSymbol, fraction, cancel, Matrix
2
+
3
+ from zoomy_core.misc.misc import Zstruct
4
+
5
+ def regularize_denominator(expr, regularization_constant = 10**(-4), regularize = False):
6
+ if not regularize:
7
+ return expr
8
+ def regularize(expr):
9
+ (nom, den) = fraction(cancel(expr))
10
+ return nom * den / (den*2 + regularization_constant)
11
+ for i in range(expr.shape[0]):
12
+ for j in range(expr.shape[1]):
13
+ expr[i,j] = regularize(expr[i,j])
14
+ return expr
15
+
16
+ def substitute_sympy_attributes_with_symbol_matrix(expr: Matrix, attr: Zstruct, attr_matrix: MatrixSymbol):
17
+ if expr is None:
18
+ return None
19
+ if type(attr) is Zstruct:
20
+ assert attr.length() <= attr_matrix.shape[0]
21
+ for i, k in enumerate(attr.get_list()):
22
+ expr = Matrix(expr).subs(k, attr_matrix[i])
23
+ else:
24
+ expr = Matrix(expr).subs(attr, attr_matrix)
25
+ return expr