示例#1
0
    def flux(self):
        from hedge.flux import (
                make_normal,
                FluxVectorPlaceholder,
                flux_max)
        from pymbolic.primitives import IfPositive

        d = self.dimensions

        w = FluxVectorPlaceholder((1+d)+1)
        u = w[0]
        v = w[1:d+1]
        c = w[1+d]

        normal = make_normal(self.dimensions)

        if self.flux_type == "central":
            return (u.int*numpy.dot(v.int, normal )
                    + u.ext*numpy.dot(v.ext, normal)) * 0.5
        elif self.flux_type == "lf":
            n_vint = numpy.dot(normal, v.int)
            n_vext = numpy.dot(normal, v.ext)
            return 0.5 * (n_vint * u.int + n_vext * u.ext) \
                   - 0.5 * (u.ext - u.int) \
                   * flux_max(c.int, c.ext)

        elif self.flux_type == "upwind":
            return (
                    IfPositive(numpy.dot(normal, v.avg),
                        numpy.dot(normal, v.int) * u.int, # outflow
                        numpy.dot(normal, v.ext) * u.ext, # inflow
                        ))
        else:
            raise ValueError, "invalid flux type"
    def flux_num(self, q, fluxes, bdry_tag_state_flux):
        n = self.len_q
        d = len(fluxes)
        fvph = FluxVectorPlaceholder(n*(d+1)+1)
        speed_ph = fvph[0]
        state_ph = fvph[1:n+1]
        fluxes_ph = [fvph[i*n+1:(i+1)*n+1] for i in range(1,d+1)]
        normal = make_normal(d)

        flux_strong = 0.5*sum(n_i*(f_i.ext-f_i.int) for n_i, f_i in zip(normal, fluxes_ph))

        if self.flux_type == "central":
            pass
        elif self.flux_type == "lf":
            penalty = flux_max(speed_ph.int,speed_ph.ext)*(state_ph.ext-state_ph.int)
            flux_strong = 0.5 * penalty + flux_strong
        else:
            raise ValueError("Invalid flux type '%s'" % self.flux_type)

        flux_op = get_flux_operator(flux_strong)
        int_operand = join_fields(self.wave_speed(q), q, *fluxes)

        return (flux_op(int_operand)
                +sum(flux_op(BoundaryPair(int_operand, join_fields(0, bdry_state, *bdry_fluxes), tag))
                     for tag, bdry_state, bdry_fluxes in bdry_tag_state_flux))
示例#3
0
    def flux(self):
        from hedge.flux import (make_normal, FluxVectorPlaceholder, flux_max)
        from pymbolic.primitives import IfPositive

        d = self.dimensions

        w = FluxVectorPlaceholder((1 + d) + 1)
        u = w[0]
        v = w[1:d + 1]
        c = w[1 + d]

        normal = make_normal(self.dimensions)

        if self.flux_type == "central":
            return (u.int * numpy.dot(v.int, normal) +
                    u.ext * numpy.dot(v.ext, normal)) * 0.5
        elif self.flux_type == "lf":
            n_vint = numpy.dot(normal, v.int)
            n_vext = numpy.dot(normal, v.ext)
            return 0.5 * (n_vint * u.int + n_vext * u.ext) \
                   - 0.5 * (u.ext - u.int) \
                   * flux_max(c.int, c.ext)

        elif self.flux_type == "upwind":
            return (IfPositive(
                numpy.dot(normal, v.avg),
                numpy.dot(normal, v.int) * u.int,  # outflow
                numpy.dot(normal, v.ext) * u.ext,  # inflow
            ))
        else:
            raise ValueError, "invalid flux type"
示例#4
0
def make_lax_friedrichs_flux(wave_speed, state, fluxes, bdry_tags_states_and_fluxes,
        strong):
    from pytools.obj_array import join_fields
    from hedge.flux import make_normal, FluxVectorPlaceholder, flux_max

    n = len(state)
    d = len(fluxes)
    normal = make_normal(d)
    fvph = FluxVectorPlaceholder(len(state)*(1+d)+1)

    wave_speed_ph = fvph[0]
    state_ph = fvph[1:1+n]
    fluxes_ph = [fvph[1+i*n:1+(i+1)*n] for i in range(1, d+1)]

    penalty = flux_max(wave_speed_ph.int,wave_speed_ph.ext)*(state_ph.ext-state_ph.int)

    if not strong:
        num_flux = 0.5*(sum(n_i*(f_i.int+f_i.ext) for n_i, f_i in zip(normal, fluxes_ph))
                - penalty)
    else:
        num_flux = 0.5*(sum(n_i*(f_i.int-f_i.ext) for n_i, f_i in zip(normal, fluxes_ph))
                + penalty)

    from hedge.optemplate import get_flux_operator
    flux_op = get_flux_operator(num_flux)
    int_operand = join_fields(wave_speed, state, *fluxes)

    from hedge.optemplate import BoundaryPair
    return (flux_op(int_operand)
            + sum(
                flux_op(BoundaryPair(int_operand,
                    join_fields(0, bdry_state, *bdry_fluxes), tag))
                for tag, bdry_state, bdry_fluxes in bdry_tags_states_and_fluxes))
示例#5
0
def make_lax_friedrichs_flux(wave_speed, state, fluxes,
                             bdry_tags_states_and_fluxes, strong):
    from pytools.obj_array import join_fields
    from hedge.flux import make_normal, FluxVectorPlaceholder, flux_max

    n = len(state)
    d = len(fluxes)
    normal = make_normal(d)
    fvph = FluxVectorPlaceholder(len(state) * (1 + d) + 1)

    wave_speed_ph = fvph[0]
    state_ph = fvph[1:1 + n]
    fluxes_ph = [fvph[1 + i * n:1 + (i + 1) * n] for i in range(1, d + 1)]

    penalty = flux_max(wave_speed_ph.int,
                       wave_speed_ph.ext) * (state_ph.ext - state_ph.int)

    if not strong:
        num_flux = 0.5 * (sum(n_i * (f_i.int + f_i.ext)
                              for n_i, f_i in zip(normal, fluxes_ph)) -
                          penalty)
    else:
        num_flux = 0.5 * (sum(n_i * (f_i.int - f_i.ext)
                              for n_i, f_i in zip(normal, fluxes_ph)) +
                          penalty)

    from hedge.optemplate import get_flux_operator
    flux_op = get_flux_operator(num_flux)
    int_operand = join_fields(wave_speed, state, *fluxes)

    from hedge.optemplate import BoundaryPair
    return (flux_op(int_operand) + sum(
        flux_op(
            BoundaryPair(int_operand, join_fields(0, bdry_state, *bdry_fluxes),
                         tag))
        for tag, bdry_state, bdry_fluxes in bdry_tags_states_and_fluxes))