Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
from pystencils.stencil import inverse_direction
from lbmpy.advanced_streaming import AccessPdfValues, numeric_offsets, numeric_index
from lbmpy.boundaries import ExtrapolationOutflow, UBB
from pystencils_walberla.additional_data_handler import AdditionalDataHandler
class UBBAdditionalDataHandler(AdditionalDataHandler):
def __init__(self, stencil, boundary_object):
assert isinstance(boundary_object, UBB)
self._boundary_object = boundary_object
super(UBBAdditionalDataHandler, self).__init__(stencil=stencil)
@property
def constructor_arguments(self):
return ", std::function<Vector3<real_t>(const Cell &, const shared_ptr<StructuredBlockForest>&, IBlock&)>& " \
"velocityCallback "
@property
def initialiser_list(self):
return "elementInitaliser(velocityCallback),"
@property
def additional_arguments_for_fill_function(self):
return "blocks, "
@property
def additional_parameters_for_fill_function(self):
return " const shared_ptr<StructuredBlockForest> &blocks, "
def data_initialisation(self, direction):
init_list = ["Vector3<real_t> InitialisatonAdditionalData = elementInitaliser(Cell(it.x(), it.y(), it.z()), "
"blocks, *block);", "element.vel_0 = InitialisatonAdditionalData[0];",
"element.vel_1 = InitialisatonAdditionalData[1];"]
if self._dim == 3:
init_list.append("element.vel_2 = InitialisatonAdditionalData[2];")
return "\n".join(init_list)
@property
def additional_member_variable(self):
return "std::function<Vector3<real_t>(const Cell &, const shared_ptr<StructuredBlockForest>&, IBlock&)> " \
"elementInitaliser; "
class OutflowAdditionalDataHandler(AdditionalDataHandler):
def __init__(self, stencil, boundary_object, target='cpu', field_name='pdfs'):
assert isinstance(boundary_object, ExtrapolationOutflow)
self._boundary_object = boundary_object
self._stencil = boundary_object.stencil
self._lb_method = boundary_object.lb_method
self._normal_direction = boundary_object.normal_direction
self._field_name = field_name
self._target = target
super(OutflowAdditionalDataHandler, self).__init__(stencil=stencil)
assert sum([a != 0 for a in self._normal_direction]) == 1,\
"The outflow boundary is only implemented for straight walls at the moment."
@property
def constructor_arguments(self):
return f", BlockDataID {self._field_name}CPUID_" if self._target == 'gpu' else ""
@property
def initialiser_list(self):
return f"{self._field_name}CPUID({self._field_name}CPUID_)," if self._target == 'gpu' else ""
@property
def additional_field_data(self):
identifier = "CPU" if self._target == "gpu" else ""
return f"auto {self._field_name} = block->getData< field::GhostLayerField<real_t, " \
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
f"{len(self._stencil)}> >({self._field_name}{identifier}ID); "
def data_initialisation(self, direction_index):
pdf_acc = AccessPdfValues(self._boundary_object.stencil,
streaming_pattern=self._boundary_object.streaming_pattern,
timestep=self._boundary_object.zeroth_timestep,
streaming_dir='out')
init_list = []
for key, value in self.get_init_dict(pdf_acc, direction_index).items():
init_list.append(f"element.{key} = {self._field_name}->get({value});")
return "\n".join(init_list)
@property
def additional_member_variable(self):
return f"BlockDataID {self._field_name}CPUID;"
@property
def stencil_info(self):
stencil_info = []
for i, d in enumerate(self._stencil):
if any([a != 0 and b != 0 and a == b for a, b in zip(self._normal_direction, d)]):
direction = d if self._dim == 3 else d + (0,)
stencil_info.append((i, direction, ", ".join([str(e) for e in direction])))
return stencil_info
def get_init_dict(self, pdf_accessor, direction_index):
"""The Extrapolation Outflow boundary needs additional data. This function provides a list of all values
which have to be initialised"""
position = ["it.x()", "it.y()", "it.z()"]
direction = self._stencil[direction_index]
inv_dir = self._stencil.index(inverse_direction(direction))
tangential_offset = tuple(offset - normal for offset, normal in zip(direction, self._normal_direction))
result = {}
pos = []
offsets = numeric_offsets(pdf_accessor.accs[inv_dir])
for p, o, t in zip(position, offsets, tangential_offset):
pos.append(p + f" + cell_idx_c({str(o + t)})")
if self._dim == 2:
pos.append("0")
pos.append(str(numeric_index(pdf_accessor.accs[inv_dir])[0]))
result[f'pdf'] = ', '.join(pos)
pos = []
for p, o, t in zip(position, offsets, tangential_offset):
pos.append(p + f" + cell_idx_c({str(o + t)})")
if self._dim == 2:
pos.append("0")
pos.append(str(numeric_index(pdf_accessor.accs[inv_dir])[0]))
result[f'pdf_nd'] = ', '.join(pos)
return result