def get_boundaries(discr, actx, t): nodes = thaw(actx, discr.nodes()) def sym_eval(expr): return sym.EvaluationMapper({"x": nodes, "t": t})(expr) exact_u = sym_eval(sym_u) exact_grad_u = make_obj_array(sym_eval(sym.grad(dim, sym_u))) boundaries = {} for i in range(dim - 1): lower_btag = DTAG_BOUNDARY("-" + str(i)) upper_btag = DTAG_BOUNDARY("+" + str(i)) upper_grad_u = discr.project("vol", upper_btag, exact_grad_u) normal = thaw(actx, discr.normal(upper_btag)) upper_grad_u_dot_n = np.dot(upper_grad_u, normal) boundaries[lower_btag] = NeumannDiffusionBoundary(0.) boundaries[upper_btag] = NeumannDiffusionBoundary( upper_grad_u_dot_n) lower_btag = DTAG_BOUNDARY("-" + str(dim - 1)) upper_btag = DTAG_BOUNDARY("+" + str(dim - 1)) upper_u = discr.project("vol", upper_btag, exact_u) boundaries[lower_btag] = DirichletDiffusionBoundary(0.) boundaries[upper_btag] = DirichletDiffusionBoundary(upper_u) return boundaries
def get_boundaries(self, discr, actx, t): nodes = thaw(actx, discr.nodes()) sym_exact_u = self.get_solution(pmbl.make_sym_vector("x", self.dim), pmbl.var("t")) exact_u = _sym_eval(sym_exact_u, x=nodes, t=t) exact_grad_u = _sym_eval(sym.grad(self.dim, sym_exact_u), x=nodes, t=t) boundaries = {} for i in range(self.dim - 1): lower_btag = DTAG_BOUNDARY("-" + str(i)) upper_btag = DTAG_BOUNDARY("+" + str(i)) upper_grad_u = discr.project("vol", upper_btag, exact_grad_u) normal = thaw(actx, discr.normal(upper_btag)) upper_grad_u_dot_n = np.dot(upper_grad_u, normal) boundaries[lower_btag] = NeumannDiffusionBoundary(0.) boundaries[upper_btag] = NeumannDiffusionBoundary( upper_grad_u_dot_n) lower_btag = DTAG_BOUNDARY("-" + str(self.dim - 1)) upper_btag = DTAG_BOUNDARY("+" + str(self.dim - 1)) upper_u = discr.project("vol", upper_btag, exact_u) boundaries[lower_btag] = DirichletDiffusionBoundary(0.) boundaries[upper_btag] = DirichletDiffusionBoundary(upper_u) return boundaries
def get_boundaries(discr, actx, t): boundaries = {} for i in range(dim-1): boundaries[DTAG_BOUNDARY("-"+str(i))] = NeumannDiffusionBoundary(0.) boundaries[DTAG_BOUNDARY("+"+str(i))] = NeumannDiffusionBoundary(0.) boundaries[DTAG_BOUNDARY("-"+str(dim-1))] = DirichletDiffusionBoundary(0.) boundaries[DTAG_BOUNDARY("+"+str(dim-1))] = DirichletDiffusionBoundary(0.) return boundaries
def get_boundaries(self, discr, actx, t): boundaries = {} for i in range(self.dim - 1): lower_btag = DTAG_BOUNDARY("-" + str(i)) upper_btag = DTAG_BOUNDARY("+" + str(i)) boundaries[lower_btag] = NeumannDiffusionBoundary(0.) boundaries[upper_btag] = NeumannDiffusionBoundary(0.) lower_btag = DTAG_BOUNDARY("-" + str(self.dim - 1)) upper_btag = DTAG_BOUNDARY("+" + str(self.dim - 1)) boundaries[lower_btag] = DirichletDiffusionBoundary(0.) boundaries[upper_btag] = DirichletDiffusionBoundary(0.) return boundaries
def get_boundaries(discr, actx, t): nodes = thaw(actx, discr.nodes()) def sym_eval(expr): return sym.EvaluationMapper({"x": nodes, "t": t})(expr) dirichlet_lower_btag = grudge_sym.DTAG_BOUNDARY("dirichlet_lower") dirichlet_upper_btag = grudge_sym.DTAG_BOUNDARY("dirichlet_upper") neumann_lower_btag = grudge_sym.DTAG_BOUNDARY("neumann_lower") neumann_upper_btag = grudge_sym.DTAG_BOUNDARY("neumann_upper") exact_u = sym_eval(sym_u) exact_grad_u = make_obj_array(sym_eval(sym.grad(dim, sym_u))) upper_u = discr.project("vol", dirichlet_upper_btag, exact_u) upper_grad_u = discr.project("vol", neumann_upper_btag, exact_grad_u) normal = thaw(actx, discr.normal(neumann_upper_btag)) upper_grad_u_dot_n = np.dot(upper_grad_u, normal) return { dirichlet_lower_btag: DirichletDiffusionBoundary(0.), dirichlet_upper_btag: DirichletDiffusionBoundary(upper_u), neumann_lower_btag: NeumannDiffusionBoundary(0.), neumann_upper_btag: NeumannDiffusionBoundary(upper_grad_u_dot_n) }
def test_lazy_op_diffusion(op_test_data, order): """Test diffusion operator in lazy context.""" eager_actx, lazy_actx, get_discr = op_test_data discr = get_discr(order) from grudge.dof_desc import DTAG_BOUNDARY, DISCR_TAG_BASE from mirgecom.diffusion import ( diffusion_operator, DirichletDiffusionBoundary, NeumannDiffusionBoundary) boundaries = { DTAG_BOUNDARY("x"): DirichletDiffusionBoundary(0), DTAG_BOUNDARY("y"): NeumannDiffusionBoundary(0) } def op(alpha, u): return diffusion_operator( discr, DISCR_TAG_BASE, alpha, boundaries, u) lazy_op = lazy_actx.compile(op) def get_inputs(actx): nodes = thaw(discr.nodes(), actx) alpha = discr.zeros(actx) + 1 u = actx.np.cos(np.pi*nodes[0]) return alpha, u tol = 1e-11 isclose = partial( _isclose, discr, rel_tol=tol, abs_tol=tol, return_operands=True) def lazy_to_eager(u): return thaw(freeze(u, lazy_actx), eager_actx) eager_result = op(*get_inputs(eager_actx)) lazy_result = lazy_to_eager(lazy_op(*get_inputs(lazy_actx))) is_close, lhs, rhs = isclose(lazy_result, eager_result) assert is_close, f"{lhs} not <= {rhs}"
def main(ctx_factory=cl.create_some_context, use_logmgr=True, use_leap=False, use_profiling=False, casename=None, rst_filename=None, actx_class=PyOpenCLArrayContext): """Run the example.""" cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) from mpi4py import MPI comm = MPI.COMM_WORLD num_parts = comm.Get_size() logmgr = initialize_logmgr(use_logmgr, filename="heat-source.sqlite", mode="wu", mpi_comm=comm) if use_profiling: queue = cl.CommandQueue( cl_ctx, properties=cl.command_queue_properties.PROFILING_ENABLE) else: queue = cl.CommandQueue(cl_ctx) actx = actx_class( queue, allocator=cl_tools.MemoryPool(cl_tools.ImmediateAllocator(queue))) from meshmode.distributed import MPIMeshDistributor, get_partition_by_pymetis mesh_dist = MPIMeshDistributor(comm) dim = 2 nel_1d = 16 t = 0 t_final = 0.0002 istep = 0 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, nelements_per_axis=(nel_1d,)*dim, boundary_tag_to_face={ "dirichlet": ["+x", "-x"], "neumann": ["+y", "-y"] } ) 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() order = 3 discr = EagerDGDiscretization(actx, local_mesh, order=order, mpi_communicator=comm) if dim == 2: # no deep meaning here, just a fudge factor dt = 0.0025/(nel_1d*order**2) else: raise ValueError("don't have a stable time step guesstimate") source_width = 0.2 from arraycontext import thaw nodes = thaw(discr.nodes(), actx) boundaries = { DTAG_BOUNDARY("dirichlet"): DirichletDiffusionBoundary(0.), DTAG_BOUNDARY("neumann"): NeumannDiffusionBoundary(0.) } u = discr.zeros(actx) if logmgr: logmgr_add_device_name(logmgr, queue) logmgr_add_device_memory_usage(logmgr, queue) logmgr.add_watches(["step.max", "t_step.max", "t_log.max"]) try: logmgr.add_watches(["memory_usage_python.max", "memory_usage_gpu.max"]) except KeyError: pass if use_profiling: logmgr.add_watches(["multiply_time.max"]) vis_timer = IntervalTimer("t_vis", "Time spent visualizing") logmgr.add_quantity(vis_timer) vis = make_visualizer(discr) def rhs(t, u): return ( diffusion_operator( discr, quad_tag=DISCR_TAG_BASE, alpha=1, boundaries=boundaries, u=u) + actx.np.exp(-np.dot(nodes, nodes)/source_width**2)) compiled_rhs = actx.compile(rhs) rank = comm.Get_rank() while t < t_final: if logmgr: logmgr.tick_before() if istep % 10 == 0: print(istep, t, actx.to_numpy(actx.np.linalg.norm(u[0]))) vis.write_vtk_file("fld-heat-source-mpi-%03d-%04d.vtu" % (rank, istep), [ ("u", u) ], overwrite=True) u = rk4_step(u, t, dt, compiled_rhs) t += dt istep += 1 if logmgr: set_dt(logmgr, dt) logmgr.tick_after() final_answer = discr.norm(u, np.inf) resid = abs(final_answer - 0.00020620711665201585) if resid > 1e-15: raise ValueError(f"Run did not produce the expected result {resid=}")
def main(): cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue, allocator=cl_tools.MemoryPool( cl_tools.ImmediateAllocator(queue))) from mpi4py import MPI comm = MPI.COMM_WORLD num_parts = comm.Get_size() from meshmode.distributed import MPIMeshDistributor, get_partition_by_pymetis mesh_dist = MPIMeshDistributor(comm) dim = 2 nel_1d = 16 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=(nel_1d, ) * dim, boundary_tag_to_face={ "dirichlet": ["+x", "-x"], "neumann": ["+y", "-y"] }) 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() order = 3 discr = EagerDGDiscretization(actx, local_mesh, order=order, mpi_communicator=comm) if dim == 2: # no deep meaning here, just a fudge factor dt = 0.0025 / (nel_1d * order**2) else: raise ValueError("don't have a stable time step guesstimate") source_width = 0.2 nodes = thaw(actx, discr.nodes()) u = discr.zeros(actx) vis = make_visualizer(discr, order + 3 if dim == 2 else order) boundaries = { grudge_sym.DTAG_BOUNDARY("dirichlet"): DirichletDiffusionBoundary(0.), grudge_sym.DTAG_BOUNDARY("neumann"): NeumannDiffusionBoundary(0.) } def rhs(t, u): return ( diffusion_operator(discr, alpha=1, boundaries=boundaries, u=u) + actx.np.exp(-np.dot(nodes, nodes) / source_width**2)) rank = comm.Get_rank() t = 0 t_final = 0.01 istep = 0 while True: if istep % 10 == 0: print(istep, t, discr.norm(u)) vis.write_vtk_file( "fld-heat-source-mpi-%03d-%04d.vtu" % (rank, istep), [("u", u)]) if t >= t_final: break u = rk4_step(u, t, dt, rhs) t += dt istep += 1
def test_diffusion_discontinuous_alpha(actx_factory, order, visualize=False): """ Checks the accuracy of the diffusion operator for an alpha field that has a jump across an element face. """ actx = actx_factory() n = 8 mesh = get_box_mesh(1, -1, 1, n) from grudge.eager import EagerDGDiscretization discr = EagerDGDiscretization(actx, mesh, order=order) nodes = thaw(actx, discr.nodes()) # Set up a 1D heat equation interface problem, apply the diffusion operator to # the exact steady state solution, and check that it's zero lower_mask_np = np.empty((n, order + 1), dtype=int) lower_mask_np[:, :] = 0 lower_mask_np[:int(n / 2), :] = 1 lower_mask = DOFArray(actx, (actx.from_numpy(lower_mask_np), )) upper_mask_np = np.empty((n, order + 1), dtype=int) upper_mask_np[:, :] = 0 upper_mask_np[int(n / 2):, :] = 1 upper_mask = DOFArray(actx, (actx.from_numpy(upper_mask_np), )) alpha_lower = 0.5 alpha_upper = 1 alpha = alpha_lower * lower_mask + alpha_upper * upper_mask boundaries = { DTAG_BOUNDARY("-0"): DirichletDiffusionBoundary(0.), DTAG_BOUNDARY("+0"): DirichletDiffusionBoundary(1.), } flux = -alpha_lower * alpha_upper / (alpha_lower + alpha_upper) u_steady = ( -flux / alpha_lower * (nodes[0] + 1) * lower_mask # noqa: E126, E221 + (1 - flux / alpha_upper * (nodes[0] - 1)) * upper_mask) # noqa: E131 def get_rhs(t, u): return diffusion_operator(discr, quad_tag=DISCR_TAG_BASE, alpha=alpha, boundaries=boundaries, u=u) rhs = get_rhs(0, u_steady) if visualize: from grudge.shortcuts import make_visualizer vis = make_visualizer(discr, discr.order + 3) vis.write_vtk_file( "diffusion_discontinuous_alpha_rhs_{order}.vtu".format( order=order), [ ("alpha", alpha), ("u_steady", u_steady), ("rhs", rhs), ]) linf_err = discr.norm(rhs, np.inf) assert (linf_err < 1e-11) # Now check stability from numpy.random import rand perturb_np = np.empty((n, order + 1), dtype=float) for i in range(n): perturb_np[i, :] = 0.1 * (rand() - 0.5) perturb = DOFArray(actx, (actx.from_numpy(perturb_np), )) u = u_steady + perturb dt = 1e-3 / order**2 t = 0 from mirgecom.integrators import rk4_step for _ in range(50): u = rk4_step(u, t, dt, get_rhs) t += dt if visualize: vis.write_vtk_file( "diffusion_disc_alpha_stability_{order}.vtu".format(order=order), [ ("alpha", alpha), ("u", u), ("u_steady", u_steady), ]) linf_diff = discr.norm(u - u_steady, np.inf) assert linf_diff < 0.1
def get_boundaries(discr, actx, t): return { grudge_sym.DTAG_BOUNDARY("dirichlet"): DirichletDiffusionBoundary(0.), grudge_sym.DTAG_BOUNDARY("neumann"): NeumannDiffusionBoundary(0.), }