phiFEM 0.8.0.dev1__py3-none-any.whl → 0.8.2.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 +73 -42
- {phifem-0.8.0.dev1.dist-info → phifem-0.8.2.dev1.dist-info}/METADATA +2 -2
- phifem-0.8.2.dev1.dist-info/RECORD +7 -0
- {phifem-0.8.0.dev1.dist-info → phifem-0.8.2.dev1.dist-info}/WHEEL +1 -1
- phifem-0.8.0.dev1.dist-info/RECORD +0 -7
- {phifem-0.8.0.dev1.dist-info → phifem-0.8.2.dev1.dist-info}/licenses/COPYING +0 -0
- {phifem-0.8.0.dev1.dist-info → phifem-0.8.2.dev1.dist-info}/licenses/COPYING.lesser +0 -0
phifem/mesh_scripts.py
CHANGED
|
@@ -380,8 +380,9 @@ def _transfer_tags(
|
|
|
380
380
|
# TODO: change this line to allow parallel computing
|
|
381
381
|
source_tags = source_mesh_tags.values
|
|
382
382
|
|
|
383
|
-
|
|
384
|
-
|
|
383
|
+
num_entities = emap.topology.index_map(edim).size_local
|
|
384
|
+
dest_entities = np.arange(num_entities)
|
|
385
|
+
dest_tags = emap.sub_topology_to_topology(source_tags, False)
|
|
385
386
|
|
|
386
387
|
dest_entities_indices = np.hstack(dest_entities).astype(np.int32)
|
|
387
388
|
dest_entities_markers = np.hstack(dest_tags).astype(np.int32)
|
|
@@ -397,10 +398,50 @@ def _transfer_tags(
|
|
|
397
398
|
return dest_entities_tags
|
|
398
399
|
|
|
399
400
|
|
|
401
|
+
def _remove_isolated_cells(
|
|
402
|
+
mesh: dfx.mesh.Mesh,
|
|
403
|
+
exterior_indices: np.ndarray[np.int32],
|
|
404
|
+
cut_indices: np.ndarray[np.int32],
|
|
405
|
+
interior_indices: np.ndarray[np.int32],
|
|
406
|
+
):
|
|
407
|
+
cdim = mesh.topology.dim
|
|
408
|
+
vdim = 0
|
|
409
|
+
# Create the cell to facet connectivity and reshape it into an array s.t. c2f_map[cell_index] = [facets of this cell index]
|
|
410
|
+
mesh.topology.create_connectivity(cdim, vdim)
|
|
411
|
+
c2v_connect = mesh.topology.connectivity(cdim, vdim)
|
|
412
|
+
num_vertices_per_cell = len(c2v_connect.links(0))
|
|
413
|
+
c2v_map = np.reshape(c2v_connect.array, (-1, num_vertices_per_cell))
|
|
414
|
+
|
|
415
|
+
mesh.topology.create_connectivity(vdim, cdim)
|
|
416
|
+
v2c_connect = mesh.topology.connectivity(vdim, cdim)
|
|
417
|
+
v2c_map, max_offset = _reshape_map(v2c_connect)
|
|
418
|
+
|
|
419
|
+
neighbor_cells = np.reshape(
|
|
420
|
+
v2c_map[c2v_map[cut_indices]], (-1, num_vertices_per_cell * max_offset)
|
|
421
|
+
)
|
|
422
|
+
mask_no_interior_connected = ~np.any(
|
|
423
|
+
np.isin(neighbor_cells, interior_indices), axis=1
|
|
424
|
+
)
|
|
425
|
+
mask_no_exterior_connected = ~np.any(
|
|
426
|
+
np.isin(neighbor_cells, exterior_indices), axis=1
|
|
427
|
+
)
|
|
428
|
+
|
|
429
|
+
cut_disconnected_interior = cut_indices[mask_no_interior_connected]
|
|
430
|
+
cut_disconnected_exterior = cut_indices[mask_no_exterior_connected]
|
|
431
|
+
|
|
432
|
+
cut_indices = np.setdiff1d(
|
|
433
|
+
cut_indices, np.union1d(cut_disconnected_interior, cut_disconnected_exterior)
|
|
434
|
+
)
|
|
435
|
+
exterior_indices = np.union1d(exterior_indices, cut_disconnected_interior)
|
|
436
|
+
interior_indices = np.union1d(interior_indices, cut_disconnected_exterior)
|
|
437
|
+
|
|
438
|
+
return exterior_indices, cut_indices, interior_indices
|
|
439
|
+
|
|
440
|
+
|
|
400
441
|
def _tag_cells(
|
|
401
442
|
mesh: Mesh,
|
|
402
443
|
levelset_expression: Expression,
|
|
403
|
-
single_layer_cut: bool
|
|
444
|
+
single_layer_cut: bool,
|
|
404
445
|
) -> MeshTags:
|
|
405
446
|
"""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.
|
|
406
447
|
Strictly inside cell => tag 1
|
|
@@ -431,26 +472,9 @@ def _tag_cells(
|
|
|
431
472
|
cut_indices = np.where(cut)[0]
|
|
432
473
|
|
|
433
474
|
if single_layer_cut:
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
mesh.topology.create_connectivity(cdim, vdim)
|
|
437
|
-
c2v_connect = mesh.topology.connectivity(cdim, vdim)
|
|
438
|
-
num_vertices_per_cell = len(c2v_connect.links(0))
|
|
439
|
-
c2v_map = np.reshape(c2v_connect.array, (-1, num_vertices_per_cell))
|
|
440
|
-
|
|
441
|
-
mesh.topology.create_connectivity(vdim, cdim)
|
|
442
|
-
v2c_connect = mesh.topology.connectivity(vdim, cdim)
|
|
443
|
-
v2c_map, max_offset = _reshape_map(v2c_connect)
|
|
444
|
-
|
|
445
|
-
neighbor_cells = np.reshape(
|
|
446
|
-
v2c_map[c2v_map[cut_indices]], (-1, num_vertices_per_cell * max_offset)
|
|
447
|
-
)
|
|
448
|
-
mask_connected_cut_cells = np.any(
|
|
449
|
-
np.isin(neighbor_cells, interior_indices), axis=1
|
|
475
|
+
exterior_indices, cut_indices, interior_indices = _remove_isolated_cells(
|
|
476
|
+
mesh, exterior_indices, cut_indices, interior_indices
|
|
450
477
|
)
|
|
451
|
-
isolated_cut_cells = cut_indices[~mask_connected_cut_cells]
|
|
452
|
-
cut_indices = np.setdiff1d(cut_indices, isolated_cut_cells)
|
|
453
|
-
exterior_indices = np.union1d(exterior_indices, isolated_cut_cells)
|
|
454
478
|
|
|
455
479
|
if debug_mode:
|
|
456
480
|
if len(interior_indices) == 0:
|
|
@@ -480,7 +504,6 @@ def _tag_cells(
|
|
|
480
504
|
cells_tags = dfx.mesh.meshtags(
|
|
481
505
|
mesh, mesh.topology.dim, indices[sorted_indices], markers[sorted_indices]
|
|
482
506
|
)
|
|
483
|
-
|
|
484
507
|
return cells_tags
|
|
485
508
|
|
|
486
509
|
|
|
@@ -506,9 +529,9 @@ def _cells_facets_pairs(f2c_map, c2f_map, facets):
|
|
|
506
529
|
def _tag_facets(
|
|
507
530
|
mesh: Mesh,
|
|
508
531
|
levelset_expression_facets: Expression,
|
|
532
|
+
single_layer_cut: bool,
|
|
509
533
|
cells_tags: MeshTags | None = None,
|
|
510
534
|
levelset_expression_cells: Expression | None = None,
|
|
511
|
-
single_layer_cut: bool = False,
|
|
512
535
|
) -> MeshTags:
|
|
513
536
|
"""Tag the mesh facets.
|
|
514
537
|
Strictly interior facets => tag 1
|
|
@@ -531,9 +554,7 @@ def _tag_facets(
|
|
|
531
554
|
assert levelset_expression_cells is not None, (
|
|
532
555
|
"You must either pass cells_tags or a levelset expression over the cells of the domain."
|
|
533
556
|
)
|
|
534
|
-
cells_tags = _tag_cells(
|
|
535
|
-
mesh, levelset_expression_cells, single_layer_cut=single_layer_cut
|
|
536
|
-
)
|
|
557
|
+
cells_tags = _tag_cells(mesh, levelset_expression_cells, single_layer_cut)
|
|
537
558
|
|
|
538
559
|
cdim = mesh.topology.dim
|
|
539
560
|
fdim = cdim - 1
|
|
@@ -550,21 +571,30 @@ def _tag_facets(
|
|
|
550
571
|
interior_facets = np.setdiff1d(all_facets, boundary_facets)
|
|
551
572
|
|
|
552
573
|
cell_facet_pairs = _cells_facets_pairs(f2c_map, c2f_map, interior_facets)
|
|
553
|
-
levelset_eval_int = levelset_expression_facets.eval(
|
|
574
|
+
levelset_eval_int = levelset_expression_facets.eval(
|
|
575
|
+
mesh, cell_facet_pairs.reshape(-1, 2)
|
|
576
|
+
)
|
|
554
577
|
|
|
555
|
-
|
|
556
|
-
|
|
578
|
+
geq_zero_int = np.greater_equal(np.min(levelset_eval_int, axis=1), 0.0)
|
|
579
|
+
leq_zero_int = np.less_equal(np.max(levelset_eval_int, axis=1), 0.0)
|
|
557
580
|
direct_int = np.isclose(np.sum(np.abs(levelset_eval_int), axis=1), 0.0)
|
|
581
|
+
exterior_int = np.logical_and(geq_zero_int, ~direct_int)
|
|
582
|
+
interior_int = np.logical_and(leq_zero_int, ~direct_int)
|
|
558
583
|
|
|
559
584
|
connected_cells = f2c_map[boundary_facets][:, 0]
|
|
560
585
|
|
|
561
586
|
cell_facet_pairs = _compute_integration_entities(
|
|
562
587
|
mesh, connected_cells, boundary_facets, 0
|
|
563
588
|
)[0][1]
|
|
564
|
-
levelset_eval_bdy = levelset_expression_facets.eval(
|
|
565
|
-
|
|
566
|
-
|
|
589
|
+
levelset_eval_bdy = levelset_expression_facets.eval(
|
|
590
|
+
mesh, cell_facet_pairs.reshape(-1, 2)
|
|
591
|
+
)
|
|
592
|
+
|
|
593
|
+
geq_zero_bdy = np.greater_equal(np.min(levelset_eval_bdy, axis=1), 0.0)
|
|
594
|
+
leq_zero_bdy = np.less_equal(np.max(levelset_eval_bdy, axis=1), 0.0)
|
|
567
595
|
direct_bdy = np.isclose(np.sum(np.abs(levelset_eval_bdy), axis=1), 0.0)
|
|
596
|
+
exterior_bdy = np.logical_and(geq_zero_bdy, ~direct_bdy)
|
|
597
|
+
interior_bdy = np.logical_and(leq_zero_bdy, ~direct_bdy)
|
|
568
598
|
|
|
569
599
|
facets_indices = np.hstack([interior_facets, boundary_facets])
|
|
570
600
|
exterior = np.hstack([exterior_int, exterior_bdy])
|
|
@@ -579,7 +609,10 @@ def _tag_facets(
|
|
|
579
609
|
cut_indices = np.setdiff1d(cut_indices, direct_indices)
|
|
580
610
|
|
|
581
611
|
# Compute the list of facets on the boundary of the union of cut cells
|
|
582
|
-
|
|
612
|
+
if len(cells_tags.find(2)) > 0:
|
|
613
|
+
boundary_cut_indices = _compute_subdomain_exterior_facets(mesh, cells_tags, [2])
|
|
614
|
+
else:
|
|
615
|
+
boundary_cut_indices = []
|
|
583
616
|
boundary_exterior_indices = np.intersect1d(boundary_cut_indices, interior_indices)
|
|
584
617
|
boundary_exterior_indices = np.setdiff1d(boundary_exterior_indices, direct_indices)
|
|
585
618
|
interior_indices = np.setdiff1d(interior_indices, boundary_exterior_indices)
|
|
@@ -679,7 +712,7 @@ def _compute_codim_interpolation_points(
|
|
|
679
712
|
codim_cell_name = codim_mesh.topology.cell_name()
|
|
680
713
|
new_elmt = element(family_name, codim_cell_name, degree)
|
|
681
714
|
new_space = dfx.fem.functionspace(codim_mesh, new_elmt)
|
|
682
|
-
return new_space.element.interpolation_points
|
|
715
|
+
return new_space.element.interpolation_points
|
|
683
716
|
|
|
684
717
|
|
|
685
718
|
def _levelset_expression(
|
|
@@ -746,12 +779,10 @@ def compute_tags_measures(
|
|
|
746
779
|
The boundaries measure.
|
|
747
780
|
Submesh c-map, v-map and n-map.
|
|
748
781
|
"""
|
|
749
|
-
interpolation_points = detection_space.element.interpolation_points
|
|
782
|
+
interpolation_points = detection_space.element.interpolation_points
|
|
750
783
|
levelset_expression = _levelset_expression(mesh, levelset, interpolation_points)
|
|
751
784
|
|
|
752
|
-
cells_tags = _tag_cells(
|
|
753
|
-
mesh, levelset_expression, single_layer_cut=single_layer_cut
|
|
754
|
-
)
|
|
785
|
+
cells_tags = _tag_cells(mesh, levelset_expression, single_layer_cut)
|
|
755
786
|
|
|
756
787
|
codim_interpolation_points = _compute_codim_interpolation_points(detection_space)
|
|
757
788
|
levelset_expression_facets = _levelset_expression(
|
|
@@ -761,9 +792,9 @@ def compute_tags_measures(
|
|
|
761
792
|
facets_tags = _tag_facets(
|
|
762
793
|
mesh,
|
|
763
794
|
levelset_expression_facets,
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
795
|
+
single_layer_cut,
|
|
796
|
+
cells_tags=cells_tags,
|
|
797
|
+
levelset_expression_cells=levelset_expression,
|
|
767
798
|
)
|
|
768
799
|
|
|
769
800
|
if overwrite_tags is not None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: phiFEM
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.2.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
|
|
@@ -12,7 +12,7 @@ License-File: COPYING.lesser
|
|
|
12
12
|
Classifier: Operating System :: OS Independent
|
|
13
13
|
Classifier: Programming Language :: Python :: 3
|
|
14
14
|
Requires-Python: >=3.9
|
|
15
|
-
Requires-Dist: fenics-dolfinx
|
|
15
|
+
Requires-Dist: fenics-dolfinx<0.11,>=0.9.0
|
|
16
16
|
Description-Content-Type: text/markdown
|
|
17
17
|
|
|
18
18
|
<p align="center" width="100%">
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
phifem/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
phifem/mesh_scripts.py,sha256=TIAGOjbfsHLrBFbNgvjs08iLEAPTabx-vrYUjmPcy0w,33678
|
|
3
|
+
phifem-0.8.2.dev1.dist-info/METADATA,sha256=dQqGlLjoQ9B5uEGV9c_Gn-qZJeg-xsxQYyHUsceXlLY,5612
|
|
4
|
+
phifem-0.8.2.dev1.dist-info/WHEEL,sha256=2iZrJkDIkeDh0k9SikKMqFuRP-ua6mb4Ir1AsER4BEw,87
|
|
5
|
+
phifem-0.8.2.dev1.dist-info/licenses/COPYING,sha256=xTplwv1WHIfqq_EHLvXcq4ZTBCvBUwhGX1JBNYXrYnE,35146
|
|
6
|
+
phifem-0.8.2.dev1.dist-info/licenses/COPYING.lesser,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
|
|
7
|
+
phifem-0.8.2.dev1.dist-info/RECORD,,
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
phifem/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
phifem/mesh_scripts.py,sha256=g9G_QjgERcNNdo26tCGymidLYaCRzSvMYwVaCOmiDIs,32508
|
|
3
|
-
phifem-0.8.0.dev1.dist-info/METADATA,sha256=jFmzNbqBlHFois1398voBC6m7rJyKoUpT_a6s_seKGI,5606
|
|
4
|
-
phifem-0.8.0.dev1.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
5
|
-
phifem-0.8.0.dev1.dist-info/licenses/COPYING,sha256=xTplwv1WHIfqq_EHLvXcq4ZTBCvBUwhGX1JBNYXrYnE,35146
|
|
6
|
-
phifem-0.8.0.dev1.dist-info/licenses/COPYING.lesser,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
|
|
7
|
-
phifem-0.8.0.dev1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|