@@ -937,6 +937,132 @@ def test_bad_refinements():
937937 )
938938
939939
940+ def test_duplicate_refinement_type_per_entity ():
941+ """Raise when the same refinement type is applied twice to one entity."""
942+ body = SnappyBody (name = "car_body" , surfaces = [])
943+ surface = Surface (name = "wing" )
944+ defaults = snappy .SurfaceMeshingDefaults (
945+ min_spacing = 1 * u .mm , max_spacing = 5 * u .mm , gap_resolution = 0.01 * u .mm
946+ )
947+
948+ # -- Two BodyRefinements targeting the same SnappyBody --
949+ with pytest .raises (
950+ pd .ValidationError ,
951+ match = r"`BodyRefinement` is applied 2 times to entity `car_body`" ,
952+ ):
953+ snappy .SurfaceMeshingParams (
954+ defaults = defaults ,
955+ refinements = [
956+ snappy .BodyRefinement (min_spacing = 2 * u .mm , bodies = [body ]),
957+ snappy .BodyRefinement (max_spacing = 4 * u .mm , bodies = [body ]),
958+ ],
959+ )
960+
961+ # -- Two RegionRefinements targeting the same Surface --
962+ with pytest .raises (
963+ pd .ValidationError ,
964+ match = r"`RegionRefinement` is applied 2 times to entity `wing`" ,
965+ ):
966+ snappy .SurfaceMeshingParams (
967+ defaults = defaults ,
968+ refinements = [
969+ snappy .RegionRefinement (
970+ min_spacing = 1 * u .mm , max_spacing = 3 * u .mm , regions = [surface ]
971+ ),
972+ snappy .RegionRefinement (
973+ min_spacing = 2 * u .mm , max_spacing = 4 * u .mm , regions = [surface ]
974+ ),
975+ ],
976+ )
977+
978+ # -- Two SurfaceEdgeRefinements targeting the same SnappyBody --
979+ with pytest .raises (
980+ pd .ValidationError ,
981+ match = r"`SurfaceEdgeRefinement` is applied 2 times to entity `car_body`" ,
982+ ):
983+ snappy .SurfaceMeshingParams (
984+ defaults = defaults ,
985+ refinements = [
986+ snappy .SurfaceEdgeRefinement (spacing = 0.5 * u .mm , entities = [body ]),
987+ snappy .SurfaceEdgeRefinement (spacing = 1 * u .mm , entities = [body ]),
988+ ],
989+ )
990+
991+ # -- Two SurfaceEdgeRefinements targeting the same Surface --
992+ with pytest .raises (
993+ pd .ValidationError ,
994+ match = r"`SurfaceEdgeRefinement` is applied 2 times to entity `wing`" ,
995+ ):
996+ snappy .SurfaceMeshingParams (
997+ defaults = defaults ,
998+ refinements = [
999+ snappy .SurfaceEdgeRefinement (spacing = 0.5 * u .mm , entities = [surface ]),
1000+ snappy .SurfaceEdgeRefinement (spacing = 1 * u .mm , entities = [surface ]),
1001+ ],
1002+ )
1003+
1004+
1005+ def test_duplicate_refinement_different_types_is_allowed ():
1006+ """Different refinement types on the same entity should NOT raise."""
1007+ body = SnappyBody (name = "car_body" , surfaces = [])
1008+ surface = Surface (name = "wing" )
1009+ defaults = snappy .SurfaceMeshingDefaults (
1010+ min_spacing = 1 * u .mm , max_spacing = 5 * u .mm , gap_resolution = 0.01 * u .mm
1011+ )
1012+
1013+ # BodyRefinement + SurfaceEdgeRefinement on the same SnappyBody is fine
1014+ snappy .SurfaceMeshingParams (
1015+ defaults = defaults ,
1016+ refinements = [
1017+ snappy .BodyRefinement (min_spacing = 2 * u .mm , bodies = [body ]),
1018+ snappy .SurfaceEdgeRefinement (spacing = 0.5 * u .mm , entities = [body ]),
1019+ ],
1020+ )
1021+
1022+ # RegionRefinement + SurfaceEdgeRefinement on the same Surface is fine
1023+ snappy .SurfaceMeshingParams (
1024+ defaults = defaults ,
1025+ refinements = [
1026+ snappy .RegionRefinement (min_spacing = 1 * u .mm , max_spacing = 3 * u .mm , regions = [surface ]),
1027+ snappy .SurfaceEdgeRefinement (spacing = 0.5 * u .mm , entities = [surface ]),
1028+ ],
1029+ )
1030+
1031+
1032+ def test_duplicate_refinement_different_entities_is_allowed ():
1033+ """Same refinement type on different entities should NOT raise."""
1034+ body1 = SnappyBody (name = "car_body" , surfaces = [])
1035+ body2 = SnappyBody (name = "other_body" , surfaces = [])
1036+ defaults = snappy .SurfaceMeshingDefaults (
1037+ min_spacing = 1 * u .mm , max_spacing = 5 * u .mm , gap_resolution = 0.01 * u .mm
1038+ )
1039+
1040+ snappy .SurfaceMeshingParams (
1041+ defaults = defaults ,
1042+ refinements = [
1043+ snappy .BodyRefinement (min_spacing = 2 * u .mm , bodies = [body1 ]),
1044+ snappy .BodyRefinement (min_spacing = 3 * u .mm , bodies = [body2 ]),
1045+ ],
1046+ )
1047+
1048+
1049+ def test_duplicate_refinement_body_and_surface_same_name_is_allowed ():
1050+ """SurfaceEdgeRefinement on a SnappyBody and a Surface sharing a name should NOT raise."""
1051+ body = SnappyBody (name = "shared_name" , surfaces = [])
1052+ surface = Surface (name = "shared_name" )
1053+ defaults = snappy .SurfaceMeshingDefaults (
1054+ min_spacing = 1 * u .mm , max_spacing = 5 * u .mm , gap_resolution = 0.01 * u .mm
1055+ )
1056+
1057+ snappy .SurfaceMeshingParams (
1058+ defaults = defaults ,
1059+ refinements = [
1060+ snappy .SurfaceEdgeRefinement (spacing = 0.5 * u .mm , entities = [body ]),
1061+ snappy .SurfaceEdgeRefinement (spacing = 1 * u .mm , entities = [surface ]),
1062+ ],
1063+ )
1064+
1065+
9401066def test_box_entity_enclosed_only_in_beta_mesher ():
9411067 # raises when beta mesher is off
9421068 with pytest .raises (
0 commit comments