zoomy-core 0.1.1__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.
- zoomy_core/decorators/decorators.py +25 -0
- zoomy_core/fvm/flux.py +97 -0
- zoomy_core/fvm/nonconservative_flux.py +97 -0
- zoomy_core/fvm/ode.py +55 -0
- zoomy_core/fvm/solver_numpy.py +305 -0
- zoomy_core/fvm/timestepping.py +13 -0
- zoomy_core/mesh/gmsh_loader.py +301 -0
- zoomy_core/mesh/mesh.py +1192 -0
- zoomy_core/mesh/mesh_extrude.py +168 -0
- zoomy_core/mesh/mesh_util.py +487 -0
- zoomy_core/misc/custom_types.py +6 -0
- zoomy_core/misc/gui.py +61 -0
- zoomy_core/misc/interpolation.py +140 -0
- zoomy_core/misc/io.py +401 -0
- zoomy_core/misc/logger_config.py +18 -0
- zoomy_core/misc/misc.py +216 -0
- zoomy_core/misc/static_class.py +94 -0
- zoomy_core/model/analysis.py +147 -0
- zoomy_core/model/basefunction.py +113 -0
- zoomy_core/model/basemodel.py +512 -0
- zoomy_core/model/boundary_conditions.py +193 -0
- zoomy_core/model/initial_conditions.py +171 -0
- zoomy_core/model/model.py +63 -0
- zoomy_core/model/models/GN.py +70 -0
- zoomy_core/model/models/advection.py +53 -0
- zoomy_core/model/models/basisfunctions.py +181 -0
- zoomy_core/model/models/basismatrices.py +377 -0
- zoomy_core/model/models/core.py +564 -0
- zoomy_core/model/models/coupled_constrained.py +60 -0
- zoomy_core/model/models/old_smm copy.py +867 -0
- zoomy_core/model/models/poisson.py +41 -0
- zoomy_core/model/models/shallow_moments.py +757 -0
- zoomy_core/model/models/shallow_moments_sediment.py +378 -0
- zoomy_core/model/models/shallow_moments_topo.py +423 -0
- zoomy_core/model/models/shallow_moments_variants.py +1509 -0
- zoomy_core/model/models/shallow_water.py +266 -0
- zoomy_core/model/models/shallow_water_topo.py +111 -0
- zoomy_core/model/models/shear_shallow_flow.py +594 -0
- zoomy_core/model/models/sme_turbulent.py +613 -0
- zoomy_core/model/models/swe_old.py +1018 -0
- zoomy_core/model/models/vam.py +455 -0
- zoomy_core/postprocessing/postprocessing.py +72 -0
- zoomy_core/preprocessing/openfoam_moments.py +452 -0
- zoomy_core/transformation/helpers.py +25 -0
- zoomy_core/transformation/to_amrex.py +238 -0
- zoomy_core/transformation/to_c.py +181 -0
- zoomy_core/transformation/to_jax.py +14 -0
- zoomy_core/transformation/to_numpy.py +115 -0
- zoomy_core/transformation/to_openfoam.py +254 -0
- zoomy_core/transformation/to_ufl.py +67 -0
- {zoomy_core-0.1.1.dist-info → zoomy_core-0.1.2.dist-info}/METADATA +1 -1
- zoomy_core-0.1.2.dist-info/RECORD +55 -0
- zoomy_core-0.1.2.dist-info/top_level.txt +1 -0
- zoomy_core-0.1.1.dist-info/RECORD +0 -5
- zoomy_core-0.1.1.dist-info/top_level.txt +0 -1
- {zoomy_core-0.1.1.dist-info → zoomy_core-0.1.2.dist-info}/WHEEL +0 -0
- {zoomy_core-0.1.1.dist-info → zoomy_core-0.1.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
## DISCLAIMER: This file is a modified version of the mesh2xdmf converter used in dolfin (https://github.com/floiseau/msh2xdmf)
|
|
2
|
+
## Modifications:
|
|
3
|
+
## - should carry the boundary condition name as a tag, to be identifyable by name
|
|
4
|
+
## - allow for more element types
|
|
5
|
+
|
|
6
|
+
# import argparse
|
|
7
|
+
import meshio
|
|
8
|
+
import os
|
|
9
|
+
import numpy as np
|
|
10
|
+
|
|
11
|
+
# from configparser import ConfigParser
|
|
12
|
+
# from compas.datastructures import Mesh as MeshCompas
|
|
13
|
+
import h5py
|
|
14
|
+
|
|
15
|
+
from library.zoomy_core.mesh.mesh_util import get_global_cell_index_from_vertices
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def gmsh_to_domain_boundary_mesh(mesh_name, mesh_type="triangle", directory="."):
|
|
19
|
+
"""
|
|
20
|
+
Function converting a MSH mesh into XDMF files.
|
|
21
|
+
The XDMF files are:
|
|
22
|
+
- "domain.xdmf": the domain;
|
|
23
|
+
- "boundaries.xdmf": the boundaries physical groups from GMSH;
|
|
24
|
+
"""
|
|
25
|
+
# Set cell type
|
|
26
|
+
if mesh_type == "triangle":
|
|
27
|
+
cell_type = "triangle"
|
|
28
|
+
dim = 2
|
|
29
|
+
elif mesh_type == "quad":
|
|
30
|
+
cell_type = "quad"
|
|
31
|
+
dim = 2
|
|
32
|
+
elif mesh_type == "tetra":
|
|
33
|
+
cell_type = "tetra"
|
|
34
|
+
dim = 3
|
|
35
|
+
else:
|
|
36
|
+
assert False
|
|
37
|
+
|
|
38
|
+
# Get the mesh name has prefix
|
|
39
|
+
prefix = mesh_name.split(".")[0]
|
|
40
|
+
# Read the input mesh
|
|
41
|
+
msh = meshio.read("{}/{}".format(directory, mesh_name))
|
|
42
|
+
|
|
43
|
+
gmsh_association_table = _get_association_table(msh, prefix, directory)
|
|
44
|
+
# Generate the domain as cells_points
|
|
45
|
+
domain = export_domain(msh, mesh_type, directory, prefix)
|
|
46
|
+
# msh = fvm_mesh.Mesh.load_cell_point_mesh(cells, points, cell_type, dim, [] )
|
|
47
|
+
# compas_msh = MeshCompas.from_vertices_and_faces(points, cells)
|
|
48
|
+
# (
|
|
49
|
+
# dimension,
|
|
50
|
+
# type,
|
|
51
|
+
# n_elements,
|
|
52
|
+
# n_vertices,
|
|
53
|
+
# n_edges,
|
|
54
|
+
# n_nodes_per_element,
|
|
55
|
+
# vertex_coordinates,
|
|
56
|
+
# element_vertices,
|
|
57
|
+
# element_edge_length,
|
|
58
|
+
# element_centers,
|
|
59
|
+
# element_volume,
|
|
60
|
+
# element_incircle,
|
|
61
|
+
# element_edge_normal,
|
|
62
|
+
# element_neighbors,
|
|
63
|
+
# element_n_neighbors,
|
|
64
|
+
# ) = fvm_mesh.Mesh.from_comas_mesh_volume(compas_msh, mesh_type, dim)
|
|
65
|
+
|
|
66
|
+
# Generate the boundaries as cells points
|
|
67
|
+
boundaries = export_boundaries(
|
|
68
|
+
msh, mesh_type, directory, prefix, gmsh_association_table
|
|
69
|
+
)
|
|
70
|
+
# compas_msh = MeshCompas.from_vertices_and_faces(points, cells)
|
|
71
|
+
# runtime_boundaries_mesh = fvm_mesh.Mesh.from_comas_mesh_boundaries(compas_msh, mesh_type, dim)
|
|
72
|
+
return domain, boundaries
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def export_domain(msh, mesh_type, directory, prefix):
|
|
76
|
+
"""
|
|
77
|
+
Export the domain as well as the subdomains values. Export types are
|
|
78
|
+
- write to XDMF file
|
|
79
|
+
- return (simple) cells and point data. Simple means only one (the first) element type is returned.
|
|
80
|
+
"""
|
|
81
|
+
# Set cell type
|
|
82
|
+
if mesh_type == "triangle":
|
|
83
|
+
cell_type = "triangle"
|
|
84
|
+
dim = 2
|
|
85
|
+
elif mesh_type == "quad":
|
|
86
|
+
cell_type = "quad"
|
|
87
|
+
dim = 2
|
|
88
|
+
elif mesh_type == "tetra":
|
|
89
|
+
cell_type = "tetra"
|
|
90
|
+
dim = 3
|
|
91
|
+
else:
|
|
92
|
+
assert False
|
|
93
|
+
# Generate the cell block for the domain cells
|
|
94
|
+
data_array = []
|
|
95
|
+
for obj in msh.cells:
|
|
96
|
+
if obj.type == cell_type:
|
|
97
|
+
data_array.append(obj.data)
|
|
98
|
+
# data_array = [arr for (t, arr) in msh.cells if t == cell_type]
|
|
99
|
+
if len(data_array) == 0:
|
|
100
|
+
print("WARNING: No domain physical group found.")
|
|
101
|
+
return
|
|
102
|
+
else:
|
|
103
|
+
data = np.concatenate(data_array)
|
|
104
|
+
cells = [
|
|
105
|
+
meshio.CellBlock(
|
|
106
|
+
cell_type=cell_type,
|
|
107
|
+
data=data,
|
|
108
|
+
)
|
|
109
|
+
]
|
|
110
|
+
# Generate a meshio Mesh for the domain
|
|
111
|
+
domain = meshio.Mesh(
|
|
112
|
+
points=msh.points[:, :],
|
|
113
|
+
cells=cells,
|
|
114
|
+
# cell_data=cell_data,
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
return domain
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def export_boundaries(msh, mesh_type, directory, prefix, gmsh_association_table):
|
|
121
|
+
"""
|
|
122
|
+
Export the boundaries XDMF file.
|
|
123
|
+
"""
|
|
124
|
+
# Set the cell type
|
|
125
|
+
if mesh_type == "triangle":
|
|
126
|
+
cell_type = "line"
|
|
127
|
+
dim = 2
|
|
128
|
+
elif mesh_type == "quad":
|
|
129
|
+
cell_type = "line"
|
|
130
|
+
dim = 2
|
|
131
|
+
elif mesh_type == "tetra":
|
|
132
|
+
cell_type = "triangle"
|
|
133
|
+
dim = 3
|
|
134
|
+
else:
|
|
135
|
+
assert False
|
|
136
|
+
# Generate the cell block for the boundaries cells
|
|
137
|
+
# data_array = [arr for (t, arr) in msh.cells if t == cell_type]
|
|
138
|
+
offset = 0
|
|
139
|
+
data = []
|
|
140
|
+
tags = []
|
|
141
|
+
corresponding_cells = []
|
|
142
|
+
|
|
143
|
+
sort_order_list = []
|
|
144
|
+
for i, (cellBlock, physical_tag_ids) in enumerate(
|
|
145
|
+
zip(msh.cells, msh.cell_data["gmsh:physical"])
|
|
146
|
+
):
|
|
147
|
+
if cellBlock.type == cell_type:
|
|
148
|
+
data.append(cellBlock.data)
|
|
149
|
+
tags.append([gmsh_association_table[tag_id] for tag_id in physical_tag_ids])
|
|
150
|
+
corresponding_cells.append(
|
|
151
|
+
_get_boundary_edges_cells(msh, cellBlock.data, mesh_type)
|
|
152
|
+
)
|
|
153
|
+
sort_order_list.append(
|
|
154
|
+
(offset)
|
|
155
|
+
+ _sort_order_for_periodic_boundary_conditions(
|
|
156
|
+
dim, msh.points, cellBlock.data
|
|
157
|
+
)
|
|
158
|
+
)
|
|
159
|
+
offset += cellBlock.data.shape[0]
|
|
160
|
+
|
|
161
|
+
if len(data) == 0:
|
|
162
|
+
print("WARNING: No boundary physical group found.")
|
|
163
|
+
return
|
|
164
|
+
else:
|
|
165
|
+
data = np.concatenate(data)
|
|
166
|
+
tags = np.concatenate(tags)
|
|
167
|
+
corresponding_cells = np.concatenate(corresponding_cells)
|
|
168
|
+
sort_order = np.concatenate(sort_order_list)
|
|
169
|
+
boundaries_cells = [
|
|
170
|
+
meshio.CellBlock(
|
|
171
|
+
cell_type=cell_type,
|
|
172
|
+
data=data[sort_order],
|
|
173
|
+
)
|
|
174
|
+
]
|
|
175
|
+
|
|
176
|
+
cell_data = {
|
|
177
|
+
"boundary_tag": [tags[sort_order]],
|
|
178
|
+
"corresponding_cell": [corresponding_cells[sort_order]],
|
|
179
|
+
}
|
|
180
|
+
# Generate the boundaries cells data
|
|
181
|
+
# cell_data = {
|
|
182
|
+
# "boundary_tag": [
|
|
183
|
+
# np.concatenate(
|
|
184
|
+
# [
|
|
185
|
+
# [ gmsh_association_table[tag_id] for tag_id in msh.cell_data["gmsh:physical"][i] ]
|
|
186
|
+
# for i, cellBlock in enumerate(msh.cells)
|
|
187
|
+
# if cellBlock.type == cell_type
|
|
188
|
+
# ]
|
|
189
|
+
# )[sort_order]
|
|
190
|
+
# ],
|
|
191
|
+
# "corresponding_cell": [
|
|
192
|
+
# np.concatenate(
|
|
193
|
+
# [
|
|
194
|
+
# _get_boundary_edges_cells(msh, cellBlock.data)
|
|
195
|
+
# for i, cellBlock in enumerate(msh.cells)
|
|
196
|
+
# if cellBlock.type == cell_type
|
|
197
|
+
# ]
|
|
198
|
+
# )[sort_order]
|
|
199
|
+
# ]
|
|
200
|
+
# }
|
|
201
|
+
# Generate the meshio Mesh for the boundaries physical groups
|
|
202
|
+
boundaries = meshio.Mesh(
|
|
203
|
+
points=msh.points[:, :],
|
|
204
|
+
cells=boundaries_cells,
|
|
205
|
+
cell_data=cell_data,
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
return boundaries
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def _sort_order_for_periodic_boundary_conditions(dimension, points, data):
|
|
212
|
+
edge_coordinates = points[data]
|
|
213
|
+
center_coordinates = np.array(
|
|
214
|
+
[np.mean(edge_coordinates[i], axis=0) for i in range(edge_coordinates.shape[0])]
|
|
215
|
+
)
|
|
216
|
+
if dimension == 1:
|
|
217
|
+
indices_sorted = np.lexsort((center_coordinates[:, 0],))
|
|
218
|
+
elif dimension == 2:
|
|
219
|
+
indices_sorted = np.lexsort(
|
|
220
|
+
(
|
|
221
|
+
center_coordinates[:, 0],
|
|
222
|
+
center_coordinates[:, 1],
|
|
223
|
+
)
|
|
224
|
+
)
|
|
225
|
+
elif dimension == 3:
|
|
226
|
+
indices_sorted = np.lexsort(
|
|
227
|
+
(
|
|
228
|
+
center_coordinates[:, 0],
|
|
229
|
+
center_coordinates[:, 1],
|
|
230
|
+
center_coordinates[:, 2],
|
|
231
|
+
)
|
|
232
|
+
)
|
|
233
|
+
else:
|
|
234
|
+
assert False
|
|
235
|
+
return indices_sorted
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def _get_boundary_edges_cells(msh, list_of_edges, element_type):
|
|
239
|
+
results = np.empty(len(list_of_edges), dtype=int)
|
|
240
|
+
for i_edge, edge in enumerate(list_of_edges):
|
|
241
|
+
# hit = get_global_cell_index_from_vertices(msh.cells[-1].data, edge)
|
|
242
|
+
offset = 0
|
|
243
|
+
for cell in msh.cells:
|
|
244
|
+
if cell.type == element_type:
|
|
245
|
+
hit = get_global_cell_index_from_vertices(
|
|
246
|
+
cell.data, edge, return_first=True, offset=offset
|
|
247
|
+
)
|
|
248
|
+
if hit != []:
|
|
249
|
+
break
|
|
250
|
+
offset += cell.data.shape[0]
|
|
251
|
+
assert hit is not False
|
|
252
|
+
assert hit is not []
|
|
253
|
+
results[i_edge] = hit
|
|
254
|
+
return list(results)
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
def _get_association_table(msh, prefix="mesh", directory=".", verbose=True):
|
|
258
|
+
"""
|
|
259
|
+
Display the association between the physical group label and the mesh
|
|
260
|
+
value.
|
|
261
|
+
"""
|
|
262
|
+
# Create association table
|
|
263
|
+
association_table = {}
|
|
264
|
+
|
|
265
|
+
for label, arrays in msh.cell_sets.items():
|
|
266
|
+
# Get the index of the array in arrays
|
|
267
|
+
for i, array in enumerate(arrays):
|
|
268
|
+
if array.size != 0:
|
|
269
|
+
index = i
|
|
270
|
+
# Added check to make sure that the association table
|
|
271
|
+
# doesn't try to import irrelevant information.
|
|
272
|
+
if label != "gmsh:bounding_entities":
|
|
273
|
+
value = msh.cell_data["gmsh:physical"][index][0]
|
|
274
|
+
# Store the association table in a dictionnary
|
|
275
|
+
association_table[value] = label
|
|
276
|
+
return association_table
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
if __name__ == "__main__":
|
|
280
|
+
# parser = argparse.ArgumentParser()
|
|
281
|
+
# parser.add_argument(
|
|
282
|
+
# "msh_file",
|
|
283
|
+
# help="input .msh file",
|
|
284
|
+
# type=str,
|
|
285
|
+
# )
|
|
286
|
+
# parser.add_argument(
|
|
287
|
+
# "-d",
|
|
288
|
+
# "--dimension",
|
|
289
|
+
# help="dimension of the domain",
|
|
290
|
+
# type=int,
|
|
291
|
+
# default=2,
|
|
292
|
+
# )
|
|
293
|
+
# args = parser.parse_args()
|
|
294
|
+
# # Get current directory
|
|
295
|
+
# current_directory = os.getcwd()
|
|
296
|
+
# # Conert the mesh
|
|
297
|
+
# msh2xdmf(args.msh_file, args.dimension, directory=current_directory)
|
|
298
|
+
# msh2xdmf('./meshes/tetra_3d/mesh.msh', 'tetra', './')
|
|
299
|
+
# msh2xdmf('./meshes/tetra_3d/test.msh', 'tetra', './')
|
|
300
|
+
# msh2runtime_fvm_mesh_simple('./meshes/tetra_3d/test.msh', 'tetra', './')
|
|
301
|
+
msh2runtime_fvm_mesh_simple("./meshes/quad_2d/mesh_coarse.msh", "quad", "./")
|