Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
itischler
lbmpy
Commits
9e24f658
Commit
9e24f658
authored
Jan 20, 2021
by
Frederik Hennig
Committed by
Markus Holzer
Jan 20, 2021
Browse files
Link-Wise Extrapolation Outflow
parent
e14f9152
Changes
3
Hide whitespace changes
Inline
Side-by-side
lbmpy/advanced_streaming/indexing.py
View file @
9e24f658
...
@@ -133,10 +133,10 @@ class BetweenTimestepsIndexing:
...
@@ -133,10 +133,10 @@ class BetweenTimestepsIndexing:
inv
=
True
inv
=
True
if
isinstance
(
sp
.
sympify
(
idx
),
sp
.
Integer
):
if
isinstance
(
sp
.
sympify
(
idx
),
sp
.
Integer
):
accessor_subs
[
fa
]
=
accesses
[
f_dir
][
idx
].
get_shifted
(
*
(
fa
.
offsets
)
)
accessor_subs
[
fa
]
=
accesses
[
f_dir
][
idx
].
get_shifted
(
*
fa
.
offsets
)
else
:
else
:
arr
=
self
.
_array_symbols
(
f_dir
,
inv
,
idx
)
arr
=
self
.
_array_symbols
(
f_dir
,
inv
,
idx
)
accessor_subs
[
fa
]
=
self
.
_pdf_field
[
arr
[
'offsets'
]](
arr
[
'index'
]).
get_shifted
(
*
(
fa
.
offsets
)
)
accessor_subs
[
fa
]
=
self
.
_pdf_field
[
arr
[
'offsets'
]](
arr
[
'index'
]).
get_shifted
(
*
fa
.
offsets
)
return
assignments
.
new_with_substitutions
(
accessor_subs
)
return
assignments
.
new_with_substitutions
(
accessor_subs
)
...
...
lbmpy/boundaries/boundaryconditions.py
View file @
9e24f658
...
@@ -7,7 +7,7 @@ from pystencils.data_types import create_type
...
@@ -7,7 +7,7 @@ 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
from
lbmpy.advanced_streaming.indexing
import
NeighbourOffsetArrays
from
pystencils.stencil
import
offset_to_direction_string
,
direction_string_to_offset
from
pystencils.stencil
import
offset_to_direction_string
,
direction_string_to_offset
,
inverse_direction
class
LbBoundary
:
class
LbBoundary
:
...
@@ -28,20 +28,21 @@ class LbBoundary:
...
@@ -28,20 +28,21 @@ class LbBoundary:
This function defines the boundary behavior and must therefore be implemented by all boundaries.
This function defines the boundary behavior and must therefore be implemented by all boundaries.
The boundary is defined through a list of sympy equations from which a boundary kernel is generated.
The boundary is defined through a list of sympy equations from which a boundary kernel is generated.
Args:
f_out: a pystencils field acting as a proxy to access the populations streaming out of the current
cell, i.e. the post-collision PDFs of the previous LBM step
f_in: a pystencils field acting as a proxy to access the populations streaming into the current
cell, i.e. the pre-collision PDFs for the next LBM step
dir_symbol: a sympy symbol that can be used as an index to f_out and f_in. It describes the direction
pointing from the fluid to the boundary cell.
inv_dir: an indexed sympy symbol which describes the inversion of a direction index. It can be used in
the indices of f_out and f_in for retrieving the PDF of the inverse direction.
lb_method: an instance of the LB method used. Use this to adapt the boundary to the method
(e.g. compressibility)
index_field: the boundary index field that can be used to retrieve and update boundary data
:param f_out: a pystencils field acting as a proxy to access the populations streaming out of the current
Returns:
cell, i.e. the post-collision PDFs of the previous LBM step
list of pystencils assignments, or pystencils.AssignmentCollection
:param f_in: a pystencils field acting as a proxy to access the populations streaming into the current
cell, i.e. the pre-collision PDFs for the next LBM step
:param dir_symbol: a sympy symbol that can be used as an index to f_out and f_in. It describes the direction
pointing from the fluid to the boundary cell.
:param inv_dir: an indexed sympy symbol which describes the inversion of a direction index. It can be used in
the indices of f_out and f_in for retrieving the PDF of the inverse direction.
: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 pystencils assignments, or pystencils.AssignmentCollection
"""
"""
raise
NotImplementedError
(
"Boundary class has to overwrite __call__"
)
raise
NotImplementedError
(
"Boundary class has to overwrite __call__"
)
...
@@ -77,6 +78,7 @@ class LbBoundary:
...
@@ -77,6 +78,7 @@ class LbBoundary:
def
name
(
self
,
new_value
):
def
name
(
self
,
new_value
):
self
.
_name
=
new_value
self
.
_name
=
new_value
# end class Boundary
# end class Boundary
...
@@ -104,6 +106,7 @@ class NoSlip(LbBoundary):
...
@@ -104,6 +106,7 @@ class NoSlip(LbBoundary):
return
False
return
False
return
self
.
name
==
other
.
name
return
self
.
name
==
other
.
name
# end class NoSlip
# end class NoSlip
...
@@ -182,9 +185,8 @@ class UBB(LbBoundary):
...
@@ -182,9 +185,8 @@ class UBB(LbBoundary):
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
)])
*
weight_of_direction
(
*
sum
([
d_i
*
v_i
for
d_i
,
v_i
in
zip
(
neighbor_offset
,
velocity
)])
\
direction
,
lb_method
)
*
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"
...
@@ -202,6 +204,8 @@ class UBB(LbBoundary):
...
@@ -202,6 +204,8 @@ class UBB(LbBoundary):
else
:
else
:
return
[
Assignment
(
f_in
(
inv_dir
[
direction
]),
return
[
Assignment
(
f_in
(
inv_dir
[
direction
]),
f_out
(
direction
)
-
vel_term
)]
f_out
(
direction
)
-
vel_term
)]
# end class UBB
# end class UBB
...
@@ -217,14 +221,10 @@ class SimpleExtrapolationOutflow(LbBoundary):
...
@@ -217,14 +221,10 @@ class SimpleExtrapolationOutflow(LbBoundary):
Args:
Args:
normal_direction: direction vector normal to the outflow
normal_direction: direction vector normal to the outflow
stencil: stencil used
for
the lattice
B
oltzmann method
stencil: stencil used
by
the lattice
b
oltzmann method
name: optional name of the boundary.
name: optional name of the boundary.
"""
"""
# We need each fluid cell only once, the direction of the outflow is given
# in the constructor.
single_link
=
True
def
__init__
(
self
,
normal_direction
,
stencil
,
name
=
None
):
def
__init__
(
self
,
normal_direction
,
stencil
,
name
=
None
):
if
isinstance
(
normal_direction
,
str
):
if
isinstance
(
normal_direction
,
str
):
normal_direction
=
direction_string_to_offset
(
normal_direction
,
dim
=
len
(
stencil
[
0
]))
normal_direction
=
direction_string_to_offset
(
normal_direction
,
dim
=
len
(
stencil
[
0
]))
...
@@ -235,26 +235,35 @@ class SimpleExtrapolationOutflow(LbBoundary):
...
@@ -235,26 +235,35 @@ class SimpleExtrapolationOutflow(LbBoundary):
self
.
normal_direction
=
normal_direction
self
.
normal_direction
=
normal_direction
super
(
SimpleExtrapolationOutflow
,
self
).
__init__
(
name
)
super
(
SimpleExtrapolationOutflow
,
self
).
__init__
(
name
)
def
get_additional_code_nodes
(
self
,
lb_method
):
"""Return a list of code nodes that will be added in the generated code before the index field loop.
Args:
lb_method: Lattice Boltzmann method. See :func:`lbmpy.creationfunctions.create_lb_method`
Returns:
list containing NeighbourOffsetArrays
"""
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
):
stencil
=
lb_method
.
stencil
neighbor_offset
=
NeighbourOffsetArrays
.
neighbour_offset
(
dir_symbol
,
lb_method
.
stencil
)
tangential_offset
=
tuple
(
offset
-
normal
for
offset
,
normal
in
zip
(
neighbor_offset
,
self
.
normal_direction
))
return
Assignment
(
f_in
.
center
(
inv_dir
[
dir_symbol
]),
f_out
[
tangential_offset
](
inv_dir
[
dir_symbol
]))
boundary_assignments
=
[]
for
i
,
stencil_dir
in
enumerate
(
stencil
):
if
all
(
n
==
0
or
n
==
-
s
for
s
,
n
in
zip
(
stencil_dir
,
self
.
normal_direction
)):
asm
=
Assignment
(
f_out
[
self
.
normal_direction
](
i
),
f_out
.
center
(
i
))
boundary_assignments
.
append
(
asm
)
print
(
boundary_assignments
)
return
boundary_assignments
# end class SimpleExtrapolationOutflow
# end class SimpleExtrapolationOutflow
class
ExtrapolationOutflow
(
LbBoundary
):
class
ExtrapolationOutflow
(
LbBoundary
):
r
"""
r
"""
Outflow boundary condition :cite:`geier2015`, equation F.2, with u neglected (listed below).
Outflow boundary condition :cite:`geier2015`, equation F.2, with u neglected (listed below).
This boundary condition interpolates missing on the boundary in normal direction. For this interpolation, the
This boundary condition interpolates populations missing on the boundary in normal direction.
PDF values of the last time step are used. They are interpolated between fluid cell and boundary cell.
For this interpolation, the PDF values of the last time step are used. They are interpolated
To get the PDF values from the last time step an index array is used which stores them.
between fluid cell and boundary cell. To get the PDF values from the last time step an index
array is used which stores them.
.. math ::
.. math ::
f_{\overline{1}jkxyzt} = f_{\overline{1}jk(x - \Delta x)yz(t - \Delta t)} c \theta^{\frac{1}{2}}
f_{\overline{1}jkxyzt} = f_{\overline{1}jk(x - \Delta x)yz(t - \Delta t)} c \theta^{\frac{1}{2}}
...
@@ -276,10 +285,6 @@ class ExtrapolationOutflow(LbBoundary):
...
@@ -276,10 +285,6 @@ class ExtrapolationOutflow(LbBoundary):
positional arguments, specifying the initial velocity on boundary nodes
positional arguments, specifying the initial velocity on boundary nodes
"""
"""
# We need each fluid cell only once, the direction of the outflow is given
# in the constructor.
single_link
=
True
def
__init__
(
self
,
normal_direction
,
lb_method
,
dt
=
1
,
dx
=
1
,
name
=
None
,
def
__init__
(
self
,
normal_direction
,
lb_method
,
dt
=
1
,
dx
=
1
,
name
=
None
,
streaming_pattern
=
'pull'
,
zeroth_timestep
=
Timestep
.
BOTH
,
streaming_pattern
=
'pull'
,
zeroth_timestep
=
Timestep
.
BOTH
,
initial_density
=
None
,
initial_velocity
=
None
):
initial_density
=
None
,
initial_velocity
=
None
):
...
@@ -335,56 +340,65 @@ class ExtrapolationOutflow(LbBoundary):
...
@@ -335,56 +340,65 @@ class ExtrapolationOutflow(LbBoundary):
return
pdf_acc
.
read_pdf
(
boundary_data
.
pdf_array
,
fluid_cell
,
j
)
return
pdf_acc
.
read_pdf
(
boundary_data
.
pdf_array
,
fluid_cell
,
j
)
for
entry
in
boundary_data
.
index_array
:
for
entry
in
boundary_data
.
index_array
:
fluid_cell
=
tuple
(
entry
[
c
]
for
c
in
coord_names
)
center
=
tuple
(
entry
[
c
]
for
c
in
coord_names
)
boundary_cell
=
tuple
(
f
+
o
for
f
,
o
in
zip
(
fluid_cell
,
self
.
normal_direction
))
direction
=
self
.
stencil
[
entry
[
"dir"
]]
inv_dir
=
self
.
stencil
.
index
(
inverse_direction
(
direction
))
tangential_offset
=
tuple
(
offset
-
normal
for
offset
,
normal
in
zip
(
direction
,
self
.
normal_direction
))
domain_cell
=
tuple
(
f
+
o
for
f
,
o
in
zip
(
center
,
tangential_offset
))
outflow_cell
=
tuple
(
f
+
o
for
f
,
o
in
zip
(
center
,
direction
))
# Initial fluid cell PDF values
# Initial fluid cell PDF values
for
j
,
stencil_dir
in
enumerate
(
self
.
stencil
):
entry
[
'pdf'
]
=
pdf_acc
.
read_pdf
(
boundary_data
.
pdf_array
,
domain_cell
,
inv_dir
)
if
all
(
n
==
0
or
n
==
-
s
for
s
,
n
in
zip
(
stencil_dir
,
self
.
normal_direction
)):
entry
[
'pdf_nd'
]
=
get_boundary_cell_pdfs
(
domain_cell
,
outflow_cell
,
inv_dir
)
entry
[
f
'pdf_
{
j
}
'
]
=
pdf_acc
.
read_pdf
(
boundary_data
.
pdf_array
,
fluid_cell
,
j
)
entry
[
f
'pdf_nd_
{
j
}
'
]
=
get_boundary_cell_pdfs
(
fluid_cell
,
boundary_cell
,
j
)
@
property
@
property
def
additional_data
(
self
):
def
additional_data
(
self
):
"""Used internally only. For the ExtrapolationOutflow information of the precious PDF values is needed. This
"""Used internally only. For the ExtrapolationOutflow information of the previous PDF values is needed. This
information is added to the boundary"""
information is stored in the index vector."""
data
=
[]
data
=
[(
'pdf'
,
create_type
(
"double"
)),
(
'pdf_nd'
,
create_type
(
"double"
))]
for
i
,
stencil_dir
in
enumerate
(
self
.
stencil
):
if
all
(
n
==
0
or
n
==
-
s
for
s
,
n
in
zip
(
stencil_dir
,
self
.
normal_direction
)):
data
.
append
((
f
'pdf_
{
i
}
'
,
create_type
(
"double"
)))
data
.
append
((
f
'pdf_nd_
{
i
}
'
,
create_type
(
"double"
)))
return
data
return
data
@
property
@
property
def
additional_data_init_callback
(
self
):
def
additional_data_init_callback
(
self
):
"""The initialisation of the additional data is implemented internally for this class.
return
self
.
init_callback
Thus no callback can be provided"""
if
callable
(
self
.
init_callback
):
def
get_additional_code_nodes
(
self
,
lb_method
):
return
self
.
init_callback
"""Return a list of code nodes that will be added in the generated code before the index field loop.
Args:
lb_method: Lattice Boltzmann method. See :func:`lbmpy.creationfunctions.create_lb_method`
Returns:
list containing NeighbourOffsetArrays
"""
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
):
subexpressions
=
[]
subexpressions
=
[]
boundary_assignments
=
[]
boundary_assignments
=
[]
dtdx
=
sp
.
Rational
(
self
.
dt
,
self
.
dx
)
dtdx
=
sp
.
Rational
(
self
.
dt
,
self
.
dx
)
for
i
,
stencil_dir
in
enumerate
(
self
.
stencil
)
:
neighbor_offset
=
NeighbourOffsetArrays
.
neighbour_offset
(
dir_symbol
,
lb_method
.
stencil
)
if
all
(
n
==
0
or
n
==
-
s
for
s
,
n
in
zip
(
stencil_dir
,
self
.
normal_direction
))
:
tangential_offset
=
tuple
(
offset
-
normal
for
offset
,
normal
in
zip
(
neighbor_offset
,
self
.
normal_direction
))
interpolated_pdf_sym
=
sp
.
Symbol
(
f
'pdf_inter
_
{
i
}
'
)
interpolated_pdf_sym
=
sp
.
Symbol
(
'pdf_inter'
)
interpolated_pdf_asm
=
Assignment
(
interpolated_pdf_sym
,
(
index_field
[
0
](
f
'pdf
_
{
i
}
'
)
*
(
self
.
c
*
dtdx
))
interpolated_pdf_asm
=
Assignment
(
interpolated_pdf_sym
,
(
index_field
[
0
](
'pdf'
)
*
(
self
.
c
*
dtdx
))
+
((
sp
.
Number
(
1
)
-
self
.
c
*
dtdx
)
*
index_field
[
0
](
f
'pdf_nd
_
{
i
}
'
)))
+
((
sp
.
Number
(
1
)
-
self
.
c
*
dtdx
)
*
index_field
[
0
](
'pdf_nd'
)))
subexpressions
.
append
(
interpolated_pdf_asm
)
subexpressions
.
append
(
interpolated_pdf_asm
)
asm
=
Assignment
(
f_
out
[
self
.
normal_direction
](
i
),
interpolated_pdf_sym
)
asm
=
Assignment
(
f_
in
.
center
(
inv_dir
[
dir_symbol
]
),
interpolated_pdf_sym
)
boundary_assignments
.
append
(
asm
)
boundary_assignments
.
append
(
asm
)
asm
=
Assignment
(
index_field
[
0
](
f
'pdf
_
{
i
}
'
),
f_out
.
center
(
i
))
asm
=
Assignment
(
index_field
[
0
](
'pdf'
),
f_out
[
tangential_offset
](
inv_dir
[
dir_symbol
]
))
boundary_assignments
.
append
(
asm
)
boundary_assignments
.
append
(
asm
)
asm
=
Assignment
(
index_field
[
0
](
f
'pdf_nd
_
{
i
}
'
),
interpolated_pdf_sym
)
asm
=
Assignment
(
index_field
[
0
](
'pdf_nd'
),
interpolated_pdf_sym
)
boundary_assignments
.
append
(
asm
)
boundary_assignments
.
append
(
asm
)
return
AssignmentCollection
(
boundary_assignments
,
subexpressions
=
subexpressions
)
return
AssignmentCollection
(
boundary_assignments
,
subexpressions
=
subexpressions
)
# end class ExtrapolationOutflow
# end class ExtrapolationOutflow
...
@@ -404,7 +418,6 @@ class FixedDensity(LbBoundary):
...
@@ -404,7 +418,6 @@ class FixedDensity(LbBoundary):
self
.
_density
=
density
self
.
_density
=
density
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
):
def
remove_asymmetric_part_of_main_assignments
(
assignment_collection
,
degrees_of_freedom
):
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
))
new_main_assignments
=
[
Assignment
(
a
.
lhs
,
get_symmetric_part
(
a
.
rhs
,
degrees_of_freedom
))
for
a
in
assignment_collection
.
main_assignments
]
for
a
in
assignment_collection
.
main_assignments
]
...
@@ -438,6 +451,8 @@ class FixedDensity(LbBoundary):
...
@@ -438,6 +451,8 @@ class FixedDensity(LbBoundary):
return
subexpressions
+
[
Assignment
(
f_in
(
inv_dir
[
dir_symbol
]),
return
subexpressions
+
[
Assignment
(
f_in
(
inv_dir
[
dir_symbol
]),
2
*
eq_component
-
f_out
(
dir_symbol
))]
2
*
eq_component
-
f_out
(
dir_symbol
))]
# end class FixedDensity
# end class FixedDensity
...
@@ -467,6 +482,8 @@ class NeumannByCopy(LbBoundary):
...
@@ -467,6 +482,8 @@ class NeumannByCopy(LbBoundary):
def
__eq__
(
self
,
other
):
def
__eq__
(
self
,
other
):
return
type
(
other
)
==
NeumannByCopy
return
type
(
other
)
==
NeumannByCopy
# end class NeumannByCopy
# end class NeumannByCopy
...
@@ -479,6 +496,7 @@ class StreamInConstant(LbBoundary):
...
@@ -479,6 +496,7 @@ class StreamInConstant(LbBoundary):
name: optional name of the boundary.
name: optional name of the boundary.
"""
"""
def
__init__
(
self
,
constant
,
name
=
None
):
def
__init__
(
self
,
constant
,
name
=
None
):
super
(
StreamInConstant
,
self
).
__init__
(
name
)
super
(
StreamInConstant
,
self
).
__init__
(
name
)
self
.
_constant
=
constant
self
.
_constant
=
constant
...
...
lbmpy_tests/test_extrapolation_outflow.py
View file @
9e24f658
from
pystencils.stencil
import
inverse_direction
from
lbmpy.stencils
import
get_stencil
from
lbmpy.stencils
import
get_stencil
from
lbmpy.advanced_streaming.utility
import
AccessPdfValues
,
get_timesteps
from
lbmpy.advanced_streaming.utility
import
AccessPdfValues
,
get_timesteps
import
pytest
import
pytest
import
numpy
as
np
import
numpy
as
np
import
sympy
as
sp
from
pystencils.datahandling
import
create_data_handling
from
pystencils.datahandling
import
create_data_handling
from
lbmpy.boundaries
import
LatticeBoltzmannBoundaryHandling
,
SimpleExtrapolationOutflow
,
ExtrapolationOutflow
from
lbmpy.boundaries
import
LatticeBoltzmannBoundaryHandling
,
SimpleExtrapolationOutflow
,
ExtrapolationOutflow
...
@@ -10,6 +11,8 @@ from lbmpy.creationfunctions import create_lb_method
...
@@ -10,6 +11,8 @@ from lbmpy.creationfunctions import create_lb_method
from
lbmpy.advanced_streaming.utility
import
streaming_patterns
from
lbmpy.advanced_streaming.utility
import
streaming_patterns
from
pystencils.slicing
import
get_ghost_region_slice
from
pystencils.slicing
import
get_ghost_region_slice
from
itertools
import
product
@
pytest
.
mark
.
parametrize
(
'stencil'
,
[
'D2Q9'
,
'D3Q27'
])
@
pytest
.
mark
.
parametrize
(
'stencil'
,
[
'D2Q9'
,
'D3Q27'
])
@
pytest
.
mark
.
parametrize
(
'streaming_pattern'
,
streaming_patterns
)
@
pytest
.
mark
.
parametrize
(
'streaming_pattern'
,
streaming_patterns
)
...
@@ -19,7 +22,7 @@ def test_pdf_simple_extrapolation(stencil, streaming_pattern):
...
@@ -19,7 +22,7 @@ def test_pdf_simple_extrapolation(stencil, streaming_pattern):
values_per_cell
=
len
(
stencil
)
values_per_cell
=
len
(
stencil
)
# Field contains exactly one fluid cell
# Field contains exactly one fluid cell
domain_size
=
(
1
,)
*
dim
domain_size
=
(
3
,)
*
dim
for
timestep
in
get_timesteps
(
streaming_pattern
):
for
timestep
in
get_timesteps
(
streaming_pattern
):
dh
=
create_data_handling
(
domain_size
,
default_target
=
'cpu'
)
dh
=
create_data_handling
(
domain_size
,
default_target
=
'cpu'
)
lb_method
=
create_lb_method
(
stencil
=
stencil
)
lb_method
=
create_lb_method
(
stencil
=
stencil
)
...
@@ -36,30 +39,23 @@ def test_pdf_simple_extrapolation(stencil, streaming_pattern):
...
@@ -36,30 +39,23 @@ def test_pdf_simple_extrapolation(stencil, streaming_pattern):
pdf_arr
=
dh
.
cpu_arrays
[
pdf_field
.
name
]
pdf_arr
=
dh
.
cpu_arrays
[
pdf_field
.
name
]
# Set up the domain with artificial PDF values
# Set up the domain with artificial PDF values
center
=
(
1
,)
*
dim
#
center = (1,) * dim
out_access
=
AccessPdfValues
(
stencil
,
streaming_pattern
,
timestep
,
'out'
)
out_access
=
AccessPdfValues
(
stencil
,
streaming_pattern
,
timestep
,
'out'
)
for
q
in
range
(
values_per_cell
):
for
cell
in
product
(
*
(
range
(
1
,
4
)
for
_
in
range
(
dim
))):
out_access
.
write_pdf
(
pdf_arr
,
center
,
q
,
q
)
for
q
in
range
(
values_per_cell
):
out_access
.
write_pdf
(
pdf_arr
,
cell
,
q
,
q
)
# Do boundary handling
# Do boundary handling
bh
(
prev_timestep
=
timestep
)
bh
(
prev_timestep
=
timestep
)
center
=
np
.
array
(
center
)
# Check PDF values
# Check PDF values
in_access
=
AccessPdfValues
(
stencil
,
streaming_pattern
,
timestep
.
next
(),
'in'
)
in_access
=
AccessPdfValues
(
stencil
,
streaming_pattern
,
timestep
.
next
(),
'in'
)
# Inbound in center cell
# Inbound in center cell
for
q
,
streaming_dir
in
enumerate
(
stencil
):
for
cell
in
product
(
*
(
range
(
1
,
4
)
for
_
in
range
(
dim
))):
f
=
in_access
.
read_pdf
(
pdf_arr
,
center
,
q
)
for
q
in
range
(
values_per_cell
):
assert
f
==
q
f
=
in_access
.
read_pdf
(
pdf_arr
,
cell
,
q
)
assert
f
==
q
# Outbound in neighbors
for
normal_dir
in
stencil
[
1
:]:
for
q
,
streaming_dir
in
enumerate
(
stencil
):
neighbor
=
center
+
np
.
array
(
normal_dir
)
if
all
(
n
==
0
or
n
==
-
s
for
s
,
n
in
zip
(
streaming_dir
,
normal_dir
)):
f
=
out_access
.
read_pdf
(
pdf_arr
,
neighbor
,
q
)
assert
f
==
q
def
test_extrapolation_outflow_initialization_by_copy
():
def
test_extrapolation_outflow_initialization_by_copy
():
...
@@ -94,12 +90,12 @@ def test_extrapolation_outflow_initialization_by_copy():
...
@@ -94,12 +90,12 @@ def test_extrapolation_outflow_initialization_by_copy():
blocks
=
list
(
dh
.
iterate
())
blocks
=
list
(
dh
.
iterate
())
index_list
=
blocks
[
0
][
bh
.
_index_array_name
].
boundary_object_to_index_list
[
outflow
]
index_list
=
blocks
[
0
][
bh
.
_index_array_name
].
boundary_object_to_index_list
[
outflow
]
assert
len
(
index_list
)
==
5
assert
len
(
index_list
)
==
13
for
entry
in
index_list
:
for
entry
in
index_list
:
for
j
,
stencil_dir
in
enumerate
(
stencil
):
direction
=
stencil
[
entry
[
"dir"
]]
if
all
(
n
==
0
or
n
==
-
s
for
s
,
n
in
zip
(
stencil_dir
,
normal_dir
))
:
inv_dir
=
stencil
.
index
(
inverse_direction
(
direction
))
assert
entry
[
f
'pdf
_
{
j
}
'
]
==
j
assert
entry
[
f
'pdf'
]
==
inv_dir
assert
entry
[
f
'pdf_nd
_
{
j
}
'
]
==
j
assert
entry
[
f
'pdf_nd'
]
==
inv_dir
def
test_extrapolation_outflow_initialization_by_callback
():
def
test_extrapolation_outflow_initialization_by_callback
():
...
@@ -120,7 +116,7 @@ def test_extrapolation_outflow_initialization_by_callback():
...
@@ -120,7 +116,7 @@ def test_extrapolation_outflow_initialization_by_callback():
normal_dir
=
(
1
,
0
)
normal_dir
=
(
1
,
0
)
density_callback
=
lambda
x
,
y
:
1
density_callback
=
lambda
x
,
y
:
1
velocity_callback
=
lambda
x
,
y
:
(
0
,
0
)
velocity_callback
=
lambda
x
,
y
:
(
0
,
0
)
outflow
=
ExtrapolationOutflow
(
normal_dir
,
lb_method
,
outflow
=
ExtrapolationOutflow
(
normal_dir
,
lb_method
,
streaming_pattern
=
streaming_pattern
,
streaming_pattern
=
streaming_pattern
,
zeroth_timestep
=
zeroth_timestep
,
zeroth_timestep
=
zeroth_timestep
,
initial_density
=
density_callback
,
initial_density
=
density_callback
,
...
@@ -133,8 +129,8 @@ def test_extrapolation_outflow_initialization_by_callback():
...
@@ -133,8 +129,8 @@ def test_extrapolation_outflow_initialization_by_callback():
blocks
=
list
(
dh
.
iterate
())
blocks
=
list
(
dh
.
iterate
())
index_list
=
blocks
[
0
][
bh
.
_index_array_name
].
boundary_object_to_index_list
[
outflow
]
index_list
=
blocks
[
0
][
bh
.
_index_array_name
].
boundary_object_to_index_list
[
outflow
]
assert
len
(
index_list
)
==
5
assert
len
(
index_list
)
==
13
for
entry
in
index_list
:
for
entry
in
index_list
:
for
j
,
stencil_dir
in
enumerate
(
stencil
):
direction
=
stencil
[
entry
[
"dir"
]]
if
all
(
n
==
0
or
n
==
-
s
for
s
,
n
in
zip
(
stencil_dir
,
normal_dir
))
:
inv_dir
=
stencil
.
index
(
inverse_direction
(
direction
))
assert
entry
[
f
'pdf_nd
_
{
j
}
'
]
==
weights
[
j
]
assert
entry
[
f
'pdf_nd'
]
==
weights
[
inv_dir
]
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