def main(ctx_factory, dim=2, order=4, visualize=False): cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) # {{{ parameters # domain [-d/2, d/2]^dim d = 1.0 # number of points in each dimension npoints = 20 # grid spacing h = d / npoints # cfl dt_factor = 2.0 # final time final_time = 1.0 # compute number of steps dt = dt_factor * h / order**2 nsteps = int(final_time // dt) + 1 dt = final_time / nsteps + 1.0e-15 # velocity field c = np.array([0.5] * dim) norm_c = la.norm(c) # flux flux_type = "central" # }}} # {{{ discretization from meshmode.mesh.generation import generate_box_mesh mesh = generate_box_mesh( [np.linspace(-d / 2, d / 2, npoints) for _ in range(dim)], order=order) from grudge import DiscretizationCollection discr = DiscretizationCollection(actx, mesh, order=order) # }}} # {{{ symbolic operators def f(x): return sym.sin(3 * x) def u_analytic(x): t = sym.var("t", dof_desc.DD_SCALAR) return f(-np.dot(c, x) / norm_c + t * norm_c) from grudge.models.advection import WeakAdvectionOperator op = WeakAdvectionOperator(c, inflow_u=u_analytic(sym.nodes(dim, BTAG_ALL)), flux_type=flux_type) bound_op = bind(discr, op.sym_operator()) u = bind(discr, u_analytic(sym.nodes(dim)))(actx, t=0) def rhs(t, u): return bound_op(t=t, u=u) # }}} # {{{ time stepping from grudge.shortcuts import set_up_rk4 dt_stepper = set_up_rk4("u", dt, u, rhs) plot = Plotter(actx, discr, order, visualize=visualize, ylim=[-1.1, 1.1]) norm = bind(discr, sym.norm(2, sym.var("u"))) step = 0 norm_u = 0.0 for event in dt_stepper.run(t_end=final_time): if not isinstance(event, dt_stepper.StateComputed): continue if step % 10 == 0: norm_u = norm(u=event.state_component) plot(event, "fld-weak-%04d" % step) step += 1 logger.info("[%04d] t = %.5f |u| = %.5e", step, event.t, norm_u)
def main(ctx_factory, dim=2, order=4, visualize=False): cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext( queue, allocator=cl_tools.MemoryPool(cl_tools.ImmediateAllocator(queue)), force_device_scalars=True, ) # {{{ parameters # domain [-d/2, d/2]^dim d = 1.0 # number of points in each dimension npoints = 20 # final time final_time = 1.0 # velocity field c = np.array([0.5] * dim) norm_c = la.norm(c) # flux flux_type = "central" # }}} # {{{ discretization from meshmode.mesh.generation import generate_box_mesh mesh = generate_box_mesh( [np.linspace(-d / 2, d / 2, npoints) for _ in range(dim)], order=order) from grudge import DiscretizationCollection dcoll = DiscretizationCollection(actx, mesh, order=order) # }}} # {{{ weak advection operator def f(x): return actx.np.sin(3 * x) def u_analytic(x, t=0): return f(-np.dot(c, x) / norm_c + t * norm_c) from grudge.models.advection import WeakAdvectionOperator adv_operator = WeakAdvectionOperator( dcoll, c, inflow_u=lambda t: u_analytic(thaw(dcoll.nodes(dd=BTAG_ALL), actx), t=t), flux_type=flux_type) nodes = thaw(dcoll.nodes(), actx) u = u_analytic(nodes, t=0) def rhs(t, u): return adv_operator.operator(t, u) dt = actx.to_numpy( adv_operator.estimate_rk4_timestep(actx, dcoll, fields=u)) logger.info("Timestep size: %g", dt) # }}} # {{{ time stepping from grudge.shortcuts import set_up_rk4 dt_stepper = set_up_rk4("u", dt, u, rhs) plot = Plotter(actx, dcoll, order, visualize=visualize, ylim=[-1.1, 1.1]) step = 0 norm_u = 0.0 for event in dt_stepper.run(t_end=final_time): if not isinstance(event, dt_stepper.StateComputed): continue if step % 10 == 0: norm_u = actx.to_numpy(op.norm(dcoll, event.state_component, 2)) plot(event, "fld-weak-%04d" % step) step += 1 logger.info("[%04d] t = %.5f |u| = %.5e", step, event.t, norm_u) # NOTE: These are here to ensure the solution is bounded for the # time interval specified assert norm_u < 1
def main(write_output=True, flux_type_arg="upwind"): from grudge.tools import mem_checkpoint from math import sin, cos, pi, sqrt from math import floor from grudge.backends import guess_run_context rcon = guess_run_context() def f(x): return sin(pi*x) def u_analytic(x, el, t): return f((-numpy.dot(v, x)/norm_v+t*norm_v)) def boundary_tagger(vertices, el, face_nr, all_v): if numpy.dot(el.face_normals[face_nr], v) < 0: return ["inflow"] else: return ["outflow"] dim = 2 if dim == 1: v = numpy.array([1]) if rcon.is_head_rank: from grudge.mesh.generator import make_uniform_1d_mesh mesh = make_uniform_1d_mesh(0, 2, 10, periodic=True) elif dim == 2: v = numpy.array([2,0]) if rcon.is_head_rank: from grudge.mesh.generator import make_disk_mesh mesh = make_disk_mesh(boundary_tagger=boundary_tagger) elif dim == 3: v = numpy.array([0,0,1]) if rcon.is_head_rank: from grudge.mesh.generator import make_cylinder_mesh, make_ball_mesh, make_box_mesh mesh = make_cylinder_mesh(max_volume=0.04, height=2, boundary_tagger=boundary_tagger, periodic=False, radial_subdivisions=32) else: raise RuntimeError("bad number of dimensions") norm_v = la.norm(v) if rcon.is_head_rank: mesh_data = rcon.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() if dim != 1: mesh_data = mesh_data.reordered_by("cuthill") discr = rcon.make_discretization(mesh_data, order=4) vis_discr = discr from grudge.visualization import VtkVisualizer if write_output: vis = VtkVisualizer(vis_discr, rcon, "fld") # operator setup ---------------------------------------------------------- from grudge.data import \ ConstantGivenFunction, \ TimeConstantGivenFunction, \ TimeDependentGivenFunction from grudge.models.advection import StrongAdvectionOperator, WeakAdvectionOperator op = WeakAdvectionOperator(v, inflow_u=TimeDependentGivenFunction(u_analytic), flux_type=flux_type_arg) u = discr.interpolate_volume_function(lambda x, el: u_analytic(x, el, 0)) # timestep setup ---------------------------------------------------------- from grudge.timestep.runge_kutta import LSRK4TimeStepper stepper = LSRK4TimeStepper() if rcon.is_head_rank: print("%d elements" % len(discr.mesh.elements)) # diagnostics setup ------------------------------------------------------- from logpyle import LogManager, \ add_general_quantities, \ add_simulation_quantities, \ add_run_info if write_output: log_file_name = "advection.dat" else: log_file_name = None logmgr = LogManager(log_file_name, "w", rcon.communicator) add_run_info(logmgr) add_general_quantities(logmgr) add_simulation_quantities(logmgr) discr.add_instrumentation(logmgr) stepper.add_instrumentation(logmgr) from grudge.log import Integral, LpNorm u_getter = lambda: u logmgr.add_quantity(Integral(u_getter, discr, name="int_u")) logmgr.add_quantity(LpNorm(u_getter, discr, p=1, name="l1_u")) logmgr.add_quantity(LpNorm(u_getter, discr, name="l2_u")) logmgr.add_watches(["step.max", "t_sim.max", "l2_u", "t_step.max"]) # timestep loop ----------------------------------------------------------- rhs = op.bind(discr) try: from grudge.timestep import times_and_steps step_it = times_and_steps( final_time=3, logmgr=logmgr, max_dt_getter=lambda t: op.estimate_timestep(discr, stepper=stepper, t=t, fields=u)) for step, t, dt in step_it: if step % 5 == 0 and write_output: visf = vis.make_file("fld-%04d" % step) vis.add_data(visf, [ ("u", discr.convert_volume(u, kind="numpy")), ], time=t, step=step) visf.close() u = stepper(u, t, dt, rhs) true_u = discr.interpolate_volume_function(lambda x, el: u_analytic(x, el, t)) print(discr.norm(u-true_u)) assert discr.norm(u-true_u) < 1e-2 finally: if write_output: vis.close() logmgr.close() discr.close()
def main(write_output=True, order=4): cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) dim = 2 from meshmode.mesh.generation import generate_regular_rect_mesh mesh = generate_regular_rect_mesh(a=(-0.5, -0.5), b=(0.5, 0.5), n=(20, 20), order=order) dt_factor = 4 h = 1 / 20 discr = DGDiscretizationWithBoundaries(cl_ctx, mesh, order=order) c = np.array([0.1, 0.1]) norm_c = la.norm(c) flux_type = "central" def f(x): return sym.sin(3 * x) def u_analytic(x): return f(-np.dot(c, x) / norm_c + sym.var("t", sym.DD_SCALAR) * norm_c) from grudge.models.advection import WeakAdvectionOperator discr = DGDiscretizationWithBoundaries(cl_ctx, mesh, order=order) op = WeakAdvectionOperator(c, inflow_u=u_analytic(sym.nodes( dim, sym.BTAG_ALL)), flux_type=flux_type) bound_op = bind(discr, op.sym_operator()) u = bind(discr, u_analytic(sym.nodes(dim)))(queue, t=0) def rhs(t, u): return bound_op(queue, t=t, u=u) final_time = 0.3 dt = dt_factor * h / order**2 nsteps = (final_time // dt) + 1 dt = final_time / nsteps + 1e-15 from grudge.shortcuts import set_up_rk4 dt_stepper = set_up_rk4("u", dt, u, rhs) from grudge.shortcuts import make_visualizer vis = make_visualizer(discr, vis_order=order) step = 0 for event in dt_stepper.run(t_end=final_time): if isinstance(event, dt_stepper.StateComputed): step += 1 #print(step, event.t, norm(queue, u=event.state_component[0])) vis.write_vtk_file("fld-weak-%04d.vtu" % step, [("u", event.state_component)])