Exemplo n.º 1
0
    def operator(self, t, w):
        dcoll = self.dcoll
        u = w[0]
        v = w[1:]
        actx = u.array_context

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

        # dirichlet BCs -------------------------------------------------------
        dir_u = op.project(dcoll, "vol", self.dirichlet_tag, u)
        dir_v = op.project(dcoll, "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 = self.dirichlet_bc_f
            dir_bc = flat_obj_array(2 * dir_g - dir_u, dir_v)
        else:
            dir_bc = flat_obj_array(-dir_u, dir_v)

        # neumann BCs ---------------------------------------------------------
        neu_u = op.project(dcoll, "vol", self.neumann_tag, u)
        neu_v = op.project(dcoll, "vol", self.neumann_tag, v)
        neu_bc = flat_obj_array(neu_u, -neu_v)

        # radiation BCs -------------------------------------------------------
        rad_normal = thaw(dcoll.normal(dd=self.radiation_tag), actx)

        rad_u = op.project(dcoll, "vol", self.radiation_tag, u)
        rad_v = op.project(dcoll, "vol", self.radiation_tag, v)

        rad_bc = flat_obj_array(
            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 -----------------------------------------------------
        def flux(tpair):
            return op.project(dcoll, tpair.dd, "all_faces", self.flux(tpair))

        result = (op.inverse_mass(
            dcoll,
            flat_obj_array(-self.c * op.weak_local_div(dcoll, v),
                           -self.c * op.weak_local_grad(dcoll, u)) -
            op.face_mass(
                dcoll,
                sum(
                    flux(tpair)
                    for tpair in op.interior_trace_pairs(dcoll, w)) +
                flux(op.bv_trace_pair(dcoll, self.dirichlet_tag, w, dir_bc)) +
                flux(op.bv_trace_pair(dcoll, self.neumann_tag, w, neu_bc)) +
                flux(op.bv_trace_pair(dcoll, self.radiation_tag, w, rad_bc)))))

        result[0] = result[0] + self.source_f(actx, dcoll, t)

        return result
Exemplo n.º 2
0
    def operator(self, t, u):
        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

        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)

        dcoll = self.dcoll

        def flux(tpair):
            return op.project(dcoll, tpair.dd, face_dd, self.flux(tpair))

        def to_quad(arg):
            return op.project(dcoll, DD_VOLUME, quad_dd, arg)

        if self.inflow_u is not None:
            inflow_flux = flux(
                op.bv_trace_pair(dcoll,
                                 boundary_dd,
                                 interior=u,
                                 exterior=self.inflow_u(t)))
        else:
            inflow_flux = 0

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

        return (op.inverse_mass(
            dcoll,
            sum(
                op.weak_local_d_dx(dcoll, quad_dd, d, quad_u * quad_v[d])
                for d in range(dcoll.ambient_dim)) -
            op.face_mass(
                dcoll, face_dd,
                sum(
                    flux(quad_tpair) for quad_tpair in to_quad_int_tpairs(
                        dcoll, u, self.quad_tag)) + inflow_flux

                # FIXME: Add support for inflow/outflow tags
                # + flux(op.bv_trace_pair(dcoll,
                #                         self.inflow_tag,
                #                         interior=u,
                #                         exterior=bc_in))
                # + flux(op.bv_trace_pair(dcoll,
                #                         self.outflow_tag,
                #                         interior=u,
                #                         exterior=bc_out))
            )))
Exemplo n.º 3
0
Arquivo: em.py Projeto: sll2/grudge
    def operator(self, t, w):
        """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

        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)),
        ]

        dcoll = self.dcoll

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

        return (-self.local_derivatives(w) - op.inverse_mass(
            dcoll,
            op.face_mass(
                dcoll,
                sum(
                    flux(tpair)
                    for tpair in op.interior_trace_pairs(dcoll, w)) + sum(
                        flux(op.bv_trace_pair(dcoll, tag, w, bc))
                        for tag, bc in tags_and_bcs)))) / material_divisor
Exemplo n.º 4
0
    def operator(self, t, u):
        from meshmode.mesh import BTAG_ALL

        dcoll = self.dcoll

        def flux(tpair):
            return op.project(dcoll, tpair.dd, "all_faces", self.flux(tpair))

        if self.inflow_u is not None:
            inflow_flux = flux(
                op.bv_trace_pair(dcoll,
                                 BTAG_ALL,
                                 interior=u,
                                 exterior=self.inflow_u(t)))
        else:
            inflow_flux = 0

        return (op.inverse_mass(
            dcoll,
            np.dot(self.v, op.weak_local_grad(dcoll, u)) - op.face_mass(
                dcoll,
                sum(
                    flux(tpair)
                    for tpair in op.interior_trace_pairs(dcoll, u)) +
                inflow_flux

                # FIXME: Add support for inflow/outflow tags
                # + flux(op.bv_trace_pair(dcoll,
                #                         self.inflow_tag,
                #                         interior=u,
                #                         exterior=bc_in))
                # + flux(op.bv_trace_pair(dcoll,
                #                         self.outflow_tag,
                #                         interior=u,
                #                         exterior=bc_out))
            )))
Exemplo n.º 5
0
right_bndry = DTAG_BOUNDARY("right")

x_vol = thaw(dcoll.nodes(), actx)
x_bndry = thaw(dcoll.discr_from_dd(left_bndry).nodes(), actx)

uh = initial_condition(x_vol)

dt = 0.001
t = 0
t_final = 0.5

# timestepper loop
while t < t_final:
    # extract the left boundary trace pair
    lbnd_tpair = op.bv_trace_pair(dcoll,
                                  dd=left_bndry,
                                  interior=uh,
                                  exterior=left_boundary_condition(x_bndry, t))
    # extract the right boundary trace pair
    rbnd_tpair = op.bv_trace_pair(dcoll,
                                  dd=right_bndry,
                                  interior=uh,
                                  exterior=op.project(dcoll, "vol",
                                                      right_bndry, uh))
    # extract the trace pairs on the interior faces
    interior_tpair = op.interior_trace_pair(dcoll,
                                            uh)
    Su = op.weak_local_grad(dcoll, uh)

    lift = op.face_mass(dcoll,
                        # left boundary weak-flux terms
                        op.project(dcoll,