Exemplo n.º 1
0
    def characteristic_velocity_optemplate(self, state):
        from grudge.symbolic.operators import ElementwiseMaxOperator

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

        sound_speed = cse(sqrt(
            self.equation_of_state.gamma*self.cse_p(state)/self.cse_rho(state)),
            "sound_speed")
        u = self.cse_u(state)
        speed = cse(sqrt(numpy.dot(u, u)), "norm_u") + sound_speed
        return ElementwiseMaxOperator()(speed)
Exemplo n.º 2
0
    def __init__(self,
                 queue,
                 discr,
                 field_var_name,
                 grudge_bound_op,
                 num_fields,
                 component_getter,
                 exec_mapper_factory=ExecutionMapper):
        """Arguments:

            field_var_name: The name of the simulation variable

            grudge_bound_op: The BoundExpression for the right-hand side

            num_fields: The number of components in the simulation variable

            component_getter: A function, which, given an object array
               representing the simulation variable, splits the array into
               its components

        """
        super().__init__(queue, component_getter)

        # Construct sym_rhs to have the effect of replacing the RHS calls in the
        # dagrt code with calls of the grudge operator.
        from grudge.symbolic.primitives import FunctionSymbol, Variable
        call = sym.cse(
            FunctionSymbol("grudge_op")(
                *((Variable("t", dd=sym.DD_SCALAR), ) + tuple(
                    Variable(field_var_name, dd=sym.DD_VOLUME)[i]
                    for i in range(num_fields)))))

        from pytools.obj_array import join_fields
        sym_rhs = join_fields(*(call[i] for i in range(num_fields)))

        self.queue = queue
        self.grudge_bound_op = grudge_bound_op

        from grudge.function_registry import register_external_function

        freg = register_external_function(base_function_registry,
                                          "grudge_op",
                                          implementation=self._bound_op,
                                          dd=sym.DD_VOLUME)

        self.set_up_stepper(discr, field_var_name, sym_rhs, num_fields, freg,
                            exec_mapper_factory)

        self.component_getter = component_getter
Exemplo n.º 3
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