def main(write_output=True, dtype=np.float32): from grudge.backends import guess_run_context rcon = guess_run_context() from grudge.mesh.generator import make_rect_mesh if rcon.is_head_rank: h_fac = 1 mesh = make_rect_mesh(a=(0, 0), b=(1, 1), max_area=h_fac**2 * 1e-4, periodicity=(True, True), subdivisions=(int(70 / h_fac), int(70 / h_fac))) from grudge.models.gas_dynamics.lbm import \ D2Q9LBMMethod, LatticeBoltzmannOperator op = LatticeBoltzmannOperator(D2Q9LBMMethod(), lbm_delta_t=0.001, nu=1e-4) if rcon.is_head_rank: print("%d elements" % len(mesh.elements)) mesh_data = rcon.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() discr = rcon.make_discretization(mesh_data, order=3, default_scalar_type=dtype, debug=["cuda_no_plan"]) from grudge.timestep.runge_kutta import LSRK4TimeStepper stepper = LSRK4TimeStepper( dtype=dtype, #vector_primitive_factory=discr.get_vector_primitive_factory() ) from grudge.visualization import VtkVisualizer if write_output: vis = VtkVisualizer(discr, rcon, "fld") from grudge.data import CompiledExpressionData def ic_expr(t, x, fields): from grudge.symbolic import FunctionSymbol from pymbolic.primitives import IfPositive from pytools.obj_array import make_obj_array tanh = FunctionSymbol("tanh") sin = FunctionSymbol("sin") rho = 1 u0 = 0.05 w = 0.05 delta = 0.05 from grudge.symbolic.primitives import make_common_subexpression as cse u = cse( make_obj_array([ IfPositive(x[1] - 1 / 2, u0 * tanh(4 * (3 / 4 - x[1]) / w), u0 * tanh(4 * (x[1] - 1 / 4) / w)), u0 * delta * sin(2 * np.pi * (x[0] + 1 / 4)) ]), "u") return make_obj_array([ op.method.f_equilibrium(rho, alpha, u) for alpha in range(len(op.method)) ]) # timestep loop ----------------------------------------------------------- stream_rhs = op.bind_rhs(discr) collision_update = op.bind(discr, op.collision_update) get_rho = op.bind(discr, op.rho) get_rho_u = op.bind(discr, op.rho_u) f_bar = CompiledExpressionData(ic_expr).volume_interpolant(0, discr) from grudge.discretization import ExponentialFilterResponseFunction from grudge.symbolic.operators import FilterOperator mode_filter = FilterOperator( ExponentialFilterResponseFunction(min_amplification=0.9, order=4))\ .bind(discr) final_time = 1000 try: lbm_dt = op.lbm_delta_t dg_dt = op.estimate_timestep(discr, stepper=stepper) print(dg_dt) dg_steps_per_lbm_step = int(np.ceil(lbm_dt / dg_dt)) dg_dt = lbm_dt / dg_steps_per_lbm_step lbm_steps = int(final_time // op.lbm_delta_t) for step in range(lbm_steps): t = step * lbm_dt if step % 100 == 0 and write_output: visf = vis.make_file("fld-%04d" % step) rho = get_rho(f_bar) rho_u = get_rho_u(f_bar) vis.add_data( visf, [("fbar%d" % i, discr.convert_volume(f_bar_i, "numpy")) for i, f_bar_i in enumerate(f_bar)] + [ ("rho", discr.convert_volume(rho, "numpy")), ("rho_u", discr.convert_volume(rho_u, "numpy")), ], time=t, step=step) visf.close() print("step=%d, t=%f" % (step, t)) f_bar = collision_update(f_bar) for substep in range(dg_steps_per_lbm_step): f_bar = stepper(f_bar, t + substep * dg_dt, dg_dt, stream_rhs) #f_bar = mode_filter(f_bar) finally: if write_output: vis.close() discr.close()
#case = OffCenterMigratingTestCase(), case=ExactTestCase(), ): from grudge.backends import guess_run_context rcon = guess_run_context() order = 3 if rcon.is_head_rank: if True: from grudge.mesh.generator import make_uniform_1d_mesh mesh = make_uniform_1d_mesh(case.a, case.b, 20, periodic=True) else: from grudge.mesh.generator import make_rect_mesh print((pi * 2) / (11 * 5 * 2)) mesh = make_rect_mesh((-pi, -1), (pi, 1), periodicity=(True, True), subdivisions=(11, 5), max_area=(pi * 2) / (11 * 5 * 2)) if rcon.is_head_rank: mesh_data = rcon.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() discr = rcon.make_discretization(mesh_data, order=order, quad_min_degrees={"quad": 3 * order}) if write_output: from grudge.visualization import VtkVisualizer vis = VtkVisualizer(discr, rcon, "fld")
def main(): from grudge.backends import guess_run_context rcon = guess_run_context() from grudge.tools import to_obj_array if rcon.is_head_rank: from grudge.mesh.generator import make_rect_mesh mesh = make_rect_mesh((-5, -5), (5, 5), max_area=0.01) mesh_data = rcon.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() for order in [1]: discr = rcon.make_discretization(mesh_data, order=order, default_scalar_type=numpy.float64) from grudge.visualization import SiloVisualizer, VtkVisualizer vis = VtkVisualizer(discr, rcon, "Sod2D-%d" % order) #vis = SiloVisualizer(discr, rcon) sod_field = Sod(gamma=1.4) fields = sod_field.volume_interpolant(0, discr) from grudge.models.gas_dynamics import GasDynamicsOperator from grudge.mesh import BTAG_ALL op = GasDynamicsOperator(dimensions=2, gamma=sod_field.gamma, mu=0.0, prandtl=sod_field.prandtl, bc_inflow=sod_field, bc_outflow=sod_field, bc_noslip=sod_field, inflow_tag=BTAG_ALL, source=None) euler_ex = op.bind(discr) max_eigval = [0] def rhs(t, q): ode_rhs, speed = euler_ex(t, q) max_eigval[0] = speed return ode_rhs rhs(0, fields) if rcon.is_head_rank: print("---------------------------------------------") print("order %d" % order) print("---------------------------------------------") print("#elements=", len(mesh.elements)) # limiter setup ------------------------------------------------------------ from grudge.models.gas_dynamics import SlopeLimiter1NEuler limiter = SlopeLimiter1NEuler(discr, sod_field.gamma, 2, op) # integrator setup--------------------------------------------------------- from grudge.timestep import SSPRK3TimeStepper, RK4TimeStepper stepper = SSPRK3TimeStepper(limiter=limiter) #stepper = SSPRK3TimeStepper() #stepper = RK4TimeStepper() # diagnostics setup --------------------------------------------------- from pytools.log import LogManager, add_general_quantities, \ add_simulation_quantities, add_run_info logmgr = LogManager("euler-%d.dat" % order, "w", rcon.communicator) add_run_info(logmgr) add_general_quantities(logmgr) add_simulation_quantities(logmgr) discr.add_instrumentation(logmgr) stepper.add_instrumentation(logmgr) logmgr.add_watches(["step.max", "t_sim.max", "t_step.max"]) # filter setup------------------------------------------------------------- from grudge.discretization import Filter, ExponentialFilterResponseFunction mode_filter = Filter( discr, ExponentialFilterResponseFunction(min_amplification=0.9, order=4)) # timestep loop ------------------------------------------------------- try: from grudge.timestep import times_and_steps step_it = times_and_steps( final_time=1.0, logmgr=logmgr, max_dt_getter=lambda t: op.estimate_timestep( discr, stepper=stepper, t=t, max_eigenvalue=max_eigval[0])) for step, t, dt in step_it: if step % 5 == 0: #if False: visf = vis.make_file("vortex-%d-%04d" % (order, step)) #true_fields = vortex.volume_interpolant(t, discr) #from pyvisfile.silo import DB_VARTYPE_VECTOR vis.add_data( visf, [ ("rho", discr.convert_volume(op.rho(fields), kind="numpy")), ("e", discr.convert_volume(op.e(fields), kind="numpy")), ("rho_u", discr.convert_volume(op.rho_u(fields), kind="numpy")), ("u", discr.convert_volume(op.u(fields), kind="numpy")), #("true_rho", op.rho(true_fields)), #("true_e", op.e(true_fields)), #("true_rho_u", op.rho_u(true_fields)), #("true_u", op.u(true_fields)), #("rhs_rho", op.rho(rhs_fields)), #("rhs_e", op.e(rhs_fields)), #("rhs_rho_u", op.rho_u(rhs_fields)), ], #expressions=[ #("diff_rho", "rho-true_rho"), #("diff_e", "e-true_e"), #("diff_rho_u", "rho_u-true_rho_u", DB_VARTYPE_VECTOR), #("p", "0.4*(e- 0.5*(rho_u*u))"), #], time=t, step=step) visf.close() fields = stepper(fields, t, dt, rhs) # fields = limiter(fields) # fields = mode_filter(fields) assert not numpy.isnan(numpy.sum(fields[0])) finally: vis.close() logmgr.close() discr.close() # not solution, just to check against when making code changes true_fields = sod_field.volume_interpolant(t, discr) print(discr.norm(fields - true_fields))