@@ -809,8 +809,8 @@ function fragment_geom!(
809
809
end
810
810
811
811
"""
812
- get_boundary(group::AbstractPhysicalGroup; combined=true, oriented=true, recursive=false)
813
- get_boundary(sm::SolidModel, groupname, dim=2; combined=true, oriented=true, recursive=false)
812
+ get_boundary(group::AbstractPhysicalGroup; combined=true, oriented=true, recursive=false, direction="all", position="all" )
813
+ get_boundary(sm::SolidModel, groupname, dim=2; combined=true, oriented=true, recursive=false, direction="all", position="all" )
814
814
815
815
Get the boundary of the model entities in `group`, given as a vector of (dim, tag) tuples.
816
816
@@ -821,14 +821,19 @@ Return tags multiplied by the sign of the boundary entity if `oriented` is true.
821
821
822
822
Apply the boundary operator recursively down to dimension 0 (i.e. to points) if `recursive`
823
823
is true.
824
+
825
+ If `direction` is specified, return only the boundaries perperdicular to the x, y, or z axis. If `position` is also specified,
826
+ return only the boundaries at the min or max position along the specified `direction`.
824
827
"""
825
828
function get_boundary (
826
829
sm:: SolidModel ,
827
830
group,
828
831
dim= 2 ;
829
832
combined= true ,
830
833
oriented= true ,
831
- recursive= false
834
+ recursive= false ,
835
+ direction= " all" ,
836
+ position= " all"
832
837
)
833
838
if ! hasgroup (sm, group, dim)
834
839
@info " get_boundary(sm, $group , $dim ): ($group , $dim ) is not a physical group, thus has no boundary."
@@ -838,16 +843,129 @@ function get_boundary(
838
843
sm[group, dim];
839
844
combined= combined,
840
845
oriented= oriented,
841
- recursive= recursive
846
+ recursive= recursive,
847
+ direction= direction,
848
+ position= position
842
849
)
843
850
end
844
851
function get_boundary (
845
852
group:: AbstractPhysicalGroup ;
846
853
combined= true ,
847
854
oriented= true ,
848
- recursive= false
855
+ recursive= false ,
856
+ direction= " all" ,
857
+ position= " all"
858
+ )
859
+ all_bc_entities = gmsh. model. getBoundary (dimtags (group), combined, oriented, recursive)
860
+ if direction == " all"
861
+ return all_bc_entities
862
+ else
863
+ if lowercase (direction) ∉ [" all" , " x" , " y" , " z" ]
864
+ @info " get_boundary(sm, $group ): direction $direction is not all, X, Y, or Z, thus has no boundary."
865
+ return Tuple{Int32, Int32}[]
866
+ end
867
+ if lowercase (position) ∉ [" all" , " min" , " max" ]
868
+ @info " get_boundary(sm, $group ): position $position is not all, min, or max, thus has no boundary."
869
+ return Tuple{Int32, Int32}[]
870
+ end
871
+ direction_map = Dict (" x" => 1 , " y" => 2 , " z" => 3 )
872
+ direction_id = direction_map[lowercase (direction)]
873
+ bboxes = Dict ()
874
+ for (dim, tag) in all_bc_entities
875
+ bboxes[tag] = gmsh. model. getBoundingBox (dim, abs (tag))
876
+ end
877
+ target_min = minimum (bbox[direction_id] for bbox in values (bboxes))
878
+ target_max = maximum (bbox[direction_id + 3 ] for bbox in values (bboxes))
879
+
880
+ bc_entities = []
881
+ for (dim, tag) in all_bc_entities
882
+ bbox = bboxes[tag]
883
+ min_val = bbox[direction_id]
884
+ max_val = bbox[direction_id + 3 ]
885
+
886
+ # Check if the boundary is perpendicular to the direction
887
+ ! isapprox (min_val, max_val, atol= 1e-6 ) && continue
888
+
889
+ # Check if at domain min/max position
890
+ if lowercase (position) == " min" || lowercase (position) == " all"
891
+ isapprox (min_val, target_min, atol= 1e-6 ) && push! (bc_entities, (dim, tag))
892
+ end
893
+ if lowercase (position) == " max" || lowercase (position) == " all"
894
+ isapprox (max_val, target_max, atol= 1e-6 ) && push! (bc_entities, (dim, tag))
895
+ end
896
+ end
897
+ return unique (bc_entities)
898
+ end
899
+ end
900
+
901
+ function get_bounding_box (dim, tags)
902
+ xmin, ymin, zmin, xmax, ymax, zmax = gmsh. model. getBoundingBox (dim, tags[1 ])
903
+
904
+ for tag in tags[2 : end ]
905
+ x_min, y_min, z_min, x_max, y_max, z_max = gmsh. model. getBoundingBox (dim, tag)
906
+ xmin = min (xmin, x_min)
907
+ ymin = min (ymin, y_min)
908
+ zmin = min (zmin, z_min)
909
+ xmax = max (xmax, x_max)
910
+ ymax = max (ymax, y_max)
911
+ zmax = max (zmax, z_max)
912
+ end
913
+
914
+ return (xmin, ymin, zmin, xmax, ymax, zmax)
915
+ end
916
+
917
+ """
918
+ set_periodic!(group1::AbstractPhysicalGroup, group2::AbstractPhysicalGroup; dim=2)
919
+ set_periodic!(sm, group1, group2, d1=2, d2=2)
920
+
921
+ Set the model entities in `group1` and `group2` to be periodic. Only supports `d1` = `d2` = 2
922
+ and surfaces in both groups need to be parallel and axis-aligned.
923
+ """
924
+ function set_periodic! (
925
+ sm:: SolidModel ,
926
+ group1:: Union{String, Symbol} ,
927
+ group2:: Union{String, Symbol} ,
928
+ d1= 2 ,
929
+ d2= 2
849
930
)
850
- return gmsh. model. getBoundary (dimtags (group), combined, oriented, recursive)
931
+ if (d1 != 2 || d2 != 2 )
932
+ @info " set_periodic!(sm, $group1 , $group2 , $d1 , $d2 ) only supports d1 = d2 = 2."
933
+ return Tuple{Int32, Int32}[]
934
+ end
935
+ return set_periodic! (sm[group1, d1], sm[group2, d2]; dim= d1)
936
+ end
937
+
938
+ function set_periodic! (group1:: AbstractPhysicalGroup , group2:: AbstractPhysicalGroup ; dim= 2 )
939
+ tags1 = [dt[2 ] for dt in dimtags (group1)]
940
+ tags2 = [dt[2 ] for dt in dimtags (group2)]
941
+
942
+ bbox1 = get_bounding_box (dim, tags1)
943
+ bbox2 = get_bounding_box (dim, tags2)
944
+
945
+ # Check if surfaces are aligned with x, y, or z axis
946
+ plane1 = [isapprox (bbox1[i], bbox1[i + 3 ], atol= 1e-6 ) for i = 1 : 3 ]
947
+ plane2 = [isapprox (bbox2[i], bbox2[i + 3 ], atol= 1e-6 ) for i = 1 : 3 ]
948
+
949
+ # Set periodicity if both surfaces are perpendicular to the same axis
950
+ dist = [0.0 , 0.0 , 0.0 ]
951
+ for i = 1 : 3
952
+ if plane1[i] && plane2[i]
953
+ dist[i] = bbox1[i] - bbox2[i]
954
+ end
955
+ end
956
+ if isapprox (sum (abs .(dist)), 0.0 ) || count (! iszero, dist) > 1
957
+ @info " set_periodic! only supports distinct parallel axis-aligned surfaces."
958
+ return Tuple{Int32, Int32}[]
959
+ end
960
+
961
+ gmsh. model. mesh. set_periodic (
962
+ dim,
963
+ tags1,
964
+ tags2,
965
+ [1 , 0 , 0 , dist[1 ], 0 , 1 , 0 , dist[2 ], 0 , 0 , 1 , dist[3 ], 0 , 0 , 0 , 1 ]
966
+ )
967
+
968
+ return vcat (dimtags (group1), dimtags (group2))
851
969
end
852
970
853
971
"""
0 commit comments