Exemplo n.º 1
0
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
Exemplo n.º 3
0
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()
Exemplo n.º 4
0
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()
Exemplo n.º 5
0
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()
Exemplo n.º 6
0
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()
Exemplo n.º 7
0
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()
Exemplo n.º 8
0
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()
Exemplo n.º 9
0
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()
Exemplo n.º 10
0
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()
Exemplo n.º 11
0
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('..')