示例#1
0
def elbm_d3q15_equilibrium(grid):
    """
    Form of equilibrium defined in PRL 97, 010201 (2006).
    See also Chikatamarla, PhD Thesis, Eq. (5.7), (5.8).
    """
    rho = S.rho

    prefactor = Symbol('prefactor')
    coeff1 = Symbol('coeff1')
    coeff2 = Symbol('coeff2')
    coeff3 = Symbol('coeff3')
    vsq = Symbol('vsq')
    vx, vy, vz = grid.v

    lvars = []
    lvars.append(Eq(vsq, grid.v.dot(grid.v)))
    lvars.append(Eq(prefactor, poly_factorize(
        rho * (1 - 3 * vsq / 2 + 9 * vsq**2 / 8 +
        Rational(27, 16) * (-vsq**3 + 2 * (vy**2 + vz**2) *
            (vsq * vx**2 + vy**2 * vz**2) +
            20 * vx**2 * vy**2 * vz**2) +
        Rational(81, 128) * vsq**4 +
        Rational(81, 32) * (vx**8 + vy**8 + vz**8
            - 36 * vx**2 * vy**2 * vz**2 * vsq
            - vx**4 * vy**4
            - vy**4 * vz**4
            - vx**4 * vz**4)))))

    cfs = [coeff1, coeff2, coeff3]

    for i, coeff in enumerate(cfs):
        tmp = (1 + 3 * grid.v[i] + 9 * grid.v[i]**2 / 2 +
            9 * grid.v[i]**3 / 2 + 27 * grid.v[i]**4 / 8)

        # Cyclic permutation.
        x = i
        y = (i + 1) % 3
        z = (i + 2) % 3

        tmp += Rational(27, 8) * (grid.v[x]**5
                - 4 * grid.v[x] * grid.v[y]**2 * grid.v[z]**2)
        tmp += Rational(81, 16) * (grid.v[x]**6
                - 8 * grid.v[x]**2 * grid.v[y]**2 * grid.v[z]**2)
        tmp += Rational(81, 16) * (grid.v[x]**7
                - 10 * grid.v[x]**3 * grid.v[y]**2 * grid.v[z]**2
                + 2 * grid.v[x] * grid.v[y]**2 * grid.v[z]**2 * vsq)
        tmp += Rational(243, 128) * (grid.v[x]**8
                + 16 * grid.v[x]**2 * grid.v[y]**2 * grid.v[z]**2
                * (grid.v[y]**2 + grid.v[z]**2))

        lvars.append(Eq(coeff, poly_factorize(tmp)))

    out = []
    for ei, weight in zip(grid.basis, grid.entropic_weights):
        t = prefactor * weight
        for j, comp in enumerate(ei):
            t *= cfs[j]**comp
        out.append(t)

    return EqDef(out, lvars)
示例#2
0
def bgk_equilibrium(grid, config, rho=None, rho0=None, order=2):
    """Get expressions for the BGK equilibrium distribution.

    :param grid: the grid class to be used
    """
    out = []

    if rho is None:
        rho = S.rho

    if rho0 is None:
        if config.incompressible:
            rho0 = S.rho0
        elif config.minimize_roundoff:
            rho0 = rho + 1.0
        else:
            rho0 = rho

    for ei, weight in zip(grid.basis, grid.weights):
        h = (ei.dot(grid.v) / grid.cssq +
             ei.dot(grid.v)**2 / grid.cssq**2 / 2 -
             grid.v.dot(grid.v) / 2 / grid.cssq)
        # Aidun, Clausen; Latice-Boltzmann Method for Complex Flows
        # Note: this does not seem to recover the 1st moment in the unit test!
#        if order > 2:
#            h += (ei.dot(grid.v)**3 / grid.cssq**3 / 2 -
#                  ei.dot(grid.v) * grid.v.dot(grid.v) / grid.cssq**2 / 2)

        out.append(weight * (rho + rho0 * poly_factorize(h)))

    return EqDef(out, local_vars=[])
示例#3
0
def bgk_equilibrium(grid, config, rho=None, rho0=None, order=2):
    """Get expressions for the BGK equilibrium distribution.

    :param grid: the grid class to be used
    """
    out = []

    if rho is None:
        rho = S.rho

    if rho0 is None:
        if config.incompressible:
            rho0 = S.rho0
        elif config.minimize_roundoff:
            rho0 = rho + 1.0
        else:
            rho0 = rho

    for ei, weight in zip(grid.basis, grid.weights):
        h = (ei.dot(grid.v) / grid.cssq +
             ei.dot(grid.v)**2 / grid.cssq**2 / 2 -
             grid.v.dot(grid.v) / 2 / grid.cssq)
        if order > 2:
            h += (ei.dot(grid.v)**3 / grid.cssq**3 / 2 -
                  ei.dot(grid.v) * grid.v.dot(grid.v) / grid.cssq**2 / 2)

        out.append(weight * (rho + rho0 * poly_factorize(h)))

    return EqDef(out, local_vars=[])
示例#4
0
    def _init_mrt_equilibrium(cls):
        cls.mrt_equilibrium = []
        cls.mrt_eq_symbols = []

        c1 = -2

        # Name -> index map.
        n2i = {}
        for i, name in enumerate(cls.mrt_names):
            n2i[name] = i

        inv_tau = Symbol('inv_tau')
        cls.mrt_eq_symbols.append(
            Eq(inv_tau, 1 / (0.5 + S.visc * Rational(12, 2 - c1))))

        cls.mrt_collision[n2i['pxx']] = inv_tau
        cls.mrt_collision[n2i['pxy']] = cls.mrt_collision[n2i['pxx']]

        vec_rho = cls.mrt_matrix[n2i['rho'], :]
        vec_mx = cls.mrt_matrix[n2i['mx'], :]
        vec_my = cls.mrt_matrix[n2i['my'], :]

        # We choose the form of the equilibrium distributions and the
        # optimal parameters as shows in the PhysRevE.61.6546 paper about
        # MRT in 2D.
        for i, name in enumerate(cls.mrt_names):
            if cls.mrt_collision[i] == 0:
                cls.mrt_equilibrium.append(0)
                continue

            vec_e = cls.mrt_matrix[i, :]
            if name == 'en':
                t = (Rational(1, vec_e.dot(vec_e)) *
                     (-8 * vec_rho.dot(vec_rho) * S.rho + 18 *
                      (vec_mx.dot(vec_mx) * cls.mx**2 +
                       vec_my.dot(vec_my) * cls.my**2)))
            elif name == 'ens':
                # The 4 and -18 below are freely adjustable parameters.
                t = (Rational(1, vec_e.dot(vec_e)) *
                     (4 * vec_rho.dot(vec_rho) * S.rho + -18 *
                      (vec_mx.dot(vec_mx) * cls.mx**2 +
                       vec_my.dot(vec_my) * cls.my**2)))
            elif name == 'ex':
                t = Rational(
                    1, vec_e.dot(vec_e)) * (c1 * vec_mx.dot(vec_mx) * cls.mx)
            elif name == 'ey':
                t = Rational(
                    1, vec_e.dot(vec_e)) * (c1 * vec_my.dot(vec_my) * cls.my)
            elif name == 'pxx':
                t = (Rational(1, vec_e.dot(vec_e)) * Rational(2, 3) *
                     (vec_mx.dot(vec_mx) * cls.mx**2 -
                      vec_my.dot(vec_my) * cls.my**2))
            elif name == 'pxy':
                t = (Rational(1, vec_e.dot(vec_e)) * Rational(2, 3) *
                     (math.sqrt(vec_mx.dot(vec_mx) * vec_my.dot(vec_my)) *
                      cls.mx * cls.my))

            t = sym_codegen.poly_factorize(t)
            cls.mrt_equilibrium.append(t)
示例#5
0
    def _init_mrt_equilibrium(cls):
        cls.mrt_equilibrium = []
        cls.mrt_eq_symbols = []

        c1 = -2

        # Name -> index map.
        n2i = {}
        for i, name in enumerate(cls.mrt_names):
            n2i[name] = i

        inv_tau = Symbol('inv_tau')
        cls.mrt_eq_symbols.append(Eq(inv_tau, 1 / (0.5 + S.visc * Rational(12, 2-c1))))

        cls.mrt_collision[n2i['pxx']] = inv_tau
        cls.mrt_collision[n2i['pxy']] = cls.mrt_collision[n2i['pxx']]

        vec_rho = cls.mrt_matrix[n2i['rho'],:]
        vec_mx = cls.mrt_matrix[n2i['mx'],:]
        vec_my = cls.mrt_matrix[n2i['my'],:]

        # We choose the form of the equilibrium distributions and the
        # optimal parameters as shows in the PhysRevE.61.6546 paper about
        # MRT in 2D.
        for i, name in enumerate(cls.mrt_names):
            if cls.mrt_collision[i] == 0:
                cls.mrt_equilibrium.append(0)
                continue

            vec_e = cls.mrt_matrix[i,:]
            if name == 'en':
                t = (Rational(1, vec_e.dot(vec_e)) *
                        (-8*vec_rho.dot(vec_rho)*S.rho +
                            18*(vec_mx.dot(vec_mx)*cls.mx**2 + vec_my.dot(vec_my)*cls.my**2)))
            elif name == 'ens':
                # The 4 and -18 below are freely adjustable parameters.
                t = (Rational(1, vec_e.dot(vec_e)) *
                        (4*vec_rho.dot(vec_rho)*S.rho +
                            -18*(vec_mx.dot(vec_mx)*cls.mx**2 + vec_my.dot(vec_my)*cls.my**2)))
            elif name == 'ex':
                t = Rational(1, vec_e.dot(vec_e)) * (c1 * vec_mx.dot(vec_mx)*cls.mx)
            elif name == 'ey':
                t = Rational(1, vec_e.dot(vec_e)) * (c1 * vec_my.dot(vec_my)*cls.my)
            elif name == 'pxx':
                t = (Rational(1, vec_e.dot(vec_e)) * Rational(2, 3) *
                        (vec_mx.dot(vec_mx)*cls.mx**2 - vec_my.dot(vec_my)*cls.my**2))
            elif name == 'pxy':
                t = (Rational(1, vec_e.dot(vec_e)) * Rational(2, 3) *
                        (math.sqrt(vec_mx.dot(vec_mx) * vec_my.dot(vec_my)) * cls.mx * cls.my))

            t = sym_codegen.poly_factorize(t)
            cls.mrt_equilibrium.append(t)
示例#6
0
def alpha_series():
    """See Phys Rev Lett 97, 010201 (2006) for the expression."""

    a1 = Symbol('a1')
    a2 = Symbol('a2')
    a3 = Symbol('a3')
    a4 = Symbol('a4')

    alpha = sym_codegen.poly_factorize(2 - 4 * a2 / a1 + 16 * a2**2 / a1**2 -
                                       8 * a3 / a1 + 80 * a2 * a3 / a1**2 -
                                       80 * a2**3 / a1**3 - 16 * a4 / a1)

    return alpha
示例#7
0
def shallow_water_equilibrium(grid, config):
    """Get expressions for the BGK equilibrium distribution for the shallow
    water equation."""

    if grid.dim != 2 or grid.Q != 9:
        raise TypeError('Shallow water equation requires the D2Q9 grid.')

    out = [S.rho - grid.weights[0] * S.rho * (
        Rational(15, 8) * S.gravity * S.rho - 3 * grid.v.dot(grid.v))]

    for ei, weight in zip(grid.basis[1:], grid.weights[1:]):
        out.append(weight * (
                S.rho * poly_factorize(Rational(3,2) * S.rho * S.gravity + 3*ei.dot(grid.v) +
                    Rational(9,2) * (ei.dot(grid.v))**2 - Rational(3, 2) * grid.v.dot(grid.v))))

    return EqDef(out, local_vars=[])
示例#8
0
文件: sym.py 项目: vikeu/sailfish
def noneq_bb(grid, orientation, eq):
    normal = grid.dir_to_vec(orientation)
    known, unknown = _get_known_dists(grid, normal)
    ret = []

    # Bounce-back of the non-equilibrium parts.
    for i in unknown:
        oi = grid.idx_opposite[i]
        ret.append((Symbol('fi->%s' % grid.idx_name[i]),
                    Symbol('fi->%s' % grid.idx_name[oi]) - eq[oi] + eq[i]))

    for i in range(0, len(ret)):
        t = sym_codegen.poly_factorize(ret[i][1])

        ret[i] = (ret[i][0], t)

    return ret
示例#9
0
文件: sym.py 项目: vikeu/sailfish
def alpha_series():
    """See Phys Rev Lett 97, 010201 (2006) for the expression."""

    a1 = Symbol('a1')
    a2 = Symbol('a2')
    a3 = Symbol('a3')
    a4 = Symbol('a4')

    alpha = sym_codegen.poly_factorize(2
            - 4 * a2 / a1
            + 16 * a2**2 / a1**2
            - 8 * a3 / a1
            + 80 * a2 * a3 / a1**2
            - 80 * a2**3 / a1**3
            - 16 * a4 / a1)

    return alpha
示例#10
0
def noneq_bb(grid, orientation, eq):
    normal = grid.dir_to_vec(orientation)
    known, unknown = _get_known_dists(grid, normal)
    ret = []

    # Bounce-back of the non-equilibrium parts.
    for i in unknown:
        oi = grid.idx_opposite[i]
        ret.append((Symbol('fi->%s' % grid.idx_name[i]),
                    Symbol('fi->%s' % grid.idx_name[oi]) - eq[oi] + eq[i]))

    for i in range(0, len(ret)):
        t = sym_codegen.poly_factorize(ret[i][1])

        ret[i] = (ret[i][0], t)

    return ret
示例#11
0
def guo_external_force(grid, grid_num=0):
    """Gets expressions for the external body force correction in the BGK model.

    This implements the external force as in Eq. 20 from PhysRevE 65, 046308.

    :param grid: the grid class to be used

    :rtype: list of sympy expressions (in the same order as the current grid's basis)
    """
    pref = Symbol('pref')

    ea = accel_vector(grid, grid_num)
    ret = []

    for i, ei in enumerate(grid.basis):
        ret.append(pref * grid.weights[i] * poly_factorize(
            (ei - grid.v + ei.dot(grid.v) * ei * 3).dot(ea)))
    return ret
示例#12
0
def guo_external_force(grid, grid_num=0):
    """Gets expressions for the external body force correction in the BGK model.

    This implements the external force as in Eq. 20 from PhysRevE 65, 046308.

    :param grid: the grid class to be used

    :rtype: list of sympy expressions (in the same order as the current grid's basis)
    """
    pref = Symbol('pref')

    ea = accel_vector(grid, grid_num)
    ret = []

    for i, ei in enumerate(grid.basis):
        ret.append(pref * grid.weights[i] *
                   poly_factorize((ei - grid.v + ei.dot(grid.v)*ei*3).dot(ea)))
    return ret
示例#13
0
def elbm_d3q15_equilibrium(grid, order=8):
    """
    Form of equilibrium defined in PRL 97, 010201 (2006).
    See also Chikatamarla, PhD Thesis, Eq. (5.7), (5.8).
    """
    rho = S.rho

    prefactor = Symbol('chi')
    coeff1 = Symbol('zeta_x')
    coeff2 = Symbol('zeta_y')
    coeff3 = Symbol('zeta_z')
    vsq = Symbol('vsq')
    vx, vy, vz = grid.v

    o = [(1 if i <= order else 0) for i in range(0, 9)]

    lvars = []
    lvars.append(Eq(vsq, grid.v.dot(grid.v)))
    lvars.append(Eq(prefactor, poly_factorize(
        rho * (1 -
               o[2] * Rational(3, 2) * vsq +
               o[4] * Rational(9, 8) * vsq**2 +
               o[6] * Rational(27, 16) * (-vsq**3 + 2 * (vy**2 + vz**2) *
                                   (vsq * vx**2 + vy**2 * vz**2) +
                                   20 * vx**2 * vy**2 * vz**2) +
               o[8] * (Rational(81, 128) * vsq**4 +
                       Rational(81, 32) * (
                           vx**8 + vy**8 + vz**8
                           - 36 * vx**2 * vy**2 * vz**2 * vsq
                           - vx**4 * vy**4
                           - vy**4 * vz**4
                           - vx**4 * vz**4))))))

    cfs = [coeff1, coeff2, coeff3]

    for i, coeff in enumerate(cfs):
        tmp = (1 +
               o[1] * 3 * grid.v[i] +
               o[2] * Rational(9, 2) * grid.v[i]**2 +
               o[3] * Rational(9, 2) * grid.v[i]**3 +
               o[4] * Rational(27, 8) * grid.v[i]**4)

        # Cyclic permutation.
        x = i
        y = (i + 1) % 3
        z = (i + 2) % 3

        tmp += o[5] * Rational(27, 8) * (
            grid.v[x]**5 - 4 * grid.v[x] * grid.v[y]**2 * grid.v[z]**2)
        tmp += o[6] * Rational(81, 16) * (
            grid.v[x]**6 - 8 * grid.v[x]**2 * grid.v[y]**2 * grid.v[z]**2)
        tmp += o[7] * Rational(81, 16) * (
            grid.v[x]**7 - 10 * grid.v[x]**3 * grid.v[y]**2 * grid.v[z]**2 +
            2 * grid.v[x] * grid.v[y]**2 * grid.v[z]**2 * vsq)
        tmp += o[8] * Rational(243, 128) * (
            grid.v[x]**8 + 16 * grid.v[x]**2 * grid.v[y]**2 * grid.v[z]**2
            * (grid.v[y]**2 + grid.v[z]**2))

        lvars.append(Eq(coeff, poly_factorize(tmp)))

    out = []
    for ei, weight in zip(grid.basis, grid.entropic_weights):
        t = prefactor * weight
        for j, comp in enumerate(ei):
            t *= cfs[j]**comp
        out.append(t)

    return EqDef(out, lvars)
示例#14
0
def elbm_d3q19_equilibrium(grid, order=8):
    rho = S.rho

    prefactor = Symbol('chi')
    coeff1 = Symbol('zeta_x')
    coeff2 = Symbol('zeta_y')
    coeff3 = Symbol('zeta_z')
    vsq = Symbol('vsq')
    vx, vy, vz = grid.v

    o = [(1 if i <= order else 0) for i in range(0, 9)]

    lvars = []
    lvars.append(Eq(vsq, grid.v.dot(grid.v)))
    lvars.append(Eq(prefactor, poly_factorize(
        rho * (1 -
               o[2] * Rational(3, 2) * vsq +
               o[4] * Rational(9, 8) * vsq**2 -
               o[6] * Rational(27, 16) * (vx**6 + vx**4 * (vy**2 + vz**2) +
                                          (vy**2 + vz**2) * (vy**4 + vz**4) +
                                          vx**2 * (vy**4 + 12 * vy**2 * vz**2 +
                                                   vz**4)) +
               o[8] * Rational(81, 128) * (5 * vx**8 + 5 * vy**8 + 4 * vy**6 *
                                           vz**2 + 2 * vy**4 * vz**4 +
                                           4 * vy**2 * vz**6 +
                                           5 * vz**8 + 4 * vx**6 * (vy**2 + vz**2) +
                                           4 * vx**2 * (vy**2 + vz**2) * (
                                               vy**4 + 17 * vy**2 * vz**2 + vz**4) +
                                           2 * vx**4 * (vy**4 + 36 * vy**2 *
                                                        vz**2 + vz**4))))))

    cfs = [coeff1, coeff2, coeff3]

    for i, coeff in enumerate(cfs):
        tmp = (1 +
               o[1] * 3 * grid.v[i] +
               o[2] * Rational(9, 2) * grid.v[i]**2 +
               o[3] * Rational(9, 2) * grid.v[i]**3 +
               o[4] * Rational(27, 8) * grid.v[i]**4)

        # Cyclic permutation.
        x = i
        y = (i + 1) % 3
        z = (i + 2) % 3

        tmp += o[5] * Rational(27, 8) * (
            grid.v[x]**5 + 2 * grid.v[x] * grid.v[y]**2 * grid.v[z]**2)
        tmp += o[6] * Rational(81, 16) * (
            grid.v[x]**6 + 4 * grid.v[x]**2 * grid.v[y]**2 * grid.v[z]**2)
        tmp += o[7] * Rational(81, 16) * (
            grid.v[x] * (grid.v[x]**6 + 4 * grid.v[x]**2 * grid.v[y]**2 * grid.v[z]**2 -
                         grid.v[y]**2 * grid.v[z]**2 * (grid.v[y]**2 +
                                                        grid.v[z]**2)))
        tmp += o[8] * Rational(243, 128) * (
            grid.v[x]**2 * (grid.v[x]**6 - 8 * grid.v[y]**2 * grid.v[z]**2 * (
                grid.v[y]**2 + grid.v[z]**2)))

        lvars.append(Eq(coeff, poly_factorize(tmp)))

    out = []
    for ei, weight in zip(grid.basis, grid.entropic_weights):
        t = prefactor * weight
        for j, comp in enumerate(ei):
            t *= cfs[j]**comp
        out.append(t)

    return EqDef(out, lvars)