Beispiel #1
0
    def __call__(self):
        max_op = self.fields.maxwell_op

        h = self.fields.h
        b = max_op.mu * h

        from hedge.tools import ptwise_dot
        energy_density = 1/2*(ptwise_dot(1, 1, h, b))
        return self.fields.discr.integral(energy_density)
Beispiel #2
0
    def __call__(self):
        max_op = self.fields.maxwell_op

        e = self.fields.e
        d = max_op.epsilon * e

        from hedge.tools import ptwise_dot
        energy_density = 1/2*(ptwise_dot(1, 1, e, d))
        return self.fields.discr.integral(energy_density)
Beispiel #3
0
    def max_eigenvalue(self, t, fields=None, discr=None):
        # Gives the max eigenvalue of a vector of eigenvalues.
        # As the velocities of each node is stored in the velocity-vector-field
        # a pointwise dot product of this vector has to be taken to get the
        # magnitude of the velocity at each node. From this vector the maximum
        # values limits the timestep.

        from hedge.tools import ptwise_dot
        v = self.advec_v.volume_interpolant(t, discr)
        return discr.nodewise_max(ptwise_dot(1, 1, v, v)**0.5)
Beispiel #4
0
    def max_eigenvalue(self, t, fields=None, discr=None):
        # Gives the max eigenvalue of a vector of eigenvalues.
        # As the velocities of each node is stored in the velocity-vector-field
        # a pointwise dot product of this vector has to be taken to get the
        # magnitude of the velocity at each node. From this vector the maximum
        # values limits the timestep.

        from hedge.tools import ptwise_dot
        v = self.advec_v.volume_interpolant(t, discr)
        return discr.nodewise_max(ptwise_dot(1, 1, v, v)**0.5)
Beispiel #5
0
    def op_template(self, with_sensor=False):
        # {{{ operator preliminaries ------------------------------------------
        from hedge.optemplate import (Field, BoundaryPair, get_flux_operator,
                make_stiffness_t, InverseMassOperator, make_sym_vector,
                ElementwiseMaxOperator, BoundarizeOperator)

        from hedge.optemplate.primitives import make_common_subexpression as cse

        from hedge.optemplate.operators import (
                QuadratureGridUpsampler,
                QuadratureInteriorFacesGridUpsampler)

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

        from hedge.tools import join_fields, \
                                ptwise_dot

        u = Field("u")
        v = make_sym_vector("v", self.dimensions)
        c = ElementwiseMaxOperator()(ptwise_dot(1, 1, v, v))

        quad_u = cse(to_quad(u))
        quad_v = cse(to_quad(v))

        w = join_fields(u, v, c)
        quad_face_w = to_if_quad(w)
        # }}}

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

        from hedge.mesh import TAG_ALL
        bc_c = to_quad(BoundarizeOperator(TAG_ALL)(c))
        bc_u = to_quad(Field("bc_u"))
        bc_v = to_quad(BoundarizeOperator(TAG_ALL)(v))

        if self.bc_u_f is "None":
            bc_w = join_fields(0, bc_v, bc_c)
        else:
            bc_w = join_fields(bc_u, bc_v, bc_c)

        minv_st = make_stiffness_t(self.dimensions)
        m_inv = InverseMassOperator()

        flux_op = get_flux_operator(self.flux())
        # }}}

        # {{{ diffusion -------------------------------------------------------
        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 IPDG to reuse the value of grad u.
            grad_tgt = SecondDerivativeTarget(
                    self.dimensions, strong_form=True,
                    operand=u)

            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=[])

            diffusion_part = div_tgt.minv_all
        else:
            diffusion_part = 0

        # }}}

        to_quad = QuadratureGridUpsampler("quad")
        quad_u = cse(to_quad(u))
        quad_v = cse(to_quad(v))

        return m_inv(numpy.dot(minv_st, cse(quad_v*quad_u))
                - (flux_op(quad_face_w)
                    + flux_op(BoundaryPair(quad_face_w, bc_w, TAG_ALL)))) \
                            + diffusion_part
Beispiel #6
0
    def op_template(self, with_sensor=False):
        # {{{ operator preliminaries ------------------------------------------
        from hedge.optemplate import (Field, BoundaryPair, get_flux_operator,
                                      make_stiffness_t, InverseMassOperator,
                                      make_sym_vector, ElementwiseMaxOperator,
                                      BoundarizeOperator)

        from hedge.optemplate.primitives import make_common_subexpression as cse

        from hedge.optemplate.operators import (
            QuadratureGridUpsampler, QuadratureInteriorFacesGridUpsampler)

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

        from hedge.tools import join_fields, \
                                ptwise_dot

        u = Field("u")
        v = make_sym_vector("v", self.dimensions)
        c = ElementwiseMaxOperator()(ptwise_dot(1, 1, v, v))

        quad_u = cse(to_quad(u))
        quad_v = cse(to_quad(v))

        w = join_fields(u, v, c)
        quad_face_w = to_if_quad(w)
        # }}}

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

        from hedge.mesh import TAG_ALL
        bc_c = to_quad(BoundarizeOperator(TAG_ALL)(c))
        bc_u = to_quad(Field("bc_u"))
        bc_v = to_quad(BoundarizeOperator(TAG_ALL)(v))

        if self.bc_u_f is "None":
            bc_w = join_fields(0, bc_v, bc_c)
        else:
            bc_w = join_fields(bc_u, bc_v, bc_c)

        minv_st = make_stiffness_t(self.dimensions)
        m_inv = InverseMassOperator()

        flux_op = get_flux_operator(self.flux())
        # }}}

        # {{{ diffusion -------------------------------------------------------
        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 IPDG to reuse the value of grad u.
            grad_tgt = SecondDerivativeTarget(self.dimensions,
                                              strong_form=True,
                                              operand=u)

            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=[])

            diffusion_part = div_tgt.minv_all
        else:
            diffusion_part = 0

        # }}}

        to_quad = QuadratureGridUpsampler("quad")
        quad_u = cse(to_quad(u))
        quad_v = cse(to_quad(v))

        return m_inv(numpy.dot(minv_st, cse(quad_v*quad_u))
                - (flux_op(quad_face_w)
                    + flux_op(BoundaryPair(quad_face_w, bc_w, TAG_ALL)))) \
                            + diffusion_part
Beispiel #7
0
def compute_initial_condition(rcon,
                              discr,
                              method,
                              state,
                              maxwell_op,
                              potential_bc,
                              force_zero=False):
    from hedge.models.poisson import PoissonOperator
    from hedge.mesh import TAG_ALL, TAG_NONE
    from hedge.data import ConstantGivenFunction, GivenVolumeInterpolant

    def rel_l2_error(field, true):
        from hedge.tools import relative_error
        return relative_error(discr.norm(field - true), discr.norm(true))

    mean_beta = method.mean_beta(state)
    gamma = method.units.gamma_from_beta(mean_beta)

    # see doc/notes.tm for derivation of IC

    def make_scaling_matrix(beta_scale, other_scale):
        if la.norm(mean_beta) < 1e-10:
            return other_scale * numpy.eye(discr.dimensions)
        else:
            beta_unit = mean_beta / la.norm(mean_beta)
            return (
                other_scale * numpy.identity(discr.dimensions) +
                (beta_scale - other_scale) * numpy.outer(beta_unit, beta_unit))

    poisson_op = PoissonOperator(discr.dimensions,
                                 diffusion_tensor=make_scaling_matrix(
                                     1 / gamma**2, 1),
                                 dirichlet_tag=TAG_ALL,
                                 neumann_tag=TAG_NONE,
                                 dirichlet_bc=potential_bc)

    rho_prime = method.deposit_rho(state)
    rho_tilde = rho_prime / gamma

    bound_poisson = poisson_op.bind(discr)
    if force_zero:
        phi_tilde = discr.volume_zeros()
    else:
        from hedge.iterative import parallel_cg
        phi_tilde = -parallel_cg(
            rcon,
            -bound_poisson,
            bound_poisson.prepare_rhs(rho_tilde / maxwell_op.epsilon),
            debug=40 if "poisson" in method.debug else False,
            tol=1e-10)

    from hedge.tools import ptwise_dot
    from hedge.models.nd_calculus import GradientOperator
    e_tilde = ptwise_dot(
        2, 1, make_scaling_matrix(1 / gamma, 1),
        GradientOperator(discr.dimensions).bind(discr)(phi_tilde))
    e_prime = ptwise_dot(2, 1, make_scaling_matrix(1, gamma), e_tilde)

    from pyrticle.tools import make_cross_product
    v_e_to_h_cross = make_cross_product(method, maxwell_op, "v", "e", "h")
    h_prime = (1 / maxwell_op.mu) * gamma / maxwell_op.c * v_e_to_h_cross(
        mean_beta, e_tilde)

    if "ic" in method.debug:
        deposited_charge = discr.integral(rho_prime)

        real_charge = numpy.sum(state.charges)
        print "charge: supposed=%g deposited=%g error=%g %%" % (
            real_charge, deposited_charge,
            100 * abs(deposited_charge - real_charge) / abs(real_charge))

        from hedge.models.nd_calculus import DivergenceOperator

        bound_div_op = DivergenceOperator(discr.dimensions).bind(discr)

        d_tilde = maxwell_op.epsilon * e_tilde
        d_prime = maxwell_op.epsilon * e_prime

        #divD_prime_ldg = bound_poisson.div(d_prime)
        #divD_prime_ldg2 = bound_poisson.div(d_prime, maxwell_op.epsilon*gamma*phi_tilde)
        from hedge.optemplate import InverseMassOperator
        divD_prime_ldg3 = maxwell_op.epsilon*\
                (InverseMassOperator().apply(discr, bound_poisson.op(gamma*phi_tilde)))
        divD_prime_central = bound_div_op(d_prime)

        print "l2 div D_prime error central: %g" % \
                rel_l2_error(divD_prime_central, rho_prime)
        #print "l2 div D_prime error ldg: %g" % \
        #rel_l2_error(divD_prime_ldg, rho_prime)
        #print "l2 div D_prime error ldg with phi: %g" % \
        #rel_l2_error(divD_prime_ldg2, rho_prime)
        print "l2 div D_prime error ldg with phi 3: %g" % \
                rel_l2_error(divD_prime_ldg3, rho_prime)

        if "vis_files" in method.debug:
            from hedge.visualization import SiloVisualizer
            vis = SiloVisualizer(discr)
            visf = vis.make_file("ic")
            vis.add_data(
                visf,
                [
                    ("phi_moving", phi_tilde),
                    ("rho_moving", rho_tilde),
                    ("e_moving", e_tilde),
                    ("rho_lab", rho_prime),
                    #("divD_lab_ldg", divD_prime_ldg),
                    #("divD_lab_ldg2", divD_prime_ldg2),
                    #("divD_lab_ldg3", divD_prime_ldg3),
                    ("divD_lab_central", divD_prime_central),
                    ("e_lab", e_prime),
                    ("h_lab", h_prime),
                ],
            )
            method.add_to_vis(vis, visf, state)
            visf.close()

    return maxwell_op.assemble_fields(e=e_prime, h=h_prime, discr=discr)
Beispiel #8
0
def compute_initial_condition(rcon, discr, method, state,
        maxwell_op, potential_bc,
        force_zero=False):
    from hedge.models.poisson import PoissonOperator
    from hedge.mesh import TAG_ALL, TAG_NONE
    from hedge.data import ConstantGivenFunction, GivenVolumeInterpolant

    def rel_l2_error(field, true):
        from hedge.tools import relative_error
        return relative_error(
                discr.norm(field-true),
                discr.norm(true))

    mean_beta = method.mean_beta(state)
    gamma = method.units.gamma_from_beta(mean_beta)

    # see doc/notes.tm for derivation of IC

    def make_scaling_matrix(beta_scale, other_scale):
        if la.norm(mean_beta) < 1e-10:
            return other_scale*numpy.eye(discr.dimensions)
        else:
            beta_unit = mean_beta/la.norm(mean_beta)
            return (other_scale*numpy.identity(discr.dimensions)
                    + (beta_scale-other_scale)*numpy.outer(beta_unit, beta_unit))

    poisson_op = PoissonOperator(
            discr.dimensions,
            diffusion_tensor=make_scaling_matrix(1/gamma**2, 1),
            dirichlet_tag=TAG_ALL,
            neumann_tag=TAG_NONE,
            dirichlet_bc=potential_bc)

    rho_prime = method.deposit_rho(state)
    rho_tilde = rho_prime/gamma

    bound_poisson = poisson_op.bind(discr)
    if force_zero:
        phi_tilde = discr.volume_zeros()
    else:
        from hedge.iterative import parallel_cg
        phi_tilde = -parallel_cg(rcon, -bound_poisson,
                bound_poisson.prepare_rhs(
                    rho_tilde/maxwell_op.epsilon),
                debug=40 if "poisson" in method.debug else False, tol=1e-10)

    from hedge.tools import ptwise_dot
    from hedge.models.nd_calculus import GradientOperator
    e_tilde = ptwise_dot(2, 1, make_scaling_matrix(1/gamma, 1),
            GradientOperator(discr.dimensions).bind(discr)(phi_tilde))
    e_prime = ptwise_dot(2, 1, make_scaling_matrix(1, gamma), e_tilde)

    from pyrticle.tools import make_cross_product
    v_e_to_h_cross = make_cross_product(method, maxwell_op, "v", "e", "h")
    h_prime = (1/maxwell_op.mu)*gamma/maxwell_op.c * v_e_to_h_cross(mean_beta, e_tilde)

    if "ic" in method.debug:
        deposited_charge = discr.integral(rho_prime)

        real_charge = numpy.sum(state.charges)
        print "charge: supposed=%g deposited=%g error=%g %%" % (
                real_charge,
                deposited_charge,
                100*abs(deposited_charge-real_charge)/abs(real_charge)
                )

        from hedge.models.nd_calculus import DivergenceOperator

        bound_div_op = DivergenceOperator(discr.dimensions).bind(discr)

        d_tilde = maxwell_op.epsilon*e_tilde
        d_prime = maxwell_op.epsilon*e_prime

        #divD_prime_ldg = bound_poisson.div(d_prime)
        #divD_prime_ldg2 = bound_poisson.div(d_prime, maxwell_op.epsilon*gamma*phi_tilde)
        from hedge.optemplate import InverseMassOperator
        divD_prime_ldg3 = maxwell_op.epsilon*\
                (InverseMassOperator().apply(discr, bound_poisson.op(gamma*phi_tilde)))
        divD_prime_central = bound_div_op(d_prime)

        print "l2 div D_prime error central: %g" % \
                rel_l2_error(divD_prime_central, rho_prime)
        #print "l2 div D_prime error ldg: %g" % \
                #rel_l2_error(divD_prime_ldg, rho_prime)
        #print "l2 div D_prime error ldg with phi: %g" % \
                #rel_l2_error(divD_prime_ldg2, rho_prime)
        print "l2 div D_prime error ldg with phi 3: %g" % \
                rel_l2_error(divD_prime_ldg3, rho_prime)

        if "vis_files" in method.debug:
            from hedge.visualization import SiloVisualizer
            vis = SiloVisualizer(discr)
            visf = vis.make_file("ic")
            vis.add_data(visf, [
                ("phi_moving", phi_tilde),
                ("rho_moving", rho_tilde),
                ("e_moving", e_tilde),

                ("rho_lab", rho_prime),
                #("divD_lab_ldg", divD_prime_ldg),
                #("divD_lab_ldg2", divD_prime_ldg2),
                #("divD_lab_ldg3", divD_prime_ldg3),
                ("divD_lab_central", divD_prime_central),
                ("e_lab", e_prime),
                ("h_lab", h_prime),
                ],
                )
            method.add_to_vis(vis, visf, state)
            visf.close()

    return maxwell_op.assemble_fields(e=e_prime, h=h_prime, discr=discr)