From 54c2055c0945f33db76ec5f97f29b32bc5b08fb1 Mon Sep 17 00:00:00 2001 From: Martin Bauer <bauer_martin@gmx.de> Date: Mon, 23 Jan 2017 13:57:17 +0100 Subject: [PATCH] new lbmpy: boundaries --- boundaries/__init__.py | 2 ++ boundaries/boundaryconditions.py | 44 ++++++++++++++++---------------- boundaries/boundaryhandling.py | 16 +++++++++--- methods/momentbased.py | 1 - 4 files changed, 37 insertions(+), 26 deletions(-) diff --git a/boundaries/__init__.py b/boundaries/__init__.py index e69de29b..882a2a77 100644 --- a/boundaries/__init__.py +++ b/boundaries/__init__.py @@ -0,0 +1,2 @@ +from lbmpy.boundaries.boundaryconditions import noSlip, ubb, fixedDensity +from lbmpy.boundaries.boundaryhandling import BoundaryHandling diff --git a/boundaries/boundaryconditions.py b/boundaries/boundaryconditions.py index a9688fd0..293f3ad9 100644 --- a/boundaries/boundaryconditions.py +++ b/boundaries/boundaryconditions.py @@ -1,16 +1,22 @@ import sympy as sp + +from lbmpy.simplificationfactory import createSimplificationStrategy +from pystencils.sympyextensions import getSymmetricPart from lbmpy.boundaries.boundaryhandling import offsetFromDir, weightOfDirection, invDir def noSlip(pdfField, direction, lbmMethod): + """No-Slip, simple bounce back boundary condition, enforcing zero velocity at obstacle""" neighbor = offsetFromDir(direction, lbmMethod.dim) inverseDir = invDir(direction) return [sp.Eq(pdfField[neighbor](inverseDir), pdfField(direction))] def ubb(pdfField, direction, lbmMethod, velocity): + """Velocity bounce back boundary condition, enforcing specified velocity at obstacle""" + assert len(velocity) == lbmMethod.dim, \ - "Dimension of velocity (%d) does not match dimension of LB method (%d)" %(len(velocity, lbmMethod.dim)) + "Dimension of velocity (%d) does not match dimension of LB method (%d)" % (len(velocity, lbmMethod.dim)) neighbor = offsetFromDir(direction, lbmMethod.dim) inverseDir = invDir(direction) @@ -19,32 +25,26 @@ def ubb(pdfField, direction, lbmMethod, velocity): pdfField(direction) - velTerm)] -def fixedDensity(pdfField, direction, latticeModel, density): - from lbmpy_old.equilibria import standardDiscreteEquilibrium - neighbor = offsetFromDir(direction, latticeModel.dim) - inverseDir = invDir(direction) - stencil = latticeModel.stencil +def fixedDensity(pdfField, direction, lbmMethod, density): + """Boundary condition that fixes the density/pressure at the obstacle""" - if not latticeModel.compressible: - density -= 1 + def removeAsymmetricPartOfMainEquations(eqColl, dofs): + newMainEquations = [sp.Eq(e.lhs, getSymmetricPart(e.rhs, dofs)) for e in eqColl.mainEquations] + return eqColl.copy(newMainEquations) - eqParams = {'stencil': stencil, - 'order': 2, - 'c_s_sq': sp.Rational(1, 3), - 'compressible': latticeModel.compressible, - 'rho': density} + neighbor = offsetFromDir(direction, lbmMethod.dim) + inverseDir = invDir(direction) - u = sp.Matrix(latticeModel.symbolicVelocity) - symmetricEq = (standardDiscreteEquilibrium(u=u, **eqParams) + standardDiscreteEquilibrium(u=-u, **eqParams)) / 2 + symmetricEq = removeAsymmetricPartOfMainEquations(lbmMethod.getEquilibrium()) + simplification = createSimplificationStrategy(lbmMethod) + symmetricEq = simplification(symmetricEq) - subExpr1, rhoExpr, subExpr2, uExprs = getDensityVelocityExpressions(stencil, - [pdfField(i) for i in range(len(stencil))], - latticeModel.compressible) - subExprs = subExpr1 + [rhoExpr] + subExpr2 + uExprs + densitySymbol = lbmMethod.conservedQuantityComputation.definedSymbols()['density'] - conditions = [(eq_i, sp.Equality(direction, i)) for i, eq_i in enumerate(symmetricEq)] + [(0, True)] + conditions = [(eq_i.rhs, sp.Equality(direction, i)) + for i, eq_i in enumerate(symmetricEq.mainEquations)] + [(0, True)] eq_component = sp.Piecewise(*conditions) - return subExprs + [sp.Eq(pdfField[neighbor](inverseDir), - 2 * eq_component - pdfField(direction))] + subExprs = [sp.Eq(eq.lhs, density if eq.lhs == densitySymbol else eq.rhs) for eq in symmetricEq.subexpressions] + return subExprs + [sp.Eq(pdfField[neighbor](inverseDir), 2 * eq_component - pdfField(direction))] diff --git a/boundaries/boundaryhandling.py b/boundaries/boundaryhandling.py index a71a28e3..407c6863 100644 --- a/boundaries/boundaryhandling.py +++ b/boundaries/boundaryhandling.py @@ -5,7 +5,8 @@ from pystencils.backends.cbackend import CustomCppCode from pystencils.ast import Block, SympyAssignment, LoopOverCoordinate, KernelFunction from pystencils.transformations import moveConstantsBeforeLoop, resolveFieldAccesses, typingFromSympyInspection, \ typeAllEquations -from pystencils.cpu import makePythonFunction +from pystencils.cpu import makePythonFunction as makePythonCpuFunction +from pystencils.gpucuda import makePythonFunction as makePythonGpuFunction from lbmpy.boundaries.createindexlist import createBoundaryIndexList INV_DIR_SYMBOL = TypedSymbol("invDir", "int") @@ -13,7 +14,7 @@ WEIGHTS_SYMBOL = TypedSymbol("weights", "double") class BoundaryHandling: - def __init__(self, symbolicPdfField, domainShape, latticeModel, ghostLayers=1): + def __init__(self, symbolicPdfField, domainShape, latticeModel, ghostLayers=1, target='cpu'): self._symbolicPdfField = symbolicPdfField self._shapeWithGhostLayers = [d + 2 * ghostLayers for d in domainShape] self._fluidFlag = 2 ** 31 @@ -23,6 +24,9 @@ class BoundaryHandling: self._boundaryFunctions = [] self._nameToIndex = {} self._boundarySweeps = [] + self._target = target + if target not in ('cpu', 'gpu'): + raise ValueError("Invalid target '%s' . Allowed values: 'cpu' or 'gpu'" % (target,)) def addBoundary(self, boundaryFunction, name=None): if name is None: @@ -69,7 +73,13 @@ class BoundaryHandling: idxField = createBoundaryIndexList(self.flagField, self._latticeModel.stencil, 2 ** boundaryIdx, self._fluidFlag, self._ghostLayers) ast = generateBoundaryHandling(self._symbolicPdfField, idxField, self._latticeModel, boundaryFunc) - self._boundarySweeps.append(makePythonFunction(ast, {'indexField': idxField})) + + if self._target == 'cpu': + self._boundarySweeps.append(makePythonCpuFunction(ast, {'indexField': idxField})) + elif self._target == 'gpu': + self._boundarySweeps.append(makePythonGpuFunction(ast, {'indexField': idxField})) + else: + assert False def __call__(self, **kwargs): if len(self._boundarySweeps) == 0: diff --git a/methods/momentbased.py b/methods/momentbased.py index 282dd882..baf71515 100644 --- a/methods/momentbased.py +++ b/methods/momentbased.py @@ -144,7 +144,6 @@ class MomentBasedLbmMethod(AbstractLbmMethod): "Can not determine their relaxation rate automatically") def getEquilibrium(self): - sp.factor D = sp.eye(len(self._relaxationRates)) return self._getCollisionRuleWithRelaxationMatrix(D) -- GitLab