예제 #1
0
파일: advection.py 프로젝트: majosm/grudge
    def sym_operator(self):
        u = sym.var("u")

        def flux(pair):
            return sym.project(pair.dd, face_dd)(self.flux(pair))

        face_dd = sym.DOFDesc(sym.FACE_RESTR_ALL, self.quad_tag)
        boundary_dd = sym.DOFDesc(sym.BTAG_ALL, self.quad_tag)
        quad_dd = sym.DOFDesc(sym.DTAG_VOLUME_ALL, self.quad_tag)

        to_quad = sym.project(sym.DD_VOLUME, quad_dd)
        stiff_t_op = sym.stiffness_t(self.ambient_dim,
                dd_in=quad_dd, dd_out=sym.DD_VOLUME)

        quad_v = to_quad(self.v)
        quad_u = to_quad(u)

        return sym.InverseMassOperator()(
                sum(stiff_t_op[n](quad_u * quad_v[n])
                    for n in range(self.ambient_dim))
                - sym.FaceMassOperator(face_dd, sym.DD_VOLUME)(
                    flux(sym.int_tpair(u, self.quad_tag))
                    + flux(sym.bv_tpair(boundary_dd, u, self.inflow_u))

                    # FIXME: Add back support for inflow/outflow tags
                    #+ flux(sym.bv_tpair(self.inflow_tag, u, bc_in))
                    #+ flux(sym.bv_tpair(self.outflow_tag, u, bc_out))
                ))
예제 #2
0
    def sym_operator(self):
        u = sym.var("u")

        # boundary conditions -------------------------------------------------
        bc_in = self.inflow_u

        all_faces_dd = sym.DOFDesc(sym.FACE_RESTR_ALL, self.quad_tag)
        boundary_dd = sym.DOFDesc(sym.BTAG_ALL, self.quad_tag)

        def flux(pair):
            return sym.interp(pair.dd, all_faces_dd)(
                    self.flux(pair))

        quad_dd = sym.DOFDesc("vol", self.quad_tag)

        to_quad = sym.interp("vol", quad_dd)

        stiff_t = sym.stiffness_t(self.ambient_dim, quad_dd, "vol")
        quad_v = to_quad(self.v)
        quad_u = to_quad(u)

        return sym.InverseMassOperator()(
                (stiff_t[0](quad_u * quad_v[0]) + stiff_t[1](quad_u * quad_v[1]))
                - sym.FaceMassOperator(all_faces_dd, "vol")(
                    flux(sym.int_tpair(u, self.quad_tag))
                    + flux(sym.bv_tpair(boundary_dd, u, bc_in))

                    # FIXME: Add back support for inflow/outflow tags
                    #+ flux(sym.bv_tpair(self.inflow_tag, u, bc_in))
                    #+ flux(sym.bv_tpair(self.outflow_tag, u, bc_out))
                ))
예제 #3
0
파일: em.py 프로젝트: majosm/grudge
    def sym_operator(self, w=None):
        """The full operator template - the high level description of
        the Maxwell operator.

        Combines the relevant operator templates for spatial
        derivatives, flux, boundary conditions etc.
        """
        from grudge.tools import count_subset
        w = sym.make_sym_array("w", count_subset(self.get_eh_subset()))

        elec_components = count_subset(self.get_eh_subset()[0:3])
        mag_components = count_subset(self.get_eh_subset()[3:6])

        if self.fixed_material:
            # need to check this
            material_divisor = ([self.epsilon] * elec_components +
                                [self.mu] * mag_components)

        tags_and_bcs = [
            (self.pec_tag, self.pec_bc(w)),
            (self.pmc_tag, self.pmc_bc(w)),
            (self.absorb_tag, self.absorbing_bc(w)),
            (self.incident_tag, self.incident_bc(w)),
        ]

        def flux(pair):
            return sym.project(pair.dd, "all_faces")(self.flux(pair))

        return (-self.local_derivatives(w) - sym.InverseMassOperator()
                (sym.FaceMassOperator()(flux(sym.int_tpair(w)) + sum(
                    flux(sym.bv_tpair(tag, w, bc))
                    for tag, bc in tags_and_bcs)))) / material_divisor
예제 #4
0
    def sym_operator(self):
        from grudge.dof_desc import DOFDesc, DD_VOLUME, DTAG_VOLUME_ALL
        from meshmode.discretization.connection import FACE_RESTR_ALL

        u = sym.var("u")

        def flux(pair):
            return sym.project(pair.dd, face_dd)(self.flux(pair))

        face_dd = DOFDesc(FACE_RESTR_ALL, self.quad_tag)
        quad_dd = DOFDesc(DTAG_VOLUME_ALL, self.quad_tag)

        to_quad = sym.project(DD_VOLUME, quad_dd)
        stiff_t_op = sym.stiffness_t(self.ambient_dim,
                                     dd_in=quad_dd,
                                     dd_out=DD_VOLUME)

        quad_v = to_quad(self.v)
        quad_u = to_quad(u)

        return sym.InverseMassOperator()(
            sum(stiff_t_op[n](quad_u * quad_v[n])
                for n in range(self.ambient_dim)) -
            sym.FaceMassOperator(face_dd, DD_VOLUME)
            (flux(sym.int_tpair(u, self.quad_tag))))
예제 #5
0
    def sym_operator(self):
        from grudge.dof_desc import DOFDesc, DD_VOLUME, DTAG_VOLUME_ALL
        from meshmode.mesh import BTAG_ALL
        from meshmode.discretization.connection import FACE_RESTR_ALL

        u = sym.var("u")

        def flux(pair):
            return sym.project(pair.dd, face_dd)(self.flux(pair))

        face_dd = DOFDesc(FACE_RESTR_ALL, self.quad_tag)
        boundary_dd = DOFDesc(BTAG_ALL, self.quad_tag)
        quad_dd = DOFDesc(DTAG_VOLUME_ALL, self.quad_tag)

        to_quad = sym.project(DD_VOLUME, quad_dd)
        stiff_t_op = sym.stiffness_t(self.ambient_dim,
                                     dd_in=quad_dd,
                                     dd_out=DD_VOLUME)

        quad_v = to_quad(self.v)
        quad_u = to_quad(u)

        return sym.InverseMassOperator()(
            sum(stiff_t_op[n](quad_u * quad_v[n])
                for n in range(self.ambient_dim)) -
            sym.FaceMassOperator(face_dd, DD_VOLUME)(
                flux(sym.int_tpair(u, self.quad_tag)) +
                flux(sym.bv_tpair(boundary_dd, u, self.inflow_u))

                # FIXME: Add back support for inflow/outflow tags
                #+ flux(sym.bv_tpair(self.inflow_tag, u, bc_in))
                #+ flux(sym.bv_tpair(self.outflow_tag, u, bc_out))
            ))
예제 #6
0
    def sym_operator(self):
        d = self.ambient_dim

        w = sym.make_sym_array("w", d + 1)
        u = w[0]
        v = w[1:]

        # boundary conditions -------------------------------------------------

        # dirichlet BCs -------------------------------------------------------
        dir_u = sym.cse(sym.interp("vol", self.dirichlet_tag)(u))
        dir_v = sym.cse(sym.interp("vol", self.dirichlet_tag)(v))
        if self.dirichlet_bc_f:
            # FIXME
            from warnings import warn
            warn("Inhomogeneous Dirichlet conditions on the wave equation "
                 "are still having issues.")

            dir_g = sym.Field("dir_bc_u")
            dir_bc = join_fields(2 * dir_g - dir_u, dir_v)
        else:
            dir_bc = join_fields(-dir_u, dir_v)

        dir_bc = sym.cse(dir_bc, "dir_bc")

        # neumann BCs ---------------------------------------------------------
        neu_u = sym.cse(sym.interp("vol", self.neumann_tag)(u))
        neu_v = sym.cse(sym.interp("vol", self.neumann_tag)(v))
        neu_bc = sym.cse(join_fields(neu_u, -neu_v), "neu_bc")

        # radiation BCs -------------------------------------------------------
        rad_normal = sym.normal(self.radiation_tag, d)

        rad_u = sym.cse(sym.interp("vol", self.radiation_tag)(u))
        rad_v = sym.cse(sym.interp("vol", self.radiation_tag)(v))

        rad_bc = sym.cse(
            join_fields(
                0.5 * (rad_u - self.sign * np.dot(rad_normal, rad_v)), 0.5 *
                rad_normal * (np.dot(rad_normal, rad_v) - self.sign * rad_u)),
            "rad_bc")

        # entire operator -----------------------------------------------------
        def flux(pair):
            return sym.interp(pair.dd, "all_faces")(self.flux(pair))

        result = sym.InverseMassOperator()(
            join_fields(-self.c *
                        np.dot(sym.stiffness_t(self.ambient_dim), v), -self.c *
                        (sym.stiffness_t(self.ambient_dim) * u)) -
            sym.FaceMassOperator()
            (flux(sym.int_tpair(w)) +
             flux(sym.bv_tpair(self.dirichlet_tag, w, dir_bc)) +
             flux(sym.bv_tpair(self.neumann_tag, w, neu_bc)) +
             flux(sym.bv_tpair(self.radiation_tag, w, rad_bc))))

        result[0] += self.source_f

        return result
예제 #7
0
def v_dot_n_tpair(velocity, dd=None):
    if dd is None:
        dd = sym.DOFDesc(sym.FACE_RESTR_INTERIOR)

    ambient_dim = len(velocity)
    normal = sym.normal(dd.with_qtag(None), ambient_dim, dim=ambient_dim - 2)

    return sym.int_tpair(velocity.dot(normal),
                         qtag=dd.quadrature_tag,
                         from_dd=dd.with_qtag(None))
예제 #8
0
def get_strong_wave_op_with_discr_direct(cl_ctx, dims=2, order=4):
    from meshmode.mesh.generation import generate_regular_rect_mesh
    mesh = generate_regular_rect_mesh(a=(-0.5, ) * dims,
                                      b=(0.5, ) * dims,
                                      n=(16, ) * dims)

    logger.debug("%d elements", mesh.nelements)

    discr = DGDiscretizationWithBoundaries(cl_ctx, mesh, order=order)

    source_center = np.array([0.1, 0.22, 0.33])[:dims]
    source_width = 0.05
    source_omega = 3

    sym_x = sym.nodes(mesh.dim)
    sym_source_center_dist = sym_x - source_center
    sym_t = sym.ScalarVariable("t")

    from meshmode.mesh import BTAG_ALL

    c = -0.1
    sign = -1

    w = sym.make_sym_array("w", dims + 1)
    u = w[0]
    v = w[1:]

    source_f = (
        sym.sin(source_omega * sym_t) *
        sym.exp(-np.dot(sym_source_center_dist, sym_source_center_dist) /
                source_width**2))

    rad_normal = sym.normal(BTAG_ALL, dims)

    rad_u = sym.cse(sym.interp("vol", BTAG_ALL)(u))
    rad_v = sym.cse(sym.interp("vol", BTAG_ALL)(v))

    rad_bc = sym.cse(
        sym.join_fields(
            0.5 * (rad_u - sign * np.dot(rad_normal, rad_v)),
            0.5 * rad_normal * (np.dot(rad_normal, rad_v) - sign * rad_u)),
        "rad_bc")

    sym_operator = (
        -sym.join_fields(-c * np.dot(sym.nabla(dims), v) - source_f, -c *
                         (sym.nabla(dims) * u)) + sym.InverseMassOperator()(
                             sym.FaceMassOperator()
                             (dg_flux(c, sym.int_tpair(w)) +
                              dg_flux(c, sym.bv_tpair(BTAG_ALL, w, rad_bc)))))

    return (sym_operator, discr)
예제 #9
0
def v_dot_n_tpair(velocity, dd=None):
    from grudge.dof_desc import DOFDesc
    from meshmode.discretization.connection import FACE_RESTR_INTERIOR

    if dd is None:
        dd = DOFDesc(FACE_RESTR_INTERIOR)

    ambient_dim = len(velocity)
    normal = sym.normal(dd.with_discr_tag(None),
                        ambient_dim,
                        dim=ambient_dim - 2)

    return sym.int_tpair(velocity.dot(normal),
                         qtag=dd.discretization_tag,
                         from_dd=dd.with_discr_tag(None))
예제 #10
0
    def sym_operator(self):
        u = sym.var("u")

        def flux(pair):
            return sym.project(pair.dd, "all_faces")(self.flux(pair))

        return (-self.v.dot(
            sym.nabla(self.ambient_dim) * u
        ) + sym.InverseMassOperator()(
            sym.FaceMassOperator()(
                flux(sym.int_tpair(u)) +
                flux(sym.bv_tpair(sym.BTAG_ALL, u, self.inflow_u))

                # FIXME: Add back support for inflow/outflow tags
                #+ flux(sym.bv_tpair(self.inflow_tag, u, bc_in))
                #+ flux(sym.bv_tpair(self.outflow_tag, u, bc_out))
            )))
예제 #11
0
    def sym_operator(self):
        u = sym.var("u")

        def flux(pair):
            return sym.project(pair.dd, "all_faces")(self.flux(pair))

        bc_in = self.inflow_u
        # bc_out = sym.project(sym.DD_VOLUME, self.outflow_tag)(u)

        return sym.InverseMassOperator()(
            np.dot(self.v,
                   sym.stiffness_t(self.ambient_dim) * u) -
            sym.FaceMassOperator()(
                flux(sym.int_tpair(u)) +
                flux(sym.bv_tpair(sym.BTAG_ALL, u, bc_in))

                # FIXME: Add back support for inflow/outflow tags
                #+ flux(sym.bv_tpair(self.inflow_tag, u, bc_in))
                #+ flux(sym.bv_tpair(self.outflow_tag, u, bc_out))
            ))
예제 #12
0
    def sym_operator(self):
        u = sym.var("u")

        # boundary conditions -------------------------------------------------
        bc_in = self.inflow_u
        # bc_out = sym.interp("vol", self.outflow_tag)(u)

        def flux(pair):
            return sym.interp(pair.dd, "all_faces")(
                    self.flux(pair))

        return sym.InverseMassOperator()(
                np.dot(
                    self.v, sym.stiffness_t(self.ambient_dim)*u)
                - sym.FaceMassOperator()(
                    flux(sym.int_tpair(u))
                    + flux(sym.bv_tpair(sym.BTAG_ALL, u, bc_in))

                    # FIXME: Add back support for inflow/outflow tags
                    #+ flux(sym.bv_tpair(self.inflow_tag, u, bc_in))
                    #+ flux(sym.bv_tpair(self.outflow_tag, u, bc_out))
                    ))
예제 #13
0
    def sym_operator(self):
        u = sym.var("u")

        def flux(pair):
            return sym.project(pair.dd, face_dd)(self.flux(pair))

        face_dd = sym.DOFDesc(sym.FACE_RESTR_ALL, self.quad_tag)
        quad_dd = sym.DOFDesc(sym.DTAG_VOLUME_ALL, self.quad_tag)

        to_quad = sym.project(sym.DD_VOLUME, quad_dd)
        stiff_t_op = sym.stiffness_t(self.ambient_dim,
                                     dd_in=quad_dd,
                                     dd_out=sym.DD_VOLUME)

        quad_v = to_quad(self.v)
        quad_u = to_quad(u)

        return sym.InverseMassOperator()(
            sum(stiff_t_op[n](quad_u * quad_v[n])
                for n in range(self.ambient_dim)) -
            sym.FaceMassOperator(face_dd, sym.DD_VOLUME)
            (flux(sym.int_tpair(u, self.quad_tag))))