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)
def main(dims, write_output=True, order=4): cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) from meshmode.mesh.generation import generate_regular_rect_mesh mesh = generate_regular_rect_mesh(a=(0.0, ) * dims, b=(1.0, ) * dims, nelements_per_axis=(4, ) * dims) discr = DiscretizationCollection(actx, mesh, order=order) if 0: epsilon0 = 8.8541878176e-12 # C**2 / (N m**2) mu0 = 4 * np.pi * 1e-7 # N/A**2. epsilon = 1 * epsilon0 mu = 1 * mu0 else: epsilon = 1 mu = 1 from grudge.models.em import MaxwellOperator op = MaxwellOperator(epsilon, mu, flux_type=0.5, dimensions=dims) if dims == 3: sym_mode = get_rectangular_cavity_mode(1, (1, 2, 2)) fields = bind(discr, sym_mode)(actx, t=0, epsilon=epsilon, mu=mu) else: sym_mode = get_rectangular_cavity_mode(1, (2, 3)) fields = bind(discr, sym_mode)(actx, t=0) # FIXME #dt = op.estimate_rk4_timestep(discr, fields=fields) op.check_bc_coverage(mesh) # print(sym.pretty(op.sym_operator())) bound_op = bind(discr, op.sym_operator()) def rhs(t, w): return bound_op(t=t, w=w) if mesh.dim == 2: dt = 0.004 elif mesh.dim == 3: dt = 0.002 dt_stepper = set_up_rk4("w", dt, fields, rhs) final_t = dt * STEPS nsteps = int(final_t / dt) print("dt=%g nsteps=%d" % (dt, nsteps)) from grudge.shortcuts import make_visualizer vis = make_visualizer(discr) step = 0 norm = bind(discr, sym.norm(2, sym.var("u"))) from time import time t_last_step = time() e, h = op.split_eh(fields) if 1: vis.write_vtk_file("fld-cavities-%04d.vtu" % step, [ ("e", e), ("h", h), ]) for event in dt_stepper.run(t_end=final_t): if isinstance(event, dt_stepper.StateComputed): assert event.component_id == "w" step += 1 print(step, event.t, norm(u=e[0]), norm(u=e[1]), norm(u=h[0]), norm(u=h[1]), time() - t_last_step) if step % 10 == 0: e, h = op.split_eh(event.state_component) vis.write_vtk_file("fld-cavities-%04d.vtu" % step, [ ("e", e), ("h", h), ]) t_last_step = time()
def test_convergence_maxwell(ctx_factory, order): """Test whether 3D Maxwell's actually converges""" cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) from pytools.convergence import EOCRecorder eoc_rec = EOCRecorder() dims = 3 ns = [4, 6, 8] for n in ns: from meshmode.mesh.generation import generate_regular_rect_mesh mesh = generate_regular_rect_mesh(a=(0.0, ) * dims, b=(1.0, ) * dims, n=(n, ) * dims) discr = DGDiscretizationWithBoundaries(actx, mesh, order=order) epsilon = 1 mu = 1 from grudge.models.em import get_rectangular_cavity_mode sym_mode = get_rectangular_cavity_mode(1, (1, 2, 2)) analytic_sol = bind(discr, sym_mode) fields = analytic_sol(actx, t=0, epsilon=epsilon, mu=mu) from grudge.models.em import MaxwellOperator op = MaxwellOperator(epsilon, mu, flux_type=0.5, dimensions=dims) op.check_bc_coverage(mesh) bound_op = bind(discr, op.sym_operator()) def rhs(t, w): return bound_op(t=t, w=w) dt = 0.002 final_t = dt * 5 nsteps = int(final_t / dt) from grudge.shortcuts import set_up_rk4 dt_stepper = set_up_rk4("w", dt, fields, rhs) logger.info("dt %.5e nsteps %5d", dt, nsteps) norm = bind(discr, sym.norm(2, sym.var("u"))) step = 0 for event in dt_stepper.run(t_end=final_t): if isinstance(event, dt_stepper.StateComputed): assert event.component_id == "w" esc = event.state_component step += 1 logger.debug("[%04d] t = %.5e", step, event.t) sol = analytic_sol(actx, mu=mu, epsilon=epsilon, t=step * dt) vals = [norm(u=(esc[i] - sol[i])) / norm(u=sol[i]) for i in range(5)] # noqa E501 total_error = sum(vals) eoc_rec.add_data_point(1.0 / n, total_error) logger.info( "\n%s", eoc_rec.pretty_print(abscissa_label="h", error_label="L2 Error")) assert eoc_rec.order_estimate() > order