diff --git a/creationfunctions.py b/creationfunctions.py index 45f1c535197474a74598e984ab1a45429527e335..913497b44060238fcf5442628cf58a3b052ddfc1 100644 --- a/creationfunctions.py +++ b/creationfunctions.py @@ -50,6 +50,8 @@ General: - ``output={}``: a dictionary mapping macroscopic quantites e.g. the strings 'density' and 'velocity' to pystencils fields. In each timestep the corresponding quantities are written to the given fields. - ``velocity_input``: symbolic field where the velocities are read from (for advection diffusion LBM) +- ``density_input``: symbolic field or field access where to read density from. When passing this parameter, + ``velocity_input`` has to be passed as well - ``kernel_type``: supported values: 'stream_pull_collide' (default), 'collide_only' @@ -174,6 +176,7 @@ from lbmpy.methods.entropic import add_iterative_entropy_condition, add_entropy_ from lbmpy.methods.entropic_eq_srt import create_srt_entropic from lbmpy.relaxationrates import relaxation_rate_from_magic_number from lbmpy.stencils import get_stencil +from pystencils.simp import add_subexpressions_for_field_reads from pystencils.stencils import stencils_have_same_entries import lbmpy.forcemodels as forcemodels from lbmpy.simplificationfactory import create_simplification_strategy @@ -252,7 +255,8 @@ def create_lb_update_rule(collision_rule=None, optimization={}, **kwargs): accessor = PeriodicTwoFieldsAccessor(opt_params['builtin_periodicity'], ghost_layers=1) return create_lbm_kernel(collision_rule, src_field, dst_field, accessor) elif params['kernel_type'] == 'collide_only': - return create_lbm_kernel(collision_rule, src_field, src_field, CollideOnlyInplaceAccessor) + result = create_lbm_kernel(collision_rule, src_field, src_field, CollideOnlyInplaceAccessor) + return add_subexpressions_for_field_reads(result, subexpressions=False, main_assignments=True) elif params['kernel_type'] == 'stream_pull_only': return create_stream_pull_with_output_kernel(lb_method, src_field, dst_field, params['output']) else: @@ -272,14 +276,22 @@ def create_lb_collision_rule(lb_method=None, optimization={}, **kwargs): split_inner_loop=split_inner_loop) cqc = lb_method.conserved_quantity_computation - if params['velocity_input'] is not None: - eqs = [Assignment(cqc.zeroth_order_moment_symbol, sum(lb_method.pre_collision_pdf_symbols))] - velocity_input = params['velocity_input'] - if isinstance(velocity_input, Field): - velocity_input = velocity_input.center_vector - eqs += [Assignment(u_sym, velocity_input[i]) for i, u_sym in enumerate(cqc.first_order_moment_symbols)] + rho_in = params['density_input'] + u_in = params['velocity_input'] + + if u_in is not None and isinstance(u_in, Field): + u_in = u_in.center_vector + if rho_in is not None and isinstance(rho_in, Field): + rho_in = rho_in.center + + if u_in is not None: + density_rhs = sum(lb_method.pre_collision_pdf_symbols) if rho_in is None else rho_in + eqs = [Assignment(cqc.zeroth_order_moment_symbol, density_rhs)] + eqs += [Assignment(u_sym, u_in[i]) for i, u_sym in enumerate(cqc.first_order_moment_symbols)] eqs = AssignmentCollection(eqs, []) collision_rule = lb_method.get_collision_rule(conserved_quantity_equations=eqs) + elif u_in is None and rho_in is not None: + raise ValueError("When setting 'density_input' parameter, 'velocity_input' has to be specified as well.") else: collision_rule = lb_method.get_collision_rule() @@ -472,6 +484,7 @@ def update_with_default_parameters(params, opt_params=None, fail_on_unknown_para 'output': {}, 'velocity_input': None, + 'density_input': None, 'kernel_type': 'stream_pull_collide',