Beispiel #1
0
    def initial_val(discr):
        # the initial solution for the TE_10-like mode
        def initial_Hz(x, el):
            from math import cos, sin
            if el in material_elements["vacuum"]:
                return h*cos(h*x[0])
            else:
                return -l*sin(h*d)/sin(l*(a-d))*cos(l*(a-x[0]))

        from hedge.tools import make_obj_array
        result_zero = discr.volume_zeros(kind="numpy", dtype=numpy.float64)
        H_z = make_tdep_given(initial_Hz).volume_interpolant(0, discr)
        return make_obj_array([result_zero, result_zero, H_z])
Beispiel #2
0
def main(write_output=True):
    from math import sqrt, pi, exp
    from os.path import join

    from hedge.backends import guess_run_context
    rcon = guess_run_context()

    epsilon0 = 8.8541878176e-12 # C**2 / (N m**2)
    mu0 = 4*pi*1e-7 # N/A**2.
    epsilon = 1*epsilon0
    mu = 1*mu0

    output_dir = "maxwell-2d"
    import os
    if not os.access(output_dir, os.F_OK):
        os.makedirs(output_dir)
    
    from hedge.mesh.generator import make_disk_mesh
    mesh = make_disk_mesh(r=0.5, max_area=1e-3)

    if rcon.is_head_rank:
        mesh_data = rcon.distribute_mesh(mesh)
    else:
        mesh_data = rcon.receive_mesh()

    class CurrentSource:
        shape = (3,)

        def __call__(self, x, el):
            return [0,0,exp(-80*la.norm(x))]

    order = 3
    final_time = 1e-8
    discr = rcon.make_discretization(mesh_data, order=order,
            debug=["cuda_no_plan"])

    from hedge.visualization import VtkVisualizer
    if write_output:
        vis = VtkVisualizer(discr, rcon, join(output_dir, "em-%d" % order))

    if rcon.is_head_rank:
        print "order %d" % order
        print "#elements=", len(mesh.elements)

    from hedge.mesh import TAG_ALL, TAG_NONE
    from hedge.models.em import TMMaxwellOperator
    from hedge.data import make_tdep_given, TimeIntervalGivenFunction
    op = TMMaxwellOperator(epsilon, mu, flux_type=1,
            current=TimeIntervalGivenFunction(
                make_tdep_given(CurrentSource()), off_time=final_time/10),
            absorb_tag=TAG_ALL, pec_tag=TAG_NONE)
    fields = op.assemble_eh(discr=discr)

    from hedge.timestep import LSRK4TimeStepper
    stepper = LSRK4TimeStepper()
    from time import time
    last_tstep = time()
    t = 0

    # diagnostics setup ---------------------------------------------------
    from pytools.log import LogManager, add_general_quantities, \
            add_simulation_quantities, add_run_info

    if write_output:
        log_file_name = join(output_dir, "maxwell-%d.dat" % order)
    else:
        log_file_name = None

    logmgr = LogManager(log_file_name, "w", rcon.communicator)
    add_run_info(logmgr)
    add_general_quantities(logmgr)
    add_simulation_quantities(logmgr)
    discr.add_instrumentation(logmgr)
    stepper.add_instrumentation(logmgr)

    from pytools.log import IntervalTimer
    vis_timer = IntervalTimer("t_vis", "Time spent visualizing")
    logmgr.add_quantity(vis_timer)

    from hedge.log import EMFieldGetter, add_em_quantities
    field_getter = EMFieldGetter(discr, op, lambda: fields)
    add_em_quantities(logmgr, op, field_getter)

    logmgr.add_watches(["step.max", "t_sim.max", 
        ("W_field", "W_el+W_mag"), "t_step.max"])

    # timestep loop -------------------------------------------------------
    rhs = op.bind(discr)

    try:
        from hedge.timestep import times_and_steps
        step_it = times_and_steps(
                final_time=final_time, 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:
                e, h = op.split_eh(fields)
                visf = vis.make_file(join(output_dir, "em-%d-%04d" % (order, step)))
                vis.add_data(visf,
                        [
                            ("e", discr.convert_volume(e, "numpy")),
                            ("h", discr.convert_volume(h, "numpy")),
                            ],
                        time=t, step=step
                        )
                visf.close()

            fields = stepper(fields, t, dt, rhs)

        assert discr.norm(fields) < 0.03
    finally:
        if write_output:
            vis.close()

        logmgr.close()
        discr.close()
Beispiel #3
0
def main(write_output=True):
    from math import sqrt, pi, exp
    from os.path import join

    from hedge.backends import guess_run_context
    rcon = guess_run_context()

    epsilon0 = 8.8541878176e-12  # C**2 / (N m**2)
    mu0 = 4 * pi * 1e-7  # N/A**2.
    epsilon = 1 * epsilon0
    mu = 1 * mu0

    output_dir = "maxwell-2d"
    import os
    if not os.access(output_dir, os.F_OK):
        os.makedirs(output_dir)

    from hedge.mesh.generator import make_disk_mesh
    mesh = make_disk_mesh(r=0.5, max_area=1e-3)

    if rcon.is_head_rank:
        mesh_data = rcon.distribute_mesh(mesh)
    else:
        mesh_data = rcon.receive_mesh()

    class CurrentSource:
        shape = (3, )

        def __call__(self, x, el):
            return [0, 0, exp(-80 * la.norm(x))]

    order = 3
    final_time = 1e-8
    discr = rcon.make_discretization(mesh_data,
                                     order=order,
                                     debug=["cuda_no_plan"])

    from hedge.visualization import VtkVisualizer
    if write_output:
        vis = VtkVisualizer(discr, rcon, join(output_dir, "em-%d" % order))

    if rcon.is_head_rank:
        print "order %d" % order
        print "#elements=", len(mesh.elements)

    from hedge.mesh import TAG_ALL, TAG_NONE
    from hedge.models.em import TMMaxwellOperator
    from hedge.data import make_tdep_given, TimeIntervalGivenFunction
    op = TMMaxwellOperator(epsilon,
                           mu,
                           flux_type=1,
                           current=TimeIntervalGivenFunction(
                               make_tdep_given(CurrentSource()),
                               off_time=final_time / 10),
                           absorb_tag=TAG_ALL,
                           pec_tag=TAG_NONE)
    fields = op.assemble_eh(discr=discr)

    from hedge.timestep import LSRK4TimeStepper
    stepper = LSRK4TimeStepper()
    from time import time
    last_tstep = time()
    t = 0

    # diagnostics setup ---------------------------------------------------
    from pytools.log import LogManager, add_general_quantities, \
            add_simulation_quantities, add_run_info

    if write_output:
        log_file_name = join(output_dir, "maxwell-%d.dat" % order)
    else:
        log_file_name = None

    logmgr = LogManager(log_file_name, "w", rcon.communicator)
    add_run_info(logmgr)
    add_general_quantities(logmgr)
    add_simulation_quantities(logmgr)
    discr.add_instrumentation(logmgr)
    stepper.add_instrumentation(logmgr)

    from pytools.log import IntervalTimer
    vis_timer = IntervalTimer("t_vis", "Time spent visualizing")
    logmgr.add_quantity(vis_timer)

    from hedge.log import EMFieldGetter, add_em_quantities
    field_getter = EMFieldGetter(discr, op, lambda: fields)
    add_em_quantities(logmgr, op, field_getter)

    logmgr.add_watches(
        ["step.max", "t_sim.max", ("W_field", "W_el+W_mag"), "t_step.max"])

    # timestep loop -------------------------------------------------------
    rhs = op.bind(discr)

    try:
        from hedge.timestep import times_and_steps
        step_it = times_and_steps(
            final_time=final_time,
            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:
                e, h = op.split_eh(fields)
                visf = vis.make_file(
                    join(output_dir, "em-%d-%04d" % (order, step)))
                vis.add_data(visf, [
                    ("e", discr.convert_volume(e, "numpy")),
                    ("h", discr.convert_volume(h, "numpy")),
                ],
                             time=t,
                             step=step)
                visf.close()

            fields = stepper(fields, t, dt, rhs)

        assert discr.norm(fields) < 0.03
    finally:
        if write_output:
            vis.close()

        logmgr.close()
        discr.close()
Beispiel #4
0
def main(write_output=True, 
        dir_tag=TAG_NONE, neu_tag=TAG_NONE, rad_tag=TAG_ALL, 
        flux_type_arg="upwind", dtype=numpy.float64, debug=[]):
    from pytools.stopwatch import Job
    from math import sin, cos, pi, exp, sqrt

    from hedge.backends import guess_run_context
    rcon = guess_run_context()

    dim = 3

    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)


    def source_u(x, el):
        return exp(-numpy.dot(x, x)*128)

    from hedge.models.wave import StrongWaveOperator
    from hedge.mesh import TAG_ALL, TAG_NONE
    from hedge.data import \
            make_tdep_given, \
            TimeHarmonicGivenFunction, \
            TimeIntervalGivenFunction

    op = StrongWaveOperator(-1, dim,
            source_f=TimeIntervalGivenFunction(
                TimeHarmonicGivenFunction(
                    make_tdep_given(source_u), omega=10),
                0, 1),
            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 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:
        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()
Beispiel #5
0
def main(write_output=True, allow_features=None, flux_type_arg=1,
        bdry_flux_type_arg=None, extra_discr_args={}):
    from math import sqrt, pi
    from hedge.models.em import TEMaxwellOperator

    from hedge.backends import guess_run_context
    rcon = guess_run_context(allow_features)

    epsilon0 = 8.8541878176e-12 # C**2 / (N m**2)
    mu0 = 4*pi*1e-7 # N/A**2.
    c = 1/sqrt(mu0*epsilon0)

    materials = {"vacuum" : (epsilon0, mu0),
                 "dielectric" : (2*epsilon0, mu0)}

    output_dir = "2d_cavity"

    import os
    if not os.access(output_dir, os.F_OK):
        os.makedirs(output_dir)

    # should no tag raise an error or default to free space?
    def eps_val(x, el):
        for key in materials.keys():
            if el in material_elements[key]:
                return materials[key][0]
        raise ValueError, "Element does not belong to any material"

    def mu_val(x, el):
        for key in materials.keys():
            if el in material_elements[key]:
                return materials[key][1]
        raise ValueError, "Element does not belong to any material"

    # geometry of cavity
    d = 100e-3
    a = 150e-3

    # analytical frequency and transverse wavenumbers of resonance
    f0 = 9.0335649907522321e8
    h = 2*pi*f0/c
    l = -h*sqrt(2)

    # substitute the following and change materials for a homogeneous cavity
    #h = pi/a
    #l =-h

    def initial_val(discr):
        # the initial solution for the TE_10-like mode
        def initial_Hz(x, el):
            from math import cos, sin
            if el in material_elements["vacuum"]:
                return h*cos(h*x[0])
            else:
                return -l*sin(h*d)/sin(l*(a-d))*cos(l*(a-x[0]))

        from hedge.tools import make_obj_array
        result_zero = discr.volume_zeros(kind="numpy", dtype=numpy.float64)
        H_z = make_tdep_given(initial_Hz).volume_interpolant(0, discr)
        return make_obj_array([result_zero, result_zero, H_z])

    if rcon.is_head_rank:
        from hedge.mesh.reader.gmsh import generate_gmsh
        mesh = generate_gmsh(CAVITY_GEOMETRY, 2, force_dimension=2)
        mesh_data = rcon.distribute_mesh(mesh)
    else:
        mesh_data = rcon.receive_mesh()

    # Work out which elements belong to each material
    material_elements = {}
    for key in materials.keys():
        material_elements[key] = set(mesh_data.tag_to_elements[key])

    order = 3
    #extra_discr_args.setdefault("debug", []).append("cuda_no_plan")
    #extra_discr_args.setdefault("debug", []).append("dump_optemplate_stages")

    from hedge.data import make_tdep_given
    from hedge.mesh import TAG_ALL

    op = TEMaxwellOperator(epsilon=make_tdep_given(eps_val), mu=make_tdep_given(mu_val), \
            flux_type=flux_type_arg, \
            bdry_flux_type=bdry_flux_type_arg, dimensions=2, pec_tag=TAG_ALL)
    # op = TEMaxwellOperator(epsilon=epsilon0, mu=mu0,
            # flux_type=flux_type_arg, \
            # bdry_flux_type=bdry_flux_type_arg, dimensions=2, pec_tag=TAG_ALL)

    discr = rcon.make_discretization(mesh_data, order=order,
            tune_for=op.op_template(),
            **extra_discr_args)

    # create the initial solution
    fields = initial_val(discr)

    from hedge.visualization import VtkVisualizer
    if write_output:
        from os.path import join
        vis = VtkVisualizer(discr, rcon, join(output_dir, "cav-%d" % order))

    # monitor the solution at a point to find the resonant frequency
    try:
        point_getter = discr.get_point_evaluator(numpy.array([75e-3, 25e-3, 0])) #[0.25, 0.25, 0.25]))
    except RuntimeError:
        point_getter = None

    if rcon.is_head_rank:
        print "---------------------------------------------"
        print "order %d" % order
        print "---------------------------------------------"
        print "#elements=", len(mesh.elements)

    from hedge.timestep.runge_kutta import LSRK4TimeStepper
    stepper = LSRK4TimeStepper(dtype=discr.default_scalar_type, rcon=rcon)
    #from hedge.timestep.dumka3 import Dumka3TimeStepper
    #stepper = Dumka3TimeStepper(3, dtype=discr.default_scalar_type, rcon=rcon)

    # diagnostics setup ---------------------------------------------------
    from pytools.log import LogManager, add_general_quantities, \
            add_simulation_quantities, add_run_info

    if write_output:
        from os.path import join
        log_file_name = join(output_dir, "cavity-%d.dat" % order)
    else:
        log_file_name = None

    logmgr = LogManager(log_file_name, "w", rcon.communicator)

    add_run_info(logmgr)
    add_general_quantities(logmgr)
    add_simulation_quantities(logmgr)
    discr.add_instrumentation(logmgr)
    stepper.add_instrumentation(logmgr)

    from pytools.log import IntervalTimer
    vis_timer = IntervalTimer("t_vis", "Time spent visualizing")
    logmgr.add_quantity(vis_timer)

    #from hedge.log import EMFieldGetter, add_em_quantities
    #field_getter = EMFieldGetter(discr, op, lambda: fields)
    #add_em_quantities(logmgr, op, field_getter)

    logmgr.add_watches(
            ["step.max", "t_sim.max",
                #("W_field", "W_el+W_mag"),
                "t_step.max"]
            )

    # timestep loop -------------------------------------------------------
    rhs = op.bind(discr)
    final_time = 10e-9

    if point_getter is not None:
        from os.path import join
        pointfile = open(join(output_dir, "point.txt"), "wt")
        done_dt = False
    try:
        from hedge.timestep import times_and_steps
        from os.path import join
        step_it = times_and_steps(
                final_time=final_time, 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:
                sub_timer = vis_timer.start_sub_timer()
                e, h = op.split_eh(fields)
                visf = vis.make_file(join(output_dir, "cav-%d-%04d") % (order, step))
                vis.add_data(visf,
                        [
                            ("e",
                                discr.convert_volume(e, kind="numpy")),
                            ("h",
                                discr.convert_volume(h, kind="numpy")),],
                        time=t, step=step
                        )
                visf.close()
                sub_timer.stop().submit()

            fields = stepper(fields, t, dt, rhs)
            if point_getter is not None:
                val = point_getter(fields)
                #print val
                if not done_dt:
                    pointfile.write("#%g\n" % dt)
                    done_dt = True
                pointfile.write("%g\n" %val[0])

    finally:
        if write_output:
            vis.close()

        logmgr.close()
        discr.close()

        if point_getter is not None:
            pointfile.close()
Beispiel #6
0
def main(write_output=True):
    from math import sin, exp, sqrt

    from hedge.mesh.generator import make_rect_mesh
    mesh = make_rect_mesh(a=(-0.5,-0.5),b=(0.5,0.5),max_area=0.008)

    from hedge.backends.jit import Discretization

    discr = Discretization(mesh, order=4)

    from hedge.visualization import VtkVisualizer
    vis = VtkVisualizer(discr, None, "fld")

    def source_u(x, el):
        x = x - numpy.array([0.1,0.22])
        return exp(-numpy.dot(x, x)*128)

    from hedge.data import \
            make_tdep_given, \
            TimeHarmonicGivenFunction, \
            TimeIntervalGivenFunction

    from hedge.models.wave import StrongWaveOperator
    from hedge.mesh import TAG_ALL, TAG_NONE
    op = StrongWaveOperator(-1, discr.dimensions, 
            source_f=TimeIntervalGivenFunction(
                TimeHarmonicGivenFunction(
                    make_tdep_given(source_u), omega=10),
                0, 1),
            dirichlet_tag=TAG_NONE,
            neumann_tag=TAG_NONE,
            radiation_tag=TAG_ALL,
            flux_type="upwind")

    from hedge.tools import join_fields
    fields = join_fields(discr.volume_zeros(),
            [discr.volume_zeros() for i in range(discr.dimensions)])

    from hedge.timestep import RK4TimeStepper
    stepper = RK4TimeStepper()
    dt = op.estimate_timestep(discr, stepper=stepper, fields=fields)

    nsteps = int(1/dt)
    print "dt=%g nsteps=%d" % (dt, nsteps)

    rhs = op.bind(discr)
    for step in range(nsteps):
        t = step*dt

        if step % 50 == 0 and write_output:
            print step, t, discr.norm(fields[0])
            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)

    vis.close()
Beispiel #7
0
def main(write_output=True, 
        flux_type_arg="upwind", dtype=numpy.float64, debug=[]):
    from pytools.stopwatch import Job
    from math import sin, cos, pi, exp, sqrt

    from hedge.backends import guess_run_context
    rcon = guess_run_context()

    if rcon.is_head_rank:
        from hedge.mesh.reader.gmsh import generate_gmsh
        mesh = generate_gmsh(GEOMETRY, 2,
                allow_internal_boundaries=True)

        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, debug=debug,
            default_scalar_type=dtype)
    from hedge.timestep import RK4TimeStepper
    stepper = RK4TimeStepper(dtype=dtype)

    from hedge.visualization import VtkVisualizer
    if write_output:
        vis = VtkVisualizer(discr, rcon, "fld")

    def source_u(x, el):
        return exp(-numpy.dot(x, x)*128)

    from hedge.models.wave import StrongWaveOperator
    from hedge.mesh import TAG_ALL, TAG_NONE
    from hedge.data import \
            make_tdep_given, \
            TimeHarmonicGivenFunction, \
            TimeIntervalGivenFunction

    op = StrongWaveOperator(-1, discr.dimensions, 
            source_f=TimeIntervalGivenFunction(
                TimeHarmonicGivenFunction(
                    make_tdep_given(source_u), omega=10),
                0, 1),
            dirichlet_tag="boundary",
            neumann_tag=TAG_NONE,
            radiation_tag=TAG_NONE,
            flux_type=flux_type_arg
            )

    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 = "wiggly.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)

    logmgr.add_watches(["step.max", "t_sim.max", "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", fields[0]),
                            ("v", fields[1:]), 
                        ],
                        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()
Beispiel #8
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()
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('..')
 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'])