Skip to content

Commit

Permalink
Fix WireInfo.starts_at_wall (and ends)
Browse files Browse the repository at this point in the history
  • Loading branch information
FranzBangar committed Nov 17, 2024
1 parent 4a9b280 commit 7980792
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 22 deletions.
2 changes: 1 addition & 1 deletion examples/advanced/inflation_grader.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
# TODO: Hack! mesh.assemble() won't work here but wires et. al. must be updated
mesh.block_list.update()

grader = InflationGrader(mesh, 1e-3, 0.1)
grader = InflationGrader(mesh, 1e-2, 0.1)
grader.grade()

mesh.write(os.path.join("..", "case", "system", "blockMeshDict"), debug_path="debug.vtk")
17 changes: 6 additions & 11 deletions src/classy_blocks/grading/autograding/params/inflation.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,6 @@ def end_size(self) -> float:
"""Size of the last cell in this layer"""
return self.start_size * self.c2c_expansion**self.count

# @abc.abstractmethod
# def get_chop(self, invert: bool) -> Chop:
# """Prepare a Chop for grader params"""

@property
def is_final(self) -> bool:
"""Returns True if this layer is the last (no more space for additional ones)"""
Expand All @@ -53,14 +49,14 @@ def get_chop(self, total_count: int, invert: bool) -> Chop:
length_ratio=self.length,
end_size=self.end_size,
c2c_expansion=1 / self.c2c_expansion,
count=max(self.count, total_count),
count=min(self.count, total_count),
)

return Chop(
length_ratio=self.length,
start_size=self.start_size,
c2c_expansion=self.c2c_expansion,
count=max(self.count, total_count),
count=min(self.count, total_count),
)

def __repr__(self):
Expand Down Expand Up @@ -89,16 +85,17 @@ def __init__(self, start_size: float, c2c_expansion: float, bulk_size: float, ma
self.total_expansion = self.bulk_size / self.start_size

# manually sum up those few cells that lead from start to bulk size
count = 1
count = 0
size = self.start_size
length = 0.0

while size <= self.bulk_size:
length += size
count += 1

if length > max_length:
break

length += size
count += 1
size *= self.c2c_expansion

self._count = count
Expand Down Expand Up @@ -236,8 +233,6 @@ def get_stack(self, length: float) -> LayerStack:
return stack

def get_count(self, length: float, starts_at_wall: bool, ends_at_wall: bool):
print(starts_at_wall, ends_at_wall)

if not (starts_at_wall or ends_at_wall):
return super().get_count(length, False, False)

Expand Down
32 changes: 25 additions & 7 deletions src/classy_blocks/grading/autograding/probe.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import dataclasses
import functools
from typing import List, Optional, Set
from typing import List, Optional, Set, Tuple

from classy_blocks.base.exceptions import PatchNotFoundError
from classy_blocks.grading.autograding.catalogue import Catalogue
Expand All @@ -11,7 +11,7 @@
from classy_blocks.mesh import Mesh
from classy_blocks.optimize.grid import HexGrid
from classy_blocks.types import DirectionType, OrientType
from classy_blocks.util.constants import FACE_MAP
from classy_blocks.util.constants import DIRECTION_MAP


@functools.lru_cache(maxsize=2)
Expand Down Expand Up @@ -130,7 +130,7 @@ def get_default_wall_vertices(self, block: Block) -> Set[Vertex]:
]

for orient in boundaries:
side_vertices = {block.vertices[i] for i in FACE_MAP[orient]}
side_vertices = set(block.get_side_vertices(orient))
# check if they are defined elsewhere
try:
self.mesh.patch_list.find(side_vertices)
Expand All @@ -143,10 +143,28 @@ def get_default_wall_vertices(self, block: Block) -> Set[Vertex]:

def get_wall_vertices(self, block: Block) -> Set[Vertex]:
"""Returns vertices that are on the 'wall' patches"""
# TODO: delete if not needed
return self.get_explicit_wall_vertices(block).union(self.get_default_wall_vertices(block))

def get_wire_info(self, wire: Wire, block: Block) -> WireInfo:
# TODO: test
wall_vertices = self.get_wall_vertices(block)
def get_wire_boundaries(self, wire: Wire, block: Block) -> Tuple[bool, bool]:
"""Finds out whether a Wire starts or ends on a wall patch"""
start_orient = DIRECTION_MAP[wire.direction][0]
end_orient = DIRECTION_MAP[wire.direction][1]

def find_patch(orient: OrientType) -> bool:
vertices = set(block.get_side_vertices(orient))

try:
patch = self.mesh.patch_list.find(vertices)
if patch.kind == "wall":
return True
except PatchNotFoundError:
if self.mesh.patch_list.default.get("kind") == "wall":
return True

return WireInfo(wire, wire.vertices[0] in wall_vertices, wire.vertices[1] in wall_vertices)
return False

return (find_patch(start_orient), find_patch(end_orient))

def get_wire_info(self, wire: Wire, block: Block) -> WireInfo:
return WireInfo(wire, *self.get_wire_boundaries(wire, block))
5 changes: 4 additions & 1 deletion src/classy_blocks/items/block.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
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.types import DirectionType, IndexType
from classy_blocks.types import DirectionType, IndexType, OrientType
from classy_blocks.util import constants
from classy_blocks.util.frame import Frame

Expand Down Expand Up @@ -117,6 +117,9 @@ def check_consistency(self) -> None:
def indexes(self) -> IndexType:
return [vertex.index for vertex in self.vertices]

def get_side_vertices(self, orient: OrientType) -> List[Vertex]:
return [self.vertices[i] for i in constants.FACE_MAP[orient]]

def format_grading(self) -> str:
"""Returns the simple/edgeGrading string"""
if all(axis.is_simple for axis in self.axes): # is_simple
Expand Down
2 changes: 1 addition & 1 deletion src/classy_blocks/items/wires/wire.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def __init__(self, vertices: List[Vertex], direction: DirectionType, corner_1: i
self.corners = [corner_1, corner_2]
self.vertices = [vertices[corner_1], vertices[corner_2]]

self.direction = direction
self.direction: DirectionType = direction

# the default edge is 'line' but will be replaced if the user wishes so
# (that is, not included in edge.factory.registry)
Expand Down
10 changes: 9 additions & 1 deletion src/classy_blocks/util/constants.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import Dict, List, Tuple

from classy_blocks.types import OrientType
from classy_blocks.types import DirectionType, OrientType

# data type
DTYPE = "float" # dtype as taken by np.array()
Expand Down Expand Up @@ -32,6 +32,14 @@
"left",
]

# Connects block axis (direction) and orients
# (read: Direction 0 goes from right to left, etc.
DIRECTION_MAP: Dict[DirectionType, Tuple[OrientType, OrientType]] = {
0: ("left", "right"),
1: ("front", "back"),
2: ("bottom", "top"),
}

# pairs of corner indexes along axes
AXIS_PAIRS = (
((0, 1), (3, 2), (7, 6), (4, 5)), # x
Expand Down
4 changes: 4 additions & 0 deletions tests/test_grading/test_autograde.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import numpy as np

from classy_blocks.construct.flat.sketches.grid import Grid
from classy_blocks.construct.operations.box import Box
from classy_blocks.construct.shapes.cylinder import Cylinder
from classy_blocks.construct.shapes.frustum import Frustum
from classy_blocks.construct.stack import ExtrudedStack
Expand Down Expand Up @@ -30,6 +31,9 @@ def get_cylinder(self) -> Cylinder:
def get_frustum(self) -> Frustum:
return Frustum([0, 0, 0], [1, 0, 0], [0, 1, 0], 0.3)

def get_box(self) -> Box:
return Box([0, 0, 0], [1, 1, 1])

def setUp(self):
self.mesh = Mesh()

Expand Down
62 changes: 62 additions & 0 deletions tests/test_grading/test_probe.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,3 +205,65 @@ def test_flipped_shape(self, flip_indexes, check_row, check_index):
probe = Probe(self.mesh)

self.assertTrue(probe.get_rows(1)[check_row].entries[check_index].flipped)

@parameterized.expand(
(
(0, 4, True),
(1, 5, True),
(2, 6, True),
(3, 7, True),
(0, 1, True),
(3, 2, True),
(4, 5, True),
(7, 6, True),
(0, 3, False),
(1, 2, False),
(4, 7, False),
(5, 6, False),
)
)
def test_wire_boundaries_explicit(self, wire_start, wire_end, starts_at_wall):
box = self.get_box()
box.set_patch(["bottom", "left", "right"], "wallPatch")
self.mesh.add(box)

self.mesh.modify_patch("wallPatch", "wall")
self.mesh.assemble()

probe = Probe(self.mesh)
block = self.mesh.blocks[0]
info = probe.get_wire_info(block.wires[wire_start][wire_end], block)

self.assertEqual(info.starts_at_wall, starts_at_wall)

@parameterized.expand(
(
(0, 4, True),
(1, 5, True),
(2, 6, True),
(3, 7, True),
(0, 1, True),
(3, 2, True),
(4, 5, True),
(7, 6, True),
(0, 3, False),
(1, 2, False),
(4, 7, False),
(5, 6, False),
)
)
def test_wire_boundaries_default(self, wire_start, wire_end, starts_at_wall):
# same situation as the 'explicit' test but 'patch' patch types are defined
# and walls are the default
box = self.get_box()
box.set_patch(["top", "front", "back"], "patchPatch")
self.mesh.add(box)

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

probe = Probe(self.mesh)
block = self.mesh.blocks[0]
info = probe.get_wire_info(block.wires[wire_start][wire_end], block)

self.assertEqual(info.starts_at_wall, starts_at_wall)

0 comments on commit 7980792

Please sign in to comment.