def test_bessel(ctx_factory): cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) dims = 2 from meshmode.mesh.generation import generate_regular_rect_mesh mesh = generate_regular_rect_mesh(a=(0.1, ) * dims, b=(1.0, ) * dims, n=(8, ) * dims) discr = DGDiscretizationWithBoundaries(actx, mesh, order=3) nodes = sym.nodes(dims) r = sym.cse(sym.sqrt(nodes[0]**2 + nodes[1]**2)) # https://dlmf.nist.gov/10.6.1 n = 3 bessel_zero = (sym.bessel_j(n + 1, r) + sym.bessel_j(n - 1, r) - 2 * n / r * sym.bessel_j(n, r)) z = bind(discr, sym.norm(2, bessel_zero))(actx) assert z < 1e-15
def max_eigenvalue_expr(self): """Return the largest eigenvalue of Maxwell's equations as a hyperbolic system. """ from math import sqrt if self.fixed_material: return 1/sqrt(self.epsilon*self.mu) # a number else: import grudge.symbolic as sym return sym.NodalMax("vol")( 1 / sym.sqrt(self.epsilon * self.mu) )
def advection_weak_flux(flux_type, u, velocity): normal = sym.normal(u.dd, len(velocity)) v_dot_n = sym.cse(velocity.dot(normal), "v_dot_normal") flux_type = flux_type.lower() if flux_type == "central": return u.avg * v_dot_n elif flux_type == "lf": norm_v = sym.sqrt((velocity**2).sum()) return u.avg * v_dot_n + 0.5 * norm_v * (u.int - u.ext) elif flux_type == "upwind": u_upwind = sym.If( sym.Comparison(v_dot_n, ">", 0), u.int, # outflow u.ext # inflow ) return u_upwind * v_dot_n else: raise ValueError("flux `{}` is not implemented".format(flux_type))
def weak_flux(self, u): normal = sym.normal(u. dd, self.ambient_dim) v_dot_normal = sym.cse(self.v.dot(normal), "v_dot_normal") norm_v = sym.sqrt((self.v**2).sum()) if self.flux_type == "central": return u.avg*v_dot_normal elif self.flux_type == "lf": return u.avg*v_dot_normal + 0.5*norm_v*(u.int - u.ext) elif self.flux_type == "upwind": return ( v_dot_normal * sym.If( sym.Comparison(v_dot_normal, ">", 0), u.int, # outflow u.ext, # inflow )) else: raise ValueError("invalid flux type")
def test_bessel(actx_factory): actx = actx_factory() dims = 2 mesh = mgen.generate_regular_rect_mesh(a=(0.1, ) * dims, b=(1.0, ) * dims, nelements_per_axis=(8, ) * dims) discr = DiscretizationCollection(actx, mesh, order=3) nodes = sym.nodes(dims) r = sym.cse(sym.sqrt(nodes[0]**2 + nodes[1]**2)) # https://dlmf.nist.gov/10.6.1 n = 3 bessel_zero = (sym.bessel_j(n + 1, r) + sym.bessel_j(n - 1, r) - 2 * n / r * sym.bessel_j(n, r)) z = bind(discr, sym.norm(2, bessel_zero))(actx) assert z < 1e-15
def test_face_normal_surface(actx_factory, mesh_name): """Check that face normals are orthogonal to the surface normal""" actx = actx_factory() # {{{ geometry if mesh_name == "2-1-ellipse": from mesh_data import EllipseMeshBuilder builder = EllipseMeshBuilder(radius=3.1, aspect_ratio=2.0) elif mesh_name == "spheroid": from mesh_data import SpheroidMeshBuilder builder = SpheroidMeshBuilder() else: raise ValueError("unknown mesh name: %s" % mesh_name) mesh = builder.get_mesh(builder.resolutions[0], builder.mesh_order) discr = DiscretizationCollection(actx, mesh, order=builder.order) volume_discr = discr.discr_from_dd(dof_desc.DD_VOLUME) logger.info("ndofs: %d", volume_discr.ndofs) logger.info("nelements: %d", volume_discr.mesh.nelements) # }}} # {{{ symbolic from meshmode.discretization.connection import FACE_RESTR_INTERIOR dv = dof_desc.DD_VOLUME df = dof_desc.as_dofdesc(FACE_RESTR_INTERIOR) ambient_dim = mesh.ambient_dim dim = mesh.dim sym_surf_normal = sym.project(dv, df)(sym.surface_normal(ambient_dim, dim=dim, dd=dv).as_vector()) sym_surf_normal = sym_surf_normal / sym.sqrt(sum(sym_surf_normal**2)) sym_face_normal_i = sym.normal(df, ambient_dim, dim=dim - 1) sym_face_normal_e = sym.OppositeInteriorFaceSwap(df)(sym_face_normal_i) if mesh.ambient_dim == 3: # NOTE: there's only one face tangent in 3d sym_face_tangent = ( sym.pseudoscalar(ambient_dim, dim - 1, dd=df) / sym.area_element(ambient_dim, dim - 1, dd=df)).as_vector() # }}} # {{{ checks def _eval_error(x): return bind(discr, sym.norm(np.inf, sym.var("x", dd=df), dd=df))(actx, x=x) rtol = 1.0e-14 surf_normal = bind(discr, sym_surf_normal)(actx) face_normal_i = bind(discr, sym_face_normal_i)(actx) face_normal_e = bind(discr, sym_face_normal_e)(actx) # check interpolated surface normal is orthogonal to face normal error = _eval_error(surf_normal.dot(face_normal_i)) logger.info("error[n_dot_i]: %.5e", error) assert error < rtol # check angle between two neighboring elements error = _eval_error(face_normal_i.dot(face_normal_e) + 1.0) logger.info("error[i_dot_e]: %.5e", error) assert error > rtol # check orthogonality with face tangent if ambient_dim == 3: face_tangent = bind(discr, sym_face_tangent)(actx) error = _eval_error(face_tangent.dot(face_normal_i)) logger.info("error[t_dot_i]: %.5e", error) assert error < 5 * rtol