def __get_discrete_cumulant_generating_function(func, stencil, wave_numbers): assert stencil.Q == len(func) laplace_transformation = sum([ factor * sp.exp(scalar_product(wave_numbers, e)) for factor, e in zip(func, stencil) ]) return sp.ln(laplace_transformation)
def match_generic_equilibrium_ansatz(stencil, equilibrium, u=sp.symbols("u_:3")): """Given a quadratic equilibrium, the generic coefficients A,B,C,D are determined. Returns: dict that maps these coefficients to their values. If the equilibrium does not have a generic quadratic form, a ValueError is raised Example: >>> from lbmpy import LBStencil, Stencil >>> from lbmpy.maxwellian_equilibrium import discrete_maxwellian_equilibrium >>> stencil = LBStencil(Stencil.D2Q9) >>> eq = discrete_maxwellian_equilibrium(stencil) >>> result = match_generic_equilibrium_ansatz(stencil, eq) >>> result[sp.Symbol('A_0')] 4*rho/9 >>> result[sp.Symbol('B_1')] rho/(9*c_s**2) """ dim = len(stencil[0]) u = u[:dim] result = dict() for direction, actual_equilibrium in zip(stencil, equilibrium): speed = np.abs(direction).sum() a, b, c, d = get_parameter_symbols(speed) u_times_d = scalar_product(u, direction) generic_equation = a + b * u_times_d + c * u_times_d**2 + d * scalar_product( u, u) equations = sp.poly(actual_equilibrium - generic_equation, *u).coeffs() solve_res = sp.solve(equations, [a, b, c, d]) if not solve_res: raise ValueError( "This equilibrium does not match the generic quadratic standard form" ) for dof, value in solve_res.items(): if dof in result and result[dof] != value: raise ValueError( "This equilibrium does not match the generic quadratic standard form" ) result[dof] = value return result
def __call__(self, lb_method): force = self.symbolic_force_vector assert len(force) == lb_method.dim, "Force vectore must match with the dimensions of the lb method" cs_sq = sp.Rational(1, 3) # squared speed of sound result = [(w_i / cs_sq) * scalar_product(force, direction) for direction, w_i in zip(lb_method.stencil, lb_method.weights)] return sp.Matrix(result)
def generic_equilibrium_ansatz(stencil, u=sp.symbols("u_:3")): """Returns a generic quadratic equilibrium with coefficients A, B, C, D according to Wolf Gladrow Book equation (5.4.1) """ dim = len(stencil[0]) u = u[:dim] equilibrium = [] for direction in stencil: speed = np.abs(direction).sum() weight, linear, mix_quadratic, quadratic = get_parameter_symbols(speed) u_times_d = scalar_product(u, direction) eq = weight + linear * u_times_d + mix_quadratic * u_times_d**2 + quadratic * scalar_product( u, u) equilibrium.append(eq) return tuple(equilibrium)
def central_moment_generating_function(func, symbols, symbols_in_result, velocity=sp.symbols("u_:3")): r""" Computes central moment generating func, which is defined as: .. math :: K( \mathbf{\Xi} ) = \exp ( - \mathbf{\Xi} \cdot \mathbf{u} ) M( \mathbf{\Xi} ). For parameter description see :func:`moment_generating_function`. """ argument = -scalar_product(symbols_in_result, velocity) return sp.exp(argument) * moment_generating_function( func, symbols, symbols_in_result)
def test_utility(): a = [1, 2] b = (2, 3) a_np = np.array(a) b_np = np.array(b) assert scalar_product(a, b) == np.dot(a_np, b_np) a = sympy.Symbol("a") b = sympy.Symbol("b") assert kronecker_delta(a, a, a, b) == 0 assert kronecker_delta(a, a, a, a) == 1 assert kronecker_delta(3, 3, 3, 2) == 0 assert kronecker_delta(2, 2, 2, 2) == 1 assert kronecker_delta([10] * 100) == 1 assert kronecker_delta((0, 1), (0, 1)) == 1