damogranlabs / classy_blocks

Python classes for easier creation of OpenFOAM's blockMesh dictionaries.
MIT License
124 stars 37 forks source link

Cylinder with multiple inlet and outlet pipes #54

Open MaguRaam opened 1 month ago

MaguRaam commented 1 month ago

Hi,

I attempted to create a cylinder with four holes that will eventually be connected to inlet and outlet pipes. I have attached a rough script that does this traditionally by combining multiple blocks, but I'm having trouble closing the cylinder at the bottom. It may have been better to start with a custom sketch and then extrude it. I would not have ended up with a dirty script.

Could you please advise on the best approach to achieve this classier, more reusable way?

Thank you! Screenshot 2024-07-01 092054

FranzBangar commented 1 month ago

Something extremely rough

import os

import numpy as np

import classy_blocks as cb
from classy_blocks.construct.point import Point
from classy_blocks.util import functions as f

mesh = cb.Mesh()

cylinder_center = [0, 0, 0]
cylinder_radius = [1, 0, 0]
cylinder_normal = [0, 0, 1]
hole_position = [0.4, 0.4, 0]
hole_radius = 0.2

class QuarterCylinderWithFilledHole(cb.MappedSketch):
    # faces for adding round edges
    hole_faces = (6, 7, 8, 5)
    outer_faces = (6, 7)

    def __init__(self, center_point, radius_point, normal, hole_position, hole_radius):
        center_point = np.asarray(center_point)
        radius_point = np.asarray(radius_point)
        normal = np.asarray(normal)

        self.center_point = Point(center_point)
        self.hole_center_point = Point(hole_position)

        hole_disk = cb.OneCoreDisk(
            hole_position, hole_position - f.unit_vector(center_point - hole_position) * hole_radius, normal
        )

        positions = np.concatenate(
            (
                hole_disk.positions,
                [
                    center_point,
                    radius_point,
                    f.rotate(radius_point, np.pi / 4, normal, center_point),
                    f.rotate(radius_point, np.pi / 2, normal, center_point),
                ],
            )
        )

        quad_map = [
            *hole_disk.indexes,
            [9, 7, 6, 8],
            [10, 4, 7, 9],
            [11, 5, 4, 10],
            [8, 6, 5, 11],
        ]

        super().__init__(positions, quad_map)

    def add_edges(self) -> None:
        for face_index in self.hole_faces:
            self.faces[face_index].add_edge(1, cb.Origin(self.hole_center_point.position))

        for face_index in self.outer_faces:
            self.faces[face_index].add_edge(3, cb.Origin(self.center_point.position))

    @property
    def center(self):
        return self.center_point.position

    @property
    def parts(self):
        return [*super().parts, self.center_point, self.hole_center_point]

# a filled quarter of a cylinder
sketch1 = QuarterCylinderWithFilledHole(cylinder_center, cylinder_radius, cylinder_normal, hole_position, hole_radius)
extrude1 = cb.ExtrudedShape(sketch1, 1)

for op in extrude1.operations:
    for i in range(3):
        op.chop(i, count=10)
mesh.add(extrude1)

# a quarter of a cylinder with hole
class QuarterCylinderWithEmptyHole(QuarterCylinderWithFilledHole):
    hole_faces = (0, 1, 2, 3)
    outer_faces = (1, 2)

    @property
    def faces(self):
        return super().faces[5:]

sketch2 = QuarterCylinderWithEmptyHole(cylinder_center, cylinder_radius, cylinder_normal, hole_position, hole_radius)
extrude2 = cb.ExtrudedShape(sketch2, 1).translate([0, 0, 1])

for op in extrude2.operations:
    for i in range(3):
        op.chop(i, count=10)

mesh.add(extrude2)

for angle in (np.pi / 2, np.pi, 3 * np.pi / 2):
    mesh.add(extrude1.copy().rotate(angle, [0, 0, 1], [0, 0, 0]))
    mesh.add(extrude2.copy().rotate(angle, [0, 0, 1], [0, 0, 0]))

mesh.write(os.path.join("..", "case", "system", "blockMeshDict"), debug_path="debug.vtk")
MaguRaam commented 1 month ago

Thanks a lot for looking into my code and rewriting it in a classier way. This will be a good starting point for me to use sketches to create my meshes.