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):
common_params = {
'compressible': lbm_config.compressible,
'zero_centered_pdfs': lbm_config.zero_centered_pdfs,
'equilibrium_order': lbm_config.equilibrium_order,
'force_model': lbm_config.force_model,
'maxwellian_moments': lbm_config.maxwellian_moments,
......@@ -421,6 +422,7 @@ def create_lb_method(lbm_config=None, **params):
}
cumulant_params = {
'zero_centered_pdfs': lbm_config.zero_centered_pdfs,
'equilibrium_order': lbm_config.equilibrium_order,
'force_model': lbm_config.force_model,
'c_s_sq': lbm_config.c_s_sq,
......@@ -579,6 +581,8 @@ class LBMConfig:
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
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
c_s_sq: speed of sound. Usually 1 / 3
weighted: For MRT methods. If True the moments are weigted orthogonal. Usually desired.
......@@ -618,6 +622,7 @@ class LBMConfig:
relaxation_rates: Any = None
relaxation_rate: Union[int, float, Type[sp.Symbol]] = None
compressible: bool = False
zero_centered_pdfs: bool = True
equilibrium_order: int = 2
c_s_sq: sympy.core.numbers.Rational = sp.Rational(1, 3)
weighted: bool = True
......
......@@ -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
field_layout: layout for output field, also used for pdf field if pdf_arr is not given
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:
a function to compute macroscopic values:
......@@ -80,8 +82,8 @@ def compile_macroscopic_values_getter(lb_method, output_quantities, pdf_arr=None
cqc = lb_method.conserved_quantity_computation
unknown_quantities = [oq for oq in output_quantities if oq not in cqc.conserved_quantities]
if unknown_quantities:
raise ValueError("No such conserved quantity: %s, conserved quantities are %s" %
(str(unknown_quantities), str(cqc.conserved_quantities.keys())))
raise ValueError(f"No such conserved quantity: {str(unknown_quantities)}, "
f"conserved quantities are {str(cqc.conserved_quantities.keys())}")
if pdf_arr is None:
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
kernel = gpu.make_python_function(gpu.create_cuda_kernel(
eqs, ghost_layers=ghost_layers, iteration_slice=iteration_slice))
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):
if pdf_arr is not None:
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)
if not set(output_quantities).issubset(kwargs.keys()):
raise ValueError("You have to specify the output field for each of the following quantities: %s"
% (str(output_quantities),))
raise ValueError(f"You have to specify the output field for "
f"each of the following quantities: {str(output_quantities)}")
kernel(pdfs=pdfs, **kwargs)
return getter
......@@ -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
field_layout: layout of the pdf field if pdf_arr was not given
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:
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
kernel = gpu.make_python_function(gpu.create_cuda_kernel(eq))
kernel = functools.partial(kernel, **fixed_kernel_parameters)
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):
if pdf_arr is not None:
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)
return setter
......
......@@ -177,7 +177,7 @@ class CenteredCumulantBasedLbMethod(AbstractLbMethod):
@property
def central_moment_transform_class(self):
self._central_moment_transform_class
return self._central_moment_transform_class
@property
def cumulants(self):
......@@ -189,7 +189,7 @@ class CenteredCumulantBasedLbMethod(AbstractLbMethod):
@property
def cumulant_transform_class(self):
self._cumulant_transform_class
return self._cumulant_transform_class
@property
def first_order_equilibrium_moment_symbols(self, ):
......@@ -211,6 +211,14 @@ class CenteredCumulantBasedLbMethod(AbstractLbMethod):
def relaxation_rates(self):
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
def zeroth_order_equilibrium_moment_symbol(self, ):
return self._conserved_quantity_computation.zeroth_order_moment_symbol
......
......@@ -82,13 +82,14 @@ class AbstractConservedQuantityComputation(abc.ABC):
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"),
first_order_moment_symbols=sp.symbols("u_:3"),
second_order_moment_symbols=sp.symbols("p_:9")):
dim = stencil.D
self._stencil = stencil
self._compressible = compressible
self._zero_centered_pdfs = zero_centered_pdfs
self._forceModel = force_model
self._symbolOrder0 = zeroth_order_moment_symbol
self._symbolsOrder1 = first_order_moment_symbols[:dim]
......@@ -103,6 +104,10 @@ class DensityVelocityComputation(AbstractConservedQuantityComputation):
def compressible(self):
return self._compressible
@property
def zero_centered_pdfs(self):
return self._zero_centered_pdfs
def defined_symbols(self, order='all'):
if order == 'all':
return {'density': self._symbolOrder0,
......@@ -114,10 +119,6 @@ class DensityVelocityComputation(AbstractConservedQuantityComputation):
else:
return None
@property
def zero_centered_pdfs(self):
return not self._compressible
@property
def zeroth_order_moment_symbol(self):
return self._symbolOrder0
......@@ -149,7 +150,7 @@ class DensityVelocityComputation(AbstractConservedQuantityComputation):
def equilibrium_input_equations_from_init_values(self, density=1, velocity=(0, 0, 0), force_substitution=True):
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]
vel_offset = [0] * dim
......@@ -180,7 +181,8 @@ class DensityVelocityComputation(AbstractConservedQuantityComputation):
if self._compressible:
ac = divide_first_order_moments_by_rho(ac, dim)
else:
if self._zero_centered_pdfs:
ac = add_density_offset(ac)
if self._forceModel is not None:
......
This diff is collapsed.
......@@ -86,6 +86,14 @@ class CentralMomentBasedLbMethod(AbstractLbMethod):
def relaxation_rates(self):
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
def zeroth_order_equilibrium_moment_symbol(self, ):
return self._conserved_quantity_computation.zeroth_order_moment_symbol
......
......@@ -24,6 +24,14 @@ class EntropicEquilibriumSRT(AbstractLbMethod):
def conserved_quantity_computation(self):
return self._cqc
@property
def compressible(self):
return self._cqc.compressible
@property
def zero_centered_pdfs(self):
return self._cqc.zero_centered_pdfs
@property
def weights(self):
return self._weights
......
......@@ -58,6 +58,14 @@ class MomentBasedLbMethod(AbstractLbMethod):
def conserved_quantity_computation(self):
return self._conservedQuantityComputation
@property
def compressible(self):
return self._conservedQuantityComputation.compressible
@property
def zero_centered_pdfs(self):
return self._conservedQuantityComputation.zero_centered_pdfs
@property
def moments(self):
return tuple(self._momentToRelaxationInfoDict.keys())
......@@ -71,11 +79,11 @@ class MomentBasedLbMethod(AbstractLbMethod):
return tuple([e.relaxation_rate for e in self._momentToRelaxationInfoDict.values()])
@property
def zeroth_order_equilibrium_moment_symbol(self, ):
def zeroth_order_equilibrium_moment_symbol(self):
return self._conservedQuantityComputation.zeroth_order_moment_symbol
@property
def first_order_equilibrium_moment_symbols(self, ):
def first_order_equilibrium_moment_symbols(self):
return self._conservedQuantityComputation.first_order_moment_symbols
@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