Commit 115b0b08 authored by Frederik Hennig's avatar Frederik Hennig
Browse files

Updated boundaries_in_kernel

parent fe36b5a3
Pipeline #27519 canceled with stage
in 3 minutes and 2 seconds
...@@ -5,6 +5,7 @@ import pystencils as ps ...@@ -5,6 +5,7 @@ import pystencils as ps
from pystencils.data_types import TypedSymbol, create_type from pystencils.data_types import TypedSymbol, create_type
from pystencils.backends.cbackend import CustomCodeNode from pystencils.backends.cbackend import CustomCodeNode
from lbmpy.stencils import get_stencil
from lbmpy.advanced_streaming.utility import get_accessor, inverse_dir_index, is_inplace, Timestep from lbmpy.advanced_streaming.utility import get_accessor, inverse_dir_index, is_inplace, Timestep
from itertools import product from itertools import product
...@@ -30,6 +31,8 @@ class BetweenTimestepsIndexing: ...@@ -30,6 +31,8 @@ class BetweenTimestepsIndexing:
@property @property
def inverse_dir_symbol(self): def inverse_dir_symbol(self):
"""Symbol denoting the inversion of a PDF field index.
Use only at top-level of index to f_out or f_in, otherwise it can't be correctly replaced."""
return sp.IndexedBase('invdir') return sp.IndexedBase('invdir')
# ============================= # =============================
...@@ -42,6 +45,9 @@ class BetweenTimestepsIndexing: ...@@ -42,6 +45,9 @@ class BetweenTimestepsIndexing:
raise ValueError('Cannot create index arrays for both kinds of timesteps for inplace streaming pattern ' raise ValueError('Cannot create index arrays for both kinds of timesteps for inplace streaming pattern '
+ streaming_pattern) + streaming_pattern)
if isinstance(stencil, str):
stencil = get_stencil(stencil)
prev_accessor = get_accessor(streaming_pattern, prev_timestep) prev_accessor = get_accessor(streaming_pattern, prev_timestep)
next_accessor = get_accessor(streaming_pattern, prev_timestep.next()) next_accessor = get_accessor(streaming_pattern, prev_timestep.next())
...@@ -193,9 +199,12 @@ class BetweenTimestepsIndexing: ...@@ -193,9 +199,12 @@ class BetweenTimestepsIndexing:
class NeighbourOffsetArrays(CustomCodeNode): class NeighbourOffsetArrays(CustomCodeNode):
@staticmethod @staticmethod
def symbolic_neighbour_offset(dir_idx, dim): def neighbour_offset(dir_idx, stencil):
return tuple([sp.IndexedBase(symbol, shape=(1,))[dir_idx] if isinstance(sp.sympify(dir_idx), sp.Integer):
for symbol in NeighbourOffsetArrays._offset_symbols(dim)]) return stencil[dir_idx]
else:
return tuple([sp.IndexedBase(symbol, shape=(1,))[dir_idx]
for symbol in NeighbourOffsetArrays._offset_symbols(len(stencil[0]))])
@staticmethod @staticmethod
def _offset_symbols(dim): def _offset_symbols(dim):
......
import sympy as sp import sympy as sp
from lbmpy.boundaries.boundaryhandling import LbmWeightInfo from lbmpy.boundaries.boundaryhandling import LbmWeightInfo
from lbmpy.advanced_streaming.indexing import BetweenTimestepsIndexing
from lbmpy.advanced_streaming.utility import Timestep, get_accessor
from pystencils.boundaries.boundaryhandling import BoundaryOffsetInfo from pystencils.boundaries.boundaryhandling import BoundaryOffsetInfo
from pystencils.assignment import Assignment from pystencils.assignment import Assignment
from pystencils.astnodes import Block, Conditional, LoopOverCoordinate, SympyAssignment from pystencils.astnodes import Block, Conditional, LoopOverCoordinate, SympyAssignment
...@@ -56,6 +58,8 @@ def border_conditions(direction, field, ghost_layers=1): ...@@ -56,6 +58,8 @@ def border_conditions(direction, field, ghost_layers=1):
result = sp.And(border_condition, *other_min, *other_max) result = sp.And(border_condition, *other_min, *other_max)
return type_all_numbers(result, loop_ctr.dtype) return type_all_numbers(result, loop_ctr.dtype)
# TODO: Function is called nowhere... remove it?
def transformed_boundary_rule(boundary, accessor_func, field, direction_symbol, lb_method, **kwargs): def transformed_boundary_rule(boundary, accessor_func, field, direction_symbol, lb_method, **kwargs):
tmp_field = field.new_field_with_different_name("t") tmp_field = field.new_field_with_different_name("t")
...@@ -82,27 +86,24 @@ def transformed_boundary_rule(boundary, accessor_func, field, direction_symbol, ...@@ -82,27 +86,24 @@ def transformed_boundary_rule(boundary, accessor_func, field, direction_symbol,
return ac.main_assignments[0].rhs return ac.main_assignments[0].rhs
def boundary_conditional(boundary, direction, read_of_next_accessor, lb_method, output_field, cse=False): def boundary_conditional(boundary, direction, streaming_pattern, prev_timestep, lb_method, output_field, cse=False):
stencil = lb_method.stencil stencil = lb_method.stencil
tmp_field = output_field.new_field_with_different_name("t")
dir_indices = direction_indices_in_direction(direction, stencil) dir_indices = direction_indices_in_direction(direction, stencil)
indexing = BetweenTimestepsIndexing(output_field, lb_method.stencil, prev_timestep, streaming_pattern)
f_out, f_in = indexing.proxy_fields
inv_dir = indexing.inverse_dir_symbol
assignments = [] assignments = []
for direction_idx in dir_indices: for direction_idx in dir_indices:
rule = boundary(tmp_field, direction_idx, lb_method, index_field=None) rule = boundary(f_out, f_in, direction_idx, inv_dir, lb_method, index_field=None)
boundary_subs = boundary_substitutions(lb_method)
rule = [a.subs(boundary_subs) for a in rule] # rhs: replace f_out by post collision symbols.
rhs_substitutions = {f_out(i): sym for i, sym in enumerate(lb_method.post_collision_pdf_symbols)}
rhs_substitutions = {tmp_field(i): sym for i, sym in enumerate(lb_method.post_collision_pdf_symbols)} rule = AssignmentCollection([rule]).new_with_substitutions(rhs_substitutions)
offset = stencil[direction_idx] rule = indexing.substitute_proxies(rule)
inv_offset = inverse_direction(offset)
inv_idx = stencil.index(inv_offset) ac = rule.new_without_subexpressions()
lhs_substitutions = {
tmp_field[offset](inv_idx): read_of_next_accessor(output_field, stencil)[inv_idx]}
rule = [Assignment(a.lhs.subs(lhs_substitutions), a.rhs.subs(rhs_substitutions)) for a in rule]
ac = AssignmentCollection([rule[-1]], rule[:-1]).new_without_subexpressions()
assignments += ac.main_assignments assignments += ac.main_assignments
border_cond = border_conditions(direction, output_field, ghost_layers=1) border_cond = border_conditions(direction, output_field, ghost_layers=1)
...@@ -112,8 +113,10 @@ def boundary_conditional(boundary, direction, read_of_next_accessor, lb_method, ...@@ -112,8 +113,10 @@ def boundary_conditional(boundary, direction, read_of_next_accessor, lb_method,
return Conditional(border_cond, Block(assignments)) return Conditional(border_cond, Block(assignments))
def update_rule_with_push_boundaries(collision_rule, field, boundary_spec, accessor, read_of_next_accessor): def update_rule_with_push_boundaries(collision_rule, field, boundary_spec,
streaming_pattern='pull', timestep=Timestep.BOTH):
method = collision_rule.method method = collision_rule.method
accessor = get_accessor(streaming_pattern, timestep)
loads = [Assignment(a, b) for a, b in zip(method.pre_collision_pdf_symbols, accessor.read(field, method.stencil))] loads = [Assignment(a, b) for a, b in zip(method.pre_collision_pdf_symbols, accessor.read(field, method.stencil))]
stores = [Assignment(a, b) for a, b in stores = [Assignment(a, b) for a, b in
zip(accessor.write(field, method.stencil), method.post_collision_pdf_symbols)] zip(accessor.write(field, method.stencil), method.post_collision_pdf_symbols)]
...@@ -122,7 +125,7 @@ def update_rule_with_push_boundaries(collision_rule, field, boundary_spec, acces ...@@ -122,7 +125,7 @@ def update_rule_with_push_boundaries(collision_rule, field, boundary_spec, acces
result.subexpressions = loads + result.subexpressions result.subexpressions = loads + result.subexpressions
result.main_assignments += stores result.main_assignments += stores
for direction, boundary in boundary_spec.items(): for direction, boundary in boundary_spec.items():
cond = boundary_conditional(boundary, direction, read_of_next_accessor, method, field) cond = boundary_conditional(boundary, direction, streaming_pattern, timestep, method, field)
result.main_assignments.append(cond) result.main_assignments.append(cond)
if 'split_groups' in result.simplification_hints: if 'split_groups' in result.simplification_hints:
......
...@@ -137,7 +137,7 @@ class UBB(Boundary): ...@@ -137,7 +137,7 @@ class UBB(Boundary):
assert self.dim == lb_method.dim, \ assert self.dim == lb_method.dim, \
f"Dimension of UBB ({self.dim}) does not match dimension of method ({lb_method.dim})" f"Dimension of UBB ({self.dim}) does not match dimension of method ({lb_method.dim})"
neighbor_offset = NeighbourOffsetArrays.symbolic_neighbour_offset(direction, lb_method.dim) neighbor_offset = NeighbourOffsetArrays.neighbour_offset(direction, lb_method.stencil)
velocity = tuple(v_i.get_shifted(*neighbor_offset) velocity = tuple(v_i.get_shifted(*neighbor_offset)
if isinstance(v_i, Field.Access) and not vel_from_idx_field if isinstance(v_i, Field.Access) and not vel_from_idx_field
...@@ -153,7 +153,7 @@ class UBB(Boundary): ...@@ -153,7 +153,7 @@ class UBB(Boundary):
weight_of_direction = LbmWeightInfo.weight_of_direction weight_of_direction = LbmWeightInfo.weight_of_direction
vel_term = 2 / c_s_sq \ vel_term = 2 / c_s_sq \
* sum([d_i * v_i for d_i, v_i in zip(neighbor_offset, velocity)]) \ * sum([d_i * v_i for d_i, v_i in zip(neighbor_offset, velocity)]) \
* weight_of_direction(direction) * weight_of_direction(direction, lb_method)
# Better alternative: in conserved value computation # Better alternative: in conserved value computation
# rename what is currently called density to "virtual_density" # rename what is currently called density to "virtual_density"
...@@ -227,7 +227,7 @@ class NeumannByCopy(Boundary): ...@@ -227,7 +227,7 @@ class NeumannByCopy(Boundary):
return [NeighbourOffsetArrays(lb_method.stencil)] return [NeighbourOffsetArrays(lb_method.stencil)]
def __call__(self, f_out, f_in, dir_symbol, inv_dir, lb_method, index_field): def __call__(self, f_out, f_in, dir_symbol, inv_dir, lb_method, index_field):
neighbour_offset = NeighbourOffsetArrays.symbolic_neighbour_offset(dir_symbol, lb_method.dim) neighbour_offset = NeighbourOffsetArrays.neighbour_offset(dir_symbol, lb_method.stencil)
return [Assignment(f_in(inv_dir[dir_symbol]), f_out(inv_dir[dir_symbol])), return [Assignment(f_in(inv_dir[dir_symbol]), f_out(inv_dir[dir_symbol])),
Assignment(f_out[neighbour_offset](dir_symbol), f_out(dir_symbol))] Assignment(f_out[neighbour_offset](dir_symbol), f_out(dir_symbol))]
...@@ -249,7 +249,7 @@ class StreamInConstant(Boundary): ...@@ -249,7 +249,7 @@ class StreamInConstant(Boundary):
return [NeighbourOffsetArrays(lb_method.stencil)] return [NeighbourOffsetArrays(lb_method.stencil)]
def __call__(self, f_out, f_in, dir_symbol, inv_dir, lb_method, index_field): def __call__(self, f_out, f_in, dir_symbol, inv_dir, lb_method, index_field):
neighbour_offset = NeighbourOffsetArrays.symbolic_neighbour_offset(dir_symbol, lb_method.dim) neighbour_offset = NeighbourOffsetArrays.neighbour_offset(dir_symbol, lb_method.stencil)
return [Assignment(f_in(inv_dir[dir_symbol]), self._constant), return [Assignment(f_in(inv_dir[dir_symbol]), self._constant),
Assignment(f_out[neighbour_offset](dir_symbol), self._constant)] Assignment(f_out[neighbour_offset](dir_symbol), self._constant)]
......
...@@ -155,8 +155,11 @@ class LbmWeightInfo(CustomCodeNode): ...@@ -155,8 +155,11 @@ class LbmWeightInfo(CustomCodeNode):
# --------------------------- Functions to be used by boundaries -------------------------- # --------------------------- Functions to be used by boundaries --------------------------
@staticmethod @staticmethod
def weight_of_direction(dir_idx): def weight_of_direction(dir_idx, lb_method=None):
return sp.IndexedBase(LbmWeightInfo.WEIGHTS_SYMBOL, shape=(1,))[dir_idx] if isinstance(sp.sympify(dir_idx), sp.Integer):
return lb_method.weights[dir_idx].evalf()
else:
return sp.IndexedBase(LbmWeightInfo.WEIGHTS_SYMBOL, shape=(1,))[dir_idx]
# ---------------------------------- Internal --------------------------------------------- # ---------------------------------- Internal ---------------------------------------------
......
...@@ -3,6 +3,7 @@ import sympy as sp ...@@ -3,6 +3,7 @@ import sympy as sp
import lbmpy.plot as plt import lbmpy.plot as plt
import pystencils as ps import pystencils as ps
from lbmpy.advanced_streaming import *
from lbmpy.boundaries import * from lbmpy.boundaries import *
from lbmpy.creationfunctions import * from lbmpy.creationfunctions import *
from lbmpy.geometry import * from lbmpy.geometry import *
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment