Skip to content

Commit

Permalink
Add search for vertices on wall patches to Probe
Browse files Browse the repository at this point in the history
  • Loading branch information
FranzBangar committed Oct 29, 2024
1 parent 536b0c4 commit c70979e
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 3 deletions.
57 changes: 55 additions & 2 deletions src/classy_blocks/grading/autograding/probe.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import functools
from typing import Dict, List, Optional, get_args
from typing import Dict, List, Optional, Set, get_args

from classy_blocks.base.exceptions import BlockNotFoundError, NoInstructionError
from classy_blocks.items.block import Block
from classy_blocks.items.vertex import Vertex
from classy_blocks.items.wires.axis import Axis
from classy_blocks.items.wires.wire import Wire
from classy_blocks.mesh import Mesh
from classy_blocks.types import ChopTakeType, DirectionType
from classy_blocks.optimize.grid import HexGrid
from classy_blocks.types import ChopTakeType, DirectionType, OrientType
from classy_blocks.util.constants import FACE_MAP


@functools.lru_cache(maxsize=3000) # that's for 1000 blocks
Expand All @@ -18,6 +21,20 @@ def get_block_from_axis(mesh: Mesh, axis: Axis) -> Block:
raise RuntimeError("Block for Axis not found!")


@functools.lru_cache(maxsize=2)
def get_defined_wall_vertices(mesh: Mesh) -> Set[Vertex]:
"""Returns vertices that are on the 'wall' patches"""
wall_vertices: set[Vertex] = set()

# explicitly defined walls
for patch in mesh.patches:
if patch.kind == "wall":
for side in patch.sides:
wall_vertices.update(set(side.vertices))

return wall_vertices


class Instruction:
"""A descriptor that tells in which direction the specific block can be chopped."""

Expand Down Expand Up @@ -151,10 +168,46 @@ class Probe:

def __init__(self, mesh: Mesh):
self.mesh = mesh

# maps blocks to rows
self.catalogue = Catalogue(self.mesh)

# finds blocks' neighbours
self.grid = HexGrid.from_mesh(self.mesh)

def get_row_blocks(self, block: Block, direction: DirectionType) -> List[Block]:
return self.catalogue.get_row_blocks(block, direction)

def get_rows(self, direction: DirectionType) -> List[Row]:
return self.catalogue.rows[direction]

def get_explicit_wall_vertices(self, block: Block) -> Set[Vertex]:
"""Returns vertices from a block that lie on explicitly defined wall patches"""
mesh_vertices = get_defined_wall_vertices(self.mesh)
block_vertices = set(block.vertices)

return block_vertices.intersection(mesh_vertices)

def get_default_wall_vertices(self, block: Block) -> Set[Vertex]:
"""Returns vertices that lie on default 'wall' patch"""
wall_vertices: Set[Vertex] = set()

# other sides when mesh has a default wall patch
if self.mesh.patch_list.default["kind"] == "wall":
# find block boundaries
block_index = self.mesh.blocks.index(block)
cell = self.grid.cells[block_index]

# sides with no neighbours are on boundary
boundaries: List[OrientType] = [
orient for orient, neighbours in cell.neighbours.items() if neighbours is None
]

for orient in boundaries:
wall_vertices.union({block.vertices[i] for i in FACE_MAP[orient]})

return wall_vertices

def get_wall_vertices(self, block: Block) -> Set[Vertex]:
"""Returns vertices that are on the 'wall' patches"""
return self.get_explicit_wall_vertices(block).union(self.get_default_wall_vertices(block))
5 changes: 5 additions & 0 deletions src/classy_blocks/mesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from classy_blocks.construct.shape import Shape
from classy_blocks.construct.stack import Stack
from classy_blocks.items.block import Block
from classy_blocks.items.patch import Patch
from classy_blocks.items.vertex import Vertex
from classy_blocks.lists.block_list import BlockList
from classy_blocks.lists.edge_list import EdgeList
Expand Down Expand Up @@ -243,6 +244,10 @@ def is_assembled(self) -> bool:
def vertices(self) -> List[Vertex]:
return self.vertex_list.vertices

@property
def patches(self) -> List[Patch]:
return list(self.patch_list.patches.values())

@property
def operations(self) -> List[Operation]:
"""Returns a list of operations from all entities in depot"""
Expand Down
65 changes: 64 additions & 1 deletion tests/test_grading/test_probe.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from typing import get_args
from typing import Set, get_args

from parameterized import parameterized

from classy_blocks.grading.autograding.probe import Probe, get_block_from_axis
from classy_blocks.items.vertex import Vertex
from classy_blocks.mesh import Mesh
from classy_blocks.modify.find.shape import RoundSolidFinder
from classy_blocks.types import DirectionType
from tests.test_grading.test_autograde import AutogradeTestsBase

Expand Down Expand Up @@ -98,3 +100,64 @@ def test_get_blocks_cylinder(self, axis, row, blocks):
indexes.add(block.index)

self.assertSetEqual(indexes, blocks)

def test_wall_vertices_defined(self) -> None:
"""Catch wall vertices from explicitly defined wall patches"""
cylinder = self.get_cylinder()
cylinder.set_outer_patch("outer")

self.mesh.add(cylinder)
self.mesh.modify_patch("outer", "wall")
self.mesh.assemble()

probe = Probe(self.mesh)

finder = RoundSolidFinder(self.mesh, cylinder)
shell_vertices = finder.find_shell(True).union(finder.find_shell(False))
wall_vertices: Set[Vertex] = set()

for block in self.mesh.blocks:
wall_vertices.update(probe.get_explicit_wall_vertices(block))

self.assertSetEqual(shell_vertices, wall_vertices)

def test_wall_vertices_default(self) -> None:
"""Catch wall vertices from default patch"""
cylinder = self.get_cylinder()
cylinder.set_start_patch("inlet")
cylinder.set_end_patch("outlet")

self.mesh.set_default_patch("outer", "wall")
self.mesh.assemble()

probe = Probe(self.mesh)

finder = RoundSolidFinder(self.mesh, cylinder)
shell_vertices = finder.find_shell(True).union(finder.find_shell(False))
wall_vertices: Set[Vertex] = set()

for block in self.mesh.blocks:
wall_vertices.update(probe.get_default_wall_vertices(block))

self.assertSetEqual(shell_vertices, wall_vertices)

def test_wall_vertices_combined(self) -> None:
cylinder = self.get_cylinder()
cylinder.set_end_patch("outlet")

cylinder.set_start_patch("bottom")
self.mesh.modify_patch("bottom", "wall")

self.mesh.set_default_patch("outer", "wall")
self.mesh.assemble()

probe = Probe(self.mesh)

finder = RoundSolidFinder(self.mesh, cylinder)
shell_vertices = finder.find_shell(True).union(finder.find_shell(False)).union(finder.find_core(False))
wall_vertices: Set[Vertex] = set()

for block in self.mesh.blocks:
wall_vertices.update(probe.get_default_wall_vertices(block))

self.assertSetEqual(shell_vertices, wall_vertices)

0 comments on commit c70979e

Please sign in to comment.