示例#1
0
def test_forward_transform(cumulants, stencil):
    stencil = LBStencil(stencil)
    if cumulants == 'monomial':
        moment_polynomials = get_default_moment_set_for_stencil(stencil)
    elif cumulants == 'polynomial':
        moment_polynomials = [
            item for sublist in cascaded_moment_sets_literature(stencil)
            for item in sublist
        ]
    pdfs = sp.symbols(f"f_:{stencil.Q}")
    rho = sp.Symbol('rho')
    u = sp.symbols(f"u_:{stencil.D}")

    matrix_transform = PdfsToCentralMomentsByMatrix(stencil,
                                                    moment_polynomials, rho, u)
    fast_transform = FastCentralMomentTransform(stencil, moment_polynomials,
                                                rho, u)
    shift_transform = PdfsToCentralMomentsByShiftMatrix(
        stencil, moment_polynomials, rho, u)

    assert shift_transform.moment_exponents == fast_transform.moment_exponents

    if cumulants == 'monomial' and not have_same_entries(
            stencil, LBStencil(Stencil.D3Q15)):
        assert fast_transform.mono_to_poly_matrix == sp.eye(stencil.Q)
        assert shift_transform.mono_to_poly_matrix == sp.eye(stencil.Q)
    else:
        assert not fast_transform.mono_to_poly_matrix == sp.eye(stencil.Q)
        assert not shift_transform.mono_to_poly_matrix == sp.eye(stencil.Q)

    f_to_k_matrix = matrix_transform.forward_transform(pdfs)
    f_to_k_matrix = f_to_k_matrix.new_without_subexpressions(
    ).main_assignments_dict

    f_to_k_fast = fast_transform.forward_transform(pdfs)
    f_to_k_fast = f_to_k_fast.new_without_subexpressions(
    ).main_assignments_dict

    f_to_k_shift = shift_transform.forward_transform(pdfs,
                                                     simplification=False)
    f_to_k_shift = f_to_k_shift.new_without_subexpressions(
    ).main_assignments_dict

    cm_symbols = matrix_transform.pre_collision_symbols

    for moment_symbol in cm_symbols:
        rhs_matrix = f_to_k_matrix[moment_symbol].expand()
        rhs_fast = f_to_k_fast[moment_symbol].expand()
        rhs_shift = f_to_k_shift[moment_symbol].expand()
        assert (
            rhs_matrix - rhs_fast
        ) == 0, f"Mismatch between matrix and fast transform at {moment_symbol}."
        assert (
            rhs_matrix - rhs_shift
        ) == 0, f"Mismatch between matrix and shift-matrix transform at {moment_symbol}."
示例#2
0
    def __init__(
            self,
            stencil,
            cumulant_to_relaxation_info_dict,
            conserved_quantity_computation,
            force_model=None,
            galilean_correction=False,
            central_moment_transform_class=PdfsToCentralMomentsByShiftMatrix,
            cumulant_transform_class=CentralMomentsToCumulantsByGeneratingFunc
    ):
        assert isinstance(conserved_quantity_computation,
                          AbstractConservedQuantityComputation)
        super(CenteredCumulantBasedLbMethod, self).__init__(stencil)

        if force_model is not None:
            assert (isinstance(force_model, CenteredCumulantForceModel)
                    or isinstance(force_model, Simple) or isinstance(
                        force_model,
                        Luo)), "Given force model currently not supported."

        for m in moments_up_to_order(1, dim=self.dim):
            if exponent_to_polynomial_representation(
                    m) not in cumulant_to_relaxation_info_dict.keys():
                raise ValueError(
                    f'No relaxation info given for conserved cumulant {m}!')

        self._cumulant_to_relaxation_info_dict = cumulant_to_relaxation_info_dict
        self._conserved_quantity_computation = conserved_quantity_computation
        self._force_model = force_model
        self._weights = None
        self._galilean_correction = galilean_correction

        if galilean_correction:
            if not have_same_entries(stencil, LBStencil(Stencil.D3Q27)):
                raise ValueError(
                    "Galilean Correction only available for D3Q27 stencil")

            if not contains_corrected_polynomials(
                    cumulant_to_relaxation_info_dict):
                raise ValueError(
                    "For the galilean correction, all three polynomial cumulants"
                    "(x^2 - y^2), (x^2 - z^2) and (x^2 + y^2 + z^2) must be present!"
                )

        self._cumulant_transform_class = cumulant_transform_class
        self._central_moment_transform_class = central_moment_transform_class

        self.force_model_rr_override = False
        if isinstance(self._force_model, CenteredCumulantForceModel) and \
                self._force_model.override_momentum_relaxation_rate is not None:
            self.set_first_moment_relaxation_rate(
                self._force_model.override_momentum_relaxation_rate)
            self.force_model_rr_override = True
def get_stencil_name(stencil):
    for name in ('D2Q9', 'D3Q15', 'D3Q19', 'D3Q27'):
        if have_same_entries(stencil, get_stencil(name, 'walberla')):
            return name
示例#4
0
 def __eq__(self, other):
     return self.ordering == other.ordering and have_same_entries(
         self._stencil_entries, other.stencil_entries)
示例#5
0
def cascaded_moment_sets_literature(stencil):
    """
    Returns default groups of cumulants to be relaxed with common relaxation rates as stated in literature.
    Groups are ordered like this:

    - First group is density
    - Second group are the momentum modes
    - Third group are the shear modes
    - Fourth group is the bulk mode
    - Remaining groups do not govern hydrodynamic properties

    Args:
        stencil: instance of :class:`lbmpy.stencils.LBStencil`. Can be D2Q9, D3Q7, D3Q15, D3Q19 or D3Q27
    """
    x, y, z = MOMENT_SYMBOLS
    if have_same_entries(stencil, LBStencil(Stencil.D2Q9)):
        #   Cumulants of the D2Q9 stencil up to third order are equal to
        #   the central moments; only the fourth-order cumulant x**2 * y**2
        #   has a more complicated form. They can be arranged into groups
        #   for the preservation of rotational invariance as described by
        #   Martin Geier in his dissertation.
        #
        #   Reference: Martin Geier. Ab inito derivation of the cascaded Lattice Boltzmann
        #   Automaton. Dissertation. University of Freiburg. 2006.
        return [
            [sp.sympify(1)],  # density is conserved
            [x, y],  # momentum is relaxed for cumulant forcing

            [x * y, x ** 2 - y ** 2],  # shear

            [x ** 2 + y ** 2],  # bulk

            [x ** 2 * y, x * y ** 2],
            [x ** 2 * y ** 2]
        ]

    elif have_same_entries(stencil, LBStencil(Stencil.D3Q7)):
        # D3Q7 moments: https://arxiv.org/ftp/arxiv/papers/1611/1611.03329.pdf
        return [
            [sp.sympify(1)],  # density is conserved
            [x, y, z],  # momentum might be affected by forcing

            [x ** 2 - y ** 2,
             x ** 2 - z ** 2],  # shear

            [x ** 2 + y ** 2 + z ** 2],  # bulk
        ]

    elif have_same_entries(stencil, LBStencil(Stencil.D3Q15)):
        #   D3Q15 central moments by Premnath et al. https://arxiv.org/pdf/1202.6081.pdf.
        return [
            [sp.sympify(1)],  # density is conserved
            [x, y, z],  # momentum might be affected by forcing

            [x * y,
             x * z,
             y * z,
             x ** 2 - y ** 2,
             x ** 2 - z ** 2],  # shear

            [x ** 2 + y ** 2 + z ** 2],  # bulk

            [x * (x ** 2 + y ** 2 + z ** 2),
             y * (x ** 2 + y ** 2 + z ** 2),
             z * (x ** 2 + y ** 2 + z ** 2)],

            [x * y * z],

            [x ** 2 * y ** 2 + x ** 2 * z ** 2 + y ** 2 * z ** 2]
        ]

    elif have_same_entries(stencil, LBStencil(Stencil.D3Q19)):
        #   D3Q19 cumulants are obtained by pruning the D3Q27 cumulant set as
        #   described by Coreixas, 2019.
        return [
            [sp.sympify(1)],  # density is conserved
            [x, y, z],  # momentum might be affected by forcing

            [x * y,
             x * z,
             y * z,
             x ** 2 - y ** 2,
             x ** 2 - z ** 2],  # shear

            [x ** 2 + y ** 2 + z ** 2],  # bulk

            [x * y ** 2 + x * z ** 2,
             x ** 2 * y + y * z ** 2,
             x ** 2 * z + y ** 2 * z],

            [x * y ** 2 - x * z ** 2,
             x ** 2 * y - y * z ** 2,
             x ** 2 * z - y ** 2 * z],

            [x ** 2 * y ** 2 - 2 * x ** 2 * z ** 2 + y ** 2 * z ** 2,
             x ** 2 * y ** 2 + x ** 2 * z ** 2 - 2 * y ** 2 * z ** 2],

            [x ** 2 * y ** 2 + x ** 2 * z ** 2 + y ** 2 * z ** 2]
        ]

    elif have_same_entries(stencil, LBStencil(Stencil.D3Q27)):
        #   Cumulants grouped to preserve rotational invariance as described by Geier et al, 2015
        return [
            [sp.sympify(1)],  # density is conserved
            [x, y, z],  # momentum might be affected by forcing

            [x * y,
             x * z,
             y * z,
             x ** 2 - y ** 2,
             x ** 2 - z ** 2],  # shear

            [x ** 2 + y ** 2 + z ** 2],  # bulk

            [x * y ** 2 + x * z ** 2,
             x ** 2 * y + y * z ** 2,
             x ** 2 * z + y ** 2 * z],

            [x * y ** 2 - x * z ** 2,
             x ** 2 * y - y * z ** 2,
             x ** 2 * z - y ** 2 * z],

            [x * y * z],

            [x ** 2 * y ** 2 - 2 * x ** 2 * z ** 2 + y ** 2 * z ** 2,
             x ** 2 * y ** 2 + x ** 2 * z ** 2 - 2 * y ** 2 * z ** 2],

            [x ** 2 * y ** 2 + x ** 2 * z ** 2 + y ** 2 * z ** 2],

            [x ** 2 * y * z,
             x * y ** 2 * z,
             x * y * z ** 2],

            [x ** 2 * y ** 2 * z,
             x ** 2 * y * z ** 2,
             x * y ** 2 * z ** 2],

            [x ** 2 * y ** 2 * z ** 2]
        ]
    else:
        raise ValueError("No default set of cascaded moments is available for this stencil. "
                         "Please specify your own set of cascaded moments.")
示例#6
0
def mrt_orthogonal_modes_literature(stencil, is_weighted):
    """
    Returns a list of lists of modes, grouped by common relaxation times.
    This is for commonly used MRT models found in literature.

    Args:
        stencil: instance of :class:`lbmpy.stencils.LBStencil`. Can be D2Q9, D3Q15, D3Q19 or D3Q27
        is_weighted: whether to use weighted or unweighted orthogonality

    MRT schemes as described in the following references are used
    """
    x, y, z = MOMENT_SYMBOLS
    one = sp.Rational(1, 1)

    if have_same_entries(stencil, LBStencil(Stencil.D2Q9)) and is_weighted:
        # Reference:
        # Duenweg, B., Schiller, U. D., & Ladd, A. J. (2007). Statistical mechanics of the fluctuating
        # lattice Boltzmann equation. Physical Review E, 76(3)
        sq = x ** 2 + y ** 2
        all_moments = [one, x, y, 3 * sq - 2, 2 * x ** 2 - sq, x * y,
                       (3 * sq - 4) * x, (3 * sq - 4) * y, 9 * sq ** 2 - 15 * sq + 2]
        nested_moments = list(sort_moments_into_groups_of_same_order(all_moments).values())
        return nested_moments
    elif have_same_entries(stencil, LBStencil(Stencil.D3Q15)) and is_weighted:
        sq = x ** 2 + y ** 2 + z ** 2
        nested_moments = [
            [one, x, y, z],  # [0, 3, 5, 7]
            [sq - 1],  # [1]
            [3 * sq ** 2 - 9 * sq + 4],  # [2]
            [(3 * sq - 5) * x, (3 * sq - 5) * y, (3 * sq - 5) * z],  # [4, 6, 8]
            [3 * x ** 2 - sq, y ** 2 - z ** 2, x * y, y * z, x * z],  # [9, 10, 11, 12, 13]
            [x * y * z]
        ]
    elif have_same_entries(stencil, LBStencil(Stencil.D3Q19)) and is_weighted:
        # This MRT variant mentioned in the dissertation of Ulf Schiller
        # "Thermal fluctuations and boundary conditions in the lattice Boltzmann method" (2008), p. 24ff
        # There are some typos in the moment matrix on p.27
        # The here implemented ordering of the moments is however different from that reference (Eq. 2.61-2.63)
        # The moments are weighted-orthogonal (Eq. 2.58)

        # Further references:
        # Duenweg, B., Schiller, U. D., & Ladd, A. J. (2007). Statistical mechanics of the fluctuating
        # lattice Boltzmann equation. Physical Review E, 76(3)
        # Chun, B., & Ladd, A. J. (2007). Interpolated boundary condition for lattice Boltzmann simulations of
        # flows in narrow gaps. Physical review E, 75(6)
        sq = x ** 2 + y ** 2 + z ** 2
        nested_moments = [
            [one, x, y, z],  # [0, 3, 5, 7]
            [sq - 1],  # [1]
            [3 * sq ** 2 - 6 * sq + 1],  # [2]
            [(3 * sq - 5) * x, (3 * sq - 5) * y, (3 * sq - 5) * z],  # [4, 6, 8]
            [3 * x ** 2 - sq, y ** 2 - z ** 2, x * y, y * z, x * z],  # [9, 11, 13, 14, 15]
            [(2 * sq - 3) * (3 * x ** 2 - sq), (2 * sq - 3) * (y ** 2 - z ** 2)],  # [10, 12]
            [(y ** 2 - z ** 2) * x, (z ** 2 - x ** 2) * y, (x ** 2 - y ** 2) * z]  # [16, 17, 18]
        ]
    elif have_same_entries(stencil, LBStencil(Stencil.D3Q27)) and not is_weighted:
        xsq, ysq, zsq = x ** 2, y ** 2, z ** 2
        all_moments = [
            sp.Rational(1, 1),  # 0
            x, y, z,  # 1, 2, 3
            x * y, x * z, y * z,  # 4, 5, 6
            xsq - ysq,  # 7
            (xsq + ysq + zsq) - 3 * zsq,  # 8
            (xsq + ysq + zsq) - 2,  # 9
            3 * (x * ysq + x * zsq) - 4 * x,  # 10
            3 * (xsq * y + y * zsq) - 4 * y,  # 11
            3 * (xsq * z + ysq * z) - 4 * z,  # 12
            x * ysq - x * zsq,  # 13
            xsq * y - y * zsq,  # 14
            xsq * z - ysq * z,  # 15
            x * y * z,  # 16
            3 * (xsq * ysq + xsq * zsq + ysq * zsq) - 4 * (xsq + ysq + zsq) + 4,  # 17
            3 * (xsq * ysq + xsq * zsq - 2 * ysq * zsq) - 2 * (2 * xsq - ysq - zsq),  # 18
            3 * (xsq * ysq - xsq * zsq) - 2 * (ysq - zsq),  # 19
            3 * (xsq * y * z) - 2 * (y * z),  # 20
            3 * (x * ysq * z) - 2 * (x * z),  # 21
            3 * (x * y * zsq) - 2 * (x * y),  # 22
            9 * (x * ysq * zsq) - 6 * (x * ysq + x * zsq) + 4 * x,  # 23
            9 * (xsq * y * zsq) - 6 * (xsq * y + y * zsq) + 4 * y,  # 24
            9 * (xsq * ysq * z) - 6 * (xsq * z + ysq * z) + 4 * z,  # 25
            27 * (xsq * ysq * zsq) - 18 * (xsq * ysq + xsq * zsq + ysq * zsq) + 12 * (xsq + ysq + zsq) - 8,  # 26
        ]
        nested_moments = list(sort_moments_into_groups_of_same_order(all_moments).values())
    else:
        raise NotImplementedError("No MRT model is available (yet) for this stencil. "
                                  "Create a custom MRT using 'create_with_discrete_maxwellian_eq_moments'")

    return nested_moments