Exemple #1
0
    def sym_operator(self):
        from grudge.mesh import BTAG_ALL
        from grudge.symbolic import Field, BoundaryPair, \
                make_nabla, InverseMassOperator, get_flux_operator

        u = Field("u")
        bc = Field("bc")

        nabla = make_nabla(self.dimensions)
        flux_op = get_flux_operator(self.flux())

        return nabla * u - InverseMassOperator()(
            flux_op(u) + flux_op(BoundaryPair(u, bc, BTAG_ALL)))
Exemple #2
0
    def bind_characteristic_velocity(self, discr):
        from grudge.symbolic import Field
        compiled = discr.compile(
            self.characteristic_velocity_optemplate(Field("u")))

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

        return do
Exemple #3
0
    def sym_operator(self, apply_minv, u=None, dir_bc=None, neu_bc=None):
        from grudge.symbolic import Field
        if u is None:
            u = Field("u")

        result = PoissonOperator.sym_operator(self, apply_minv, u, dir_bc,
                                              neu_bc)

        if apply_minv:
            return result + self.k**2 * u
        else:
            from grudge.symbolic import MassOperator
            return result + self.k**2 * MassOperator()(u)
Exemple #4
0
    def sym_operator(self, with_sensor):
        from grudge.symbolic import (Field, make_stiffness_t, make_nabla,
                                     InverseMassOperator,
                                     ElementwiseMaxOperator, get_flux_operator)

        from grudge.symbolic.operators import (
            QuadratureGridUpsampler, QuadratureInteriorFacesGridUpsampler)

        to_quad = QuadratureGridUpsampler("quad")
        to_if_quad = QuadratureInteriorFacesGridUpsampler("quad")

        u = Field("u")
        u0 = Field("u0")

        # boundary conditions -------------------------------------------------
        minv_st = make_stiffness_t(self.dimensions)
        nabla = make_nabla(self.dimensions)
        m_inv = InverseMassOperator()

        def flux(u):
            return u**2 / 2
            #return u0*u

        emax_u = self.characteristic_velocity_optemplate(u)
        from grudge.flux.tools import make_lax_friedrichs_flux
        from pytools.obj_array import make_obj_array
        num_flux = make_lax_friedrichs_flux(
            #u0,
            to_if_quad(emax_u),
            make_obj_array([to_if_quad(u)]),
            [make_obj_array([flux(to_if_quad(u))])],
            [],
            strong=False)[0]

        from grudge.second_order import SecondDerivativeTarget

        if self.viscosity is not None or with_sensor:
            viscosity_coeff = 0
            if with_sensor:
                viscosity_coeff += Field("sensor")

            if isinstance(self.viscosity, float):
                viscosity_coeff += self.viscosity
            elif self.viscosity is None:
                pass
            else:
                raise TypeError("unsupported type of viscosity coefficient")

            # strong_form here allows IPDG to reuse the value of grad u.
            grad_tgt = SecondDerivativeTarget(self.dimensions,
                                              strong_form=True,
                                              operand=u)

            self.viscosity_scheme.grad(grad_tgt,
                                       bc_getter=None,
                                       dirichlet_tags=[],
                                       neumann_tags=[])

            div_tgt = SecondDerivativeTarget(self.dimensions,
                                             strong_form=False,
                                             operand=viscosity_coeff *
                                             grad_tgt.minv_all)

            self.viscosity_scheme.div(div_tgt,
                                      bc_getter=None,
                                      dirichlet_tags=[],
                                      neumann_tags=[])

            viscosity_bit = div_tgt.minv_all
        else:
            viscosity_bit = 0

        return m_inv((minv_st[0](flux(to_quad(u)))) - num_flux) \
                + viscosity_bit
Exemple #5
0
    def sym_operator(self, apply_minv, u=None, dir_bc=None, neu_bc=None):
        """
        :param apply_minv: :class:`bool` specifying whether to compute a complete
          divergence operator. If False, the final application of the inverse
          mass operator is skipped. This is used in :meth:`op` in order to
          reduce the scheme :math:`M^{-1} S u = f` to :math:`S u = M f`, so
          that the mass operator only needs to be applied once, when preparing
          the right hand side in :meth:`prepare_rhs`.

          :class:`grudge.models.diffusion.DiffusionOperator` needs this.
        """

        from grudge.symbolic import Field, make_sym_vector
        from grudge.second_order import SecondDerivativeTarget

        if u is None:
            u = Field("u")
        if dir_bc is None:
            dir_bc = Field("dir_bc")
        if neu_bc is None:
            neu_bc = Field("neu_bc")

        # strong_form here allows IPDG to reuse the value of grad u.
        grad_tgt = SecondDerivativeTarget(self.dimensions,
                                          strong_form=True,
                                          operand=u)

        def grad_bc_getter(tag, expr):
            assert tag == self.dirichlet_tag
            return dir_bc

        self.scheme.grad(grad_tgt,
                         bc_getter=grad_bc_getter,
                         dirichlet_tags=[self.dirichlet_tag],
                         neumann_tags=[self.neumann_tag])

        def apply_diff_tensor(v):
            if isinstance(self.diffusion_tensor, np.ndarray):
                sym_diff_tensor = self.diffusion_tensor
            else:
                sym_diff_tensor = (make_sym_vector("diffusion",
                                                   self.dimensions**2).reshape(
                                                       self.dimensions,
                                                       self.dimensions))

            return np.dot(sym_diff_tensor, v)

        div_tgt = SecondDerivativeTarget(self.dimensions,
                                         strong_form=False,
                                         operand=apply_diff_tensor(
                                             grad_tgt.minv_all))

        def div_bc_getter(tag, expr):
            if tag == self.dirichlet_tag:
                return dir_bc
            elif tag == self.neumann_tag:
                return neu_bc
            else:
                assert False, "divergence bc getter " \
                        "asked for '%s' BC for '%s'" % (tag, expr)

        self.scheme.div(div_tgt,
                        div_bc_getter,
                        dirichlet_tags=[self.dirichlet_tag],
                        neumann_tags=[self.neumann_tag])

        if apply_minv:
            return div_tgt.minv_all
        else:
            return div_tgt.all