Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Frederik Hennig
lbmpy
Commits
b5ac8c01
Commit
b5ac8c01
authored
Oct 24, 2020
by
Frederik Hennig
Browse files
Integrated exotic boundaries
parent
dd1cbd09
Changes
5
Expand all
Hide whitespace changes
Inline
Side-by-side
lbmpy/advanced_streaming/Advanced Boundaries.ipynb
deleted
100644 → 0
View file @
dd1cbd09
This diff is collapsed.
Click to expand it.
lbmpy/advanced_streaming/indexing.py
View file @
b5ac8c01
...
...
@@ -9,9 +9,11 @@ from lbmpy.advanced_streaming.utility import get_accessor, inverse_dir_index, is
from
itertools
import
product
def
_array_pattern
(
dtype
,
name
,
content
):
return
f
"const
{
str
(
dtype
)
}
{
name
}
[] = {{
{
','
.
join
(
str
(
c
)
for
c
in
content
)
}
}};
\n
"
class
BetweenTimestepsIndexing
:
# ==============================================
...
...
@@ -187,12 +189,13 @@ class BetweenTimestepsIndexing:
# end class AdvancedStreamingIndexing
class
NeighbourOffsetArraysForStencil
(
CustomCodeNode
):
class
NeighbourOffsetArrays
(
CustomCodeNode
):
@
staticmethod
def
symbolic_neighbour_offset
_from_dir
(
dir_idx
,
dim
):
def
symbolic_neighbour_offset
(
dir_idx
,
dim
):
return
tuple
([
sp
.
IndexedBase
(
symbol
,
shape
=
(
1
,))[
dir_idx
]
for
symbol
in
NeighbourOffsetArrays
ForStencil
.
_offset_symbols
(
dim
)])
for
symbol
in
NeighbourOffsetArrays
.
_offset_symbols
(
dim
)])
@
staticmethod
def
_offset_symbols
(
dim
):
...
...
@@ -202,11 +205,11 @@ class NeighbourOffsetArraysForStencil(CustomCodeNode):
offsets_dtype
=
create_type
(
offsets_dtype
)
dim
=
len
(
stencil
[
0
])
array_symbols
=
NeighbourOffsetArrays
ForStencil
.
_offset_symbols
(
dim
)
array_symbols
=
NeighbourOffsetArrays
.
_offset_symbols
(
dim
)
code
=
"
\n
"
for
i
,
arrsymb
in
enumerate
(
array_symbols
):
code
+=
_array_pattern
(
offsets_dtype
,
arrsymb
.
name
,
(
d
[
i
]
for
d
in
stencil
))
offset_symbols
=
NeighbourOffsetArraysForStencil
.
_offset_symbols
(
dim
)
super
(
NeighbourOffsetArraysForStencil
,
self
).
__init__
(
code
,
symbols_read
=
set
(),
symbols_defined
=
set
(
offset_symbols
))
\ No newline at end of file
offset_symbols
=
NeighbourOffsetArrays
.
_offset_symbols
(
dim
)
super
(
NeighbourOffsetArrays
,
self
).
__init__
(
code
,
symbols_read
=
set
(),
symbols_defined
=
set
(
offset_symbols
))
lbmpy/advanced_streaming/utility.py
View file @
b5ac8c01
...
...
@@ -114,5 +114,3 @@ class AccessPdfValues:
return
tuple
(
idx
[
v
]
for
v
in
(
'x'
,
'y'
,
'z'
)[:
len
(
idx
)
-
1
]
+
(
'dir'
,))
return
self
.
read_multiple
(
pdf_arr
,
(
to_index_tuple
(
idx
)
for
idx
in
index_list
))
lbmpy/boundaries/boundaryconditions.py
View file @
b5ac8c01
...
...
@@ -4,7 +4,7 @@ from lbmpy.boundaries.boundaryhandling import LbmWeightInfo
from
pystencils.data_types
import
create_type
from
pystencils.sympyextensions
import
get_symmetric_part
from
lbmpy.simplificationfactory
import
create_simplification_strategy
from
lbmpy.advanced_streaming.indexing
import
NeighbourOffsetArrays
ForStencil
from
lbmpy.advanced_streaming.indexing
import
NeighbourOffsetArrays
class
Boundary
:
...
...
@@ -127,18 +127,17 @@ class UBB(Boundary):
return
self
.
_velocity
def
get_additional_code_nodes
(
self
,
lb_method
):
return
[
LbmWeightInfo
(
lb_method
),
NeighbourOffsetArraysForStencil
(
lb_method
.
stencil
)]
return
[
LbmWeightInfo
(
lb_method
),
NeighbourOffsetArrays
(
lb_method
.
stencil
)]
def
__call__
(
self
,
f_out
,
f_in
,
dir_symbol
,
inv_dir
,
lb_method
,
index_field
):
vel_from_idx_field
=
callable
(
self
.
_velocity
)
vel
=
[
index_field
(
f
'vel_
{
i
}
'
)
for
i
in
range
(
self
.
dim
)]
if
vel_from_idx_field
else
self
.
_velocity
direction
=
dir_symbol
assert
self
.
dim
==
lb_method
.
dim
,
f
"Dimension of UBB (
{
self
.
dim
}
) does not match dimension of method (
{
lb_method
.
dim
}
)"
assert
self
.
dim
==
lb_method
.
dim
,
\
f
"Dimension of UBB (
{
self
.
dim
}
) does not match dimension of method (
{
lb_method
.
dim
}
)"
neighbor_offset
=
NeighbourOffsetArraysForStencil
.
symbolic_neighbour_offset_from_dir
(
direction
,
lb_method
.
dim
)
neighbor_offset
=
NeighbourOffsetArrays
.
symbolic_neighbour_offset
(
direction
,
lb_method
.
dim
)
velocity
=
tuple
(
v_i
.
get_shifted
(
*
neighbor_offset
)
if
isinstance
(
v_i
,
Field
.
Access
)
and
not
vel_from_idx_field
...
...
@@ -153,8 +152,8 @@ class UBB(Boundary):
c_s_sq
=
sp
.
Rational
(
1
,
3
)
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_offset
,
velocity
)])
\
*
weight_of_direction
(
direction
)
*
sum
([
d_i
*
v_i
for
d_i
,
v_i
in
zip
(
neighbor_offset
,
velocity
)])
\
*
weight_of_direction
(
direction
)
# Better alternative: in conserved value computation
# rename what is currently called density to "virtual_density"
...
...
@@ -174,17 +173,16 @@ class UBB(Boundary):
f_out
(
direction
)
-
vel_term
)]
# end class UBB
# TODO
class
FixedDensity
(
Boundary
):
def
__init__
(
self
,
density
,
name
=
None
):
raise
NotImplementedError
()
# not yet operable
if
name
is
None
:
name
=
"Fixed Density "
+
str
(
density
)
super
(
FixedDensity
,
self
).
__init__
(
name
)
self
.
_density
=
density
def
__call__
(
self
,
pdf_field
,
direction_symbol
,
lb_method
,
**
kwargs
):
def
__call__
(
self
,
f_out
,
f_in
,
dir_symbol
,
inv_dir
,
lb_method
,
index_field
):
"""Boundary condition that fixes the density/pressure at the obstacle"""
def
remove_asymmetric_part_of_main_assignments
(
assignment_collection
,
degrees_of_freedom
):
...
...
@@ -192,14 +190,11 @@ class FixedDensity(Boundary):
for
a
in
assignment_collection
.
main_assignments
]
return
assignment_collection
.
copy
(
new_main_assignments
)
neighbor
=
BoundaryOffsetInfo
.
offset_from_dir
(
direction_symbol
,
lb_method
.
dim
)
inverse_dir
=
BoundaryOffsetInfo
.
inv_dir
(
direction_symbol
)
cqc
=
lb_method
.
conserved_quantity_computation
velocity
=
cqc
.
defined_symbols
()[
'velocity'
]
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
)}
substitutions
=
{
sym
:
f_out
(
i
)
for
i
,
sym
in
enumerate
(
lb_method
.
pre_collision_pdf_symbols
)}
symmetric_eq
=
symmetric_eq
.
new_with_substitutions
(
substitutions
)
simplification
=
create_simplification_strategy
(
lb_method
)
...
...
@@ -214,24 +209,27 @@ class FixedDensity(Boundary):
assert
density_eq
.
lhs
==
density_symbol
transformed_density
=
density_eq
.
rhs
conditions
=
[(
eq_i
.
rhs
,
sp
.
Equality
(
dir
ection
_symbol
,
i
))
conditions
=
[(
eq_i
.
rhs
,
sp
.
Equality
(
dir_symbol
,
i
))
for
i
,
eq_i
in
enumerate
(
symmetric_eq
.
main_assignments
)]
+
[(
0
,
True
)]
eq_component
=
sp
.
Piecewise
(
*
conditions
)
subexpressions
=
[
Assignment
(
eq
.
lhs
,
transformed_density
if
eq
.
lhs
==
density_symbol
else
eq
.
rhs
)
for
eq
in
symmetric_eq
.
subexpressions
]
return
subexpressions
+
[
Assignment
(
pdf_field
[
neighbor
](
inverse_dir
),
2
*
eq_component
-
pdf_field
(
direction_symbol
))]
return
subexpressions
+
[
Assignment
(
f_in
(
inv_dir
[
dir_symbol
]),
2
*
eq_component
-
f_out
(
dir_symbol
))]
# end class FixedDensity
class
NeumannByCopy
(
Boundary
):
def
__call__
(
self
,
pdf_field
,
direction_symbol
,
lb_method
,
**
kwargs
):
raise
NotImplementedError
()
# not yet operable
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
get_additional_code_nodes
(
self
,
lb_method
):
return
[
NeighbourOffsetArrays
(
lb_method
.
stencil
)]
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
)
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
))]
def
__hash__
(
self
):
# All boundaries of these class behave equal -> should also be equal
...
...
@@ -239,19 +237,21 @@ class NeumannByCopy(Boundary):
def
__eq__
(
self
,
other
):
return
type
(
other
)
==
NeumannByCopy
# end class NeumannByCopy
class
StreamInConstant
(
Boundary
):
def
__init__
(
self
,
constant
,
name
=
None
):
raise
NotImplementedError
()
# not yet operable
super
(
StreamInConstant
,
self
).
__init__
(
name
)
self
.
_constant
=
constant
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
),
self
.
_constant
),
Assignment
(
pdf_field
[
neighbor
](
direction_symbol
),
self
.
_constant
)]
def
get_additional_code_nodes
(
self
,
lb_method
):
return
[
NeighbourOffsetArrays
(
lb_method
.
stencil
)]
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
)
return
[
Assignment
(
f_in
(
inv_dir
[
dir_symbol
]),
self
.
_constant
),
Assignment
(
f_out
[
neighbour_offset
](
dir_symbol
),
self
.
_constant
)]
def
__hash__
(
self
):
# All boundaries of these class behave equal -> should also be equal
...
...
@@ -259,3 +259,4 @@ class StreamInConstant(Boundary):
def
__eq__
(
self
,
other
):
return
type
(
other
)
==
StreamInConstant
# end class StreamInConstant
lbmpy/boundaries/boundaryhandling.py
View file @
b5ac8c01
...
...
@@ -23,7 +23,7 @@ class LatticeBoltzmannBoundaryHandling(BoundaryHandling):
self
.
_inplace
=
is_inplace
(
streaming_pattern
)
self
.
_prev_timestep
=
None
super
(
LatticeBoltzmannBoundaryHandling
,
self
).
__init__
(
data_handling
,
pdf_field_name
,
lb_method
.
stencil
,
name
,
flag_interface
,
target
,
openmp
)
name
,
flag_interface
,
target
,
openmp
)
# ------------------------- Overridden methods of pystencils.BoundaryHandling -------------------------
...
...
@@ -121,7 +121,7 @@ class LatticeBoltzmannBoundaryHandling(BoundaryHandling):
method
=
self
.
_lb_method
stencil
=
np
.
array
(
method
.
stencil
)
inv_direction
=
np
.
array
([
method
.
stencil
.
index
(
inverse_direction
(
d
))
for
d
in
method
.
stencil
])
for
d
in
method
.
stencil
])
result
=
np
.
zeros
(
self
.
dim
)
for
b
in
dh
.
iterate
(
ghost_layers
=
ff_ghost_layers
):
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment