"""outlet guide vane (OGV) mesh module"""
import os
from typing import Any, Tuple
if os.environ.get('__USE_CUDA', '0') == '1':
import cupy as np
else:
import numpy as np
from g3d.defs import G3DWorld
from g3d.defs import G3DDisplay
from g3d.defs import AngleType
from g3d.defs import NodeDistribution
from g3d.defs import Direction
from g3d.defs import BlockFace
from g3d.defs import INTFTypes
from g3d.defs import DIMMode
from g3d.defs import FaceOrientation
from g3d.mesh.modules import MeshModule
from g3d.mesh.geo import Coord
from g3d.mesh.geo import Edge
from g3d.mesh.geo import Face
[docs]
class OGVModule(MeshModule):
def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs)
# - global OGV geometric parameters
self._pitch = 1. # pitch inter-blade distance
self._span = 1. # span (total blade length)
self._chord = 1. # chord length
self._length = 1. # length of extruded domain
# - grid metrics
self._wall_resolution = 0.0001 # size of first node in wall-normal direction [meters]
self._o_grid_offset = 0.0025 # o-grid offset (distance between outer and inner surface of o-grid) [meters]
self._x_in = -self._chord # inlet plane coordinate
self._x_out = 2.0 * self._chord # outlet plane coordinate
# - node counts
self._nj_o_grid = 1 # o-grid coordinates in wall normal direction
self._ni_ss = 1 # suction side node count
self._ni_ps = 1 # pressure side node count
self._ni_le = 1 # leading edge node count
self._ni_te = 1 # trailing edge node count
self._ni_inlet_block = 1 # inlet domain node count (flow direction)
self._ni_outlet_block = 1 # outlet domain node count (flow direction)
self._nj_pitch = 1 # inter-blade node count (flow normal direction)
self._ni_chord = 1 # node count along blade chord (overrides ni_ps and ni_ss if used)
# - data file indices
self._idx_ss_le = 0 # index of start of suction side
self._idx_ss_te = 0 # index of end of suction side
self._idx_ps_le = 0 # index of start of pressure side
self._idx_ps_te = 0 # index of end of pressure side
self._idx_le = 0 # index of leading edge
self._idx_te = 0 # index of trailing edge
# reachable variables (getters)
# - reference coordinates
self._ss_le = Coord(tag=self._tags['ss_le'])
self._ss_te = Coord(tag=self._tags['ss_te'])
self._ps_le = Coord(tag=self._tags['ps_le'])
self._ps_te = Coord(tag=self._tags['ps_te'])
self._le = Coord(tag=self._tags['le'])
self._te = Coord(tag=self._tags['te'])
# - OGV surface edges
self._leading_edge = Edge(tag=self._tags['le'])
self._trailing_edge = Edge(tag=self._tags['te'])
self._pressure_side_edge = Edge(tag=self._tags['ps'])
self._suction_side_edge = Edge(tag=self._tags['ss'])
self._ogv_edge = Edge(tag=self._tags['ogv'])
self._ogv_edge_offset = Edge(tag=self._tags['ogv_offset'])
# - OGV extreme coordinates
self._idx_x_min = 0
self._idx_x_max = 0
self._idx_y_min = 0
self._idx_y_max = 0
self._x_min = Coord(tag=self._tags['x_min'])
self._x_max = Coord(tag=self._tags['x_max'])
self._y_min = Coord(tag=self._tags['y_min'])
self._y_max = Coord(tag=self._tags['y_max'])
# protected variables (only accessible from class ogv module and child modules)
self._nj31 = 1
self._nj32 = 1
self._nj33 = 1
self._nj41 = 1
self._nj42 = 1
self._nj43 = 1
self._o_grid_outer_spacing = 1.0
self._stretch_rate_x = 1.0 # cell stretch rate in the x-direction
def _initialize_module(self, **kwargs: Any) -> None:
super()._initialize_module(**kwargs)
def _set_code_type(self) -> None:
super()._set_code_type()
g3d_world = G3DWorld()
g3d_world.info.code_sub_description = 'OGV mesh module'
@property
def pitch(self) -> float:
"""
:return:
"""
return self._pitch
@pitch.setter
def pitch(self, val: float) -> None:
self._pitch = val
@property
def span(self) -> float:
"""
:return:
"""
return self._span
@span.setter
def span(self, val: float) -> None:
self._span = val
@property
def chord(self) -> float:
"""
:return:
"""
return self._chord
@chord.setter
def chord(self, val: float) -> None:
self._chord = val
@property
def length(self) -> float:
"""
:return:
"""
return self._length
@length.setter
def length(self, val: float) -> None:
self._length = val
@property
def wall_resolution(self) -> float:
"""
:return:
"""
return self._wall_resolution
@wall_resolution.setter
def wall_resolution(self, val: float) -> None:
self._wall_resolution = val
@property
def o_grid_offset(self) -> float:
"""
:return:
"""
return self._o_grid_offset
@o_grid_offset.setter
def o_grid_offset(self, val: float) -> None:
self._o_grid_offset = val
@property
def stretch_rate_x(self) -> float:
"""
:return:
"""
return self._stretch_rate_x
@stretch_rate_x.setter
def stretch_rate_x(self, val: float) -> None:
self._stretch_rate_x = val
@property
def x_in(self) -> float:
"""
:return:
"""
return self._x_in
@x_in.setter
def x_in(self, val: float) -> None:
self._x_in = val
@property
def x_out(self) -> float:
"""
:return:
"""
return self._x_out
@x_out.setter
def x_out(self, val: float) -> None:
self._x_out = val
@property
def nj_o_grid(self) -> int:
"""
:return:
"""
return self._nj_o_grid
@nj_o_grid.setter
def nj_o_grid(self, val: int) -> None:
self._nj_o_grid = val
@property
def ni_ss(self) -> int:
"""
:return:
"""
return self._ni_ss
@ni_ss.setter
def ni_ss(self, val: int) -> None:
self._ni_ss = val
@property
def ni_ps(self) -> int:
"""
:return:
"""
return self._ni_ps
@ni_ps.setter
def ni_ps(self, val: int) -> None:
self._ni_ps = val
@property
def ni_chord(self) -> int:
"""
:return:
"""
return self._ni_chord
@ni_chord.setter
def ni_chord(self, val: int) -> None:
self._ni_chord = val
self._ni_ps = self._ni_ss = self._ni_chord
@property
def ni_le(self) -> int:
"""
:return:
"""
return self._ni_le
@ni_le.setter
def ni_le(self, val: int) -> None:
self._ni_le = val
@property
def ni_te(self) -> int:
"""
:return:
"""
return self._ni_te
@ni_te.setter
def ni_te(self, val: int) -> None:
self._ni_te = val
@property
def ni_inlet_block(self) -> int:
"""
:return:
"""
return self._ni_inlet_block
@ni_inlet_block.setter
def ni_inlet_block(self, val: int) -> None:
self._ni_inlet_block = val
@property
def ni_outlet_block(self) -> int:
"""
:return:
"""
return self._ni_outlet_block
@ni_outlet_block.setter
def ni_outlet_block(self, val: int) -> None:
self._ni_outlet_block = val
@property
def nj_pitch(self) -> int:
"""
:return:
"""
return self._nj_pitch
@nj_pitch.setter
def nj_pitch(self, val: int) -> None:
self._nj_pitch = val
@property
def idx_ss_le(self) -> int:
"""
:return:
"""
return self._idx_ss_le
@idx_ss_le.setter
def idx_ss_le(self, val: int) -> None:
self._idx_ss_le = val
@property
def idx_ss_te(self) -> int:
"""
:return:
"""
return self._idx_ss_te
@idx_ss_te.setter
def idx_ss_te(self, val: int) -> None:
self._idx_ss_te = val
@property
def idx_ps_le(self) -> int:
"""
:return:
"""
return self._idx_ps_le
@idx_ps_le.setter
def idx_ps_le(self, val: int) -> None:
self._idx_ps_le = val
@property
def idx_ps_te(self) -> int:
"""
:return:
"""
return self._idx_ps_te
@idx_ps_te.setter
def idx_ps_te(self, val: int) -> None:
self._idx_ps_te = val
@property
def idx_le(self) -> int:
"""
:return:
"""
return self._idx_le
@idx_le.setter
def idx_le(self, val: int) -> None:
self._idx_le = val
@property
def idx_te(self) -> int:
"""
:return:
"""
return self._idx_te
@idx_te.setter
def idx_te(self, val: int) -> None:
self._idx_te = val
@property
def ss_le(self) -> Coord:
"""
:return:
"""
return self._ss_le
@property
def ss_te(self) -> Coord:
"""
:return:
"""
return self._ss_te
@property
def ps_le(self) -> Coord:
"""
:return:
"""
return self._ps_le
@property
def ps_te(self) -> Coord:
"""
:return:
"""
return self._ps_te
@property
def le(self) -> Coord:
"""
:return:
"""
return self._le
@property
def te(self) -> Coord:
"""
:return:
"""
return self._te
@property
def leading_edge(self) -> Edge:
"""
:return:
"""
return self._leading_edge
@property
def trailing_edge(self) -> Edge:
"""
:return:
"""
return self._trailing_edge
@property
def pressure_side_edge(self) -> Edge:
"""
:return:
"""
return self._pressure_side_edge
@property
def suction_side_edge(self) -> Edge:
"""
:return:
"""
return self._suction_side_edge
@property
def ogv_edge(self) -> Edge:
"""
:return:
"""
return self._ogv_edge
@property
def ogv_edge_offset(self) -> Edge:
"""
:return:
"""
return self._ogv_edge_offset
@property
def idx_x_min(self) -> int:
"""
:return:
"""
return self._idx_x_min
@property
def idx_x_max(self) -> int:
"""
:return:
"""
return self._idx_x_max
@property
def idx_y_min(self) -> int:
"""
:return:
"""
return self._idx_y_min
@property
def idx_y_max(self) -> int:
"""
:return:
"""
return self._idx_y_max
@property
def x_min(self) -> Coord:
"""
:return:
"""
return self._x_min
@property
def x_max(self) -> Coord:
"""
:return:
"""
return self._x_max
@property
def y_min(self) -> Coord:
"""
:return:
"""
return self._y_min
@property
def y_max(self) -> Coord:
"""
:return:
"""
return self._y_max
[docs]
def set_from_key_value(self, key: str, value: Any) -> bool:
if super().set_from_key_value(key, value):
return True
elif key == 'pitch':
self._pitch = value
return True
elif key == 'span':
self._span = value
return True
elif key == 'chord':
self._chord = value
return True
elif key == 'length':
self._length = value
return True
elif key == 'wall_resolution':
self._wall_resolution = value
return True
elif key == 'o_grid_offset':
self._o_grid_offset = value
return True
elif key == 'nj_o_grid':
self._nj_o_grid = value
return True
elif key == 'ni_ss':
self._ni_ss = value
return True
elif key == 'ni_ps':
self._ni_ps = value
return True
elif key == 'ni_le':
self._ni_le = value
return True
elif key == 'ni_te':
self._ni_te = value
return True
elif key == 'ni_inlet_block':
self._ni_inlet_block = value
return True
elif key == 'ni_outlet_block':
self._ni_outlet_block = value
return True
elif key == 'nj_pitch':
self._nj_pitch = value
return True
return False
def _populate_tags(self) -> None:
self._tags = {'block 1': 'o-grid block',
'block 2': 'inter-blade block',
'block 3': 'domain outlet block',
'block 4': 'domain inlet block',
'ss_le': 'suction side start',
'ss_te': 'suction side end',
'ps_le': 'pressure side start',
'ps_te': 'pressure side end',
'le': 'leading edge',
'te': 'trailing edge',
'ps': 'pressure side',
'ss': 'suction side',
'ogv': 'ogv surface',
'ogv_offset': 'ogv offset surface',
'x_min': 'minimum x-coordinate',
'x_max': 'maximum x-coordinate',
'y_min': 'minimum y-coordinate',
'y_max': 'maximum y-coordinate',
}
def _get_o_grid_angle(self, i: int, **kwargs: Any) -> Tuple[float, float]:
direction = Direction.POSITIVE
for key, value in kwargs.items():
if key == 'direction':
direction = value
c1 = self._ogv_edge.get_Coord(i)
c2 = self._ogv_edge_offset.get_Coord(i)
if direction == Direction.POSITIVE:
return c1.get_angle(c2, **kwargs)
else:
return c2.get_angle(c1, **kwargs)
def _read_data_from_file(self) -> None:
pass
def _get_extreme_coordinates(self) -> None:
self._idx_x_min = np.argmin(self._data[:, 0])
self._idx_x_max = np.argmax(self._data[:, 0])
self._idx_y_min = np.argmin(self._data[:, 1])
self._idx_y_max = np.argmax(self._data[:, 1])
self._x_min = Coord(self._data[self._idx_x_min, 0],
self._data[self._idx_x_min, 1],
self._data[self._idx_x_min, 2], tag=self._x_min.tag)
self._x_max = Coord(self._data[self._idx_x_max, 0],
self._data[self._idx_x_max, 1],
self._data[self._idx_x_max, 2], tag=self._x_max.tag)
self._y_min = Coord(self._data[self._idx_y_min, 0],
self._data[self._idx_y_min, 1],
self._data[self._idx_y_min, 2], tag=self._y_min.tag)
self._y_max = Coord(self._data[self._idx_y_max, 0],
self._data[self._idx_y_max, 1],
self._data[self._idx_y_max, 2], tag=self._y_max.tag)
g3d_disp = G3DDisplay()
if g3d_disp.verbose:
g3d_disp.header('span in xy-coordinate system:')
self._x_min.print()
self._x_max.print()
def _extract_ogv_edges(self):
# =====================================================================
# import OGV coordinates from file
# =====================================================================
g3d_disp = G3DDisplay()
if g3d_disp.verbose:
g3d_disp.header('generating OGV edges')
self._le = Coord(self._data[self._idx_le, 0],
self._data[self._idx_le, 1],
self._data[self._idx_le, 2], tag=self._le.tag)
self._te = Coord(self._data[self._idx_te, 0],
self._data[self._idx_te, 1],
self._data[self._idx_te, 2], tag=self._te.tag)
self._ss_le = Coord(self._data[self._idx_ss_le, 0],
self._data[self._idx_ss_le, 1],
self._data[self._idx_ss_le, 2], tag=self._ss_le.tag)
self._ss_te = Coord(self._data[self._idx_ss_te, 0],
self._data[self._idx_ss_te, 1],
self._data[self._idx_ss_te, 2], tag=self._ss_te.tag)
self._ps_le = Coord(self._data[self._idx_ps_le, 0],
self._data[self._idx_ps_le, 1],
self._data[self._idx_ps_le, 2], tag=self._ps_le.tag)
self._ps_te = Coord(self._data[self._idx_ps_te, 0],
self._data[self._idx_ps_te, 1],
self._data[self._idx_ps_te, 2], tag=self._ps_te.tag)
self.add_Coord(self._le)
self.add_Coord(self._te)
self.add_Coord(self._ss_le)
self.add_Coord(self._ss_te)
self.add_Coord(self._ps_le)
self.add_Coord(self._ps_te)
self.print_coordinates()
# DEFINITION OF DATA ARRAYS NOT GENERIC...
ogvXYZ_SS = self._data[self._idx_ss_le - 1:self._idx_ss_te + 1 + 1, :]
ogvXYZ_PS = self._data[self._idx_ps_te:self._idx_ps_le + 1 + 1, :]
ogvXYZ_LE = self._data[self._idx_ps_le:self._idx_ss_le + 1, :]
ogvXYZ_TE = self._data[self._idx_ss_te:, :]
alfa_le, beta_le = self._ps_le.get_angle(self._ss_le, ialt=AngleType.IALT_1, angle_dim=AngleType.DEGREES)
alfa_te, beta_te = self._ss_te.get_angle(self._ps_te, ialt=AngleType.IALT_1, angle_dim=AngleType.DEGREES)
alfa_ss, beta_ss = self._ss_le.get_angle(self._ss_te, ialt=AngleType.IALT_1, angle_dim=AngleType.DEGREES)
alfa_ps, beta_ps = self._ps_te.get_angle(self._ps_le, ialt=AngleType.IALT_1, angle_dim=AngleType.DEGREES)
# dx_le, dy_le, dz_le = self._ps_le.get_delta(self._ss_le)
# dx_te, dy_te, dz_te = self._ss_te.get_delta(self._ps_te)
# print(' leading edge lean (%.2f, %.2f) degrees (dx=%f, dy=%f, dz=%f)' %
# (alfa_le, beta_le, dx_le, dy_le, dz_le))
# print(' trailing edge lean (%.2f, %.2f) degrees (dx=%f, dy=%f, dz=%f)' %
# (alfa_te, beta_te, dx_te, dy_te, dz_te))
# populate leading edge with nodes (equal spacing)
ss_le_m = Coord(self._ss_le)
ps_le_m = Coord(self._ps_le)
tag = self._leading_edge.tag
self._leading_edge = Edge(self._ni_le, ps_le_m, ss_le_m, distribute=NodeDistribution.CURVE_10,
ialt=AngleType.IALT_1, alpha=alfa_le, beta=beta_le,
stretch_rate=2.0, data=ogvXYZ_LE, tag=tag)
# re-populate leading edge (unequal spacing based on initial population)
ss_le_m.set(spacing=self._leading_edge.h1 * 1.35)
ps_le_m.set(spacing=self._leading_edge.h0 * 1.35)
self._leading_edge = Edge(self._ni_le, ps_le_m, ss_le_m, distribute=NodeDistribution.CURVE_10,
ialt=AngleType.IALT_1, alpha=alfa_le, beta=beta_le,
stretch_rate=2.0, data=ogvXYZ_LE, tag=tag)
self.add_Edge(self._leading_edge)
# populate trailing edge with nodes (equal spacing)
ss_te_m = Coord(self._ss_te)
ps_te_m = Coord(self._ps_te)
tag = self._trailing_edge.tag
self._trailing_edge = Edge(self._ni_te, ss_te_m, ps_te_m, distribute=NodeDistribution.CURVE_10,
ialt=AngleType.IALT_1, alpha=alfa_te, beta=beta_te,
stretch_rate=2.0, data=ogvXYZ_TE, tag=tag)
# re-populate trailing edge (unequal spacing based on initial population)
# ss_te_m.set(spacing=self._trailing_edge.h0 * 1.3)
# ps_te_m.set(spacing=self._trailing_edge.h1 * 1.3)
self._trailing_edge = Edge(self._ni_te, ss_te_m, ps_te_m, distribute=NodeDistribution.CURVE_10,
ialt=AngleType.IALT_1, alpha=alfa_te, beta=beta_te,
stretch_rate=2.0, data=ogvXYZ_TE, tag=tag)
self.add_Edge(self._trailing_edge)
# suction-side node distribution
ss_le_m = Coord(self._ss_le, spacing=self._leading_edge.h1)
ss_te_m = Coord(self._ss_te, spacing=self._trailing_edge.h0)
# ss_le_m.set(spacing=-1)
# ss_te_m.set(spacing=-1)
tag = self._suction_side_edge.tag
self._suction_side_edge = Edge(self._ni_ss, ss_le_m, ss_te_m, distribute=NodeDistribution.CURVE_10,
ialt=AngleType.IALT_1, alpha=alfa_ss, beta=beta_ss,
stretch_rate=self._stretch_rate_x, data=ogvXYZ_SS, tag=tag)
self.add_Edge(self._suction_side_edge)
# pressure-side node distribution
ps_te_m = Coord(self._ps_te, spacing=self._trailing_edge.h1)
ps_le_m = Coord(self._ps_le, spacing=self._leading_edge.h0)
# ps_te_m.set(spacing=-1)
# ps_le_m.set(spacing=-1)
tag = self._pressure_side_edge.tag
self._pressure_side_edge = Edge(self._ni_ps, ps_te_m, ps_le_m, distribute=NodeDistribution.CURVE_10,
ialt=AngleType.IALT_1, alpha=alfa_ps, beta=beta_ps,
stretch_rate=self._stretch_rate_x, data=ogvXYZ_PS, tag=tag)
self.add_Edge(self._pressure_side_edge)
tag = self._ogv_edge.tag
self._ogv_edge = Edge(self._pressure_side_edge, tag=tag)
self._ogv_edge.append(self._leading_edge)
self._ogv_edge.append(self._suction_side_edge)
self._ogv_edge.append(self._trailing_edge)
in_plane_vector = np.array([0, 0, 1])
tag = self._ogv_edge_offset.tag
self._ogv_edge_offset = Edge(self._ogv_edge.generate_offset_Edge(self._o_grid_offset, in_plane_vector), tag=tag)
def _generate_mesh(self) -> None:
pass
def _generate_mesh_post(self) -> int:
self._smooth()
self._extrude_mesh()
return super()._generate_mesh_post()
def _extrude_mesh(self) -> None:
g3d_disp = G3DDisplay()
# extrude mesh in K-direction
if not g3d_disp.silent:
g3d_disp.header('extruding 2D mesh plane in K-direction')
x_max_ext = Coord(self._x_max.x, self._x_max.y, self._length)
e_ext = Edge(self._nk3D, self._x_max, x_max_ext, distribute=NodeDistribution.CURVE_2, stretch_rate=0.)
for b in self._blocks:
b.extrude_Face(b.get_Face(BlockFace.KLOW, FaceOrientation.INWARD_FACING_NORMAL), e_ext)
def _smooth(self) -> None:
if self._smooth_faces:
g3d_disp = G3DDisplay()
if not g3d_disp.silent:
g3d_disp.header('smoothing mesh (surface smoother)')
for b in self._blocks:
self.add_smooth_face(b.get_Face(BlockFace.KLOW))
b1 = self._blocks[0]
b2 = self._blocks[1]
# b3 = self._blocks[2]
b4 = self._blocks[3]
self.add_smooth_face_glue([1, b1.ni - self._nj31 - b2.ni + 2, b1.nj, 1, 5, 1, 1, b2.ni],
[2, 1, 1, 1, 5, 1, 2, b2.ni])
self.add_smooth_face_glue([1, b1.ni - self._nj31 + 1, b1.nj, 1, 5, 1, 1, self._nj33],
[3, 1, self._nj31, 1, 5, 4, 1, self._nj31])
self.add_smooth_face_glue([1, self._nj33 + b2.ni + self._nj43 - 2, b1.nj, 1, 5, 1, 1, self._nj41],
[4, b4.ni, 1, 1, 5, 3, 1, self._nj41])
self.add_smooth_face_glue([4, b4.ni, self._nj41, 1, 3, 5, b2.nj, 1],
[2, 1, 1, 1, 3, 5, b2.nj, 1])
self.add_smooth_face_glue([2, b2.ni, 1, 1, 3, 5, b2.nj, 1],
[3, 1, self._nj31, 1, 3, 5, b2.nj, 1])
self.add_smooth_face_glue([1, self._nj33, b1.nj, 1, 5, 1, 1, b2.ni, 0., self._pitch, 0.],
[2, b2.ni, b2.nj, 1, 5, 2, 1, b2.ni])
self.add_smooth_face_glue([1, self._nj33, b1.nj, 1, 2, 5, self._nj33, 1, 0., self._pitch, 0.],
[3, 1, 1, 1, 3, 5, self._nj33, 1])
self.add_smooth_face_glue([1, self._nj33 + b2.ni - 1, b1.nj, 1, 5, 1, 1, self._nj43, 0., self._pitch, 0.],
[4, b4.ni, self._nj41 + self._nj42 - 1, 1, 5, 3, 1, self._nj43])
# self.add_smooth_face_glue([4, 1, 1, 1, 1, 5, b4.ni, 1, 0., self._pitch, 0.],
# [4, 1, b4.nj, 1, 1, 5, b4.ni, 1])
self.smooth(self._n_smooth)
def _add_boundaries(self) -> None:
g3d_world = G3DWorld()
b1 = self._blocks[0]
b2 = self._blocks[1]
b3 = self._blocks[2]
b4 = self._blocks[3]
# mesh block interfaces
self.add_Intf([1, b1.ni - self._nj31 - b2.ni + 2, b1.nj, 1, 5, 1, self._nk3D, b2.ni],
[2, 1, 1, 1, 5, 1, self._nk3D, b2.ni])
self.add_Intf([1, b1.ni - self._nj31 + 1, b1.nj, 1, 5, 1, self._nk3D, self._nj33],
[3, 1, self._nj31, 1, 5, 4, self._nk3D, self._nj31])
self.add_Intf([1, self._nj33 + b2.ni + self._nj43 - 2, b1.nj, 1, 5, 1, self._nk3D, self._nj41],
[4, b4.ni, 1, 1, 5, 3, self._nk3D, self._nj41])
self.add_Intf([2, b2.ni, 1, 1, 3, 5, b2.nj, self._nk3D],
[3, 1, self._nj31, 1, 3, 5, self._nj32, self._nk3D])
self.add_Intf([4, b4.ni, self._nj41, 1, 3, 5, self._nj42, self._nk3D],
[2, 1, 1, 1, 3, 5, b2.nj, self._nk3D])
self.add_Intf(b1.get_Face(BlockFace.IHIGH, FaceOrientation.OUTWARD_FACING_NORMAL),
b1.get_Face(BlockFace.ILOW, FaceOrientation.INWARD_FACING_NORMAL))
# periodic faces
faceA = b3.get_Face(BlockFace.JLOW, FaceOrientation.OUTWARD_FACING_NORMAL)
faceA.delta.y = self._pitch
faceB = b3.get_Face(BlockFace.JHIGH, FaceOrientation.INWARD_FACING_NORMAL)
self.add_Intf(faceA, faceB, intf_type=INTFTypes.TRANSPERINT)
faceA = b4.get_Face(BlockFace.JLOW, FaceOrientation.OUTWARD_FACING_NORMAL)
faceA.delta.y = self._pitch
faceB = b4.get_Face(BlockFace.JHIGH, FaceOrientation.INWARD_FACING_NORMAL)
self.add_Intf(faceA, faceB, intf_type=INTFTypes.TRANSPERINT)
faceA = Face([1, self._nj33, b1.nj, 1, 5, 1, self._nk3D, b2.ni])
faceA.delta.y = self._pitch
faceB = Face([2, b2.ni, b2.nj, 1, 5, 2, self._nk3D, b2.ni])
self.add_Intf(faceA, faceB, intf_type=INTFTypes.TRANSPERINT)
faceA = Face([1, self._nj33, b1.nj, 1, 2, 5, self._nj33, self._nk3D])
faceA.delta.y = self._pitch
faceB = Face([3, 1, self._nj31 + self._nj32 - 1, 1, 3, 5, self._nj33, self._nk3D])
self.add_Intf(faceA, faceB, intf_type=INTFTypes.TRANSPERINT)
faceA = Face([1, self._nj33 + b2.ni - 1, b1.nj, 1, 5, 1, self._nk3D, self._nj43])
faceA.delta.y = self._pitch
faceB = Face([4, b4.ni, self._nj41 + self._nj42 - 1, 1, 5, 3, self._nk3D, self._nj43])
self.add_Intf(faceA, faceB, intf_type=INTFTypes.TRANSPERINT)
# block end faces (K-direction)
if g3d_world.options.dim_mode == DIMMode.G3D:
for b in self._blocks:
faceA = b.get_Face(BlockFace.KLOW, FaceOrientation.OUTWARD_FACING_NORMAL)
faceA.delta.z = self._length
faceB = b.get_Face(BlockFace.KHIGH, FaceOrientation.INWARD_FACING_NORMAL)
self.add_Intf(faceA, faceB, intf_type=INTFTypes.TRANSPERINT)
# inlet and outlet
self.add_IO(b4.get_Face(BlockFace.ILOW), tag='inlet')
self.add_IO(b3.get_Face(BlockFace.IHIGH), tag='outlet')
# ogv surface
self.add_BC(b1.get_Face(BlockFace.JLOW), tag='ogv')
[docs]
def export_3D_connections(self) -> None:
"""
"""
g3d_world = G3DWorld()
n_tmp = self._nk3D
jobname_tmp = g3d_world.io.jobname
self._nk3D = 100001
g3d_world.io.jobname = jobname_tmp + '_extrude'
for b in self._blocks:
b.nk = self._nk3D
b.init_Face_list()
self.nullify_boundary_lists()
self._add_boundaries()
self.export_connections()
lines = []
with open(g3d_world.io.wd + g3d_world.io.jobname + '.bc', 'r') as f:
lines = f.readlines()
with open(g3d_world.io.wd + g3d_world.io.jobname + '.bc', 'w') as f:
for line in lines:
line = line.replace(str(self._nk3D), 'nk')
f.write(line)
self._nk3D = n_tmp
g3d_world.io.jobname = jobname_tmp
for b in self._blocks:
b.nk = self._nk3D
b.init_Face_list()
self.nullify_boundary_lists()
self._add_boundaries()