def get_rectangular_cavity_mode(E_0, mode_indices): # noqa: N803 """A rectangular TM cavity mode for a rectangle / cube with one corner at the origin and the other at (1,1[,1]).""" dims = len(mode_indices) if dims != 2 and dims != 3: raise ValueError("Improper mode_indices dimensions") import numpy factors = [n * numpy.pi for n in mode_indices] kx, ky = factors[0:2] if dims == 3: kz = factors[2] omega = numpy.sqrt(sum(f**2 for f in factors)) nodes = sym.nodes(dims) x = nodes[0] y = nodes[1] if dims == 3: z = nodes[2] sx = sym.sin(kx * x) cx = sym.cos(kx * x) sy = sym.sin(ky * y) cy = sym.cos(ky * y) if dims == 3: sz = sym.sin(kz * z) cz = sym.cos(kz * z) if dims == 2: tfac = sym.ScalarVariable("t") * omega result = flat_obj_array( 0, 0, sym.sin(kx * x) * sym.sin(ky * y) * sym.cos(tfac), # ez -ky * sym.sin(kx * x) * sym.cos(ky * y) * sym.sin(tfac) / omega, # hx kx * sym.cos(kx * x) * sym.sin(ky * y) * sym.sin(tfac) / omega, # hy 0, ) else: tdep = sym.exp(-1j * omega * sym.ScalarVariable("t")) gamma_squared = ky**2 + kx**2 result = flat_obj_array( -kx * kz * E_0 * cx * sy * sz * tdep / gamma_squared, # ex -ky * kz * E_0 * sx * cy * sz * tdep / gamma_squared, # ey E_0 * sx * sy * cz * tdep, # ez -1j * omega * ky * E_0 * sx * cy * cz * tdep / gamma_squared, # hx 1j * omega * kx * E_0 * cx * sy * cz * tdep / gamma_squared, 0, ) return result
def simple_mpi_communication_entrypoint(): cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) from meshmode.distributed import MPIMeshDistributor, get_partition_by_pymetis from meshmode.mesh import BTAG_ALL from mpi4py import MPI comm = MPI.COMM_WORLD num_parts = comm.Get_size() mesh_dist = MPIMeshDistributor(comm) if mesh_dist.is_mananger_rank(): from meshmode.mesh.generation import generate_regular_rect_mesh mesh = generate_regular_rect_mesh(a=(-1, ) * 2, b=(1, ) * 2, nelements_per_axis=(2, ) * 2) part_per_element = get_partition_by_pymetis(mesh, num_parts) local_mesh = mesh_dist.send_mesh_parts(mesh, part_per_element, num_parts) else: local_mesh = mesh_dist.receive_mesh_part() vol_discr = DiscretizationCollection(actx, local_mesh, order=5, mpi_communicator=comm) sym_x = sym.nodes(local_mesh.dim) myfunc_symb = sym.sin(np.dot(sym_x, [2, 3])) myfunc = bind(vol_discr, myfunc_symb)(actx) sym_all_faces_func = sym.cse( sym.project("vol", "all_faces")(sym.var("myfunc"))) sym_int_faces_func = sym.cse( sym.project("vol", "int_faces")(sym.var("myfunc"))) sym_bdry_faces_func = sym.cse( sym.project(BTAG_ALL, "all_faces")(sym.project("vol", BTAG_ALL)(sym.var("myfunc")))) bound_face_swap = bind( vol_discr, sym.project("int_faces", "all_faces")( sym.OppositeInteriorFaceSwap("int_faces")(sym_int_faces_func)) - (sym_all_faces_func - sym_bdry_faces_func)) hopefully_zero = bound_face_swap(myfunc=myfunc) error = actx.np.linalg.norm(hopefully_zero, ord=np.inf) print(__file__) with np.printoptions(threshold=100000000, suppress=True): logger.debug(hopefully_zero) logger.info("error: %.5e", error) assert error < 1e-14
def simple_mpi_communication_entrypoint(): cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) from meshmode.distributed import MPIMeshDistributor, get_partition_by_pymetis from mpi4py import MPI comm = MPI.COMM_WORLD num_parts = comm.Get_size() mesh_dist = MPIMeshDistributor(comm) if mesh_dist.is_mananger_rank(): from meshmode.mesh.generation import generate_regular_rect_mesh mesh = generate_regular_rect_mesh(a=(-1, ) * 2, b=(1, ) * 2, n=(3, ) * 2) part_per_element = get_partition_by_pymetis(mesh, num_parts) local_mesh = mesh_dist.send_mesh_parts(mesh, part_per_element, num_parts) else: local_mesh = mesh_dist.receive_mesh_part() vol_discr = DGDiscretizationWithBoundaries(cl_ctx, local_mesh, order=5, mpi_communicator=comm) sym_x = sym.nodes(local_mesh.dim) myfunc_symb = sym.sin(np.dot(sym_x, [2, 3])) myfunc = bind(vol_discr, myfunc_symb)(queue) sym_all_faces_func = sym.cse( sym.interp("vol", "all_faces")(sym.var("myfunc"))) sym_int_faces_func = sym.cse( sym.interp("vol", "int_faces")(sym.var("myfunc"))) sym_bdry_faces_func = sym.cse( sym.interp(sym.BTAG_ALL, "all_faces")(sym.interp("vol", sym.BTAG_ALL)(sym.var("myfunc")))) bound_face_swap = bind( vol_discr, sym.interp("int_faces", "all_faces")( sym.OppositeInteriorFaceSwap("int_faces")(sym_int_faces_func)) - (sym_all_faces_func - sym_bdry_faces_func)) # print(bound_face_swap) # 1/0 hopefully_zero = bound_face_swap(queue, myfunc=myfunc) import numpy.linalg as la error = la.norm(hopefully_zero.get()) np.set_printoptions(threshold=100000000, suppress=True) print(hopefully_zero) print(error) assert error < 1e-14
def get_strong_wave_op_with_discr(cl_ctx, dims=2, order=4): from meshmode.mesh.generation import generate_regular_rect_mesh mesh = generate_regular_rect_mesh(a=(-0.5, ) * dims, b=(0.5, ) * dims, n=(16, ) * dims) logger.debug("%d elements", mesh.nelements) discr = DGDiscretizationWithBoundaries(cl_ctx, mesh, order=order) source_center = np.array([0.1, 0.22, 0.33])[:dims] source_width = 0.05 source_omega = 3 sym_x = sym.nodes(mesh.dim) sym_source_center_dist = sym_x - source_center sym_t = sym.ScalarVariable("t") from grudge.models.wave import StrongWaveOperator from meshmode.mesh import BTAG_ALL, BTAG_NONE op = StrongWaveOperator( -0.1, dims, source_f=( sym.sin(source_omega * sym_t) * sym.exp(-np.dot(sym_source_center_dist, sym_source_center_dist) / source_width**2)), dirichlet_tag=BTAG_NONE, neumann_tag=BTAG_NONE, radiation_tag=BTAG_ALL, flux_type="upwind") op.check_bc_coverage(mesh) return (op.sym_operator(), discr)
def _get_source_term(dims): source_center = np.array([0.1, 0.22, 0.33])[:dims] source_width = 0.05 source_omega = 3 sym_x = sym.nodes(dims) sym_source_center_dist = sym_x - source_center sym_t = sym.ScalarVariable("t") return (sym.sin(source_omega * sym_t) * sym.exp(-np.dot(sym_source_center_dist, sym_source_center_dist) / source_width**2))
def get_strong_wave_op_with_discr_direct(cl_ctx, dims=2, order=4): from meshmode.mesh.generation import generate_regular_rect_mesh mesh = generate_regular_rect_mesh(a=(-0.5, ) * dims, b=(0.5, ) * dims, n=(16, ) * dims) logger.debug("%d elements", mesh.nelements) discr = DGDiscretizationWithBoundaries(cl_ctx, mesh, order=order) source_center = np.array([0.1, 0.22, 0.33])[:dims] source_width = 0.05 source_omega = 3 sym_x = sym.nodes(mesh.dim) sym_source_center_dist = sym_x - source_center sym_t = sym.ScalarVariable("t") from meshmode.mesh import BTAG_ALL c = -0.1 sign = -1 w = sym.make_sym_array("w", dims + 1) u = w[0] v = w[1:] source_f = ( sym.sin(source_omega * sym_t) * sym.exp(-np.dot(sym_source_center_dist, sym_source_center_dist) / source_width**2)) rad_normal = sym.normal(BTAG_ALL, dims) rad_u = sym.cse(sym.interp("vol", BTAG_ALL)(u)) rad_v = sym.cse(sym.interp("vol", BTAG_ALL)(v)) rad_bc = sym.cse( sym.join_fields( 0.5 * (rad_u - sign * np.dot(rad_normal, rad_v)), 0.5 * rad_normal * (np.dot(rad_normal, rad_v) - sign * rad_u)), "rad_bc") sym_operator = ( -sym.join_fields(-c * np.dot(sym.nabla(dims), v) - source_f, -c * (sym.nabla(dims) * u)) + sym.InverseMassOperator()( sym.FaceMassOperator() (dg_flux(c, sym.int_tpair(w)) + dg_flux(c, sym.bv_tpair(BTAG_ALL, w, rad_bc))))) return (sym_operator, discr)
def test_tri_diff_mat(ctx_factory, dim, order=4): """Check differentiation matrix along the coordinate axes on a disk Uses sines as the function to differentiate. """ cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) from meshmode.mesh.generation import generate_regular_rect_mesh from pytools.convergence import EOCRecorder axis_eoc_recs = [EOCRecorder() for axis in range(dim)] for n in [10, 20]: mesh = generate_regular_rect_mesh(a=(-0.5, ) * dim, b=(0.5, ) * dim, n=(n, ) * dim, order=4) discr = DGDiscretizationWithBoundaries(actx, mesh, order=4) nabla = sym.nabla(dim) for axis in range(dim): x = sym.nodes(dim) f = bind(discr, sym.sin(3 * x[axis]))(actx) df = bind(discr, 3 * sym.cos(3 * x[axis]))(actx) sym_op = nabla[axis](sym.var("f")) bound_op = bind(discr, sym_op) df_num = bound_op(f=f) linf_error = flat_norm(df_num - df, np.Inf) axis_eoc_recs[axis].add_data_point(1 / n, linf_error) for axis, eoc_rec in enumerate(axis_eoc_recs): logger.info("axis %d\n%s", axis, eoc_rec) assert eoc_rec.order_estimate() >= order
def test_tri_diff_mat(actx_factory, dim, order=4): """Check differentiation matrix along the coordinate axes on a disk Uses sines as the function to differentiate. """ actx = actx_factory() from pytools.convergence import EOCRecorder axis_eoc_recs = [EOCRecorder() for axis in range(dim)] for n in [4, 8, 16]: mesh = mgen.generate_regular_rect_mesh(a=(-0.5, ) * dim, b=(0.5, ) * dim, nelements_per_axis=(n, ) * dim, order=4) discr = DiscretizationCollection(actx, mesh, order=4) nabla = sym.nabla(dim) for axis in range(dim): x = sym.nodes(dim) f = bind(discr, sym.sin(3 * x[axis]))(actx) df = bind(discr, 3 * sym.cos(3 * x[axis]))(actx) sym_op = nabla[axis](sym.var("f")) bound_op = bind(discr, sym_op) df_num = bound_op(f=f) linf_error = actx.np.linalg.norm(df_num - df, ord=np.inf) axis_eoc_recs[axis].add_data_point(1 / n, linf_error) for axis, eoc_rec in enumerate(axis_eoc_recs): logger.info("axis %d\n%s", axis, eoc_rec) assert eoc_rec.order_estimate() > order - 0.25
def f(x): return sym.sin(3 * x)
def f(x): return sym.sin(10 * x)
def f(x): return flat_obj_array( sym.sin(3 * x[0]) + sym.cos(3 * x[1]), sym.sin(2 * x[0]) + sym.cos(x[1]))
def main(write_output=True, order=4): cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) dims = 2 from meshmode.mesh.generation import generate_regular_rect_mesh mesh = generate_regular_rect_mesh(a=(-0.5, ) * dims, b=(0.5, ) * dims, n=(16, ) * dims) if mesh.dim == 2: dt = 0.04 elif mesh.dim == 3: dt = 0.02 print("%d elements" % mesh.nelements) discr = DGDiscretizationWithBoundaries(cl_ctx, mesh, order=order) source_center = np.array([0.1, 0.22, 0.33])[:mesh.dim] source_width = 0.05 source_omega = 3 sym_x = sym.nodes(mesh.dim) sym_source_center_dist = sym_x - source_center sym_t = sym.ScalarVariable("t") from grudge.models.wave import StrongWaveOperator from meshmode.mesh import BTAG_ALL, BTAG_NONE op = StrongWaveOperator( -0.1, discr.dim, source_f=( sym.sin(source_omega * sym_t) * sym.exp(-np.dot(sym_source_center_dist, sym_source_center_dist) / source_width**2)), dirichlet_tag=BTAG_NONE, neumann_tag=BTAG_NONE, radiation_tag=BTAG_ALL, flux_type="upwind") queue = cl.CommandQueue(discr.cl_context) from pytools.obj_array import join_fields fields = join_fields(discr.zeros(queue), [discr.zeros(queue) for i in range(discr.dim)]) # 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(queue, t=t, w=w) dt_stepper = set_up_rk4("w", dt, fields, rhs) final_t = 10 nsteps = int(final_t / dt) print("dt=%g nsteps=%d" % (dt, nsteps)) from grudge.shortcuts import make_visualizer vis = make_visualizer(discr, vis_order=order) step = 0 norm = bind(discr, sym.norm(2, sym.var("u"))) from time import time t_last_step = time() 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(queue, u=event.state_component[0]), time() - t_last_step) if step % 10 == 0: vis.write_vtk_file("fld-wave-min-%04d.vtu" % step, [ ("u", event.state_component[0]), ("v", event.state_component[1:]), ]) t_last_step = time()
def mpi_communication_entrypoint(): cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) from mpi4py import MPI comm = MPI.COMM_WORLD i_local_rank = comm.Get_rank() num_parts = comm.Get_size() from meshmode.distributed import MPIMeshDistributor, get_partition_by_pymetis mesh_dist = MPIMeshDistributor(comm) dim = 2 dt = 0.04 order = 4 if mesh_dist.is_mananger_rank(): from meshmode.mesh.generation import generate_regular_rect_mesh mesh = generate_regular_rect_mesh(a=(-0.5, ) * dim, b=(0.5, ) * dim, n=(16, ) * dim) part_per_element = get_partition_by_pymetis(mesh, num_parts) local_mesh = mesh_dist.send_mesh_parts(mesh, part_per_element, num_parts) else: local_mesh = mesh_dist.receive_mesh_part() vol_discr = DGDiscretizationWithBoundaries(cl_ctx, local_mesh, order=order, mpi_communicator=comm) source_center = np.array([0.1, 0.22, 0.33])[:local_mesh.dim] source_width = 0.05 source_omega = 3 sym_x = sym.nodes(local_mesh.dim) sym_source_center_dist = sym_x - source_center sym_t = sym.ScalarVariable("t") from grudge.models.wave import StrongWaveOperator from meshmode.mesh import BTAG_ALL, BTAG_NONE op = StrongWaveOperator( -0.1, vol_discr.dim, source_f=( sym.sin(source_omega * sym_t) * sym.exp(-np.dot(sym_source_center_dist, sym_source_center_dist) / source_width**2)), dirichlet_tag=BTAG_NONE, neumann_tag=BTAG_NONE, radiation_tag=BTAG_ALL, flux_type="upwind") from pytools.obj_array import join_fields fields = join_fields( vol_discr.zeros(queue), [vol_discr.zeros(queue) for i in range(vol_discr.dim)]) # FIXME # dt = op.estimate_rk4_timestep(vol_discr, fields=fields) # FIXME: Should meshmode consider BTAG_PARTITION to be a boundary? # Fails because: "found faces without boundary conditions" # op.check_bc_coverage(local_mesh) from pytools.log import LogManager, \ add_general_quantities, \ add_run_info, \ IntervalTimer, EventCounter log_filename = None # NOTE: LogManager hangs when using a file on a shared directory. # log_filename = 'grudge_log.dat' logmgr = LogManager(log_filename, "w", comm) add_run_info(logmgr) add_general_quantities(logmgr) log_quantities =\ {"rank_data_swap_timer": IntervalTimer("rank_data_swap_timer", "Time spent evaluating RankDataSwapAssign"), "rank_data_swap_counter": EventCounter("rank_data_swap_counter", "Number of RankDataSwapAssign instructions evaluated"), "exec_timer": IntervalTimer("exec_timer", "Total time spent executing instructions"), "insn_eval_timer": IntervalTimer("insn_eval_timer", "Time spend evaluating instructions"), "future_eval_timer": IntervalTimer("future_eval_timer", "Time spent evaluating futures"), "busy_wait_timer": IntervalTimer("busy_wait_timer", "Time wasted doing busy wait")} for quantity in log_quantities.values(): logmgr.add_quantity(quantity) # print(sym.pretty(op.sym_operator())) bound_op = bind(vol_discr, op.sym_operator()) # print(bound_op) # 1/0 def rhs(t, w): val, rhs.profile_data = bound_op(queue, profile_data=rhs.profile_data, log_quantities=log_quantities, t=t, w=w) return val rhs.profile_data = {} dt_stepper = set_up_rk4("w", dt, fields, rhs) final_t = 4 nsteps = int(final_t / dt) print("rank=%d dt=%g nsteps=%d" % (i_local_rank, dt, nsteps)) # from grudge.shortcuts import make_visualizer # vis = make_visualizer(vol_discr, vis_order=order) step = 0 norm = bind(vol_discr, sym.norm(2, sym.var("u"))) from time import time t_last_step = time() logmgr.tick_before() 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(queue, u=event.state_component[0]), time() - t_last_step) # if step % 10 == 0: # vis.write_vtk_file("rank%d-fld-%04d.vtu" % (i_local_rank, step), # [("u", event.state_component[0]), # ("v", event.state_component[1:])]) t_last_step = time() logmgr.tick_after() logmgr.tick_before() logmgr.tick_after() def print_profile_data(data): print("""execute() for rank %d: \tInstruction Evaluation: %f%% \tFuture Evaluation: %f%% \tBusy Wait: %f%% \tTotal: %f seconds""" % (i_local_rank, data['insn_eval_time'] / data['total_time'] * 100, data['future_eval_time'] / data['total_time'] * 100, data['busy_wait_time'] / data['total_time'] * 100, data['total_time'])) print_profile_data(rhs.profile_data) logmgr.close() logger.debug("Rank %d exiting", i_local_rank)
def simple_wave_entrypoint(dim=2, num_elems=256, order=4, num_steps=30, log_filename="grudge.dat"): cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) from mpi4py import MPI comm = MPI.COMM_WORLD num_parts = comm.Get_size() n = int(num_elems ** (1./dim)) from meshmode.distributed import MPIMeshDistributor mesh_dist = MPIMeshDistributor(comm) if mesh_dist.is_mananger_rank(): from meshmode.mesh.generation import generate_regular_rect_mesh mesh = generate_regular_rect_mesh(a=(-0.5,)*dim, b=(0.5,)*dim, n=(n,)*dim) from pymetis import part_graph _, p = part_graph(num_parts, xadj=mesh.nodal_adjacency.neighbors_starts.tolist(), adjncy=mesh.nodal_adjacency.neighbors.tolist()) part_per_element = np.array(p) local_mesh = mesh_dist.send_mesh_parts(mesh, part_per_element, num_parts) else: local_mesh = mesh_dist.receive_mesh_part() vol_discr = DGDiscretizationWithBoundaries(cl_ctx, local_mesh, order=order, mpi_communicator=comm) source_center = np.array([0.1, 0.22, 0.33])[:local_mesh.dim] source_width = 0.05 source_omega = 3 sym_x = sym.nodes(local_mesh.dim) sym_source_center_dist = sym_x - source_center sym_t = sym.ScalarVariable("t") from grudge.models.wave import StrongWaveOperator from meshmode.mesh import BTAG_ALL, BTAG_NONE op = StrongWaveOperator(-0.1, vol_discr.dim, source_f=( sym.sin(source_omega*sym_t) * sym.exp( -np.dot(sym_source_center_dist, sym_source_center_dist) / source_width**2)), dirichlet_tag=BTAG_NONE, neumann_tag=BTAG_NONE, radiation_tag=BTAG_ALL, flux_type="upwind") from pytools.obj_array import join_fields fields = join_fields(vol_discr.zeros(queue), [vol_discr.zeros(queue) for i in range(vol_discr.dim)]) from logpyle import LogManager, \ add_general_quantities, \ add_run_info, \ IntervalTimer, EventCounter # NOTE: LogManager hangs when using a file on a shared directory. logmgr = LogManager(log_filename, "w", comm) add_run_info(logmgr) add_general_quantities(logmgr) log_quantities =\ {"rank_data_swap_timer": IntervalTimer("rank_data_swap_timer", "Time spent evaluating RankDataSwapAssign"), "rank_data_swap_counter": EventCounter("rank_data_swap_counter", "Number of RankDataSwapAssign instructions evaluated"), "exec_timer": IntervalTimer("exec_timer", "Total time spent executing instructions"), "insn_eval_timer": IntervalTimer("insn_eval_timer", "Time spend evaluating instructions"), "future_eval_timer": IntervalTimer("future_eval_timer", "Time spent evaluating futures"), "busy_wait_timer": IntervalTimer("busy_wait_timer", "Time wasted doing busy wait")} for quantity in log_quantities.values(): logmgr.add_quantity(quantity) bound_op = bind(vol_discr, op.sym_operator()) def rhs(t, w): val, rhs.profile_data = bound_op(queue, profile_data=rhs.profile_data, log_quantities=log_quantities, t=t, w=w) return val rhs.profile_data = {} dt = 0.04 dt_stepper = set_up_rk4("w", dt, fields, rhs) logmgr.tick_before() for event in dt_stepper.run(t_end=dt * num_steps): if isinstance(event, dt_stepper.StateComputed): logmgr.tick_after() logmgr.tick_before() logmgr.tick_after() def print_profile_data(data): print("""execute() for rank %d: \tInstruction Evaluation: %f%% \tFuture Evaluation: %f%% \tBusy Wait: %f%% \tTotal: %f seconds""" % (comm.Get_rank(), data['insn_eval_time'] / data['total_time'] * 100, data['future_eval_time'] / data['total_time'] * 100, data['busy_wait_time'] / data['total_time'] * 100, data['total_time'])) print_profile_data(rhs.profile_data) logmgr.close()
def main(write_output=True, order=4): cl_ctx = cl.create_some_context() 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.5,)*dims, b=(0.5,)*dims, nelements_per_axis=(20,)*dims) discr = DiscretizationCollection(actx, mesh, order=order) source_center = np.array([0.1, 0.22, 0.33])[:mesh.dim] source_width = 0.05 source_omega = 3 sym_x = sym.nodes(mesh.dim) sym_source_center_dist = sym_x - source_center sym_t = sym.ScalarVariable("t") c = sym.If(sym.Comparison( np.dot(sym_x, sym_x), "<", 0.15), np.float32(0.1), np.float32(0.2)) from grudge.models.wave import VariableCoefficientWeakWaveOperator from meshmode.mesh import BTAG_ALL, BTAG_NONE op = VariableCoefficientWeakWaveOperator(c, discr.dim, source_f=( sym.sin(source_omega*sym_t) * sym.exp( -np.dot(sym_source_center_dist, sym_source_center_dist) / source_width**2)), dirichlet_tag=BTAG_NONE, neumann_tag=BTAG_NONE, radiation_tag=BTAG_ALL, flux_type="upwind") from pytools.obj_array import flat_obj_array fields = flat_obj_array(discr.zeros(actx), [discr.zeros(actx) for i in range(discr.dim)]) op.check_bc_coverage(mesh) c_eval = bind(discr, c)(actx) bound_op = bind(discr, op.sym_operator()) def rhs(t, w): return bound_op(t=t, w=w) if mesh.dim == 2: dt = 0.04 * 0.3 elif mesh.dim == 3: dt = 0.02 * 0.1 dt_stepper = set_up_rk4("w", dt, fields, rhs) final_t = 1 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() 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=event.state_component[0]), time()-t_last_step) if step % 10 == 0: vis.write_vtk_file("fld-var-propogation-speed-%04d.vtu" % step, [ ("u", event.state_component[0]), ("v", event.state_component[1:]), ("c", c_eval), ]) t_last_step = time()
def f(x): return flat_obj_array( sym.sin(3 * x[1]) + sym.cos(3 * x[0]) + 1.0, sym.sin(2 * x[0]) + sym.cos(x[1]), 3.0 * sym.cos(x[0] / 2) + sym.cos(x[1]), )[:ambient_dim]
def main(write_output=True, order=4): cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) comm = MPI.COMM_WORLD num_parts = comm.Get_size() from meshmode.distributed import MPIMeshDistributor, get_partition_by_pymetis mesh_dist = MPIMeshDistributor(comm) if mesh_dist.is_mananger_rank(): dims = 2 from meshmode.mesh.generation import generate_regular_rect_mesh mesh = generate_regular_rect_mesh(a=(-0.5, ) * dims, b=(0.5, ) * dims, n=(16, ) * dims) print("%d elements" % mesh.nelements) part_per_element = get_partition_by_pymetis(mesh, num_parts) local_mesh = mesh_dist.send_mesh_parts(mesh, part_per_element, num_parts) del mesh else: local_mesh = mesh_dist.receive_mesh_part() discr = DGDiscretizationWithBoundaries(actx, local_mesh, order=order, mpi_communicator=comm) if local_mesh.dim == 2: dt = 0.04 elif local_mesh.dim == 3: dt = 0.02 source_center = np.array([0.1, 0.22, 0.33])[:local_mesh.dim] source_width = 0.05 source_omega = 3 sym_x = sym.nodes(local_mesh.dim) sym_source_center_dist = sym_x - source_center sym_t = sym.ScalarVariable("t") from grudge.models.wave import StrongWaveOperator from meshmode.mesh import BTAG_ALL, BTAG_NONE op = StrongWaveOperator( -0.1, discr.dim, source_f=( sym.sin(source_omega * sym_t) * sym.exp(-np.dot(sym_source_center_dist, sym_source_center_dist) / source_width**2)), dirichlet_tag=BTAG_NONE, neumann_tag=BTAG_NONE, radiation_tag=BTAG_ALL, flux_type="upwind") from pytools.obj_array import flat_obj_array fields = flat_obj_array(discr.zeros(actx), [discr.zeros(actx) for i in range(discr.dim)]) # FIXME #dt = op.estimate_rk4_timestep(discr, fields=fields) op.check_bc_coverage(local_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) dt_stepper = set_up_rk4("w", dt, fields, rhs) final_t = 10 nsteps = int(final_t / dt) print("dt=%g nsteps=%d" % (dt, nsteps)) from grudge.shortcuts import make_visualizer vis = make_visualizer(discr, vis_order=order) step = 0 norm = bind(discr, sym.norm(2, sym.var("u"))) from time import time t_last_step = time() rank = comm.Get_rank() 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=event.state_component[0]), time() - t_last_step) if step % 10 == 0: vis.write_vtk_file( "fld-wave-min-mpi-%03d-%04d.vtu" % ( rank, step, ), [ ("u", event.state_component[0]), ("v", event.state_component[1:]), ]) t_last_step = time()
def f(x): return sym.join_fields( sym.sin(3 * x[0]) + sym.cos(3 * x[1]), sym.sin(2 * x[0]) + sym.cos(x[1]))