Skip to content
GitLab
Menu
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
...
@@ -9,9 +9,11 @@ from lbmpy.advanced_streaming.utility import get_accessor, inverse_dir_index, is
from
itertools
import
product
from
itertools
import
product
def
_array_pattern
(
dtype
,
name
,
content
):
def
_array_pattern
(
dtype
,
name
,
content
):
return
f
"const
{
str
(
dtype
)
}
{
name
}
[] = {{
{
','
.
join
(
str
(
c
)
for
c
in
content
)
}
}};
\n
"
return
f
"const
{
str
(
dtype
)
}
{
name
}
[] = {{
{
','
.
join
(
str
(
c
)
for
c
in
content
)
}
}};
\n
"
class
BetweenTimestepsIndexing
:
class
BetweenTimestepsIndexing
:
# ==============================================
# ==============================================
...
@@ -187,12 +189,13 @@ class BetweenTimestepsIndexing:
...
@@ -187,12 +189,13 @@ class BetweenTimestepsIndexing:
# end class AdvancedStreamingIndexing
# end class AdvancedStreamingIndexing
class
NeighbourOffsetArraysForStencil
(
CustomCodeNode
):
class
NeighbourOffsetArrays
(
CustomCodeNode
):
@
staticmethod
@
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
]
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
@
staticmethod
def
_offset_symbols
(
dim
):
def
_offset_symbols
(
dim
):
...
@@ -202,11 +205,11 @@ class NeighbourOffsetArraysForStencil(CustomCodeNode):
...
@@ -202,11 +205,11 @@ class NeighbourOffsetArraysForStencil(CustomCodeNode):
offsets_dtype
=
create_type
(
offsets_dtype
)
offsets_dtype
=
create_type
(
offsets_dtype
)
dim
=
len
(
stencil
[
0
])
dim
=
len
(
stencil
[
0
])
array_symbols
=
NeighbourOffsetArrays
ForStencil
.
_offset_symbols
(
dim
)
array_symbols
=
NeighbourOffsetArrays
.
_offset_symbols
(
dim
)
code
=
"
\n
"
code
=
"
\n
"
for
i
,
arrsymb
in
enumerate
(
array_symbols
):
for
i
,
arrsymb
in
enumerate
(
array_symbols
):
code
+=
_array_pattern
(
offsets_dtype
,
arrsymb
.
name
,
(
d
[
i
]
for
d
in
stencil
))
code
+=
_array_pattern
(
offsets_dtype
,
arrsymb
.
name
,
(
d
[
i
]
for
d
in
stencil
))
offset_symbols
=
NeighbourOffsetArraysForStencil
.
_offset_symbols
(
dim
)
offset_symbols
=
NeighbourOffsetArrays
.
_offset_symbols
(
dim
)
super
(
NeighbourOffsetArraysForStencil
,
self
).
__init__
(
code
,
symbols_read
=
set
(),
super
(
NeighbourOffsetArrays
,
self
).
__init__
(
code
,
symbols_read
=
set
(),
symbols_defined
=
set
(
offset_symbols
))
symbols_defined
=
set
(
offset_symbols
))
\ No newline at end of file
lbmpy/advanced_streaming/utility.py
View file @
b5ac8c01
...
@@ -114,5 +114,3 @@ class AccessPdfValues:
...
@@ -114,5 +114,3 @@ class AccessPdfValues:
return
tuple
(
idx
[
v
]
for
v
in
(
'x'
,
'y'
,
'z'
)[:
len
(
idx
)
-
1
]
+
(
'dir'
,))
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
))
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
...
@@ -4,7 +4,7 @@ from lbmpy.boundaries.boundaryhandling import LbmWeightInfo
from
pystencils.data_types
import
create_type
from
pystencils.data_types
import
create_type
from
pystencils.sympyextensions
import
get_symmetric_part
from
pystencils.sympyextensions
import
get_symmetric_part
from
lbmpy.simplificationfactory
import
create_simplification_strategy
from
lbmpy.simplificationfactory
import
create_simplification_strategy
from
lbmpy.advanced_streaming.indexing
import
NeighbourOffsetArrays
ForStencil
from
lbmpy.advanced_streaming.indexing
import
NeighbourOffsetArrays
class
Boundary
:
class
Boundary
:
...
@@ -127,18 +127,17 @@ class UBB(Boundary):
...
@@ -127,18 +127,17 @@ class UBB(Boundary):
return
self
.
_velocity
return
self
.
_velocity
def
get_additional_code_nodes
(
self
,
lb_method
):
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
):
def
__call__
(
self
,
f_out
,
f_in
,
dir_symbol
,
inv_dir
,
lb_method
,
index_field
):
vel_from_idx_field
=
callable
(
self
.
_velocity
)
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
vel
=
[
index_field
(
f
'vel_
{
i
}
'
)
for
i
in
range
(
self
.
dim
)]
if
vel_from_idx_field
else
self
.
_velocity
direction
=
dir_symbol
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
(
neighbor_offset
=
NeighbourOffsetArrays
.
symbolic_neighbour_offset
(
direction
,
lb_method
.
dim
)
direction
,
lb_method
.
dim
)
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,8 +152,8 @@ class UBB(Boundary):
...
@@ -153,8 +152,8 @@ class UBB(Boundary):
c_s_sq
=
sp
.
Rational
(
1
,
3
)
c_s_sq
=
sp
.
Rational
(
1
,
3
)
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
)
# 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"
...
@@ -174,17 +173,16 @@ class UBB(Boundary):
...
@@ -174,17 +173,16 @@ class UBB(Boundary):
f_out
(
direction
)
-
vel_term
)]
f_out
(
direction
)
-
vel_term
)]
# end class UBB
# end class UBB
# TODO
class
FixedDensity
(
Boundary
):
class
FixedDensity
(
Boundary
):
def
__init__
(
self
,
density
,
name
=
None
):
def
__init__
(
self
,
density
,
name
=
None
):
raise
NotImplementedError
()
# not yet operable
if
name
is
None
:
if
name
is
None
:
name
=
"Fixed Density "
+
str
(
density
)
name
=
"Fixed Density "
+
str
(
density
)
super
(
FixedDensity
,
self
).
__init__
(
name
)
super
(
FixedDensity
,
self
).
__init__
(
name
)
self
.
_density
=
density
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"""
"""Boundary condition that fixes the density/pressure at the obstacle"""
def
remove_asymmetric_part_of_main_assignments
(
assignment_collection
,
degrees_of_freedom
):
def
remove_asymmetric_part_of_main_assignments
(
assignment_collection
,
degrees_of_freedom
):
...
@@ -192,14 +190,11 @@ class FixedDensity(Boundary):
...
@@ -192,14 +190,11 @@ class FixedDensity(Boundary):
for
a
in
assignment_collection
.
main_assignments
]
for
a
in
assignment_collection
.
main_assignments
]
return
assignment_collection
.
copy
(
new_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
cqc
=
lb_method
.
conserved_quantity_computation
velocity
=
cqc
.
defined_symbols
()[
'velocity'
]
velocity
=
cqc
.
defined_symbols
()[
'velocity'
]
symmetric_eq
=
remove_asymmetric_part_of_main_assignments
(
lb_method
.
get_equilibrium
(),
symmetric_eq
=
remove_asymmetric_part_of_main_assignments
(
lb_method
.
get_equilibrium
(),
degrees_of_freedom
=
velocity
)
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
)
symmetric_eq
=
symmetric_eq
.
new_with_substitutions
(
substitutions
)
simplification
=
create_simplification_strategy
(
lb_method
)
simplification
=
create_simplification_strategy
(
lb_method
)
...
@@ -214,24 +209,27 @@ class FixedDensity(Boundary):
...
@@ -214,24 +209,27 @@ class FixedDensity(Boundary):
assert
density_eq
.
lhs
==
density_symbol
assert
density_eq
.
lhs
==
density_symbol
transformed_density
=
density_eq
.
rhs
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
)]
for
i
,
eq_i
in
enumerate
(
symmetric_eq
.
main_assignments
)]
+
[(
0
,
True
)]
eq_component
=
sp
.
Piecewise
(
*
conditions
)
eq_component
=
sp
.
Piecewise
(
*
conditions
)
subexpressions
=
[
Assignment
(
eq
.
lhs
,
transformed_density
if
eq
.
lhs
==
density_symbol
else
eq
.
rhs
)
subexpressions
=
[
Assignment
(
eq
.
lhs
,
transformed_density
if
eq
.
lhs
==
density_symbol
else
eq
.
rhs
)
for
eq
in
symmetric_eq
.
subexpressions
]
for
eq
in
symmetric_eq
.
subexpressions
]
return
subexpressions
+
[
Assignment
(
pdf_field
[
neighbor
](
inverse_dir
),
return
subexpressions
+
[
Assignment
(
f_in
(
inv_dir
[
dir_symbol
]),
2
*
eq_component
-
pdf_field
(
direction_symbol
))]
2
*
eq_component
-
f_out
(
dir_symbol
))]
# end class FixedDensity
class
NeumannByCopy
(
Boundary
):
class
NeumannByCopy
(
Boundary
):
def
__call__
(
self
,
pdf_field
,
direction_symbol
,
lb_method
,
**
kwargs
):
raise
NotImplementedError
()
# not yet operable
def
get_additional_code_nodes
(
self
,
lb_method
):
neighbor
=
BoundaryOffsetInfo
.
offset_from_dir
(
direction_symbol
,
lb_method
.
dim
)
return
[
NeighbourOffsetArrays
(
lb_method
.
stencil
)]
inverse_dir
=
BoundaryOffsetInfo
.
inv_dir
(
direction_symbol
)
return
[
Assignment
(
pdf_field
[
neighbor
](
inverse_dir
),
pdf_field
(
inverse_dir
)),
def
__call__
(
self
,
f_out
,
f_in
,
dir_symbol
,
inv_dir
,
lb_method
,
index_field
):
Assignment
(
pdf_field
[
neighbor
](
direction_symbol
),
pdf_field
(
direction_symbol
))]
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
):
def
__hash__
(
self
):
# All boundaries of these class behave equal -> should also be equal
# All boundaries of these class behave equal -> should also be equal
...
@@ -239,19 +237,21 @@ class NeumannByCopy(Boundary):
...
@@ -239,19 +237,21 @@ class NeumannByCopy(Boundary):
def
__eq__
(
self
,
other
):
def
__eq__
(
self
,
other
):
return
type
(
other
)
==
NeumannByCopy
return
type
(
other
)
==
NeumannByCopy
# end class NeumannByCopy
class
StreamInConstant
(
Boundary
):
class
StreamInConstant
(
Boundary
):
def
__init__
(
self
,
constant
,
name
=
None
):
def
__init__
(
self
,
constant
,
name
=
None
):
raise
NotImplementedError
()
# not yet operable
super
(
StreamInConstant
,
self
).
__init__
(
name
)
super
(
StreamInConstant
,
self
).
__init__
(
name
)
self
.
_constant
=
constant
self
.
_constant
=
constant
def
__call__
(
self
,
pdf_field
,
direction_symbol
,
lb_method
,
**
kwargs
):
def
get_additional_code_nodes
(
self
,
lb_method
):
neighbor
=
BoundaryOffsetInfo
.
offset_from_dir
(
direction_symbol
,
lb_method
.
dim
)
return
[
NeighbourOffsetArrays
(
lb_method
.
stencil
)]
inverse_dir
=
BoundaryOffsetInfo
.
inv_dir
(
direction_symbol
)
return
[
Assignment
(
pdf_field
[
neighbor
](
inverse_dir
),
self
.
_constant
),
def
__call__
(
self
,
f_out
,
f_in
,
dir_symbol
,
inv_dir
,
lb_method
,
index_field
):
Assignment
(
pdf_field
[
neighbor
](
direction_symbol
),
self
.
_constant
)]
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
):
def
__hash__
(
self
):
# All boundaries of these class behave equal -> should also be equal
# All boundaries of these class behave equal -> should also be equal
...
@@ -259,3 +259,4 @@ class StreamInConstant(Boundary):
...
@@ -259,3 +259,4 @@ class StreamInConstant(Boundary):
def
__eq__
(
self
,
other
):
def
__eq__
(
self
,
other
):
return
type
(
other
)
==
StreamInConstant
return
type
(
other
)
==
StreamInConstant
# end class StreamInConstant
lbmpy/boundaries/boundaryhandling.py
View file @
b5ac8c01
...
@@ -23,7 +23,7 @@ class LatticeBoltzmannBoundaryHandling(BoundaryHandling):
...
@@ -23,7 +23,7 @@ class LatticeBoltzmannBoundaryHandling(BoundaryHandling):
self
.
_inplace
=
is_inplace
(
streaming_pattern
)
self
.
_inplace
=
is_inplace
(
streaming_pattern
)
self
.
_prev_timestep
=
None
self
.
_prev_timestep
=
None
super
(
LatticeBoltzmannBoundaryHandling
,
self
).
__init__
(
data_handling
,
pdf_field_name
,
lb_method
.
stencil
,
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 -------------------------
# ------------------------- Overridden methods of pystencils.BoundaryHandling -------------------------
...
@@ -121,7 +121,7 @@ class LatticeBoltzmannBoundaryHandling(BoundaryHandling):
...
@@ -121,7 +121,7 @@ class LatticeBoltzmannBoundaryHandling(BoundaryHandling):
method
=
self
.
_lb_method
method
=
self
.
_lb_method
stencil
=
np
.
array
(
method
.
stencil
)
stencil
=
np
.
array
(
method
.
stencil
)
inv_direction
=
np
.
array
([
method
.
stencil
.
index
(
inverse_direction
(
d
))
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
)
result
=
np
.
zeros
(
self
.
dim
)
for
b
in
dh
.
iterate
(
ghost_layers
=
ff_ghost_layers
):
for
b
in
dh
.
iterate
(
ghost_layers
=
ff_ghost_layers
):
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a 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