Example #1
0
    def pml_local_op(self, w):
        sub_e, sub_h, sub_p, sub_q = self.split_ehpq(w)

        e_subset = self.get_eh_subset()[0:3]
        h_subset = self.get_eh_subset()[3:6]
        dim_subset = (True, ) * self.dimensions + (False, ) * (3 -
                                                               self.dimensions)

        def pad_vec(v, subset):
            result = numpy.zeros((3, ), dtype=object)
            result[numpy.array(subset, dtype=bool)] = v
            return result

        from grudge.symbolic import make_sym_vector
        sig = pad_vec(make_sym_vector("sigma", self.dimensions), dim_subset)
        sig_prime = pad_vec(make_sym_vector("sigma_prime", self.dimensions),
                            dim_subset)
        if self.add_decay:
            tau = pad_vec(make_sym_vector("tau", self.dimensions), dim_subset)
        else:
            tau = numpy.zeros((3, ))

        e = pad_vec(sub_e, e_subset)
        h = pad_vec(sub_h, h_subset)
        p = pad_vec(sub_p, dim_subset)
        q = pad_vec(sub_q, dim_subset)

        rhs = numpy.zeros(12, dtype=object)

        for mx in range(3):
            my = (mx + 1) % 3
            mz = (mx + 2) % 3

            from grudge.tools.mathematics import levi_civita
            assert levi_civita((mx, my, mz)) == 1

            rhs[mx] += -sig[my] / self.epsilon * (
                2 * e[mx] + p[mx]) - 2 * tau[my] / self.epsilon * e[mx]
            rhs[my] += -sig[mx] / self.epsilon * (
                2 * e[my] + p[my]) - 2 * tau[mx] / self.epsilon * e[my]
            rhs[3 +
                mz] += 1 / (self.epsilon * self.mu) * (sig_prime[mx] * q[mx] -
                                                       sig_prime[my] * q[my])

            rhs[6 + mx] += sig[my] / self.epsilon * e[mx]
            rhs[6 + my] += sig[mx] / self.epsilon * e[my]
            rhs[9 + mx] += -sig[mx] / self.epsilon * q[mx] - (e[my] + e[mz])

        from grudge.tools import full_to_subset_indices
        sub_idx = full_to_subset_indices(e_subset + h_subset + dim_subset +
                                         dim_subset)

        return rhs[sub_idx]
Example #2
0
        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)
Example #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)
Example #4
0
    def sym_operator(self):
        from grudge.mesh import BTAG_ALL
        from grudge.symbolic 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, BTAG_ALL)))
Example #5
0
 def f_bar(self):
     from grudge.symbolic import make_sym_vector
     return make_sym_vector("f_bar", len(self.method))