Commit 50816cbe authored by Markus Holzer's avatar Markus Holzer
Browse files

Cleaned update kernels

parent 932cb492
Pipeline #32593 passed with stage
in 15 minutes and 11 seconds
...@@ -12,14 +12,13 @@ from pystencils.sympyextensions import fast_subs ...@@ -12,14 +12,13 @@ from pystencils.sympyextensions import fast_subs
# -------------------------------------------- LBM Kernel Creation ----------------------------------------------------- # -------------------------------------------- LBM Kernel Creation -----------------------------------------------------
def create_lbm_kernel(collision_rule, input_field, output_field, accessor): def create_lbm_kernel(collision_rule, src_field, dst_field=None, accessor=StreamPullTwoFieldsAccessor()):
"""Replaces the pre- and post collision symbols in the collision rule by field accesses. """Replaces the pre- and post collision symbols in the collision rule by field accesses.
Args: Args:
collision_rule: instance of LbmCollisionRule, defining the collision step collision_rule: instance of LbmCollisionRule, defining the collision step
input_field: field used for reading pdf values src_field: field used for reading pdf values
output_field: field used for writing pdf values dst_field: field used for writing pdf values if accessor.is_inplace this parameter is ignored
if accessor.is_inplace this parameter is ignored
accessor: instance of PdfFieldAccessor, defining where to read and write values accessor: instance of PdfFieldAccessor, defining where to read and write values
to create e.g. a fused stream-collide kernel to create e.g. a fused stream-collide kernel
...@@ -27,15 +26,18 @@ def create_lbm_kernel(collision_rule, input_field, output_field, accessor): ...@@ -27,15 +26,18 @@ def create_lbm_kernel(collision_rule, input_field, output_field, accessor):
LbmCollisionRule where pre- and post collision symbols have been replaced LbmCollisionRule where pre- and post collision symbols have been replaced
""" """
if accessor.is_inplace: if accessor.is_inplace:
output_field = input_field dst_field = src_field
if not accessor.is_inplace and dst_field is None:
raise ValueError("For two field accessors a destination field has to be provided")
method = collision_rule.method method = collision_rule.method
pre_collision_symbols = method.pre_collision_pdf_symbols pre_collision_symbols = method.pre_collision_pdf_symbols
post_collision_symbols = method.post_collision_pdf_symbols post_collision_symbols = method.post_collision_pdf_symbols
substitutions = {} substitutions = {}
input_accesses = accessor.read(input_field, method.stencil) input_accesses = accessor.read(src_field, method.stencil)
output_accesses = accessor.write(output_field, method.stencil) output_accesses = accessor.write(dst_field, method.stencil)
for (idx, offset), input_access, output_access in zip(enumerate(method.stencil), input_accesses, output_accesses): for (idx, offset), input_access, output_access in zip(enumerate(method.stencil), input_accesses, output_accesses):
substitutions[pre_collision_symbols[idx]] = input_access substitutions[pre_collision_symbols[idx]] = input_access
...@@ -55,7 +57,7 @@ def create_lbm_kernel(collision_rule, input_field, output_field, accessor): ...@@ -55,7 +57,7 @@ def create_lbm_kernel(collision_rule, input_field, output_field, accessor):
return result return result
def create_stream_only_kernel(stencil, src_field, dst_field, accessor=StreamPullTwoFieldsAccessor()): def create_stream_only_kernel(stencil, src_field, dst_field=None, accessor=StreamPullTwoFieldsAccessor()):
"""Creates a stream kernel, without collision. """Creates a stream kernel, without collision.
Args: Args:
...@@ -67,7 +69,13 @@ def create_stream_only_kernel(stencil, src_field, dst_field, accessor=StreamPull ...@@ -67,7 +69,13 @@ def create_stream_only_kernel(stencil, src_field, dst_field, accessor=StreamPull
Returns: Returns:
AssignmentCollection of the stream only update rule AssignmentCollection of the stream only update rule
""" """
temporary_symbols = sp.symbols(f'tmp_:{len(stencil)}') if accessor.is_inplace:
dst_field = src_field
if not accessor.is_inplace and dst_field is None:
raise ValueError("For two field accessors a destination field has to be provided")
temporary_symbols = sp.symbols(f'streamed_:{len(stencil)}')
subexpressions = [Assignment(tmp, acc) for tmp, acc in zip(temporary_symbols, accessor.read(src_field, stencil))] subexpressions = [Assignment(tmp, acc) for tmp, acc in zip(temporary_symbols, accessor.read(src_field, stencil))]
main_assignments = [Assignment(acc, tmp) for acc, tmp in zip(accessor.write(dst_field, stencil), temporary_symbols)] main_assignments = [Assignment(acc, tmp) for acc, tmp in zip(accessor.write(dst_field, stencil), temporary_symbols)]
return AssignmentCollection(main_assignments, subexpressions=subexpressions) return AssignmentCollection(main_assignments, subexpressions=subexpressions)
...@@ -103,13 +111,33 @@ def create_stream_pull_only_kernel(stencil, numpy_arr=None, src_field_name="src" ...@@ -103,13 +111,33 @@ def create_stream_pull_only_kernel(stencil, numpy_arr=None, src_field_name="src"
return create_stream_only_kernel(stencil, src, dst, accessor=StreamPullTwoFieldsAccessor()) return create_stream_only_kernel(stencil, src, dst, accessor=StreamPullTwoFieldsAccessor())
def create_stream_pull_with_output_kernel(lb_method, src_field, dst_field, output): def create_stream_pull_with_output_kernel(lb_method, src_field, dst_field=None, output=None,
accessor=StreamPullTwoFieldsAccessor()):
"""Creates a stream kernel, without collision but macroscopic quantaties like density or velocity can be calculated.
Args:
lb_method: lattice Boltzmann method see 'creationfunctions.create_lb_method'
src_field: Field the pre-streaming values are read from
dst_field: field used for writing pdf values if accessor.is_inplace this parameter is ignored
output: Dictonary which containes macroscopic quantities as keys which should be calculated and fields as
values which should be used to write the data e.g.: {'density': density_field}
accessor: Field accessor which is used to create the update rule. See 'fieldaccess.PdfFieldAccessor'
Returns:
AssignmentCollection of the stream only update rule
"""
if accessor.is_inplace:
dst_field = src_field
if not accessor.is_inplace and dst_field is None:
raise ValueError("For two field accessors a destination field has to be provided")
stencil = lb_method.stencil stencil = lb_method.stencil
cqc = lb_method.conserved_quantity_computation cqc = lb_method.conserved_quantity_computation
streamed = sp.symbols(f"streamed_:{len(stencil)}") streamed = sp.symbols(f"streamed_:{len(stencil)}")
accessor = StreamPullTwoFieldsAccessor()
stream_assignments = [Assignment(a, b) for a, b in zip(streamed, accessor.read(src_field, stencil))] stream_assignments = [Assignment(a, b) for a, b in zip(streamed, accessor.read(src_field, stencil))]
output_eq_collection = cqc.output_equations_from_pdfs(streamed, output) output_eq_collection = cqc.output_equations_from_pdfs(streamed, output) if output\
else AssignmentCollection(main_assignments=[])
write_eqs = [Assignment(a, b) for a, b in zip(accessor.write(dst_field, stencil), streamed)] write_eqs = [Assignment(a, b) for a, b in zip(accessor.write(dst_field, stencil), streamed)]
subexpressions = stream_assignments + output_eq_collection.subexpressions subexpressions = stream_assignments + output_eq_collection.subexpressions
......
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