Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
lbmpy
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
itischler
lbmpy
Commits
1366f610
Commit
1366f610
authored
4 years ago
by
RudolfWeeber
Browse files
Options
Downloads
Patches
Plain Diff
Test Poiseuille channel against analytical solution for several stencils
parent
e3b2f20d
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
lbmpy_tests/test_poisuille_channel.py
+93
-90
93 additions, 90 deletions
lbmpy_tests/test_poisuille_channel.py
with
93 additions
and
90 deletions
lbmpy_tests/test_poisuille_channel.py
+
93
−
90
View file @
1366f610
"""
T
his test revealed a problem with OpenCL (https://i10git.cs.fau.de/pycodegen/lbmpy/issues/9#note_9521)
T
est Poiseuille flow against analytical solution
"""
import
numpy
as
np
import
pytest
import
sympy
as
sp
import
lbmpy
from
lbmpy.boundaries
import
NoSlip
from
lbmpy.boundaries.boundaryhandling
import
LatticeBoltzmannBoundaryHandling
from
lbmpy.creationfunctions
import
create_lb_update_rule
,
create_stream_pull_with_output_kernel
from
lbmpy.macroscopic_value_kernels
import
macroscopic_values_setter
from
lbmpy.session
import
*
from
pystencils.session
import
*
from
lbmpy.stencils
import
get_stencil
previous_vmids
=
{}
previous_endresults
=
{}
import
pystencils
as
ps
def
poiseuille_flow
(
z
,
H
,
ext_force_density
,
dyn_visc
):
"""
Analytical solution for plane Poiseuille flow.
Parameters
----------
z : :obj:`float`
Distance to the mid plane of the channel.
H : :obj:`float`
Distance between the boundaries.
ext_force_density : :obj:`float`
Force density on the fluid normal to the boundaries.
dyn_visc : :obj:`float`
Dynamic viscosity of the LB fluid.
"""
return
ext_force_density
*
1.
/
(
2
*
dyn_visc
)
*
(
H
**
2.0
/
4.0
-
z
**
2.0
)
rho_0
=
1.2
# density
eta
=
0.2
# kinematic viscosity
width
=
41
# of box
actual_width
=
width
-
2
# subtract boundary layer from box width
ext_force_density
=
0.2
/
actual_width
**
2
# scale by width to keep stable
@pytest.mark.parametrize
(
'
target
'
,
(
'
cpu
'
,
'
gpu
'
,
'
opencl
'
))
def
test_poiseuille_channel
(
target
):
# # Lattice Boltzmann
#
# ## Definitions
@pytest.mark.parametrize
(
'
stencil_name
'
,
(
"
D2Q9
"
,
"
D3Q19
"
,))
def
test_poiseuille_channel
(
target
,
stencil_name
):
# OpenCL and Cuda
if
target
==
'
opencl
'
:
import
pytest
pytest
.
importorskip
(
"
pyopencl
"
)
...
...
@@ -30,65 +55,72 @@ def test_poiseuille_channel(target):
import
pytest
pytest
.
importorskip
(
"
pycuda
"
)
# In[2]:
# LB parameters
lb_stencil
=
get_stencil
(
stencil_name
)
dim
=
len
(
lb_stencil
[
0
])
L
=
(
34
,
34
)
if
dim
==
2
:
L
=
[
4
,
width
]
elif
dim
==
3
:
L
=
[
4
,
width
,
4
]
else
:
raise
Exception
()
periodicity
=
[
True
,
False
]
+
[
True
]
*
(
dim
-
2
)
lb_stencil
=
get_stencil
(
"
D2Q9
"
)
eta
=
1
omega
=
lbmpy
.
relaxationrates
.
relaxation_rate_from_lattice_viscosity
(
eta
)
f_pre
=
0.00001
# ## Data structures
# In[3]:
dh
=
ps
.
create_data_handling
(
L
,
periodicity
=
(
True
,
False
),
default_target
=
target
)
opts
=
{
'
cpu_openmp
'
:
True
,
'
cpu_vectorize_info
'
:
None
,
'
target
'
:
dh
.
default_target
}
dh
=
ps
.
create_data_handling
(
L
,
periodicity
=
periodicity
,
default_target
=
target
)
src
=
dh
.
add_array
(
'
src
'
,
values_per_cell
=
len
(
lb_stencil
))
dst
=
dh
.
add_array_like
(
'
dst
'
,
'
src
'
)
ρ
=
dh
.
add_array
(
'
rho
'
,
latex_name
=
'
\\
rho
'
)
u
=
dh
.
add_array
(
'
u
'
,
values_per_cell
=
dh
.
dim
)
# In[4]:
# LB Setup
collision
=
create_lb_update_rule
(
stencil
=
lb_stencil
,
relaxation_rate
=
omega
,
method
=
"
trt
"
,
compressible
=
True
,
force_model
=
'
guo
'
,
force
=
sp
.
Matrix
([
f_pre
,
0
]
),
force_model
=
"
schiller
"
,
force
=
sp
.
Matrix
([
ext_force_density
]
+
[
0
]
*
(
dim
-
1
)
),
kernel_type
=
'
collide_only
'
,
optimization
=
{
'
symbolic_field
'
:
src
})
stream
=
create_stream_pull_with_output_kernel
(
collision
.
method
,
src
,
dst
,
{
'
velocity
'
:
u
})
lbbh
=
LatticeBoltzmannBoundaryHandling
(
collision
.
method
,
dh
,
src
.
name
,
target
=
dh
.
default_target
)
opts
=
{
'
cpu_openmp
'
:
False
,
'
cpu_vectorize_info
'
:
None
,
'
target
'
:
dh
.
default_target
}
stream_kernel
=
ps
.
create_kernel
(
stream
,
**
opts
).
compile
()
collision_kernel
=
ps
.
create_kernel
(
collision
,
**
opts
).
compile
()
# ## Set up the simulation
# Boundaries
lbbh
=
LatticeBoltzmannBoundaryHandling
(
collision
.
method
,
dh
,
src
.
name
,
target
=
dh
.
default_target
)
#
In[5]:
#
## Set up the simulation
init
=
macroscopic_values_setter
(
collision
.
method
,
velocity
=
(
0
,)
*
dh
.
dim
,
init
=
macroscopic_values_setter
(
collision
.
method
,
velocity
=
(
0
,)
*
dh
.
dim
,
pdfs
=
src
.
center_vector
,
density
=
ρ
.
center
)
init_kernel
=
ps
.
create_kernel
(
init
,
ghost_layers
=
0
).
compile
()
noslip
=
NoSlip
()
lbbh
.
set_boundary
(
noslip
,
make_slice
[:,
:
4
])
lbbh
.
set_boundary
(
noslip
,
make_slice
[:,
-
4
:])
wall_thickness
=
2
if
dim
==
2
:
lbbh
.
set_boundary
(
noslip
,
ps
.
make_slice
[:,
:
wall_thickness
])
lbbh
.
set_boundary
(
noslip
,
ps
.
make_slice
[:,
-
wall_thickness
:])
elif
dim
==
3
:
lbbh
.
set_boundary
(
noslip
,
ps
.
make_slice
[:,
:
wall_thickness
,
:])
lbbh
.
set_boundary
(
noslip
,
ps
.
make_slice
[:,
-
wall_thickness
:,
:])
else
:
raise
Exception
()
for
bh
in
lbbh
,
:
assert
len
(
bh
.
_boundary_object_to_boundary_info
)
==
1
,
"
Restart kernel to clear boundaries
"
def
init
():
dh
.
fill
(
ρ
.
name
,
1
)
dh
.
fill
(
ρ
.
name
,
rho_0
)
dh
.
fill
(
u
.
name
,
np
.
nan
,
ghost_layers
=
True
,
inner_ghost_layers
=
True
)
dh
.
fill
(
u
.
name
,
0
)
...
...
@@ -98,10 +130,11 @@ def test_poiseuille_channel(target):
sync_pdfs
=
dh
.
synchronization_function
([
src
.
name
])
# Time loop
def
time_loop
(
steps
):
dh
.
all_to_gpu
()
vmid
=
np
.
empty
((
2
,
steps
//
10
+
1
))
i
=
-
1
last_max_vel
=
-
1
for
i
in
range
(
steps
):
dh
.
run_kernel
(
collision_kernel
)
sync_pdfs
()
...
...
@@ -110,71 +143,41 @@ def test_poiseuille_channel(target):
dh
.
swap
(
src
.
name
,
dst
.
name
)
if
i
%
10
==
0
:
# Consider early termination
if
i
%
100
==
0
:
if
u
.
name
in
dh
.
gpu_arrays
:
dh
.
to_cpu
(
u
.
name
)
uu
=
dh
.
gather_array
(
u
.
name
)
uu
=
uu
[
L
[
0
]
//
2
-
1
:
L
[
0
]
//
2
+
1
,
L
[
1
]
//
2
-
1
:
L
[
1
]
//
2
+
1
,
0
].
mean
()
vmid
[:,
i
//
10
]
=
[
i
,
uu
]
if
1
/
np
.
sqrt
(
3
)
<
uu
:
break
if
dh
.
is_on_gpu
(
u
.
name
):
dh
.
to_cpu
(
u
.
name
)
return
vmid
[:,
:
i
//
10
+
1
]
# average periodic directions
if
dim
==
3
:
# dont' swap order
uu
=
np
.
average
(
uu
,
axis
=
2
)
uu
=
np
.
average
(
uu
,
axis
=
0
)
# In[7]:
# def plot():
# plt.subplot(2, 2, 1)
# plt.title("$u$")
# plt.xlabel("$x$")
# plt.ylabel("$y$")
# plt.vector_field_magnitude(uu)
# plt.colorbar()
# plt.subplot(2, 2, 2)
# plt.title("$u$")
# plt.xlabel("$x/2$")
# plt.ylabel("$y/2$")
# plt.vector_field(uu, step=2)
# actualwidth = np.sum(1-np.isnan(uu[0, :, 0]))
# uref = f_pre*actualwidth**2/(8*(eta))
# plt.subplot(2, 2, 3)
# plt.title("flow profile")
# plt.xlabel("$y$")
# plt.ylabel(r"$u_x$")
# plt.plot((uu[L[0]//2-1, :, 0]+uu[L[0]//2, :, 0])/2)
max_vel
=
np
.
nanmax
(
uu
)
if
np
.
abs
(
max_vel
/
last_max_vel
-
1
)
<
5E-6
:
break
last_max_vel
=
max_vel
# plt.subplot(2, 2, 4)
# plt.title("convergence")
# plt.xlabel("$t$")
# plt.plot()
# cut off wall regions
uu
=
uu
[
wall_thickness
:
-
wall_thickness
]
# ## Run the simulation
# correct for f/2 term
uu
-=
np
.
array
([
ext_force_density
/
2
/
rho_0
]
+
[
0
]
*
(
dim
-
1
))
# In[8]:
return
uu
init
()
vmid
=
time_loop
(
1000
)
# plot()
uu
=
dh
.
gather_array
(
u
.
name
)
# Simulation
profile
=
time_loop
(
5000
)
for
target
,
prev_endresult
in
previous_endresults
.
items
():
assert
np
.
allclose
(
uu
[
4
:
-
4
,
4
:
-
4
,
0
],
prev_endresult
[
4
:
-
4
,
4
:
-
4
,
0
],
atol
=
1e-5
),
f
'
uu does not agree with result from
{
target
}
'
# compare against analytical solution
# The profile is of shape (n,3). Force is in x-direction
y
=
np
.
arange
(
len
(
profile
[:,
0
]))
mid
=
(
y
[
-
1
]
-
y
[
0
])
/
2
# Mid point of channel
for
target
,
prev_vmid
in
previous_vmids
.
items
():
assert
np
.
allclose
(
vmid
,
prev_vmid
,
atol
=
1e-5
),
f
'
vmid does not agree with result from
{
target
}
'
expected
=
poiseuille_flow
((
y
-
mid
),
actual_width
,
ext_force_density
,
rho_0
*
eta
)
# uref = f_pre*actualwidth**2/(8*(eta))
# actualwidth = np.sum(1-np.isnan(uu[0, :, 0]))
# assert np.allclose(vmid[1, -1]/uref, 1, atol=1e-3)
# print(vmid[1, -1])
np
.
testing
.
assert_allclose
(
profile
[:,
0
],
expected
,
rtol
=
0.006
)
previous_vmids
[
target
]
=
vmid
previous_endresults
[
target
]
=
uu
# Test zero vel in other directions
np
.
testing
.
assert_allclose
(
profile
[:,
1
:],
np
.
zeros_like
(
profile
[:,
1
:]),
atol
=
1E-9
)
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
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!
Save comment
Cancel
Please
register
or
sign in
to comment