Commit a6c4c41d authored by Frederik Hennig's avatar Frederik Hennig
Browse files

Introduced utility file and refactored tests

parent 1a13269e
Pipeline #26953 failed with stage
in 16 minutes and 19 seconds
from .boundaryindexing import AdvancedStreamingBoundaryIndexing
from .boundaryconditions import FlexibleBoundary, FlexibleNoSlip
from .boundaryhandling import create_advanced_streaming_boundary_kernel
from .boundaryhandling import FlexibleLBMBoundaryHandling, \
create_advanced_streaming_boundary_kernel
__all__ = ['AdvancedStreamingBoundaryIndexing', 'FlexibleBoundary',
'FlexibleNoSlip', 'create_advanced_streaming_boundary_kernel']
'FlexibleNoSlip', 'create_advanced_streaming_boundary_kernel',
'FlexibleLBMBoundaryHandling']
......@@ -12,6 +12,8 @@ from lbmpy.fieldaccess import StreamPullTwoFieldsAccessor, \
EsoTwistEvenTimeStepAccessor, \
EsoTwistOddTimeStepAccessor
from lbmpy.advanced_streaming.utility import get_accessor, inverse_dir_index
from itertools import product
......@@ -50,26 +52,8 @@ class AdvancedStreamingBoundaryIndexing:
odd_to_even = (between_timesteps == 'odd_to_even')
even_accessors = {
'pull': StreamPullTwoFieldsAccessor,
'push': StreamPushTwoFieldsAccessor,
'aa': AAEvenTimeStepAccessor,
'esotwist': EsoTwistEvenTimeStepAccessor
}
odd_accessors = {
'pull': StreamPullTwoFieldsAccessor,
'push': StreamPushTwoFieldsAccessor,
'aa': AAOddTimeStepAccessor,
'esotwist': EsoTwistOddTimeStepAccessor
}
try:
even_accessor = even_accessors[kernel_type]
odd_accessor = odd_accessors[kernel_type]
except KeyError:
raise ValueError(
"Invalid value of parameter 'kernel_type'.", kernel_type)
even_accessor = get_accessor(kernel_type, 'even')
odd_accessor = get_accessor(kernel_type, 'odd')
if between_timesteps == 'both':
assert even_accessor == odd_accessor
......@@ -149,7 +133,7 @@ class AdvancedStreamingBoundaryIndexing:
if isinstance(idx, sp.Indexed) and idx.base == inv_dir:
idx = idx.indices[0]
if isinstance(sp.sympify(idx), sp.Integer):
idx = self._inverse_integer_dir_index(idx)
idx = inverse_dir_index(self._stencil, idx)
inv = True
if isinstance(sp.sympify(idx), sp.Integer):
......@@ -164,14 +148,11 @@ class AdvancedStreamingBoundaryIndexing:
# Internals
# =================
def _inverse_integer_dir_index(self, idx):
return self._stencil.index(tuple(-d for d in self._stencil[idx]))
def _get_translated_indices_and_offsets(self, f_dir, inv):
accesses = self._accesses[f_dir]
if inv:
inverse_indices = [self._inverse_integer_dir_index(i)
inverse_indices = [inverse_dir_index(self._stencil, i)
for i in range(len(self._stencil))]
accesses = [accesses[idx] for idx in inverse_indices]
......
from lbmpy.fieldaccess import StreamPullTwoFieldsAccessor, \
StreamPushTwoFieldsAccessor, \
AAEvenTimeStepAccessor, \
AAOddTimeStepAccessor, \
EsoTwistEvenTimeStepAccessor, \
EsoTwistOddTimeStepAccessor
supported_kernels = ['push', 'pull', 'aa', 'esotwist']
timesteps = ['even', 'odd', 'both']
even_accessors = {
'pull': StreamPullTwoFieldsAccessor,
'push': StreamPushTwoFieldsAccessor,
'aa': AAEvenTimeStepAccessor,
'esotwist': EsoTwistEvenTimeStepAccessor
}
odd_accessors = {
'pull': StreamPullTwoFieldsAccessor,
'push': StreamPushTwoFieldsAccessor,
'aa': AAOddTimeStepAccessor,
'esotwist': EsoTwistOddTimeStepAccessor
}
def get_accessor(kernel_type, timestep):
if kernel_type not in supported_kernels:
raise ValueError(
"Invalid value of parameter 'kernel_type'.", kernel_type)
if timestep not in timesteps:
raise ValueError("Invalid time step:", timestep)
if timestep == 'even':
return even_accessors[kernel_type]
else:
return odd_accessors[kernel_type]
def inverse_dir_index(stencil, dir):
return stencil.index(tuple(-d for d in stencil[dir]))
"""
Allows to access values from a PDF array correctly depending on
the streaming pattern.
"""
class AccessPdfValues:
def __init__(self, pdf_field, stencil, kernel_type='pull', timestep='both', accessor=None):
if accessor is None:
accessor = get_accessor(kernel_type, timestep)
self.read_accs = accessor.read(pdf_field, stencil)
self.write_accs = accessor.write(pdf_field, stencil)
def write_pdf(self, pdf_arr, pos, d, value):
offsets = self.write_accs[d].offsets
pos = tuple( p + o for p, o in zip(pos, offsets) )
i = self.write_accs[d].index[0]
pdf_arr[pos + (i,)] = value
def read_pdf(self, pdf_arr, pos, d):
offsets = self.read_accs[d].offsets
pos = tuple( p + o for p, o in zip(pos, offsets) )
i = self.read_accs[d].index[0]
return pdf_arr[pos + (i,)]
......@@ -5,6 +5,7 @@ from lbmpy.simplificationfactory import create_simplification_strategy
from pystencils.field import Field, get_layout_of_array
from lbmpy.fieldaccess import StreamPullTwoFieldsAccessor
from lbmpy.advanced_streaming.utility import get_accessor
def pdf_initialization_assignments(lb_method, density, velocity, pdfs):
......@@ -34,15 +35,15 @@ macroscopic_values_setter = pdf_initialization_assignments
def flexible_macroscopic_values_setter(lb_method, density, velocity,
pdf_field,
previous_step_accessor=StreamPullTwoFieldsAccessor):
pdf_field, kernel_type='pull', previous_timestep='both'):
previous_step_accessor = get_accessor(kernel_type, previous_timestep)
write_accesses = previous_step_accessor.write(pdf_field, lb_method.stencil)
return pdf_initialization_assignments(lb_method, density, velocity, write_accesses)
def flexible_macroscopic_values_getter(lb_method, density, velocity,
pdf_field,
previous_step_accessor=StreamPullTwoFieldsAccessor):
pdf_field, kernel_type='pull', previous_timestep='both'):
previous_step_accessor = get_accessor(kernel_type, previous_timestep)
write_accesses = previous_step_accessor.write(pdf_field, lb_method.stencil)
return macroscopic_values_getter(lb_method, density, velocity, write_accesses)
......@@ -50,7 +51,7 @@ def flexible_macroscopic_values_getter(lb_method, density, velocity,
def compile_macroscopic_values_getter(lb_method, output_quantities, pdf_arr=None,
ghost_layers=1, iteration_slice=None,
field_layout='numpy', target='cpu',
previous_step_accessor=StreamPullTwoFieldsAccessor):
kernel_type='pull', previous_timestep='both'):
"""
Create kernel to compute macroscopic value(s) from a pdf field (e.g. density or velocity)
......@@ -112,6 +113,7 @@ def compile_macroscopic_values_getter(lb_method, output_quantities, pdf_arr=None
# pdf_symbols = [pdf_field(i) for i in range(len(stencil))]
# Extension for any kind of streaming rule
previous_step_accessor = get_accessor(kernel_type, previous_timestep)
pdf_symbols = previous_step_accessor.write(pdf_field, stencil)
eqs = cqc.output_equations_from_pdfs(pdf_symbols, output_mapping).all_assignments
......@@ -142,7 +144,7 @@ def compile_macroscopic_values_getter(lb_method, output_quantities, pdf_arr=None
def compile_macroscopic_values_setter(lb_method, quantities_to_set, pdf_arr=None,
ghost_layers=1, iteration_slice=None,
field_layout='numpy', target='cpu',
previous_step_accessor=StreamPullTwoFieldsAccessor):
kernel_type='pull', previous_timestep='both'):
"""
Creates a function that sets a pdf field to specified macroscopic quantities
The returned function can be called with the pdf field to set as single argument
......@@ -196,6 +198,7 @@ def compile_macroscopic_values_setter(lb_method, quantities_to_set, pdf_arr=None
eq = eq.new_without_subexpressions()
# Extension for any streaming rule
previous_step_accessor = get_accessor(kernel_type, previous_timestep)
write_accesses = previous_step_accessor.write(pdf_field, lb_method.stencil)
substitutions = {sym: write_accesses[i] for i, sym in enumerate(lb_method.post_collision_pdf_symbols)}
......
......@@ -9,6 +9,7 @@ from lbmpy.fieldaccess import StreamPullTwoFieldsAccessor, \
EsoTwistOddTimeStepAccessor
from lbmpy.advanced_streaming import FlexibleNoSlip, create_advanced_streaming_boundary_kernel
from lbmpy.advanced_streaming.utility import even_accessors, odd_accessors, supported_kernels, inverse_dir_index, AccessPdfValues
from lbmpy.creationfunctions import create_lb_method
from lbmpy.stencils import get_stencil
......@@ -20,66 +21,12 @@ from pystencils.field import Field, FieldType
from itertools import product
# ===========================
# INFRASTRUCTURE
# ===========================
stencils = [ 'D2Q9', 'D3Q19', 'D3Q27']
timesteps = ['odd_to_even', 'even_to_odd']
kernel_types = ['push', 'pull', 'aa', 'esotwist']
even_accessors = {
'pull': StreamPullTwoFieldsAccessor,
'push': StreamPushTwoFieldsAccessor,
'aa': AAEvenTimeStepAccessor,
'esotwist': EsoTwistEvenTimeStepAccessor
}
odd_accessors = {
'pull': StreamPullTwoFieldsAccessor,
'push': StreamPushTwoFieldsAccessor,
'aa': AAOddTimeStepAccessor,
'esotwist': EsoTwistOddTimeStepAccessor
}
def inverse_dir_index(stencil, dir):
return stencil.index(tuple(-d for d in stencil[dir]))
"""
Allows to access values from a PDF array correctly depending on
the streaming pattern.
"""
class AccessPdfValues:
def __init__(self, pdf_field, stencil, accessor):
self.read_accs = accessor.read(pdf_field, stencil)
self.write_accs = accessor.write(pdf_field, stencil)
def write_pdf(self, pdf_arr, pos, d, value):
offsets = self.write_accs[d].offsets
pos = tuple( p + o for p, o in zip(pos, offsets) )
i = self.write_accs[d].index[0]
pdf_arr[pos + (i,)] = value
def read_pdf(self, pdf_arr, pos, d):
offsets = self.read_accs[d].offsets
pos = tuple( p + o for p, o in zip(pos, offsets) )
i = self.read_accs[d].index[0]
return pdf_arr[pos + (i,)]
# ===========================
# TESTS
# ===========================
import pytest
arguments = product(stencils, timesteps, kernel_types)
@pytest.mark.parametrize("stencil, timestep_type, kernel_type", arguments)
def test_flexible_noslip_single_cell(stencil, timestep_type, kernel_type):
@pytest.mark.parametrize("stencil", [ 'D2Q9', 'D3Q19', 'D3Q27'])
@pytest.mark.parametrize("kernel_type", supported_kernels)
@pytest.mark.parametrize("timestep_type", ['odd_to_even', 'even_to_odd'])
def test_flexible_noslip_single_cell(stencil, kernel_type, timestep_type):
"""
Flexible NoSlip Test
"""
......@@ -95,8 +42,8 @@ def test_flexible_noslip_single_cell(stencil, timestep_type, kernel_type):
prev_accessor = (odd_accessor if timestep_type == 'odd_to_even' else even_accessor)
next_accessor = (even_accessor if timestep_type == 'odd_to_even' else odd_accessor)
prev_pdf_access = AccessPdfValues(pdf_field, stencil, prev_accessor)
next_pdf_access = AccessPdfValues(pdf_field, stencil, next_accessor)
prev_pdf_access = AccessPdfValues(pdf_field, stencil, accessor=prev_accessor)
next_pdf_access = AccessPdfValues(pdf_field, stencil, accessor=next_accessor)
pdfs = np.zeros((3,) * dim + (q,))
pos = (1,) * dim
......
......@@ -3,30 +3,16 @@ import numpy as np
from lbmpy.creationfunctions import create_lb_method
from lbmpy.macroscopic_value_kernels import (
compile_macroscopic_values_getter, compile_macroscopic_values_setter)
from lbmpy.fieldaccess import StreamPullTwoFieldsAccessor, \
StreamPushTwoFieldsAccessor, \
AAEvenTimeStepAccessor, \
AAOddTimeStepAccessor, \
EsoTwistEvenTimeStepAccessor, \
EsoTwistOddTimeStepAccessor
from lbmpy.advanced_streaming.utility import supported_kernels
import pytest
from itertools import product
accessors = [StreamPullTwoFieldsAccessor,
StreamPushTwoFieldsAccessor,
AAEvenTimeStepAccessor,
AAOddTimeStepAccessor,
EsoTwistEvenTimeStepAccessor,
EsoTwistOddTimeStepAccessor]
stencils = ['D2Q9', 'D3Q19']
force_models = ['guo', 'luo', 'none']
compressibilities = [True, False]
@pytest.mark.parametrize('stencil,force_model,compressible,accessor', product(stencils, force_models, compressibilities, accessors))
def test_set_get_density_velocity_with_fields(stencil, force_model, compressible, accessor):
@pytest.mark.parametrize('stencil', ['D2Q9', 'D3Q19'])
@pytest.mark.parametrize('force_model', ['guo', 'luo', None])
@pytest.mark.parametrize('compressible', ['compressible', False])
@pytest.mark.parametrize('kernel_type', supported_kernels)
@pytest.mark.parametrize('prev_timestep', ['even', 'odd'])
def test_set_get_density_velocity_with_fields(stencil, force_model, compressible, kernel_type, prev_timestep):
force = (0.1, 0.12, -0.17)
method = create_lb_method(stencil=stencil, force_model=force_model, method='trt',
compressible=compressible, force=force)
......@@ -45,11 +31,11 @@ def test_set_get_density_velocity_with_fields(stencil, force_model, compressible
quantities_to_set = {'density': density_input_field, 'velocity': velocity_input_field}
setter = compile_macroscopic_values_setter(method, pdf_arr=pdf_arr, quantities_to_set=quantities_to_set,
ghost_layers=ghost_layers, previous_step_accessor=accessor)
ghost_layers=ghost_layers, kernel_type=kernel_type, previous_timestep=prev_timestep)
setter(pdf_arr)
getter = compile_macroscopic_values_getter(method, ['density', 'velocity'], pdf_arr=pdf_arr,
ghost_layers=ghost_layers, previous_step_accessor=accessor)
ghost_layers=ghost_layers, kernel_type=kernel_type, previous_timestep=prev_timestep)
density_output_field = np.zeros_like(density_input_field)
velocity_output_field = np.zeros_like(velocity_input_field)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment