Exemple #1
0
    def __init__(self, stencil,
                 moment_polynomials,
                 equilibrium_density,
                 equilibrium_velocity,
                 conserved_quantity_equations=None,
                 **kwargs):
        super(FastCentralMomentTransform, self).__init__(
            stencil, moment_polynomials, equilibrium_density, equilibrium_velocity,
            conserved_quantity_equations=conserved_quantity_equations, **kwargs)

        #   Potentially, de-aliasing is required
        if len(self.moment_exponents) != self.q:
            P, m_reduced = central_moment_reduced_monomial_to_polynomial_matrix(self.moment_polynomials,
                                                                                self.stencil,
                                                                                velocity_symbols=equilibrium_velocity)
            self.mono_to_poly_matrix = P
            self.moment_exponents = m_reduced
        else:
            self.mono_to_poly_matrix = monomial_to_polynomial_transformation_matrix(self.moment_exponents,
                                                                                    self.moment_polynomials)

        self.poly_to_mono_matrix = self.mono_to_poly_matrix.inv()

        moment_matrix_without_shift = moment_matrix(self.moment_exponents, self.stencil)
        shift_matrix = set_up_shift_matrix(self.moment_exponents, self.stencil, equilibrium_velocity)
        self.inv_monomial_matrix = moment_matrix_without_shift.inv() * shift_matrix.inv()
Exemple #2
0
    def __init__(self, stencil, moment_polynomials,
                 equilibrium_density,
                 equilibrium_velocity,
                 conserved_quantity_equations=None,
                 **kwargs):
        super(PdfsToCentralMomentsByShiftMatrix, self).__init__(
            stencil, moment_polynomials, equilibrium_density, equilibrium_velocity,
            conserved_quantity_equations=conserved_quantity_equations, **kwargs)

        #   Potentially, de-aliasing is required
        if len(self.moment_exponents) != self.q:
            P, m_reduced = central_moment_reduced_monomial_to_polynomial_matrix(self.moment_polynomials,
                                                                                self.stencil,
                                                                                velocity_symbols=equilibrium_velocity)
            self.mono_to_poly_matrix = P
            self.moment_exponents = m_reduced
        else:
            self.mono_to_poly_matrix = monomial_to_polynomial_transformation_matrix(self.moment_exponents,
                                                                                    self.moment_polynomials)

        if 'moment_exponents' in kwargs:
            del kwargs['moment_exponents']

        self.raw_moment_transform = PdfsToMomentsByChimeraTransform(
            stencil, None, equilibrium_density, equilibrium_velocity,
            conserved_quantity_equations=conserved_quantity_equations,
            moment_exponents=self.moment_exponents,
            **kwargs)

        self.shift_matrix = set_up_shift_matrix(self.moment_exponents, self.stencil, self.equilibrium_velocity)
        self.inv_shift_matrix = self.shift_matrix.inv()
        self.poly_to_mono_matrix = self.mono_to_poly_matrix.inv()
Exemple #3
0
    def __init__(self, stencil, moment_polynomials,
                 equilibrium_density,
                 equilibrium_velocity,
                 **kwargs):
        super(PdfsToCentralMomentsByMatrix, self).__init__(
            stencil, moment_polynomials, equilibrium_density, equilibrium_velocity, **kwargs)

        moment_matrix_without_shift = moment_matrix(self.moment_polynomials, self.stencil)
        shift_matrix = set_up_shift_matrix(self.moment_polynomials, self.stencil, equilibrium_velocity)

        self.forward_matrix = shift_matrix * moment_matrix_without_shift
        self.backward_matrix = moment_matrix_without_shift.inv() * shift_matrix.inv()
Exemple #4
0
    def backward_transform(self, pdf_symbols, simplification=True, subexpression_base='sub_k_to_f',
                           start_from_monomials=False):
        r"""Returns an assignment collection containing equations for post-collision populations, 
        expressed in terms of the post-collision polynomial central moments by matrix-multiplication.

        The moment transformation matrix :math:`K` provided by :func:`lbmpy.moments.moment_matrix` is
        inverted and used to compute the pre-collision moments as 
        :math:`\mathbf{f}^{\ast} = K^{-1} \cdot \mathbf{K}_{\mathrm{post}}`, which is returned element-wise.

        Args:
            pdf_symbols: List of symbols that represent the post-collision populations
            simplification: Simplification specification. See :class:`AbstractMomentTransform`
            subexpression_base: The base name used for any subexpressions of the transformation.
            start_from_monomials: Return equations for monomial moments. Use only when specifying 
                                  ``moment_exponents`` in constructor!
        """
        simplification = self._get_simp_strategy(simplification)

        if start_from_monomials:
            assert len(self.moment_exponents) == self.q, "Could not derive invertible monomial transform." \
                f"Expected {self.q} monomials, but got {len(self.moment_exponents)}."
            mm_inv = moment_matrix(self.moment_exponents, self.stencil).inv()
            shift_inv = set_up_shift_matrix(self.moment_exponents, self.stencil, self.equilibrium_velocity).inv()
            km_inv = mm_inv * shift_inv
            post_collision_moments = self.post_collision_monomial_symbols
        else:
            km_inv = self.backward_matrix
            post_collision_moments = self.post_collision_symbols

        m_to_f_vec = km_inv * sp.Matrix(post_collision_moments)
        main_assignments = [Assignment(f, eq) for f, eq in zip(pdf_symbols, m_to_f_vec)]

        symbol_gen = SymbolGen(subexpression_base)
        ac = AssignmentCollection(main_assignments, subexpression_symbol_generator=symbol_gen)

        if simplification:
            ac = simplification.apply(ac)
        return ac
Exemple #5
0
 def continuous_force_central_moments(self, lb_method):
     raw_moments = self.continuous_force_raw_moments(lb_method)
     u = lb_method.first_order_equilibrium_moment_symbols
     shift_matrix = set_up_shift_matrix(lb_method.moments, lb_method.stencil, velocity_symbols=u)
     return (shift_matrix * raw_moments).expand()
Exemple #6
0
 def shift_matrix(self):
     return set_up_shift_matrix(self.moments, self.stencil)
Exemple #7
0
def create_with_discrete_maxwellian_eq_moments(
        stencil,
        moment_to_relaxation_rate_dict,
        compressible=False,
        force_model=None,
        equilibrium_order=2,
        c_s_sq=sp.Rational(1, 3),
        central_moment_space=False,
        moment_transform_class=None,
        central_moment_transform_class=PdfsToCentralMomentsByShiftMatrix):
    r"""Creates a moment-based LBM by taking a list of moments with corresponding relaxation rate.

    These moments are relaxed against the moments of the discrete Maxwellian distribution.

    Args:
        stencil: instance of :class:`lbmpy.stencils.LBStenil`
        moment_to_relaxation_rate_dict: dict that has as many entries as the stencil. Each moment, which can be
                                        represented by an exponent tuple or in polynomial form
                                        (see `lbmpy.moments`), is mapped to a relaxation rate.
        compressible: incompressible LBM methods split the density into :math:`\rho = \rho_0 + \Delta \rho`
                      where :math:`\rho_0` is chosen as one, and the first moment of the pdfs is :math:`\Delta \rho` .
                      This approximates the incompressible Navier-Stokes equations better than the standard
                      compressible model.
        force_model: force model instance, or None if no external forces
        equilibrium_order: approximation order of macroscopic velocity :math:`\mathbf{u}` in the equilibrium
        c_s_sq: Speed of sound squared
        central_moment_space: If set to True, an instance of 
                              :class:`lbmpy.methods.momentbased.CentralMomentBasedLbMethod` is returned, 
                              and the the collision will be performed in the central moment space.
        moment_transform_class: Class implementing the transform from populations to moment space.
        central_moment_transform_class: Class implementing the transform from populations to central moment space.

    Returns:
        Instance of either :class:`lbmpy.methods.momentbased.MomentBasedLbMethod` or 
        :class:`lbmpy.methods.momentbased.CentralMomentBasedLbMethod` 
    """
    mom_to_rr_dict = OrderedDict(moment_to_relaxation_rate_dict)
    assert len(mom_to_rr_dict) == stencil.Q, \
        "The number of moments has to be the same as the number of stencil entries"

    density_velocity_computation = DensityVelocityComputation(
        stencil, compressible, force_model)

    moments = tuple(mom_to_rr_dict.keys())
    eq_values = get_moments_of_discrete_maxwellian_equilibrium(
        stencil,
        moments,
        c_s_sq=c_s_sq,
        compressible=compressible,
        order=equilibrium_order)
    if central_moment_space:
        N = set_up_shift_matrix(moments, stencil)
        eq_values = sp.simplify(N * sp.Matrix(eq_values))

    rr_dict = OrderedDict([
        (mom, RelaxationInfo(eq_mom, rr)) for mom, rr, eq_mom in zip(
            mom_to_rr_dict.keys(), mom_to_rr_dict.values(), eq_values)
    ])

    if central_moment_space:
        return CentralMomentBasedLbMethod(stencil, rr_dict,
                                          density_velocity_computation,
                                          force_model,
                                          central_moment_transform_class)
    else:
        return MomentBasedLbMethod(stencil, rr_dict,
                                   density_velocity_computation, force_model,
                                   moment_transform_class)
Exemple #8
0
def test_central_moment_class():
    stencil = LBStencil(Stencil.D2Q9)
    lbm_config = LBMConfig(stencil=stencil,
                           method=Method.CENTRAL_MOMENT,
                           relaxation_rates=[1.2, 1.3, 1.4, 1.5],
                           equilibrium_order=4,
                           compressible=True)

    method = create_lb_method(lbm_config=lbm_config)

    lbm_config = LBMConfig(stencil=stencil,
                           method=Method.SRT,
                           relaxation_rate=1.2,
                           equilibrium_order=4,
                           compressible=True)
    srt = create_lb_method(lbm_config=lbm_config)

    rho = method.zeroth_order_equilibrium_moment_symbol
    u = method.first_order_equilibrium_moment_symbols
    cs_sq = sp.Rational(1, 3)

    force_model = Luo(force=sp.symbols(f"F_:{2}"))

    eq = (rho, 0, 0, 0, 0, 2 * rho * cs_sq, 0, 0, rho * cs_sq**2)

    default_moments = cascaded_moment_sets_literature(stencil)
    default_moments = [item for sublist in default_moments for item in sublist]

    assert method.central_moment_transform_class == PdfsToCentralMomentsByShiftMatrix
    assert method.conserved_quantity_computation.zeroth_order_moment_symbol == rho
    assert method.conserved_quantity_computation.first_order_moment_symbols == u
    assert method.moment_equilibrium_values == eq

    assert method.force_model is None
    method.set_force_model(force_model)
    assert method.force_model == force_model

    assert method.relaxation_matrix[0, 0] == 0
    assert method.relaxation_matrix[1, 1] == 0
    assert method.relaxation_matrix[2, 2] == 0

    method.set_conserved_moments_relaxation_rate(1.9)

    assert method.relaxation_matrix[0, 0] == 1.9
    assert method.relaxation_matrix[1, 1] == 1.9
    assert method.relaxation_matrix[2, 2] == 1.9

    moments = list()
    for i in method.relaxation_info_dict:
        moments.append(i)

    assert moments == default_moments

    for i in range(len(stencil)):
        assert method.relaxation_rates[i] == method.relaxation_matrix[i, i]

    M = method.moment_matrix
    N = method.shift_matrix

    assert M == moment_matrix(moments, stencil=stencil)
    assert N == set_up_shift_matrix(moments, stencil=stencil)

    assert get_weights(stencil) == method.weights

    eq_terms_central = method.get_equilibrium_terms()
    eq_terms_srt = srt.get_equilibrium_terms()

    for i in range(len(stencil)):
        assert sp.simplify(eq_terms_central[i] - eq_terms_srt[i]) == 0

    method = create_lb_method(
        lbm_config=LBMConfig(stencil=LBStencil(Stencil.D2Q9),
                             method=Method.CENTRAL_MOMENT,
                             relaxation_rates=[1.7, 1.8, 1.2, 1.3, 1.4],
                             equilibrium_order=4,
                             compressible=True))

    assert method.relaxation_matrix[0, 0] == 0
    assert method.relaxation_matrix[1, 1] == 0
    assert method.relaxation_matrix[2, 2] == 0

    method = create_lb_method(
        lbm_config=LBMConfig(stencil=LBStencil(Stencil.D2Q9),
                             method=Method.CENTRAL_MOMENT,
                             relaxation_rates=[1.3] * 9,
                             equilibrium_order=4,
                             compressible=True))

    np.testing.assert_almost_equal(sum(method.relaxation_rates), 1.3 * 9)