Ejemplo n.º 1
0
    def assemble_ehpq(self, e=None, h=None, p=None, q=None, discr=None):
        if discr is None:

            def zero():
                return 0
        else:

            def zero():
                return discr.volume_zeros()

        from grudge.tools import count_subset
        e_components = count_subset(self.get_eh_subset()[0:3])
        h_components = count_subset(self.get_eh_subset()[3:6])

        def default_fld(fld, comp):
            if fld is None:
                return [zero() for i in range(comp)]
            else:
                return fld

        e = default_fld(e, e_components)
        h = default_fld(h, h_components)
        p = default_fld(p, self.dimensions)
        q = default_fld(q, self.dimensions)

        from grudge.tools import join_fields
        return join_fields(e, h, p, q)
Ejemplo n.º 2
0
Archivo: em.py Proyecto: 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
Ejemplo n.º 3
0
    def sym_operator(self, w=None):
        from grudge.tools import count_subset
        fld_cnt = count_subset(self.get_eh_subset())
        if w is None:
            from grudge.symbolic import make_sym_vector
            w = make_sym_vector("w", fld_cnt + 2 * self.dimensions)

        from grudge.tools import join_fields
        return join_fields(MaxwellOperator.sym_operator(self, w[:fld_cnt]),
                           numpy.zeros((2 * self.dimensions, ),
                                       dtype=object)) + self.pml_local_op(w)
Ejemplo n.º 4
0
    def __init__(self, dimensions, subset=None):
        self.dimensions = dimensions

        if subset is None:
            self.subset = dimensions * [
                True,
            ]
        else:
            # chop off any extra dimensions
            self.subset = subset[:dimensions]

        from grudge.tools import count_subset
        self.arg_count = count_subset(self.subset)
Ejemplo n.º 5
0
Archivo: em.py Proyecto: 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
Ejemplo n.º 6
0
    def incident_bc(self, w):
        """Flux terms for incident boundary conditions"""
        # NOTE: Untested for inhomogeneous materials, but would usually be
        # physically meaningless anyway (are there exceptions to this?)

        e, h = self.split_eh(w)

        from grudge.tools import count_subset
        fld_cnt = count_subset(self.get_eh_subset())

        from grudge.tools import is_zero
        incident_bc_data = self.incident_bc_data(self, e, h)
        if is_zero(incident_bc_data):
            return make_obj_array([0]*fld_cnt)
        else:
            return sym.cse(-incident_bc_data)