def no_test_tri_mass_mat_gauss(self):
    """Check the integral of a Gaussian on a disk using the mass matrix"""

    # This is a bad test, since it's never exact. The Gaussian has infinite support,
    # and this *does* matter numerically.

    from hedge.mesh.generator import make_disk_mesh
    from hedge.discretization.local import TriangleDiscretization
    from math import sqrt, exp, pi

    sigma_squared = 1 / 219.3

    mesh = make_disk_mesh()
    discr = self.discr_class(
        make_disk_mesh(), TriangleDiscretization(4), debug=self.discr_class.noninteractive_debug_flags()
    )
    f = discr.interpolate_volume_function(lambda x, el: exp(-x * x / (2 * sigma_squared)))
    ones = discr.interpolate_volume_function(lambda x, el: 1)

    # discr.visualize_vtk("gaussian.vtk", [("f", f)])
    num_integral_1 = ones * (discr.mass_operator * f)
    num_integral_2 = f * (discr.mass_operator * ones)
    dim = 2
    true_integral = (2 * pi) ** (dim / 2) * sqrt(sigma_squared) ** dim
    err_1 = abs(num_integral_1 - true_integral)
    err_2 = abs(num_integral_2 - true_integral)
    self.assert_(err_1 < 1e-11)
    self.assert_(err_2 < 1e-11)
def test_tri_diff_mat():
    """Check differentiation matrix along the coordinate axes on a disk

    Uses sines as the function to differentiate.
    """
    from hedge.mesh.generator import make_disk_mesh
    from hedge.discretization.local import TriangleDiscretization
    from math import sin, cos, sqrt

    from hedge.optemplate import make_nabla

    nabla = make_nabla(2)

    for coord in [0, 1]:
        mesh = make_disk_mesh()
        discr = discr_class(make_disk_mesh(), TriangleDiscretization(4), debug=discr_class.noninteractive_debug_flags())
        f = discr.interpolate_volume_function(lambda x, el: sin(3 * x[coord]))
        df = discr.interpolate_volume_function(lambda x, el: 3 * cos(3 * x[coord]))

        df_num = nabla[coord].apply(discr, f)
        # discr.visualize_vtk("diff-err.vtk",
        # [("f", f), ("df", df), ("df_num", df_num), ("error", error)])

        linf_error = la.norm(df_num - df, numpy.Inf)
        print linf_error
        assert linf_error < 4e-5
def test_tri_diff_mat():
    """Check differentiation matrix along the coordinate axes on a disk

    Uses sines as the function to differentiate.
    """
    from hedge.mesh.generator import make_disk_mesh
    from hedge.discretization.local import TriangleDiscretization
    from math import sin, cos

    from hedge.optemplate import make_nabla
    nabla = make_nabla(2)

    for coord in [0, 1]:
        discr = discr_class(make_disk_mesh(),
                            TriangleDiscretization(4),
                            debug=discr_class.noninteractive_debug_flags())
        f = discr.interpolate_volume_function(lambda x, el: sin(3 * x[coord]))
        df = discr.interpolate_volume_function(
            lambda x, el: 3 * cos(3 * x[coord]))

        df_num = nabla[coord].apply(discr, f)
        #discr.visualize_vtk("diff-err.vtk",
        #[("f", f), ("df", df), ("df_num", df_num), ("error", error)])

        linf_error = la.norm(df_num - df, numpy.Inf)
        print linf_error
        assert linf_error < 4e-5
def no_test_tri_mass_mat_gauss(self):
    """Check the integral of a Gaussian on a disk using the mass matrix"""

    # This is a bad test, since it's never exact. The Gaussian has infinite support,
    # and this *does* matter numerically.

    from hedge.mesh.generator import make_disk_mesh
    from hedge.discretization.local import TriangleDiscretization
    from math import sqrt, exp, pi

    sigma_squared = 1 / 219.3

    discr = self.discr_class(
        make_disk_mesh(),
        TriangleDiscretization(4),
        debug=self.discr_class.noninteractive_debug_flags())
    f = discr.interpolate_volume_function(
        lambda x, el: exp(-x * x / (2 * sigma_squared)))
    ones = discr.interpolate_volume_function(lambda x, el: 1)

    #discr.visualize_vtk("gaussian.vtk", [("f", f)])
    num_integral_1 = ones * (discr.mass_operator * f)
    num_integral_2 = f * (discr.mass_operator * ones)
    dim = 2
    true_integral = (2 * pi)**(dim / 2) * sqrt(sigma_squared)**dim
    err_1 = abs(num_integral_1 - true_integral)
    err_2 = abs(num_integral_2 - true_integral)
    self.assert_(err_1 < 1e-11)
    self.assert_(err_2 < 1e-11)
def test_projection():
    """Test whether projection between different orders works"""

    from hedge.mesh.generator import make_disk_mesh
    from hedge.discretization import Projector
    from hedge.discretization.local import TriangleDiscretization
    from math import sin, pi

    from numpy import dot

    a = numpy.array([1, 3])

    def u_analytic(x, el):
        return sin(dot(a, x))

    mesh = make_disk_mesh(r=pi, max_area=0.5)

    discr2 = discr_class(mesh,
                         TriangleDiscretization(2),
                         debug=discr_class.noninteractive_debug_flags())
    discr5 = discr_class(mesh,
                         TriangleDiscretization(5),
                         debug=discr_class.noninteractive_debug_flags())
    p2to5 = Projector(discr2, discr5)
    p5to2 = Projector(discr5, discr2)

    u2 = discr2.interpolate_volume_function(u_analytic)
    u2_i = p5to2(p2to5(u2))
    assert discr2.norm(u2 - u2_i) < 3e-15
def test_projection():
    """Test whether projection between different orders works"""

    from hedge.mesh.generator import make_disk_mesh
    from hedge.discretization import Projector
    from hedge.discretization.local import TriangleDiscretization
    from hedge.tools import EOCRecorder
    from math import sin, pi, sqrt

    from numpy import dot

    a = numpy.array([1, 3])

    def u_analytic(x, el):
        return sin(dot(a, x))

    mesh = make_disk_mesh(r=pi, max_area=0.5)

    discr2 = discr_class(mesh, TriangleDiscretization(2), debug=discr_class.noninteractive_debug_flags())
    discr5 = discr_class(mesh, TriangleDiscretization(5), debug=discr_class.noninteractive_debug_flags())
    p2to5 = Projector(discr2, discr5)
    p5to2 = Projector(discr5, discr2)

    u2 = discr2.interpolate_volume_function(u_analytic)
    u2_i = p5to2(p2to5(u2))
    assert discr2.norm(u2 - u2_i) < 3e-15
def test_filter():
    """Exercise mode-based filtering."""

    from hedge.mesh.generator import make_disk_mesh
    from hedge.discretization.local import TriangleDiscretization
    from math import sin

    mesh = make_disk_mesh(r=3.4, max_area=0.5)
    discr = discr_class(mesh,
                        TriangleDiscretization(5),
                        debug=discr_class.noninteractive_debug_flags())

    from hedge.optemplate.operators import FilterOperator
    from hedge.discretization import ExponentialFilterResponseFunction
    half_filter = FilterOperator(lambda mid, ldis: 0.5)
    for eg in discr.element_groups:
        fmat = half_filter.matrix(eg)
        n, m = fmat.shape
        assert la.norm(fmat - 0.5 * numpy.eye(n, m)) < 2e-15

    from numpy import dot

    def test_freq(n):
        a = numpy.array([1, n])

        def u_analytic(x, el):
            return sin(dot(a, x))

        exp_filter = FilterOperator(ExponentialFilterResponseFunction(0.9, 3)) \
                .bind(discr)

        u = discr.interpolate_volume_function(u_analytic)
        filt_u = exp_filter(u)

        int_error = abs(discr.integral(u) - discr.integral(filt_u))
        l2_ratio = discr.norm(filt_u) / discr.norm(u)
        assert int_error < 1e-14
        assert 0.96 < l2_ratio < 0.99999

    test_freq(3)
    test_freq(5)
    test_freq(9)
    test_freq(17)
Beispiel #8
0
def test_filter():
    """Exercise mode-based filtering."""

    from hedge.mesh.generator import make_disk_mesh
    from hedge.discretization.local import TriangleDiscretization
    from math import sin

    mesh = make_disk_mesh(r=3.4, max_area=0.5)
    discr = discr_class(mesh, TriangleDiscretization(5),
            debug=discr_class.noninteractive_debug_flags())

    from hedge.optemplate.operators import FilterOperator
    from hedge.discretization import ExponentialFilterResponseFunction
    half_filter = FilterOperator(lambda mid, ldis: 0.5)
    for eg in discr.element_groups:
        fmat = half_filter.matrix(eg)
        n, m = fmat.shape
        assert la.norm(fmat - 0.5*numpy.eye(n, m)) < 2e-15

    from numpy import dot

    def test_freq(n):
        a = numpy.array([1, n])

        def u_analytic(x, el):
            return sin(dot(a, x))

        exp_filter = FilterOperator(ExponentialFilterResponseFunction(0.9, 3)) \
                .bind(discr)

        u = discr.interpolate_volume_function(u_analytic)
        filt_u = exp_filter(u)

        int_error = abs(discr.integral(u) - discr.integral(filt_u))
        l2_ratio = discr.norm(filt_u) / discr.norm(u)
        assert int_error < 1e-14
        assert 0.96 < l2_ratio < 0.99999

    test_freq(3)
    test_freq(5)
    test_freq(9)
    test_freq(17)
Beispiel #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()
Beispiel #10
0
def main(write_output=True):
    from hedge.data import GivenFunction, ConstantGivenFunction

    from hedge.backends import guess_run_context
    rcon = guess_run_context()

    dim = 2

    def boundary_tagger(fvi, el, fn, points):
        from math import atan2, pi
        normal = el.face_normals[fn]
        if -90/180*pi < atan2(normal[1], normal[0]) < 90/180*pi:
            return ["neumann"]
        else:
            return ["dirichlet"]

    if dim == 2:
        if rcon.is_head_rank:
            from hedge.mesh.generator import make_disk_mesh
            mesh = make_disk_mesh(r=0.5, boundary_tagger=boundary_tagger,
                    max_area=1e-2)
    elif dim == 3:
        if rcon.is_head_rank:
            from hedge.mesh.generator import make_ball_mesh
            mesh = make_ball_mesh(max_volume=0.0001,
                    boundary_tagger=lambda fvi, el, fn, points:
                    ["dirichlet"])
    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=5, 
            debug=[])

    def dirichlet_bc(x, el):
        from math import sin
        return sin(10*x[0])

    def rhs_c(x, el):
        if la.norm(x) < 0.1:
            return 1000
        else:
            return 0

    def my_diff_tensor():
        result = numpy.eye(dim)
        result[0,0] = 0.1
        return result

    try:
        from hedge.models.poisson import PoissonOperator
        from hedge.second_order import \
                IPDGSecondDerivative, LDGSecondDerivative, \
                StabilizedCentralSecondDerivative
        from hedge.mesh import TAG_NONE, TAG_ALL
        op = PoissonOperator(discr.dimensions, 
                diffusion_tensor=my_diff_tensor(),

                #dirichlet_tag="dirichlet",
                #neumann_tag="neumann", 

                dirichlet_tag=TAG_ALL,
                neumann_tag=TAG_NONE, 

                #dirichlet_tag=TAG_ALL,
                #neumann_tag=TAG_NONE, 

                dirichlet_bc=GivenFunction(dirichlet_bc),
                neumann_bc=ConstantGivenFunction(-10),

                scheme=StabilizedCentralSecondDerivative(),
                #scheme=LDGSecondDerivative(),
                #scheme=IPDGSecondDerivative(),
                )
        bound_op = op.bind(discr)

        from hedge.iterative import parallel_cg
        u = -parallel_cg(rcon, -bound_op, 
                bound_op.prepare_rhs(discr.interpolate_volume_function(rhs_c)), 
                debug=20, tol=5e-4,
                dot=discr.nodewise_dot_product,
                x=discr.volume_zeros())

        if write_output:
            from hedge.visualization import SiloVisualizer, VtkVisualizer
            vis = VtkVisualizer(discr, rcon)
            visf = vis.make_file("fld")
            vis.add_data(visf, [ ("sol", discr.convert_volume(u, kind="numpy")), ])
            visf.close()
    finally:
        discr.close()
Beispiel #11
0
def main(write_output=True):
    from math import sin, cos, pi, exp, sqrt
    from hedge.data import TimeConstantGivenFunction, \
            ConstantGivenFunction

    from hedge.backends import guess_run_context
    rcon = guess_run_context()

    dim = 2

    def boundary_tagger(fvi, el, fn, all_v):
        if el.face_normals[fn][0] > 0:
            return ["dirichlet"]
        else:
            return ["neumann"]

    if dim == 2:
        if rcon.is_head_rank:
            from hedge.mesh.generator import make_disk_mesh
            mesh = make_disk_mesh(r=0.5, boundary_tagger=boundary_tagger)
    elif dim == 3:
        if rcon.is_head_rank:
            from hedge.mesh.generator import make_ball_mesh
            mesh = make_ball_mesh(max_volume=0.001)
    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=3,
                                     debug=["cuda_no_plan"],
                                     default_scalar_type=numpy.float64)

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

    def u0(x, el):
        if la.norm(x) < 0.2:
            return 1
        else:
            return 0

    def coeff(x, el):
        if x[0] < 0:
            return 0.25
        else:
            return 1

    def dirichlet_bc(t, x):
        return 0

    def neumann_bc(t, x):
        return 2

    from hedge.models.diffusion import DiffusionOperator
    op = DiffusionOperator(
        discr.dimensions,
        #coeff=coeff,
        dirichlet_tag="dirichlet",
        dirichlet_bc=TimeConstantGivenFunction(ConstantGivenFunction(0)),
        neumann_tag="neumann",
        neumann_bc=TimeConstantGivenFunction(ConstantGivenFunction(1)))
    u = discr.interpolate_volume_function(u0)

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

    if write_output:
        log_file_name = "heat.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, 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 -----------------------------------------------------------
    from hedge.timestep.runge_kutta import LSRK4TimeStepper, ODE45TimeStepper
    from hedge.timestep.dumka3 import Dumka3TimeStepper
    #stepper = LSRK4TimeStepper()
    stepper = Dumka3TimeStepper(
        3,
        rtol=1e-6,
        rcon=rcon,
        vector_primitive_factory=discr.get_vector_primitive_factory(),
        dtype=discr.default_scalar_type)
    #stepper = ODE45TimeStepper(rtol=1e-6, rcon=rcon,
    #vector_primitive_factory=discr.get_vector_primitive_factory(),
    #dtype=discr.default_scalar_type)
    stepper.add_instrumentation(logmgr)

    rhs = op.bind(discr)
    try:
        next_dt = op.estimate_timestep(discr,
                                       stepper=LSRK4TimeStepper(),
                                       t=0,
                                       fields=u)

        from hedge.timestep import times_and_steps
        step_it = times_and_steps(final_time=0.1,
                                  logmgr=logmgr,
                                  max_dt_getter=lambda t: next_dt,
                                  taken_dt_getter=lambda: taken_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", discr.convert_volume(u, kind="numpy")),
                ],
                             time=t,
                             step=step)
                visf.close()

            u, t, taken_dt, next_dt = stepper(u, t, next_dt, rhs)
            #u = stepper(u, t, dt, rhs)

        assert discr.norm(u) < 1
    finally:
        if write_output:
            vis.close()

        logmgr.close()
        discr.close()
def test_convergence_advec_2d():
    """Test whether 2D advection actually converges"""

    import pyublas
    from hedge.mesh.generator import make_disk_mesh, make_regular_rect_mesh
    from hedge.discretization.local import TriangleDiscretization
    from hedge.timestep import RK4TimeStepper
    from hedge.tools import EOCRecorder
    from math import sin, pi, sqrt
    from hedge.models.advection import StrongAdvectionOperator
    from hedge.data import TimeDependentGivenFunction

    v = numpy.array([0.27, 0])
    norm_a = la.norm(v)

    from numpy import dot

    def f(x):
        return sin(x)

    def u_analytic(x, el, t):
        return f((-dot(v, x) / norm_a + t * norm_a))

    def boundary_tagger(vertices, el, face_nr, all_v):
        if dot(el.face_normals[face_nr], v) < 0:
            return ["inflow"]
        else:
            return ["outflow"]

    for mesh in [
        # non-periodic
        make_disk_mesh(r=pi, boundary_tagger=boundary_tagger, max_area=0.5),
        # periodic
        make_regular_rect_mesh(
            a=(0, 0), b=(2 * pi, 1), n=(8, 4), periodicity=(True, False), boundary_tagger=boundary_tagger
        ),
    ]:
        for flux_type in StrongAdvectionOperator.flux_types:
            eoc_rec = EOCRecorder()

            for order in [1, 2, 3, 4, 5, 6]:
                discr = discr_class(mesh, TriangleDiscretization(order), debug=discr_class.noninteractive_debug_flags())
                op = StrongAdvectionOperator(v, inflow_u=TimeDependentGivenFunction(u_analytic), flux_type=flux_type)

                u = discr.interpolate_volume_function(lambda x, el: u_analytic(x, el, 0))

                stepper = RK4TimeStepper()
                dt = op.estimate_timestep(discr, stepper=stepper)
                nsteps = int(1 / dt)
                rhs = op.bind(discr)
                for step in range(nsteps):
                    u = stepper(u, step * dt, dt, rhs)

                u_true = discr.interpolate_volume_function(lambda x, el: u_analytic(x, el, nsteps * dt))
                error = u - u_true
                error_l2 = discr.norm(error)
                eoc_rec.add_data_point(order, error_l2)

            if False:
                print "%s\n%s\n" % (flux_type.upper(), "-" * len(flux_type))
                print eoc_rec.pretty_print(abscissa_label="Poly. Order", error_label="L2 Error")

            assert eoc_rec.estimate_order_of_convergence()[0, 1] > 4
            assert eoc_rec.estimate_order_of_convergence(2)[-1, 1] > 10
def test_2d_gauss_theorem():
    """Verify Gauss's theorem explicitly on a mesh"""

    from hedge.mesh.generator import make_disk_mesh
    from math import sin, cos, sqrt, exp, pi
    from numpy import dot

    mesh = make_disk_mesh()
    order = 2

    discr = discr_class(mesh, order=order, debug=discr_class.noninteractive_debug_flags())
    ref_discr = discr_class(mesh, order=order)

    from hedge.flux import make_normal, FluxScalarPlaceholder

    normal = make_normal(discr.dimensions)
    flux_f_ph = FluxScalarPlaceholder(0)
    one_sided_x = flux_f_ph.int * normal[0]
    one_sided_y = flux_f_ph.int * normal[1]

    def f1(x, el):
        return sin(3 * x[0]) + cos(3 * x[1])

    def f2(x, el):
        return sin(2 * x[0]) + cos(x[1])

    from hedge.discretization import ones_on_volume

    ones = ones_on_volume(discr)
    f1_v = discr.interpolate_volume_function(f1)
    f2_v = discr.interpolate_volume_function(f2)

    from hedge.optemplate import BoundaryPair, Field, make_nabla, get_flux_operator

    nabla = make_nabla(discr.dimensions)
    diff_optp = nabla[0] * Field("f1") + nabla[1] * Field("f2")

    divergence = nabla[0].apply(discr, f1_v) + nabla[1].apply(discr, f2_v)
    int_div = discr.integral(divergence)

    flux_optp = get_flux_operator(one_sided_x)(BoundaryPair(Field("f1"), Field("fz"))) + get_flux_operator(one_sided_y)(
        BoundaryPair(Field("f2"), Field("fz"))
    )

    from hedge.mesh import TAG_ALL

    bdry_val = discr.compile(flux_optp)(f1=f1_v, f2=f2_v, fz=discr.boundary_zeros(TAG_ALL))
    ref_bdry_val = ref_discr.compile(flux_optp)(f1=f1_v, f2=f2_v, fz=discr.boundary_zeros(TAG_ALL))

    boundary_int = dot(bdry_val, ones)

    if False:
        from hedge.visualization import SiloVisualizer

        vis = SiloVisualizer(discr)
        visf = vis.make_file("test")

        from hedge.tools import make_obj_array
        from hedge.mesh import TAG_ALL

        vis.add_data(
            visf,
            [
                ("bdry", bdry_val),
                ("ref_bdry", ref_bdry_val),
                ("div", divergence),
                ("f", make_obj_array([f1_v, f2_v])),
                ("n", discr.volumize_boundary_field(discr.boundary_normals(TAG_ALL), TAG_ALL)),
            ],
            expressions=[("bdiff", "bdry-ref_bdry")],
        )

        # print abs(boundary_int-int_div)

    assert abs(boundary_int - int_div) < 5e-15
Beispiel #14
0
def main(write_output=True):
    from hedge.data import GivenFunction, ConstantGivenFunction

    from hedge.backends import guess_run_context
    rcon = guess_run_context()

    dim = 2

    def boundary_tagger(fvi, el, fn, points):
        from math import atan2, pi
        normal = el.face_normals[fn]
        if -90 / 180 * pi < atan2(normal[1], normal[0]) < 90 / 180 * pi:
            return ["neumann"]
        else:
            return ["dirichlet"]

    if dim == 2:
        if rcon.is_head_rank:
            from hedge.mesh.generator import make_disk_mesh
            mesh = make_disk_mesh(r=0.5,
                                  boundary_tagger=boundary_tagger,
                                  max_area=1e-2)
    elif dim == 3:
        if rcon.is_head_rank:
            from hedge.mesh.generator import make_ball_mesh
            mesh = make_ball_mesh(
                max_volume=0.0001,
                boundary_tagger=lambda fvi, el, fn, points: ["dirichlet"])
    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=5, debug=[])

    def dirichlet_bc(x, el):
        from math import sin
        return sin(10 * x[0])

    def rhs_c(x, el):
        if la.norm(x) < 0.1:
            return 1000
        else:
            return 0

    def my_diff_tensor():
        result = numpy.eye(dim)
        result[0, 0] = 0.1
        return result

    try:
        from hedge.models.poisson import PoissonOperator
        from hedge.second_order import \
                IPDGSecondDerivative, LDGSecondDerivative, \
                StabilizedCentralSecondDerivative
        from hedge.mesh import TAG_NONE, TAG_ALL
        op = PoissonOperator(
            discr.dimensions,
            diffusion_tensor=my_diff_tensor(),

            #dirichlet_tag="dirichlet",
            #neumann_tag="neumann",
            dirichlet_tag=TAG_ALL,
            neumann_tag=TAG_NONE,

            #dirichlet_tag=TAG_ALL,
            #neumann_tag=TAG_NONE,
            dirichlet_bc=GivenFunction(dirichlet_bc),
            neumann_bc=ConstantGivenFunction(-10),
            scheme=StabilizedCentralSecondDerivative(),
            #scheme=LDGSecondDerivative(),
            #scheme=IPDGSecondDerivative(),
        )
        bound_op = op.bind(discr)

        from hedge.iterative import parallel_cg
        u = -parallel_cg(rcon,
                         -bound_op,
                         bound_op.prepare_rhs(
                             discr.interpolate_volume_function(rhs_c)),
                         debug=20,
                         tol=5e-4,
                         dot=discr.nodewise_dot_product,
                         x=discr.volume_zeros())

        if write_output:
            from hedge.visualization import SiloVisualizer, VtkVisualizer
            vis = VtkVisualizer(discr, rcon)
            visf = vis.make_file("fld")
            vis.add_data(visf, [
                ("sol", discr.convert_volume(u, kind="numpy")),
            ])
            visf.close()
    finally:
        discr.close()
def test_2d_gauss_theorem():
    """Verify Gauss's theorem explicitly on a mesh"""

    from hedge.mesh.generator import make_disk_mesh
    from math import sin, cos
    from numpy import dot

    mesh = make_disk_mesh()
    order = 2

    discr = discr_class(mesh,
                        order=order,
                        debug=discr_class.noninteractive_debug_flags())
    ref_discr = discr_class(mesh, order=order)

    from hedge.flux import make_normal, FluxScalarPlaceholder

    normal = make_normal(discr.dimensions)
    flux_f_ph = FluxScalarPlaceholder(0)
    one_sided_x = flux_f_ph.int * normal[0]
    one_sided_y = flux_f_ph.int * normal[1]

    def f1(x, el):
        return sin(3 * x[0]) + cos(3 * x[1])

    def f2(x, el):
        return sin(2 * x[0]) + cos(x[1])

    from hedge.discretization import ones_on_volume
    ones = ones_on_volume(discr)
    f1_v = discr.interpolate_volume_function(f1)
    f2_v = discr.interpolate_volume_function(f2)

    from hedge.optemplate import BoundaryPair, Field, make_nabla, \
            get_flux_operator
    nabla = make_nabla(discr.dimensions)

    divergence = nabla[0].apply(discr, f1_v) + nabla[1].apply(discr, f2_v)
    int_div = discr.integral(divergence)

    flux_optp = (
        get_flux_operator(one_sided_x)(BoundaryPair(Field("f1"),
                                                    Field("fz"))) +
        get_flux_operator(one_sided_y)(BoundaryPair(Field("f2"), Field("fz"))))

    from hedge.mesh import TAG_ALL
    bdry_val = discr.compile(flux_optp)(f1=f1_v,
                                        f2=f2_v,
                                        fz=discr.boundary_zeros(TAG_ALL))
    ref_bdry_val = ref_discr.compile(flux_optp)(
        f1=f1_v, f2=f2_v, fz=discr.boundary_zeros(TAG_ALL))

    boundary_int = dot(bdry_val, ones)

    if False:
        from hedge.visualization import SiloVisualizer
        vis = SiloVisualizer(discr)
        visf = vis.make_file("test")

        from hedge.tools import make_obj_array
        from hedge.mesh import TAG_ALL
        vis.add_data(visf, [
            ("bdry", bdry_val),
            ("ref_bdry", ref_bdry_val),
            ("div", divergence),
            ("f", make_obj_array([f1_v, f2_v])),
            ("n",
             discr.volumize_boundary_field(discr.boundary_normals(TAG_ALL),
                                           TAG_ALL)),
        ],
                     expressions=[("bdiff", "bdry-ref_bdry")])

        #print abs(boundary_int-int_div)

    assert abs(boundary_int - int_div) < 5e-15
def test_elliptic():
    """Test various properties of elliptic operators."""

    from hedge.tools import unit_vector

    def matrix_rep(op):
        h, w = op.shape
        mat = numpy.zeros(op.shape)
        for j in range(w):
            mat[:, j] = op(unit_vector(w, j))
        return mat

    def check_grad_mat():
        import pyublas

        if not pyublas.has_sparse_wrappers():
            return

        grad_mat = op.grad_matrix()

        # print len(discr), grad_mat.nnz, type(grad_mat)
        for i in range(10):
            u = numpy.random.randn(len(discr))

            mat_result = grad_mat * u
            op_result = numpy.hstack(op.grad(u))

            err = la.norm(mat_result - op_result) * la.norm(op_result)
            assert la.norm(mat_result - op_result) * la.norm(op_result) < 1e-5

    def check_matrix_tgt():
        big = num.zeros((20, 20), flavor=num.SparseBuildMatrix)
        small = num.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
        print small
        from hedge._internal import MatrixTarget

        tgt = MatrixTarget(big, 4, 4)
        tgt.begin(small.shape[0], small.shape[1])
        print "YO"
        tgt.add_coefficients(4, 4, small)
        print "DUDE"
        tgt.finalize()
        print big

    import pymbolic

    v_x = pymbolic.var("x")
    truesol = pymbolic.parse("math.sin(x[0]**2*x[1]**2)")
    truesol_c = pymbolic.compile(truesol, variables=["x"])
    rhs = pymbolic.simplify(pymbolic.laplace(truesol, [v_x[0], v_x[1]]))
    rhs_c = pymbolic.compile(rhs, variables=["x", "el"])

    from hedge.mesh import TAG_ALL, TAG_NONE
    from hedge.mesh.generator import make_disk_mesh

    mesh = make_disk_mesh(r=0.5, max_area=0.1, faces=20)
    mesh = mesh.reordered_by("cuthill")

    from hedge.backends import CPURunContext

    rcon = CPURunContext()

    from hedge.tools import EOCRecorder

    eocrec = EOCRecorder()
    for order in [1, 2, 3, 4, 5]:
        for flux in ["ldg", "ip"]:
            from hedge.discretization.local import TriangleDiscretization

            discr = rcon.make_discretization(
                mesh, TriangleDiscretization(order), debug=discr_class.noninteractive_debug_flags()
            )

            from hedge.data import GivenFunction
            from hedge.models.poisson import PoissonOperator

            op = PoissonOperator(
                discr.dimensions,
                dirichlet_tag=TAG_ALL,
                dirichlet_bc=GivenFunction(lambda x, el: truesol_c(x)),
                neumann_tag=TAG_NONE,
            )

            bound_op = op.bind(discr)

            if order <= 3:
                mat = matrix_rep(bound_op)
                sym_err = la.norm(mat - mat.T)
                # print sym_err
                assert sym_err < 1e-12
                # check_grad_mat()

            from hedge.iterative import parallel_cg

            truesol_v = discr.interpolate_volume_function(lambda x, el: truesol_c(x))
            sol_v = -parallel_cg(
                rcon,
                -bound_op,
                bound_op.prepare_rhs(discr.interpolate_volume_function(rhs_c)),
                tol=1e-10,
                max_iterations=40000,
            )

            eocrec.add_data_point(order, discr.norm(sol_v - truesol_v))

    # print eocrec.pretty_print()
    assert eocrec.estimate_order_of_convergence()[0, 1] > 8
def test_convergence_advec_2d():
    """Test whether 2D advection actually converges"""

    import pyublas  # noqa
    from hedge.mesh.generator import make_disk_mesh, make_regular_rect_mesh
    from hedge.discretization.local import TriangleDiscretization
    from hedge.timestep import RK4TimeStepper
    from hedge.tools import EOCRecorder
    from math import sin, pi
    from hedge.models.advection import StrongAdvectionOperator
    from hedge.data import TimeDependentGivenFunction

    v = numpy.array([0.27, 0])
    norm_a = la.norm(v)

    from numpy import dot

    def f(x):
        return sin(x)

    def u_analytic(x, el, t):
        return f((-dot(v, x) / norm_a + t * norm_a))

    def boundary_tagger(vertices, el, face_nr, all_v):
        if dot(el.face_normals[face_nr], v) < 0:
            return ["inflow"]
        else:
            return ["outflow"]

    for mesh in [
            # non-periodic
            make_disk_mesh(r=pi, boundary_tagger=boundary_tagger,
                           max_area=0.5),
            # periodic
            make_regular_rect_mesh(
                a=(0, 0),
                b=(2 * pi, 1),
                n=(8, 4),
                periodicity=(True, False),
                boundary_tagger=boundary_tagger,
            )
    ]:
        for flux_type in StrongAdvectionOperator.flux_types:
            eoc_rec = EOCRecorder()

            for order in [1, 2, 3, 4, 5, 6]:
                discr = discr_class(
                    mesh,
                    TriangleDiscretization(order),
                    debug=discr_class.noninteractive_debug_flags())
                op = StrongAdvectionOperator(
                    v,
                    inflow_u=TimeDependentGivenFunction(u_analytic),
                    flux_type=flux_type)

                u = discr.interpolate_volume_function(
                    lambda x, el: u_analytic(x, el, 0))

                stepper = RK4TimeStepper()
                dt = op.estimate_timestep(discr, stepper=stepper)
                nsteps = int(1 / dt)
                rhs = op.bind(discr)
                for step in range(nsteps):
                    u = stepper(u, step * dt, dt, rhs)

                u_true = discr.interpolate_volume_function(
                    lambda x, el: u_analytic(x, el, nsteps * dt))
                error = u - u_true
                error_l2 = discr.norm(error)
                eoc_rec.add_data_point(order, error_l2)

            if False:
                print "%s\n%s\n" % (flux_type.upper(), "-" * len(flux_type))
                print eoc_rec.pretty_print(abscissa_label="Poly. Order",
                                           error_label="L2 Error")

            assert eoc_rec.estimate_order_of_convergence()[0, 1] > 4
            assert eoc_rec.estimate_order_of_convergence(2)[-1, 1] > 10
Beispiel #18
0
def main(write_output=True) :
    from math import sin, cos, pi, exp, sqrt
    from hedge.data import TimeConstantGivenFunction, \
            ConstantGivenFunction

    from hedge.backends import guess_run_context
    rcon = guess_run_context()

    dim = 2

    def boundary_tagger(fvi, el, fn, all_v):
        if el.face_normals[fn][0] > 0:
            return ["dirichlet"]
        else:
            return ["neumann"]

    if dim == 2:
        if rcon.is_head_rank:
            from hedge.mesh.generator import make_disk_mesh
            mesh = make_disk_mesh(r=0.5, boundary_tagger=boundary_tagger)
    elif dim == 3:
        if rcon.is_head_rank:
            from hedge.mesh.generator import make_ball_mesh
            mesh = make_ball_mesh(max_volume=0.001)
    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=3,
            debug=["cuda_no_plan"],
            default_scalar_type=numpy.float64)

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

    def u0(x, el):
        if la.norm(x) < 0.2:
            return 1
        else:
            return 0

    def coeff(x, el):
        if x[0] < 0:
            return 0.25
        else:
            return 1

    def dirichlet_bc(t, x):
        return 0

    def neumann_bc(t, x):
        return 2

    from hedge.models.diffusion import DiffusionOperator
    op = DiffusionOperator(discr.dimensions,
            #coeff=coeff,
            dirichlet_tag="dirichlet",
            dirichlet_bc=TimeConstantGivenFunction(ConstantGivenFunction(0)),
            neumann_tag="neumann",
            neumann_bc=TimeConstantGivenFunction(ConstantGivenFunction(1))
            )
    u = discr.interpolate_volume_function(u0)

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

    if write_output:
        log_file_name = "heat.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, 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 -----------------------------------------------------------
    from hedge.timestep.runge_kutta import LSRK4TimeStepper, ODE45TimeStepper
    from hedge.timestep.dumka3 import Dumka3TimeStepper
    #stepper = LSRK4TimeStepper()
    stepper = Dumka3TimeStepper(3, rtol=1e-6, rcon=rcon,
            vector_primitive_factory=discr.get_vector_primitive_factory(),
            dtype=discr.default_scalar_type)
    #stepper = ODE45TimeStepper(rtol=1e-6, rcon=rcon,
            #vector_primitive_factory=discr.get_vector_primitive_factory(),
            #dtype=discr.default_scalar_type)
    stepper.add_instrumentation(logmgr)

    rhs = op.bind(discr)
    try:
        next_dt = op.estimate_timestep(discr,
                stepper=LSRK4TimeStepper(), t=0, fields=u)

        from hedge.timestep import times_and_steps
        step_it = times_and_steps(
                final_time=0.1, logmgr=logmgr,
                max_dt_getter=lambda t: next_dt,
                taken_dt_getter=lambda: taken_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", discr.convert_volume(u, kind="numpy")), 
                    ], time=t, step=step)
                visf.close()

            u, t, taken_dt, next_dt = stepper(u, t, next_dt, rhs)
            #u = stepper(u, t, dt, rhs)

        assert discr.norm(u) < 1
    finally:
        if write_output:
            vis.close()

        logmgr.close()
        discr.close()
Beispiel #19
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()
def test_elliptic():
    """Test various properties of elliptic operators."""

    from hedge.tools import unit_vector

    def matrix_rep(op):
        h, w = op.shape
        mat = numpy.zeros(op.shape)
        for j in range(w):
            mat[:, j] = op(unit_vector(w, j))
        return mat

    def check_grad_mat():
        import pyublas
        if not pyublas.has_sparse_wrappers():
            return

        grad_mat = op.grad_matrix()

        #print len(discr), grad_mat.nnz, type(grad_mat)
        for i in range(10):
            u = numpy.random.randn(len(discr))

            mat_result = grad_mat * u
            op_result = numpy.hstack(op.grad(u))

            err = la.norm(mat_result - op_result) * la.norm(op_result)
            assert err < 1e-5

    def check_matrix_tgt():
        big = numpy.zeros((20, 20), flavor=numpy.SparseBuildMatrix)
        small = numpy.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
        print small
        from hedge._internal import MatrixTarget
        tgt = MatrixTarget(big, 4, 4)
        tgt.begin(small.shape[0], small.shape[1])
        print "YO"
        tgt.add_coefficients(4, 4, small)
        print "DUDE"
        tgt.finalize()
        print big

    import pymbolic
    v_x = pymbolic.var("x")
    truesol = pymbolic.parse("math.sin(x[0]**2*x[1]**2)")
    truesol_c = pymbolic.compile(truesol, variables=["x"])

    def laplace(expression, variables):
        return sum(
            pymbolic.diff(pymbolic.diff(expression, var), var)
            for var in variables)

    rhs = laplace(truesol, [v_x[0], v_x[1]])
    rhs_c = pymbolic.compile(rhs, variables=["x", "el"])

    from hedge.mesh import TAG_ALL, TAG_NONE
    from hedge.mesh.generator import make_disk_mesh
    mesh = make_disk_mesh(r=0.5, max_area=0.1, faces=20)
    mesh = mesh.reordered_by("cuthill")

    from hedge.backends import CPURunContext
    rcon = CPURunContext()

    from hedge.tools import EOCRecorder
    eocrec = EOCRecorder()
    for order in [1, 2, 3, 4, 5]:
        for flux in ["ldg", "ip"]:
            from hedge.discretization.local import TriangleDiscretization
            discr = rcon.make_discretization(
                mesh,
                TriangleDiscretization(order),
                debug=discr_class.noninteractive_debug_flags())

            from hedge.data import GivenFunction
            from hedge.models.poisson import PoissonOperator
            op = PoissonOperator(
                discr.dimensions,
                dirichlet_tag=TAG_ALL,
                dirichlet_bc=GivenFunction(lambda x, el: truesol_c(x)),
                neumann_tag=TAG_NONE)

            bound_op = op.bind(discr)

            if order <= 3:
                mat = matrix_rep(bound_op)
                sym_err = la.norm(mat - mat.T)
                #print sym_err
                assert sym_err < 1e-12
                #check_grad_mat()

            from hedge.iterative import parallel_cg
            truesol_v = discr.interpolate_volume_function(
                lambda x, el: truesol_c(x))
            sol_v = -parallel_cg(rcon,
                                 -bound_op,
                                 bound_op.prepare_rhs(
                                     discr.interpolate_volume_function(rhs_c)),
                                 tol=1e-10,
                                 max_iterations=40000)

            eocrec.add_data_point(order, discr.norm(sol_v - truesol_v))

    #print eocrec.pretty_print()
    assert eocrec.estimate_order_of_convergence()[0, 1] > 8
Beispiel #21
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 #22
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()