Commit 29a9ecff authored by Markus Holzer's avatar Markus Holzer
Browse files

Implemented zero center logic

parent eb191dc1
Pipeline #34566 failed with stages
in 14 minutes and 55 seconds
...@@ -412,6 +412,7 @@ def create_lb_method(lbm_config=None, **params): ...@@ -412,6 +412,7 @@ def create_lb_method(lbm_config=None, **params):
common_params = { common_params = {
'compressible': lbm_config.compressible, 'compressible': lbm_config.compressible,
'zero_centered_pdfs': lbm_config.zero_centered_pdfs,
'equilibrium_order': lbm_config.equilibrium_order, 'equilibrium_order': lbm_config.equilibrium_order,
'force_model': lbm_config.force_model, 'force_model': lbm_config.force_model,
'maxwellian_moments': lbm_config.maxwellian_moments, 'maxwellian_moments': lbm_config.maxwellian_moments,
...@@ -421,6 +422,7 @@ def create_lb_method(lbm_config=None, **params): ...@@ -421,6 +422,7 @@ def create_lb_method(lbm_config=None, **params):
} }
cumulant_params = { cumulant_params = {
'zero_centered_pdfs': lbm_config.zero_centered_pdfs,
'equilibrium_order': lbm_config.equilibrium_order, 'equilibrium_order': lbm_config.equilibrium_order,
'force_model': lbm_config.force_model, 'force_model': lbm_config.force_model,
'c_s_sq': lbm_config.c_s_sq, 'c_s_sq': lbm_config.c_s_sq,
...@@ -579,6 +581,8 @@ class LBMConfig: ...@@ -579,6 +581,8 @@ class LBMConfig:
relaxation_rates: List of relexation rates for the method. Can contain symbols, ints and floats relaxation_rates: List of relexation rates for the method. Can contain symbols, ints and floats
relaxation_rate: For TRT and KBC methods the remaining relaxation rate is determined via magic parameter relaxation_rate: For TRT and KBC methods the remaining relaxation rate is determined via magic parameter
compressible: If Helmholtz decomposition is used to better approximate the incompressible Navier Stokes eq compressible: If Helmholtz decomposition is used to better approximate the incompressible Navier Stokes eq
zero_centered_pdfs: If True the density is subtracted from the PDFs to center them around zero.
This is important for simulations in single precision
equilibrium_order: order of the highest term in the equilibrium formulation equilibrium_order: order of the highest term in the equilibrium formulation
c_s_sq: speed of sound. Usually 1 / 3 c_s_sq: speed of sound. Usually 1 / 3
weighted: For MRT methods. If True the moments are weigted orthogonal. Usually desired. weighted: For MRT methods. If True the moments are weigted orthogonal. Usually desired.
...@@ -618,6 +622,7 @@ class LBMConfig: ...@@ -618,6 +622,7 @@ class LBMConfig:
relaxation_rates: Any = None relaxation_rates: Any = None
relaxation_rate: Union[int, float, Type[sp.Symbol]] = None relaxation_rate: Union[int, float, Type[sp.Symbol]] = None
compressible: bool = False compressible: bool = False
zero_centered_pdfs: bool = True
equilibrium_order: int = 2 equilibrium_order: int = 2
c_s_sq: sympy.core.numbers.Rational = sp.Rational(1, 3) c_s_sq: sympy.core.numbers.Rational = sp.Rational(1, 3)
weighted: bool = True weighted: bool = True
......
...@@ -67,7 +67,9 @@ def compile_macroscopic_values_getter(lb_method, output_quantities, pdf_arr=None ...@@ -67,7 +67,9 @@ def compile_macroscopic_values_getter(lb_method, output_quantities, pdf_arr=None
iteration_slice: if not None, iteration is done only over this slice of the field iteration_slice: if not None, iteration is done only over this slice of the field
field_layout: layout for output field, also used for pdf field if pdf_arr is not given field_layout: layout for output field, also used for pdf field if pdf_arr is not given
target: `Target.CPU` or `Target.GPU` target: `Target.CPU` or `Target.GPU`
previous_step_accessor: The accessor used by the streaming pattern of the previous timestep streaming_pattern: define the streaming pattern for the getter kernel. Default is pull
previous_timestep: timestep which is used. Timestep.BOTH for two population methods.
Timestep.EVEN to use the even order timestep, Timestep.ODD to use the odd order timestep
Returns: Returns:
a function to compute macroscopic values: a function to compute macroscopic values:
...@@ -80,8 +82,8 @@ def compile_macroscopic_values_getter(lb_method, output_quantities, pdf_arr=None ...@@ -80,8 +82,8 @@ def compile_macroscopic_values_getter(lb_method, output_quantities, pdf_arr=None
cqc = lb_method.conserved_quantity_computation cqc = lb_method.conserved_quantity_computation
unknown_quantities = [oq for oq in output_quantities if oq not in cqc.conserved_quantities] unknown_quantities = [oq for oq in output_quantities if oq not in cqc.conserved_quantities]
if unknown_quantities: if unknown_quantities:
raise ValueError("No such conserved quantity: %s, conserved quantities are %s" % raise ValueError(f"No such conserved quantity: {str(unknown_quantities)}, "
(str(unknown_quantities), str(cqc.conserved_quantities.keys()))) f"conserved quantities are {str(cqc.conserved_quantities.keys())}")
if pdf_arr is None: if pdf_arr is None:
pdf_field = Field.create_generic('pdfs', lb_method.dim, index_dimensions=1, layout=field_layout) pdf_field = Field.create_generic('pdfs', lb_method.dim, index_dimensions=1, layout=field_layout)
...@@ -126,15 +128,15 @@ def compile_macroscopic_values_getter(lb_method, output_quantities, pdf_arr=None ...@@ -126,15 +128,15 @@ def compile_macroscopic_values_getter(lb_method, output_quantities, pdf_arr=None
kernel = gpu.make_python_function(gpu.create_cuda_kernel( kernel = gpu.make_python_function(gpu.create_cuda_kernel(
eqs, ghost_layers=ghost_layers, iteration_slice=iteration_slice)) eqs, ghost_layers=ghost_layers, iteration_slice=iteration_slice))
else: else:
raise ValueError("Unknown target '%s'. Possible targets are `Target.CPU` and `Target.GPU`" % (target,)) raise ValueError(f"Unknown target '{target}'. Possible targets are `Target.CPU` and `Target.GPU`")
def getter(pdfs, **kwargs): def getter(pdfs, **kwargs):
if pdf_arr is not None: if pdf_arr is not None:
assert pdfs.shape == pdf_arr.shape and pdfs.strides == pdf_arr.strides, \ assert pdfs.shape == pdf_arr.shape and pdfs.strides == pdf_arr.strides, \
"Pdf array not matching blueprint which was used to compile" + str(pdfs.shape) + str(pdf_arr.shape) "Pdf array not matching blueprint which was used to compile" + str(pdfs.shape) + str(pdf_arr.shape)
if not set(output_quantities).issubset(kwargs.keys()): if not set(output_quantities).issubset(kwargs.keys()):
raise ValueError("You have to specify the output field for each of the following quantities: %s" raise ValueError(f"You have to specify the output field for "
% (str(output_quantities),)) f"each of the following quantities: {str(output_quantities)}")
kernel(pdfs=pdfs, **kwargs) kernel(pdfs=pdfs, **kwargs)
return getter return getter
...@@ -158,7 +160,9 @@ def compile_macroscopic_values_setter(lb_method, quantities_to_set, pdf_arr=None ...@@ -158,7 +160,9 @@ def compile_macroscopic_values_setter(lb_method, quantities_to_set, pdf_arr=None
iteration_slice: if not None, iteration is done only over this slice of the field iteration_slice: if not None, iteration is done only over this slice of the field
field_layout: layout of the pdf field if pdf_arr was not given field_layout: layout of the pdf field if pdf_arr was not given
target: `Target.CPU` or `Target.GPU` target: `Target.CPU` or `Target.GPU`
previous_step_accessor: The accessor used by the streaming pattern of the previous timestep streaming_pattern: define the streaming pattern for the getter kernel. Default is pull
previous_timestep: timestep which is used. Timestep.BOTH for two population methods.
Timestep.EVEN to use the even order timestep, Timestep.ODD to use the odd order timestep
Returns: Returns:
function taking pdf array as single argument and which sets the field to the given values function taking pdf array as single argument and which sets the field to the given values
...@@ -211,12 +215,12 @@ def compile_macroscopic_values_setter(lb_method, quantities_to_set, pdf_arr=None ...@@ -211,12 +215,12 @@ def compile_macroscopic_values_setter(lb_method, quantities_to_set, pdf_arr=None
kernel = gpu.make_python_function(gpu.create_cuda_kernel(eq)) kernel = gpu.make_python_function(gpu.create_cuda_kernel(eq))
kernel = functools.partial(kernel, **fixed_kernel_parameters) kernel = functools.partial(kernel, **fixed_kernel_parameters)
else: else:
raise ValueError("Unknown target '%s'. Possible targets are `Target.CPU` and `Target.GPU`" % (target,)) raise ValueError(f"Unknown target '{target}'. Possible targets are `Target.CPU` and `Target.GPU`")
def setter(pdfs, **kwargs): def setter(pdfs, **kwargs):
if pdf_arr is not None: if pdf_arr is not None:
assert pdfs.shape == pdf_arr.shape and pdfs.strides == pdf_arr.strides, \ assert pdfs.shape == pdf_arr.shape and pdfs.strides == pdf_arr.strides, \
"Pdf array not matching blueprint which was used to compile" + str(pdfs.shape) + str(pdf_arr.shape) f"Pdf array not matching blueprint which was used to compile {str(pdfs.shape)} {str(pdfs.strides)}"
kernel(pdfs=pdfs, **kwargs) kernel(pdfs=pdfs, **kwargs)
return setter return setter
......
...@@ -177,7 +177,7 @@ class CenteredCumulantBasedLbMethod(AbstractLbMethod): ...@@ -177,7 +177,7 @@ class CenteredCumulantBasedLbMethod(AbstractLbMethod):
@property @property
def central_moment_transform_class(self): def central_moment_transform_class(self):
self._central_moment_transform_class return self._central_moment_transform_class
@property @property
def cumulants(self): def cumulants(self):
...@@ -189,7 +189,7 @@ class CenteredCumulantBasedLbMethod(AbstractLbMethod): ...@@ -189,7 +189,7 @@ class CenteredCumulantBasedLbMethod(AbstractLbMethod):
@property @property
def cumulant_transform_class(self): def cumulant_transform_class(self):
self._cumulant_transform_class return self._cumulant_transform_class
@property @property
def first_order_equilibrium_moment_symbols(self, ): def first_order_equilibrium_moment_symbols(self, ):
...@@ -211,6 +211,14 @@ class CenteredCumulantBasedLbMethod(AbstractLbMethod): ...@@ -211,6 +211,14 @@ class CenteredCumulantBasedLbMethod(AbstractLbMethod):
def relaxation_rates(self): def relaxation_rates(self):
return tuple([e.relaxation_rate for e in self._cumulant_to_relaxation_info_dict.values()]) return tuple([e.relaxation_rate for e in self._cumulant_to_relaxation_info_dict.values()])
@property
def compressible(self):
return self._conserved_quantity_computation.compressible
@property
def zero_centered_pdfs(self):
return self._conserved_quantity_computation.zero_centered_pdfs
@property @property
def zeroth_order_equilibrium_moment_symbol(self, ): def zeroth_order_equilibrium_moment_symbol(self, ):
return self._conserved_quantity_computation.zeroth_order_moment_symbol return self._conserved_quantity_computation.zeroth_order_moment_symbol
......
...@@ -82,13 +82,14 @@ class AbstractConservedQuantityComputation(abc.ABC): ...@@ -82,13 +82,14 @@ class AbstractConservedQuantityComputation(abc.ABC):
class DensityVelocityComputation(AbstractConservedQuantityComputation): class DensityVelocityComputation(AbstractConservedQuantityComputation):
def __init__(self, stencil, compressible, force_model=None, def __init__(self, stencil, compressible, zero_centered_pdfs, force_model=None,
zeroth_order_moment_symbol=sp.Symbol("rho"), zeroth_order_moment_symbol=sp.Symbol("rho"),
first_order_moment_symbols=sp.symbols("u_:3"), first_order_moment_symbols=sp.symbols("u_:3"),
second_order_moment_symbols=sp.symbols("p_:9")): second_order_moment_symbols=sp.symbols("p_:9")):
dim = stencil.D dim = stencil.D
self._stencil = stencil self._stencil = stencil
self._compressible = compressible self._compressible = compressible
self._zero_centered_pdfs = zero_centered_pdfs
self._forceModel = force_model self._forceModel = force_model
self._symbolOrder0 = zeroth_order_moment_symbol self._symbolOrder0 = zeroth_order_moment_symbol
self._symbolsOrder1 = first_order_moment_symbols[:dim] self._symbolsOrder1 = first_order_moment_symbols[:dim]
...@@ -103,6 +104,10 @@ class DensityVelocityComputation(AbstractConservedQuantityComputation): ...@@ -103,6 +104,10 @@ class DensityVelocityComputation(AbstractConservedQuantityComputation):
def compressible(self): def compressible(self):
return self._compressible return self._compressible
@property
def zero_centered_pdfs(self):
return self._zero_centered_pdfs
def defined_symbols(self, order='all'): def defined_symbols(self, order='all'):
if order == 'all': if order == 'all':
return {'density': self._symbolOrder0, return {'density': self._symbolOrder0,
...@@ -114,10 +119,6 @@ class DensityVelocityComputation(AbstractConservedQuantityComputation): ...@@ -114,10 +119,6 @@ class DensityVelocityComputation(AbstractConservedQuantityComputation):
else: else:
return None return None
@property
def zero_centered_pdfs(self):
return not self._compressible
@property @property
def zeroth_order_moment_symbol(self): def zeroth_order_moment_symbol(self):
return self._symbolOrder0 return self._symbolOrder0
...@@ -149,7 +150,7 @@ class DensityVelocityComputation(AbstractConservedQuantityComputation): ...@@ -149,7 +150,7 @@ class DensityVelocityComputation(AbstractConservedQuantityComputation):
def equilibrium_input_equations_from_init_values(self, density=1, velocity=(0, 0, 0), force_substitution=True): def equilibrium_input_equations_from_init_values(self, density=1, velocity=(0, 0, 0), force_substitution=True):
dim = self._stencil.D dim = self._stencil.D
zeroth_order_moment = density if self._compressible else density - sp.Rational(1, 1) zeroth_order_moment = density - sp.Rational(1, 1) if self._zero_centered_pdfs else density
first_order_moments = velocity[:dim] first_order_moments = velocity[:dim]
vel_offset = [0] * dim vel_offset = [0] * dim
...@@ -180,7 +181,8 @@ class DensityVelocityComputation(AbstractConservedQuantityComputation): ...@@ -180,7 +181,8 @@ class DensityVelocityComputation(AbstractConservedQuantityComputation):
if self._compressible: if self._compressible:
ac = divide_first_order_moments_by_rho(ac, dim) ac = divide_first_order_moments_by_rho(ac, dim)
else:
if self._zero_centered_pdfs:
ac = add_density_offset(ac) ac = add_density_offset(ac)
if self._forceModel is not None: if self._forceModel is not None:
......
This diff is collapsed.
...@@ -86,6 +86,14 @@ class CentralMomentBasedLbMethod(AbstractLbMethod): ...@@ -86,6 +86,14 @@ class CentralMomentBasedLbMethod(AbstractLbMethod):
def relaxation_rates(self): def relaxation_rates(self):
return tuple([e.relaxation_rate for e in self._moment_to_relaxation_info_dict.values()]) return tuple([e.relaxation_rate for e in self._moment_to_relaxation_info_dict.values()])
@property
def compressible(self):
return self._conserved_quantity_computation.compressible
@property
def zero_centered_pdfs(self):
return self._conserved_quantity_computation.zero_centered_pdfs
@property @property
def zeroth_order_equilibrium_moment_symbol(self, ): def zeroth_order_equilibrium_moment_symbol(self, ):
return self._conserved_quantity_computation.zeroth_order_moment_symbol return self._conserved_quantity_computation.zeroth_order_moment_symbol
......
...@@ -24,6 +24,14 @@ class EntropicEquilibriumSRT(AbstractLbMethod): ...@@ -24,6 +24,14 @@ class EntropicEquilibriumSRT(AbstractLbMethod):
def conserved_quantity_computation(self): def conserved_quantity_computation(self):
return self._cqc return self._cqc
@property
def compressible(self):
return self._cqc.compressible
@property
def zero_centered_pdfs(self):
return self._cqc.zero_centered_pdfs
@property @property
def weights(self): def weights(self):
return self._weights return self._weights
......
...@@ -58,6 +58,14 @@ class MomentBasedLbMethod(AbstractLbMethod): ...@@ -58,6 +58,14 @@ class MomentBasedLbMethod(AbstractLbMethod):
def conserved_quantity_computation(self): def conserved_quantity_computation(self):
return self._conservedQuantityComputation return self._conservedQuantityComputation
@property
def compressible(self):
return self._conservedQuantityComputation.compressible
@property
def zero_centered_pdfs(self):
return self._conservedQuantityComputation.zero_centered_pdfs
@property @property
def moments(self): def moments(self):
return tuple(self._momentToRelaxationInfoDict.keys()) return tuple(self._momentToRelaxationInfoDict.keys())
...@@ -71,11 +79,11 @@ class MomentBasedLbMethod(AbstractLbMethod): ...@@ -71,11 +79,11 @@ class MomentBasedLbMethod(AbstractLbMethod):
return tuple([e.relaxation_rate for e in self._momentToRelaxationInfoDict.values()]) return tuple([e.relaxation_rate for e in self._momentToRelaxationInfoDict.values()])
@property @property
def zeroth_order_equilibrium_moment_symbol(self, ): def zeroth_order_equilibrium_moment_symbol(self):
return self._conservedQuantityComputation.zeroth_order_moment_symbol return self._conservedQuantityComputation.zeroth_order_moment_symbol
@property @property
def first_order_equilibrium_moment_symbols(self, ): def first_order_equilibrium_moment_symbols(self):
return self._conservedQuantityComputation.first_order_moment_symbols return self._conservedQuantityComputation.first_order_moment_symbols
@property @property
......
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