def absorbing_bc(self, w=None): """Construct part of the flux operator template for 1st order absorbing boundary conditions. """ from hedge.optemplate import normal absorb_normal = normal(self.absorb_tag, self.dimensions) from hedge.optemplate import BoundarizeOperator, Field from hedge.tools import join_fields e, h = self.split_eh(self.field_placeholder(w)) if self.fixed_material: epsilon = self.epsilon mu = self.mu else: epsilon = cse( BoundarizeOperator(self.absorb_tag)(Field("epsilon"))) mu = cse( BoundarizeOperator(self.absorb_tag)(Field("mu"))) absorb_Z = (mu/epsilon)**0.5 absorb_Y = 1/absorb_Z absorb_e = BoundarizeOperator(self.absorb_tag)(e) absorb_h = BoundarizeOperator(self.absorb_tag)(h) bc = join_fields( absorb_e + 1/2*(self.space_cross_h(absorb_normal, self.space_cross_e( absorb_normal, absorb_e)) - absorb_Z*self.space_cross_h(absorb_normal, absorb_h)), absorb_h + 1/2*( self.space_cross_e(absorb_normal, self.space_cross_h( absorb_normal, absorb_h)) + absorb_Y*self.space_cross_e(absorb_normal, absorb_e))) return bc
def absorbing_bc(self, w=None): """Construct part of the flux operator template for 1st order absorbing boundary conditions. """ from hedge.optemplate import normal absorb_normal = normal(self.absorb_tag, self.dimensions) from hedge.optemplate import BoundarizeOperator, Field from hedge.tools import join_fields e, h = self.split_eh(self.field_placeholder(w)) if self.fixed_material: epsilon = self.epsilon mu = self.mu else: epsilon = cse( BoundarizeOperator(self.absorb_tag)(Field("epsilon"))) mu = cse(BoundarizeOperator(self.absorb_tag)(Field("mu"))) absorb_Z = (mu / epsilon)**0.5 absorb_Y = 1 / absorb_Z absorb_e = BoundarizeOperator(self.absorb_tag)(e) absorb_h = BoundarizeOperator(self.absorb_tag)(h) bc = join_fields( absorb_e + 1 / 2 * (self.space_cross_h(absorb_normal, self.space_cross_e(absorb_normal, absorb_e)) - absorb_Z * self.space_cross_h(absorb_normal, absorb_h)), absorb_h + 1 / 2 * (self.space_cross_e(absorb_normal, self.space_cross_h(absorb_normal, absorb_h)) + absorb_Y * self.space_cross_e(absorb_normal, absorb_e))) return bc
def op_template(self): from hedge.optemplate import \ make_sym_vector, \ BoundaryPair, \ get_flux_operator, \ make_nabla, \ InverseMassOperator, \ BoundarizeOperator d = self.dimensions w = make_sym_vector("w", d+1) u = w[0] v = w[1:] # boundary conditions ------------------------------------------------- from hedge.tools import join_fields # dirichlet BCs ------------------------------------------------------- from hedge.optemplate import normal, Field dir_u = BoundarizeOperator(self.dirichlet_tag) * u dir_v = BoundarizeOperator(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 = Field("dir_bc_u") dir_bc = join_fields(2*dir_g - dir_u, dir_v) else: dir_bc = join_fields(-dir_u, dir_v) # neumann BCs --------------------------------------------------------- neu_u = BoundarizeOperator(self.neumann_tag) * u neu_v = BoundarizeOperator(self.neumann_tag) * v neu_bc = join_fields(neu_u, -neu_v) # radiation BCs ------------------------------------------------------- rad_normal = normal(self.radiation_tag, d) rad_u = BoundarizeOperator(self.radiation_tag) * u rad_v = BoundarizeOperator(self.radiation_tag) * v rad_bc = join_fields( 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 ----------------------------------------------------- nabla = make_nabla(d) flux_op = get_flux_operator(self.flux()) from hedge.tools import join_fields result = ( - join_fields( -self.c*np.dot(nabla, v), -self.c*(nabla*u) ) + InverseMassOperator() * ( flux_op(w) + flux_op(BoundaryPair(w, dir_bc, self.dirichlet_tag)) + flux_op(BoundaryPair(w, neu_bc, self.neumann_tag)) + flux_op(BoundaryPair(w, rad_bc, self.radiation_tag)) )) result[0] += self.source_f return result