phiFEM 0.7.0.dev1__py3-none-any.whl → 0.7.1.dev1__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.
- phifem/mesh_scripts.py +153 -130
- {phifem-0.7.0.dev1.dist-info → phifem-0.7.1.dev1.dist-info}/METADATA +11 -1
- phifem-0.7.1.dev1.dist-info/RECORD +7 -0
- {phifem-0.7.0.dev1.dist-info → phifem-0.7.1.dev1.dist-info}/WHEEL +1 -1
- phifem-0.7.0.dev1.dist-info/RECORD +0 -7
- {phifem-0.7.0.dev1.dist-info → phifem-0.7.1.dev1.dist-info}/licenses/COPYING +0 -0
- {phifem-0.7.0.dev1.dist-info → phifem-0.7.1.dev1.dist-info}/licenses/COPYING.lesser +0 -0
phifem/mesh_scripts.py
CHANGED
|
@@ -118,22 +118,19 @@ def _compute_detection_vector(
|
|
|
118
118
|
detection_denom_form = dfx.fem.form(detection_denom)
|
|
119
119
|
detection_denom_vec = assemble_vector(detection_denom_form)
|
|
120
120
|
|
|
121
|
-
imap = dg_0_space.dofmap.index_map
|
|
122
|
-
detection_vector = dfx.la.vector(imap)
|
|
123
121
|
# detection_denom_vec is not supposed to be zero, this would mean that the levelset is zero at all dofs in a cell.
|
|
124
122
|
# However, in practice it can happen that for a very small cut triangle, detection_denom_vec is of the order of the machine precision.
|
|
125
123
|
# In this case, we set the value of detection_vector to 0.5, meaning we consider the cell as cut.
|
|
124
|
+
mask = np.where(detection_denom_vec.array > 0.0)
|
|
125
|
+
detection_vector = np.full_like(detection_num_vec.array, 0.5)
|
|
126
|
+
detection_vector[mask] = (
|
|
127
|
+
detection_num_vec.array[mask] / detection_denom_vec.array[mask]
|
|
128
|
+
)
|
|
126
129
|
if np.any(np.isclose(detection_denom_vec.array, 0.0)):
|
|
127
130
|
warnings.warn(
|
|
128
|
-
"The
|
|
131
|
+
"The detection function is zero everywhere on a cell. We mark it as 'cut' but this can be incorrect and should be carefully checked.",
|
|
129
132
|
RuntimeWarning,
|
|
130
133
|
)
|
|
131
|
-
mask = np.where(detection_denom_vec.array > 0.0)
|
|
132
|
-
detection_vector.array[:] = 0.5
|
|
133
|
-
detection_vector.array[mask] = (
|
|
134
|
-
detection_num_vec.array[mask] / detection_denom_vec.array[mask]
|
|
135
|
-
)
|
|
136
|
-
detection_vector.scatter_forward()
|
|
137
134
|
return detection_vector
|
|
138
135
|
|
|
139
136
|
|
|
@@ -217,31 +214,71 @@ def _reshape_map(connect: AdjacencyList_int32) -> npt.NDArray[np.int32]:
|
|
|
217
214
|
return emap, max_offset
|
|
218
215
|
|
|
219
216
|
|
|
220
|
-
def
|
|
221
|
-
|
|
217
|
+
def _transfer_tags(
|
|
218
|
+
source_mesh_tags: MeshTags,
|
|
219
|
+
dest_mesh: Mesh,
|
|
222
220
|
cmap: npt.NDArray[Any],
|
|
223
|
-
|
|
224
|
-
) ->
|
|
221
|
+
source_mesh: Mesh = None,
|
|
222
|
+
) -> MeshTags:
|
|
225
223
|
"""Given entities tags (cells or facets) from a source mesh, a destination mesh and the source mesh-destination mesh cells mapping, transfers the entities tags to the destination mesh.
|
|
226
224
|
|
|
227
225
|
Args:
|
|
228
|
-
|
|
226
|
+
source_mesh_tags: the tags on the source mesh.
|
|
229
227
|
dest_mesh: the destination mesh.
|
|
230
228
|
cmap: the source mesh-destination mesh cells mapping.
|
|
229
|
+
source_mesh: the source mesh mandatory to transfer facets tags.
|
|
231
230
|
|
|
232
231
|
Returns:
|
|
233
232
|
Cells tags on the destination mesh.
|
|
234
233
|
"""
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
234
|
+
cdim = dest_mesh.topology.dim
|
|
235
|
+
fdim = cdim - 1
|
|
236
|
+
edim = source_mesh_tags.dim
|
|
237
|
+
|
|
238
|
+
if edim == cdim:
|
|
239
|
+
emap = cmap
|
|
240
|
+
elif edim == fdim:
|
|
241
|
+
if source_mesh is None:
|
|
242
|
+
raise ValueError("You must pass a source_mesh to transfer facets tags.")
|
|
243
|
+
|
|
244
|
+
source_mesh.topology.create_connectivity(cdim, fdim)
|
|
245
|
+
c2f_connect = source_mesh.topology.connectivity(cdim, fdim)
|
|
246
|
+
num_facets_per_cell = len(c2f_connect.links(0))
|
|
247
|
+
source_c2f_map = np.reshape(c2f_connect.array, (-1, num_facets_per_cell))
|
|
248
|
+
dest_mesh.topology.create_connectivity(cdim, fdim)
|
|
249
|
+
c2f_connect = dest_mesh.topology.connectivity(cdim, fdim)
|
|
250
|
+
num_facets_per_cell = len(c2f_connect.links(0))
|
|
251
|
+
dest_c2f_map = np.reshape(c2f_connect.array, (-1, num_facets_per_cell))
|
|
252
|
+
source_c2f_dest_map = source_c2f_map[cmap]
|
|
253
|
+
source_c2f_dest_map = source_c2f_dest_map.reshape(
|
|
254
|
+
-1,
|
|
255
|
+
)
|
|
256
|
+
dest_c2f_map = dest_c2f_map.reshape(
|
|
257
|
+
-1,
|
|
258
|
+
)
|
|
259
|
+
unique_indices, sorted_indices = np.unique(dest_c2f_map, return_index=True)
|
|
260
|
+
emap = source_c2f_dest_map[sorted_indices]
|
|
261
|
+
else:
|
|
262
|
+
raise ValueError("The source_mesh_tags can only be cells tags or facets tags.")
|
|
263
|
+
|
|
264
|
+
# TODO: change this line to allow parallel computing
|
|
265
|
+
source_tags = source_mesh_tags.values
|
|
266
|
+
|
|
267
|
+
dest_entities = np.arange(len(emap))
|
|
268
|
+
dest_tags = source_tags[emap]
|
|
269
|
+
|
|
270
|
+
dest_entities_indices = np.hstack(dest_entities).astype(np.int32)
|
|
271
|
+
dest_entities_markers = np.hstack(dest_tags).astype(np.int32)
|
|
272
|
+
sorted_indices = np.argsort(dest_entities_indices)
|
|
273
|
+
|
|
274
|
+
dest_entities_tags = dfx.mesh.meshtags(
|
|
275
|
+
dest_mesh,
|
|
276
|
+
edim,
|
|
277
|
+
dest_entities_indices[sorted_indices],
|
|
278
|
+
dest_entities_markers[sorted_indices],
|
|
240
279
|
)
|
|
241
|
-
dest_markers = dfx.la.vector(sub_index_map)
|
|
242
|
-
dest_markers.array[:] = source_markers.array[emap]
|
|
243
280
|
|
|
244
|
-
return
|
|
281
|
+
return dest_entities_tags
|
|
245
282
|
|
|
246
283
|
|
|
247
284
|
def _tag_cells(
|
|
@@ -249,7 +286,7 @@ def _tag_cells(
|
|
|
249
286
|
discrete_levelset: Function,
|
|
250
287
|
detection_degree: int,
|
|
251
288
|
single_layer_cut: bool = False,
|
|
252
|
-
) ->
|
|
289
|
+
) -> MeshTags:
|
|
253
290
|
"""Tag the mesh cells by computing detection = Σ f(dof)/Σ|f(dof)| where 'dof' are coming from a custom quadrature rule with points on the boundary of the cell only.
|
|
254
291
|
Strictly inside cell => tag 1
|
|
255
292
|
Cut cell => tag 2
|
|
@@ -262,7 +299,7 @@ def _tag_cells(
|
|
|
262
299
|
single_layer_cut: boolean, if True force a single layer of cut cells.
|
|
263
300
|
|
|
264
301
|
Returns:
|
|
265
|
-
The cells
|
|
302
|
+
The cells tags as a MeshTags object.
|
|
266
303
|
"""
|
|
267
304
|
if single_layer_cut:
|
|
268
305
|
cdim = mesh.topology.dim
|
|
@@ -304,12 +341,10 @@ def _tag_cells(
|
|
|
304
341
|
mesh, discrete_levelset, detection_measure
|
|
305
342
|
)
|
|
306
343
|
cut_indices = np.where(
|
|
307
|
-
np.logical_and(
|
|
308
|
-
detection_vector.array[:] > -1.0, detection_vector.array[:] < 1.0
|
|
309
|
-
)
|
|
344
|
+
np.logical_and(detection_vector > -1.0, detection_vector < 1.0)
|
|
310
345
|
)[0]
|
|
311
|
-
exterior_indices = np.where(
|
|
312
|
-
interior_indices = np.where(
|
|
346
|
+
exterior_indices = np.where(detection_vector == 1.0)[0]
|
|
347
|
+
interior_indices = np.where(detection_vector == -1.0)[0]
|
|
313
348
|
|
|
314
349
|
if single_layer_cut:
|
|
315
350
|
neighbor_cells = np.reshape(
|
|
@@ -337,21 +372,30 @@ def _tag_cells(
|
|
|
337
372
|
assert np.logical_not(np.isin(exterior_indices, interior_indices).any()), (
|
|
338
373
|
"The sets of outside cells and inside cells have a non-empty intersection"
|
|
339
374
|
)
|
|
340
|
-
cells_markers = dfx.la.vector(detection_vector.index_map)
|
|
341
|
-
cells_markers.array[interior_indices] = 1
|
|
342
|
-
cells_markers.array[cut_indices] = 2
|
|
343
|
-
cells_markers.array[exterior_indices] = 3
|
|
344
|
-
cells_markers.scatter_forward()
|
|
345
375
|
|
|
346
|
-
|
|
376
|
+
# Create the meshtags from the indices.
|
|
377
|
+
indices = np.hstack([exterior_indices, interior_indices, cut_indices]).astype(
|
|
378
|
+
np.int32
|
|
379
|
+
)
|
|
380
|
+
interior_marker = np.full_like(interior_indices, 1).astype(np.int32)
|
|
381
|
+
exterior_marker = np.full_like(exterior_indices, 3).astype(np.int32)
|
|
382
|
+
cut_marker = np.full_like(cut_indices, 2).astype(np.int32)
|
|
383
|
+
markers = np.hstack([exterior_marker, interior_marker, cut_marker]).astype(np.int32)
|
|
384
|
+
sorted_indices = np.argsort(indices)
|
|
385
|
+
|
|
386
|
+
cells_tags = dfx.mesh.meshtags(
|
|
387
|
+
mesh, mesh.topology.dim, indices[sorted_indices], markers[sorted_indices]
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
return cells_tags
|
|
347
391
|
|
|
348
392
|
|
|
349
393
|
def _tag_facets(
|
|
350
394
|
mesh: Mesh,
|
|
351
|
-
|
|
395
|
+
cells_tags: MeshTags,
|
|
352
396
|
discrete_levelset: Function,
|
|
353
397
|
detection_degree: int,
|
|
354
|
-
) ->
|
|
398
|
+
) -> MeshTags:
|
|
355
399
|
"""Tag the mesh facets.
|
|
356
400
|
Strictly interior facets => tag 1
|
|
357
401
|
Cut facets => tag 2
|
|
@@ -362,13 +406,12 @@ def _tag_facets(
|
|
|
362
406
|
|
|
363
407
|
Args:
|
|
364
408
|
mesh: the background mesh.
|
|
365
|
-
|
|
409
|
+
cells_tags: the MeshTags object containing cells tags.
|
|
366
410
|
discrete_levelset: the discretization of the levelset.
|
|
367
411
|
detection_degree: the degree of the custom quadrature rule used to detect cut entities.
|
|
368
412
|
|
|
369
413
|
Returns:
|
|
370
|
-
The facets
|
|
371
|
-
The wireframe mesh containing all facets.
|
|
414
|
+
The facets tags as a MeshTags object.
|
|
372
415
|
"""
|
|
373
416
|
cdim = mesh.topology.dim
|
|
374
417
|
fdim = cdim - 1
|
|
@@ -379,9 +422,9 @@ def _tag_facets(
|
|
|
379
422
|
c2f_map = np.reshape(c2f_connect.array, (-1, num_facets_per_cell))
|
|
380
423
|
|
|
381
424
|
# Get tagged cells
|
|
382
|
-
interior_cells =
|
|
383
|
-
cut_cells =
|
|
384
|
-
exterior_cells =
|
|
425
|
+
interior_cells = cells_tags.find(1)
|
|
426
|
+
cut_cells = cells_tags.find(2)
|
|
427
|
+
exterior_cells = cells_tags.find(3)
|
|
385
428
|
|
|
386
429
|
# Check which background mesh boundary facets are cut by the interface
|
|
387
430
|
background_mesh_boundary_facets = dfx.mesh.locate_entities_boundary(
|
|
@@ -403,7 +446,7 @@ def _tag_facets(
|
|
|
403
446
|
mesh, discrete_levelset, detection_measure
|
|
404
447
|
)
|
|
405
448
|
mask_cut_indices_cells = np.logical_and(
|
|
406
|
-
detection_vector
|
|
449
|
+
detection_vector > -1.0, detection_vector < 1.0
|
|
407
450
|
)
|
|
408
451
|
cut_indices_cells = np.where(mask_cut_indices_cells)[0]
|
|
409
452
|
comp_indices_cells = np.where(np.logical_not(mask_cut_indices_cells))[0]
|
|
@@ -477,26 +520,52 @@ def _tag_facets(
|
|
|
477
520
|
+ " have a non-empty intersection!"
|
|
478
521
|
)
|
|
479
522
|
|
|
480
|
-
#
|
|
481
|
-
|
|
482
|
-
|
|
523
|
+
# Create the meshtags from the indices.
|
|
524
|
+
indices = np.hstack(
|
|
525
|
+
[
|
|
526
|
+
exterior_facets,
|
|
527
|
+
interior_facets,
|
|
528
|
+
interior_boundary_facets,
|
|
529
|
+
cut_facets,
|
|
530
|
+
boundary_facets,
|
|
531
|
+
direct_interface_facets,
|
|
532
|
+
]
|
|
533
|
+
).astype(np.int32)
|
|
534
|
+
interior_marker = np.full_like(interior_facets, 1).astype(np.int32)
|
|
535
|
+
cut_marker = np.full_like(cut_facets, 2).astype(np.int32)
|
|
536
|
+
interior_boundary_marker = np.full_like(interior_boundary_facets, 3).astype(
|
|
537
|
+
np.int32
|
|
483
538
|
)
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
539
|
+
boundary_marker = np.full_like(boundary_facets, 4).astype(np.int32)
|
|
540
|
+
exterior_marker = np.full_like(exterior_facets, 5).astype(np.int32)
|
|
541
|
+
direct_interface_marker = np.full_like(direct_interface_facets, 6).astype(np.int32)
|
|
542
|
+
markers = np.hstack(
|
|
543
|
+
[
|
|
544
|
+
exterior_marker,
|
|
545
|
+
interior_marker,
|
|
546
|
+
interior_boundary_marker,
|
|
547
|
+
cut_marker,
|
|
548
|
+
boundary_marker,
|
|
549
|
+
direct_interface_marker,
|
|
550
|
+
]
|
|
551
|
+
).astype(np.int32)
|
|
552
|
+
sorted_indices = np.argsort(indices)
|
|
490
553
|
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
facets_markers.array[boundary_facets] = 4
|
|
495
|
-
facets_markers.array[exterior_facets] = 5
|
|
496
|
-
facets_markers.array[direct_interface_facets] = 6
|
|
497
|
-
facets_markers.scatter_forward()
|
|
554
|
+
facets_tags = dfx.mesh.meshtags(
|
|
555
|
+
mesh, fdim, indices[sorted_indices], markers[sorted_indices]
|
|
556
|
+
)
|
|
498
557
|
|
|
499
|
-
return
|
|
558
|
+
return facets_tags
|
|
559
|
+
|
|
560
|
+
|
|
561
|
+
def _overwrite_tags(mesh, tags_to_overwrite, new_tags):
|
|
562
|
+
stack_indices = np.hstack([new_tags.indices, tags_to_overwrite.indices])
|
|
563
|
+
stack_values = np.hstack([new_tags.values, tags_to_overwrite.values])
|
|
564
|
+
overwritten_indices, ind = np.unique(stack_indices, return_index=True)
|
|
565
|
+
overwritten_values = stack_values[ind]
|
|
566
|
+
|
|
567
|
+
overwritten_tags = dfx.mesh.meshtags(mesh, tags_to_overwrite.dim, overwritten_indices, overwritten_values)
|
|
568
|
+
return overwritten_tags
|
|
500
569
|
|
|
501
570
|
|
|
502
571
|
def compute_tags_measures(
|
|
@@ -505,6 +574,7 @@ def compute_tags_measures(
|
|
|
505
574
|
detection_degree: int,
|
|
506
575
|
box_mode: bool = False,
|
|
507
576
|
single_layer_cut: bool = False,
|
|
577
|
+
overwrite_tags: dict[str,MeshTags] | dict = {},
|
|
508
578
|
) -> Tuple[
|
|
509
579
|
MeshTags,
|
|
510
580
|
MeshTags,
|
|
@@ -528,34 +598,31 @@ def compute_tags_measures(
|
|
|
528
598
|
The boundaries measure.
|
|
529
599
|
Submesh c-map, v-map and n-map.
|
|
530
600
|
"""
|
|
531
|
-
|
|
601
|
+
cells_tags = _tag_cells(
|
|
532
602
|
mesh, discrete_levelset, detection_degree, single_layer_cut=single_layer_cut
|
|
533
603
|
)
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
)
|
|
604
|
+
facets_tags = _tag_facets(mesh, cells_tags, discrete_levelset, detection_degree)
|
|
605
|
+
|
|
606
|
+
if "cells" in overwrite_tags.keys():
|
|
607
|
+
ow_cells_tags = overwrite_tags["cells"]
|
|
608
|
+
if np.any(np.isin([1, 2, 3], ow_cells_tags.values)):
|
|
609
|
+
raise ValueError("Cannot overwrite cells tags with values 1, 2 or 3.")
|
|
610
|
+
cells_tags = _overwrite_tags(mesh, cells_tags, ow_cells_tags)
|
|
611
|
+
if "facets" in overwrite_tags.keys():
|
|
612
|
+
ow_facets_tags = overwrite_tags["facets"]
|
|
613
|
+
if np.any(np.isin([1, 2, 3, 4, 5, 6, 100, 101], ow_facets_tags.values)):
|
|
614
|
+
raise ValueError("Cannot overwrite facets tags with values 1, 2, 3, 4, 5, 6, 100 or 101.")
|
|
615
|
+
facets_tags = _overwrite_tags(mesh, facets_tags, ow_facets_tags)
|
|
537
616
|
|
|
538
617
|
if box_mode:
|
|
539
618
|
submesh = None
|
|
540
|
-
integration_cells = np.union1d(
|
|
541
|
-
np.where(np.isclose(cells_markers.array[:], 2)),
|
|
542
|
-
np.where(np.isclose(cells_markers.array[:], 1)),
|
|
543
|
-
)
|
|
619
|
+
integration_cells = np.union1d(cells_tags.find(2), cells_tags.find(1))
|
|
544
620
|
integration_entities_outside = _compute_integration_entities(
|
|
545
|
-
mesh,
|
|
546
|
-
integration_cells,
|
|
547
|
-
np.where(np.isclose(facets_markers.array[:], 4)),
|
|
548
|
-
100,
|
|
549
|
-
)
|
|
550
|
-
integration_cells = np.union1d(
|
|
551
|
-
np.where(np.isclose(cells_markers.array[:], 2)),
|
|
552
|
-
np.where(np.isclose(cells_markers.array[:], 3)),
|
|
621
|
+
mesh, integration_cells, facets_tags.find(4), 100
|
|
553
622
|
)
|
|
623
|
+
integration_cells = np.union1d(cells_tags.find(2), cells_tags.find(3))
|
|
554
624
|
integration_entities_inside = _compute_integration_entities(
|
|
555
|
-
mesh,
|
|
556
|
-
integration_cells,
|
|
557
|
-
np.where(np.isclose(facets_markers.array[:], 3)),
|
|
558
|
-
101,
|
|
625
|
+
mesh, integration_cells, facets_tags.find(3), 101
|
|
559
626
|
)
|
|
560
627
|
combined_integration_entities = (
|
|
561
628
|
integration_entities_outside + integration_entities_inside
|
|
@@ -565,61 +632,17 @@ def compute_tags_measures(
|
|
|
565
632
|
"ds", domain=mesh, subdomain_data=combined_integration_entities
|
|
566
633
|
)
|
|
567
634
|
submesh_maps = None
|
|
568
|
-
indices = np.arange(
|
|
569
|
-
cells_markers.index_map.size_local + cells_markers.index_map.num_ghosts
|
|
570
|
-
)
|
|
571
|
-
cells_tags = dfx.mesh.meshtags(
|
|
572
|
-
mesh, mesh.topology.dim, indices, cells_markers.array[:]
|
|
573
|
-
)
|
|
574
|
-
indices = np.arange(
|
|
575
|
-
facets_markers.index_map.size_local + facets_markers.index_map.num_ghosts
|
|
576
|
-
)
|
|
577
|
-
facets_tags = dfx.mesh.meshtags(
|
|
578
|
-
mesh, mesh.topology.dim - 1, indices, facets_markers.array[:]
|
|
579
|
-
)
|
|
580
635
|
else:
|
|
581
636
|
# We create the submesh
|
|
582
|
-
omega_h_cells = np.unique(
|
|
583
|
-
np.hstack(
|
|
584
|
-
[
|
|
585
|
-
np.where(np.isclose(cells_markers.array[:], 1)),
|
|
586
|
-
np.where(np.isclose(cells_markers.array[:], 2)),
|
|
587
|
-
]
|
|
588
|
-
)
|
|
589
|
-
)
|
|
637
|
+
omega_h_cells = np.unique(np.hstack([cells_tags.find(1), cells_tags.find(2)]))
|
|
590
638
|
submesh, c_map, v_map, n_map = dfx.mesh.create_submesh(
|
|
591
639
|
mesh, mesh.topology.dim, omega_h_cells
|
|
592
|
-
)
|
|
593
|
-
submesh_maps = [c_map, v_map, n_map]
|
|
640
|
+
) # type: ignore
|
|
594
641
|
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
)
|
|
598
|
-
submesh.topology.create_entities(submesh.topology.dim - 1)
|
|
599
|
-
submesh_imap = submesh.topology.index_map(submesh.topology.dim - 1)
|
|
600
|
-
submesh_facets = np.arange(submesh_imap.size_local + submesh_imap.num_ghosts)
|
|
601
|
-
wf_submesh, wf_map = dfx.mesh.create_submesh(
|
|
602
|
-
submesh, submesh.topology.dim - 1, submesh_facets
|
|
603
|
-
)[:2]
|
|
604
|
-
wf_submesh.topology.create_entities(wf_submesh.topology.dim)
|
|
605
|
-
facets_markers_subwf = _transfer_markers(
|
|
606
|
-
facets_markers, wf_map, submesh.topology.dim - 1
|
|
607
|
-
)
|
|
642
|
+
cells_tags = _transfer_tags(cells_tags, submesh, c_map)
|
|
643
|
+
facets_tags = _transfer_tags(facets_tags, submesh, c_map, source_mesh=mesh)
|
|
608
644
|
boundaries_measure = ufl.Measure("ds", domain=submesh)
|
|
609
|
-
|
|
610
|
-
indices = np.arange(
|
|
611
|
-
cells_markers_submesh.index_map.size_local
|
|
612
|
-
+ cells_markers_submesh.index_map.num_ghosts
|
|
613
|
-
)
|
|
614
|
-
cells_tags = dfx.mesh.meshtags(
|
|
615
|
-
submesh, submesh.topology.dim, indices, cells_markers_submesh.array[:]
|
|
616
|
-
)
|
|
617
|
-
facets_tags = dfx.mesh.meshtags(
|
|
618
|
-
submesh,
|
|
619
|
-
submesh.topology.dim - 1,
|
|
620
|
-
submesh_facets,
|
|
621
|
-
facets_markers_subwf.array[submesh_facets],
|
|
622
|
-
)
|
|
645
|
+
submesh_maps = [c_map, v_map, n_map]
|
|
623
646
|
|
|
624
647
|
return (
|
|
625
648
|
cells_tags,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: phiFEM
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.1.dev1
|
|
4
4
|
Summary: phiFEM: convenience tools to use the phiFEM immersed boundary finite element method with dolfinx.
|
|
5
5
|
Project-URL: Homepage, https://github.com/PhiFEM/phiFEM
|
|
6
6
|
Project-URL: Issues, https://github.com/PhiFEM/phiFEM/issues
|
|
@@ -113,6 +113,16 @@ To run the demos first clone the repository.
|
|
|
113
113
|
pytest
|
|
114
114
|
```
|
|
115
115
|
|
|
116
|
+
## Disclaimer
|
|
117
|
+
|
|
118
|
+
The author Raphaël Bulle guarantees that his contributions to this project are generative-ai-free.
|
|
119
|
+
|
|
120
|
+
<p align="center" width="50%">
|
|
121
|
+
<img width="30%" src="https://github.com/PhiFEM/phiFEM/raw/main/logo/sw_wbg.png">
|
|
122
|
+
</p>
|
|
123
|
+
|
|
124
|
+
For more information, see [here (in french)](https://doi.org/10.58079/1591s).
|
|
125
|
+
|
|
116
126
|
## License
|
|
117
127
|
|
|
118
128
|
`phiFEM` is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
phifem/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
phifem/mesh_scripts.py,sha256=mFbgpjs3tAmMOdMQYZCXICh91YIcwhKjE5lXmEUIcWw,25772
|
|
3
|
+
phifem-0.7.1.dev1.dist-info/METADATA,sha256=9-pTFrhjCVyvyK25xFdzNOS8jeD1IgYGpf6N2OI9GqU,5603
|
|
4
|
+
phifem-0.7.1.dev1.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
|
|
5
|
+
phifem-0.7.1.dev1.dist-info/licenses/COPYING,sha256=xTplwv1WHIfqq_EHLvXcq4ZTBCvBUwhGX1JBNYXrYnE,35146
|
|
6
|
+
phifem-0.7.1.dev1.dist-info/licenses/COPYING.lesser,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
|
|
7
|
+
phifem-0.7.1.dev1.dist-info/RECORD,,
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
phifem/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
phifem/mesh_scripts.py,sha256=jVRTsIQRmEffTfhWHyJrqiImqtWZoiCBnSpuhW4W-Ho,24614
|
|
3
|
-
phifem-0.7.0.dev1.dist-info/METADATA,sha256=R0NitwqmCfRUTMiH-p907mLfKPWTX1RTEXJaKO-f0YY,5285
|
|
4
|
-
phifem-0.7.0.dev1.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
5
|
-
phifem-0.7.0.dev1.dist-info/licenses/COPYING,sha256=xTplwv1WHIfqq_EHLvXcq4ZTBCvBUwhGX1JBNYXrYnE,35146
|
|
6
|
-
phifem-0.7.0.dev1.dist-info/licenses/COPYING.lesser,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
|
|
7
|
-
phifem-0.7.0.dev1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|