Ejemplo n.º 1
0
def main(write_output=True):
    from math import sqrt, pi, exp
    from os.path import join

    from grudge.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 grudge.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 grudge.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 grudge.mesh import BTAG_ALL, BTAG_NONE
    from grudge.models.em import TMMaxwellOperator
    from grudge.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=BTAG_ALL,
                           pec_tag=BTAG_NONE)
    fields = op.assemble_eh(discr=discr)

    from grudge.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 grudge.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 grudge.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()
Ejemplo n.º 2
0
def main(write_output=True, allow_features=None):
    from grudge.timestep import RK4TimeStepper
    from grudge.mesh import make_ball_mesh, make_cylinder_mesh, make_box_mesh
    from grudge.visualization import \
            VtkVisualizer, \
            SiloVisualizer, \
            get_rank_partition
    from math import sqrt, pi

    from grudge.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.
    epsilon = 1 * epsilon0
    mu = 1 * mu0

    dims = 3

    if rcon.is_head_rank:
        if dims == 2:
            from grudge.mesh import make_rect_mesh
            mesh = make_rect_mesh(a=(-10.5, -1.5), b=(10.5, 1.5), max_area=0.1)
        elif dims == 3:
            from grudge.mesh import make_box_mesh
            mesh = make_box_mesh(a=(-10.5, -1.5, -1.5),
                                 b=(10.5, 1.5, 1.5),
                                 max_volume=0.1)

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

    #for order in [1,2,3,4,5,6]:
    discr = rcon.make_discretization(mesh_data, order=3)

    if write_output:
        vis = VtkVisualizer(discr, rcon, "dipole")

    from analytic_solutions import DipoleFarField, SphericalFieldAdapter
    from grudge.data import ITimeDependentGivenFunction

    sph_dipole = DipoleFarField(
        q=1,  #C
        d=1 / 39,
        omega=2 * pi * 1e8,
        epsilon=epsilon0,
        mu=mu0,
    )
    cart_dipole = SphericalFieldAdapter(sph_dipole)

    class PointDipoleSource(ITimeDependentGivenFunction):
        def __init__(self):
            from pyrticle.tools import CInfinityShapeFunction
            sf = CInfinityShapeFunction(0.1 * sph_dipole.wavelength,
                                        discr.dimensions)
            self.num_sf = discr.interpolate_volume_function(
                lambda x, el: sf(x))
            self.vol_0 = discr.volume_zeros()

        def volume_interpolant(self, t, discr):
            from grudge.tools import make_obj_array
            return make_obj_array([
                self.vol_0, self.vol_0,
                sph_dipole.source_modulation(t) * self.num_sf
            ])

    from grudge.mesh import BTAG_ALL, BTAG_NONE
    if dims == 2:
        from grudge.models.em import TMMaxwellOperator as MaxwellOperator
    else:
        from grudge.models.em import MaxwellOperator

    op = MaxwellOperator(
        epsilon,
        mu,
        flux_type=1,
        pec_tag=BTAG_NONE,
        absorb_tag=BTAG_ALL,
        current=PointDipoleSource(),
    )

    fields = op.assemble_eh(discr=discr)

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

    stepper = RK4TimeStepper()

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

    if write_output:
        log_file_name = "dipole.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 pytools.log import IntervalTimer
    vis_timer = IntervalTimer("t_vis", "Time spent visualizing")
    logmgr.add_quantity(vis_timer)

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

    from pytools.log import PushLogQuantity
    relerr_e_q = PushLogQuantity("relerr_e", "1",
                                 "Relative error in masked E-field")
    relerr_h_q = PushLogQuantity("relerr_h", "1",
                                 "Relative error in masked H-field")
    logmgr.add_quantity(relerr_e_q)
    logmgr.add_quantity(relerr_h_q)

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

    if write_output:
        point_timeseries = [(open("b-x%d-vs-time.dat" % i,
                                  "w"), open("b-x%d-vs-time-true.dat" % i,
                                             "w"),
                             discr.get_point_evaluator(
                                 numpy.array([i, 0, 0][:dims],
                                             dtype=discr.default_scalar_type)))
                            for i in range(1, 5)]

    # timestep loop -------------------------------------------------------
    mask = discr.interpolate_volume_function(sph_dipole.far_field_mask)

    def apply_mask(field):
        from grudge.tools import log_shape
        ls = log_shape(field)
        result = discr.volume_empty(ls)
        from pytools import indices_in_shape
        for i in indices_in_shape(ls):
            result[i] = mask * field[i]

        return result

    rhs = op.bind(discr)

    t = 0
    try:
        from grudge.timestep import times_and_steps
        step_it = times_and_steps(
            final_time=1e-8,
            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 write_output and step % 10 == 0:
                sub_timer = vis_timer.start_sub_timer()
                e, h = op.split_eh(fields)
                sph_dipole.set_time(t)
                true_e, true_h = op.split_eh(
                    discr.interpolate_volume_function(cart_dipole))
                visf = vis.make_file("dipole-%04d" % step)

                mask_e = apply_mask(e)
                mask_h = apply_mask(h)
                mask_true_e = apply_mask(true_e)
                mask_true_h = apply_mask(true_h)

                from pyvisfile.silo import DB_VARTYPE_VECTOR
                vis.add_data(visf, [("e", e), ("h", h), ("true_e", true_e),
                                    ("true_h", true_h), ("mask_e", mask_e),
                                    ("mask_h", mask_h),
                                    ("mask_true_e", mask_true_e),
                                    ("mask_true_h", mask_true_h)],
                             time=t,
                             step=step)
                visf.close()
                sub_timer.stop().submit()

                from grudge.tools import relative_error
                relerr_e_q.push_value(
                    relative_error(discr.norm(mask_e - mask_true_e),
                                   discr.norm(mask_true_e)))
                relerr_h_q.push_value(
                    relative_error(discr.norm(mask_h - mask_true_h),
                                   discr.norm(mask_true_h)))

                if write_output:
                    for outf_num, outf_true, evaluator in point_timeseries:
                        for outf, ev_h in zip([outf_num, outf_true],
                                              [h, true_h]):
                            outf.write("%g\t%g\n" %
                                       (t, op.mu * evaluator(ev_h[1])))
                            outf.flush()

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

    finally:
        if write_output:
            vis.close()

        logmgr.save()
        discr.close()
Ejemplo n.º 3
0
def main(write_output=True):
    from grudge.timestep.runge_kutta import LSRK4TimeStepper
    from math import sqrt, pi, exp

    from grudge.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

    c = 1 / sqrt(mu * epsilon)

    pml_width = 0.5
    #mesh = make_mesh(a=np.array((-1,-1,-1)), b=np.array((1,1,1)),
    #mesh = make_mesh(a=np.array((-3,-3)), b=np.array((3,3)),
    mesh = make_mesh(
        a=np.array((-1, -1)),
        b=np.array((1, 1)),
        #mesh = make_mesh(a=np.array((-2,-2)), b=np.array((2,2)),
        pml_width=pml_width,
        max_volume=0.01)

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

    class Current:
        def volume_interpolant(self, t, discr):
            from grudge.tools import make_obj_array

            result = discr.volume_zeros(kind="numpy", dtype=np.float64)

            omega = 6 * c
            if omega * t > 2 * pi:
                return make_obj_array([result, result, result])

            x = make_obj_array(discr.nodes.T)
            r = np.sqrt(np.dot(x, x))

            idx = r < 0.3
            result[idx] = (1+np.cos(pi*r/0.3))[idx] \
                    *np.sin(omega*t)**3

            result = discr.convert_volume(result,
                                          kind=discr.compute_kind,
                                          dtype=discr.default_scalar_type)
            return make_obj_array([-result, result, result])

    order = 3
    discr = rcon.make_discretization(mesh_data,
                                     order=order,
                                     debug=["cuda_no_plan"])

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

    from grudge.mesh import BTAG_ALL, BTAG_NONE
    from grudge.data import GivenFunction, TimeHarmonicGivenFunction, TimeIntervalGivenFunction
    from grudge.models.em import MaxwellOperator
    from grudge.models.pml import \
            AbarbanelGottliebPMLMaxwellOperator, \
            AbarbanelGottliebPMLTMMaxwellOperator, \
            AbarbanelGottliebPMLTEMaxwellOperator

    op = AbarbanelGottliebPMLTEMaxwellOperator(epsilon,
                                               mu,
                                               flux_type=1,
                                               current=Current(),
                                               pec_tag=BTAG_ALL,
                                               absorb_tag=BTAG_NONE,
                                               add_decay=True)

    fields = op.assemble_ehpq(discr=discr)

    stepper = LSRK4TimeStepper()

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

    # diagnostics setup ---------------------------------------------------
    from logpyle import LogManager, add_general_quantities, \
            add_simulation_quantities, add_run_info

    if write_output:
        log_file_name = "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 logpyle import IntervalTimer
    vis_timer = IntervalTimer("t_vis", "Time spent visualizing")
    logmgr.add_quantity(vis_timer)

    from grudge.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"])

    from grudge.log import LpNorm

    class FieldIdxGetter:
        def __init__(self, whole_getter, idx):
            self.whole_getter = whole_getter
            self.idx = idx

        def __call__(self):
            return self.whole_getter()[self.idx]

    # timestep loop -------------------------------------------------------

    t = 0
    pml_coeff = op.coefficients_from_width(discr, width=pml_width)
    rhs = op.bind(discr, pml_coeff)

    try:
        from grudge.timestep import times_and_steps
        step_it = times_and_steps(
            final_time=4 / c,
            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, p, q = op.split_ehpq(fields)
                visf = vis.make_file("em-%d-%04d" % (order, step))
                #pml_rhs_e, pml_rhs_h, pml_rhs_p, pml_rhs_q = \
                #op.split_ehpq(rhs(t, fields))
                j = Current().volume_interpolant(t, discr)
                vis.add_data(
                    visf,
                    [
                        ("e", discr.convert_volume(e, "numpy")),
                        ("h", discr.convert_volume(h, "numpy")),
                        ("p", discr.convert_volume(p, "numpy")),
                        ("q", discr.convert_volume(q, "numpy")),
                        ("j", discr.convert_volume(j, "numpy")),
                        #("pml_rhs_e", pml_rhs_e),
                        #("pml_rhs_h", pml_rhs_h),
                        #("pml_rhs_p", pml_rhs_p),
                        #("pml_rhs_q", pml_rhs_q),
                        #("max_rhs_e", max_rhs_e),
                        #("max_rhs_h", max_rhs_h),
                        #("max_rhs_p", max_rhs_p),
                        #("max_rhs_q", max_rhs_q),
                    ],
                    time=t,
                    step=step)
                visf.close()

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

        _, _, energies_data = logmgr.get_expr_dataset("W_el+W_mag")
        energies = [value for tick_nbr, value in energies_data]

        assert energies[-1] < max(energies) * 1e-2

    finally:
        logmgr.close()

        if write_output:
            vis.close()