Commit 482c8293 authored by Martin Bauer's avatar Martin Bauer
Browse files

PEP8 name refactoring

- test run again
- notebooks not yet
parent 48999882
......@@ -3,41 +3,41 @@ from pystencils import Field, Assignment
from pystencils.astnodes import SympyAssignment
from pystencils.sympyextensions import get_symmetric_part
from pystencils.data_types import create_type
from lbmpy.simplificationfactory import createSimplificationStrategy
from lbmpy.simplificationfactory import create_simplification_strategy
from lbmpy.boundaries.boundaryhandling import BoundaryOffsetInfo, LbmWeightInfo
class Boundary(object):
class Boundary:
"""Base class all boundaries should derive from"""
def __init__(self, name=None):
self._name = name
def __call__(self, pdfField, directionSymbol, lbMethod, indexField):
def __call__(self, pdf_field, direction_symbol, lb_method, index_field):
"""
This function defines the boundary behavior and must therefore be implemented by all boundaries.
Here the boundary is defined as a list of sympy equations, from which a boundary kernel is generated.
:param pdfField: pystencils field describing the pdf. The current cell is cell next to the boundary,
:param pdf_field: pystencils field describing the pdf. The current cell is cell next to the boundary,
which is influenced by the boundary cell i.e. has a link from the boundary cell to
itself.
:param directionSymbol: a sympy symbol that can be used as index to the pdfField. It describes
:param direction_symbol: a sympy symbol that can be used as index to the pdfField. It describes
the direction pointing from the fluid to the boundary cell
:param lbMethod: an instance of the LB method used. Use this to adapt the boundary to the method
(e.g. compressiblity)
:param indexField: the boundary index field that can be used to retrieve and update boundary data
:param lb_method: an instance of the LB method used. Use this to adapt the boundary to the method
(e.g. compressibility)
:param index_field: the boundary index field that can be used to retrieve and update boundary data
:return: list of sympy equations
"""
raise NotImplementedError("Boundary class has to overwrite __call__")
@property
def additionalData(self):
def additional_data(self):
"""Return a list of (name, type) tuples for additional data items required in this boundary
These data items can either be initialized in separate kernel see additionalDataKernelInit or by
Python callbacks - see additionalDataCallback """
return []
@property
def additionalDataInitCallback(self):
def additional_data_init_callback(self):
"""Return a callback function called with a boundary data setter object and returning a dict of
data-name to data for each element that should be initialized"""
return None
......@@ -50,8 +50,8 @@ class Boundary(object):
return type(self).__name__
@name.setter
def name(self, newValue):
self._name = newValue
def name(self, new_value):
self._name = new_value
class NoSlip(Boundary):
......@@ -61,10 +61,10 @@ class NoSlip(Boundary):
super(NoSlip, self).__init__(name)
"""No-Slip, (half-way) simple bounce back boundary condition, enforcing zero velocity at obstacle"""
def __call__(self, pdfField, directionSymbol, lbMethod, **kwargs):
neighbor = BoundaryOffsetInfo.offsetFromDir(directionSymbol, lbMethod.dim)
inverseDir = BoundaryOffsetInfo.invDir(directionSymbol)
return [Assignment(pdfField[neighbor](inverseDir), pdfField(directionSymbol))]
def __call__(self, pdf_field, direction_symbol, lb_method, **kwargs):
neighbor = BoundaryOffsetInfo.offset_from_dir(direction_symbol, lb_method.dim)
inverse_dir = BoundaryOffsetInfo.inv_dir(direction_symbol)
return [Assignment(pdf_field[neighbor](inverse_dir), pdf_field(direction_symbol))]
def __hash__(self):
# All boundaries of these class behave equal -> should also be equal (as long as name is equal)
......@@ -80,17 +80,17 @@ class UBB(Boundary):
"""Velocity bounce back boundary condition, enforcing specified velocity at obstacle"""
def __init__(self, velocity, adaptVelocityToForce=False, dim=None, name=None):
def __init__(self, velocity, adapt_velocity_to_force=False, dim=None, name=None):
"""
:param velocity: can either be a constant, an access into a field, or a callback function.
The callback functions gets a numpy record array with members, 'x','y','z', 'dir' (direction)
and 'velocity' which has to be set to the desired velocity of the corresponding link
:param adaptVelocityToForce:
:param adapt_velocity_to_force:
"""
super(UBB, self).__init__(name)
self._velocity = velocity
self._adaptVelocityToForce = adaptVelocityToForce
self._adaptVelocityToForce = adapt_velocity_to_force
if callable(self._velocity) and not dim:
raise ValueError("When using a velocity callback the dimension has to be specified with the dim parameter")
elif not callable(self._velocity):
......@@ -98,56 +98,57 @@ class UBB(Boundary):
self.dim = dim
@property
def additionalData(self):
def additional_data(self):
if callable(self._velocity):
return [('vel_%d' % (i,), create_type("double")) for i in range(self.dim)]
else:
return []
@property
def additionalDataInitCallback(self):
def additional_data_init_callback(self):
if callable(self._velocity):
return self._velocity
def __call__(self, pdfField, directionSymbol, lbMethod, indexField, **kwargs):
velFromIdxField = callable(self._velocity)
vel = [indexField('vel_%d' % (i,)) for i in range(self.dim)] if velFromIdxField else self._velocity
direction = directionSymbol
def __call__(self, pdf_field, direction_symbol, lb_method, index_field, **kwargs):
vel_from_idx_field = callable(self._velocity)
vel = [index_field('vel_%d' % (i,)) for i in range(self.dim)] if vel_from_idx_field else self._velocity
direction = direction_symbol
assert self.dim == lbMethod.dim, "Dimension of UBB (%d) does not match dimension of method (%d)" \
% (self.dim, lbMethod.dim)
assert self.dim == lb_method.dim, "Dimension of UBB (%d) does not match dimension of method (%d)" \
% (self.dim, lb_method.dim)
neighbor = BoundaryOffsetInfo.offsetFromDir(direction, lbMethod.dim)
inverseDir = BoundaryOffsetInfo.invDir(direction)
neighbor = BoundaryOffsetInfo.offset_from_dir(direction, lb_method.dim)
inverse_dir = BoundaryOffsetInfo.inv_dir(direction)
velocity = tuple(v_i.getShifted(*neighbor) if isinstance(v_i, Field.Access) and not velFromIdxField else v_i
velocity = tuple(v_i.get_shifted(*neighbor) if isinstance(v_i, Field.Access) and not vel_from_idx_field else v_i
for v_i in vel)
if self._adaptVelocityToForce:
cqc = lbMethod.conservedQuantityComputation
shiftedVelEqs = cqc.equilibriumInputEquationsFromInitValues(velocity=velocity)
velocity = [eq.rhs for eq in shiftedVelEqs.new_filtered(cqc.firstOrderMomentSymbols).main_assignments]
cqc = lb_method.conserved_quantity_computation
shifted_vel_eqs = cqc.equilibrium_input_equations_from_init_values(velocity=velocity)
velocity = [eq.rhs for eq in shifted_vel_eqs.new_filtered(cqc.first_order_moment_symbols).main_assignments]
c_s_sq = sp.Rational(1, 3)
weightOfDirection = LbmWeightInfo.weightOfDirection
velTerm = 2 / c_s_sq * sum([d_i * v_i for d_i, v_i in zip(neighbor, velocity)]) * weightOfDirection(direction)
weight_of_direction = LbmWeightInfo.weight_of_direction
vel_term = 2 / c_s_sq * sum([d_i * v_i
for d_i, v_i in zip(neighbor, velocity)]) * weight_of_direction(direction)
# Better alternative: in conserved value computation
# rename what is currently called density to "virtualDensity"
# provide a new quantity density, which is constant in case of incompressible models
if not lbMethod.conservedQuantityComputation.zeroCenteredPdfs:
cqc = lbMethod.conservedQuantityComputation
densitySymbol = sp.Symbol("rho")
pdfFieldAccesses = [pdfField(i) for i in range(len(lbMethod.stencil))]
densityEquations = cqc.outputEquationsFromPdfs(pdfFieldAccesses, {'density': densitySymbol})
densitySymbol = lbMethod.conservedQuantityComputation.defined_symbols()['density']
result = densityEquations.all_assignments
result += [Assignment(pdfField[neighbor](inverseDir),
pdfField(direction) - velTerm * densitySymbol)]
if not lb_method.conserved_quantity_computation.zero_centered_pdfs:
cqc = lb_method.conserved_quantity_computation
density_symbol = sp.Symbol("rho")
pdf_field_accesses = [pdf_field(i) for i in range(len(lb_method.stencil))]
density_equations = cqc.output_equations_from_pdfs(pdf_field_accesses, {'density': density_symbol})
density_symbol = lb_method.conserved_quantity_computation.defined_symbols()['density']
result = density_equations.all_assignments
result += [Assignment(pdf_field[neighbor](inverse_dir),
pdf_field(direction) - vel_term * density_symbol)]
return result
else:
return [Assignment(pdfField[neighbor](inverseDir),
pdfField(direction) - velTerm)]
return [Assignment(pdf_field[neighbor](inverse_dir),
pdf_field(direction) - vel_term)]
class FixedDensity(Boundary):
......@@ -156,49 +157,52 @@ class FixedDensity(Boundary):
super(FixedDensity, self).__init__(name)
self._density = density
def __call__(self, pdfField, directionSymbol, lbMethod, **kwargs):
def __call__(self, pdf_field, direction_symbol, lb_method, **kwargs):
"""Boundary condition that fixes the density/pressure at the obstacle"""
def removeAsymmetricPartOfmain_assignments(eqColl, dofs):
newmain_assignments = [Assignment(e.lhs, get_symmetric_part(e.rhs, dofs)) for e in eqColl.main_assignments]
return eqColl.copy(newmain_assignments)
def remove_asymmetric_part_of_main_assignments(assignment_collection, degrees_of_freedom):
new_main_assignments = [Assignment(a.lhs, get_symmetric_part(a.rhs, degrees_of_freedom))
for a in assignment_collection.main_assignments]
return assignment_collection.copy(new_main_assignments)
neighbor = BoundaryOffsetInfo.offsetFromDir(directionSymbol, lbMethod.dim)
inverseDir = BoundaryOffsetInfo.invDir(directionSymbol)
neighbor = BoundaryOffsetInfo.offset_from_dir(direction_symbol, lb_method.dim)
inverse_dir = BoundaryOffsetInfo.inv_dir(direction_symbol)
cqc = lbMethod.conservedQuantityComputation
cqc = lb_method.conserved_quantity_computation
velocity = cqc.defined_symbols()['velocity']
symmetricEq = removeAsymmetricPartOfmain_assignments(lbMethod.getEquilibrium(), dofs=velocity)
substitutions = {sym: pdfField(i) for i, sym in enumerate(lbMethod.preCollisionPdfSymbols)}
symmetricEq = symmetricEq.new_with_substitutions(substitutions)
symmetric_eq = remove_asymmetric_part_of_main_assignments(lb_method.get_equilibrium(),
degrees_of_freedom=velocity)
substitutions = {sym: pdf_field(i) for i, sym in enumerate(lb_method.pre_collision_pdf_symbols)}
symmetric_eq = symmetric_eq.new_with_substitutions(substitutions)
simplification = createSimplificationStrategy(lbMethod)
symmetricEq = simplification(symmetricEq)
simplification = create_simplification_strategy(lb_method)
symmetric_eq = simplification(symmetric_eq)
densitySymbol = cqc.defined_symbols()['density']
density_symbol = cqc.defined_symbols()['density']
density = self._density
densityEq = cqc.equilibriumInputEquationsFromInitValues(density=density).new_without_subexpressions().main_assignments[0]
assert densityEq.lhs == densitySymbol
transformedDensity = densityEq.rhs
equilibrium_input = cqc.equilibrium_input_equations_from_init_values(density=density).new_without_subexpressions()
density_eq = equilibrium_input.main_assignments[0]
assert density_eq.lhs == density_symbol
transformed_density = density_eq.rhs
conditions = [(eq_i.rhs, sp.Equality(directionSymbol, i))
for i, eq_i in enumerate(symmetricEq.main_assignments)] + [(0, True)]
conditions = [(eq_i.rhs, sp.Equality(direction_symbol, i))
for i, eq_i in enumerate(symmetric_eq.main_assignments)] + [(0, True)]
eq_component = sp.Piecewise(*conditions)
subExprs = [Assignment(eq.lhs, transformedDensity if eq.lhs == densitySymbol else eq.rhs)
for eq in symmetricEq.subexpressions]
subexpressions = [Assignment(eq.lhs, transformed_density if eq.lhs == density_symbol else eq.rhs)
for eq in symmetric_eq.subexpressions]
return subExprs + [SympyAssignment(pdfField[neighbor](inverseDir),
2 * eq_component - pdfField(directionSymbol))]
return subexpressions + [SympyAssignment(pdf_field[neighbor](inverse_dir),
2 * eq_component - pdf_field(direction_symbol))]
class NeumannByCopy(Boundary):
def __call__(self, pdfField, directionSymbol, lbMethod, **kwargs):
neighbor = BoundaryOffsetInfo.offsetFromDir(directionSymbol, lbMethod.dim)
inverseDir = BoundaryOffsetInfo.invDir(directionSymbol)
return [Assignment(pdfField[neighbor](inverseDir), pdfField(inverseDir)),
Assignment(pdfField[neighbor](directionSymbol), pdfField(directionSymbol))]
def __call__(self, pdf_field, direction_symbol, lb_method, **kwargs):
neighbor = BoundaryOffsetInfo.offset_from_dir(direction_symbol, lb_method.dim)
inverse_dir = BoundaryOffsetInfo.inv_dir(direction_symbol)
return [Assignment(pdf_field[neighbor](inverse_dir), pdf_field(inverse_dir)),
Assignment(pdf_field[neighbor](direction_symbol), pdf_field(direction_symbol))]
def __hash__(self):
# All boundaries of these class behave equal -> should also be equal
......@@ -209,11 +213,11 @@ class NeumannByCopy(Boundary):
class StreamInZero(Boundary):
def __call__(self, pdfField, directionSymbol, lbMethod, **kwargs):
neighbor = BoundaryOffsetInfo.offsetFromDir(directionSymbol, lbMethod.dim)
inverseDir = BoundaryOffsetInfo.invDir(directionSymbol)
return [Assignment(pdfField[neighbor](inverseDir), 0),
Assignment(pdfField[neighbor](directionSymbol), 0)]
def __call__(self, pdf_field, direction_symbol, lb_method, **kwargs):
neighbor = BoundaryOffsetInfo.offset_from_dir(direction_symbol, lb_method.dim)
inverse_dir = BoundaryOffsetInfo.inv_dir(direction_symbol)
return [Assignment(pdf_field[neighbor](inverse_dir), 0),
Assignment(pdf_field[neighbor](direction_symbol), 0)]
def __hash__(self):
# All boundaries of these class behave equal -> should also be equal
......@@ -226,12 +230,12 @@ class StreamInZero(Boundary):
class AntiBounceBack(Boundary):
"""No-Slip, (half-way) simple bounce back boundary condition, enforcing zero velocity at obstacle"""
def __call__(self, pdfField, directionSymbol, lbMethod, **kwargs):
neighbor = BoundaryOffsetInfo.offsetFromDir(directionSymbol, lbMethod.dim)
inverseDir = BoundaryOffsetInfo.invDir(directionSymbol)
rhs = pdfField(directionSymbol)
def __call__(self, pdf_field, direction_symbol, lb_method, **kwargs):
neighbor = BoundaryOffsetInfo.offset_from_dir(direction_symbol, lb_method.dim)
inverse_dir = BoundaryOffsetInfo.inv_dir(direction_symbol)
rhs = pdf_field(direction_symbol)
t = -rhs
return [SympyAssignment(pdfField[neighbor](inverseDir), t)]
return [SympyAssignment(pdf_field[neighbor](inverse_dir), t)]
def __hash__(self):
# All boundaries of these class behave equal -> should also be equal (as long as name is equal)
......@@ -241,4 +245,3 @@ class AntiBounceBack(Boundary):
if not isinstance(other, AntiBounceBack):
return False
return self.name == other.name
import numpy as np
import sympy as sp
from pystencils import TypedSymbol, createIndexedKernel, Assignment
from pystencils import TypedSymbol, create_indexed_kernel, Assignment
from pystencils.backends.cbackend import CustomCppCode
from pystencils.boundaries import BoundaryHandling
from pystencils.boundaries.boundaryhandling import BoundaryOffsetInfo
from lbmpy.stencils import inverseDirection
from lbmpy.stencils import inverse_direction
class LatticeBoltzmannBoundaryHandling(BoundaryHandling):
def __init__(self, lbMethod, dataHandling, pdfFieldName, name="boundaryHandling", flagInterface=None,
target='cpu', openMP=True):
self.lbMethod = lbMethod
super(LatticeBoltzmannBoundaryHandling, self).__init__(dataHandling, pdfFieldName, lbMethod.stencil,
name, flagInterface, target, openMP)
def __init__(self, lb_method, data_handling, pdf_field_name, name="boundary_handling", flag_interface=None,
target='cpu', openmp=True):
self.lb_method = lb_method
super(LatticeBoltzmannBoundaryHandling, self).__init__(data_handling, pdf_field_name, lb_method.stencil,
name, flag_interface, target, openmp)
def forceOnBoundary(self, boundaryObj):
def force_on_boundary(self, boundary_obj):
from lbmpy.boundaries import NoSlip
if isinstance(boundaryObj, NoSlip):
return self._forceOnNoSlip(boundaryObj)
if isinstance(boundary_obj, NoSlip):
return self._force_on_no_slip(boundary_obj)
else:
self.__call__()
return self._forceOnBoundary(boundaryObj)
return self._force_on_boundary(boundary_obj)
# ------------------------------ Implementation Details ------------------------------------------------------------
def _forceOnNoSlip(self, boundaryObj):
dh = self._dataHandling
ffGhostLayers = dh.ghostLayersOfField(self.flagInterface.flagFieldName)
method = self.lbMethod
def _force_on_no_slip(self, boundary_obj):
dh = self._data_handling
ff_ghost_layers = dh.ghost_layers_of_field(self.flag_interface.flag_field_name)
method = self.lb_method
stencil = np.array(method.stencil)
result = np.zeros(self.dim)
for b in dh.iterate(ghostLayers=ffGhostLayers):
objToIndList = b[self._indexArrayName].boundaryObjectToIndexList
pdfArray = b[self._fieldName]
if boundaryObj in objToIndList:
indArr = objToIndList[boundaryObj]
indices = [indArr[name] for name in ('x', 'y', 'z')[:method.dim]]
indices.append(indArr['dir'])
values = 2 * pdfArray[tuple(indices)]
forces = stencil[indArr['dir']] * values[:, np.newaxis]
for b in dh.iterate(ghost_layers=ff_ghost_layers):
obj_to_ind_list = b[self._index_array_name].boundary_object_to_index_list
pdf_array = b[self._field_name]
if boundary_obj in obj_to_ind_list:
ind_arr = obj_to_ind_list[boundary_obj]
indices = [ind_arr[name] for name in ('x', 'y', 'z')[:method.dim]]
indices.append(ind_arr['dir'])
values = 2 * pdf_array[tuple(indices)]
forces = stencil[ind_arr['dir']] * values[:, np.newaxis]
result += forces.sum(axis=0)
return dh.reduceFloatSequence(list(result), 'sum')
return dh.reduce_float_sequence(list(result), 'sum')
def _forceOnBoundary(self, boundaryObj):
dh = self._dataHandling
ffGhostLayers = dh.ghostLayersOfField(self.flagInterface.flagFieldName)
method = self.lbMethod
def _force_on_boundary(self, boundary_obj):
dh = self._data_handling
ff_ghost_layers = dh.ghost_layers_of_field(self.flag_interface.flag_field_name)
method = self.lb_method
stencil = np.array(method.stencil)
invDirection = np.array([method.stencil.index(inverseDirection(d))
inv_direction = np.array([method.stencil.index(inverse_direction(d))
for d in method.stencil])
result = np.zeros(self.dim)
for b in dh.iterate(ghostLayers=ffGhostLayers):
objToIndList = b[self._indexArrayName].boundaryObjectToIndexList
pdfArray = b[self._fieldName]
if boundaryObj in objToIndList:
indArr = objToIndList[boundaryObj]
indices = [indArr[name] for name in ('x', 'y', 'z')[:method.dim]]
offsets = stencil[indArr['dir']]
invDir = invDirection[indArr['dir']]
fluidValues = pdfArray[tuple(indices) + (indArr['dir'],)]
boundaryValues = pdfArray[tuple(ind + offsets[:, i] for i, ind in enumerate(indices)) + (invDir,)]
values = fluidValues + boundaryValues
forces = stencil[indArr['dir']] * values[:, np.newaxis]
for b in dh.iterate(ghost_layers=ff_ghost_layers):
obj_to_ind_list = b[self._index_array_name].boundary_object_to_index_list
pdf_array = b[self._field_name]
if boundary_obj in obj_to_ind_list:
ind_arr = obj_to_ind_list[boundary_obj]
indices = [ind_arr[name] for name in ('x', 'y', 'z')[:method.dim]]
offsets = stencil[ind_arr['dir']]
inv_dir = inv_direction[ind_arr['dir']]
fluid_values = pdf_array[tuple(indices) + (ind_arr['dir'],)]
boundary_values = pdf_array[tuple(ind + offsets[:, i] for i, ind in enumerate(indices)) + (inv_dir,)]
values = fluid_values + boundary_values
forces = stencil[ind_arr['dir']] * values[:, np.newaxis]
result += forces.sum(axis=0)
return dh.reduceFloatSequence(list(result), 'sum')
return dh.reduce_float_sequence(list(result), 'sum')
def _createBoundaryKernel(self, symbolicField, symbolicIndexField, boundaryObject):
return createLatticeBoltzmannBoundaryKernel(symbolicField, symbolicIndexField, self.lbMethod,
boundaryObject, target=self._target, openMP=self._openMP)
def _create_boundary_kernel(self, symbolic_field, symbolic_index_field, boundary_obj):
return create_lattice_boltzmann_boundary_kernel(symbolic_field, symbolic_index_field, self.lb_method,
boundary_obj, target=self._target, openmp=self._openmp)
class LbmWeightInfo(CustomCppCode):
......@@ -81,24 +81,26 @@ class LbmWeightInfo(CustomCppCode):
# --------------------------- Functions to be used by boundaries --------------------------
@staticmethod
def weightOfDirection(dirIdx):
return sp.IndexedBase(LbmWeightInfo.WEIGHTS_SYMBOL, shape=(1,))[dirIdx]
def weight_of_direction(dir_idx):
return sp.IndexedBase(LbmWeightInfo.WEIGHTS_SYMBOL, shape=(1,))[dir_idx]
# ---------------------------------- Internal ---------------------------------------------
WEIGHTS_SYMBOL = TypedSymbol("weights", "double")
def __init__(self, lbMethod):
weights = [str(w.evalf()) for w in lbMethod.weights]
def __init__(self, lb_method):
weights = [str(w.evalf()) for w in lb_method.weights]
code = "const double %s [] = { %s };\n" % (LbmWeightInfo.WEIGHTS_SYMBOL.name, ",".join(weights))
super(LbmWeightInfo, self).__init__(code, symbols_read=set(),
symbols_defined=set([LbmWeightInfo.WEIGHTS_SYMBOL]))
def createLatticeBoltzmannBoundaryKernel(pdfField, indexField, lbMethod, boundaryFunctor, target='cpu', openMP=True):
elements = [BoundaryOffsetInfo(lbMethod.stencil), LbmWeightInfo(lbMethod)]
indexArrDtype = indexField.dtype.numpy_dtype
dirSymbol = TypedSymbol("dir", indexArrDtype.fields['dir'][0])
elements += [Assignment(dirSymbol, indexField[0]('dir'))]
elements += boundaryFunctor(pdfField=pdfField, directionSymbol=dirSymbol, lbMethod=lbMethod, indexField=indexField)
return createIndexedKernel(elements, [indexField], target=target, cpuOpenMP=openMP)
symbols_defined={LbmWeightInfo.WEIGHTS_SYMBOL})
def create_lattice_boltzmann_boundary_kernel(pdf_field, index_field, lb_method, boundary_functor,
target='cpu', openmp=True):
elements = [BoundaryOffsetInfo(lb_method.stencil), LbmWeightInfo(lb_method)]
index_arr_dtype = index_field.dtype.numpy_dtype
dir_symbol = TypedSymbol("dir", index_arr_dtype.fields['dir'][0])
elements += [Assignment(dir_symbol, index_field[0]('dir'))]
elements += boundary_functor(pdf_field=pdf_field, direction_symbol=dir_symbol,
lb_method=lb_method, index_field=index_field)
return create_indexed_kernel(elements, [index_field], target=target, cpu_openmp=openmp)
......@@ -13,51 +13,51 @@ ctypedef fused IntegerType:
unsigned int
unsigned long
@cython.boundscheck(False) # turn off bounds-checking for entire function
@cython.wraparound(False) # turn off negative index wrapping for entire function
def createBoundaryIndexList2D(object[IntegerType, ndim=2] flagField,
int nrOfGhostLayers, IntegerType boundaryMask, IntegerType fluidMask,
object[int, ndim=2] stencil):
@cython.boundscheck(False)
@cython.wraparound(False)
def create_boundary_index_list_2d(object[IntegerType, ndim=2] flag_field,
int nr_of_ghost_layers, IntegerType boundary_mask, IntegerType fluid_mask,
object[int, ndim=2] stencil):
cdef int xs, ys, x, y
cdef int dirIdx, numDirections, dx, dy
cdef int dirIdx, num_directions, dx, dy
xs, ys = flagField.shape
boundaryIndexList = []
numDirections = stencil.shape[0]
xs, ys = flag_field.shape
boundary_index_list = []
num_directions = stencil.shape[0]
for y in range(nrOfGhostLayers,ys-nrOfGhostLayers):
for x in range(nrOfGhostLayers,xs-nrOfGhostLayers):
if flagField[x,y] & fluidMask:
for dirIdx in range(1, numDirections):
for y in range(nr_of_ghost_layers, ys - nr_of_ghost_layers):
for x in range(nr_of_ghost_layers, xs - nr_of_ghost_layers):
if flag_field[x, y] & fluid_mask:
for dirIdx in range(1, num_directions):
dx = stencil[dirIdx,0]
dy = stencil[dirIdx,1]
if flagField[x+dx, y+dy] & boundaryMask:
boundaryIndexList.append((x,y, dirIdx))
return boundaryIndexList
if flag_field[x + dx, y + dy] & boundary_mask:
boundary_index_list.append((x,y, dirIdx))
return boundary_index_list
@cython.boundscheck(False) # turn off bounds-checking for entire function
@cython.wraparound(False) # turn off negative index wrapping for entire function
def createBoundaryIndexList3D(object[IntegerType, ndim=3] flagField,
int nrOfGhostLayers, IntegerType boundaryMask, IntegerType fluidMask,
object[int, ndim=2] stencil):
@cython.boundscheck(False)
@cython.wraparound(False)
def create_boundary_index_list_3d(object[IntegerType, ndim=3] flag_field,
int nr_of_ghost_layers, IntegerType boundary_mask, IntegerType fluid_mask,
object[int, ndim=2] stencil):
cdef int xs, ys, zs, x, y, z
cdef int dirIdx, numDirections, dx, dy, dz
cdef int dirIdx, num_directions, dx, dy, dz
xs, ys, zs = flagField.shape
boundaryIndexList = []
numDirections = stencil.shape[0]
xs, ys, zs = flag_field.shape
boundary_index_list = []
num_directions = stencil.shape[0]
for z in range(nrOfGhostLayers, zs-nrOfGhostLayers):
for y in range(nrOfGhostLayers,ys-nrOfGhostLayers):
for x in range(nrOfGhostLayers,xs-nrOfGhostLayers):
if flagField[x, y, z] & fluidMask:
for dirIdx in range(1, numDirections):
for z in range(nr_of_ghost_layers, zs - nr_of_ghost_layers):
for y in range(nr_of_ghost_layers, ys - nr_of_ghost_layers):
for x in range(nr_of_ghost_layers, xs - nr_of_ghost_layers):
if flag_field[x, y, z] & fluid_mask:
for dirIdx in range(1, num_directions):
dx = stencil[dirIdx,0]
dy = stencil[dirIdx,1]
dz = stencil[dirIdx,2]
if flagField[x + dx, y + dy, z + dz] & boundaryMask:
boundaryIndexList.append((x,y,z, dirIdx))
return boundaryIndexList
if flag_field[x + dx, y + dy, z + dz] & boundary_mask:
boundary_index_list.append((x,y,z, dirIdx))
return boundary_index_list
from lbmpy.chapman_enskog.derivative import DiffOperator, Diff, expandUsingLinearity, expandUsingProductRule, \
normalizeDiffOrder, chapmanEnskogDerivativeExpansion, chapmanEnskogDerivativeRecombination
from lbmpy.chapman_enskog.chapman_enskog import LbMethodEqMoments, insertMoments, takeMoments, \
CeMoment, chainSolveAndSubstitute, timeDiffSelector, momentSelector, ChapmanEnskogAnalysis