def test_quadrature_tri_mass_mat_monomial(): """Check that quadrature integration on triangles is exact as designed.""" from hedge.mesh.generator import make_square_mesh mesh = make_square_mesh(a=-1, b=1, max_area=4 * 1 / 8 + 0.001) order = 4 discr = discr_class( mesh, order=order, debug=discr_class.noninteractive_debug_flags(), quad_min_degrees={"quad": 3 * order} ) m, n = 2, 1 f = Monomial((m, n)) f_vec = discr.interpolate_volume_function(lambda x, el: f(x)) from hedge.discretization import ones_on_volume ones = ones_on_volume(discr) if False: from hedge.visualization import SiloVisualizer vis = SiloVisualizer(discr) visf = vis.make_file("test") vis.add_data(visf, [("f", f_vec * f_vec)]) visf.close() from hedge.optemplate import MassOperator, Field, QuadratureGridUpsampler f_fld = Field("f") mass_op = discr.compile(MassOperator()(f_fld * f_fld)) from hedge.optemplate.primitives import make_common_subexpression as cse f_upsamp = cse(QuadratureGridUpsampler("quad")(f_fld)) quad_mass_op = discr.compile(MassOperator()(f_upsamp * f_upsamp)) num_integral_1 = numpy.dot(ones, mass_op(f=f_vec)) num_integral_2 = numpy.dot(ones, quad_mass_op(f=f_vec)) true_integral = 4 / ((2 * m + 1) * (2 * n + 1)) err_1 = abs(num_integral_1 - true_integral) err_2 = abs(num_integral_2 - true_integral) print num_integral_1, num_integral_2, true_integral print err_1, err_2 assert err_1 > 1e-8 assert err_2 < 1e-14
def test_quadrature_tri_mass_mat_monomial(): """Check that quadrature integration on triangles is exact as designed.""" from hedge.mesh.generator import make_square_mesh mesh = make_square_mesh(a=-1, b=1, max_area=4 * 1 / 8 + 0.001) order = 4 discr = discr_class(mesh, order=order, debug=discr_class.noninteractive_debug_flags(), quad_min_degrees={"quad": 3 * order}) m, n = 2, 1 f = Monomial((m, n)) f_vec = discr.interpolate_volume_function(lambda x, el: f(x)) from hedge.discretization import ones_on_volume ones = ones_on_volume(discr) if False: from hedge.visualization import SiloVisualizer vis = SiloVisualizer(discr) visf = vis.make_file("test") vis.add_data(visf, [("f", f_vec * f_vec)]) visf.close() from hedge.optemplate import (MassOperator, Field, QuadratureGridUpsampler) f_fld = Field("f") mass_op = discr.compile(MassOperator()(f_fld * f_fld)) from hedge.optemplate.primitives import make_common_subexpression as cse f_upsamp = cse(QuadratureGridUpsampler("quad")(f_fld)) quad_mass_op = discr.compile(MassOperator()(f_upsamp * f_upsamp)) num_integral_1 = numpy.dot(ones, mass_op(f=f_vec)) num_integral_2 = numpy.dot(ones, quad_mass_op(f=f_vec)) true_integral = 4 / ((2 * m + 1) * (2 * n + 1)) err_1 = abs(num_integral_1 - true_integral) err_2 = abs(num_integral_2 - true_integral) print num_integral_1, num_integral_2, true_integral print err_1, err_2 assert err_1 > 1e-8 assert err_2 < 1e-14
def run_convergence_test_advec(dtype, flux_type, random_partition, mesh_gen, debug_output=False): """Test whether 2/3D advection actually converges""" from hedge.timestep import RK4TimeStepper from hedge.tools import EOCRecorder from math import sin from hedge.data import TimeDependentGivenFunction from hedge.visualization import SiloVisualizer from hedge.backends import guess_run_context rcon = guess_run_context(["mpi"]) # note: x component must remain zero because x-periodicity is used v = np.array([0.0, 0.9, 0.3]) def f(x): return sin(x) def u_analytic(x, el, t): return f( (np.dot(-v[:dims], x) / la.norm(v[:dims]) + t * la.norm(v[:dims]))) def boundary_tagger(vertices, el, face_nr, points): face_normal = el.face_normals[face_nr] if np.dot(face_normal, v[:len(face_normal)]) < 0: return ["inflow"] else: return ["outflow"] mesh = mesh_gen(boundary_tagger) eoc_rec = EOCRecorder() if random_partition: # Distribute elements randomly across nodes. # This is bad, efficiency-wise, but it puts stress # on the parallel implementation, which is desired here. # Another main point of this is to force the code to split # a periodic face pair across nodes. from random import choice partition = [choice(rcon.ranks) for el in mesh.elements] else: partition = None for order in [1, 2, 3, 4]: if rcon.is_head_rank: mesh_data = rcon.distribute_mesh(mesh, partition) else: mesh_data = rcon.receive_mesh() dims = mesh.points.shape[1] discr = rcon.make_discretization(mesh_data, order=order, default_scalar_type=dtype) op = StrongAdvectionOperator( v[:dims], inflow_u=TimeDependentGivenFunction(u_analytic), flux_type=flux_type) if debug_output: vis = SiloVisualizer(discr, rcon) u = discr.interpolate_volume_function( lambda x, el: u_analytic(x, el, 0)) ic = u.copy() if debug_output and rcon.is_head_rank: print "#elements=%d" % len(mesh.elements) test_name = "test-%s-o%d-m%s-r%s" % ( flux_type, order, mesh_gen.__name__, random_partition) rhs = op.bind(discr) stepper = RK4TimeStepper(dtype=dtype) from hedge.timestep import times_and_steps final_time = 1 step_it = times_and_steps(final_time=final_time, max_dt_getter=lambda t: op.estimate_timestep( discr, stepper=stepper, t=t, fields=u)) for step, t, dt in step_it: u = stepper(u, t, dt, rhs) assert u.dtype == dtype u_true = discr.interpolate_volume_function( lambda x, el: u_analytic(x, el, final_time)) error = u - u_true l2_error = discr.norm(error) if debug_output: visf = vis.make_file(test_name + "-final") vis.add_data(visf, [("u", u), ("u_true", u_true), ("ic", ic)]) visf.close() eoc_rec.add_data_point(order, l2_error) if debug_output and rcon.is_head_rank: print "%s\n%s\n" % (flux_type.upper(), "-" * len(flux_type)) print eoc_rec.pretty_print(abscissa_label="Poly. Order", error_label="L2 Error") assert eoc_rec.estimate_order_of_convergence()[0, 1] > 3 assert eoc_rec.estimate_order_of_convergence(2)[-1, 1] > 7
def main(): from hedge.backends import guess_run_context rcon = guess_run_context( #["cuda"] ) from hedge.tools import EOCRecorder, to_obj_array eoc_rec = EOCRecorder() def boundary_tagger(vertices, el, face_nr, all_v): return ["inflow"] if rcon.is_head_rank: from hedge.mesh import make_rect_mesh, \ make_centered_regular_rect_mesh #mesh = make_rect_mesh((0,0), (10,1), max_area=0.01) refine = 1 mesh = make_centered_regular_rect_mesh( (0, 0), (10, 1), n=(20, 4), #periodicity=(True, False), post_refine_factor=refine, boundary_tagger=boundary_tagger) mesh_data = rcon.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() for order in [3]: discr = rcon.make_discretization(mesh_data, order=order, default_scalar_type=numpy.float64) from hedge.visualization import SiloVisualizer, VtkVisualizer #vis = VtkVisualizer(discr, rcon, "shearflow-%d" % order) vis = SiloVisualizer(discr, rcon) shearflow = SteadyShearFlow() fields = shearflow.volume_interpolant(0, discr) gamma, mu, prandtl, spec_gas_const = shearflow.properties() from hedge.models.gas_dynamics import GasDynamicsOperator op = GasDynamicsOperator(dimensions=2, gamma=gamma, mu=mu, prandtl=prandtl, spec_gas_const=spec_gas_const, bc_inflow=shearflow, bc_outflow=shearflow, bc_noslip=shearflow, inflow_tag="inflow", outflow_tag="outflow", noslip_tag="noslip") navierstokes_ex = op.bind(discr) max_eigval = [0] def rhs(t, q): ode_rhs, speed = navierstokes_ex(t, q) max_eigval[0] = speed return ode_rhs # needed to get first estimate of maximum eigenvalue rhs(0, fields) if rcon.is_head_rank: print "---------------------------------------------" print "order %d" % order print "---------------------------------------------" print "#elements=", len(mesh.elements) from hedge.timestep import RK4TimeStepper stepper = RK4TimeStepper() # diagnostics setup --------------------------------------------------- from pytools.log import LogManager, add_general_quantities, \ add_simulation_quantities, add_run_info logmgr = LogManager("navierstokes-cpu-%d-%d.dat" % (order, refine), "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"]) # timestep loop ------------------------------------------------------- try: from hedge.timestep import times_and_steps step_it = times_and_steps( final_time=0.3, #max_steps=500, 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 % 10 == 0: #if False: visf = vis.make_file("shearflow-%d-%04d" % (order, step)) #true_fields = shearflow.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", discr.convert_volume(op.rho(true_fields), kind="numpy")), #("true_e", discr.convert_volume(op.e(true_fields), kind="numpy")), #("true_rho_u", discr.convert_volume(op.rho_u(true_fields), kind="numpy")), #("true_u", discr.convert_volume(op.u(true_fields), kind="numpy")), ], 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) true_fields = shearflow.volume_interpolant(t, discr) l2_error = discr.norm(op.u(fields) - op.u(true_fields)) eoc_rec.add_data_point(order, l2_error) print print eoc_rec.pretty_print("P.Deg.", "L2 Error") logmgr.set_constant("l2_error", l2_error) finally: vis.close() logmgr.save() discr.close()
def optimize_shape_bandwidth(method, state, analytic_rho, exponent): discr = method.discretization rec = method.depositor adv_radius = method.mesh_data.advisable_particle_radius() radii = [adv_radius * 2**i for i in numpy.linspace(-4, 2, 50)] def set_radius(r): method.depositor.set_shape_function( state, method.get_shape_function_class()( r, method.mesh_data.dimensions, exponent, )) tried_radii = [] l1_errors = [] debug = "shape_bw" in method.debug visualize = set(["shape_bw", "vis_files"]) <= method.debug if visualize: from hedge.visualization import SiloVisualizer vis = SiloVisualizer(discr) import sys if debug: sys.stdout.write("optimizing shape bw (%d attempts): " % len(radii)) for step, radius in enumerate(radii): if debug: sys.stdout.write("%d." % step) sys.stdout.flush() try: try: method.set_ignore_core_warnings(True) set_radius(radius) except RuntimeError, re: if "particle mass is zero" in str(re): continue else: raise finally: method.set_ignore_core_warnings(False) state.derived_quantity_cache.clear() try: try: method.set_ignore_core_warnings(True) rec_rho = method.deposit_rho(state) except RuntimeError, re: if "particle mass is zero" in str(re): continue else: raise finally: method.set_ignore_core_warnings(False) tried_radii.append(radius) l1_errors.append(discr.integral(numpy.abs(rec_rho - analytic_rho))) if visualize: visf = vis.make_file("bwopt-%04d" % step) method.add_to_vis(vis, visf, state, time=radius, step=step) vis.add_data( visf, [ ("rho", rec_rho), #("j", method.deposit_j(state)), ("rho_analytic", analytic_rho), ], expressions=[("rho_diff", "rho-rho_analytic")], time=radius, step=step) try: rec.visualize_grid_quantities except AttributeError: pass else: rec.visualize_grid_quantities(visf, [ ("rho_grid", rec.deposit_grid_rho(state)), ("j_grid", rec.deposit_grid_j(state, method.velocities(state))), ("rho_resid", rec.remap_residual(rec.deposit_grid_rho(state))), ]) visf.close() if debug: sys.stdout.write("\n") sys.stdout.flush() if visualize: vis.close() from pytools import argmin min_idx = argmin(l1_errors) min_rad = tried_radii[min_idx] min_l1_error = l1_errors[min_idx] rel_l1_error = abs(min_l1_error / discr.integral(analytic_rho)) if rel_l1_error > 0.1: from warnings import warn warn("Charge density is very poorly resolved (rel L1 error=%g)" % rel_l1_error) def is_local_minimum(list, i): if i == 0: return False elif i == len(list) - 1: return False else: return list[i] < list[i - 1] and list[i] < list[i + 1] local_minima = [ idx for idx in range(len(tried_radii)) if is_local_minimum(l1_errors, idx) ] chosen_idx = max(local_minima) chosen_rad = tried_radii[chosen_idx] if "shape_bw" in method.debug: chosen_l1_error = l1_errors[chosen_idx] print "radius: guessed optimum=%g, found optimum=%g, chosen=%g" % ( adv_radius, min_rad, chosen_rad) print "radius: optimum l1 error=%g, chosen l1 error=%g" % ( min_l1_error, chosen_l1_error) set_radius(chosen_rad) state.derived_quantity_cache.clear() if set(["interactive", "shape_bw"]) < method.debug: from pylab import semilogx, show semilogx(tried_radii, l1_errors) show()
def main(): from hedge.backends import guess_run_context rcon = guess_run_context( ["cuda", "mpi"]) if rcon.is_head_rank: mesh = make_wingmesh() #from hedge.mesh import make_rect_mesh #mesh = make_rect_mesh( # boundary_tagger=lambda fvi, el, fn, all_v: ["inflow"]) mesh_data = rcon.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() for order in [3]: from pytools import add_python_path_relative_to_script add_python_path_relative_to_script("..") from gas_dynamics_initials import UniformMachFlow wing = UniformMachFlow(angle_of_attack=0) from hedge.models.gas_dynamics import GasDynamicsOperator op = GasDynamicsOperator(dimensions=3, gamma=wing.gamma, mu=wing.mu, prandtl=wing.prandtl, spec_gas_const=wing.spec_gas_const, bc_inflow=wing, bc_outflow=wing, bc_noslip=wing, inflow_tag="inflow", outflow_tag="outflow", noslip_tag="noslip") discr = rcon.make_discretization(mesh_data, order=order, debug=["cuda_no_plan", #"cuda_dump_kernels", #"dump_dataflow_graph", #"dump_optemplate_stages", #"dump_dataflow_graph", #"print_op_code" "cuda_no_metis", ], default_scalar_type=numpy.float64, tune_for=op.op_template()) from hedge.visualization import SiloVisualizer, VtkVisualizer #vis = VtkVisualizer(discr, rcon, "shearflow-%d" % order) vis = SiloVisualizer(discr, rcon) fields = wing.volume_interpolant(0, discr) navierstokes_ex = op.bind(discr) max_eigval = [0] def rhs(t, q): ode_rhs, speed = navierstokes_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) from hedge.timestep import RK4TimeStepper stepper = RK4TimeStepper() # diagnostics setup --------------------------------------------------- from pytools.log import LogManager, add_general_quantities, \ add_simulation_quantities, add_run_info logmgr = LogManager("navierstokes-%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"]) # timestep loop ------------------------------------------------------- try: from hedge.timestep import times_and_steps step_it = times_and_steps( final_time=200, #max_steps=500, logmgr=logmgr, max_dt_getter=lambda t: 0.6 * op.estimate_timestep(discr, stepper=stepper, t=t, max_eigenvalue=max_eigval[0])) for step, t, dt in step_it: if step % 200 == 0: #if False: visf = vis.make_file("wing-%d-%06d" % (order, step)) #rhs_fields = rhs(t, fields) from pyvisfile.silo import DB_VARTYPE_VECTOR from hedge.discretization import ones_on_boundary 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")), #("rhs_rho", discr.convert_volume(op.rho(rhs_fields), kind="numpy")), #("rhs_e", discr.convert_volume(op.e(rhs_fields), kind="numpy")), #("rhs_rho_u", discr.convert_volume(op.rho_u(rhs_fields), kind="numpy")), ], expressions=[ ("p", "(0.4)*(e- 0.5*(rho_u*u))"), ], time=t, step=step ) visf.close() fields = stepper(fields, t, dt, rhs) t += dt finally: vis.close() logmgr.save() discr.close()
def test_symmetry_preservation_2d(): """Test whether we preserve symmetry in a symmetric 2D advection problem""" from numpy import dot def make_mesh(): array = numpy.array # # 1---8---2 # |7 /|\ 1| # | / | \ | # |/ 6|0 \| # 5---4---7 # |\ 5|3 /| # | \ | / | # |4 \|/ 2| # 0---6---3 # points = [ array([-0.5, -0.5]), array([-0.5, 0.5]), array([0.5, 0.5]), array([0.5, -0.5]), array([0.0, 0.0]), array([-0.5, 0.0]), array([0.0, -0.5]), array([0.5, 0.0]), array([0.0, 0.5]) ] elements = [ [8, 7, 4], [8, 7, 2], [6, 7, 3], [7, 4, 6], [5, 6, 0], [5, 6, 4], [5, 8, 4], [1, 5, 8], ] def boundary_tagger(vertices, el, face_nr, all_v): if dot(el.face_normals[face_nr], v) < 0: return ["inflow"] else: return ["outflow"] from hedge.mesh import make_conformal_mesh return make_conformal_mesh(points, elements, boundary_tagger) from hedge.discretization import SymmetryMap from hedge.timestep import RK4TimeStepper from hedge.models.advection import StrongAdvectionOperator from hedge.data import TimeDependentGivenFunction v = numpy.array([-1, 0]) mesh = make_mesh() discr = discr_class(mesh, order=4, debug=discr_class.noninteractive_debug_flags()) #ref_discr = DynamicDiscretization(mesh, order=4) def f(x): if x < 0.5: return 0 else: return (x - 0.5) #def f(x): #return sin(5*x) def u_analytic(x, el, t): return f(-dot(v, x) + t) u = discr.interpolate_volume_function(lambda x, el: u_analytic(x, el, 0)) sym_map = SymmetryMap(discr, lambda x: numpy.array([x[0], -x[1]]), { 0: 3, 2: 1, 5: 6, 7: 4 }) for flux_type in StrongAdvectionOperator.flux_types: stepper = RK4TimeStepper() op = StrongAdvectionOperator( v, inflow_u=TimeDependentGivenFunction(u_analytic), flux_type=flux_type) dt = op.estimate_timestep(discr, stepper=stepper) nsteps = int(1 / dt) rhs = op.bind(discr) #test_comp = [ "bflux"] #test_rhs = op.bind(discr, test_comp) #ref_rhs = op.bind(ref_discr, test_comp) for step in xrange(nsteps): u = stepper(u, step * dt, dt, rhs) sym_error_u = u - sym_map(u) sym_error_u_l2 = discr.norm(sym_error_u) if False: from hedge.visualization import SiloVisualizer vis = SiloVisualizer(discr) visf = vis.make_file("test-%s-%04d" % (flux_type, step)) vis.add_data( visf, [ ("u", u), ("sym_u", sym_map(u)), ("sym_diff", u - sym_map(u)), ("rhs", rhs(step * dt, u)), #("rhs_test", test_rhs(step*dt, u)), #("rhs_ref", ref_rhs(step*dt, u)), #("rhs_diff", test_rhs(step*dt, u)-ref_rhs(step*dt, u)), ]) print sym_error_u_l2 assert sym_error_u_l2 < 4e-15
def run_convergence_test_advec(dtype, debug_output=False): """Test whether 2/3D advection actually converges""" from hedge.mesh.generator import make_ball_mesh, make_box_mesh, make_rect_mesh from hedge.timestep import RK4TimeStepper from hedge.tools import EOCRecorder from math import sin, pi, sqrt from hedge.models.advection import StrongAdvectionOperator from hedge.data import TimeDependentGivenFunction from hedge.visualization import SiloVisualizer from hedge.backends import guess_run_context rcon = guess_run_context(["mpi"]) # note: x component must remain zero because x-periodicity is used v = numpy.array([0.0,0.9,0.3]) def f(x): return sin(x) def u_analytic(x, el, t): return f((numpy.dot(-v[:dims],x)/la.norm(v[:dims])+t*la.norm(v[:dims]))) def boundary_tagger(vertices, el, face_nr, points): face_normal = el.face_normals[face_nr] if numpy.dot(face_normal, v[:len(face_normal)]) < 0: return ["inflow"] else: return ["outflow"] for i_mesh, mesh in enumerate([ # 2D semiperiodic make_rect_mesh(b=(2*pi,3), max_area=0.4, periodicity=(True, False), subdivisions=(5,10), boundary_tagger=boundary_tagger, ), # 3D x-periodic make_box_mesh((0,0,0), (2*pi, 2, 2), max_volume=0.4, periodicity=(True, False, False), boundary_tagger=boundary_tagger, ), # non-periodic make_ball_mesh(r=pi, boundary_tagger=boundary_tagger, max_volume=0.7), ]): for flux_type in StrongAdvectionOperator.flux_types: for random_partition in [True, False]: eoc_rec = EOCRecorder() if random_partition: # Distribute elements randomly across nodes. # This is bad, efficiency-wise, but it puts stress # on the parallel implementation, which is desired here. # Another main point of this is to force the code to split # a periodic face pair across nodes. from random import choice partition = [choice(rcon.ranks) for el in mesh.elements] else: partition = None for order in [1,2,3,4]: if rcon.is_head_rank: mesh_data = rcon.distribute_mesh(mesh, partition) else: mesh_data = rcon.receive_mesh() dims = mesh.points.shape[1] discr = rcon.make_discretization(mesh_data, order=order, default_scalar_type=dtype) op = StrongAdvectionOperator(v[:dims], inflow_u=TimeDependentGivenFunction(u_analytic), flux_type=flux_type) if debug_output: vis = SiloVisualizer(discr, rcon) u = discr.interpolate_volume_function( lambda x, el: u_analytic(x, el, 0)) ic = u.copy() if debug_output and rcon.is_head_rank: print "#elements=%d" % len(mesh.elements) test_name = "test-%s-o%d-m%d-r%s" % ( flux_type, order, i_mesh, random_partition) rhs = op.bind(discr) stepper = RK4TimeStepper(dtype=dtype) from hedge.timestep import times_and_steps final_time = 1 step_it = times_and_steps( final_time=final_time, max_dt_getter=lambda t: op.estimate_timestep(discr, stepper=stepper, t=t, fields=u)) for step, t, dt in step_it: u = stepper(u, t, dt, rhs) assert u.dtype == dtype u_true = discr.interpolate_volume_function( lambda x, el: u_analytic(x, el, final_time)) error = u-u_true l2_error = discr.norm(error) if debug_output: visf = vis.make_file(test_name+"-final") vis.add_data(visf, [ ("u", u), ("u_true", u_true), ("ic", ic)]) visf.close() eoc_rec.add_data_point(order, l2_error) if debug_output and rcon.is_head_rank: print "%s\n%s\n" % (flux_type.upper(), "-" * len(flux_type)) print eoc_rec.pretty_print(abscissa_label="Poly. Order", error_label="L2 Error") assert eoc_rec.estimate_order_of_convergence()[0,1] > 3 assert eoc_rec.estimate_order_of_convergence(2)[-1,1] > 7
def test_symmetry_preservation_2d(): """Test whether we preserve symmetry in a symmetric 2D advection problem""" from numpy import dot def make_mesh(): array = numpy.array # # 1---8---2 # |7 /|\ 1| # | / | \ | # |/ 6|0 \| # 5---4---7 # |\ 5|3 /| # | \ | / | # |4 \|/ 2| # 0---6---3 # points = [ array([-0.5, -0.5]), array([-0.5, 0.5]), array([0.5, 0.5]), array([0.5, -0.5]), array([0.0, 0.0]), array([-0.5, 0.0]), array([0.0, -0.5]), array([0.5, 0.0]), array([0.0, 0.5]), ] elements = [[8, 7, 4], [8, 7, 2], [6, 7, 3], [7, 4, 6], [5, 6, 0], [5, 6, 4], [5, 8, 4], [1, 5, 8]] def boundary_tagger(vertices, el, face_nr, all_v): if dot(el.face_normals[face_nr], v) < 0: return ["inflow"] else: return ["outflow"] from hedge.mesh import make_conformal_mesh return make_conformal_mesh(points, elements, boundary_tagger) from hedge.discretization import SymmetryMap from hedge.discretization.local import TriangleDiscretization from hedge.timestep import RK4TimeStepper from math import sqrt, sin from hedge.models.advection import StrongAdvectionOperator from hedge.data import TimeDependentGivenFunction v = numpy.array([-1, 0]) mesh = make_mesh() discr = discr_class(mesh, order=4, debug=discr_class.noninteractive_debug_flags()) # ref_discr = DynamicDiscretization(mesh, order=4) def f(x): if x < 0.5: return 0 else: return x - 0.5 # def f(x): # return sin(5*x) def u_analytic(x, el, t): return f(-dot(v, x) + t) u = discr.interpolate_volume_function(lambda x, el: u_analytic(x, el, 0)) sym_map = SymmetryMap(discr, lambda x: numpy.array([x[0], -x[1]]), {0: 3, 2: 1, 5: 6, 7: 4}) for flux_type in StrongAdvectionOperator.flux_types: stepper = RK4TimeStepper() op = StrongAdvectionOperator(v, inflow_u=TimeDependentGivenFunction(u_analytic), flux_type=flux_type) dt = op.estimate_timestep(discr, stepper=stepper) nsteps = int(1 / dt) rhs = op.bind(discr) # test_comp = [ "bflux"] # test_rhs = op.bind(discr, test_comp) # ref_rhs = op.bind(ref_discr, test_comp) for step in xrange(nsteps): u = stepper(u, step * dt, dt, rhs) sym_error_u = u - sym_map(u) sym_error_u_l2 = discr.norm(sym_error_u) if False: from hedge.visualization import SiloVisualizer vis = SiloVisualizer(discr) visf = vis.make_file("test-%s-%04d" % (flux_type, step)) vis.add_data( visf, [ ("u", u), ("sym_u", sym_map(u)), ("sym_diff", u - sym_map(u)), ("rhs", rhs(step * dt, u)), ("rhs_test", test_rhs(step * dt, u)), ("rhs_ref", ref_rhs(step * dt, u)), ("rhs_diff", test_rhs(step * dt, u) - ref_rhs(step * dt, u)), ], ) print sym_error_u_l2 assert sym_error_u_l2 < 4e-15
def prepare_with_pointwise_projection_and_basis_reduction(self): discr = self.method.discretization backend = self.backend backend.elements_on_grid.reserve( sum(len(eg.members) for eg in discr.element_groups)) min_s_values = [] max_s_values = [] cond_s_values = [] basis_len_vec = discr.volume_zeros() el_condition_vec = discr.volume_zeros() point_count_vec = discr.volume_zeros() # Iterate over all elements for eg in discr.element_groups: ldis = eg.local_discretization mode_id_to_index = dict( (bid, i) for i, bid in enumerate(ldis.generate_mode_identifiers())) for el in eg.members: basis = list(zip( ldis.generate_mode_identifiers(), ldis.basis_functions())) eog, points = self.find_points_in_element(el, self.el_tolerance) while True: scaled_vdm = self.scaled_vandermonde(el, eog, points, [bf for bid, bf in basis]) max_bid_sum = max(sum(bid) for bid, bf in basis) killable_basis_elements = [ (i, bid) for i, (bid, bf) in enumerate(basis) if sum(bid) == max_bid_sum] try: u, s, vt = svd = la.svd(scaled_vdm) thresh = (numpy.finfo(float).eps * max(scaled_vdm.shape) * s[0]) assert s[-1] == numpy.min(s) assert s[0] == numpy.max(s) # Imagine that--s can have negative entries. # (AK: I encountered one negative zero.) if len(basis) > len(points) or numpy.abs(s[0]/s[-1]) > 10: retry = True # badly conditioned, kill a basis entry vti = vt[-1] from pytools import argmax2 kill_idx, kill_bid = argmax2( ((j, bid), abs(vti[j])) for j, bid in killable_basis_elements) assert kill_bid == basis[kill_idx][0] basis.pop(kill_idx) else: retry = False except la.LinAlgError: # SVD likely didn't converge. Lacking an SVD, we don't have # much guidance on what modes to kill. Any of the killable # ones will do. # Bang, you're dead. basis.pop(killable_basis_elements[0][0]) retry = True if not retry: break if len(basis) == 1: raise RuntimeError( "basis reduction has killed almost the entire basis on element %d" % el.id) if ldis.node_count() > len(basis): print "element %d: #nodes=%d, killed modes=%d" % ( el.id, ldis.node_count(), ldis.node_count()-len(basis),) basis_len_vec[discr.find_el_range(el.id)] = len(basis) el_condition_vec[discr.find_el_range(el.id)] = s[0]/s[-1] point_count_vec[discr.find_el_range(el.id)] = len(points) min_s_values.append(min(s)) max_s_values.append(max(s)) cond_s_values.append(max(s)/min(s)) self.make_pointwise_interpolation_matrix(eog, eg, el, ldis, svd, scaled_vdm, basis_subset=[mode_id_to_index[bid] for bid, bf in basis]) backend.elements_on_grid.append(eog) # visualize basis length for each element if set(["depositor", "vis_files"]) < self.method.debug: from hedge.visualization import SiloVisualizer vis = SiloVisualizer(discr) visf = vis.make_file("rec-debug") vis.add_data(visf, [ ("basis_len", basis_len_vec), ("el_condition", el_condition_vec), ("point_count", point_count_vec), ]) visf.close() # we don't need no stinkin' extra points backend.extra_point_brick_starts.extend([0]*(len(backend.bricks)+1)) # print some statistics self.generate_point_statistics()
def prepare_with_pointwise_projection_and_enlargement(self): tolerance_bound = 1.5 discr = self.method.discretization backend = self.backend backend.elements_on_grid.reserve( sum(len(eg.members) for eg in discr.element_groups)) cond_claims = 0 min_s_values = [] max_s_values = [] cond_s_values = [] from hedge.discretization import Projector, Discretization fine_discr = Discretization(discr.mesh, order=8) proj = Projector(discr, fine_discr) from hedge.visualization import SiloVisualizer vis = SiloVisualizer(fine_discr) # Iterate over all elements for eg in discr.element_groups: ldis = eg.local_discretization for el in eg.members: # If the structured Vandermonde matrix is singular, # enlarge the element tolerance my_tolerance = self.el_tolerance orig_point_count = None while True: eog, points = self.find_points_in_element(el, my_tolerance) if orig_point_count is None: orig_point_count = len(points) scaled_vdm = self.scaled_vandermonde(el, eog, points, ldis.basis_functions()) bad_vdm = len(points) < ldis.node_count() if not bad_vdm: try: u, s, vt = svd = la.svd(scaled_vdm) thresh = (numpy.finfo(float).eps * max(scaled_vdm.shape) * s[0]) zero_indices = [i for i, si in enumerate(s) if abs(si) < thresh] bad_vdm = bool(zero_indices) except la.LinAlgError: bad_vdm = True if not bad_vdm: break my_tolerance += 0.03 if my_tolerance >= tolerance_bound: from warnings import warn warn("rec_grid: could not regularize structured " "vandermonde matrix for el #%d by enlargement" % el.id) break #from pytools import average #print average(eog.weight_factors), min(s) #raw_input() if my_tolerance > self.el_tolerance: print "element %d: #nodes=%d, orig #sgridpt=%d, extra tol=%g, #extra points=%d" % ( el.id, ldis.node_count(), orig_point_count, my_tolerance-self.el_tolerance, len(points)-orig_point_count) cond_claims += len(points)-orig_point_count min_s_values.append(min(s)) max_s_values.append(max(s)) cond_s_values.append(max(s)/min(s)) if max(s)/min(s) > 1e2: for i in range(len(s)): if s[0]/s[i] > 1e2: zeroed_mode = vt[i] zeroed_mode_nodal = numpy.dot(ldis.vandermonde(), zeroed_mode) print el.id, i, s[0]/s[i] fromvec = discr.volume_zeros() fromvec[discr.find_el_range(el.id)] = zeroed_mode_nodal gn = list(eog.grid_nodes) assert len(gn) == len(u[i]) tovec = numpy.zeros((backend.grid_node_count_with_extra(),), dtype=float) tovec[gn] = s[i]*u[i] usevec = numpy.zeros((backend.grid_node_count_with_extra(),), dtype=float) usevec[gn] = 1 visf = vis.make_file("nulled-%04d%02d" % (el.id, i)) vis.add_data(visf, [("meshmode", proj(fromvec))], expressions=[ ("absmesh", "abs(meshmode)"), ("absgrid", "abs(gridmode)"), ]) self.visualize_grid_quantities(visf, [ ("gridmode", tovec), ("usevec", usevec), ], ) visf.close() #print s #raw_input() self.make_pointwise_interpolation_matrix(eog, eg, el, ldis, svd, scaled_vdm) backend.elements_on_grid.append(eog) # we don't need no stinkin' extra points backend.extra_point_brick_starts.extend([0]*(len(backend.bricks)+1)) # print some statistics self.generate_point_statistics(cond_claims)
def main(): from hedge.backends import guess_run_context rcon = guess_run_context() if rcon.is_head_rank: mesh = make_nacamesh() mesh_data = rcon.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() from pytools import add_python_path_relative_to_script add_python_path_relative_to_script("..") for order in [4]: from gas_dynamics_initials import UniformMachFlow uniform_flow = UniformMachFlow() from hedge.models.gas_dynamics import GasDynamicsOperator, GammaLawEOS op = GasDynamicsOperator( dimensions=2, equation_of_state=GammaLawEOS(uniform_flow.gamma), prandtl=uniform_flow.prandtl, spec_gas_const=uniform_flow.spec_gas_const, mu=uniform_flow.mu, bc_inflow=uniform_flow, bc_outflow=uniform_flow, bc_noslip=uniform_flow, inflow_tag="inflow", outflow_tag="outflow", noslip_tag="noslip", ) discr = rcon.make_discretization( mesh_data, order=order, debug=[ "cuda_no_plan", # "cuda_dump_kernels", # "dump_optemplate_stages", # "dump_dataflow_graph", # "print_op_code" ], default_scalar_type=numpy.float32, tune_for=op.op_template(), ) from hedge.visualization import SiloVisualizer, VtkVisualizer # vis = VtkVisualizer(discr, rcon, "shearflow-%d" % order) vis = SiloVisualizer(discr, rcon) fields = uniform_flow.volume_interpolant(0, discr) navierstokes_ex = op.bind(discr) max_eigval = [0] def rhs(t, q): ode_rhs, speed = navierstokes_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) from hedge.timestep.runge_kutta import ODE23TimeStepper, LSRK4TimeStepper stepper = ODE23TimeStepper( dtype=discr.default_scalar_type, rtol=1e-6, vector_primitive_factory=discr.get_vector_primitive_factory() ) # stepper = LSRK4TimeStepper(dtype=discr.default_scalar_type) # diagnostics setup --------------------------------------------------- from pytools.log import LogManager, add_general_quantities, add_simulation_quantities, add_run_info logmgr = LogManager("cns-naca-%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) from pytools.log import LogQuantity class ChangeSinceLastStep(LogQuantity): """Records the change of a variable between a time step and the previous one""" def __init__(self, name="change"): LogQuantity.__init__(self, name, "1", "Change since last time step") self.old_fields = 0 def __call__(self): result = discr.norm(fields - self.old_fields) self.old_fields = fields return result # logmgr.add_quantity(ChangeSinceLastStep()) # filter setup------------------------------------------------------------- from hedge.discretization import Filter, ExponentialFilterResponseFunction mode_filter = Filter(discr, ExponentialFilterResponseFunction(min_amplification=0.9, order=4)) # timestep loop ------------------------------------------------------- logmgr.add_watches(["step.max", "t_sim.max", "t_step.max"]) try: from hedge.timestep import times_and_steps step_it = times_and_steps( final_time=200, # max_steps=500, logmgr=logmgr, max_dt_getter=lambda t: next_dt, taken_dt_getter=lambda: taken_dt, ) model_stepper = LSRK4TimeStepper() next_dt = op.estimate_timestep(discr, stepper=model_stepper, t=0, max_eigenvalue=max_eigval[0]) for step, t, dt in step_it: if step % 10 == 0: visf = vis.make_file("naca-%d-%06d" % (order, step)) 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", discr.convert_volume(op.rho(rhs_fields), kind="numpy")), # ("rhs_e", discr.convert_volume(op.e(rhs_fields), kind="numpy")), # ("rhs_rho_u", discr.convert_volume(op.rho_u(rhs_fields), kind="numpy")), ], 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, t, taken_dt, next_dt = stepper(fields, t, dt, rhs) fields = mode_filter(fields) finally: vis.close() logmgr.save() discr.close()
def compute_initial_condition(rcon, discr, method, state, maxwell_op, potential_bc, force_zero=False): from hedge.models.poisson import PoissonOperator from hedge.mesh import TAG_ALL, TAG_NONE from hedge.data import ConstantGivenFunction, GivenVolumeInterpolant def rel_l2_error(field, true): from hedge.tools import relative_error return relative_error( discr.norm(field-true), discr.norm(true)) mean_beta = method.mean_beta(state) gamma = method.units.gamma_from_beta(mean_beta) # see doc/notes.tm for derivation of IC def make_scaling_matrix(beta_scale, other_scale): if la.norm(mean_beta) < 1e-10: return other_scale*numpy.eye(discr.dimensions) else: beta_unit = mean_beta/la.norm(mean_beta) return (other_scale*numpy.identity(discr.dimensions) + (beta_scale-other_scale)*numpy.outer(beta_unit, beta_unit)) poisson_op = PoissonOperator( discr.dimensions, diffusion_tensor=make_scaling_matrix(1/gamma**2, 1), dirichlet_tag=TAG_ALL, neumann_tag=TAG_NONE, dirichlet_bc=potential_bc) rho_prime = method.deposit_rho(state) rho_tilde = rho_prime/gamma bound_poisson = poisson_op.bind(discr) if force_zero: phi_tilde = discr.volume_zeros() else: from hedge.iterative import parallel_cg phi_tilde = -parallel_cg(rcon, -bound_poisson, bound_poisson.prepare_rhs( rho_tilde/maxwell_op.epsilon), debug=40 if "poisson" in method.debug else False, tol=1e-10) from hedge.tools import ptwise_dot from hedge.models.nd_calculus import GradientOperator e_tilde = ptwise_dot(2, 1, make_scaling_matrix(1/gamma, 1), GradientOperator(discr.dimensions).bind(discr)(phi_tilde)) e_prime = ptwise_dot(2, 1, make_scaling_matrix(1, gamma), e_tilde) from pyrticle.tools import make_cross_product v_e_to_h_cross = make_cross_product(method, maxwell_op, "v", "e", "h") h_prime = (1/maxwell_op.mu)*gamma/maxwell_op.c * v_e_to_h_cross(mean_beta, e_tilde) if "ic" in method.debug: deposited_charge = discr.integral(rho_prime) real_charge = numpy.sum(state.charges) print "charge: supposed=%g deposited=%g error=%g %%" % ( real_charge, deposited_charge, 100*abs(deposited_charge-real_charge)/abs(real_charge) ) from hedge.models.nd_calculus import DivergenceOperator bound_div_op = DivergenceOperator(discr.dimensions).bind(discr) d_tilde = maxwell_op.epsilon*e_tilde d_prime = maxwell_op.epsilon*e_prime #divD_prime_ldg = bound_poisson.div(d_prime) #divD_prime_ldg2 = bound_poisson.div(d_prime, maxwell_op.epsilon*gamma*phi_tilde) from hedge.optemplate import InverseMassOperator divD_prime_ldg3 = maxwell_op.epsilon*\ (InverseMassOperator().apply(discr, bound_poisson.op(gamma*phi_tilde))) divD_prime_central = bound_div_op(d_prime) print "l2 div D_prime error central: %g" % \ rel_l2_error(divD_prime_central, rho_prime) #print "l2 div D_prime error ldg: %g" % \ #rel_l2_error(divD_prime_ldg, rho_prime) #print "l2 div D_prime error ldg with phi: %g" % \ #rel_l2_error(divD_prime_ldg2, rho_prime) print "l2 div D_prime error ldg with phi 3: %g" % \ rel_l2_error(divD_prime_ldg3, rho_prime) if "vis_files" in method.debug: from hedge.visualization import SiloVisualizer vis = SiloVisualizer(discr) visf = vis.make_file("ic") vis.add_data(visf, [ ("phi_moving", phi_tilde), ("rho_moving", rho_tilde), ("e_moving", e_tilde), ("rho_lab", rho_prime), #("divD_lab_ldg", divD_prime_ldg), #("divD_lab_ldg2", divD_prime_ldg2), #("divD_lab_ldg3", divD_prime_ldg3), ("divD_lab_central", divD_prime_central), ("e_lab", e_prime), ("h_lab", h_prime), ], ) method.add_to_vis(vis, visf, state) visf.close() return maxwell_op.assemble_fields(e=e_prime, h=h_prime, discr=discr)
def optimize_shape_bandwidth(method, state, analytic_rho, exponent): discr = method.discretization rec = method.depositor adv_radius = method.mesh_data.advisable_particle_radius() radii = [adv_radius*2**i for i in numpy.linspace(-4, 2, 50)] def set_radius(r): method.depositor.set_shape_function( state, method.get_shape_function_class() (r, method.mesh_data.dimensions, exponent,)) tried_radii = [] l1_errors = [] debug = "shape_bw" in method.debug visualize = set(["shape_bw", "vis_files"]) <= method.debug if visualize: from hedge.visualization import SiloVisualizer vis = SiloVisualizer(discr) import sys if debug: sys.stdout.write("optimizing shape bw (%d attempts): " % len(radii)) for step, radius in enumerate(radii): if debug: sys.stdout.write("%d." % step) sys.stdout.flush() try: try: method.set_ignore_core_warnings(True) set_radius(radius) except RuntimeError, re: if "particle mass is zero" in str(re): continue else: raise finally: method.set_ignore_core_warnings(False) state.derived_quantity_cache.clear() try: try: method.set_ignore_core_warnings(True) rec_rho = method.deposit_rho(state) except RuntimeError, re: if "particle mass is zero" in str(re): continue else: raise finally: method.set_ignore_core_warnings(False) tried_radii.append(radius) l1_errors.append(discr.integral(numpy.abs(rec_rho-analytic_rho))) if visualize: visf = vis.make_file("bwopt-%04d" % step) method.add_to_vis(vis, visf, state, time=radius, step=step) vis.add_data(visf, [ ("rho", rec_rho), #("j", method.deposit_j(state)), ("rho_analytic", analytic_rho), ], expressions=[("rho_diff", "rho-rho_analytic")], time=radius, step=step) try: rec.visualize_grid_quantities except AttributeError: pass else: rec.visualize_grid_quantities(visf, [ ("rho_grid", rec.deposit_grid_rho(state)), ("j_grid", rec.deposit_grid_j(state, method.velocities(state))), ("rho_resid", rec.remap_residual(rec.deposit_grid_rho(state))), ]) visf.close() if debug: sys.stdout.write("\n") sys.stdout.flush() if visualize: vis.close() from pytools import argmin min_idx = argmin(l1_errors) min_rad = tried_radii[min_idx] min_l1_error = l1_errors[min_idx] rel_l1_error = abs(min_l1_error / discr.integral(analytic_rho)) if rel_l1_error > 0.1: from warnings import warn warn("Charge density is very poorly resolved (rel L1 error=%g)" % rel_l1_error) def is_local_minimum(list, i): if i == 0: return False elif i == len(list)-1: return False else: return list[i] < list[i-1] and list[i] < list[i+1] local_minima = [idx for idx in range(len(tried_radii)) if is_local_minimum(l1_errors, idx)] chosen_idx = max(local_minima) chosen_rad = tried_radii[chosen_idx] if "shape_bw" in method.debug: chosen_l1_error = l1_errors[chosen_idx] print "radius: guessed optimum=%g, found optimum=%g, chosen=%g" % ( adv_radius, min_rad, chosen_rad) print "radius: optimum l1 error=%g, chosen l1 error=%g" % ( min_l1_error, chosen_l1_error) set_radius(chosen_rad) state.derived_quantity_cache.clear() if set(["interactive", "shape_bw"]) < method.debug: from pylab import semilogx, show semilogx(tried_radii, l1_errors) show()
def inner_run(self): t = 0 setup = self.setup setup.hook_startup(self) vis_order = setup.vis_order if vis_order is None: vis_order = setup.element_order if vis_order != setup.element_order: vis_discr = self.rcon.make_discretization(self.discr.mesh, order=vis_order, debug=setup.dg_debug) from hedge.discretization import Projector vis_proj = Projector(self.discr, vis_discr) else: vis_discr = self.discr def vis_proj(f): return f from hedge.visualization import SiloVisualizer vis = SiloVisualizer(vis_discr) fields = self.fields self.observer.set_fields_and_state(fields, self.state) from hedge.tools import make_obj_array from pyrticle.cloud import TimesteppablePicState def visualize(observer): sub_timer = self.vis_timer.start_sub_timer() import os.path visf = vis.make_file( os.path.join(setup.output_path, setup.vis_pattern % step)) self.method.add_to_vis(vis, visf, observer.state, time=t, step=step) vis.add_data( visf, [(name, vis_proj(fld)) for name, fld in setup.hook_vis_quantities(observer)], time=t, step=step) setup.hook_visualize(self, vis, visf, observer) visf.close() sub_timer.stop().submit() from hedge.timestep.multirate_ab import TwoRateAdamsBashforthTimeStepper if not isinstance(self.stepper, TwoRateAdamsBashforthTimeStepper): def rhs(t, fields_and_state): fields, ts_state = fields_and_state state_f = lambda: ts_state.state fields_f = lambda: fields fields_rhs = (self.f_rhs_calculator(t, fields_f, state_f) + self.p2f_rhs_calculator(t, fields_f, state_f)) state_rhs = (self.p_rhs_calculator(t, fields_f, state_f) + self.f2p_rhs_calculator(t, fields_f, state_f)) return make_obj_array([fields_rhs, state_rhs]) step_args = (self.dt, rhs) else: def add_unwrap(rhs): def unwrapping_rhs(t, fields, ts_state): return rhs(t, fields, lambda: ts_state().state) return unwrapping_rhs step_args = (( add_unwrap(self.f_rhs_calculator), add_unwrap(self.p2f_rhs_calculator), add_unwrap(self.f2p_rhs_calculator), add_unwrap(self.p_rhs_calculator), ), ) y = make_obj_array( [fields, TimesteppablePicState(self.method, self.state)]) del self.state try: from hedge.timestep import times_and_steps step_it = times_and_steps(max_steps=self.nsteps, logmgr=self.logmgr, max_dt_getter=lambda t: self.dt) for step, t, dt in step_it: self.method.upkeep(y[1].state) if step % setup.vis_interval == 0: visualize(self.observer) y = self.stepper(y, t, *step_args) fields, ts_state = y self.observer.set_fields_and_state(fields, ts_state.state) setup.hook_after_step(self, self.observer) finally: vis.close() self.discr.close() self.logmgr.save() setup.hook_when_done(self)
def prepare_with_pointwise_projection_and_basis_reduction(self): discr = self.method.discretization backend = self.backend backend.elements_on_grid.reserve( sum(len(eg.members) for eg in discr.element_groups)) min_s_values = [] max_s_values = [] cond_s_values = [] basis_len_vec = discr.volume_zeros() el_condition_vec = discr.volume_zeros() point_count_vec = discr.volume_zeros() # Iterate over all elements for eg in discr.element_groups: ldis = eg.local_discretization mode_id_to_index = dict( (bid, i) for i, bid in enumerate(ldis.generate_mode_identifiers())) for el in eg.members: basis = list( zip(ldis.generate_mode_identifiers(), ldis.basis_functions())) eog, points = self.find_points_in_element( el, self.el_tolerance) while True: scaled_vdm = self.scaled_vandermonde( el, eog, points, [bf for bid, bf in basis]) max_bid_sum = max(sum(bid) for bid, bf in basis) killable_basis_elements = [ (i, bid) for i, (bid, bf) in enumerate(basis) if sum(bid) == max_bid_sum ] try: u, s, vt = svd = la.svd(scaled_vdm) thresh = (numpy.finfo(float).eps * max(scaled_vdm.shape) * s[0]) assert s[-1] == numpy.min(s) assert s[0] == numpy.max(s) # Imagine that--s can have negative entries. # (AK: I encountered one negative zero.) if len(basis) > len(points) or numpy.abs( s[0] / s[-1]) > 10: retry = True # badly conditioned, kill a basis entry vti = vt[-1] from pytools import argmax2 kill_idx, kill_bid = argmax2( ((j, bid), abs(vti[j])) for j, bid in killable_basis_elements) assert kill_bid == basis[kill_idx][0] basis.pop(kill_idx) else: retry = False except la.LinAlgError: # SVD likely didn't converge. Lacking an SVD, we don't have # much guidance on what modes to kill. Any of the killable # ones will do. # Bang, you're dead. basis.pop(killable_basis_elements[0][0]) retry = True if not retry: break if len(basis) == 1: raise RuntimeError( "basis reduction has killed almost the entire basis on element %d" % el.id) if ldis.node_count() > len(basis): print "element %d: #nodes=%d, killed modes=%d" % ( el.id, ldis.node_count(), ldis.node_count() - len(basis), ) basis_len_vec[discr.find_el_range(el.id)] = len(basis) el_condition_vec[discr.find_el_range(el.id)] = s[0] / s[-1] point_count_vec[discr.find_el_range(el.id)] = len(points) min_s_values.append(min(s)) max_s_values.append(max(s)) cond_s_values.append(max(s) / min(s)) self.make_pointwise_interpolation_matrix( eog, eg, el, ldis, svd, scaled_vdm, basis_subset=[mode_id_to_index[bid] for bid, bf in basis]) backend.elements_on_grid.append(eog) # visualize basis length for each element if set(["depositor", "vis_files"]) < self.method.debug: from hedge.visualization import SiloVisualizer vis = SiloVisualizer(discr) visf = vis.make_file("rec-debug") vis.add_data(visf, [ ("basis_len", basis_len_vec), ("el_condition", el_condition_vec), ("point_count", point_count_vec), ]) visf.close() # we don't need no stinkin' extra points backend.extra_point_brick_starts.extend([0] * (len(backend.bricks) + 1)) # print some statistics self.generate_point_statistics()
def main(): from hedge.backends import guess_run_context rcon = guess_run_context(["cuda", "mpi"]) if rcon.is_head_rank: mesh = make_wingmesh() #from hedge.mesh import make_rect_mesh #mesh = make_rect_mesh( # boundary_tagger=lambda fvi, el, fn, all_v: ["inflow"]) mesh_data = rcon.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() for order in [3]: from pytools import add_python_path_relative_to_script add_python_path_relative_to_script("..") from gas_dynamics_initials import UniformMachFlow wing = UniformMachFlow(angle_of_attack=0) from hedge.models.gas_dynamics import GasDynamicsOperator op = GasDynamicsOperator(dimensions=3, gamma=wing.gamma, mu=wing.mu, prandtl=wing.prandtl, spec_gas_const=wing.spec_gas_const, bc_inflow=wing, bc_outflow=wing, bc_noslip=wing, inflow_tag="inflow", outflow_tag="outflow", noslip_tag="noslip") discr = rcon.make_discretization( mesh_data, order=order, debug=[ "cuda_no_plan", #"cuda_dump_kernels", #"dump_dataflow_graph", #"dump_optemplate_stages", #"dump_dataflow_graph", #"print_op_code" "cuda_no_metis", ], default_scalar_type=numpy.float64, tune_for=op.op_template()) from hedge.visualization import SiloVisualizer, VtkVisualizer #vis = VtkVisualizer(discr, rcon, "shearflow-%d" % order) vis = SiloVisualizer(discr, rcon) fields = wing.volume_interpolant(0, discr) navierstokes_ex = op.bind(discr) max_eigval = [0] def rhs(t, q): ode_rhs, speed = navierstokes_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) from hedge.timestep import RK4TimeStepper stepper = RK4TimeStepper() # diagnostics setup --------------------------------------------------- from pytools.log import LogManager, add_general_quantities, \ add_simulation_quantities, add_run_info logmgr = LogManager("navierstokes-%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"]) # timestep loop ------------------------------------------------------- try: from hedge.timestep import times_and_steps step_it = times_and_steps( final_time=200, #max_steps=500, logmgr=logmgr, max_dt_getter=lambda t: 0.6 * op.estimate_timestep( discr, stepper=stepper, t=t, max_eigenvalue=max_eigval[0])) for step, t, dt in step_it: if step % 200 == 0: #if False: visf = vis.make_file("wing-%d-%06d" % (order, step)) #rhs_fields = rhs(t, fields) from pyvisfile.silo import DB_VARTYPE_VECTOR from hedge.discretization import ones_on_boundary 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")), #("rhs_rho", discr.convert_volume(op.rho(rhs_fields), kind="numpy")), #("rhs_e", discr.convert_volume(op.e(rhs_fields), kind="numpy")), #("rhs_rho_u", discr.convert_volume(op.rho_u(rhs_fields), kind="numpy")), ], expressions=[ ("p", "(0.4)*(e- 0.5*(rho_u*u))"), ], time=t, step=step) visf.close() fields = stepper(fields, t, dt, rhs) t += dt finally: vis.close() logmgr.save() discr.close()
def main(): from hedge.backends import guess_run_context rcon = guess_run_context(["cuda"]) if rcon.is_head_rank: mesh = make_boxmesh() #from hedge.mesh import make_rect_mesh #mesh = make_rect_mesh( # boundary_tagger=lambda fvi, el, fn, all_v: ["inflow"]) mesh_data = rcon.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() for order in [3]: from pytools import add_python_path_relative_to_script add_python_path_relative_to_script("..") from gas_dynamics_initials import UniformMachFlow box = UniformMachFlow(angle_of_attack=0) from hedge.models.gas_dynamics import GasDynamicsOperator op = GasDynamicsOperator(dimensions=3, gamma=box.gamma, mu=box.mu, prandtl=box.prandtl, spec_gas_const=box.spec_gas_const, bc_inflow=box, bc_outflow=box, bc_noslip=box, inflow_tag="inflow", outflow_tag="outflow", noslip_tag="noslip") discr = rcon.make_discretization( mesh_data, order=order, debug=[ #"cuda_no_plan", #"cuda_dump_kernels", #"dump_dataflow_graph", #"dump_optemplate_stages", #"dump_dataflow_graph", #"print_op_code", "cuda_no_plan_el_local", ], default_scalar_type=numpy.float32, tune_for=op.op_template()) from hedge.visualization import SiloVisualizer, VtkVisualizer # noqa #vis = VtkVisualizer(discr, rcon, "shearflow-%d" % order) vis = SiloVisualizer(discr, rcon) fields = box.volume_interpolant(0, discr) navierstokes_ex = op.bind(discr) max_eigval = [0] def rhs(t, q): ode_rhs, speed = navierstokes_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) from hedge.timestep import RK4TimeStepper stepper = RK4TimeStepper() # diagnostics setup --------------------------------------------------- from pytools.log import LogManager, add_general_quantities, \ add_simulation_quantities, add_run_info logmgr = LogManager("navierstokes-%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"]) from pytools.log import LogQuantity class ChangeSinceLastStep(LogQuantity): """Records the change of a variable between a time step and the previous one""" def __init__(self, name="change"): LogQuantity.__init__(self, name, "1", "Change since last time step") self.old_fields = 0 def __call__(self): result = discr.norm(fields - self.old_fields) self.old_fields = fields return result logmgr.add_quantity(ChangeSinceLastStep()) # timestep loop ------------------------------------------------------- try: from hedge.timestep import times_and_steps step_it = times_and_steps( final_time=200, #max_steps=500, 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 % 200 == 0: #if False: visf = vis.make_file("box-%d-%06d" % (order, step)) #rhs_fields = rhs(t, fields) 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")), # ("rhs_rho", discr.convert_volume( # op.rho(rhs_fields), kind="numpy")), # ("rhs_e", discr.convert_volume( # op.e(rhs_fields), kind="numpy")), # ("rhs_rho_u", discr.convert_volume( # op.rho_u(rhs_fields), kind="numpy")), ], expressions=[ ("p", "(0.4)*(e- 0.5*(rho_u*u))"), ], time=t, step=step) visf.close() fields = stepper(fields, t, dt, rhs) finally: vis.close() logmgr.save() discr.close()
def initialize(self, method): Depositor.initialize(self, method) backend_class = getattr( _internal, "GridFindDepositor" + method.get_dimensionality_suffix()) backend = self.backend = backend_class(method.mesh_data) discr = method.discretization grid_node_num_to_nodes = {} if self.brick_generator is None: bbox_min, bbox_max = discr.mesh.bounding_box() max_bbox_size = max(bbox_max - bbox_min) self.brick_generator = SingleBrickGenerator(mesh_margin=1e-3 * max_bbox_size, overresolve=0.2) from pyrticle._internal import Brick for i, (stepwidths, origin, dims) in enumerate(self.brick_generator(discr)): backend.bricks.append( Brick(i, backend.grid_node_count(), stepwidths, origin, dims)) from pyrticle._internal import BoxFloat for eg in discr.element_groups: ldis = eg.local_discretization for el in eg.members: el_bbox = BoxFloat(*el.bounding_box(discr.mesh.points)) el_slice = discr.find_el_range(el.id) for brk in backend.bricks: if brk.bounding_box().intersect(el_bbox).is_empty(): continue for node_num in range(el_slice.start, el_slice.stop): try: cell_number = brk.which_cell(discr.nodes[node_num]) except ValueError: pass else: grid_node_num_to_nodes.setdefault( brk.index(cell_number), []).append(node_num) from pytools import flatten unassigned_nodes = (set(xrange(len(discr))) - set(flatten(grid_node_num_to_nodes.itervalues()))) if unassigned_nodes: raise RuntimeError( "dep_grid_find: unassigned mesh nodes found. " "you should specify a mesh_margin when generating " "bricks") usecounts = numpy.zeros((backend.grid_node_count(), )) for gnn in xrange(backend.grid_node_count()): grid_nodes = grid_node_num_to_nodes.get(gnn, []) usecounts[gnn] = len(grid_nodes) backend.node_number_list_starts.append( len(backend.node_number_lists)) backend.node_number_lists.extend(grid_nodes) backend.node_number_list_starts.append(len(backend.node_number_lists)) if "depositor" in method.debug: from hedge.visualization import SiloVisualizer vis = SiloVisualizer(discr) visf = vis.make_file("grid-find-debug") vis.add_data(visf, []) self.visualize_grid_quantities(visf, [("usecounts", usecounts)]) visf.close() if "interactive" in cloud.debug: from matplotlib.pylab import hist, show hist(usecounts, bins=20) show()
def main(): import logging logging.basicConfig(level=logging.INFO) from hedge.backends import guess_run_context rcon = guess_run_context() if rcon.is_head_rank: if True: mesh = make_squaremesh() else: from hedge.mesh import make_rect_mesh mesh = make_rect_mesh( boundary_tagger=lambda fvi, el, fn, all_v: ["inflow"], max_area=0.1) mesh_data = rcon.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() from pytools import add_python_path_relative_to_script add_python_path_relative_to_script(".") for order in [3]: from gas_dynamics_initials import UniformMachFlow square = UniformMachFlow(gaussian_pulse_at=numpy.array([-2, 2]), pulse_magnitude=0.003) from hedge.models.gas_dynamics import ( GasDynamicsOperator, GammaLawEOS) op = GasDynamicsOperator(dimensions=2, equation_of_state=GammaLawEOS(square.gamma), mu=square.mu, prandtl=square.prandtl, spec_gas_const=square.spec_gas_const, bc_inflow=square, bc_outflow=square, bc_noslip=square, inflow_tag="inflow", outflow_tag="outflow", noslip_tag="noslip") discr = rcon.make_discretization(mesh_data, order=order, debug=["cuda_no_plan", "cuda_dump_kernels", #"dump_dataflow_graph", #"dump_optemplate_stages", #"dump_dataflow_graph", #"dump_op_code" #"cuda_no_plan_el_local" ], default_scalar_type=numpy.float64, tune_for=op.op_template(), quad_min_degrees={ "gasdyn_vol": 3*order, "gasdyn_face": 3*order, } ) from hedge.visualization import SiloVisualizer, VtkVisualizer #vis = VtkVisualizer(discr, rcon, "shearflow-%d" % order) vis = SiloVisualizer(discr, rcon) from hedge.timestep.runge_kutta import ( LSRK4TimeStepper, ODE23TimeStepper, ODE45TimeStepper) from hedge.timestep.dumka3 import Dumka3TimeStepper #stepper = LSRK4TimeStepper(dtype=discr.default_scalar_type, #vector_primitive_factory=discr.get_vector_primitive_factory()) stepper = ODE23TimeStepper(dtype=discr.default_scalar_type, rtol=1e-6, vector_primitive_factory=discr.get_vector_primitive_factory()) # Dumka works kind of poorly #stepper = Dumka3TimeStepper(dtype=discr.default_scalar_type, #rtol=1e-7, pol_index=2, #vector_primitive_factory=discr.get_vector_primitive_factory()) #from hedge.timestep.dumka3 import Dumka3TimeStepper #stepper = Dumka3TimeStepper(3, rtol=1e-7) # diagnostics setup --------------------------------------------------- from pytools.log import LogManager, add_general_quantities, \ add_simulation_quantities, add_run_info logmgr = LogManager("cns-square-sp-%d.dat" % order, "w", rcon.communicator) add_run_info(logmgr) add_general_quantities(logmgr) discr.add_instrumentation(logmgr) stepper.add_instrumentation(logmgr) from pytools.log import LogQuantity class ChangeSinceLastStep(LogQuantity): """Records the change of a variable between a time step and the previous one""" def __init__(self, name="change"): LogQuantity.__init__(self, name, "1", "Change since last time step") self.old_fields = 0 def __call__(self): result = discr.norm(fields - self.old_fields) self.old_fields = fields return result #logmgr.add_quantity(ChangeSinceLastStep()) add_simulation_quantities(logmgr) logmgr.add_watches(["step.max", "t_sim.max", "t_step.max"]) # filter setup ------------------------------------------------------------ from hedge.discretization import Filter, ExponentialFilterResponseFunction mode_filter = Filter(discr, ExponentialFilterResponseFunction(min_amplification=0.95, order=6)) # timestep loop ------------------------------------------------------- fields = square.volume_interpolant(0, discr) navierstokes_ex = op.bind(discr) max_eigval = [0] def rhs(t, q): ode_rhs, speed = navierstokes_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) try: from hedge.timestep import times_and_steps step_it = times_and_steps( final_time=1000, #max_steps=500, logmgr=logmgr, max_dt_getter=lambda t: next_dt, taken_dt_getter=lambda: taken_dt) model_stepper = LSRK4TimeStepper() next_dt = op.estimate_timestep(discr, stepper=model_stepper, t=0, max_eigenvalue=max_eigval[0]) for step, t, dt in step_it: #if (step % 10000 == 0): #and step < 950000) or (step % 500 == 0 and step > 950000): #if False: if step % 5 == 0: visf = vis.make_file("square-%d-%06d" % (order, step)) #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")), ], expressions=[ ("p", "(0.4)*(e- 0.5*(rho_u*u))"), ], time=t, step=step ) visf.close() if stepper.adaptive: fields, t, taken_dt, next_dt = stepper(fields, t, dt, rhs) else: taken_dt = dt fields = stepper(fields, t, dt, rhs) dt = op.estimate_timestep(discr, stepper=model_stepper, t=0, max_eigenvalue=max_eigval[0]) #fields = mode_filter(fields) finally: vis.close() logmgr.save() discr.close()
def test_2d_gauss_theorem(): """Verify Gauss's theorem explicitly on a mesh""" from hedge.mesh.generator import make_disk_mesh from math import sin, cos from numpy import dot mesh = make_disk_mesh() order = 2 discr = discr_class(mesh, order=order, debug=discr_class.noninteractive_debug_flags()) ref_discr = discr_class(mesh, order=order) from hedge.flux import make_normal, FluxScalarPlaceholder normal = make_normal(discr.dimensions) flux_f_ph = FluxScalarPlaceholder(0) one_sided_x = flux_f_ph.int * normal[0] one_sided_y = flux_f_ph.int * normal[1] def f1(x, el): return sin(3 * x[0]) + cos(3 * x[1]) def f2(x, el): return sin(2 * x[0]) + cos(x[1]) from hedge.discretization import ones_on_volume ones = ones_on_volume(discr) f1_v = discr.interpolate_volume_function(f1) f2_v = discr.interpolate_volume_function(f2) from hedge.optemplate import BoundaryPair, Field, make_nabla, \ get_flux_operator nabla = make_nabla(discr.dimensions) divergence = nabla[0].apply(discr, f1_v) + nabla[1].apply(discr, f2_v) int_div = discr.integral(divergence) flux_optp = ( get_flux_operator(one_sided_x)(BoundaryPair(Field("f1"), Field("fz"))) + get_flux_operator(one_sided_y)(BoundaryPair(Field("f2"), Field("fz")))) from hedge.mesh import TAG_ALL bdry_val = discr.compile(flux_optp)(f1=f1_v, f2=f2_v, fz=discr.boundary_zeros(TAG_ALL)) ref_bdry_val = ref_discr.compile(flux_optp)( f1=f1_v, f2=f2_v, fz=discr.boundary_zeros(TAG_ALL)) boundary_int = dot(bdry_val, ones) if False: from hedge.visualization import SiloVisualizer vis = SiloVisualizer(discr) visf = vis.make_file("test") from hedge.tools import make_obj_array from hedge.mesh import TAG_ALL vis.add_data(visf, [ ("bdry", bdry_val), ("ref_bdry", ref_bdry_val), ("div", divergence), ("f", make_obj_array([f1_v, f2_v])), ("n", discr.volumize_boundary_field(discr.boundary_normals(TAG_ALL), TAG_ALL)), ], expressions=[("bdiff", "bdry-ref_bdry")]) #print abs(boundary_int-int_div) assert abs(boundary_int - int_div) < 5e-15
def inner_run(self): t = 0 setup = self.setup setup.hook_startup(self) vis_order = setup.vis_order if vis_order is None: vis_order = setup.element_order if vis_order != setup.element_order: vis_discr = self.rcon.make_discretization(self.discr.mesh, order=vis_order, debug=setup.dg_debug) from hedge.discretization import Projector vis_proj = Projector(self.discr, vis_discr) else: vis_discr = self.discr def vis_proj(f): return f from hedge.visualization import SiloVisualizer vis = SiloVisualizer(vis_discr) fields = self.fields self.observer.set_fields_and_state(fields, self.state) from hedge.tools import make_obj_array from pyrticle.cloud import TimesteppablePicState def visualize(observer): sub_timer = self.vis_timer.start_sub_timer() import os.path visf = vis.make_file(os.path.join( setup.output_path, setup.vis_pattern % step)) self.method.add_to_vis(vis, visf, observer.state, time=t, step=step) vis.add_data(visf, [(name, vis_proj(fld)) for name, fld in setup.hook_vis_quantities(observer)], time=t, step=step) setup.hook_visualize(self, vis, visf, observer) visf.close() sub_timer.stop().submit() from hedge.timestep.multirate_ab import TwoRateAdamsBashforthTimeStepper if not isinstance(self.stepper, TwoRateAdamsBashforthTimeStepper): def rhs(t, fields_and_state): fields, ts_state = fields_and_state state_f = lambda: ts_state.state fields_f = lambda: fields fields_rhs = ( self.f_rhs_calculator(t, fields_f, state_f) + self.p2f_rhs_calculator(t, fields_f, state_f)) state_rhs = ( self.p_rhs_calculator(t, fields_f, state_f) + self.f2p_rhs_calculator(t, fields_f, state_f)) return make_obj_array([fields_rhs, state_rhs]) step_args = (self.dt, rhs) else: def add_unwrap(rhs): def unwrapping_rhs(t, fields, ts_state): return rhs(t, fields, lambda: ts_state().state) return unwrapping_rhs step_args = (( add_unwrap(self.f_rhs_calculator), add_unwrap(self.p2f_rhs_calculator), add_unwrap(self.f2p_rhs_calculator), add_unwrap(self.p_rhs_calculator), ),) y = make_obj_array([ fields, TimesteppablePicState(self.method, self.state) ]) del self.state try: from hedge.timestep import times_and_steps step_it = times_and_steps( max_steps=self.nsteps, logmgr=self.logmgr, max_dt_getter=lambda t: self.dt) for step, t, dt in step_it: self.method.upkeep(y[1].state) if step % setup.vis_interval == 0: visualize(self.observer) y = self.stepper(y, t, *step_args) fields, ts_state = y self.observer.set_fields_and_state(fields, ts_state.state) setup.hook_after_step(self, self.observer) finally: vis.close() self.discr.close() self.logmgr.save() setup.hook_when_done(self)
def run_setup(units, casename, setup, discr, pusher, visualize=False): from hedge.timestep.runge_kutta import LSRK4TimeStepper from hedge.visualization import SiloVisualizer from hedge.models.em import MaxwellOperator vis = SiloVisualizer(discr) from pyrticle.cloud import PicMethod from pyrticle.deposition.shape import ShapeFunctionDepositor method = PicMethod(discr, units, ShapeFunctionDepositor(), pusher(), 3, 3, debug=set(["verbose_vis"])) e, h = setup.fields(discr) b = units.MU0 * h init_positions = setup.positions(0) init_velocities = setup.velocities(0) nparticles = len(init_positions) state = method.make_state() method.add_particles(state, zip(init_positions, init_velocities, nparticles * [setup.charge], nparticles * [units.EL_MASS], ), nparticles) final_time = setup.final_time() nsteps = setup.nsteps() dt = final_time/nsteps # timestepping ------------------------------------------------------------ from hedge.models.em import MaxwellOperator max_op = MaxwellOperator( epsilon=units.EPSILON0, mu=units.MU0, flux_type=1) fields = max_op.assemble_eh(e, h) from pyrticle.cloud import \ FieldToParticleRhsCalculator, \ ParticleRhsCalculator p_rhs_calculator = ParticleRhsCalculator(method, max_op) f2p_rhs_calculator = FieldToParticleRhsCalculator(method, max_op) def rhs(t, ts_state): return (p_rhs_calculator(t, lambda: fields, lambda: ts_state.state) + f2p_rhs_calculator(t, lambda: fields, lambda: ts_state.state)) stepper = LSRK4TimeStepper() t = 0 bbox = discr.mesh.bounding_box() z_period = bbox[1][2] - bbox[0][2] def check_result(): from hedge.tools import cross deriv_dt = 1e-12 dim = discr.dimensions true_x = setup.positions(t) true_v = setup.velocities(t) true_f = [(p2-p1)/(2*deriv_dt) for p1, p2 in zip(setup.momenta(t-deriv_dt), setup.momenta(t+deriv_dt))] state = ts_state.state from pyrticle.tools import NumberShiftableVector vis_info = state.vis_listener.particle_vis_map sim_x = state.positions sim_v = method.velocities(state) sim_f = NumberShiftableVector.unwrap( vis_info["mag_force"] + vis_info["el_force"]) sim_el_f = NumberShiftableVector.unwrap(vis_info["el_force"]) sim_mag_f = NumberShiftableVector.unwrap(vis_info["mag_force"]) local_e = setup.e() local_b = units.MU0 * setup.h() x_err = 0 v_err = 0 f_err = 0 for i in range(len(state)): #real_f = numpy.array(cross(sim_v, setup.charge*local_b)) + setup.charge*local_e my_true_x = true_x[i] my_true_x[2] = my_true_x[2] % z_period if False and i == 0: #print "particle %d" % i print "pos:", la.norm(true_x[i]-sim_x[i])/la.norm(true_x[i]) #print "vel:", la.norm(true_v[i]-sim_v[i])/la.norm(true_v[i]) #print "force:", la.norm(true_f[i]-sim_f[i])/la.norm(true_f[i]) print "pos:", true_x[i], sim_x[i] #print "vel:", true_v[i], sim_v[i] #print "force:", true_f[i], sim_f[i] #print "forces%d:..." % i, sim_el_f[i], sim_mag_f[i] #print "acc%d:" % i, la.norm(a-sim_a) #u = numpy.vstack((v, sim_v, f, sim_f, real_f)) #print "acc%d:\n%s" % (i, u) #raw_input() def rel_err(sim, true): return la.norm(true-sim)/la.norm(true) x_err = max(x_err, rel_err(sim_x[i], my_true_x)) v_err = max(v_err, rel_err(sim_v[i], true_v[i])) f_err = max(f_err, rel_err(sim_f[i], true_f[i])) return x_err, v_err, f_err # make sure verbose-vis fields are filled from pyrticle.cloud import TimesteppablePicState ts_state = TimesteppablePicState(method, state) del state rhs(t, ts_state) errors = (0, 0, 0) for step in xrange(nsteps): if step % int(setup.nsteps()/300) == 0: errors = tuple( max(old_err, new_err) for old_err, new_err in zip(errors, check_result())) if visualize: visf = vis.make_file("%s-%04d" % (casename, step)) method.add_to_vis(vis, visf, ts_state.state, time=t, step=step) if True: vis.add_data(visf, [ ("e", e), ("h", h), ], time=t, step=step) else: vis.add_data(visf, [], time=t, step=step) visf.close() method.upkeep(ts_state.state) ts_state = stepper(ts_state, t, dt, rhs) t += dt assert errors[0] < 2e-12, casename+"-pos" assert errors[1] < 2e-13, casename+"-vel" assert errors[2] < 2e-4, casename+"-acc" vis.close()
def check_time_harmonic_solution(discr, mode, c_sol): from hedge.discretization import bind_nabla, bind_mass_matrix from hedge.visualization import SiloVisualizer from hedge.silo import SiloFile from hedge.tools import dot, cross from hedge.silo import DB_VARTYPE_VECTOR def curl(field): return cross(nabla, field) vis = SiloVisualizer(discr) nabla = bind_nabla(discr) mass = bind_mass_matrix(discr) def rel_l2_error(err, base): def l2_norm(field): return sqrt(dot(field, mass * field)) base_l2 = l2_norm(base) err_l2 = l2_norm(err) if base_l2 == 0: if err_l2 == 0: return 0. else: return float("inf") else: return err_l2 / base_l2 dt = 0.1 for step in range(10): t = step * dt mode.set_time(t) fields = discr.interpolate_volume_function(c_sol) er = fields[0:3] hr = fields[3:6] ei = fields[6:9] hi = fields[9:12] silo = SiloFile("em-complex-%04d.silo" % step) vis.add_to_silo(silo, vectors=[ ("curl_er", curl(er)), ("om_hi", -mode.mu * mode.omega * hi), ("curl_hr", curl(hr)), ("om_ei", mode.epsilon * mode.omega * hi), ], expressions=[ ("diff_er", "curl_er-om_hi", DB_VARTYPE_VECTOR), ("diff_hr", "curl_hr-om_ei", DB_VARTYPE_VECTOR), ], write_coarse_mesh=True, time=t, step=step) er_res = curl(er) + mode.mu * mode.omega * hi ei_res = curl(ei) - mode.mu * mode.omega * hr hr_res = curl(hr) - mode.epsilon * mode.omega * ei hi_res = curl(hi) + mode.epsilon * mode.omega * er print "time=%f, rel l2 residual in Re[E]=%g\tIm[E]=%g\tRe[H]=%g\tIm[H]=%g" % ( t, rel_l2_error(er_res, er), rel_l2_error(ei_res, ei), rel_l2_error(hr_res, hr), rel_l2_error(hi_res, hi), )
def main(): from hedge.backends import guess_run_context rcon = guess_run_context(["cuda"]) if rcon.is_head_rank: mesh = make_boxmesh() #from hedge.mesh import make_rect_mesh #mesh = make_rect_mesh( # boundary_tagger=lambda fvi, el, fn, all_v: ["inflow"]) mesh_data = rcon.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() for order in [3]: from pytools import add_python_path_relative_to_script add_python_path_relative_to_script("..") from gas_dynamics_initials import UniformMachFlow box = UniformMachFlow(angle_of_attack=0) from hedge.models.gas_dynamics import GasDynamicsOperator op = GasDynamicsOperator(dimensions=3, gamma=box.gamma, mu=box.mu, prandtl=box.prandtl, spec_gas_const=box.spec_gas_const, bc_inflow=box, bc_outflow=box, bc_noslip=box, inflow_tag="inflow", outflow_tag="outflow", noslip_tag="noslip") discr = rcon.make_discretization(mesh_data, order=order, debug=[ #"cuda_no_plan", #"cuda_dump_kernels", #"dump_dataflow_graph", #"dump_optemplate_stages", #"dump_dataflow_graph", #"print_op_code", "cuda_no_plan_el_local", ], default_scalar_type=numpy.float32, tune_for=op.op_template()) from hedge.visualization import SiloVisualizer, VtkVisualizer # noqa #vis = VtkVisualizer(discr, rcon, "shearflow-%d" % order) vis = SiloVisualizer(discr, rcon) fields = box.volume_interpolant(0, discr) navierstokes_ex = op.bind(discr) max_eigval = [0] def rhs(t, q): ode_rhs, speed = navierstokes_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) from hedge.timestep import RK4TimeStepper stepper = RK4TimeStepper() # diagnostics setup --------------------------------------------------- from pytools.log import LogManager, add_general_quantities, \ add_simulation_quantities, add_run_info logmgr = LogManager("navierstokes-%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"]) from pytools.log import LogQuantity class ChangeSinceLastStep(LogQuantity): """Records the change of a variable between a time step and the previous one""" def __init__(self, name="change"): LogQuantity.__init__(self, name, "1", "Change since last time step") self.old_fields = 0 def __call__(self): result = discr.norm(fields - self.old_fields) self.old_fields = fields return result logmgr.add_quantity(ChangeSinceLastStep()) # timestep loop ------------------------------------------------------- try: from hedge.timestep import times_and_steps step_it = times_and_steps( final_time=200, #max_steps=500, 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 % 200 == 0: #if False: visf = vis.make_file("box-%d-%06d" % (order, step)) #rhs_fields = rhs(t, fields) 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")), # ("rhs_rho", discr.convert_volume( # op.rho(rhs_fields), kind="numpy")), # ("rhs_e", discr.convert_volume( # op.e(rhs_fields), kind="numpy")), # ("rhs_rho_u", discr.convert_volume( # op.rho_u(rhs_fields), kind="numpy")), ], expressions=[ ("p", "(0.4)*(e- 0.5*(rho_u*u))"), ], time=t, step=step ) visf.close() fields = stepper(fields, t, dt, rhs) finally: vis.close() logmgr.save() discr.close()
def initialize(self, method): Depositor.initialize(self, method) backend_class = getattr(_internal, "GridFindDepositor" + method.get_dimensionality_suffix()) backend = self.backend = backend_class(method.mesh_data) discr = method.discretization grid_node_num_to_nodes = {} if self.brick_generator is None: bbox_min, bbox_max = discr.mesh.bounding_box() max_bbox_size = max(bbox_max-bbox_min) self.brick_generator = SingleBrickGenerator( mesh_margin=1e-3*max_bbox_size, overresolve=0.2) from pyrticle._internal import Brick for i, (stepwidths, origin, dims) in enumerate( self.brick_generator(discr)): backend.bricks.append( Brick(i, backend.grid_node_count(), stepwidths, origin, dims)) from pyrticle._internal import BoxFloat for eg in discr.element_groups: ldis = eg.local_discretization for el in eg.members: el_bbox = BoxFloat(*el.bounding_box(discr.mesh.points)) el_slice = discr.find_el_range(el.id) for brk in backend.bricks: if brk.bounding_box().intersect(el_bbox).is_empty(): continue for node_num in range(el_slice.start, el_slice.stop): try: cell_number = brk.which_cell( discr.nodes[node_num]) except ValueError: pass else: grid_node_num_to_nodes.setdefault( brk.index(cell_number), []).append(node_num) from pytools import flatten unassigned_nodes = (set(xrange(len(discr))) - set(flatten(grid_node_num_to_nodes.itervalues()))) if unassigned_nodes: raise RuntimeError("dep_grid_find: unassigned mesh nodes found. " "you should specify a mesh_margin when generating " "bricks") usecounts = numpy.zeros( (backend.grid_node_count(),)) for gnn in xrange(backend.grid_node_count()): grid_nodes = grid_node_num_to_nodes.get(gnn, []) usecounts[gnn] = len(grid_nodes) backend.node_number_list_starts.append(len(backend.node_number_lists)) backend.node_number_lists.extend(grid_nodes) backend.node_number_list_starts.append(len(backend.node_number_lists)) if "depositor" in method.debug: from hedge.visualization import SiloVisualizer vis = SiloVisualizer(discr) visf = vis.make_file("grid-find-debug") vis.add_data(visf, []) self.visualize_grid_quantities(visf, [ ("usecounts", usecounts) ]) visf.close() if "interactive" in cloud.debug: from matplotlib.pylab import hist, show hist(usecounts, bins=20) show()
def compute_initial_condition(rcon, discr, method, state, maxwell_op, potential_bc, force_zero=False): from hedge.models.poisson import PoissonOperator from hedge.mesh import TAG_ALL, TAG_NONE from hedge.data import ConstantGivenFunction, GivenVolumeInterpolant def rel_l2_error(field, true): from hedge.tools import relative_error return relative_error(discr.norm(field - true), discr.norm(true)) mean_beta = method.mean_beta(state) gamma = method.units.gamma_from_beta(mean_beta) # see doc/notes.tm for derivation of IC def make_scaling_matrix(beta_scale, other_scale): if la.norm(mean_beta) < 1e-10: return other_scale * numpy.eye(discr.dimensions) else: beta_unit = mean_beta / la.norm(mean_beta) return ( other_scale * numpy.identity(discr.dimensions) + (beta_scale - other_scale) * numpy.outer(beta_unit, beta_unit)) poisson_op = PoissonOperator(discr.dimensions, diffusion_tensor=make_scaling_matrix( 1 / gamma**2, 1), dirichlet_tag=TAG_ALL, neumann_tag=TAG_NONE, dirichlet_bc=potential_bc) rho_prime = method.deposit_rho(state) rho_tilde = rho_prime / gamma bound_poisson = poisson_op.bind(discr) if force_zero: phi_tilde = discr.volume_zeros() else: from hedge.iterative import parallel_cg phi_tilde = -parallel_cg( rcon, -bound_poisson, bound_poisson.prepare_rhs(rho_tilde / maxwell_op.epsilon), debug=40 if "poisson" in method.debug else False, tol=1e-10) from hedge.tools import ptwise_dot from hedge.models.nd_calculus import GradientOperator e_tilde = ptwise_dot( 2, 1, make_scaling_matrix(1 / gamma, 1), GradientOperator(discr.dimensions).bind(discr)(phi_tilde)) e_prime = ptwise_dot(2, 1, make_scaling_matrix(1, gamma), e_tilde) from pyrticle.tools import make_cross_product v_e_to_h_cross = make_cross_product(method, maxwell_op, "v", "e", "h") h_prime = (1 / maxwell_op.mu) * gamma / maxwell_op.c * v_e_to_h_cross( mean_beta, e_tilde) if "ic" in method.debug: deposited_charge = discr.integral(rho_prime) real_charge = numpy.sum(state.charges) print "charge: supposed=%g deposited=%g error=%g %%" % ( real_charge, deposited_charge, 100 * abs(deposited_charge - real_charge) / abs(real_charge)) from hedge.models.nd_calculus import DivergenceOperator bound_div_op = DivergenceOperator(discr.dimensions).bind(discr) d_tilde = maxwell_op.epsilon * e_tilde d_prime = maxwell_op.epsilon * e_prime #divD_prime_ldg = bound_poisson.div(d_prime) #divD_prime_ldg2 = bound_poisson.div(d_prime, maxwell_op.epsilon*gamma*phi_tilde) from hedge.optemplate import InverseMassOperator divD_prime_ldg3 = maxwell_op.epsilon*\ (InverseMassOperator().apply(discr, bound_poisson.op(gamma*phi_tilde))) divD_prime_central = bound_div_op(d_prime) print "l2 div D_prime error central: %g" % \ rel_l2_error(divD_prime_central, rho_prime) #print "l2 div D_prime error ldg: %g" % \ #rel_l2_error(divD_prime_ldg, rho_prime) #print "l2 div D_prime error ldg with phi: %g" % \ #rel_l2_error(divD_prime_ldg2, rho_prime) print "l2 div D_prime error ldg with phi 3: %g" % \ rel_l2_error(divD_prime_ldg3, rho_prime) if "vis_files" in method.debug: from hedge.visualization import SiloVisualizer vis = SiloVisualizer(discr) visf = vis.make_file("ic") vis.add_data( visf, [ ("phi_moving", phi_tilde), ("rho_moving", rho_tilde), ("e_moving", e_tilde), ("rho_lab", rho_prime), #("divD_lab_ldg", divD_prime_ldg), #("divD_lab_ldg2", divD_prime_ldg2), #("divD_lab_ldg3", divD_prime_ldg3), ("divD_lab_central", divD_prime_central), ("e_lab", e_prime), ("h_lab", h_prime), ], ) method.add_to_vis(vis, visf, state) visf.close() return maxwell_op.assemble_fields(e=e_prime, h=h_prime, discr=discr)
def check_time_harmonic_solution(discr, mode, c_sol): from hedge.discretization import bind_nabla, bind_mass_matrix from hedge.visualization import SiloVisualizer from hedge.silo import SiloFile from hedge.tools import dot, cross from hedge.silo import DB_VARTYPE_VECTOR def curl(field): return cross(nabla, field) vis = SiloVisualizer(discr) nabla = bind_nabla(discr) mass = bind_mass_matrix(discr) def rel_l2_error(err, base): def l2_norm(field): return sqrt(dot(field, mass*field)) base_l2 = l2_norm(base) err_l2 = l2_norm(err) if base_l2 == 0: if err_l2 == 0: return 0. else: return float("inf") else: return err_l2/base_l2 dt = 0.1 for step in range(10): t = step*dt mode.set_time(t) fields = discr.interpolate_volume_function(c_sol) er = fields[0:3] hr = fields[3:6] ei = fields[6:9] hi = fields[9:12] silo = SiloFile("em-complex-%04d.silo" % step) vis.add_to_silo(silo, vectors=[ ("curl_er", curl(er)), ("om_hi", -mode.mu*mode.omega*hi), ("curl_hr", curl(hr)), ("om_ei", mode.epsilon*mode.omega*hi), ], expressions=[ ("diff_er", "curl_er-om_hi", DB_VARTYPE_VECTOR), ("diff_hr", "curl_hr-om_ei", DB_VARTYPE_VECTOR), ], write_coarse_mesh=True, time=t, step=step ) er_res = curl(er) + mode.mu *mode.omega*hi ei_res = curl(ei) - mode.mu *mode.omega*hr hr_res = curl(hr) - mode.epsilon*mode.omega*ei hi_res = curl(hi) + mode.epsilon*mode.omega*er print "time=%f, rel l2 residual in Re[E]=%g\tIm[E]=%g\tRe[H]=%g\tIm[H]=%g" % ( t, rel_l2_error(er_res, er), rel_l2_error(ei_res, ei), rel_l2_error(hr_res, hr), rel_l2_error(hi_res, hi), )
def run_setup(units, casename, setup, discr, pusher, visualize=False): from hedge.timestep.runge_kutta import LSRK4TimeStepper from hedge.visualization import SiloVisualizer from hedge.models.em import MaxwellOperator vis = SiloVisualizer(discr) from pyrticle.cloud import PicMethod from pyrticle.deposition.shape import ShapeFunctionDepositor method = PicMethod(discr, units, ShapeFunctionDepositor(), pusher(), 3, 3, debug=set(["verbose_vis"])) e, h = setup.fields(discr) b = units.MU0 * h init_positions = setup.positions(0) init_velocities = setup.velocities(0) nparticles = len(init_positions) state = method.make_state() method.add_particles( state, zip( init_positions, init_velocities, nparticles * [setup.charge], nparticles * [units.EL_MASS], ), nparticles) final_time = setup.final_time() nsteps = setup.nsteps() dt = final_time / nsteps # timestepping ------------------------------------------------------------ from hedge.models.em import MaxwellOperator max_op = MaxwellOperator(epsilon=units.EPSILON0, mu=units.MU0, flux_type=1) fields = max_op.assemble_eh(e, h) from pyrticle.cloud import \ FieldToParticleRhsCalculator, \ ParticleRhsCalculator p_rhs_calculator = ParticleRhsCalculator(method, max_op) f2p_rhs_calculator = FieldToParticleRhsCalculator(method, max_op) def rhs(t, ts_state): return (p_rhs_calculator(t, lambda: fields, lambda: ts_state.state) + f2p_rhs_calculator(t, lambda: fields, lambda: ts_state.state)) stepper = LSRK4TimeStepper() t = 0 bbox = discr.mesh.bounding_box() z_period = bbox[1][2] - bbox[0][2] def check_result(): from hedge.tools import cross deriv_dt = 1e-12 dim = discr.dimensions true_x = setup.positions(t) true_v = setup.velocities(t) true_f = [(p2 - p1) / (2 * deriv_dt) for p1, p2 in zip( setup.momenta(t - deriv_dt), setup.momenta(t + deriv_dt))] state = ts_state.state from pyrticle.tools import NumberShiftableVector vis_info = state.vis_listener.particle_vis_map sim_x = state.positions sim_v = method.velocities(state) sim_f = NumberShiftableVector.unwrap(vis_info["mag_force"] + vis_info["el_force"]) sim_el_f = NumberShiftableVector.unwrap(vis_info["el_force"]) sim_mag_f = NumberShiftableVector.unwrap(vis_info["mag_force"]) local_e = setup.e() local_b = units.MU0 * setup.h() x_err = 0 v_err = 0 f_err = 0 for i in range(len(state)): #real_f = numpy.array(cross(sim_v, setup.charge*local_b)) + setup.charge*local_e my_true_x = true_x[i] my_true_x[2] = my_true_x[2] % z_period if False and i == 0: #print "particle %d" % i print "pos:", la.norm(true_x[i] - sim_x[i]) / la.norm( true_x[i]) #print "vel:", la.norm(true_v[i]-sim_v[i])/la.norm(true_v[i]) #print "force:", la.norm(true_f[i]-sim_f[i])/la.norm(true_f[i]) print "pos:", true_x[i], sim_x[i] #print "vel:", true_v[i], sim_v[i] #print "force:", true_f[i], sim_f[i] #print "forces%d:..." % i, sim_el_f[i], sim_mag_f[i] #print "acc%d:" % i, la.norm(a-sim_a) #u = numpy.vstack((v, sim_v, f, sim_f, real_f)) #print "acc%d:\n%s" % (i, u) #raw_input() def rel_err(sim, true): return la.norm(true - sim) / la.norm(true) x_err = max(x_err, rel_err(sim_x[i], my_true_x)) v_err = max(v_err, rel_err(sim_v[i], true_v[i])) f_err = max(f_err, rel_err(sim_f[i], true_f[i])) return x_err, v_err, f_err # make sure verbose-vis fields are filled from pyrticle.cloud import TimesteppablePicState ts_state = TimesteppablePicState(method, state) del state rhs(t, ts_state) errors = (0, 0, 0) for step in xrange(nsteps): if step % int(setup.nsteps() / 300) == 0: errors = tuple( max(old_err, new_err) for old_err, new_err in zip(errors, check_result())) if visualize: visf = vis.make_file("%s-%04d" % (casename, step)) method.add_to_vis(vis, visf, ts_state.state, time=t, step=step) if True: vis.add_data(visf, [ ("e", e), ("h", h), ], time=t, step=step) else: vis.add_data(visf, [], time=t, step=step) visf.close() method.upkeep(ts_state.state) ts_state = stepper(ts_state, t, dt, rhs) t += dt assert errors[0] < 2e-12, casename + "-pos" assert errors[1] < 2e-13, casename + "-vel" assert errors[2] < 2e-4, casename + "-acc" vis.close()
def main(): from hedge.backends import guess_run_context rcon = guess_run_context( #["cuda"] ) from hedge.tools import EOCRecorder, to_obj_array eoc_rec = EOCRecorder() def boundary_tagger(vertices, el, face_nr, all_v): return ["inflow"] if rcon.is_head_rank: from hedge.mesh import make_rect_mesh, \ make_centered_regular_rect_mesh #mesh = make_rect_mesh((0,0), (10,1), max_area=0.01) refine = 1 mesh = make_centered_regular_rect_mesh((0,0), (10,1), n=(20,4), #periodicity=(True, False), post_refine_factor=refine, boundary_tagger=boundary_tagger) mesh_data = rcon.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() for order in [3]: discr = rcon.make_discretization(mesh_data, order=order, default_scalar_type=numpy.float64) from hedge.visualization import SiloVisualizer, VtkVisualizer #vis = VtkVisualizer(discr, rcon, "shearflow-%d" % order) vis = SiloVisualizer(discr, rcon) shearflow = SteadyShearFlow() fields = shearflow.volume_interpolant(0, discr) gamma, mu, prandtl, spec_gas_const = shearflow.properties() from hedge.models.gas_dynamics import GasDynamicsOperator op = GasDynamicsOperator(dimensions=2, gamma=gamma, mu=mu, prandtl=prandtl, spec_gas_const=spec_gas_const, bc_inflow=shearflow, bc_outflow=shearflow, bc_noslip=shearflow, inflow_tag="inflow", outflow_tag="outflow", noslip_tag="noslip") navierstokes_ex = op.bind(discr) max_eigval = [0] def rhs(t, q): ode_rhs, speed = navierstokes_ex(t, q) max_eigval[0] = speed return ode_rhs # needed to get first estimate of maximum eigenvalue rhs(0, fields) if rcon.is_head_rank: print "---------------------------------------------" print "order %d" % order print "---------------------------------------------" print "#elements=", len(mesh.elements) from hedge.timestep import RK4TimeStepper stepper = RK4TimeStepper() # diagnostics setup --------------------------------------------------- from pytools.log import LogManager, add_general_quantities, \ add_simulation_quantities, add_run_info logmgr = LogManager("navierstokes-cpu-%d-%d.dat" % (order, refine), "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"]) # timestep loop ------------------------------------------------------- try: from hedge.timestep import times_and_steps step_it = times_and_steps( final_time=0.3, #max_steps=500, 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 % 10 == 0: #if False: visf = vis.make_file("shearflow-%d-%04d" % (order, step)) #true_fields = shearflow.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", discr.convert_volume(op.rho(true_fields), kind="numpy")), #("true_e", discr.convert_volume(op.e(true_fields), kind="numpy")), #("true_rho_u", discr.convert_volume(op.rho_u(true_fields), kind="numpy")), #("true_u", discr.convert_volume(op.u(true_fields), kind="numpy")), ], 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) true_fields = shearflow.volume_interpolant(t, discr) l2_error = discr.norm(op.u(fields)-op.u(true_fields)) eoc_rec.add_data_point(order, l2_error) print print eoc_rec.pretty_print("P.Deg.", "L2 Error") logmgr.set_constant("l2_error", l2_error) finally: vis.close() logmgr.save() discr.close()
def prepare_with_pointwise_projection_and_enlargement(self): tolerance_bound = 1.5 discr = self.method.discretization backend = self.backend backend.elements_on_grid.reserve( sum(len(eg.members) for eg in discr.element_groups)) cond_claims = 0 min_s_values = [] max_s_values = [] cond_s_values = [] from hedge.discretization import Projector, Discretization fine_discr = Discretization(discr.mesh, order=8) proj = Projector(discr, fine_discr) from hedge.visualization import SiloVisualizer vis = SiloVisualizer(fine_discr) # Iterate over all elements for eg in discr.element_groups: ldis = eg.local_discretization for el in eg.members: # If the structured Vandermonde matrix is singular, # enlarge the element tolerance my_tolerance = self.el_tolerance orig_point_count = None while True: eog, points = self.find_points_in_element(el, my_tolerance) if orig_point_count is None: orig_point_count = len(points) scaled_vdm = self.scaled_vandermonde( el, eog, points, ldis.basis_functions()) bad_vdm = len(points) < ldis.node_count() if not bad_vdm: try: u, s, vt = svd = la.svd(scaled_vdm) thresh = (numpy.finfo(float).eps * max(scaled_vdm.shape) * s[0]) zero_indices = [ i for i, si in enumerate(s) if abs(si) < thresh ] bad_vdm = bool(zero_indices) except la.LinAlgError: bad_vdm = True if not bad_vdm: break my_tolerance += 0.03 if my_tolerance >= tolerance_bound: from warnings import warn warn("rec_grid: could not regularize structured " "vandermonde matrix for el #%d by enlargement" % el.id) break #from pytools import average #print average(eog.weight_factors), min(s) #raw_input() if my_tolerance > self.el_tolerance: print "element %d: #nodes=%d, orig #sgridpt=%d, extra tol=%g, #extra points=%d" % ( el.id, ldis.node_count(), orig_point_count, my_tolerance - self.el_tolerance, len(points) - orig_point_count) cond_claims += len(points) - orig_point_count min_s_values.append(min(s)) max_s_values.append(max(s)) cond_s_values.append(max(s) / min(s)) if max(s) / min(s) > 1e2: for i in range(len(s)): if s[0] / s[i] > 1e2: zeroed_mode = vt[i] zeroed_mode_nodal = numpy.dot( ldis.vandermonde(), zeroed_mode) print el.id, i, s[0] / s[i] fromvec = discr.volume_zeros() fromvec[discr.find_el_range( el.id)] = zeroed_mode_nodal gn = list(eog.grid_nodes) assert len(gn) == len(u[i]) tovec = numpy.zeros( (backend.grid_node_count_with_extra(), ), dtype=float) tovec[gn] = s[i] * u[i] usevec = numpy.zeros( (backend.grid_node_count_with_extra(), ), dtype=float) usevec[gn] = 1 visf = vis.make_file("nulled-%04d%02d" % (el.id, i)) vis.add_data(visf, [("meshmode", proj(fromvec))], expressions=[ ("absmesh", "abs(meshmode)"), ("absgrid", "abs(gridmode)"), ]) self.visualize_grid_quantities( visf, [ ("gridmode", tovec), ("usevec", usevec), ], ) visf.close() #print s #raw_input() self.make_pointwise_interpolation_matrix( eog, eg, el, ldis, svd, scaled_vdm) backend.elements_on_grid.append(eog) # we don't need no stinkin' extra points backend.extra_point_brick_starts.extend([0] * (len(backend.bricks) + 1)) # print some statistics self.generate_point_statistics(cond_claims)
def test_2d_gauss_theorem(): """Verify Gauss's theorem explicitly on a mesh""" from hedge.mesh.generator import make_disk_mesh from math import sin, cos, sqrt, exp, pi from numpy import dot mesh = make_disk_mesh() order = 2 discr = discr_class(mesh, order=order, debug=discr_class.noninteractive_debug_flags()) ref_discr = discr_class(mesh, order=order) from hedge.flux import make_normal, FluxScalarPlaceholder normal = make_normal(discr.dimensions) flux_f_ph = FluxScalarPlaceholder(0) one_sided_x = flux_f_ph.int * normal[0] one_sided_y = flux_f_ph.int * normal[1] def f1(x, el): return sin(3 * x[0]) + cos(3 * x[1]) def f2(x, el): return sin(2 * x[0]) + cos(x[1]) from hedge.discretization import ones_on_volume ones = ones_on_volume(discr) f1_v = discr.interpolate_volume_function(f1) f2_v = discr.interpolate_volume_function(f2) from hedge.optemplate import BoundaryPair, Field, make_nabla, get_flux_operator nabla = make_nabla(discr.dimensions) diff_optp = nabla[0] * Field("f1") + nabla[1] * Field("f2") divergence = nabla[0].apply(discr, f1_v) + nabla[1].apply(discr, f2_v) int_div = discr.integral(divergence) flux_optp = get_flux_operator(one_sided_x)(BoundaryPair(Field("f1"), Field("fz"))) + get_flux_operator(one_sided_y)( BoundaryPair(Field("f2"), Field("fz")) ) from hedge.mesh import TAG_ALL bdry_val = discr.compile(flux_optp)(f1=f1_v, f2=f2_v, fz=discr.boundary_zeros(TAG_ALL)) ref_bdry_val = ref_discr.compile(flux_optp)(f1=f1_v, f2=f2_v, fz=discr.boundary_zeros(TAG_ALL)) boundary_int = dot(bdry_val, ones) if False: from hedge.visualization import SiloVisualizer vis = SiloVisualizer(discr) visf = vis.make_file("test") from hedge.tools import make_obj_array from hedge.mesh import TAG_ALL vis.add_data( visf, [ ("bdry", bdry_val), ("ref_bdry", ref_bdry_val), ("div", divergence), ("f", make_obj_array([f1_v, f2_v])), ("n", discr.volumize_boundary_field(discr.boundary_normals(TAG_ALL), TAG_ALL)), ], expressions=[("bdiff", "bdry-ref_bdry")], ) # print abs(boundary_int-int_div) assert abs(boundary_int - int_div) < 5e-15
def main(write_output=True): from hedge.backends import guess_run_context rcon = guess_run_context( #["cuda"] ) gamma = 1.4 # at A=1 we have case of isentropic vortex, source terms # arise for other values densityA = 2.0 from hedge.tools import EOCRecorder, to_obj_array eoc_rec = EOCRecorder() if rcon.is_head_rank: from hedge.mesh import \ make_rect_mesh, \ make_centered_regular_rect_mesh refine = 1 mesh = make_centered_regular_rect_mesh((0,-5), (10,5), n=(9,9), post_refine_factor=refine) mesh_data = rcon.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() for order in [4,5]: discr = rcon.make_discretization(mesh_data, order=order, debug=[#"cuda_no_plan", #"print_op_code" ], default_scalar_type=numpy.float64) from hedge.visualization import SiloVisualizer, VtkVisualizer #vis = VtkVisualizer(discr, rcon, "vortex-%d" % order) vis = SiloVisualizer(discr, rcon) vortex = Vortex(beta=5, gamma=gamma, center=[5,0], velocity=[1,0], densityA=densityA) fields = vortex.volume_interpolant(0, discr) sources=SourceTerms(beta=5, gamma=gamma, center=[5,0], velocity=[1,0], densityA=densityA) from hedge.models.gas_dynamics import ( GasDynamicsOperator, GammaLawEOS) from hedge.mesh import TAG_ALL op = GasDynamicsOperator(dimensions=2, mu=0.0, prandtl=0.72, spec_gas_const=287.1, equation_of_state=GammaLawEOS(vortex.gamma), bc_inflow=vortex, bc_outflow=vortex, bc_noslip=vortex, inflow_tag=TAG_ALL, source=sources) 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 hedge.models.gas_dynamics import SlopeLimiter1NEuler limiter = SlopeLimiter1NEuler(discr, gamma, 2, op) # time stepper -------------------------------------------------------- from hedge.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 if write_output: log_file_name = "euler-%d.dat" % order 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) logmgr.add_watches(["step.max", "t_sim.max", "t_step.max"]) # timestep loop ------------------------------------------------------- t = 0 #fields = limiter(fields) try: from hedge.timestep import times_and_steps step_it = times_and_steps( final_time=.1, #max_steps=500, logmgr=logmgr, max_dt_getter=lambda t: 0.4*op.estimate_timestep(discr, stepper=stepper, t=t, max_eigenvalue=max_eigval[0])) for step, t, dt in step_it: if step % 1 == 0 and write_output: #if False: visf = vis.make_file("vortex-%d-%04d" % (order, step)) true_fields = vortex.volume_interpolant(t, discr) #rhs_fields = rhs(t, fields) 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", discr.convert_volume(op.rho(true_fields), kind="numpy")), #("true_e", discr.convert_volume(op.e(true_fields), kind="numpy")), #("true_rho_u", discr.convert_volume(op.rho_u(true_fields), kind="numpy")), #("true_u", discr.convert_volume(op.u(true_fields), kind="numpy")), #("rhs_rho", discr.convert_volume(op.rho(rhs_fields), kind="numpy")), #("rhs_e", discr.convert_volume(op.e(rhs_fields), kind="numpy")), #("rhs_rho_u", discr.convert_volume(op.rho_u(rhs_fields), kind="numpy")), ], 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) true_fields = vortex.volume_interpolant(t, discr) l2_error = discr.norm(fields-true_fields) l2_error_rho = discr.norm(op.rho(fields)-op.rho(true_fields)) l2_error_e = discr.norm(op.e(fields)-op.e(true_fields)) l2_error_rhou = discr.norm(op.rho_u(fields)-op.rho_u(true_fields)) l2_error_u = discr.norm(op.u(fields)-op.u(true_fields)) eoc_rec.add_data_point(order, l2_error_rho) print print eoc_rec.pretty_print("P.Deg.", "L2 Error") logmgr.set_constant("l2_error", l2_error) logmgr.set_constant("l2_error_rho", l2_error_rho) logmgr.set_constant("l2_error_e", l2_error_e) logmgr.set_constant("l2_error_rhou", l2_error_rhou) logmgr.set_constant("l2_error_u", l2_error_u) logmgr.set_constant("refinement", refine) finally: if write_output: vis.close() logmgr.close() discr.close()
def main(): import logging logging.basicConfig(level=logging.INFO) from hedge.backends import guess_run_context rcon = guess_run_context() if rcon.is_head_rank: if True: mesh = make_squaremesh() else: from hedge.mesh import make_rect_mesh mesh = make_rect_mesh( boundary_tagger=lambda fvi, el, fn, all_v: ["inflow"], max_area=0.1) mesh_data = rcon.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() from pytools import add_python_path_relative_to_script add_python_path_relative_to_script(".") for order in [3]: from gas_dynamics_initials import UniformMachFlow square = UniformMachFlow(gaussian_pulse_at=numpy.array([-2, 2]), pulse_magnitude=0.003) from hedge.models.gas_dynamics import (GasDynamicsOperator, GammaLawEOS) op = GasDynamicsOperator(dimensions=2, equation_of_state=GammaLawEOS(square.gamma), mu=square.mu, prandtl=square.prandtl, spec_gas_const=square.spec_gas_const, bc_inflow=square, bc_outflow=square, bc_noslip=square, inflow_tag="inflow", outflow_tag="outflow", noslip_tag="noslip") discr = rcon.make_discretization( mesh_data, order=order, debug=[ "cuda_no_plan", "cuda_dump_kernels", #"dump_dataflow_graph", #"dump_optemplate_stages", #"dump_dataflow_graph", #"dump_op_code" #"cuda_no_plan_el_local" ], default_scalar_type=numpy.float64, tune_for=op.op_template(), quad_min_degrees={ "gasdyn_vol": 3 * order, "gasdyn_face": 3 * order, }) from hedge.visualization import SiloVisualizer, VtkVisualizer #vis = VtkVisualizer(discr, rcon, "shearflow-%d" % order) vis = SiloVisualizer(discr, rcon) from hedge.timestep.runge_kutta import (LSRK4TimeStepper, ODE23TimeStepper, ODE45TimeStepper) from hedge.timestep.dumka3 import Dumka3TimeStepper #stepper = LSRK4TimeStepper(dtype=discr.default_scalar_type, #vector_primitive_factory=discr.get_vector_primitive_factory()) stepper = ODE23TimeStepper( dtype=discr.default_scalar_type, rtol=1e-6, vector_primitive_factory=discr.get_vector_primitive_factory()) # Dumka works kind of poorly #stepper = Dumka3TimeStepper(dtype=discr.default_scalar_type, #rtol=1e-7, pol_index=2, #vector_primitive_factory=discr.get_vector_primitive_factory()) #from hedge.timestep.dumka3 import Dumka3TimeStepper #stepper = Dumka3TimeStepper(3, rtol=1e-7) # diagnostics setup --------------------------------------------------- from pytools.log import LogManager, add_general_quantities, \ add_simulation_quantities, add_run_info logmgr = LogManager("cns-square-sp-%d.dat" % order, "w", rcon.communicator) add_run_info(logmgr) add_general_quantities(logmgr) discr.add_instrumentation(logmgr) stepper.add_instrumentation(logmgr) from pytools.log import LogQuantity class ChangeSinceLastStep(LogQuantity): """Records the change of a variable between a time step and the previous one""" def __init__(self, name="change"): LogQuantity.__init__(self, name, "1", "Change since last time step") self.old_fields = 0 def __call__(self): result = discr.norm(fields - self.old_fields) self.old_fields = fields return result #logmgr.add_quantity(ChangeSinceLastStep()) add_simulation_quantities(logmgr) logmgr.add_watches(["step.max", "t_sim.max", "t_step.max"]) # filter setup ------------------------------------------------------------ from hedge.discretization import Filter, ExponentialFilterResponseFunction mode_filter = Filter( discr, ExponentialFilterResponseFunction(min_amplification=0.95, order=6)) # timestep loop ------------------------------------------------------- fields = square.volume_interpolant(0, discr) navierstokes_ex = op.bind(discr) max_eigval = [0] def rhs(t, q): ode_rhs, speed = navierstokes_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) try: from hedge.timestep import times_and_steps step_it = times_and_steps( final_time=1000, #max_steps=500, logmgr=logmgr, max_dt_getter=lambda t: next_dt, taken_dt_getter=lambda: taken_dt) model_stepper = LSRK4TimeStepper() next_dt = op.estimate_timestep(discr, stepper=model_stepper, t=0, max_eigenvalue=max_eigval[0]) for step, t, dt in step_it: #if (step % 10000 == 0): #and step < 950000) or (step % 500 == 0 and step > 950000): #if False: if step % 5 == 0: visf = vis.make_file("square-%d-%06d" % (order, step)) #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")), ], expressions=[ ("p", "(0.4)*(e- 0.5*(rho_u*u))"), ], time=t, step=step) visf.close() if stepper.adaptive: fields, t, taken_dt, next_dt = stepper(fields, t, dt, rhs) else: taken_dt = dt fields = stepper(fields, t, dt, rhs) dt = op.estimate_timestep(discr, stepper=model_stepper, t=0, max_eigenvalue=max_eigval[0]) #fields = mode_filter(fields) finally: vis.close() logmgr.save() discr.close()