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
Exemplo n.º 2
0
Arquivo: em.py Projeto: felipeh/hedge
    def local_derivatives(self, w=None):
        """Template for the spatial derivatives of the relevant components of E and H"""
        e, h = self.split_eh(self.field_placeholder(w))

        def e_curl(field):
            return self.space_cross_e(nabla, field)

        def h_curl(field):
            return self.space_cross_h(nabla, field)

        from hedge.optemplate import make_nabla
        from hedge.tools import join_fields, count_subset

        nabla = make_nabla(self.dimensions)

        if self.current is not None:
            from hedge.optemplate import make_vector_field
            j = make_vector_field("j",
                    count_subset(self.get_eh_subset()[:3]))
        else:
            j = 0

        # in conservation form: u_t + A u_x = 0
        return join_fields(
                (j - h_curl(h)),
                e_curl(e)
                )
Exemplo n.º 3
0
def test_tri_diff_mat():
    """Check differentiation matrix along the coordinate axes on a disk

    Uses sines as the function to differentiate.
    """
    from hedge.mesh.generator import make_disk_mesh
    from hedge.discretization.local import TriangleDiscretization
    from math import sin, cos, sqrt

    from hedge.optemplate import make_nabla

    nabla = make_nabla(2)

    for coord in [0, 1]:
        mesh = make_disk_mesh()
        discr = discr_class(make_disk_mesh(), TriangleDiscretization(4), debug=discr_class.noninteractive_debug_flags())
        f = discr.interpolate_volume_function(lambda x, el: sin(3 * x[coord]))
        df = discr.interpolate_volume_function(lambda x, el: 3 * cos(3 * x[coord]))

        df_num = nabla[coord].apply(discr, f)
        # discr.visualize_vtk("diff-err.vtk",
        # [("f", f), ("df", df), ("df_num", df_num), ("error", error)])

        linf_error = la.norm(df_num - df, numpy.Inf)
        print linf_error
        assert linf_error < 4e-5
def test_tri_diff_mat():
    """Check differentiation matrix along the coordinate axes on a disk

    Uses sines as the function to differentiate.
    """
    from hedge.mesh.generator import make_disk_mesh
    from hedge.discretization.local import TriangleDiscretization
    from math import sin, cos

    from hedge.optemplate import make_nabla
    nabla = make_nabla(2)

    for coord in [0, 1]:
        discr = discr_class(make_disk_mesh(),
                            TriangleDiscretization(4),
                            debug=discr_class.noninteractive_debug_flags())
        f = discr.interpolate_volume_function(lambda x, el: sin(3 * x[coord]))
        df = discr.interpolate_volume_function(
            lambda x, el: 3 * cos(3 * x[coord]))

        df_num = nabla[coord].apply(discr, f)
        #discr.visualize_vtk("diff-err.vtk",
        #[("f", f), ("df", df), ("df_num", df_num), ("error", error)])

        linf_error = la.norm(df_num - df, numpy.Inf)
        print linf_error
        assert linf_error < 4e-5
    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)
Exemplo n.º 6
0
    def op_template(self):
        from hedge.mesh import TAG_ALL
        from hedge.optemplate 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, TAG_ALL)))
Exemplo n.º 7
0
    def op_template(self):
        from hedge.mesh import TAG_ALL
        from hedge.optemplate 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, TAG_ALL)))
Exemplo n.º 8
0
    def op_template(self):
        from hedge.optemplate import Field, BoundaryPair, \
                get_flux_operator, make_nabla, InverseMassOperator

        u = Field("u")
        bc_in = Field("bc_in")

        nabla = make_nabla(self.dimensions)
        m_inv = InverseMassOperator()

        flux_op = get_flux_operator(self.flux())

        return (-numpy.dot(self.v, nabla * u) + m_inv(
            flux_op(u) + flux_op(BoundaryPair(u, bc_in, self.inflow_tag))))
Exemplo n.º 9
0
    def op_template(self, w=None):
        """The full operator template - the high level description of
        the nonlinear mechanics operator.

        Combines the relevant operator templates for spatial
        derivatives, flux, boundary conditions etc.

        NOTE: Only boundary conditions allowed currently are homogenous
        dirichlet and neumann, and I'm not sure dirichlet is done 
        properly
        """
        from hedge.optemplate import InverseMassOperator, Field, \
                make_vector_field

        from hedge.tools import join_fields
        w = self.field_placeholder(w)
       
        u,v = self.split_vars(w)
        from hedge.optemplate import make_nabla

        nabla = make_nabla(self.dimensions)
        ij = 0
        F = [0,]*9
        for i in range(self.dimensions):
            for j in range(self.dimensions):
                F[ij] = nabla[j](u[i]) 
                if i == j:
                    F[ij] = F[ij] + 1
                ij = ij + 1
        
        w = join_fields(u,v,F)
        flux_w = w

        from hedge.optemplate import BoundaryPair, get_flux_operator

        flux_op = get_flux_operator(self.flux(self.beta, is_dirich=False))
        d_flux_op = get_flux_operator(self.flux(self.beta, is_dirich=True))
        
        from hedge.optemplate import make_normal, BoundarizeOperator

        dir_normal = make_normal(self.dirichlet_tag, self.dimensions)

        dir_bc = self.dirichlet_bc(w)

        return    self.local_derivatives(w) \
                - (flux_op(flux_w) + 
                   d_flux_op(BoundaryPair(flux_w, dir_bc, self.dirichlet_tag))
                  )
Exemplo n.º 10
0
 def max_eigenvalue(self, t, fields=None, discr=None):
     """Return the wave speed in the material"""
     u,v = self.split_vars(fields)
     from hedge.optemplate import make_nabla
     nabla = make_nabla(self.dimensions)
     dim = self.dimensions
     F = [0,]*dim*dim
     ij = 0
     for i in range(self.dimensions):
         for j in range(self.dimensions):
             F[ij] = nabla[i]*u[j]
             if i == j:
                 F[ij] = F[ij] + 1
             ij = ij + 1
     speed = self.material.celerity(F, self.dimensions)
     max_speed = discr.nodewise_max(speed)
     return max_speed * self.beta
Exemplo n.º 11
0
    def op_template(self):
        from hedge.optemplate import Field, BoundaryPair, \
                get_flux_operator, make_nabla, InverseMassOperator

        u = Field("u")
        bc_in = Field("bc_in")

        nabla = make_nabla(self.dimensions)
        m_inv = InverseMassOperator()

        flux_op = get_flux_operator(self.flux())

        return (
                -numpy.dot(self.v, nabla*u)
                + m_inv(
                flux_op(u)
                + flux_op(BoundaryPair(u, bc_in, self.inflow_tag))))
Exemplo n.º 12
0
    def calculate_piola(self,u=None):
        from hedge.optemplate import make_nabla
        from hedge.optemplate import make_vector_field
        
        u = make_vector_field('u', 3)

        nabla = make_nabla(self.dimensions)
        ij = 0
        F = [0,]*9
        for i in range(self.dimensions):
            for j in range(self.dimensions):
                F[ij] = nabla[i](u[j])
                if i == j:
                    F[ij] = F[ij] + 1
                ij = ij + 1
        
        return make_obj_array(self.material.stress(F, self.dimensions))
Exemplo n.º 13
0
    def local_derivatives(self, w=None):
        """Template for the spatial derivatives of the relevant components of
        :math:`E` and :math:`H`
        """

        e, h = self.split_eh(self.field_placeholder(w))

        def e_curl(field):
            return self.space_cross_e(nabla, field)

        def h_curl(field):
            return self.space_cross_h(nabla, field)

        from hedge.optemplate import make_nabla
        from hedge.tools import join_fields

        nabla = make_nabla(self.dimensions)

        # in conservation form: u_t + A u_x = 0
        return join_fields((self.current - h_curl(h)), e_curl(e))
Exemplo n.º 14
0
    def op_template(self):
        from hedge.mesh import TAG_ALL
        from hedge.optemplate import make_sym_vector, BoundaryPair, \
                get_flux_operator, make_nabla, InverseMassOperator

        nabla = make_nabla(self.dimensions)
        m_inv = InverseMassOperator()

        v = make_sym_vector("v", self.arg_count)
        bc = make_sym_vector("bc", self.arg_count)

        local_op_result = 0
        idx = 0
        for i, i_enabled in enumerate(self.subset):
            if i_enabled and i < self.dimensions:
                local_op_result += nabla[i] * v[idx]
                idx += 1

        flux_op = get_flux_operator(self.flux())

        return local_op_result - m_inv(
            flux_op(v) + flux_op(BoundaryPair(v, bc, TAG_ALL)))
Exemplo n.º 15
0
    def local_derivatives(self, w=None):
        """Template for the spatial derivatives of the relevant components of
        :math:`E` and :math:`H`
        """

        e, h = self.split_eh(self.field_placeholder(w))

        def e_curl(field):
            return self.space_cross_e(nabla, field)

        def h_curl(field):
            return self.space_cross_h(nabla, field)

        from hedge.optemplate import make_nabla
        from hedge.tools import join_fields

        nabla = make_nabla(self.dimensions)

        # in conservation form: u_t + A u_x = 0
        return join_fields(
                (self.current - h_curl(h)),
                e_curl(e)
                )
Exemplo n.º 16
0
    def op_template(self):
        from hedge.mesh import TAG_ALL
        from hedge.optemplate import make_vector_field, BoundaryPair, \
                get_flux_operator, make_nabla, InverseMassOperator

        nabla = make_nabla(self.dimensions)
        m_inv = InverseMassOperator()

        v = make_vector_field("v", self.arg_count)
        bc = make_vector_field("bc", self.arg_count)

        local_op_result = 0
        idx = 0
        for i, i_enabled in enumerate(self.subset):
            if i_enabled and i < self.dimensions:
                local_op_result += nabla[i]*v[idx]
                idx += 1

        flux_op = get_flux_operator(self.flux())

        return local_op_result - m_inv(
                flux_op(v) +
                flux_op(BoundaryPair(v, bc, TAG_ALL)))
Exemplo n.º 17
0
    def op_template(self):
        from hedge.tools import join_fields
        from hedge.optemplate import Field, make_vector_field, BoundaryPair, \
                BoundarizeOperator, make_normal, get_flux_operator, \
                make_nabla, InverseMassOperator

        w = make_vector_field("w", self.component_count)
        e, h, phi = self.split_ehphi(w)
        rho = Field("rho")

        # local part ----------------------------------------------------------
        nabla = make_nabla(self.maxwell_op.dimensions)

        # in conservation form: u_t + A u_x = 0
        # we're describing the A u_x part, the sign gets reversed
        # below.
        max_local_op = join_fields(self.maxwell_op.local_derivatives(w), 0)

        c = self.maxwell_op.c
        chi = self.chi

        hyp_local_operator = max_local_op + join_fields(
            c * chi * (nabla * phi),
            0 * h,
            c * chi * numpy.dot(nabla, e) -
            c * chi * rho / self.maxwell_op.epsilon

            # sign gets reversed below, so this is actually
            # the decay it advertises to be.
            + self.phi_decay * phi)

        # BCs -----------------------------------------------------------------
        pec_tag = self.maxwell_op.pec_tag

        pec_e = BoundarizeOperator(pec_tag)(e)
        pec_h = BoundarizeOperator(pec_tag)(h)
        pec_phi = BoundarizeOperator(pec_tag)(phi)
        pec_n = make_normal(pec_tag, self.maxwell_op.dimensions)

        bc = "prev"
        print "HYP CLEAN BC", bc
        if bc == "char":
            # see hedge/doc/maxima/eclean.mac for derivation
            pec_bc = join_fields(
                -pec_e + 3 / 2 * pec_n * numpy.dot(pec_n, pec_e) +
                1 / 2 * pec_phi * pec_n, pec_h,
                1 / 2 * (pec_phi + numpy.dot(pec_n, pec_e)))
        elif bc == "invent":
            # see hedge/doc/maxima/eclean.mac for derivation
            pec_bc = join_fields(-pec_e + 2 * pec_n * numpy.dot(pec_n, pec_e),
                                 pec_h, pec_phi)
        elif bc == "munz":
            # Munz et al
            pec_bc = join_fields(-pec_e, pec_h,
                                 pec_phi - numpy.dot(pec_n, pec_e))
        elif bc == "prev":
            # previous condition
            pec_bc = join_fields(-pec_e + 2 * pec_n * numpy.dot(pec_n, pec_e),
                                 pec_h, -pec_phi)

        # assemble operator ---------------------------------------------------
        flux_op = get_flux_operator(self.flux())
        return -hyp_local_operator + InverseMassOperator()(
            flux_op(w) + flux_op(BoundaryPair(w, pec_bc, pec_tag)))
Exemplo n.º 18
0
    def op_template(self, with_sensor=False):
        from hedge.optemplate import \
                Field, \
                make_sym_vector, \
                BoundaryPair, \
                get_flux_operator, \
                make_nabla, \
                InverseMassOperator, \
                BoundarizeOperator

        d = self.dimensions

        w = make_sym_vector("w", d+1)
        u = w[0]
        v = w[1:]

        from hedge.tools import join_fields
        flux_w = join_fields(self.c, w)

        # {{{ boundary conditions
        from hedge.tools import join_fields

        # Dirichlet
        dir_c = BoundarizeOperator(self.dirichlet_tag) * self.c
        dir_u = BoundarizeOperator(self.dirichlet_tag) * u
        dir_v = BoundarizeOperator(self.dirichlet_tag) * v

        dir_bc = join_fields(dir_c, -dir_u, dir_v)

        # Neumann
        neu_c = BoundarizeOperator(self.neumann_tag) * self.c
        neu_u = BoundarizeOperator(self.neumann_tag) * u
        neu_v = BoundarizeOperator(self.neumann_tag) * v

        neu_bc = join_fields(neu_c, neu_u, -neu_v)

        # Radiation
        from hedge.optemplate import make_normal
        rad_normal = make_normal(self.radiation_tag, d)

        rad_c = BoundarizeOperator(self.radiation_tag) * self.c
        rad_u = BoundarizeOperator(self.radiation_tag) * u
        rad_v = BoundarizeOperator(self.radiation_tag) * v

        rad_bc = join_fields(
                rad_c,
                0.5*(rad_u - self.time_sign*np.dot(rad_normal, rad_v)),
                0.5*rad_normal*(np.dot(rad_normal, rad_v) - self.time_sign*rad_u)
                )

        # }}}

        # {{{ diffusion -------------------------------------------------------
        from pytools.obj_array import with_object_array_or_scalar

        def make_diffusion(arg):
            if with_sensor or (
                    self.diffusion_coeff is not None and self.diffusion_coeff != 0):
                if self.diffusion_coeff is None:
                    diffusion_coeff = 0
                else:
                    diffusion_coeff = self.diffusion_coeff

                if with_sensor:
                    diffusion_coeff += Field("sensor")

                from hedge.second_order import SecondDerivativeTarget

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

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

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

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

                return div_tgt.minv_all
            else:
                return 0

        # }}}

        # entire operator -----------------------------------------------------
        nabla = make_nabla(d)
        flux_op = get_flux_operator(self.flux())

        return (
                - join_fields(
                    - self.time_sign*self.c*np.dot(nabla, v) - make_diffusion(u)
                    + self.source,

                    -self.time_sign*self.c*(nabla*u) - with_object_array_or_scalar(
                        make_diffusion, v)
                    )
                +
                InverseMassOperator() * (
                    flux_op(flux_w)
                    + flux_op(BoundaryPair(flux_w, dir_bc, self.dirichlet_tag))
                    + flux_op(BoundaryPair(flux_w, neu_bc, self.neumann_tag))
                    + flux_op(BoundaryPair(flux_w, rad_bc, self.radiation_tag))
                    ))
Exemplo n.º 19
0
    def op_template(self):
        from hedge.optemplate import \
                make_sym_vector, \
                BoundaryPair, \
                get_flux_operator, \
                make_nabla, \
                InverseMassOperator, \
                BoundarizeOperator

        d = self.dimensions

        w = make_sym_vector("w", d+1)
        u = w[0]
        v = w[1:]

        # boundary conditions -------------------------------------------------
        from hedge.tools import join_fields

        # dirichlet BCs -------------------------------------------------------
        from hedge.optemplate import normal, Field

        dir_u = BoundarizeOperator(self.dirichlet_tag) * u
        dir_v = BoundarizeOperator(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 = Field("dir_bc_u")
            dir_bc = join_fields(2*dir_g - dir_u, dir_v)
        else:
            dir_bc = join_fields(-dir_u, dir_v)

        # neumann BCs ---------------------------------------------------------
        neu_u = BoundarizeOperator(self.neumann_tag) * u
        neu_v = BoundarizeOperator(self.neumann_tag) * v
        neu_bc = join_fields(neu_u, -neu_v)

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

        rad_u = BoundarizeOperator(self.radiation_tag) * u
        rad_v = BoundarizeOperator(self.radiation_tag) * v

        rad_bc = 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)
                )

        # entire operator -----------------------------------------------------
        nabla = make_nabla(d)
        flux_op = get_flux_operator(self.flux())

        from hedge.tools import join_fields
        result = (
                - join_fields(
                    -self.c*np.dot(nabla, v),
                    -self.c*(nabla*u)
                    )
                +
                InverseMassOperator() * (
                    flux_op(w)
                    + flux_op(BoundaryPair(w, dir_bc, self.dirichlet_tag))
                    + flux_op(BoundaryPair(w, neu_bc, self.neumann_tag))
                    + flux_op(BoundaryPair(w, rad_bc, self.radiation_tag))
                    ))

        result[0] += self.source_f

        return result
Exemplo n.º 20
0
    def op_template(self, with_sensor):
        from hedge.optemplate import (Field, make_stiffness_t, make_nabla,
                                      InverseMassOperator,
                                      ElementwiseMaxOperator,
                                      get_flux_operator)

        from hedge.optemplate.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 hedge.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 hedge.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
Exemplo n.º 21
0
def test_2d_gauss_theorem():
    """Verify Gauss's theorem explicitly on a mesh"""

    from hedge.mesh.generator import make_disk_mesh
    from math import sin, cos, sqrt, exp, pi
    from numpy import dot

    mesh = make_disk_mesh()
    order = 2

    discr = discr_class(mesh, order=order, debug=discr_class.noninteractive_debug_flags())
    ref_discr = discr_class(mesh, order=order)

    from hedge.flux import make_normal, FluxScalarPlaceholder

    normal = make_normal(discr.dimensions)
    flux_f_ph = FluxScalarPlaceholder(0)
    one_sided_x = flux_f_ph.int * normal[0]
    one_sided_y = flux_f_ph.int * normal[1]

    def f1(x, el):
        return sin(3 * x[0]) + cos(3 * x[1])

    def f2(x, el):
        return sin(2 * x[0]) + cos(x[1])

    from hedge.discretization import ones_on_volume

    ones = ones_on_volume(discr)
    f1_v = discr.interpolate_volume_function(f1)
    f2_v = discr.interpolate_volume_function(f2)

    from hedge.optemplate import BoundaryPair, Field, make_nabla, get_flux_operator

    nabla = make_nabla(discr.dimensions)
    diff_optp = nabla[0] * Field("f1") + nabla[1] * Field("f2")

    divergence = nabla[0].apply(discr, f1_v) + nabla[1].apply(discr, f2_v)
    int_div = discr.integral(divergence)

    flux_optp = get_flux_operator(one_sided_x)(BoundaryPair(Field("f1"), Field("fz"))) + get_flux_operator(one_sided_y)(
        BoundaryPair(Field("f2"), Field("fz"))
    )

    from hedge.mesh import TAG_ALL

    bdry_val = discr.compile(flux_optp)(f1=f1_v, f2=f2_v, fz=discr.boundary_zeros(TAG_ALL))
    ref_bdry_val = ref_discr.compile(flux_optp)(f1=f1_v, f2=f2_v, fz=discr.boundary_zeros(TAG_ALL))

    boundary_int = dot(bdry_val, ones)

    if False:
        from hedge.visualization import SiloVisualizer

        vis = SiloVisualizer(discr)
        visf = vis.make_file("test")

        from hedge.tools import make_obj_array
        from hedge.mesh import TAG_ALL

        vis.add_data(
            visf,
            [
                ("bdry", bdry_val),
                ("ref_bdry", ref_bdry_val),
                ("div", divergence),
                ("f", make_obj_array([f1_v, f2_v])),
                ("n", discr.volumize_boundary_field(discr.boundary_normals(TAG_ALL), TAG_ALL)),
            ],
            expressions=[("bdiff", "bdry-ref_bdry")],
        )

        # print abs(boundary_int-int_div)

    assert abs(boundary_int - int_div) < 5e-15
Exemplo n.º 22
0
    def op_template(self):
        from hedge.optemplate import \
                make_vector_field, \
                BoundaryPair, \
                get_flux_operator, \
                make_nabla, \
                InverseMassOperator, \
                BoundarizeOperator

        d = self.dimensions

        w = make_vector_field("w", d + 1)
        u = w[0]
        v = w[1:]

        # boundary conditions -------------------------------------------------
        from hedge.tools import join_fields

        # dirichlet BCs -------------------------------------------------------
        from hedge.optemplate import make_normal, Field

        dir_normal = make_normal(self.dirichlet_tag, d)

        dir_u = BoundarizeOperator(self.dirichlet_tag) * u
        dir_v = BoundarizeOperator(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 = Field("dir_bc_u")
            dir_bc = join_fields(2 * dir_g - dir_u, dir_v)
        else:
            dir_bc = join_fields(-dir_u, dir_v)

        # neumann BCs ---------------------------------------------------------
        neu_u = BoundarizeOperator(self.neumann_tag) * u
        neu_v = BoundarizeOperator(self.neumann_tag) * v
        neu_bc = join_fields(neu_u, -neu_v)

        # radiation BCs -------------------------------------------------------
        from hedge.optemplate import make_normal
        rad_normal = make_normal(self.radiation_tag, d)

        rad_u = BoundarizeOperator(self.radiation_tag) * u
        rad_v = BoundarizeOperator(self.radiation_tag) * v

        rad_bc = join_fields(
            0.5 * (rad_u - self.sign * numpy.dot(rad_normal, rad_v)), 0.5 *
            rad_normal * (numpy.dot(rad_normal, rad_v) - self.sign * rad_u))

        # entire operator -----------------------------------------------------
        nabla = make_nabla(d)
        flux_op = get_flux_operator(self.flux())

        from hedge.tools import join_fields
        result = (
            -join_fields(-self.c * numpy.dot(nabla, v), -self.c * (nabla * u))
            + InverseMassOperator() *
            (flux_op(w) + flux_op(BoundaryPair(w, dir_bc, self.dirichlet_tag))
             + flux_op(BoundaryPair(w, neu_bc, self.neumann_tag)) + flux_op(
                 BoundaryPair(w, rad_bc, self.radiation_tag))))

        if self.source_f is not None:
            result[0] += Field("source_u")

        return result
Exemplo n.º 23
0
    def op_template(self, with_sensor):
        from hedge.optemplate import (
                Field,
                make_stiffness_t,
                make_nabla,
                InverseMassOperator,
                ElementwiseMaxOperator,
                get_flux_operator)

        from hedge.optemplate.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 hedge.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 hedge.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
Exemplo n.º 24
0
    def op_template(self):
        from hedge.tools import join_fields
        from hedge.optemplate import Field, make_vector_field, BoundaryPair, \
                BoundarizeOperator, make_normal, get_flux_operator, \
                make_nabla, InverseMassOperator

        w = make_vector_field("w", self.component_count)
        e, h, phi = self.split_ehphi(w)
        rho = Field("rho")


        # local part ----------------------------------------------------------
        nabla = make_nabla(self.maxwell_op.dimensions)

        # in conservation form: u_t + A u_x = 0
        # we're describing the A u_x part, the sign gets reversed
        # below.
        max_local_op = join_fields(self.maxwell_op.local_derivatives(w), 0)

        c = self.maxwell_op.c
        chi = self.chi

        hyp_local_operator = max_local_op + join_fields(
                c*chi*(nabla*phi),
                0*h,
                c*chi*numpy.dot(nabla, e) 
                - c*chi*rho/self.maxwell_op.epsilon

                # sign gets reversed below, so this is actually 
                # the decay it advertises to be.
                + self.phi_decay*phi
                )

        # BCs -----------------------------------------------------------------
        pec_tag = self.maxwell_op.pec_tag

        pec_e = BoundarizeOperator(pec_tag)(e)
        pec_h = BoundarizeOperator(pec_tag)(h)
        pec_phi = BoundarizeOperator(pec_tag)(phi)
        pec_n = make_normal(pec_tag, self.maxwell_op.dimensions)

        bc = "prev"
        print "HYP CLEAN BC", bc
        if bc == "char":
            # see hedge/doc/maxima/eclean.mac for derivation
            pec_bc = join_fields(
                    -pec_e
                    + 3/2 * pec_n * numpy.dot(pec_n, pec_e)
                    + 1/2 * pec_phi * pec_n ,

                    pec_h,

                    1/2*(pec_phi+numpy.dot(pec_n, pec_e))
                    )
        elif bc == "invent":
            # see hedge/doc/maxima/eclean.mac for derivation
            pec_bc = join_fields(
                    -pec_e
                    + 2 * pec_n * numpy.dot(pec_n, pec_e),
                    pec_h, 
                    pec_phi)
        elif bc == "munz":
            # Munz et al
            pec_bc = join_fields(
                    -pec_e, 
                    pec_h, 
                    pec_phi-numpy.dot(pec_n, pec_e))
        elif bc == "prev":
            # previous condition
            pec_bc = join_fields(
                    -pec_e
                    +2*pec_n * numpy.dot(pec_n, pec_e),

                    pec_h,

                    -pec_phi)

        # assemble operator ---------------------------------------------------
        flux_op = get_flux_operator(self.flux())
        return -hyp_local_operator + InverseMassOperator()(
                    flux_op(w)
                    + flux_op(BoundaryPair(w, pec_bc, pec_tag)))
Exemplo n.º 25
0
    def op_template(self, with_sensor=False):
        from hedge.optemplate import \
                Field, \
                make_vector_field, \
                BoundaryPair, \
                get_flux_operator, \
                make_nabla, \
                InverseMassOperator, \
                BoundarizeOperator

        d = self.dimensions

        w = make_vector_field("w", d + 1)
        u = w[0]
        v = w[1:]

        from hedge.tools import join_fields
        c = Field("c")
        flux_w = join_fields(c, w)

        # {{{ boundary conditions
        from hedge.flux import make_normal
        normal = make_normal(d)

        from hedge.tools import join_fields

        # Dirichlet
        dir_c = BoundarizeOperator(self.dirichlet_tag) * c
        dir_u = BoundarizeOperator(self.dirichlet_tag) * u
        dir_v = BoundarizeOperator(self.dirichlet_tag) * v

        dir_bc = join_fields(dir_c, -dir_u, dir_v)

        # Neumann
        neu_c = BoundarizeOperator(self.neumann_tag) * c
        neu_u = BoundarizeOperator(self.neumann_tag) * u
        neu_v = BoundarizeOperator(self.neumann_tag) * v

        neu_bc = join_fields(neu_c, neu_u, -neu_v)

        # Radiation
        from hedge.optemplate import make_normal
        rad_normal = make_normal(self.radiation_tag, d)

        rad_c = BoundarizeOperator(self.radiation_tag) * c
        rad_u = BoundarizeOperator(self.radiation_tag) * u
        rad_v = BoundarizeOperator(self.radiation_tag) * v

        rad_bc = join_fields(
            rad_c,
            0.5 * (rad_u - self.time_sign * numpy.dot(rad_normal, rad_v)),
            0.5 * rad_normal *
            (numpy.dot(rad_normal, rad_v) - self.time_sign * rad_u))

        # }}}

        # {{{ diffusion -------------------------------------------------------
        from pytools.obj_array import with_object_array_or_scalar

        def make_diffusion(arg):
            if with_sensor or (self.diffusion_coeff is not None
                               and self.diffusion_coeff != 0):
                if self.diffusion_coeff is None:
                    diffusion_coeff = 0
                else:
                    diffusion_coeff = self.diffusion_coeff

                if with_sensor:
                    diffusion_coeff += Field("sensor")

                from hedge.second_order import SecondDerivativeTarget

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

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

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

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

                return div_tgt.minv_all
            else:
                return 0

        # }}}

        # entire operator -----------------------------------------------------
        nabla = make_nabla(d)
        flux_op = get_flux_operator(self.flux())

        return (
            -join_fields(
                -self.time_sign * c * numpy.dot(nabla, v) - make_diffusion(u),
                -self.time_sign * c *
                (nabla * u) - with_object_array_or_scalar(make_diffusion, v)) +
            InverseMassOperator() * (flux_op(flux_w) + flux_op(
                BoundaryPair(flux_w, dir_bc, self.dirichlet_tag)) + flux_op(
                    BoundaryPair(flux_w, neu_bc, self.neumann_tag)) + flux_op(
                        BoundaryPair(flux_w, rad_bc, self.radiation_tag))))
Exemplo n.º 26
0
def test_2d_gauss_theorem():
    """Verify Gauss's theorem explicitly on a mesh"""

    from hedge.mesh.generator import make_disk_mesh
    from math import sin, cos
    from numpy import dot

    mesh = make_disk_mesh()
    order = 2

    discr = discr_class(mesh,
                        order=order,
                        debug=discr_class.noninteractive_debug_flags())
    ref_discr = discr_class(mesh, order=order)

    from hedge.flux import make_normal, FluxScalarPlaceholder

    normal = make_normal(discr.dimensions)
    flux_f_ph = FluxScalarPlaceholder(0)
    one_sided_x = flux_f_ph.int * normal[0]
    one_sided_y = flux_f_ph.int * normal[1]

    def f1(x, el):
        return sin(3 * x[0]) + cos(3 * x[1])

    def f2(x, el):
        return sin(2 * x[0]) + cos(x[1])

    from hedge.discretization import ones_on_volume
    ones = ones_on_volume(discr)
    f1_v = discr.interpolate_volume_function(f1)
    f2_v = discr.interpolate_volume_function(f2)

    from hedge.optemplate import BoundaryPair, Field, make_nabla, \
            get_flux_operator
    nabla = make_nabla(discr.dimensions)

    divergence = nabla[0].apply(discr, f1_v) + nabla[1].apply(discr, f2_v)
    int_div = discr.integral(divergence)

    flux_optp = (
        get_flux_operator(one_sided_x)(BoundaryPair(Field("f1"),
                                                    Field("fz"))) +
        get_flux_operator(one_sided_y)(BoundaryPair(Field("f2"), Field("fz"))))

    from hedge.mesh import TAG_ALL
    bdry_val = discr.compile(flux_optp)(f1=f1_v,
                                        f2=f2_v,
                                        fz=discr.boundary_zeros(TAG_ALL))
    ref_bdry_val = ref_discr.compile(flux_optp)(
        f1=f1_v, f2=f2_v, fz=discr.boundary_zeros(TAG_ALL))

    boundary_int = dot(bdry_val, ones)

    if False:
        from hedge.visualization import SiloVisualizer
        vis = SiloVisualizer(discr)
        visf = vis.make_file("test")

        from hedge.tools import make_obj_array
        from hedge.mesh import TAG_ALL
        vis.add_data(visf, [
            ("bdry", bdry_val),
            ("ref_bdry", ref_bdry_val),
            ("div", divergence),
            ("f", make_obj_array([f1_v, f2_v])),
            ("n",
             discr.volumize_boundary_field(discr.boundary_normals(TAG_ALL),
                                           TAG_ALL)),
        ],
                     expressions=[("bdiff", "bdry-ref_bdry")])

        #print abs(boundary_int-int_div)

    assert abs(boundary_int - int_div) < 5e-15