From 223d1abd814edaac2bfa006ac30cb2d869cf2741 Mon Sep 17 00:00:00 2001 From: Rudolf Weeber <weeber@icp.uni-stuttgart.de> Date: Thu, 20 Mar 2025 16:47:02 +0100 Subject: [PATCH] Fix fluctuating LB with zero centered pdf storage --- src/lbmpy/fluctuatinglb.py | 2 +- tests/test_fluctuating_lb.py | 40 ++++++++++++++++++++---------------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/lbmpy/fluctuatinglb.py b/src/lbmpy/fluctuatinglb.py index cd035fc1..d0232775 100644 --- a/src/lbmpy/fluctuatinglb.py +++ b/src/lbmpy/fluctuatinglb.py @@ -42,7 +42,7 @@ def fluctuation_amplitude_from_temperature(method, temperature, c_s_sq=sp.Symbol """Produces amplitude equations according to (2.60) and (3.54) in Schiller08""" normalization_factors = sp.matrix_multiply_elementwise(method.moment_matrix, method.moment_matrix) * \ sp.Matrix(method.weights) - density = method.zeroth_order_equilibrium_moment_symbol + density = method._cqc.density_symbol mu = temperature * density / c_s_sq return [sp.sqrt(mu * norm * (1 - (1 - rr) ** 2)) for norm, rr in zip(normalization_factors, method.relaxation_rates)] diff --git a/tests/test_fluctuating_lb.py b/tests/test_fluctuating_lb.py index 7086898a..9fe76777 100644 --- a/tests/test_fluctuating_lb.py +++ b/tests/test_fluctuating_lb.py @@ -14,7 +14,7 @@ from pystencils.enums import Target from pystencils.rng import PhiloxTwoDoubles from lbmpy.creationfunctions import * -from lbmpy.forcemodels import Guo +from lbmpy.forcemodels import Schiller from lbmpy.macroscopic_value_kernels import macroscopic_values_setter import numpy as np from lbmpy.enums import Stencil @@ -137,7 +137,7 @@ def get_fluctuating_lb( weighted=True, zero_centered=zero_centered, relaxation_rates=rr_getter, - force_model=Guo(force=force_field.center_vector), + force_model=Schiller(force=force_field.center_vector), fluctuating={"temperature": kT}, kernel_type="collide_only", ) @@ -175,7 +175,7 @@ def get_fluctuating_lb( collision.method, velocity=(0,) * dh.dim, pdfs=src.center_vector, - density=rho.center, + density=rho_0 ) init_kernel = ps.create_kernel(init, ghost_layers=0).compile() @@ -216,7 +216,7 @@ def get_fluctuating_lb( "domain_size", [8, 60] ) def test_resting_fluid(zero_centered: bool, domain_size: int, target=Target.CPU): - rho_0 = 0.86 + rho_0 = 0.86 kT = 4e-4 L = [domain_size] * 3 dh, time_loop = get_fluctuating_lb( @@ -243,16 +243,18 @@ def test_resting_fluid(zero_centered: bool, domain_size: int, target=Target.CPU) res_u = dh.gather_array("u").reshape((-1, 3)) res_rho = dh.gather_array("rho").reshape((-1,)) - # mass conservation - np.testing.assert_allclose(np.mean(res_rho), rho_0, atol=3e-12) + # mass conservationo + # density per cell fluctuates, but toal mass is conserved + np.testing.assert_allclose(np.mean(res_rho), rho_0, atol=3E-12) # momentum conservation momentum = np.dot(res_rho, res_u) np.testing.assert_allclose(momentum, [0, 0, 0], atol=1e-10) - # temperature + # temperature (fluctuates around pre-set kT) kinetic_energy = 1 / 2 * np.dot(res_rho, res_u * res_u) / np.prod(L) - np.testing.assert_allclose(kinetic_energy, [kT / 2] * 3, atol=kT * 0.01) + kT_tol = 0.075 *(16/domain_size)**(3/2) + np.testing.assert_allclose(kinetic_energy, [kT / 2] * 3, rtol=kT_tol) # velocity distribution v_hist, v_bins = np.histogram( @@ -271,12 +273,12 @@ def test_resting_fluid(zero_centered: bool, domain_size: int, target=Target.CPU) v_expected.append(res) v_expected = np.array(v_expected) - # 10% accuracy on the entire histogram - np.testing.assert_allclose(v_hist, v_expected, rtol=0.1) - # 1% accuracy on the middle part + hist_tol_all = 0.75 *(16/domain_size)**(3/2) + np.testing.assert_allclose(v_hist, v_expected, rtol=hist_tol_all) + hist_tol_center = hist_tol_all/10 remove = 3 np.testing.assert_allclose( - v_hist[remove:-remove], v_expected[remove:-remove], rtol=0.01 + v_hist[remove:-remove], v_expected[remove:-remove], rtol=hist_tol_center ) # pressure tensor against expressions from @@ -291,9 +293,10 @@ def test_resting_fluid(zero_centered: bool, domain_size: int, target=Target.CPU) # thermalized, the expectation value of <u,u> = kT due to the # equi-partition theorem. p_av_expected = np.diag([rho_0 * c_s**2 + kT] * 3) + pressure_atol = c_s**2 / 200 *(16/domain_size)**(3/2) np.testing.assert_allclose( - np.mean(res_pressure, axis=0), p_av_expected, atol=c_s**2 / 2000 - ) + np.mean(res_pressure, axis=0), p_av_expected, atol=pressure_atol) + @pytest.mark.parametrize( @@ -314,8 +317,8 @@ def test_point_force(zero_centered: bool, domain_size: int, target=Target.CPU): kT=kT, omega_shear=0.8, omega_bulk=0.5, - omega_even=0.04, - omega_odd=0.3, + omega_even=0.8, + omega_odd=0.8, zero_centered=zero_centered ) @@ -326,7 +329,7 @@ def test_point_force(zero_centered: bool, domain_size: int, target=Target.CPU): introduced_momentum = np.zeros(3) for i in range(100): - point_force = 1e-5 * (np.random.random(3) - 0.5) + point_force = 1e-2/domain_size**(3/2) * (np.random.random(3) - 0.5) introduced_momentum += point_force # Note that ghost layers are included in the indexing @@ -336,9 +339,10 @@ def test_point_force(zero_centered: bool, domain_size: int, target=Target.CPU): t = time_loop(t, 1) res_u = dh.gather_array("u").reshape((-1, 3)) res_rho = dh.gather_array("rho").reshape((-1,)) + # mass conservation - np.testing.assert_allclose(np.mean(res_rho), rho_0, atol=3e-12) + np.testing.assert_allclose(np.mean(res_rho), rho_0, atol=3E-12) # momentum conservation momentum = np.dot(res_rho, res_u) -- GitLab