def bind(self, discr, **extra_context): "Convert the abstract operator template into compiled code." from hedge.mesh import check_bc_coverage check_bc_coverage(discr.mesh, [ self.pec_tag, self.absorb_tag, self.incident_tag]) compiled_op_template = discr.compile(self.op_template()) from hedge.tools import full_to_subset_indices e_indices = full_to_subset_indices(self.get_eh_subset()[0:3]) all_indices = full_to_subset_indices(self.get_eh_subset()) def rhs(t, w): if self.current is not None: j = self.current.volume_interpolant(t, discr)[e_indices] else: j = 0 if self.incident_bc_data is not None: incident_bc_data = self.incident_bc_data.boundary_interpolant( t, discr, self.incident_tag)[all_indices] else: incident_bc_data = 0 kwargs = {} kwargs.update(extra_context) if not self.fixed_material: kwargs["epsilon"] = self.epsilon.volume_interpolant(t, discr) kwargs["mu"] = self.mu.volume_interpolant(t, discr) return compiled_op_template( w=w, j=j, incident_bc=incident_bc_data, **kwargs) return rhs
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 hedge.optemplate import make_vector_field sig = pad_vec( make_vector_field("sigma", self.dimensions), dim_subset) sig_prime = pad_vec( make_vector_field("sigma_prime", self.dimensions), dim_subset) if self.add_decay: tau = pad_vec( make_vector_field("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 hedge.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 hedge.tools import full_to_subset_indices sub_idx = full_to_subset_indices(e_subset+h_subset+dim_subset+dim_subset) return rhs[sub_idx]
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 hedge.optemplate 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 hedge.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 hedge.tools import full_to_subset_indices sub_idx = full_to_subset_indices(e_subset + h_subset + dim_subset + dim_subset) return rhs[sub_idx]