def test_1d_mass_mat_trig(): """Check the integral of some trig functions on an interval using the mass matrix""" from hedge.mesh.generator import make_uniform_1d_mesh from hedge.discretization.local import IntervalDiscretization from math import sqrt, pi, cos, sin from numpy import dot mesh = make_uniform_1d_mesh(-4 * pi, 9 * pi, 17, periodic=True) discr = discr_class(mesh, IntervalDiscretization(8), debug=discr_class.noninteractive_debug_flags()) f = discr.interpolate_volume_function(lambda x, el: cos(x[0]) ** 2) ones = discr.interpolate_volume_function(lambda x, el: 1) from hedge.optemplate import MassOperator mass_op = MassOperator() num_integral_1 = dot(ones, mass_op.apply(discr, f)) num_integral_2 = dot(f, mass_op.apply(discr, ones)) num_integral_3 = discr.integral(f) true_integral = 13 * pi / 2 err_1 = abs(num_integral_1 - true_integral) err_2 = abs(num_integral_2 - true_integral) err_3 = abs(num_integral_3 - true_integral) assert err_1 < 1e-10 assert err_2 < 1e-10 assert err_3 < 1e-10
def test_1d_mass_mat_trig(): """Check the integral of some trig functions on an interval using the mass matrix """ from hedge.mesh.generator import make_uniform_1d_mesh from hedge.discretization.local import IntervalDiscretization from math import pi, cos from numpy import dot mesh = make_uniform_1d_mesh(-4 * pi, 9 * pi, 17, periodic=True) discr = discr_class(mesh, IntervalDiscretization(8), debug=discr_class.noninteractive_debug_flags()) f = discr.interpolate_volume_function(lambda x, el: cos(x[0])**2) ones = discr.interpolate_volume_function(lambda x, el: 1) from hedge.optemplate import MassOperator mass_op = MassOperator() num_integral_1 = dot(ones, mass_op.apply(discr, f)) num_integral_2 = dot(f, mass_op.apply(discr, ones)) num_integral_3 = discr.integral(f) true_integral = 13 * pi / 2 err_1 = abs(num_integral_1 - true_integral) err_2 = abs(num_integral_2 - true_integral) err_3 = abs(num_integral_3 - true_integral) assert err_1 < 1e-10 assert err_2 < 1e-10 assert err_3 < 1e-10
def main(write_output=True, dir_tag=TAG_NONE, neu_tag=TAG_NONE, rad_tag=TAG_ALL, flux_type_arg="upwind", dtype=np.float64, debug=[]): from math import sin, cos, pi, exp, sqrt # noqa from hedge.backends import guess_run_context rcon = guess_run_context() dim = 2 if dim == 1: if rcon.is_head_rank: from hedge.mesh.generator import make_uniform_1d_mesh mesh = make_uniform_1d_mesh(-10, 10, 500) elif dim == 2: from hedge.mesh.generator import make_rect_mesh if rcon.is_head_rank: mesh = make_rect_mesh(a=(-0.5, -0.5), b=(0.5, 0.5), max_area=0.008) elif dim == 3: if rcon.is_head_rank: from hedge.mesh.generator import make_ball_mesh mesh = make_ball_mesh(max_volume=0.0005) else: raise RuntimeError("bad number of dimensions") if rcon.is_head_rank: print "%d elements" % len(mesh.elements) mesh_data = rcon.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() from hedge.timestep.runge_kutta import LSRK4TimeStepper stepper = LSRK4TimeStepper(dtype=dtype) from hedge.models.wave import StrongWaveOperator from hedge.mesh import TAG_ALL, TAG_NONE # noqa source_center = np.array([0.1, 0.22]) source_width = 0.05 source_omega = 3 import hedge.optemplate as sym sym_x = sym.nodes(2) sym_source_center_dist = sym_x - source_center op = StrongWaveOperator(-1, dim, source_f= sym.CFunction("sin")(source_omega*sym.ScalarParameter("t")) * sym.CFunction("exp")( -np.dot(sym_source_center_dist, sym_source_center_dist) / source_width**2), dirichlet_tag=dir_tag, neumann_tag=neu_tag, radiation_tag=rad_tag, flux_type=flux_type_arg ) discr = rcon.make_discretization(mesh_data, order=4, debug=debug, default_scalar_type=dtype, tune_for=op.op_template()) from hedge.visualization import VtkVisualizer if write_output: vis = VtkVisualizer(discr, rcon, "fld") from hedge.tools import join_fields fields = join_fields(discr.volume_zeros(dtype=dtype), [discr.volume_zeros(dtype=dtype) for i in range(discr.dimensions)]) # {{{ diagnostics setup from pytools.log import LogManager, \ add_general_quantities, \ add_simulation_quantities, \ add_run_info if write_output: log_file_name = "wave.dat" else: log_file_name = None logmgr = LogManager(log_file_name, "w", rcon.communicator) add_run_info(logmgr) add_general_quantities(logmgr) add_simulation_quantities(logmgr) discr.add_instrumentation(logmgr) from pytools.log import IntervalTimer vis_timer = IntervalTimer("t_vis", "Time spent visualizing") logmgr.add_quantity(vis_timer) stepper.add_instrumentation(logmgr) from hedge.log import LpNorm u_getter = lambda: fields[0] logmgr.add_quantity(LpNorm(u_getter, discr, 1, name="l1_u")) logmgr.add_quantity(LpNorm(u_getter, discr, name="l2_u")) logmgr.add_watches(["step.max", "t_sim.max", "l2_u", "t_step.max"]) # }}} # {{{ timestep loop rhs = op.bind(discr) try: from hedge.timestep import times_and_steps step_it = times_and_steps( final_time=4, logmgr=logmgr, max_dt_getter=lambda t: op.estimate_timestep(discr, stepper=stepper, t=t, fields=fields)) for step, t, dt in step_it: if step % 10 == 0 and write_output: visf = vis.make_file("fld-%04d" % step) vis.add_data(visf, [ ("u", discr.convert_volume(fields[0], kind="numpy")), ("v", discr.convert_volume(fields[1:], kind="numpy")), ], time=t, step=step) visf.close() fields = stepper(fields, t, dt, rhs) assert discr.norm(fields) < 1 assert fields[0].dtype == dtype finally: if write_output: vis.close() logmgr.close() discr.close()
def main(write_output=True, dir_tag=TAG_NONE, neu_tag=TAG_NONE, rad_tag=TAG_ALL, flux_type_arg="upwind"): from math import sin, cos, pi, exp, sqrt # noqa from hedge.backends import guess_run_context rcon = guess_run_context() dim = 2 if dim == 1: if rcon.is_head_rank: from hedge.mesh.generator import make_uniform_1d_mesh mesh = make_uniform_1d_mesh(-10, 10, 500) elif dim == 2: from hedge.mesh.generator import make_rect_mesh if rcon.is_head_rank: mesh = make_rect_mesh(a=(-1, -1), b=(1, 1), max_area=0.003) elif dim == 3: if rcon.is_head_rank: from hedge.mesh.generator import make_ball_mesh mesh = make_ball_mesh(max_volume=0.0005) else: raise RuntimeError("bad number of dimensions") if rcon.is_head_rank: print "%d elements" % len(mesh.elements) mesh_data = rcon.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() discr = rcon.make_discretization(mesh_data, order=4) from hedge.timestep.runge_kutta import LSRK4TimeStepper stepper = LSRK4TimeStepper() from hedge.visualization import VtkVisualizer if write_output: vis = VtkVisualizer(discr, rcon, "fld") source_center = np.array([0.7, 0.4]) source_width = 1 / 16 source_omega = 3 import hedge.optemplate as sym sym_x = sym.nodes(2) sym_source_center_dist = sym_x - source_center from hedge.models.wave import VariableVelocityStrongWaveOperator op = VariableVelocityStrongWaveOperator( c=sym.If(sym.Comparison(np.dot(sym_x, sym_x), "<", 0.4**2), 1, 0.5), dimensions=discr.dimensions, source=sym.CFunction("sin")(source_omega * sym.ScalarParameter("t")) * sym.CFunction("exp")( -np.dot(sym_source_center_dist, sym_source_center_dist) / source_width**2), dirichlet_tag=dir_tag, neumann_tag=neu_tag, radiation_tag=rad_tag, flux_type=flux_type_arg) from hedge.tools import join_fields fields = join_fields( discr.volume_zeros(), [discr.volume_zeros() for i in range(discr.dimensions)]) # {{{ diagnostics setup from pytools.log import LogManager, \ add_general_quantities, \ add_simulation_quantities, \ add_run_info if write_output: log_file_name = "wave.dat" else: log_file_name = None logmgr = LogManager(log_file_name, "w", rcon.communicator) add_run_info(logmgr) add_general_quantities(logmgr) add_simulation_quantities(logmgr) discr.add_instrumentation(logmgr) from pytools.log import IntervalTimer vis_timer = IntervalTimer("t_vis", "Time spent visualizing") logmgr.add_quantity(vis_timer) stepper.add_instrumentation(logmgr) from hedge.log import LpNorm u_getter = lambda: fields[0] logmgr.add_quantity(LpNorm(u_getter, discr, 1, name="l1_u")) logmgr.add_quantity(LpNorm(u_getter, discr, name="l2_u")) logmgr.add_watches(["step.max", "t_sim.max", "l2_u", "t_step.max"]) # }}} # {{{ timestep loop rhs = op.bind(discr) try: from hedge.timestep.stability import \ approximate_rk4_relative_imag_stability_region max_dt = (1 / discr.compile(op.max_eigenvalue_expr())() * discr.dt_non_geometric_factor() * discr.dt_geometric_factor() * approximate_rk4_relative_imag_stability_region(stepper)) if flux_type_arg == "central": max_dt *= 0.25 from hedge.timestep import times_and_steps step_it = times_and_steps(final_time=3, logmgr=logmgr, max_dt_getter=lambda t: max_dt) for step, t, dt in step_it: if step % 10 == 0 and write_output: visf = vis.make_file("fld-%04d" % step) vis.add_data(visf, [ ("u", fields[0]), ("v", fields[1:]), ], time=t, step=step) visf.close() fields = stepper(fields, t, dt, rhs) assert discr.norm(fields) < 1 finally: if write_output: vis.close() logmgr.close() discr.close()
def main(write_output=True, dir_tag=TAG_NONE, neu_tag=TAG_NONE, rad_tag=TAG_ALL, flux_type_arg="upwind", dtype=np.float64, debug=[]): from math import sin, cos, pi, exp, sqrt # noqa from hedge.backends import guess_run_context rcon = guess_run_context() dim = 2 if dim == 1: if rcon.is_head_rank: from hedge.mesh.generator import make_uniform_1d_mesh mesh = make_uniform_1d_mesh(-10, 10, 500) elif dim == 2: from hedge.mesh.generator import make_rect_mesh if rcon.is_head_rank: mesh = make_rect_mesh(a=(-0.5, -0.5), b=(0.5, 0.5), max_area=0.008) elif dim == 3: if rcon.is_head_rank: from hedge.mesh.generator import make_ball_mesh mesh = make_ball_mesh(max_volume=0.0005) else: raise RuntimeError("bad number of dimensions") if rcon.is_head_rank: print "%d elements" % len(mesh.elements) mesh_data = rcon.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() from hedge.timestep.runge_kutta import LSRK4TimeStepper stepper = LSRK4TimeStepper(dtype=dtype) from hedge.models.wave import StrongWaveOperator from hedge.mesh import TAG_ALL, TAG_NONE # noqa source_center = np.array([0.1, 0.22]) source_width = 0.05 source_omega = 3 import hedge.optemplate as sym sym_x = sym.nodes(2) sym_source_center_dist = sym_x - source_center op = StrongWaveOperator( -1, dim, source_f=sym.CFunction("sin")( source_omega * sym.ScalarParameter("t")) * sym.CFunction("exp")( -np.dot(sym_source_center_dist, sym_source_center_dist) / source_width**2), dirichlet_tag=dir_tag, neumann_tag=neu_tag, radiation_tag=rad_tag, flux_type=flux_type_arg) discr = rcon.make_discretization(mesh_data, order=4, debug=debug, default_scalar_type=dtype, tune_for=op.op_template()) from hedge.visualization import VtkVisualizer if write_output: vis = VtkVisualizer(discr, rcon, "fld") from hedge.tools import join_fields fields = join_fields( discr.volume_zeros(dtype=dtype), [discr.volume_zeros(dtype=dtype) for i in range(discr.dimensions)]) # {{{ diagnostics setup from pytools.log import LogManager, \ add_general_quantities, \ add_simulation_quantities, \ add_run_info if write_output: log_file_name = "wave.dat" else: log_file_name = None logmgr = LogManager(log_file_name, "w", rcon.communicator) add_run_info(logmgr) add_general_quantities(logmgr) add_simulation_quantities(logmgr) discr.add_instrumentation(logmgr) from pytools.log import IntervalTimer vis_timer = IntervalTimer("t_vis", "Time spent visualizing") logmgr.add_quantity(vis_timer) stepper.add_instrumentation(logmgr) from hedge.log import LpNorm u_getter = lambda: fields[0] logmgr.add_quantity(LpNorm(u_getter, discr, 1, name="l1_u")) logmgr.add_quantity(LpNorm(u_getter, discr, name="l2_u")) logmgr.add_watches(["step.max", "t_sim.max", "l2_u", "t_step.max"]) # }}} # {{{ timestep loop rhs = op.bind(discr) try: from hedge.timestep import times_and_steps step_it = times_and_steps( final_time=4, logmgr=logmgr, max_dt_getter=lambda t: op.estimate_timestep( discr, stepper=stepper, t=t, fields=fields)) for step, t, dt in step_it: if step % 10 == 0 and write_output: visf = vis.make_file("fld-%04d" % step) vis.add_data(visf, [ ("u", discr.convert_volume(fields[0], kind="numpy")), ("v", discr.convert_volume(fields[1:], kind="numpy")), ], time=t, step=step) visf.close() fields = stepper(fields, t, dt, rhs) assert discr.norm(fields) < 1 assert fields[0].dtype == dtype finally: if write_output: vis.close() logmgr.close() discr.close()
def main(write_output=True, dir_tag=TAG_NONE, neu_tag=TAG_NONE, rad_tag=TAG_ALL, flux_type_arg="upwind"): from math import sin, cos, pi, exp, sqrt # noqa from hedge.backends import guess_run_context rcon = guess_run_context() dim = 2 if dim == 1: if rcon.is_head_rank: from hedge.mesh.generator import make_uniform_1d_mesh mesh = make_uniform_1d_mesh(-10, 10, 500) elif dim == 2: from hedge.mesh.generator import make_rect_mesh if rcon.is_head_rank: mesh = make_rect_mesh(a=(-1, -1), b=(1, 1), max_area=0.003) elif dim == 3: if rcon.is_head_rank: from hedge.mesh.generator import make_ball_mesh mesh = make_ball_mesh(max_volume=0.0005) else: raise RuntimeError("bad number of dimensions") if rcon.is_head_rank: print "%d elements" % len(mesh.elements) mesh_data = rcon.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() discr = rcon.make_discretization(mesh_data, order=4) from hedge.timestep.runge_kutta import LSRK4TimeStepper stepper = LSRK4TimeStepper() from hedge.visualization import VtkVisualizer if write_output: vis = VtkVisualizer(discr, rcon, "fld") source_center = np.array([0.7, 0.4]) source_width = 1/16 source_omega = 3 import hedge.optemplate as sym sym_x = sym.nodes(2) sym_source_center_dist = sym_x - source_center from hedge.models.wave import VariableVelocityStrongWaveOperator op = VariableVelocityStrongWaveOperator( c=sym.If(sym.Comparison( np.dot(sym_x, sym_x), "<", 0.4**2), 1, 0.5), dimensions=discr.dimensions, source= sym.CFunction("sin")(source_omega*sym.ScalarParameter("t")) * sym.CFunction("exp")( -np.dot(sym_source_center_dist, sym_source_center_dist) / source_width**2), dirichlet_tag=dir_tag, neumann_tag=neu_tag, radiation_tag=rad_tag, flux_type=flux_type_arg ) from hedge.tools import join_fields fields = join_fields(discr.volume_zeros(), [discr.volume_zeros() for i in range(discr.dimensions)]) # {{{ diagnostics setup from pytools.log import LogManager, \ add_general_quantities, \ add_simulation_quantities, \ add_run_info if write_output: log_file_name = "wave.dat" else: log_file_name = None logmgr = LogManager(log_file_name, "w", rcon.communicator) add_run_info(logmgr) add_general_quantities(logmgr) add_simulation_quantities(logmgr) discr.add_instrumentation(logmgr) from pytools.log import IntervalTimer vis_timer = IntervalTimer("t_vis", "Time spent visualizing") logmgr.add_quantity(vis_timer) stepper.add_instrumentation(logmgr) from hedge.log import LpNorm u_getter = lambda: fields[0] logmgr.add_quantity(LpNorm(u_getter, discr, 1, name="l1_u")) logmgr.add_quantity(LpNorm(u_getter, discr, name="l2_u")) logmgr.add_watches(["step.max", "t_sim.max", "l2_u", "t_step.max"]) # }}} # {{{ timestep loop rhs = op.bind(discr) try: from hedge.timestep.stability import \ approximate_rk4_relative_imag_stability_region max_dt = ( 1/discr.compile(op.max_eigenvalue_expr())() * discr.dt_non_geometric_factor() * discr.dt_geometric_factor() * approximate_rk4_relative_imag_stability_region(stepper)) if flux_type_arg == "central": max_dt *= 0.25 from hedge.timestep import times_and_steps step_it = times_and_steps(final_time=3, logmgr=logmgr, max_dt_getter=lambda t: max_dt) for step, t, dt in step_it: if step % 10 == 0 and write_output: visf = vis.make_file("fld-%04d" % step) vis.add_data(visf, [ ("u", fields[0]), ("v", fields[1:]), ], time=t, step=step) visf.close() fields = stepper(fields, t, dt, rhs) assert discr.norm(fields) < 1 finally: if write_output: vis.close() logmgr.close() discr.close()
def main(write_output=True, flux_type_arg="upwind", #case = CenteredStationaryTestCase(), #case = OffCenterStationaryTestCase(), #case = OffCenterMigratingTestCase(), case = ExactTestCase(), ): from hedge.backends import guess_run_context rcon = guess_run_context() order = 3 if rcon.is_head_rank: if True: from hedge.mesh.generator import make_uniform_1d_mesh mesh = make_uniform_1d_mesh(case.a, case.b, 20, periodic=True) else: from hedge.mesh.generator import make_rect_mesh print (pi*2)/(11*5*2) mesh = make_rect_mesh((-pi, -1), (pi, 1), periodicity=(True, True), subdivisions=(11,5), max_area=(pi*2)/(11*5*2) ) if rcon.is_head_rank: mesh_data = rcon.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() discr = rcon.make_discretization(mesh_data, order=order, quad_min_degrees={"quad": 3*order}) if write_output: from hedge.visualization import VtkVisualizer vis = VtkVisualizer(discr, rcon, "fld") # operator setup ---------------------------------------------------------- from hedge.second_order import IPDGSecondDerivative from hedge.models.burgers import BurgersOperator op = BurgersOperator(mesh.dimensions, viscosity_scheme=IPDGSecondDerivative()) if rcon.is_head_rank: print "%d elements" % len(discr.mesh.elements) # exact solution ---------------------------------------------------------- import pymbolic var = pymbolic.var u = discr.interpolate_volume_function(lambda x, el: case.u0(x[0])) # diagnostics setup ------------------------------------------------------- from pytools.log import LogManager, \ add_general_quantities, \ add_simulation_quantities, \ add_run_info if write_output: log_file_name = "burgers.dat" else: log_file_name = None logmgr = LogManager(log_file_name, "w", rcon.communicator) add_run_info(logmgr) add_general_quantities(logmgr) add_simulation_quantities(logmgr) discr.add_instrumentation(logmgr) from hedge.log import LpNorm u_getter = lambda: u logmgr.add_quantity(LpNorm(u_getter, discr, p=1, name="l1_u")) logmgr.add_watches(["step.max", "t_sim.max", "l1_u", "t_step.max"]) # timestep loop ----------------------------------------------------------- rhs = op.bind(discr) from hedge.timestep.runge_kutta import ODE45TimeStepper, LSRK4TimeStepper stepper = ODE45TimeStepper() stepper.add_instrumentation(logmgr) try: from hedge.timestep import times_and_steps # for visc=0.01 #stab_fac = 0.1 # RK4 #stab_fac = 1.6 # dumka3(3), central #stab_fac = 3 # dumka3(4), central #stab_fac = 0.01 # RK4 stab_fac = 0.2 # dumka3(3), central #stab_fac = 3 # dumka3(4), central dt = stab_fac*op.estimate_timestep(discr, stepper=LSRK4TimeStepper(), t=0, fields=u) step_it = times_and_steps( final_time=case.final_time, logmgr=logmgr, max_dt_getter=lambda t: dt) from hedge.optemplate import InverseVandermondeOperator inv_vdm = InverseVandermondeOperator().bind(discr) for step, t, dt in step_it: if step % 3 == 0 and write_output: if hasattr(case, "u_exact"): extra_fields = [ ("u_exact", discr.interpolate_volume_function( lambda x, el: case.u_exact(x[0], t)))] else: extra_fields = [] visf = vis.make_file("fld-%04d" % step) vis.add_data(visf, [ ("u", u), ] + extra_fields, time=t, step=step) visf.close() u = stepper(u, t, dt, rhs) if isinstance(case, ExactTestCase): assert discr.norm(u, 1) < 50 finally: if write_output: vis.close() logmgr.save()
def main(write_output=True, flux_type_arg="upwind"): from hedge.tools import mem_checkpoint from math import sin, cos, pi, sqrt from math import floor from hedge.backends import guess_run_context rcon = guess_run_context() def f(x): return sin(pi*x) def u_analytic(x, el, t): return f((-numpy.dot(v, x)/norm_v+t*norm_v)) def boundary_tagger(vertices, el, face_nr, all_v): if numpy.dot(el.face_normals[face_nr], v) < 0: return ["inflow"] else: return ["outflow"] dim = 2 if dim == 1: v = numpy.array([1]) if rcon.is_head_rank: from hedge.mesh.generator import make_uniform_1d_mesh mesh = make_uniform_1d_mesh(0, 2, 10, periodic=True) elif dim == 2: v = numpy.array([2,0]) if rcon.is_head_rank: from hedge.mesh.generator import make_disk_mesh mesh = make_disk_mesh(boundary_tagger=boundary_tagger) elif dim == 3: v = numpy.array([0,0,1]) if rcon.is_head_rank: from hedge.mesh.generator import make_cylinder_mesh, make_ball_mesh, make_box_mesh mesh = make_cylinder_mesh(max_volume=0.04, height=2, boundary_tagger=boundary_tagger, periodic=False, radial_subdivisions=32) else: raise RuntimeError, "bad number of dimensions" norm_v = la.norm(v) if rcon.is_head_rank: mesh_data = rcon.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() if dim != 1: mesh_data = mesh_data.reordered_by("cuthill") discr = rcon.make_discretization(mesh_data, order=4) vis_discr = discr from hedge.visualization import VtkVisualizer if write_output: vis = VtkVisualizer(vis_discr, rcon, "fld") # operator setup ---------------------------------------------------------- from hedge.data import \ ConstantGivenFunction, \ TimeConstantGivenFunction, \ TimeDependentGivenFunction from hedge.models.advection import StrongAdvectionOperator, WeakAdvectionOperator op = WeakAdvectionOperator(v, inflow_u=TimeDependentGivenFunction(u_analytic), flux_type=flux_type_arg) u = discr.interpolate_volume_function(lambda x, el: u_analytic(x, el, 0)) # timestep setup ---------------------------------------------------------- from hedge.timestep.runge_kutta import LSRK4TimeStepper stepper = LSRK4TimeStepper() if rcon.is_head_rank: print "%d elements" % len(discr.mesh.elements) # diagnostics setup ------------------------------------------------------- from pytools.log import LogManager, \ add_general_quantities, \ add_simulation_quantities, \ add_run_info if write_output: log_file_name = "advection.dat" else: log_file_name = None logmgr = LogManager(log_file_name, "w", rcon.communicator) add_run_info(logmgr) add_general_quantities(logmgr) add_simulation_quantities(logmgr) discr.add_instrumentation(logmgr) stepper.add_instrumentation(logmgr) from hedge.log import Integral, LpNorm u_getter = lambda: u logmgr.add_quantity(Integral(u_getter, discr, name="int_u")) logmgr.add_quantity(LpNorm(u_getter, discr, p=1, name="l1_u")) logmgr.add_quantity(LpNorm(u_getter, discr, name="l2_u")) logmgr.add_watches(["step.max", "t_sim.max", "l2_u", "t_step.max"]) # timestep loop ----------------------------------------------------------- rhs = op.bind(discr) try: from hedge.timestep import times_and_steps step_it = times_and_steps( final_time=3, logmgr=logmgr, max_dt_getter=lambda t: op.estimate_timestep(discr, stepper=stepper, t=t, fields=u)) for step, t, dt in step_it: if step % 5 == 0 and write_output: visf = vis.make_file("fld-%04d" % step) vis.add_data(visf, [ ("u", discr.convert_volume(u, kind="numpy")), ], time=t, step=step) visf.close() u = stepper(u, t, dt, rhs) true_u = discr.interpolate_volume_function(lambda x, el: u_analytic(x, el, t)) print discr.norm(u-true_u) assert discr.norm(u-true_u) < 1e-2 finally: if write_output: vis.close() logmgr.close() discr.close()
def main(write_output=True, flux_type_arg="upwind"): from hedge.tools import mem_checkpoint from math import sin, cos, pi, sqrt from math import floor from hedge.backends import guess_run_context rcon = guess_run_context() def f(x): return sin(pi * x) def u_analytic(x, el, t): return f((-numpy.dot(v, x) / norm_v + t * norm_v)) def boundary_tagger(vertices, el, face_nr, all_v): if numpy.dot(el.face_normals[face_nr], v) < 0: return ["inflow"] else: return ["outflow"] dim = 2 if dim == 1: v = numpy.array([1]) if rcon.is_head_rank: from hedge.mesh.generator import make_uniform_1d_mesh mesh = make_uniform_1d_mesh(0, 2, 10, periodic=True) elif dim == 2: v = numpy.array([2, 0]) if rcon.is_head_rank: from hedge.mesh.generator import make_disk_mesh mesh = make_disk_mesh(boundary_tagger=boundary_tagger) elif dim == 3: v = numpy.array([0, 0, 1]) if rcon.is_head_rank: from hedge.mesh.generator import make_cylinder_mesh, make_ball_mesh, make_box_mesh mesh = make_cylinder_mesh(max_volume=0.04, height=2, boundary_tagger=boundary_tagger, periodic=False, radial_subdivisions=32) else: raise RuntimeError, "bad number of dimensions" norm_v = la.norm(v) if rcon.is_head_rank: mesh_data = rcon.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() if dim != 1: mesh_data = mesh_data.reordered_by("cuthill") discr = rcon.make_discretization(mesh_data, order=4) vis_discr = discr from hedge.visualization import VtkVisualizer if write_output: vis = VtkVisualizer(vis_discr, rcon, "fld") # operator setup ---------------------------------------------------------- from hedge.data import \ ConstantGivenFunction, \ TimeConstantGivenFunction, \ TimeDependentGivenFunction from hedge.models.advection import StrongAdvectionOperator, WeakAdvectionOperator op = WeakAdvectionOperator(v, inflow_u=TimeDependentGivenFunction(u_analytic), flux_type=flux_type_arg) u = discr.interpolate_volume_function(lambda x, el: u_analytic(x, el, 0)) # timestep setup ---------------------------------------------------------- from hedge.timestep.runge_kutta import LSRK4TimeStepper stepper = LSRK4TimeStepper() if rcon.is_head_rank: print "%d elements" % len(discr.mesh.elements) # diagnostics setup ------------------------------------------------------- from pytools.log import LogManager, \ add_general_quantities, \ add_simulation_quantities, \ add_run_info if write_output: log_file_name = "advection.dat" else: log_file_name = None logmgr = LogManager(log_file_name, "w", rcon.communicator) add_run_info(logmgr) add_general_quantities(logmgr) add_simulation_quantities(logmgr) discr.add_instrumentation(logmgr) stepper.add_instrumentation(logmgr) from hedge.log import Integral, LpNorm u_getter = lambda: u logmgr.add_quantity(Integral(u_getter, discr, name="int_u")) logmgr.add_quantity(LpNorm(u_getter, discr, p=1, name="l1_u")) logmgr.add_quantity(LpNorm(u_getter, discr, name="l2_u")) logmgr.add_watches(["step.max", "t_sim.max", "l2_u", "t_step.max"]) # timestep loop ----------------------------------------------------------- rhs = op.bind(discr) try: from hedge.timestep import times_and_steps step_it = times_and_steps(final_time=3, logmgr=logmgr, max_dt_getter=lambda t: op.estimate_timestep( discr, stepper=stepper, t=t, fields=u)) for step, t, dt in step_it: if step % 5 == 0 and write_output: visf = vis.make_file("fld-%04d" % step) vis.add_data(visf, [ ("u", discr.convert_volume(u, kind="numpy")), ], time=t, step=step) visf.close() u = stepper(u, t, dt, rhs) true_u = discr.interpolate_volume_function( lambda x, el: u_analytic(x, el, t)) print discr.norm(u - true_u) assert discr.norm(u - true_u) < 1e-2 finally: if write_output: vis.close() logmgr.close() discr.close()
def main(write_output=True, \ dir_tag=TAG_NONE, \ neu_tag=TAG_NONE,\ rad_tag=TAG_ALL, flux_type_arg="upwind"): from math import sin, cos, pi, exp, sqrt from hedge.backends import guess_run_context rcon = guess_run_context() dim = 2 if dim == 1: if rcon.is_head_rank: from hedge.mesh.generator import make_uniform_1d_mesh mesh = make_uniform_1d_mesh(-10, 10, 500) elif dim == 2: from hedge.mesh.generator import make_rect_mesh if rcon.is_head_rank: mesh = make_rect_mesh(a=(-1,-1),b=(1,1),max_area=0.003) elif dim == 3: if rcon.is_head_rank: from hedge.mesh.generator import make_ball_mesh mesh = make_ball_mesh(max_volume=0.0005) else: raise RuntimeError, "bad number of dimensions" if rcon.is_head_rank: print "%d elements" % len(mesh.elements) mesh_data = rcon.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() discr = rcon.make_discretization(mesh_data, order=4) from hedge.timestep import RK4TimeStepper stepper = RK4TimeStepper() from hedge.visualization import VtkVisualizer if write_output: vis = VtkVisualizer(discr, rcon, "fld") def source_u(x, el): x = x - numpy.array([0.7, 0.4]) return exp(-numpy.dot(x, x)*256) def c_speed(x, el): if la.norm(x) < 0.4: return 1 else: return 0.5 from hedge.models.wave import VariableVelocityStrongWaveOperator from hedge.data import \ TimeIntervalGivenFunction, \ make_tdep_given from hedge.mesh import TAG_ALL, TAG_NONE op = VariableVelocityStrongWaveOperator( make_tdep_given(c_speed), discr.dimensions, source=TimeIntervalGivenFunction( make_tdep_given(source_u), 0, 0.1), dirichlet_tag=dir_tag, neumann_tag=neu_tag, radiation_tag=rad_tag, flux_type=flux_type_arg ) from hedge.tools import join_fields fields = join_fields(discr.volume_zeros(), [discr.volume_zeros() for i in range(discr.dimensions)]) # diagnostics setup ------------------------------------------------------- from pytools.log import LogManager, \ add_general_quantities, \ add_simulation_quantities, \ add_run_info if write_output: log_file_name = "wave.dat" else: log_file_name = None logmgr = LogManager(log_file_name, "w", rcon.communicator) add_run_info(logmgr) add_general_quantities(logmgr) add_simulation_quantities(logmgr) discr.add_instrumentation(logmgr) from pytools.log import IntervalTimer vis_timer = IntervalTimer("t_vis", "Time spent visualizing") logmgr.add_quantity(vis_timer) stepper.add_instrumentation(logmgr) from hedge.log import Integral, LpNorm u_getter = lambda: fields[0] logmgr.add_quantity(LpNorm(u_getter, discr, 1, name="l1_u")) logmgr.add_quantity(LpNorm(u_getter, discr, name="l2_u")) logmgr.add_watches(["step.max", "t_sim.max", "l2_u", "t_step.max"]) # timestep loop ----------------------------------------------------------- rhs = op.bind(discr) try: dt = op.estimate_timestep(discr, stepper=stepper, fields=fields) if flux_type_arg == "central": dt *= 0.25 from hedge.timestep import times_and_steps step_it = times_and_steps(final_time=3, logmgr=logmgr, max_dt_getter=lambda t: dt) for step, t, dt in step_it: if step % 10 == 0 and write_output: visf = vis.make_file("fld-%04d" % step) vis.add_data(visf, [ ("u", fields[0]), ("v", fields[1:]), ("c", op.c.volume_interpolant(0, discr)), ], time=t, step=step) visf.close() fields = stepper(fields, t, dt, rhs) assert discr.norm(fields) < 1 finally: if write_output: vis.close() logmgr.close() discr.close()
def main(write_output=['vtu', 'receivers'], allow_features='', dim=2, order=4, stfree_tag=TAG_NONE, fix_tag=TAG_ALL, op_tag=TAG_NONE, flux_type="lf", max_steps=None, output_dir='output', pml=None, sources=None, source_param={}, final_time=12, quiet_output=True, nonlinearity_type=None, mesh_file='', periodicity=None, material_files=None, vtu_every=20): """ Parameters: @param write_output: output data, among 'vtu', 'receivers' and 'txt' @param allow_features: 'mpi' or 'cuda' @param dim: 1, 2 or 3 @param order: the order of the method @param stfree_tag: which elements to mark as stress-free boundaries @param fix_tag: which elements to mark as fixed boundaries @param op_tag: which elements to mark as open boundaries @param flux_type: 'lf' (Lax-Freidrich flux) or 'central' @param max_steps: None (no limit) or maximum number of steps to compute @param output_dir: directory where to write the output @param pml: None or NPML widths in this order: [x_l, y_l, z_l, x_r, y_r, z_r] @param sources: an array containing the coordinates of the source or None @param source_param: a dict containing the parameters for the source functions @param final_time: number of seconds of simulations to compute @param quiet_output: if True, only the main thread will print information @param nonlinearity_type: None (linear) or 'classical' (non-linear) @param mesh_file: the file to use as a mesh, or '' in 1D @param periodicity: the names of the boundaries to stick together, or None @param material_files: array, the material files (.dat) to use @param vtu_every: n, to write a vtu file every n steps """ rcon = guess_run_context(allow_features) rcon_init = guess_run_context(allow_features) debug = ['dump_optemplate_stages'] dtype = numpy.float64 if 'cuda' in allow_features: dtype = numpy.float32 debug.append('cuda_no_plan') if rcon.is_head_rank and output_dir and not access(output_dir, F_OK): makedirs(output_dir) if quiet_output: print_output = rcon.is_head_rank else: print_output = True if print_output: print "Using features:", ', '.join(allow_features).upper() nbranks = len(rcon.ranks) print "Using", nbranks, "rank" + ('s' if nbranks > 1 else '') print "Using", dim, "dimension" + ('s' if dim > 1 else '') print "Rank", rcon.rank, "will print its output." else: print "Rank", rcon.rank, "will be silent." class Receiver(): pass assert dim in [1, 2, 3], 'Bad number of dimensions' # Define mesh --- mesh = None if mesh_file != '': mesh = read_gmsh(mesh_file, force_dimension=dim, periodicity=periodicity, allow_internal_boundaries=False, tag_mapper=lambda tag: tag) elif dim == 1: from hedge.mesh.generator import make_uniform_1d_mesh mesh = make_uniform_1d_mesh(-10, 10, 500) else: raise Exception('Error: No mesh file specified!') if rcon.is_head_rank: print "Using %d elements and order %d" % (len(mesh.elements), order) mesh_data = rcon.distribute_mesh(mesh) mesh_init = rcon_init.distribute_mesh(mesh) else: mesh_data = rcon.receive_mesh() mesh_init = rcon_init.receive_mesh() if mesh_file: from libraries.gmsh_reader import GmshReader gmsh = GmshReader(mesh_file, dim, print_output) # End of mesh definition --- # Define sources --- source = None if sources is not None: #FIXME: "Multiple source points are currently unsupported" source = sources if print_output: print "Using specified source", source else: if print_output: print "No source specified", if mesh_file: if print_output: print "trying to find one in", mesh_file sources = gmsh.pointSources if sources != []: source = sources[0] if print_output: print "Using source", source, "from", mesh_file else: if print_output: print "Error: no source!" else: if print_output: print "and no mesh file!" raise Exception('Error: Could not find any source!') def source_v_x(pos, el): pos = pos - source #return exp(-numpy.dot(pos, pos) / source_param['sigma'] ** 2) return exp(- pos[0]**2 / source_param['sigma'] ** 2) def source_v_y(pos, el): pos = pos - source return 0 def source_v_z(pos, el): pos = pos - source return 0 source_type = None if source_param['type'] == 'Sinus': from libraries.functions import SinusGivenFunction source_type = 'SinusGivenFunction' elif source_param['type'] == 'SineBurst': from libraries.functions import SineBurstGivenFunction source_type = 'SineBurstGivenFunction' elif source_param['type'] == 'Modulated_sinus': from libraries.functions import ModulatedSinusGivenFunction source_type = 'ModulatedSinusGivenFunction' elif source_param['type'] == 'Ricker': from libraries.functions import TimeRickerWaveletGivenFunction source_type = 'TimeRickerWaveletGivenFunction' assert source_type is not None, "Failed to define source function!" source_function = locals()[source_type] print "Using source type:", source_type from hedge.data import make_tdep_given, TimeIntervalGivenFunction def source_i(source_v_i): return TimeIntervalGivenFunction( source_function(make_tdep_given(source_v_i), source_param['fc'], source_param['td']), source_param['begin'], source_param['end']) sources = {'source_x': source_i(source_v_x), 'source_y': source_i(source_v_y), 'source_z': source_i(source_v_z)} # End of sources definition --- # Define materials and link them with elements --- materials = [] constants = ['Density', 'LinearElasticConstants'] if nonlinearity_type == 'cubic': constants.append('ElasticConstant_lambda') constants.append('ElasticConstant_mu') constants.append('QuadraticElasticConstant_f') constants.append('CubicElasticConstant_h') elif nonlinearity_type is not None: constants.append('NonlinearElasticConstants') for material_file in material_files: material = Material(material_file, constants, dtype, print_output) if nonlinearity_type == 'cubic': assert material.lambda_ is not None, "Error: Missing elastic constant lambda in " + file assert material.mu is not None, "Error: Missing elastic constant mu in " + file assert material.f is not None, "Error: Missing quadratic constant f in " + file assert material.h is not None, "Error: Missing cubic constant h in " + file elif nonlinearity_type is not None: # In the nonlinear mode, materials MUST have a nonlinear constants assert material.Cnl is not None, "Error: Missing nonlinear constants in " + file materials.append(material) assert len(materials) > 0, "Error: You must define at least 1 material." # Work out which elements belong to each material material_elements = [] used_materials = [] speeds = [] for num, name in [(0, 'mat1'), (1, 'mat2'), (2, 'mat3')]: if len(materials) > num: if name in mesh_init.tag_to_elements.keys(): elements_list = [el.id for el in mesh_init.tag_to_elements[name]] material_elements.append(elements_list) else: num = 0 speed = (materials[num].C[0, 0] / materials[num].rho) ** 0.5 speeds.append(speed.astype(dtype)) used_materials.append(materials[num]) if print_output: print "Using", materials[num].filename, "as", name speed = max(speeds) if print_output: print "Using max speed:", speed, "m/s" def mat_val(x, el): # Will be used in Evaluate(mat, val) for i in range(len(material_elements)): if el.id in material_elements[i]: return i return 0 # End of materials definition --- # Define the elastodynamics operator and the discretization --- kwargs = { 'dimensions': dim, 'speed': speed, 'material': make_tdep_given(mat_val), 'sources': sources, 'boundaryconditions_tag': \ {'stressfree': stfree_tag, 'fixed': fix_tag, 'open': op_tag}, 'materials': used_materials, 'flux_type': flux_type } operator = None if nonlinearity_type == 'cubic': kwargs['nonlinearity_type'] = nonlinearity_type if pml: from elastodynamic import CubicNPMLElastoDynamicsOperator operator = 'CubicNPMLElastoDynamicsOperator' else: raise NotImplementedError elif nonlinearity_type is not None: kwargs['nonlinearity_type'] = nonlinearity_type if pml: from elastodynamic import QuadraticNPMLElastoDynamicsOperator operator = 'QuadraticNPMLElastoDynamicsOperator' else: from elastodynamic import QuadraticElastoDynamicsOperator operator = 'QuadraticElastoDynamicsOperator' else: if pml: from elastodynamic import NPMLElastoDynamicsOperator operator = "NPMLElastoDynamicsOperator" else: from elastodynamic import ElastoDynamicsOperator operator = "ElastoDynamicsOperator" assert operator is not None, "Failed to define operator!" op = locals()[operator](**kwargs) if print_output: print "Using", operator discr = rcon.make_discretization(mesh_data, order=order, debug=debug, tune_for=op.op_template()) # End of elastodynamics operator and discretization definition --- # Define receivers --- receivers = [] point_receivers = [] if write_output and print_output: print "Using output dir:", output_dir if "receivers" in write_output: i = 0 if mesh_file: receivers = gmsh.pointReceivers if receivers != []: for receiver in receivers: try: point_receiver = Receiver() point_receiver.evaluator = discr.get_point_evaluator(numpy.array(receiver)) point_receiver.done_dt = False point_receiver.id = i point_receiver.coordinates = receiver point_receiver.filename = "receiver_%s.txt" % repr(point_receiver.coordinates) except: if not quiet_output: print "Receiver ignored (point not found):", receiver else: point_receivers.append(point_receiver) i += 1 print "Using", point_receiver.filename, "for receiver", receiver # End of receivers definition --- # Define visualization --- def write_datafile(filename, variables): if rcon is not None and len(rcon.ranks) > 1: filename += "-%04d" % rcon.rank visfile = open(filename + ".txt", "wt") visfile.write("x\ty\t") for name, field in variables: if name == "m": visfile.write("m\t") else: i = 0 for subvect in field: i += 1 assert len(subvect) == len(discr.nodes), "Wrong length!" visfile.write(name + "_" + format(i) + "\t") visfile.write("\n") for i in range(len(discr.nodes)): for coord in discr.nodes[i]: visfile.write(format(coord) + "\t") for name, field in variables: if name == "m": visfile.write(format(field[i]) + "\t") else: for subvect in field: visfile.write(format(subvect[i]) + "\t") visfile.write("\n") visfile.close() if 'vtu' in write_output: from hedge.visualization import VtkVisualizer vis = VtkVisualizer(discr, rcon, 'fld') if output_dir: chdir(output_dir) if 'receivers' in write_output: for point_receiver in point_receivers: point_receiver.pointfile = open(point_receiver.filename, "wt") #sumfile = open("receiver_%s_sum.txt" % rcon.rank, "wt") # End of visualization definition --- # Bind the operator to the discretization --- if pml: coefficients = op.coefficients_from_width(discr, mesh, widths=pml, material=materials[0], alpha_magnitude=2 * pi * source_param['fc'] / 10) rhs = op.bind(discr, coefficients) else: rhs = op.bind(discr) # End of operator binding --- # Define the timestep loop --- t = 0.0 max_txt = '' try: len_fields = op.len_q if pml: len_fields += op.len_f2 fields = make_obj_array([discr.volume_zeros(dtype=dtype) for _ in range(len_fields)]) vector_primitive_factory = None if 'cuda' in allow_features else discr.get_vector_primitive_factory() from hedge.timestep import times_and_steps, LSRK4TimeStepper stepper = LSRK4TimeStepper(vector_primitive_factory=vector_primitive_factory, dtype=dtype) max_dt_getter = lambda t: op.estimate_timestep(discr, stepper=stepper, t=t, fields=fields) step_it = times_and_steps(final_time=final_time, logmgr=None, max_dt_getter=max_dt_getter) for step, t, dt in step_it: if max_steps > 0: max_txt = ' on %d' % max_steps if step > max_steps: break if step % vtu_every == 0: variables = [("m", discr.convert_volume(op.m(fields), "numpy")), ("v", discr.convert_volume(op.v(fields), "numpy")), ("F", discr.convert_volume(op.F(fields), "numpy"))] if print_output: print time.strftime('[%H:%M:%S] ', time.localtime()) + \ 'Step: ' + format(step) + max_txt + '; time: ' + format(t) if 'vtu' in write_output: visf = vis.make_file("fld-%04d" % step) vis.add_data(visf, variables, time=t, step=step) visf.close() if 'txt' in write_output: write_datafile("fld-%04d" % step, variables) if 'receivers' in write_output and point_receivers != []: variables = discr.convert_volume(fields, "numpy") #sum_val = numpy.zeros(len(fields)) #sumfile.write("\n%s " % format(t)) for point_receiver in point_receivers: val = point_receiver.evaluator(variables) if not point_receiver.done_dt: point_receiver.pointfile.write("# dt: %g s\n" % dt) point_receiver.pointfile.write("# m: 1 field\n") point_receiver.pointfile.write("# v: %d fields\n" % dim) point_receiver.pointfile.write("# F: %d fields\n" % op.len_f) point_receiver.pointfile.write("# Coordinates: %s\n# t m " % repr(point_receiver.coordinates)) for i in range(dim): point_receiver.pointfile.write('v%s ' % i) for i in range(op.len_f): point_receiver.pointfile.write("F%s " % i) point_receiver.done_dt = True point_receiver.pointfile.write("\n%s " % format(t)) for i in range(1 + dim + op.len_f): #sum_val[i] += val[i] point_receiver.pointfile.write("%s " % format(val[i])) #for i in range(len(val)): #sumfile.write("%s " % format(sum_val[i])) fields = stepper(fields, t, dt, rhs) finally: if 'vtu' in write_output: vis.close() if 'receivers' in write_output: for point_receiver in point_receivers: point_receiver.pointfile.close() #sumfile.close() discr.close() if output_dir: chdir('..')