Ejemplo n.º 1
0
    def make_func(self, discr, boundary_tag=None):
        from pymbolic import var

        def make_vec(basename):
            from hedge.tools import make_obj_array
            return make_obj_array(
                    [var("%s%d" % (basename, i)) for i in range(self.dimensions)])

        from hedge.optemplate.primitives  import ScalarParameter
        from hedge.optemplate.tools import make_vector_field

        x = make_vector_field("x", discr.dimensions)
        fields = make_vector_field("fields", self.arg_count)
        exprs = self.expressions_getter(
                t=ScalarParameter("t"), x=x, fields=fields)

        from hedge.optemplate.mappers.type_inference import (
                type_info, NodalRepresentation)
        type_hints = {}
        if boundary_tag is not None:
            my_vec_type = type_info.BoundaryVector(
                    boundary_tag, NodalRepresentation())
        else:
            my_vec_type = type_info.VolumeVector(
                    NodalRepresentation())

        for x_i in x:
            type_hints[x_i] = my_vec_type

        for f_i in fields:
            type_hints[f_i] = my_vec_type

        return discr.compile(exprs, type_hints=type_hints)
    def op_template(self):
        dim = self.dimensions
        q = make_vector_field('q', self.len_q)
        f2 = make_vector_field('f2', self.len_f2)
        w = join_fields(q, f2)
        dim_subset = (True,) * dim + (False,) * (3-dim)

        def pad_vec(v, subset):
            result = numpy.zeros((3,), dtype=object)
            result[numpy.array(subset, dtype=bool)] = v
            return result

        sigma = pad_vec(make_vector_field('sigma', dim),dim_subset)
        alpha = pad_vec(make_vector_field('alpha', dim),dim_subset)
        kappa = pad_vec(make_vector_field('kappa', dim),dim_subset)

        fluxes = self.flux(w, kappa)

        # Boundary conditions
        q_bc_stressfree = BoundarizeOperator(self.boundaryconditions_tag['stressfree'])(q)
        q_bc_stressfree_null = BoundarizeOperator(self.boundaryconditions_tag['stressfree'])(0)
        q_bc_fixed = BoundarizeOperator(self.boundaryconditions_tag['fixed'])(q)
        q_bc_fixed_null = BoundarizeOperator(self.boundaryconditions_tag['fixed'])(0)

        all_tags_and_bcs = [
                (self.boundaryconditions_tag['stressfree'], q_bc_stressfree, q_bc_stressfree_null),
                (self.boundaryconditions_tag['fixed'], q_bc_fixed, q_bc_fixed_null)
                           ]

        bdry_tag_state_flux = [(tag, bc, self.bdry_flux(bc, bc_null, tag))
                               for tag, bc, bc_null in all_tags_and_bcs]

        # Entire operator
        nabla = make_nabla(dim)
        res_q = (numpy.dot(nabla, fluxes) + InverseMassOperator()
                 * (self.flux_num(q, fluxes, bdry_tag_state_flux)))
        res_q = self.add_sources(res_q)

        F2 = self.F2(w)
        P = self.P(q)
        v = self.v(q)
        if dim == 1:
            F = [P[0],v[0]]
        elif dim == 2:
            F = [P[0],P[2],v[0],v[1],
                 P[2],P[1],v[1],v[0]]
        elif dim == 3:
            F = [P[0],P[5],P[4],v[0],v[2],v[1],
                 P[5],P[1],P[3],v[1],v[2],v[0],
                 P[4],P[3],P[2],v[2],v[1],v[0]]
        else:
            raise ValueError("Invalid dimension")

        res_f2 = numpy.zeros(self.len_f2, dtype=object)
        for i in range(dim):
            for j in range(dim*2):
                res_f2[i*dim*2+j] = (-1)*F2[i*dim*2+j]*alpha[i]-sigma[i]/kappa[i]*(F2[i*dim*2+j]+F[i*dim*2+j])

        return join_fields(res_q, res_f2)
Ejemplo n.º 3
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_vector_field(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 hedge.optemplate import BoundarizeOperator
        bdrize_op = BoundarizeOperator(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"))
    def op_template(self):
        q = make_vector_field('q', self.len_q)
        fluxes = self.flux(q)

        # Boundary conditions
        q_bc_stressfree = BoundarizeOperator(self.boundaryconditions_tag['stressfree'])(q)
        q_bc_stressfree_null = BoundarizeOperator(self.boundaryconditions_tag['stressfree'])(0)
        q_bc_fixed = BoundarizeOperator(self.boundaryconditions_tag['fixed'])(q)
        q_bc_fixed_null = BoundarizeOperator(self.boundaryconditions_tag['fixed'])(0)

        all_tags_and_bcs = [
                (self.boundaryconditions_tag['stressfree'], q_bc_stressfree, q_bc_stressfree_null),
                (self.boundaryconditions_tag['fixed'], q_bc_fixed, q_bc_fixed_null)
                           ]

        bdry_tag_state_flux = [(tag, bc, self.bdry_flux(bc, bc_null, tag))
                               for tag, bc, bc_null in all_tags_and_bcs]

        # Entire operator
        nabla = make_nabla(self.dimensions)

        result = (numpy.dot(nabla, fluxes) + InverseMassOperator()
                  * (self.flux_num(q, fluxes, bdry_tag_state_flux)))
        result = self.add_sources(result)
        return result
Ejemplo n.º 5
0
 def noslip_state(self, state):
     from hedge.optemplate import make_normal
     state0 = join_fields(
         make_vector_field("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")
Ejemplo n.º 6
0
    def bind_characteristic_velocity(self, discr):
        state = make_vector_field("q", self.dimensions+2)

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

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

        return do
Ejemplo n.º 7
0
    def get_conservative_boundary_conditions(self):
        state = self.state()

        from hedge.optemplate import BoundarizeOperator
        return {
                self.supersonic_inflow_tag:
                make_vector_field("bc_q_supersonic_in", self.dimensions+2),
                self.supersonic_outflow_tag:
                BoundarizeOperator(self.supersonic_outflow_tag)(
                            (state)),
                self.wall_tag: self.wall_state(state),
                }
Ejemplo n.º 8
0
    def op_template(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 hedge.optemplate.primitives import CFunction
        sqrt = CFunction("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 hedge.flux.tools import make_lax_friedrichs_flux
        from hedge.optemplate.operators import InverseMassOperator

        from hedge.optemplate.tools import make_stiffness_t

        primitive_bcs_as_quad_conservative = dict(
                (tag, self.primitive_to_conservative(to_bdry_quad(bc)))
                for tag, bc in 
                self.get_primitive_boundary_conditions().iteritems())

        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_vector_field("source_vect", len(self.state())),
                    # extra field for speed
                    0)

        return result
Ejemplo n.º 9
0
 def state(self):
     return make_vector_field("q", self.dimensions+2)