예제 #1
0
    def make_bc_info(self, bc_name, tag, state, state0=None):
        """
        :param state0: The boundary 'free-stream' state around which the
          BC is linearized.
        """
        if state0 is None:
            state0 = make_sym_vector(bc_name, self.dimensions+2)

        state0 = cse(to_bdry_quad(state0))

        rho0 = self.rho(state0)
        p0 = self.cse_p(state0)
        u0 = self.cse_u(state0)

        c0 = (self.equation_of_state.gamma * p0 / rho0)**0.5

        from grudge.symbolic import RestrictToBoundary
        bdrize_op = RestrictToBoundary(tag)

        class SingleBCInfo(Record):
            pass

        return SingleBCInfo(
            rho0=rho0, p0=p0, u0=u0, c0=c0,

            # notation: suffix "m" for "minus", i.e. "interior"
            drhom=cse(self.rho(cse(to_bdry_quad(bdrize_op(state))))
                - rho0, "drhom"),
            dumvec=cse(self.cse_u(cse(to_bdry_quad(bdrize_op(state))))
                - u0, "dumvec"),
            dpm=cse(self.cse_p(cse(to_bdry_quad(bdrize_op(state))))
                - p0, "dpm"))
예제 #2
0
 def noslip_state(self, state):
     from grudge.symbolic import make_normal
     state0 = join_fields(make_sym_vector("bc_q_noslip", 2),
                          [0] * self.dimensions)
     normal = make_normal(self.noslip_tag, self.dimensions)
     bc = self.make_bc_info("bc_q_noslip", self.noslip_tag, state, state0)
     return self.inflow_state_inner(normal, bc, "noslip")
예제 #3
0
    def bind_characteristic_velocity(self, discr):
        state = make_sym_vector("q", self.dimensions+2)

        compiled = discr.compile(
                self.characteristic_velocity_optemplate(state))

        def do(q):
            return compiled(q=q)

        return do
예제 #4
0
    def get_conservative_boundary_conditions(self):
        state = self.state()

        from grudge.symbolic import RestrictToBoundary
        return {
                self.supersonic_inflow_tag:
                make_sym_vector("bc_q_supersonic_in", self.dimensions+2),
                self.supersonic_outflow_tag:
                RestrictToBoundary(self.supersonic_outflow_tag)(
                            state),
                self.wall_tag: self.wall_state(state),
                }
예제 #5
0
    def sym_operator(self, sensor_scaling=None, viscosity_only=False):
        u = self.cse_u
        rho = self.cse_rho
        rho_u = self.rho_u
        p = self.p
        e = self.e

        # {{{ artificial diffusion
        def make_artificial_diffusion():
            if self.artificial_viscosity_mode not in ["diffusion"]:
                return 0

            dq = self.grad_of_state()

            return make_obj_array([
                self.div(
                    to_vol_quad(self.sensor())*to_vol_quad(dq[i]),
                    to_int_face_quad(self.sensor())*to_int_face_quad(dq[i]))
                for i in range(dq.shape[0])])
        # }}}

        # {{{ state setup

        volq_flux = self.flux(self.volq_state())
        faceq_flux = self.flux(self.faceq_state())

        from grudge.symbolic.primitives import FunctionSymbol
        sqrt = FunctionSymbol("sqrt")

        speed = self.characteristic_velocity_optemplate(self.state())

        has_viscosity = not is_zero(self.get_mu(self.state(), to_quad_op=None))

        # }}}

        # {{{ operator assembly -----------------------------------------------
        from grudge.flux.tools import make_lax_friedrichs_flux
        from grudge.symbolic.operators import InverseMassOperator

        from grudge.symbolic.tools import make_stiffness_t

        primitive_bcs_as_quad_conservative = {
                tag: self.primitive_to_conservative(to_bdry_quad(bc))
                for tag, bc in
                self.get_primitive_boundary_conditions().items()}

        def get_bc_tuple(tag):
            state = self.state()
            bc = make_obj_array([
                self.get_boundary_condition_for(tag, s_i) for s_i in state])
            return tag, bc, self.flux(bc)

        first_order_part = InverseMassOperator()(
                numpy.dot(make_stiffness_t(self.dimensions), volq_flux)
                - make_lax_friedrichs_flux(
                    wave_speed=cse(to_int_face_quad(speed), "emax_c"),

                    state=self.faceq_state(), fluxes=faceq_flux,
                    bdry_tags_states_and_fluxes=[
                        get_bc_tuple(tag) for tag in self.get_boundary_tags()],
                    strong=False))

        if viscosity_only:
            first_order_part = 0*first_order_part

        result = join_fields(
                first_order_part
                + self.make_second_order_part()
                + make_artificial_diffusion()
                + self.make_extra_terms(),
                 speed)

        if self.source is not None:
            result = result + join_fields(
                    make_sym_vector("source_vect", len(self.state())),
                    # extra field for speed
                    0)

        return result
예제 #6
0
 def state(self):
     return make_sym_vector("q", self.dimensions+2)