def __call__(self): max_op = self.fields.maxwell_op h = self.fields.h b = max_op.mu * h from hedge.tools import ptwise_dot energy_density = 1/2*(ptwise_dot(1, 1, h, b)) return self.fields.discr.integral(energy_density)
def __call__(self): max_op = self.fields.maxwell_op e = self.fields.e d = max_op.epsilon * e from hedge.tools import ptwise_dot energy_density = 1/2*(ptwise_dot(1, 1, e, d)) return self.fields.discr.integral(energy_density)
def max_eigenvalue(self, t, fields=None, discr=None): # Gives the max eigenvalue of a vector of eigenvalues. # As the velocities of each node is stored in the velocity-vector-field # a pointwise dot product of this vector has to be taken to get the # magnitude of the velocity at each node. From this vector the maximum # values limits the timestep. from hedge.tools import ptwise_dot v = self.advec_v.volume_interpolant(t, discr) return discr.nodewise_max(ptwise_dot(1, 1, v, v)**0.5)
def op_template(self, with_sensor=False): # {{{ operator preliminaries ------------------------------------------ from hedge.optemplate import (Field, BoundaryPair, get_flux_operator, make_stiffness_t, InverseMassOperator, make_sym_vector, ElementwiseMaxOperator, BoundarizeOperator) from hedge.optemplate.primitives import make_common_subexpression as cse from hedge.optemplate.operators import ( QuadratureGridUpsampler, QuadratureInteriorFacesGridUpsampler) to_quad = QuadratureGridUpsampler("quad") to_if_quad = QuadratureInteriorFacesGridUpsampler("quad") from hedge.tools import join_fields, \ ptwise_dot u = Field("u") v = make_sym_vector("v", self.dimensions) c = ElementwiseMaxOperator()(ptwise_dot(1, 1, v, v)) quad_u = cse(to_quad(u)) quad_v = cse(to_quad(v)) w = join_fields(u, v, c) quad_face_w = to_if_quad(w) # }}} # {{{ boundary conditions --------------------------------------------- from hedge.mesh import TAG_ALL bc_c = to_quad(BoundarizeOperator(TAG_ALL)(c)) bc_u = to_quad(Field("bc_u")) bc_v = to_quad(BoundarizeOperator(TAG_ALL)(v)) if self.bc_u_f is "None": bc_w = join_fields(0, bc_v, bc_c) else: bc_w = join_fields(bc_u, bc_v, bc_c) minv_st = make_stiffness_t(self.dimensions) m_inv = InverseMassOperator() flux_op = get_flux_operator(self.flux()) # }}} # {{{ diffusion ------------------------------------------------------- if with_sensor or ( self.diffusion_coeff is not None and self.diffusion_coeff != 0): if self.diffusion_coeff is None: diffusion_coeff = 0 else: diffusion_coeff = self.diffusion_coeff if with_sensor: diffusion_coeff += Field("sensor") from hedge.second_order import SecondDerivativeTarget # strong_form here allows IPDG to reuse the value of grad u. grad_tgt = SecondDerivativeTarget( self.dimensions, strong_form=True, operand=u) self.diffusion_scheme.grad(grad_tgt, bc_getter=None, dirichlet_tags=[], neumann_tags=[]) div_tgt = SecondDerivativeTarget( self.dimensions, strong_form=False, operand=diffusion_coeff*grad_tgt.minv_all) self.diffusion_scheme.div(div_tgt, bc_getter=None, dirichlet_tags=[], neumann_tags=[]) diffusion_part = div_tgt.minv_all else: diffusion_part = 0 # }}} to_quad = QuadratureGridUpsampler("quad") quad_u = cse(to_quad(u)) quad_v = cse(to_quad(v)) return m_inv(numpy.dot(minv_st, cse(quad_v*quad_u)) - (flux_op(quad_face_w) + flux_op(BoundaryPair(quad_face_w, bc_w, TAG_ALL)))) \ + diffusion_part
def op_template(self, with_sensor=False): # {{{ operator preliminaries ------------------------------------------ from hedge.optemplate import (Field, BoundaryPair, get_flux_operator, make_stiffness_t, InverseMassOperator, make_sym_vector, ElementwiseMaxOperator, BoundarizeOperator) from hedge.optemplate.primitives import make_common_subexpression as cse from hedge.optemplate.operators import ( QuadratureGridUpsampler, QuadratureInteriorFacesGridUpsampler) to_quad = QuadratureGridUpsampler("quad") to_if_quad = QuadratureInteriorFacesGridUpsampler("quad") from hedge.tools import join_fields, \ ptwise_dot u = Field("u") v = make_sym_vector("v", self.dimensions) c = ElementwiseMaxOperator()(ptwise_dot(1, 1, v, v)) quad_u = cse(to_quad(u)) quad_v = cse(to_quad(v)) w = join_fields(u, v, c) quad_face_w = to_if_quad(w) # }}} # {{{ boundary conditions --------------------------------------------- from hedge.mesh import TAG_ALL bc_c = to_quad(BoundarizeOperator(TAG_ALL)(c)) bc_u = to_quad(Field("bc_u")) bc_v = to_quad(BoundarizeOperator(TAG_ALL)(v)) if self.bc_u_f is "None": bc_w = join_fields(0, bc_v, bc_c) else: bc_w = join_fields(bc_u, bc_v, bc_c) minv_st = make_stiffness_t(self.dimensions) m_inv = InverseMassOperator() flux_op = get_flux_operator(self.flux()) # }}} # {{{ diffusion ------------------------------------------------------- if with_sensor or (self.diffusion_coeff is not None and self.diffusion_coeff != 0): if self.diffusion_coeff is None: diffusion_coeff = 0 else: diffusion_coeff = self.diffusion_coeff if with_sensor: diffusion_coeff += Field("sensor") from hedge.second_order import SecondDerivativeTarget # strong_form here allows IPDG to reuse the value of grad u. grad_tgt = SecondDerivativeTarget(self.dimensions, strong_form=True, operand=u) self.diffusion_scheme.grad(grad_tgt, bc_getter=None, dirichlet_tags=[], neumann_tags=[]) div_tgt = SecondDerivativeTarget(self.dimensions, strong_form=False, operand=diffusion_coeff * grad_tgt.minv_all) self.diffusion_scheme.div(div_tgt, bc_getter=None, dirichlet_tags=[], neumann_tags=[]) diffusion_part = div_tgt.minv_all else: diffusion_part = 0 # }}} to_quad = QuadratureGridUpsampler("quad") quad_u = cse(to_quad(u)) quad_v = cse(to_quad(v)) return m_inv(numpy.dot(minv_st, cse(quad_v*quad_u)) - (flux_op(quad_face_w) + flux_op(BoundaryPair(quad_face_w, bc_w, TAG_ALL)))) \ + diffusion_part
def compute_initial_condition(rcon, discr, method, state, maxwell_op, potential_bc, force_zero=False): from hedge.models.poisson import PoissonOperator from hedge.mesh import TAG_ALL, TAG_NONE from hedge.data import ConstantGivenFunction, GivenVolumeInterpolant def rel_l2_error(field, true): from hedge.tools import relative_error return relative_error(discr.norm(field - true), discr.norm(true)) mean_beta = method.mean_beta(state) gamma = method.units.gamma_from_beta(mean_beta) # see doc/notes.tm for derivation of IC def make_scaling_matrix(beta_scale, other_scale): if la.norm(mean_beta) < 1e-10: return other_scale * numpy.eye(discr.dimensions) else: beta_unit = mean_beta / la.norm(mean_beta) return ( other_scale * numpy.identity(discr.dimensions) + (beta_scale - other_scale) * numpy.outer(beta_unit, beta_unit)) poisson_op = PoissonOperator(discr.dimensions, diffusion_tensor=make_scaling_matrix( 1 / gamma**2, 1), dirichlet_tag=TAG_ALL, neumann_tag=TAG_NONE, dirichlet_bc=potential_bc) rho_prime = method.deposit_rho(state) rho_tilde = rho_prime / gamma bound_poisson = poisson_op.bind(discr) if force_zero: phi_tilde = discr.volume_zeros() else: from hedge.iterative import parallel_cg phi_tilde = -parallel_cg( rcon, -bound_poisson, bound_poisson.prepare_rhs(rho_tilde / maxwell_op.epsilon), debug=40 if "poisson" in method.debug else False, tol=1e-10) from hedge.tools import ptwise_dot from hedge.models.nd_calculus import GradientOperator e_tilde = ptwise_dot( 2, 1, make_scaling_matrix(1 / gamma, 1), GradientOperator(discr.dimensions).bind(discr)(phi_tilde)) e_prime = ptwise_dot(2, 1, make_scaling_matrix(1, gamma), e_tilde) from pyrticle.tools import make_cross_product v_e_to_h_cross = make_cross_product(method, maxwell_op, "v", "e", "h") h_prime = (1 / maxwell_op.mu) * gamma / maxwell_op.c * v_e_to_h_cross( mean_beta, e_tilde) if "ic" in method.debug: deposited_charge = discr.integral(rho_prime) real_charge = numpy.sum(state.charges) print "charge: supposed=%g deposited=%g error=%g %%" % ( real_charge, deposited_charge, 100 * abs(deposited_charge - real_charge) / abs(real_charge)) from hedge.models.nd_calculus import DivergenceOperator bound_div_op = DivergenceOperator(discr.dimensions).bind(discr) d_tilde = maxwell_op.epsilon * e_tilde d_prime = maxwell_op.epsilon * e_prime #divD_prime_ldg = bound_poisson.div(d_prime) #divD_prime_ldg2 = bound_poisson.div(d_prime, maxwell_op.epsilon*gamma*phi_tilde) from hedge.optemplate import InverseMassOperator divD_prime_ldg3 = maxwell_op.epsilon*\ (InverseMassOperator().apply(discr, bound_poisson.op(gamma*phi_tilde))) divD_prime_central = bound_div_op(d_prime) print "l2 div D_prime error central: %g" % \ rel_l2_error(divD_prime_central, rho_prime) #print "l2 div D_prime error ldg: %g" % \ #rel_l2_error(divD_prime_ldg, rho_prime) #print "l2 div D_prime error ldg with phi: %g" % \ #rel_l2_error(divD_prime_ldg2, rho_prime) print "l2 div D_prime error ldg with phi 3: %g" % \ rel_l2_error(divD_prime_ldg3, rho_prime) if "vis_files" in method.debug: from hedge.visualization import SiloVisualizer vis = SiloVisualizer(discr) visf = vis.make_file("ic") vis.add_data( visf, [ ("phi_moving", phi_tilde), ("rho_moving", rho_tilde), ("e_moving", e_tilde), ("rho_lab", rho_prime), #("divD_lab_ldg", divD_prime_ldg), #("divD_lab_ldg2", divD_prime_ldg2), #("divD_lab_ldg3", divD_prime_ldg3), ("divD_lab_central", divD_prime_central), ("e_lab", e_prime), ("h_lab", h_prime), ], ) method.add_to_vis(vis, visf, state) visf.close() return maxwell_op.assemble_fields(e=e_prime, h=h_prime, discr=discr)
def compute_initial_condition(rcon, discr, method, state, maxwell_op, potential_bc, force_zero=False): from hedge.models.poisson import PoissonOperator from hedge.mesh import TAG_ALL, TAG_NONE from hedge.data import ConstantGivenFunction, GivenVolumeInterpolant def rel_l2_error(field, true): from hedge.tools import relative_error return relative_error( discr.norm(field-true), discr.norm(true)) mean_beta = method.mean_beta(state) gamma = method.units.gamma_from_beta(mean_beta) # see doc/notes.tm for derivation of IC def make_scaling_matrix(beta_scale, other_scale): if la.norm(mean_beta) < 1e-10: return other_scale*numpy.eye(discr.dimensions) else: beta_unit = mean_beta/la.norm(mean_beta) return (other_scale*numpy.identity(discr.dimensions) + (beta_scale-other_scale)*numpy.outer(beta_unit, beta_unit)) poisson_op = PoissonOperator( discr.dimensions, diffusion_tensor=make_scaling_matrix(1/gamma**2, 1), dirichlet_tag=TAG_ALL, neumann_tag=TAG_NONE, dirichlet_bc=potential_bc) rho_prime = method.deposit_rho(state) rho_tilde = rho_prime/gamma bound_poisson = poisson_op.bind(discr) if force_zero: phi_tilde = discr.volume_zeros() else: from hedge.iterative import parallel_cg phi_tilde = -parallel_cg(rcon, -bound_poisson, bound_poisson.prepare_rhs( rho_tilde/maxwell_op.epsilon), debug=40 if "poisson" in method.debug else False, tol=1e-10) from hedge.tools import ptwise_dot from hedge.models.nd_calculus import GradientOperator e_tilde = ptwise_dot(2, 1, make_scaling_matrix(1/gamma, 1), GradientOperator(discr.dimensions).bind(discr)(phi_tilde)) e_prime = ptwise_dot(2, 1, make_scaling_matrix(1, gamma), e_tilde) from pyrticle.tools import make_cross_product v_e_to_h_cross = make_cross_product(method, maxwell_op, "v", "e", "h") h_prime = (1/maxwell_op.mu)*gamma/maxwell_op.c * v_e_to_h_cross(mean_beta, e_tilde) if "ic" in method.debug: deposited_charge = discr.integral(rho_prime) real_charge = numpy.sum(state.charges) print "charge: supposed=%g deposited=%g error=%g %%" % ( real_charge, deposited_charge, 100*abs(deposited_charge-real_charge)/abs(real_charge) ) from hedge.models.nd_calculus import DivergenceOperator bound_div_op = DivergenceOperator(discr.dimensions).bind(discr) d_tilde = maxwell_op.epsilon*e_tilde d_prime = maxwell_op.epsilon*e_prime #divD_prime_ldg = bound_poisson.div(d_prime) #divD_prime_ldg2 = bound_poisson.div(d_prime, maxwell_op.epsilon*gamma*phi_tilde) from hedge.optemplate import InverseMassOperator divD_prime_ldg3 = maxwell_op.epsilon*\ (InverseMassOperator().apply(discr, bound_poisson.op(gamma*phi_tilde))) divD_prime_central = bound_div_op(d_prime) print "l2 div D_prime error central: %g" % \ rel_l2_error(divD_prime_central, rho_prime) #print "l2 div D_prime error ldg: %g" % \ #rel_l2_error(divD_prime_ldg, rho_prime) #print "l2 div D_prime error ldg with phi: %g" % \ #rel_l2_error(divD_prime_ldg2, rho_prime) print "l2 div D_prime error ldg with phi 3: %g" % \ rel_l2_error(divD_prime_ldg3, rho_prime) if "vis_files" in method.debug: from hedge.visualization import SiloVisualizer vis = SiloVisualizer(discr) visf = vis.make_file("ic") vis.add_data(visf, [ ("phi_moving", phi_tilde), ("rho_moving", rho_tilde), ("e_moving", e_tilde), ("rho_lab", rho_prime), #("divD_lab_ldg", divD_prime_ldg), #("divD_lab_ldg2", divD_prime_ldg2), #("divD_lab_ldg3", divD_prime_ldg3), ("divD_lab_central", divD_prime_central), ("e_lab", e_prime), ("h_lab", h_prime), ], ) method.add_to_vis(vis, visf, state) visf.close() return maxwell_op.assemble_fields(e=e_prime, h=h_prime, discr=discr)