# %% [markdown] # # Targeting resolutions # ResolutionSpecs have many attributes that allow them to be targeted. # %% import shapely from meshwell.cad_occ import cad_occ from meshwell.mesh import mesh from meshwell.occ_xao_writer import write_xao from meshwell.polysurface import PolySurface from meshwell.resolution import ConstantInField, ThresholdField from meshwell.visualization import plot2D # %% [markdown] # ## Filtering by mass # ResolutionSpecs can be selectively applied given the "mass" of the entity (total lengths of curves, total area of surfaces, total volumes of volumes). # %% # Create two boxes of different sizes small_box = shapely.box(0, 0, 1, 1) large_box = shapely.box(3, 0, 5, 2) # Combine into multipolygon multi = shapely.MultiPolygon([small_box, large_box]) # Create polysurface with filtered resolution specs polysurface = PolySurface( polygons=multi, physical_name="filtered_boxes", ) write_xao(cad_occ([polysurface]), "filtering_model.xao") output_mesh = mesh( dim=2, input_file="filtering_model.xao", output_file="mass_unfiltered.msh", default_characteristic_length=2, ) plot2D(output_mesh, wireframe=True, title="Reference Resolution Example") output_mesh = mesh( dim=2, input_file="filtering_model.xao", output_file="mass_filtered.msh", default_characteristic_length=2, resolution_specs={ "filtered_boxes": [ # Fine resolution for small curves ConstantInField( resolution=0.1, apply_to="surfaces", max_mass=4, # Only applies to curves with perimeter < 4 ), ], }, ) plot2D(output_mesh, wireframe=True, title="Mass-filtered Resolution Example") # %% [markdown] # ## Filtering the application by sharing/not sharing # For surfaces/curves/points, the ResolutionSpec can be applied if the entity is touching (or not touching) another entity. # %% [markdown] # ## Restricting the evaluation of the field # Once applied, a field can be restricted in its evaluation to specific entities using the `restrict_to` parameter. # This allows you to control which entities the resolution field affects, even when the field is defined on one entity. # %% # Create geometry: outer square with two inner squares large_rect = 20 small_rect = 5 # Create outer square outer_square = shapely.Polygon( [[0, 0], [large_rect, 0], [large_rect, large_rect], [0, large_rect], [0, 0]], ) # Create smaller square that will be duplicated inner_square = shapely.Polygon( [ [large_rect / 2 - small_rect / 2, large_rect / 2 - small_rect / 2], [large_rect / 2 + small_rect / 2, large_rect / 2 - small_rect / 2], [large_rect / 2 + small_rect / 2, large_rect / 2 + small_rect / 2], [large_rect / 2 - small_rect / 2, large_rect / 2 + small_rect / 2], [large_rect / 2 - small_rect / 2, large_rect / 2 - small_rect / 2], ], ) # Example 1: Field restricted to inner_left only poly_outer = PolySurface( polygons=outer_square, mesh_order=2, physical_name="outer", ) poly_left = PolySurface( polygons=shapely.affinity.translate(inner_square, xoff=-3.1), mesh_order=1, physical_name="inner_left", ) poly_right = PolySurface( polygons=shapely.affinity.translate(inner_square, xoff=3.1), mesh_order=1, physical_name="inner_right", ) write_xao(cad_occ([poly_outer, poly_left, poly_right]), "restricted_field_model.xao") output_mesh = mesh( dim=2, input_file="restricted_field_model.xao", output_file="restricted_field_inner_only.msh", default_characteristic_length=2, resolution_specs={ "inner_left": [ ThresholdField( sizemin=0.3, distmax=10, sizemax=1.5, apply_to="curves", restrict_to=["inner_left"], # Field only affects inner_left ) ], }, ) plot2D(output_mesh, wireframe=True, title="Field Restricted to Inner Left Only") # Example 2: Field restricted to both inner_left and outer output_mesh = mesh( dim=2, input_file="restricted_field_model.xao", output_file="restricted_field_inner_and_outer.msh", default_characteristic_length=2, resolution_specs={ "inner_left": [ ThresholdField( sizemin=0.3, distmax=10, sizemax=1.5, apply_to="curves", restrict_to=[ "inner_left", "outer", ], # Field affects both inner_left and outer ) ], }, ) plot2D(output_mesh, wireframe=True, title="Field Restricted to Inner Left and Outer") # %% [markdown] # In the first example, the threshold field only affects the inner_left square, resulting in refined mesh elements only around that entity. # In the second example, the field affects both the inner_left square and the outer square, causing mesh refinement to propagate through # the outer square as well. The inner_right square maintains the default mesh size in both cases since it's not included in the restrict_to list. # %%