Exemplo n.º 1
0
def test_quadrature_tri_mass_mat_monomial():
    """Check that quadrature integration on triangles is exact as designed."""

    from hedge.mesh.generator import make_square_mesh

    mesh = make_square_mesh(a=-1, b=1, max_area=4 * 1 / 8 + 0.001)
    order = 4
    discr = discr_class(
        mesh, order=order, debug=discr_class.noninteractive_debug_flags(), quad_min_degrees={"quad": 3 * order}
    )

    m, n = 2, 1
    f = Monomial((m, n))
    f_vec = discr.interpolate_volume_function(lambda x, el: f(x))

    from hedge.discretization import ones_on_volume

    ones = ones_on_volume(discr)

    if False:
        from hedge.visualization import SiloVisualizer

        vis = SiloVisualizer(discr)
        visf = vis.make_file("test")
        vis.add_data(visf, [("f", f_vec * f_vec)])
        visf.close()

    from hedge.optemplate import MassOperator, Field, QuadratureGridUpsampler

    f_fld = Field("f")
    mass_op = discr.compile(MassOperator()(f_fld * f_fld))
    from hedge.optemplate.primitives import make_common_subexpression as cse

    f_upsamp = cse(QuadratureGridUpsampler("quad")(f_fld))
    quad_mass_op = discr.compile(MassOperator()(f_upsamp * f_upsamp))

    num_integral_1 = numpy.dot(ones, mass_op(f=f_vec))
    num_integral_2 = numpy.dot(ones, quad_mass_op(f=f_vec))
    true_integral = 4 / ((2 * m + 1) * (2 * n + 1))
    err_1 = abs(num_integral_1 - true_integral)
    err_2 = abs(num_integral_2 - true_integral)
    print num_integral_1, num_integral_2, true_integral
    print err_1, err_2
    assert err_1 > 1e-8
    assert err_2 < 1e-14
def test_quadrature_tri_mass_mat_monomial():
    """Check that quadrature integration on triangles is exact as designed."""

    from hedge.mesh.generator import make_square_mesh

    mesh = make_square_mesh(a=-1, b=1, max_area=4 * 1 / 8 + 0.001)
    order = 4
    discr = discr_class(mesh,
                        order=order,
                        debug=discr_class.noninteractive_debug_flags(),
                        quad_min_degrees={"quad": 3 * order})

    m, n = 2, 1
    f = Monomial((m, n))
    f_vec = discr.interpolate_volume_function(lambda x, el: f(x))

    from hedge.discretization import ones_on_volume
    ones = ones_on_volume(discr)

    if False:
        from hedge.visualization import SiloVisualizer
        vis = SiloVisualizer(discr)
        visf = vis.make_file("test")
        vis.add_data(visf, [("f", f_vec * f_vec)])
        visf.close()

    from hedge.optemplate import (MassOperator, Field, QuadratureGridUpsampler)
    f_fld = Field("f")
    mass_op = discr.compile(MassOperator()(f_fld * f_fld))
    from hedge.optemplate.primitives import make_common_subexpression as cse
    f_upsamp = cse(QuadratureGridUpsampler("quad")(f_fld))
    quad_mass_op = discr.compile(MassOperator()(f_upsamp * f_upsamp))

    num_integral_1 = numpy.dot(ones, mass_op(f=f_vec))
    num_integral_2 = numpy.dot(ones, quad_mass_op(f=f_vec))
    true_integral = 4 / ((2 * m + 1) * (2 * n + 1))
    err_1 = abs(num_integral_1 - true_integral)
    err_2 = abs(num_integral_2 - true_integral)
    print num_integral_1, num_integral_2, true_integral
    print err_1, err_2
    assert err_1 > 1e-8
    assert err_2 < 1e-14
Exemplo n.º 3
0
def run_convergence_test_advec(dtype,
                               flux_type,
                               random_partition,
                               mesh_gen,
                               debug_output=False):
    """Test whether 2/3D advection actually converges"""

    from hedge.timestep import RK4TimeStepper
    from hedge.tools import EOCRecorder
    from math import sin
    from hedge.data import TimeDependentGivenFunction
    from hedge.visualization import SiloVisualizer

    from hedge.backends import guess_run_context
    rcon = guess_run_context(["mpi"])

    # note: x component must remain zero because x-periodicity is used
    v = np.array([0.0, 0.9, 0.3])

    def f(x):
        return sin(x)

    def u_analytic(x, el, t):
        return f(
            (np.dot(-v[:dims], x) / la.norm(v[:dims]) + t * la.norm(v[:dims])))

    def boundary_tagger(vertices, el, face_nr, points):
        face_normal = el.face_normals[face_nr]
        if np.dot(face_normal, v[:len(face_normal)]) < 0:
            return ["inflow"]
        else:
            return ["outflow"]

    mesh = mesh_gen(boundary_tagger)
    eoc_rec = EOCRecorder()

    if random_partition:
        # Distribute elements randomly across nodes.
        # This is bad, efficiency-wise, but it puts stress
        # on the parallel implementation, which is desired here.
        # Another main point of this is to force the code to split
        # a periodic face pair across nodes.
        from random import choice
        partition = [choice(rcon.ranks) for el in mesh.elements]
    else:
        partition = None

    for order in [1, 2, 3, 4]:
        if rcon.is_head_rank:
            mesh_data = rcon.distribute_mesh(mesh, partition)
        else:
            mesh_data = rcon.receive_mesh()

        dims = mesh.points.shape[1]

        discr = rcon.make_discretization(mesh_data,
                                         order=order,
                                         default_scalar_type=dtype)

        op = StrongAdvectionOperator(
            v[:dims],
            inflow_u=TimeDependentGivenFunction(u_analytic),
            flux_type=flux_type)
        if debug_output:
            vis = SiloVisualizer(discr, rcon)

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

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

        test_name = "test-%s-o%d-m%s-r%s" % (
            flux_type, order, mesh_gen.__name__, random_partition)

        rhs = op.bind(discr)

        stepper = RK4TimeStepper(dtype=dtype)
        from hedge.timestep import times_and_steps
        final_time = 1
        step_it = times_and_steps(final_time=final_time,
                                  max_dt_getter=lambda t: op.estimate_timestep(
                                      discr, stepper=stepper, t=t, fields=u))

        for step, t, dt in step_it:
            u = stepper(u, t, dt, rhs)

        assert u.dtype == dtype

        u_true = discr.interpolate_volume_function(
            lambda x, el: u_analytic(x, el, final_time))
        error = u - u_true
        l2_error = discr.norm(error)

        if debug_output:
            visf = vis.make_file(test_name + "-final")
            vis.add_data(visf, [("u", u), ("u_true", u_true), ("ic", ic)])
            visf.close()

        eoc_rec.add_data_point(order, l2_error)

    if debug_output and rcon.is_head_rank:
        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] > 3
    assert eoc_rec.estimate_order_of_convergence(2)[-1, 1] > 7
Exemplo n.º 4
0
def main():
    from hedge.backends import guess_run_context
    rcon = guess_run_context(
        #["cuda"]
    )

    from hedge.tools import EOCRecorder, to_obj_array
    eoc_rec = EOCRecorder()

    def boundary_tagger(vertices, el, face_nr, all_v):
        return ["inflow"]

    if rcon.is_head_rank:
        from hedge.mesh import make_rect_mesh, \
                               make_centered_regular_rect_mesh
        #mesh = make_rect_mesh((0,0), (10,1), max_area=0.01)
        refine = 1
        mesh = make_centered_regular_rect_mesh(
            (0, 0),
            (10, 1),
            n=(20, 4),
            #periodicity=(True, False),
            post_refine_factor=refine,
            boundary_tagger=boundary_tagger)
        mesh_data = rcon.distribute_mesh(mesh)
    else:
        mesh_data = rcon.receive_mesh()

    for order in [3]:
        discr = rcon.make_discretization(mesh_data,
                                         order=order,
                                         default_scalar_type=numpy.float64)

        from hedge.visualization import SiloVisualizer, VtkVisualizer
        #vis = VtkVisualizer(discr, rcon, "shearflow-%d" % order)
        vis = SiloVisualizer(discr, rcon)

        shearflow = SteadyShearFlow()
        fields = shearflow.volume_interpolant(0, discr)
        gamma, mu, prandtl, spec_gas_const = shearflow.properties()

        from hedge.models.gas_dynamics import GasDynamicsOperator
        op = GasDynamicsOperator(dimensions=2,
                                 gamma=gamma,
                                 mu=mu,
                                 prandtl=prandtl,
                                 spec_gas_const=spec_gas_const,
                                 bc_inflow=shearflow,
                                 bc_outflow=shearflow,
                                 bc_noslip=shearflow,
                                 inflow_tag="inflow",
                                 outflow_tag="outflow",
                                 noslip_tag="noslip")

        navierstokes_ex = op.bind(discr)

        max_eigval = [0]

        def rhs(t, q):
            ode_rhs, speed = navierstokes_ex(t, q)
            max_eigval[0] = speed
            return ode_rhs

        # needed to get first estimate of maximum eigenvalue
        rhs(0, fields)

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

        from hedge.timestep import RK4TimeStepper
        stepper = RK4TimeStepper()

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

        logmgr = LogManager("navierstokes-cpu-%d-%d.dat" % (order, refine),
                            "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 -------------------------------------------------------
        try:
            from hedge.timestep import times_and_steps
            step_it = times_and_steps(
                final_time=0.3,
                #max_steps=500,
                logmgr=logmgr,
                max_dt_getter=lambda t: op.estimate_timestep(
                    discr, stepper=stepper, t=t, max_eigenvalue=max_eigval[0]))

            for step, t, dt in step_it:
                if step % 10 == 0:
                    #if False:
                    visf = vis.make_file("shearflow-%d-%04d" % (order, step))

                    #true_fields = shearflow.volume_interpolant(t, discr)

                    from pyvisfile.silo import DB_VARTYPE_VECTOR
                    vis.add_data(
                        visf,
                        [
                            ("rho",
                             discr.convert_volume(op.rho(fields),
                                                  kind="numpy")),
                            ("e",
                             discr.convert_volume(op.e(fields), kind="numpy")),
                            ("rho_u",
                             discr.convert_volume(op.rho_u(fields),
                                                  kind="numpy")),
                            ("u",
                             discr.convert_volume(op.u(fields), kind="numpy")),

                            #("true_rho", discr.convert_volume(op.rho(true_fields), kind="numpy")),
                            #("true_e", discr.convert_volume(op.e(true_fields), kind="numpy")),
                            #("true_rho_u", discr.convert_volume(op.rho_u(true_fields), kind="numpy")),
                            #("true_u", discr.convert_volume(op.u(true_fields), kind="numpy")),
                        ],
                        expressions=[
                            #("diff_rho", "rho-true_rho"),
                            #("diff_e", "e-true_e"),
                            #("diff_rho_u", "rho_u-true_rho_u", DB_VARTYPE_VECTOR),
                            ("p", "0.4*(e- 0.5*(rho_u*u))"),
                        ],
                        time=t,
                        step=step)
                    visf.close()

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

            true_fields = shearflow.volume_interpolant(t, discr)
            l2_error = discr.norm(op.u(fields) - op.u(true_fields))
            eoc_rec.add_data_point(order, l2_error)
            print
            print eoc_rec.pretty_print("P.Deg.", "L2 Error")

            logmgr.set_constant("l2_error", l2_error)

        finally:
            vis.close()
            logmgr.save()
            discr.close()
Exemplo n.º 5
0
def optimize_shape_bandwidth(method, state, analytic_rho, exponent):
    discr = method.discretization
    rec = method.depositor

    adv_radius = method.mesh_data.advisable_particle_radius()
    radii = [adv_radius * 2**i for i in numpy.linspace(-4, 2, 50)]

    def set_radius(r):
        method.depositor.set_shape_function(
            state,
            method.get_shape_function_class()(
                r,
                method.mesh_data.dimensions,
                exponent,
            ))

    tried_radii = []
    l1_errors = []

    debug = "shape_bw" in method.debug
    visualize = set(["shape_bw", "vis_files"]) <= method.debug

    if visualize:
        from hedge.visualization import SiloVisualizer
        vis = SiloVisualizer(discr)

    import sys

    if debug:
        sys.stdout.write("optimizing shape bw (%d attempts): " % len(radii))
    for step, radius in enumerate(radii):
        if debug:
            sys.stdout.write("%d." % step)
            sys.stdout.flush()

        try:
            try:
                method.set_ignore_core_warnings(True)
                set_radius(radius)
            except RuntimeError, re:
                if "particle mass is zero" in str(re):
                    continue
                else:
                    raise
        finally:
            method.set_ignore_core_warnings(False)

        state.derived_quantity_cache.clear()

        try:
            try:
                method.set_ignore_core_warnings(True)
                rec_rho = method.deposit_rho(state)
            except RuntimeError, re:
                if "particle mass is zero" in str(re):
                    continue
                else:
                    raise
        finally:
            method.set_ignore_core_warnings(False)

        tried_radii.append(radius)
        l1_errors.append(discr.integral(numpy.abs(rec_rho - analytic_rho)))

        if visualize:
            visf = vis.make_file("bwopt-%04d" % step)
            method.add_to_vis(vis, visf, state, time=radius, step=step)
            vis.add_data(
                visf,
                [
                    ("rho", rec_rho),
                    #("j", method.deposit_j(state)),
                    ("rho_analytic", analytic_rho),
                ],
                expressions=[("rho_diff", "rho-rho_analytic")],
                time=radius,
                step=step)

            try:
                rec.visualize_grid_quantities
            except AttributeError:
                pass
            else:
                rec.visualize_grid_quantities(visf, [
                    ("rho_grid", rec.deposit_grid_rho(state)),
                    ("j_grid",
                     rec.deposit_grid_j(state, method.velocities(state))),
                    ("rho_resid",
                     rec.remap_residual(rec.deposit_grid_rho(state))),
                ])

            visf.close()

    if debug:
        sys.stdout.write("\n")
        sys.stdout.flush()

    if visualize:
        vis.close()

    from pytools import argmin
    min_idx = argmin(l1_errors)
    min_rad = tried_radii[min_idx]
    min_l1_error = l1_errors[min_idx]

    rel_l1_error = abs(min_l1_error / discr.integral(analytic_rho))
    if rel_l1_error > 0.1:
        from warnings import warn
        warn("Charge density is very poorly resolved (rel L1 error=%g)" %
             rel_l1_error)

    def is_local_minimum(list, i):
        if i == 0:
            return False
        elif i == len(list) - 1:
            return False
        else:
            return list[i] < list[i - 1] and list[i] < list[i + 1]

    local_minima = [
        idx for idx in range(len(tried_radii))
        if is_local_minimum(l1_errors, idx)
    ]

    chosen_idx = max(local_minima)
    chosen_rad = tried_radii[chosen_idx]

    if "shape_bw" in method.debug:
        chosen_l1_error = l1_errors[chosen_idx]
        print "radius: guessed optimum=%g, found optimum=%g, chosen=%g" % (
            adv_radius, min_rad, chosen_rad)
        print "radius: optimum l1 error=%g, chosen l1 error=%g" % (
            min_l1_error, chosen_l1_error)

    set_radius(chosen_rad)
    state.derived_quantity_cache.clear()

    if set(["interactive", "shape_bw"]) < method.debug:
        from pylab import semilogx, show
        semilogx(tried_radii, l1_errors)
        show()
Exemplo n.º 6
0
def main():
    from hedge.backends import guess_run_context
    rcon = guess_run_context( ["cuda", "mpi"])

    if rcon.is_head_rank:
        mesh = make_wingmesh()
        #from hedge.mesh import make_rect_mesh
        #mesh = make_rect_mesh(
        #       boundary_tagger=lambda fvi, el, fn, all_v: ["inflow"])
        mesh_data = rcon.distribute_mesh(mesh)
    else:
        mesh_data = rcon.receive_mesh()

    for order in [3]:
        from pytools import add_python_path_relative_to_script
        add_python_path_relative_to_script("..")

        from gas_dynamics_initials import UniformMachFlow
        wing = UniformMachFlow(angle_of_attack=0)

        from hedge.models.gas_dynamics import GasDynamicsOperator
        op = GasDynamicsOperator(dimensions=3,
                gamma=wing.gamma, mu=wing.mu,
                prandtl=wing.prandtl, spec_gas_const=wing.spec_gas_const,
                bc_inflow=wing, bc_outflow=wing, bc_noslip=wing,
                inflow_tag="inflow", outflow_tag="outflow", noslip_tag="noslip")

        discr = rcon.make_discretization(mesh_data, order=order,
                        debug=["cuda_no_plan",
                            #"cuda_dump_kernels",
                            #"dump_dataflow_graph",
                            #"dump_optemplate_stages",
                            #"dump_dataflow_graph",
                            #"print_op_code"
                            "cuda_no_metis",
                            ],
                        default_scalar_type=numpy.float64,
                        tune_for=op.op_template())

        from hedge.visualization import SiloVisualizer, VtkVisualizer
        #vis = VtkVisualizer(discr, rcon, "shearflow-%d" % order)
        vis = SiloVisualizer(discr, rcon)

        fields = wing.volume_interpolant(0, discr)

        navierstokes_ex = op.bind(discr)

        max_eigval = [0]
        def rhs(t, q):
            ode_rhs, speed = navierstokes_ex(t, q)
            max_eigval[0] = speed
            return ode_rhs
        rhs(0, fields)

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

        from hedge.timestep import RK4TimeStepper
        stepper = RK4TimeStepper()

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

        logmgr = LogManager("navierstokes-%d.dat" % order, "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 -------------------------------------------------------
        try:
            from hedge.timestep import times_and_steps
            step_it = times_and_steps(
                    final_time=200,
                    #max_steps=500,
                    logmgr=logmgr,
                    max_dt_getter=lambda t: 0.6 * op.estimate_timestep(discr,
                        stepper=stepper, t=t, max_eigenvalue=max_eigval[0]))

            for step, t, dt in step_it:
                if step % 200 == 0:
                #if False:
                    visf = vis.make_file("wing-%d-%06d" % (order, step))

                    #rhs_fields = rhs(t, fields)

                    from pyvisfile.silo import DB_VARTYPE_VECTOR
                    from hedge.discretization import ones_on_boundary
                    vis.add_data(visf,
                            [
                                ("rho", discr.convert_volume(op.rho(fields), kind="numpy")),
                                ("e", discr.convert_volume(op.e(fields), kind="numpy")),
                                ("rho_u", discr.convert_volume(op.rho_u(fields), kind="numpy")),
                                ("u", discr.convert_volume(op.u(fields), kind="numpy")),

                                #("rhs_rho", discr.convert_volume(op.rho(rhs_fields), kind="numpy")),
                                #("rhs_e", discr.convert_volume(op.e(rhs_fields), kind="numpy")),
                                #("rhs_rho_u", discr.convert_volume(op.rho_u(rhs_fields), kind="numpy")),
                                ],
                            expressions=[
                                ("p", "(0.4)*(e- 0.5*(rho_u*u))"),
                                ],
                            time=t, step=step
                            )
                    visf.close()

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

        finally:
            vis.close()
            logmgr.save()
            discr.close()
def test_symmetry_preservation_2d():
    """Test whether we preserve symmetry in a symmetric 2D advection problem"""
    from numpy import dot

    def make_mesh():
        array = numpy.array

        #
        #    1---8---2
        #    |7 /|\ 1|
        #    | / | \ |
        #    |/ 6|0 \|
        #    5---4---7
        #    |\ 5|3 /|
        #    | \ | / |
        #    |4 \|/ 2|
        #    0---6---3
        #
        points = [
            array([-0.5, -0.5]),
            array([-0.5, 0.5]),
            array([0.5, 0.5]),
            array([0.5, -0.5]),
            array([0.0, 0.0]),
            array([-0.5, 0.0]),
            array([0.0, -0.5]),
            array([0.5, 0.0]),
            array([0.0, 0.5])
        ]

        elements = [
            [8, 7, 4],
            [8, 7, 2],
            [6, 7, 3],
            [7, 4, 6],
            [5, 6, 0],
            [5, 6, 4],
            [5, 8, 4],
            [1, 5, 8],
        ]

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

        from hedge.mesh import make_conformal_mesh
        return make_conformal_mesh(points, elements, boundary_tagger)

    from hedge.discretization import SymmetryMap
    from hedge.timestep import RK4TimeStepper
    from hedge.models.advection import StrongAdvectionOperator
    from hedge.data import TimeDependentGivenFunction

    v = numpy.array([-1, 0])

    mesh = make_mesh()
    discr = discr_class(mesh,
                        order=4,
                        debug=discr_class.noninteractive_debug_flags())

    #ref_discr = DynamicDiscretization(mesh, order=4)

    def f(x):
        if x < 0.5:
            return 0
        else:
            return (x - 0.5)

    #def f(x):
    #return sin(5*x)

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

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

    sym_map = SymmetryMap(discr, lambda x: numpy.array([x[0], -x[1]]), {
        0: 3,
        2: 1,
        5: 6,
        7: 4
    })

    for flux_type in StrongAdvectionOperator.flux_types:
        stepper = RK4TimeStepper()
        op = StrongAdvectionOperator(
            v,
            inflow_u=TimeDependentGivenFunction(u_analytic),
            flux_type=flux_type)

        dt = op.estimate_timestep(discr, stepper=stepper)
        nsteps = int(1 / dt)
        rhs = op.bind(discr)
        #test_comp = [ "bflux"]
        #test_rhs = op.bind(discr, test_comp)
        #ref_rhs = op.bind(ref_discr, test_comp)
        for step in xrange(nsteps):
            u = stepper(u, step * dt, dt, rhs)
            sym_error_u = u - sym_map(u)
            sym_error_u_l2 = discr.norm(sym_error_u)

            if False:
                from hedge.visualization import SiloVisualizer
                vis = SiloVisualizer(discr)
                visf = vis.make_file("test-%s-%04d" % (flux_type, step))
                vis.add_data(
                    visf,
                    [
                        ("u", u),
                        ("sym_u", sym_map(u)),
                        ("sym_diff", u - sym_map(u)),
                        ("rhs", rhs(step * dt, u)),
                        #("rhs_test", test_rhs(step*dt, u)),
                        #("rhs_ref", ref_rhs(step*dt, u)),
                        #("rhs_diff", test_rhs(step*dt, u)-ref_rhs(step*dt, u)),
                    ])

                print sym_error_u_l2
            assert sym_error_u_l2 < 4e-15
Exemplo n.º 8
0
def run_convergence_test_advec(dtype, debug_output=False):
    """Test whether 2/3D advection actually converges"""

    from hedge.mesh.generator import make_ball_mesh, make_box_mesh, make_rect_mesh
    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
    from hedge.visualization import SiloVisualizer

    from hedge.backends import guess_run_context
    rcon = guess_run_context(["mpi"])

    # note: x component must remain zero because x-periodicity is used
    v = numpy.array([0.0,0.9,0.3])

    def f(x):
        return sin(x)

    def u_analytic(x, el, t):
        return f((numpy.dot(-v[:dims],x)/la.norm(v[:dims])+t*la.norm(v[:dims])))

    def boundary_tagger(vertices, el, face_nr, points):
        face_normal = el.face_normals[face_nr]
        if numpy.dot(face_normal, v[:len(face_normal)]) < 0:
            return ["inflow"]
        else:
            return ["outflow"]

    for i_mesh, mesh in enumerate([
        # 2D semiperiodic
        make_rect_mesh(b=(2*pi,3), max_area=0.4,
            periodicity=(True, False),
            subdivisions=(5,10),
            boundary_tagger=boundary_tagger, 
            ),
        # 3D x-periodic
        make_box_mesh((0,0,0), (2*pi, 2, 2), max_volume=0.4,
            periodicity=(True, False, False),
            boundary_tagger=boundary_tagger, 
            ),
        # non-periodic
        make_ball_mesh(r=pi, 
            boundary_tagger=boundary_tagger, max_volume=0.7),
        ]):
        for flux_type in StrongAdvectionOperator.flux_types:
            for random_partition in [True, False]:
                eoc_rec = EOCRecorder()

                if random_partition:
                    # Distribute elements randomly across nodes.
                    # This is bad, efficiency-wise, but it puts stress
                    # on the parallel implementation, which is desired here.
                    # Another main point of this is to force the code to split
                    # a periodic face pair across nodes.
                    from random import choice
                    partition = [choice(rcon.ranks) for el in mesh.elements]
                else:
                    partition = None

                for order in [1,2,3,4]:
                    if rcon.is_head_rank:
                        mesh_data = rcon.distribute_mesh(mesh, partition)
                    else:
                        mesh_data = rcon.receive_mesh()

                    dims = mesh.points.shape[1]

                    discr = rcon.make_discretization(mesh_data, order=order,
                            default_scalar_type=dtype)

                    op = StrongAdvectionOperator(v[:dims], 
                            inflow_u=TimeDependentGivenFunction(u_analytic),
                            flux_type=flux_type)
                    if debug_output:
                        vis = SiloVisualizer(discr, rcon)

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

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

                    test_name = "test-%s-o%d-m%d-r%s" % (
                            flux_type, order, i_mesh, random_partition)

                    rhs = op.bind(discr)

                    stepper = RK4TimeStepper(dtype=dtype)
                    from hedge.timestep import times_and_steps
                    final_time = 1
                    step_it = times_and_steps(
                            final_time=final_time,
                            max_dt_getter=lambda t: op.estimate_timestep(discr,
                                stepper=stepper, t=t, fields=u))

                    for step, t, dt in step_it:
                        u = stepper(u, t, dt, rhs)

                    assert u.dtype == dtype

                    u_true = discr.interpolate_volume_function(
                            lambda x, el: u_analytic(x, el, final_time))
                    error = u-u_true
                    l2_error = discr.norm(error)

                    if debug_output:
                        visf = vis.make_file(test_name+"-final")
                        vis.add_data(visf, [
                            ("u", u),
                            ("u_true", u_true),
                            ("ic", ic)])
                        visf.close()

                    eoc_rec.add_data_point(order, l2_error)

                if debug_output and rcon.is_head_rank:
                    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] > 3
                assert eoc_rec.estimate_order_of_convergence(2)[-1,1] > 7
Exemplo n.º 9
0
def test_symmetry_preservation_2d():
    """Test whether we preserve symmetry in a symmetric 2D advection problem"""
    from numpy import dot

    def make_mesh():
        array = numpy.array

        #
        #    1---8---2
        #    |7 /|\ 1|
        #    | / | \ |
        #    |/ 6|0 \|
        #    5---4---7
        #    |\ 5|3 /|
        #    | \ | / |
        #    |4 \|/ 2|
        #    0---6---3
        #
        points = [
            array([-0.5, -0.5]),
            array([-0.5, 0.5]),
            array([0.5, 0.5]),
            array([0.5, -0.5]),
            array([0.0, 0.0]),
            array([-0.5, 0.0]),
            array([0.0, -0.5]),
            array([0.5, 0.0]),
            array([0.0, 0.5]),
        ]

        elements = [[8, 7, 4], [8, 7, 2], [6, 7, 3], [7, 4, 6], [5, 6, 0], [5, 6, 4], [5, 8, 4], [1, 5, 8]]

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

        from hedge.mesh import make_conformal_mesh

        return make_conformal_mesh(points, elements, boundary_tagger)

    from hedge.discretization import SymmetryMap
    from hedge.discretization.local import TriangleDiscretization
    from hedge.timestep import RK4TimeStepper
    from math import sqrt, sin
    from hedge.models.advection import StrongAdvectionOperator
    from hedge.data import TimeDependentGivenFunction

    v = numpy.array([-1, 0])

    mesh = make_mesh()
    discr = discr_class(mesh, order=4, debug=discr_class.noninteractive_debug_flags())
    # ref_discr = DynamicDiscretization(mesh, order=4)

    def f(x):
        if x < 0.5:
            return 0
        else:
            return x - 0.5

    # def f(x):
    # return sin(5*x)

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

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

    sym_map = SymmetryMap(discr, lambda x: numpy.array([x[0], -x[1]]), {0: 3, 2: 1, 5: 6, 7: 4})

    for flux_type in StrongAdvectionOperator.flux_types:
        stepper = RK4TimeStepper()
        op = StrongAdvectionOperator(v, inflow_u=TimeDependentGivenFunction(u_analytic), flux_type=flux_type)

        dt = op.estimate_timestep(discr, stepper=stepper)
        nsteps = int(1 / dt)
        rhs = op.bind(discr)
        # test_comp = [ "bflux"]
        # test_rhs = op.bind(discr, test_comp)
        # ref_rhs = op.bind(ref_discr, test_comp)
        for step in xrange(nsteps):
            u = stepper(u, step * dt, dt, rhs)
            sym_error_u = u - sym_map(u)
            sym_error_u_l2 = discr.norm(sym_error_u)

            if False:
                from hedge.visualization import SiloVisualizer

                vis = SiloVisualizer(discr)
                visf = vis.make_file("test-%s-%04d" % (flux_type, step))
                vis.add_data(
                    visf,
                    [
                        ("u", u),
                        ("sym_u", sym_map(u)),
                        ("sym_diff", u - sym_map(u)),
                        ("rhs", rhs(step * dt, u)),
                        ("rhs_test", test_rhs(step * dt, u)),
                        ("rhs_ref", ref_rhs(step * dt, u)),
                        ("rhs_diff", test_rhs(step * dt, u) - ref_rhs(step * dt, u)),
                    ],
                )

                print sym_error_u_l2
            assert sym_error_u_l2 < 4e-15
Exemplo n.º 10
0
    def prepare_with_pointwise_projection_and_basis_reduction(self):
        discr = self.method.discretization
        backend = self.backend

        backend.elements_on_grid.reserve(
                sum(len(eg.members) for eg in discr.element_groups))

        min_s_values = []
        max_s_values = []
        cond_s_values = []

        basis_len_vec = discr.volume_zeros()
        el_condition_vec = discr.volume_zeros()
        point_count_vec = discr.volume_zeros()

        # Iterate over all elements
        for eg in discr.element_groups:
            ldis = eg.local_discretization

            mode_id_to_index = dict(
                    (bid, i) for i, bid in enumerate(ldis.generate_mode_identifiers()))

            for el in eg.members:
                basis = list(zip(
                    ldis.generate_mode_identifiers(), 
                    ldis.basis_functions()))

                eog, points = self.find_points_in_element(el, self.el_tolerance)

                while True:
                    scaled_vdm = self.scaled_vandermonde(el, eog, points, 
                            [bf for bid, bf in basis])

                    max_bid_sum = max(sum(bid) for bid, bf in basis)
                    killable_basis_elements = [
                            (i, bid) for i, (bid, bf) in enumerate(basis)
                            if sum(bid) == max_bid_sum]

                    try:
                        u, s, vt = svd = la.svd(scaled_vdm)

                        thresh = (numpy.finfo(float).eps
                                * max(scaled_vdm.shape) * s[0])

                        assert s[-1] == numpy.min(s)
                        assert s[0] == numpy.max(s)
                        
                        # Imagine that--s can have negative entries.
                        # (AK: I encountered one negative zero.)

                        if len(basis) > len(points) or numpy.abs(s[0]/s[-1]) > 10:
                            retry = True

                            # badly conditioned, kill a basis entry
                            vti = vt[-1]

                            from pytools import argmax2
                            kill_idx, kill_bid = argmax2(
                                    ((j, bid), abs(vti[j])) 
                                    for j, bid in killable_basis_elements)

                            assert kill_bid == basis[kill_idx][0]
                            basis.pop(kill_idx)
                        else:
                            retry = False

                    except la.LinAlgError:
                        # SVD likely didn't converge. Lacking an SVD, we don't have 
                        # much guidance on what modes to kill. Any of the killable
                        # ones will do.

                        # Bang, you're dead.
                        basis.pop(killable_basis_elements[0][0])

                        retry = True

                    if not retry:
                        break

                    if len(basis) == 1:
                        raise RuntimeError(
                                "basis reduction has killed almost the entire basis on element %d"
                                % el.id)

                if ldis.node_count() > len(basis):
                    print "element %d: #nodes=%d, killed modes=%d" % (
                            el.id, ldis.node_count(), ldis.node_count()-len(basis),)

                basis_len_vec[discr.find_el_range(el.id)] = len(basis)
                el_condition_vec[discr.find_el_range(el.id)] = s[0]/s[-1]
                point_count_vec[discr.find_el_range(el.id)] = len(points)

                min_s_values.append(min(s))
                max_s_values.append(max(s))
                cond_s_values.append(max(s)/min(s))

                self.make_pointwise_interpolation_matrix(eog, eg, el, ldis, svd, scaled_vdm,
                        basis_subset=[mode_id_to_index[bid] for bid, bf in basis])

                backend.elements_on_grid.append(eog)

        # visualize basis length for each element
        if set(["depositor", "vis_files"]) < self.method.debug:
            from hedge.visualization import SiloVisualizer
            vis = SiloVisualizer(discr)
            visf = vis.make_file("rec-debug")
            vis.add_data(visf, [
                ("basis_len", basis_len_vec),
                ("el_condition", el_condition_vec),
                ("point_count", point_count_vec),
                ])
            visf.close()

        # we don't need no stinkin' extra points
        backend.extra_point_brick_starts.extend([0]*(len(backend.bricks)+1))

        # print some statistics
        self.generate_point_statistics()
Exemplo n.º 11
0
    def prepare_with_pointwise_projection_and_enlargement(self):
        tolerance_bound = 1.5

        discr = self.method.discretization
        backend = self.backend

        backend.elements_on_grid.reserve(
                sum(len(eg.members) for eg in discr.element_groups))

        cond_claims = 0
        min_s_values = []
        max_s_values = []
        cond_s_values = []

        from hedge.discretization import Projector, Discretization
        fine_discr = Discretization(discr.mesh, order=8)
        proj = Projector(discr, fine_discr)

        from hedge.visualization import SiloVisualizer
        vis = SiloVisualizer(fine_discr)

        # Iterate over all elements
        for eg in discr.element_groups:
            ldis = eg.local_discretization

            for el in eg.members:
                # If the structured Vandermonde matrix is singular,
                # enlarge the element tolerance

                my_tolerance = self.el_tolerance

                orig_point_count = None

                while True:
                    eog, points = self.find_points_in_element(el, my_tolerance)
                    if orig_point_count is None:
                        orig_point_count = len(points)

                    scaled_vdm = self.scaled_vandermonde(el, eog, points, 
                            ldis.basis_functions())

                    bad_vdm = len(points) < ldis.node_count()
                    if not bad_vdm:
                        try:
                            u, s, vt = svd = la.svd(scaled_vdm)
                            thresh = (numpy.finfo(float).eps
                                    * max(scaled_vdm.shape) * s[0])
                            zero_indices = [i for i, si in enumerate(s)
                                if abs(si) < thresh]
                            bad_vdm = bool(zero_indices)
                        except la.LinAlgError:
                            bad_vdm = True

                    if not bad_vdm:
                        break

                    my_tolerance += 0.03
                    if my_tolerance >= tolerance_bound:
                        from warnings import warn
                        warn("rec_grid: could not regularize structured "
                                "vandermonde matrix for el #%d by enlargement" % el.id)
                        break

                #from pytools import average
                #print average(eog.weight_factors), min(s)
                #raw_input()

                if my_tolerance > self.el_tolerance:
                    print "element %d: #nodes=%d, orig #sgridpt=%d, extra tol=%g, #extra points=%d" % (
                            el.id, ldis.node_count(), orig_point_count, 
                            my_tolerance-self.el_tolerance,
                            len(points)-orig_point_count)
                    cond_claims += len(points)-orig_point_count
                min_s_values.append(min(s))
                max_s_values.append(max(s))
                cond_s_values.append(max(s)/min(s))

                if max(s)/min(s) > 1e2:
                    for i in range(len(s)):
                        if s[0]/s[i] > 1e2:
                            zeroed_mode = vt[i]
                            zeroed_mode_nodal = numpy.dot(ldis.vandermonde(), 
                                    zeroed_mode)
                            print el.id, i, s[0]/s[i]
                            fromvec = discr.volume_zeros()
                            fromvec[discr.find_el_range(el.id)] = zeroed_mode_nodal

                            gn = list(eog.grid_nodes)
                            assert len(gn) == len(u[i])

                            tovec = numpy.zeros((backend.grid_node_count_with_extra(),), dtype=float)
                            tovec[gn] = s[i]*u[i]

                            usevec = numpy.zeros((backend.grid_node_count_with_extra(),), dtype=float)
                            usevec[gn] = 1

                            visf = vis.make_file("nulled-%04d%02d" % (el.id, i))
                            vis.add_data(visf, [("meshmode", proj(fromvec))],
                                    expressions=[
                                    ("absmesh", "abs(meshmode)"),
                                    ("absgrid", "abs(gridmode)"),
                                    ])
                            self.visualize_grid_quantities(visf, [
                                    ("gridmode", tovec),
                                    ("usevec", usevec),
                                    ],
                                    )
                            visf.close()
                    #print s
                    #raw_input()

                self.make_pointwise_interpolation_matrix(eog, eg, el, ldis, svd, scaled_vdm)

                backend.elements_on_grid.append(eog)

        # we don't need no stinkin' extra points
        backend.extra_point_brick_starts.extend([0]*(len(backend.bricks)+1))

        # print some statistics
        self.generate_point_statistics(cond_claims)
Exemplo n.º 12
0
Arquivo: naca.py Projeto: gimac/hedge
def main():
    from hedge.backends import guess_run_context

    rcon = guess_run_context()

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

    from pytools import add_python_path_relative_to_script

    add_python_path_relative_to_script("..")

    for order in [4]:
        from gas_dynamics_initials import UniformMachFlow

        uniform_flow = UniformMachFlow()

        from hedge.models.gas_dynamics import GasDynamicsOperator, GammaLawEOS

        op = GasDynamicsOperator(
            dimensions=2,
            equation_of_state=GammaLawEOS(uniform_flow.gamma),
            prandtl=uniform_flow.prandtl,
            spec_gas_const=uniform_flow.spec_gas_const,
            mu=uniform_flow.mu,
            bc_inflow=uniform_flow,
            bc_outflow=uniform_flow,
            bc_noslip=uniform_flow,
            inflow_tag="inflow",
            outflow_tag="outflow",
            noslip_tag="noslip",
        )

        discr = rcon.make_discretization(
            mesh_data,
            order=order,
            debug=[
                "cuda_no_plan",
                # "cuda_dump_kernels",
                # "dump_optemplate_stages",
                # "dump_dataflow_graph",
                # "print_op_code"
            ],
            default_scalar_type=numpy.float32,
            tune_for=op.op_template(),
        )

        from hedge.visualization import SiloVisualizer, VtkVisualizer

        # vis = VtkVisualizer(discr, rcon, "shearflow-%d" % order)
        vis = SiloVisualizer(discr, rcon)

        fields = uniform_flow.volume_interpolant(0, discr)

        navierstokes_ex = op.bind(discr)

        max_eigval = [0]

        def rhs(t, q):
            ode_rhs, speed = navierstokes_ex(t, q)
            max_eigval[0] = speed
            return ode_rhs

        rhs(0, fields)

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

        from hedge.timestep.runge_kutta import ODE23TimeStepper, LSRK4TimeStepper

        stepper = ODE23TimeStepper(
            dtype=discr.default_scalar_type, rtol=1e-6, vector_primitive_factory=discr.get_vector_primitive_factory()
        )
        # stepper = LSRK4TimeStepper(dtype=discr.default_scalar_type)

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

        logmgr = LogManager("cns-naca-%d.dat" % order, "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 LogQuantity

        class ChangeSinceLastStep(LogQuantity):
            """Records the change of a variable between a time step and the previous
               one"""

            def __init__(self, name="change"):
                LogQuantity.__init__(self, name, "1", "Change since last time step")

                self.old_fields = 0

            def __call__(self):
                result = discr.norm(fields - self.old_fields)
                self.old_fields = fields
                return result

        # logmgr.add_quantity(ChangeSinceLastStep())

        # filter setup-------------------------------------------------------------
        from hedge.discretization import Filter, ExponentialFilterResponseFunction

        mode_filter = Filter(discr, ExponentialFilterResponseFunction(min_amplification=0.9, order=4))
        # timestep loop -------------------------------------------------------

        logmgr.add_watches(["step.max", "t_sim.max", "t_step.max"])

        try:
            from hedge.timestep import times_and_steps

            step_it = times_and_steps(
                final_time=200,
                # max_steps=500,
                logmgr=logmgr,
                max_dt_getter=lambda t: next_dt,
                taken_dt_getter=lambda: taken_dt,
            )

            model_stepper = LSRK4TimeStepper()
            next_dt = op.estimate_timestep(discr, stepper=model_stepper, t=0, max_eigenvalue=max_eigval[0])

            for step, t, dt in step_it:
                if step % 10 == 0:
                    visf = vis.make_file("naca-%d-%06d" % (order, step))

                    from pyvisfile.silo import DB_VARTYPE_VECTOR

                    vis.add_data(
                        visf,
                        [
                            ("rho", discr.convert_volume(op.rho(fields), kind="numpy")),
                            ("e", discr.convert_volume(op.e(fields), kind="numpy")),
                            ("rho_u", discr.convert_volume(op.rho_u(fields), kind="numpy")),
                            ("u", discr.convert_volume(op.u(fields), kind="numpy")),
                            # ("true_rho", op.rho(true_fields)),
                            # ("true_e", op.e(true_fields)),
                            # ("true_rho_u", op.rho_u(true_fields)),
                            # ("true_u", op.u(true_fields)),
                            # ("rhs_rho", discr.convert_volume(op.rho(rhs_fields), kind="numpy")),
                            # ("rhs_e", discr.convert_volume(op.e(rhs_fields), kind="numpy")),
                            # ("rhs_rho_u", discr.convert_volume(op.rho_u(rhs_fields), kind="numpy")),
                        ],
                        expressions=[
                            # ("diff_rho", "rho-true_rho"),
                            # ("diff_e", "e-true_e"),
                            # ("diff_rho_u", "rho_u-true_rho_u", DB_VARTYPE_VECTOR),
                            ("p", "(0.4)*(e- 0.5*(rho_u*u))")
                        ],
                        time=t,
                        step=step,
                    )
                    visf.close()

                fields, t, taken_dt, next_dt = stepper(fields, t, dt, rhs)
                fields = mode_filter(fields)

        finally:
            vis.close()
            logmgr.save()
            discr.close()
Exemplo n.º 13
0
def compute_initial_condition(rcon, discr, method, state,
        maxwell_op, potential_bc,
        force_zero=False):
    from hedge.models.poisson import PoissonOperator
    from hedge.mesh import TAG_ALL, TAG_NONE
    from hedge.data import ConstantGivenFunction, GivenVolumeInterpolant

    def rel_l2_error(field, true):
        from hedge.tools import relative_error
        return relative_error(
                discr.norm(field-true),
                discr.norm(true))

    mean_beta = method.mean_beta(state)
    gamma = method.units.gamma_from_beta(mean_beta)

    # see doc/notes.tm for derivation of IC

    def make_scaling_matrix(beta_scale, other_scale):
        if la.norm(mean_beta) < 1e-10:
            return other_scale*numpy.eye(discr.dimensions)
        else:
            beta_unit = mean_beta/la.norm(mean_beta)
            return (other_scale*numpy.identity(discr.dimensions)
                    + (beta_scale-other_scale)*numpy.outer(beta_unit, beta_unit))

    poisson_op = PoissonOperator(
            discr.dimensions,
            diffusion_tensor=make_scaling_matrix(1/gamma**2, 1),
            dirichlet_tag=TAG_ALL,
            neumann_tag=TAG_NONE,
            dirichlet_bc=potential_bc)

    rho_prime = method.deposit_rho(state)
    rho_tilde = rho_prime/gamma

    bound_poisson = poisson_op.bind(discr)
    if force_zero:
        phi_tilde = discr.volume_zeros()
    else:
        from hedge.iterative import parallel_cg
        phi_tilde = -parallel_cg(rcon, -bound_poisson,
                bound_poisson.prepare_rhs(
                    rho_tilde/maxwell_op.epsilon),
                debug=40 if "poisson" in method.debug else False, tol=1e-10)

    from hedge.tools import ptwise_dot
    from hedge.models.nd_calculus import GradientOperator
    e_tilde = ptwise_dot(2, 1, make_scaling_matrix(1/gamma, 1),
            GradientOperator(discr.dimensions).bind(discr)(phi_tilde))
    e_prime = ptwise_dot(2, 1, make_scaling_matrix(1, gamma), e_tilde)

    from pyrticle.tools import make_cross_product
    v_e_to_h_cross = make_cross_product(method, maxwell_op, "v", "e", "h")
    h_prime = (1/maxwell_op.mu)*gamma/maxwell_op.c * v_e_to_h_cross(mean_beta, e_tilde)

    if "ic" in method.debug:
        deposited_charge = discr.integral(rho_prime)

        real_charge = numpy.sum(state.charges)
        print "charge: supposed=%g deposited=%g error=%g %%" % (
                real_charge,
                deposited_charge,
                100*abs(deposited_charge-real_charge)/abs(real_charge)
                )

        from hedge.models.nd_calculus import DivergenceOperator

        bound_div_op = DivergenceOperator(discr.dimensions).bind(discr)

        d_tilde = maxwell_op.epsilon*e_tilde
        d_prime = maxwell_op.epsilon*e_prime

        #divD_prime_ldg = bound_poisson.div(d_prime)
        #divD_prime_ldg2 = bound_poisson.div(d_prime, maxwell_op.epsilon*gamma*phi_tilde)
        from hedge.optemplate import InverseMassOperator
        divD_prime_ldg3 = maxwell_op.epsilon*\
                (InverseMassOperator().apply(discr, bound_poisson.op(gamma*phi_tilde)))
        divD_prime_central = bound_div_op(d_prime)

        print "l2 div D_prime error central: %g" % \
                rel_l2_error(divD_prime_central, rho_prime)
        #print "l2 div D_prime error ldg: %g" % \
                #rel_l2_error(divD_prime_ldg, rho_prime)
        #print "l2 div D_prime error ldg with phi: %g" % \
                #rel_l2_error(divD_prime_ldg2, rho_prime)
        print "l2 div D_prime error ldg with phi 3: %g" % \
                rel_l2_error(divD_prime_ldg3, rho_prime)

        if "vis_files" in method.debug:
            from hedge.visualization import SiloVisualizer
            vis = SiloVisualizer(discr)
            visf = vis.make_file("ic")
            vis.add_data(visf, [
                ("phi_moving", phi_tilde),
                ("rho_moving", rho_tilde),
                ("e_moving", e_tilde),

                ("rho_lab", rho_prime),
                #("divD_lab_ldg", divD_prime_ldg),
                #("divD_lab_ldg2", divD_prime_ldg2),
                #("divD_lab_ldg3", divD_prime_ldg3),
                ("divD_lab_central", divD_prime_central),
                ("e_lab", e_prime),
                ("h_lab", h_prime),
                ],
                )
            method.add_to_vis(vis, visf, state)
            visf.close()

    return maxwell_op.assemble_fields(e=e_prime, h=h_prime, discr=discr)
Exemplo n.º 14
0
def optimize_shape_bandwidth(method, state, analytic_rho, exponent):
    discr = method.discretization
    rec = method.depositor

    adv_radius = method.mesh_data.advisable_particle_radius()
    radii = [adv_radius*2**i
            for i in numpy.linspace(-4, 2, 50)]

    def set_radius(r):
        method.depositor.set_shape_function(
                state,
                method.get_shape_function_class()
                (r, method.mesh_data.dimensions, exponent,))

    tried_radii = []
    l1_errors = []

    debug = "shape_bw" in method.debug
    visualize = set(["shape_bw", "vis_files"]) <= method.debug

    if visualize:
        from hedge.visualization import SiloVisualizer
        vis = SiloVisualizer(discr)

    import sys

    if debug:
        sys.stdout.write("optimizing shape bw (%d attempts): " % len(radii))
    for step, radius in enumerate(radii):
        if debug:
            sys.stdout.write("%d." % step)
            sys.stdout.flush()

        try:
            try:
                method.set_ignore_core_warnings(True)
                set_radius(radius)
            except RuntimeError, re:
                if "particle mass is zero" in str(re):
                    continue
                else:
                    raise
        finally:
            method.set_ignore_core_warnings(False)

        state.derived_quantity_cache.clear()

        try:
            try:
                method.set_ignore_core_warnings(True)
                rec_rho = method.deposit_rho(state)
            except RuntimeError, re:
                if "particle mass is zero" in str(re):
                    continue
                else:
                    raise
        finally:
            method.set_ignore_core_warnings(False)

        tried_radii.append(radius)
        l1_errors.append(discr.integral(numpy.abs(rec_rho-analytic_rho)))

        if visualize:
            visf = vis.make_file("bwopt-%04d" % step)
            method.add_to_vis(vis, visf, state, time=radius, step=step)
            vis.add_data(visf, [
                ("rho", rec_rho),
                #("j", method.deposit_j(state)),
                ("rho_analytic", analytic_rho),
                ],
                expressions=[("rho_diff", "rho-rho_analytic")],
                time=radius, step=step)

            try:
                rec.visualize_grid_quantities
            except AttributeError:
                pass
            else:
                rec.visualize_grid_quantities(visf, [
                        ("rho_grid", rec.deposit_grid_rho(state)),
                        ("j_grid", rec.deposit_grid_j(state, method.velocities(state))),
                        ("rho_resid", rec.remap_residual(rec.deposit_grid_rho(state))),
                        ])

            visf.close()

    if debug:
        sys.stdout.write("\n")
        sys.stdout.flush()

    if visualize:
        vis.close()

    from pytools import argmin
    min_idx = argmin(l1_errors)
    min_rad = tried_radii[min_idx]
    min_l1_error = l1_errors[min_idx]

    rel_l1_error = abs(min_l1_error / discr.integral(analytic_rho))
    if rel_l1_error > 0.1:
        from warnings import warn
        warn("Charge density is very poorly resolved (rel L1 error=%g)" % rel_l1_error)

    def is_local_minimum(list, i):
        if i == 0:
            return False
        elif i == len(list)-1:
            return False
        else:
            return list[i] < list[i-1] and list[i] < list[i+1]

    local_minima = [idx for idx in range(len(tried_radii))
            if is_local_minimum(l1_errors, idx)]

    chosen_idx = max(local_minima)
    chosen_rad = tried_radii[chosen_idx]

    if "shape_bw" in method.debug:
        chosen_l1_error = l1_errors[chosen_idx]
        print "radius: guessed optimum=%g, found optimum=%g, chosen=%g" % (
                adv_radius, min_rad, chosen_rad)
        print "radius: optimum l1 error=%g, chosen l1 error=%g" % (
                min_l1_error, chosen_l1_error)

    set_radius(chosen_rad)
    state.derived_quantity_cache.clear()

    if set(["interactive", "shape_bw"]) < method.debug:
        from pylab import semilogx, show
        semilogx(tried_radii, l1_errors)
        show()
Exemplo n.º 15
0
    def inner_run(self):
        t = 0

        setup = self.setup
        setup.hook_startup(self)

        vis_order = setup.vis_order
        if vis_order is None:
            vis_order = setup.element_order

        if vis_order != setup.element_order:
            vis_discr = self.rcon.make_discretization(self.discr.mesh,
                                                      order=vis_order,
                                                      debug=setup.dg_debug)

            from hedge.discretization import Projector
            vis_proj = Projector(self.discr, vis_discr)
        else:
            vis_discr = self.discr

            def vis_proj(f):
                return f

        from hedge.visualization import SiloVisualizer
        vis = SiloVisualizer(vis_discr)

        fields = self.fields
        self.observer.set_fields_and_state(fields, self.state)

        from hedge.tools import make_obj_array
        from pyrticle.cloud import TimesteppablePicState

        def visualize(observer):
            sub_timer = self.vis_timer.start_sub_timer()
            import os.path
            visf = vis.make_file(
                os.path.join(setup.output_path, setup.vis_pattern % step))

            self.method.add_to_vis(vis,
                                   visf,
                                   observer.state,
                                   time=t,
                                   step=step)
            vis.add_data(
                visf, [(name, vis_proj(fld))
                       for name, fld in setup.hook_vis_quantities(observer)],
                time=t,
                step=step)
            setup.hook_visualize(self, vis, visf, observer)

            visf.close()
            sub_timer.stop().submit()

        from hedge.timestep.multirate_ab import TwoRateAdamsBashforthTimeStepper
        if not isinstance(self.stepper, TwoRateAdamsBashforthTimeStepper):

            def rhs(t, fields_and_state):
                fields, ts_state = fields_and_state
                state_f = lambda: ts_state.state
                fields_f = lambda: fields

                fields_rhs = (self.f_rhs_calculator(t, fields_f, state_f) +
                              self.p2f_rhs_calculator(t, fields_f, state_f))
                state_rhs = (self.p_rhs_calculator(t, fields_f, state_f) +
                             self.f2p_rhs_calculator(t, fields_f, state_f))

                return make_obj_array([fields_rhs, state_rhs])

            step_args = (self.dt, rhs)
        else:

            def add_unwrap(rhs):
                def unwrapping_rhs(t, fields, ts_state):
                    return rhs(t, fields, lambda: ts_state().state)

                return unwrapping_rhs

            step_args = ((
                add_unwrap(self.f_rhs_calculator),
                add_unwrap(self.p2f_rhs_calculator),
                add_unwrap(self.f2p_rhs_calculator),
                add_unwrap(self.p_rhs_calculator),
            ), )

        y = make_obj_array(
            [fields, TimesteppablePicState(self.method, self.state)])
        del self.state

        try:
            from hedge.timestep import times_and_steps
            step_it = times_and_steps(max_steps=self.nsteps,
                                      logmgr=self.logmgr,
                                      max_dt_getter=lambda t: self.dt)

            for step, t, dt in step_it:
                self.method.upkeep(y[1].state)

                if step % setup.vis_interval == 0:
                    visualize(self.observer)

                y = self.stepper(y, t, *step_args)

                fields, ts_state = y
                self.observer.set_fields_and_state(fields, ts_state.state)

                setup.hook_after_step(self, self.observer)
        finally:
            vis.close()
            self.discr.close()
            self.logmgr.save()

        setup.hook_when_done(self)
Exemplo n.º 16
0
    def prepare_with_pointwise_projection_and_basis_reduction(self):
        discr = self.method.discretization
        backend = self.backend

        backend.elements_on_grid.reserve(
            sum(len(eg.members) for eg in discr.element_groups))

        min_s_values = []
        max_s_values = []
        cond_s_values = []

        basis_len_vec = discr.volume_zeros()
        el_condition_vec = discr.volume_zeros()
        point_count_vec = discr.volume_zeros()

        # Iterate over all elements
        for eg in discr.element_groups:
            ldis = eg.local_discretization

            mode_id_to_index = dict(
                (bid, i)
                for i, bid in enumerate(ldis.generate_mode_identifiers()))

            for el in eg.members:
                basis = list(
                    zip(ldis.generate_mode_identifiers(),
                        ldis.basis_functions()))

                eog, points = self.find_points_in_element(
                    el, self.el_tolerance)

                while True:
                    scaled_vdm = self.scaled_vandermonde(
                        el, eog, points, [bf for bid, bf in basis])

                    max_bid_sum = max(sum(bid) for bid, bf in basis)
                    killable_basis_elements = [
                        (i, bid) for i, (bid, bf) in enumerate(basis)
                        if sum(bid) == max_bid_sum
                    ]

                    try:
                        u, s, vt = svd = la.svd(scaled_vdm)

                        thresh = (numpy.finfo(float).eps *
                                  max(scaled_vdm.shape) * s[0])

                        assert s[-1] == numpy.min(s)
                        assert s[0] == numpy.max(s)

                        # Imagine that--s can have negative entries.
                        # (AK: I encountered one negative zero.)

                        if len(basis) > len(points) or numpy.abs(
                                s[0] / s[-1]) > 10:
                            retry = True

                            # badly conditioned, kill a basis entry
                            vti = vt[-1]

                            from pytools import argmax2
                            kill_idx, kill_bid = argmax2(
                                ((j, bid), abs(vti[j]))
                                for j, bid in killable_basis_elements)

                            assert kill_bid == basis[kill_idx][0]
                            basis.pop(kill_idx)
                        else:
                            retry = False

                    except la.LinAlgError:
                        # SVD likely didn't converge. Lacking an SVD, we don't have
                        # much guidance on what modes to kill. Any of the killable
                        # ones will do.

                        # Bang, you're dead.
                        basis.pop(killable_basis_elements[0][0])

                        retry = True

                    if not retry:
                        break

                    if len(basis) == 1:
                        raise RuntimeError(
                            "basis reduction has killed almost the entire basis on element %d"
                            % el.id)

                if ldis.node_count() > len(basis):
                    print "element %d: #nodes=%d, killed modes=%d" % (
                        el.id,
                        ldis.node_count(),
                        ldis.node_count() - len(basis),
                    )

                basis_len_vec[discr.find_el_range(el.id)] = len(basis)
                el_condition_vec[discr.find_el_range(el.id)] = s[0] / s[-1]
                point_count_vec[discr.find_el_range(el.id)] = len(points)

                min_s_values.append(min(s))
                max_s_values.append(max(s))
                cond_s_values.append(max(s) / min(s))

                self.make_pointwise_interpolation_matrix(
                    eog,
                    eg,
                    el,
                    ldis,
                    svd,
                    scaled_vdm,
                    basis_subset=[mode_id_to_index[bid] for bid, bf in basis])

                backend.elements_on_grid.append(eog)

        # visualize basis length for each element
        if set(["depositor", "vis_files"]) < self.method.debug:
            from hedge.visualization import SiloVisualizer
            vis = SiloVisualizer(discr)
            visf = vis.make_file("rec-debug")
            vis.add_data(visf, [
                ("basis_len", basis_len_vec),
                ("el_condition", el_condition_vec),
                ("point_count", point_count_vec),
            ])
            visf.close()

        # we don't need no stinkin' extra points
        backend.extra_point_brick_starts.extend([0] *
                                                (len(backend.bricks) + 1))

        # print some statistics
        self.generate_point_statistics()
Exemplo n.º 17
0
def main():
    from hedge.backends import guess_run_context
    rcon = guess_run_context(["cuda", "mpi"])

    if rcon.is_head_rank:
        mesh = make_wingmesh()
        #from hedge.mesh import make_rect_mesh
        #mesh = make_rect_mesh(
        #       boundary_tagger=lambda fvi, el, fn, all_v: ["inflow"])
        mesh_data = rcon.distribute_mesh(mesh)
    else:
        mesh_data = rcon.receive_mesh()

    for order in [3]:
        from pytools import add_python_path_relative_to_script
        add_python_path_relative_to_script("..")

        from gas_dynamics_initials import UniformMachFlow
        wing = UniformMachFlow(angle_of_attack=0)

        from hedge.models.gas_dynamics import GasDynamicsOperator
        op = GasDynamicsOperator(dimensions=3,
                                 gamma=wing.gamma,
                                 mu=wing.mu,
                                 prandtl=wing.prandtl,
                                 spec_gas_const=wing.spec_gas_const,
                                 bc_inflow=wing,
                                 bc_outflow=wing,
                                 bc_noslip=wing,
                                 inflow_tag="inflow",
                                 outflow_tag="outflow",
                                 noslip_tag="noslip")

        discr = rcon.make_discretization(
            mesh_data,
            order=order,
            debug=[
                "cuda_no_plan",
                #"cuda_dump_kernels",
                #"dump_dataflow_graph",
                #"dump_optemplate_stages",
                #"dump_dataflow_graph",
                #"print_op_code"
                "cuda_no_metis",
            ],
            default_scalar_type=numpy.float64,
            tune_for=op.op_template())

        from hedge.visualization import SiloVisualizer, VtkVisualizer
        #vis = VtkVisualizer(discr, rcon, "shearflow-%d" % order)
        vis = SiloVisualizer(discr, rcon)

        fields = wing.volume_interpolant(0, discr)

        navierstokes_ex = op.bind(discr)

        max_eigval = [0]

        def rhs(t, q):
            ode_rhs, speed = navierstokes_ex(t, q)
            max_eigval[0] = speed
            return ode_rhs

        rhs(0, fields)

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

        from hedge.timestep import RK4TimeStepper
        stepper = RK4TimeStepper()

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

        logmgr = LogManager("navierstokes-%d.dat" % order, "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 -------------------------------------------------------
        try:
            from hedge.timestep import times_and_steps
            step_it = times_and_steps(
                final_time=200,
                #max_steps=500,
                logmgr=logmgr,
                max_dt_getter=lambda t: 0.6 * op.estimate_timestep(
                    discr, stepper=stepper, t=t, max_eigenvalue=max_eigval[0]))

            for step, t, dt in step_it:
                if step % 200 == 0:
                    #if False:
                    visf = vis.make_file("wing-%d-%06d" % (order, step))

                    #rhs_fields = rhs(t, fields)

                    from pyvisfile.silo import DB_VARTYPE_VECTOR
                    from hedge.discretization import ones_on_boundary
                    vis.add_data(
                        visf,
                        [
                            ("rho",
                             discr.convert_volume(op.rho(fields),
                                                  kind="numpy")),
                            ("e",
                             discr.convert_volume(op.e(fields), kind="numpy")),
                            ("rho_u",
                             discr.convert_volume(op.rho_u(fields),
                                                  kind="numpy")),
                            ("u",
                             discr.convert_volume(op.u(fields), kind="numpy")),

                            #("rhs_rho", discr.convert_volume(op.rho(rhs_fields), kind="numpy")),
                            #("rhs_e", discr.convert_volume(op.e(rhs_fields), kind="numpy")),
                            #("rhs_rho_u", discr.convert_volume(op.rho_u(rhs_fields), kind="numpy")),
                        ],
                        expressions=[
                            ("p", "(0.4)*(e- 0.5*(rho_u*u))"),
                        ],
                        time=t,
                        step=step)
                    visf.close()

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

        finally:
            vis.close()
            logmgr.save()
            discr.close()
Exemplo n.º 18
0
def main():
    from hedge.backends import guess_run_context
    rcon = guess_run_context(["cuda"])

    if rcon.is_head_rank:
        mesh = make_boxmesh()
        #from hedge.mesh import make_rect_mesh
        #mesh = make_rect_mesh(
        #       boundary_tagger=lambda fvi, el, fn, all_v: ["inflow"])
        mesh_data = rcon.distribute_mesh(mesh)
    else:
        mesh_data = rcon.receive_mesh()

    for order in [3]:
        from pytools import add_python_path_relative_to_script
        add_python_path_relative_to_script("..")

        from gas_dynamics_initials import UniformMachFlow
        box = UniformMachFlow(angle_of_attack=0)

        from hedge.models.gas_dynamics import GasDynamicsOperator
        op = GasDynamicsOperator(dimensions=3,
                                 gamma=box.gamma,
                                 mu=box.mu,
                                 prandtl=box.prandtl,
                                 spec_gas_const=box.spec_gas_const,
                                 bc_inflow=box,
                                 bc_outflow=box,
                                 bc_noslip=box,
                                 inflow_tag="inflow",
                                 outflow_tag="outflow",
                                 noslip_tag="noslip")

        discr = rcon.make_discretization(
            mesh_data,
            order=order,
            debug=[
                #"cuda_no_plan",
                #"cuda_dump_kernels",
                #"dump_dataflow_graph",
                #"dump_optemplate_stages",
                #"dump_dataflow_graph",
                #"print_op_code",
                "cuda_no_plan_el_local",
            ],
            default_scalar_type=numpy.float32,
            tune_for=op.op_template())

        from hedge.visualization import SiloVisualizer, VtkVisualizer  # noqa
        #vis = VtkVisualizer(discr, rcon, "shearflow-%d" % order)
        vis = SiloVisualizer(discr, rcon)

        fields = box.volume_interpolant(0, discr)

        navierstokes_ex = op.bind(discr)

        max_eigval = [0]

        def rhs(t, q):
            ode_rhs, speed = navierstokes_ex(t, q)
            max_eigval[0] = speed
            return ode_rhs

        rhs(0, fields)

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

        from hedge.timestep import RK4TimeStepper
        stepper = RK4TimeStepper()

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

        logmgr = LogManager("navierstokes-%d.dat" % order, "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"])

        from pytools.log import LogQuantity

        class ChangeSinceLastStep(LogQuantity):
            """Records the change of a variable between a time step and the previous
               one"""
            def __init__(self, name="change"):
                LogQuantity.__init__(self, name, "1",
                                     "Change since last time step")

                self.old_fields = 0

            def __call__(self):
                result = discr.norm(fields - self.old_fields)
                self.old_fields = fields
                return result

        logmgr.add_quantity(ChangeSinceLastStep())

        # timestep loop -------------------------------------------------------
        try:
            from hedge.timestep import times_and_steps
            step_it = times_and_steps(
                final_time=200,
                #max_steps=500,
                logmgr=logmgr,
                max_dt_getter=lambda t: op.estimate_timestep(
                    discr, stepper=stepper, t=t, max_eigenvalue=max_eigval[0]))

            for step, t, dt in step_it:
                if step % 200 == 0:
                    #if False:
                    visf = vis.make_file("box-%d-%06d" % (order, step))

                    #rhs_fields = rhs(t, fields)

                    vis.add_data(
                        visf,
                        [
                            ("rho",
                             discr.convert_volume(op.rho(fields),
                                                  kind="numpy")),
                            ("e",
                             discr.convert_volume(op.e(fields), kind="numpy")),
                            ("rho_u",
                             discr.convert_volume(op.rho_u(fields),
                                                  kind="numpy")),
                            ("u",
                             discr.convert_volume(op.u(fields), kind="numpy")),

                            # ("rhs_rho", discr.convert_volume(
                            #     op.rho(rhs_fields), kind="numpy")),
                            # ("rhs_e", discr.convert_volume(
                            #     op.e(rhs_fields), kind="numpy")),
                            # ("rhs_rho_u", discr.convert_volume(
                            #     op.rho_u(rhs_fields), kind="numpy")),
                        ],
                        expressions=[
                            ("p", "(0.4)*(e- 0.5*(rho_u*u))"),
                        ],
                        time=t,
                        step=step)
                    visf.close()

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

        finally:
            vis.close()
            logmgr.save()
            discr.close()
Exemplo n.º 19
0
    def initialize(self, method):
        Depositor.initialize(self, method)

        backend_class = getattr(
            _internal,
            "GridFindDepositor" + method.get_dimensionality_suffix())
        backend = self.backend = backend_class(method.mesh_data)

        discr = method.discretization

        grid_node_num_to_nodes = {}

        if self.brick_generator is None:
            bbox_min, bbox_max = discr.mesh.bounding_box()
            max_bbox_size = max(bbox_max - bbox_min)
            self.brick_generator = SingleBrickGenerator(mesh_margin=1e-3 *
                                                        max_bbox_size,
                                                        overresolve=0.2)

        from pyrticle._internal import Brick
        for i, (stepwidths, origin,
                dims) in enumerate(self.brick_generator(discr)):
            backend.bricks.append(
                Brick(i, backend.grid_node_count(), stepwidths, origin, dims))

        from pyrticle._internal import BoxFloat
        for eg in discr.element_groups:
            ldis = eg.local_discretization

            for el in eg.members:
                el_bbox = BoxFloat(*el.bounding_box(discr.mesh.points))
                el_slice = discr.find_el_range(el.id)

                for brk in backend.bricks:
                    if brk.bounding_box().intersect(el_bbox).is_empty():
                        continue

                    for node_num in range(el_slice.start, el_slice.stop):
                        try:
                            cell_number = brk.which_cell(discr.nodes[node_num])
                        except ValueError:
                            pass
                        else:
                            grid_node_num_to_nodes.setdefault(
                                brk.index(cell_number), []).append(node_num)

        from pytools import flatten
        unassigned_nodes = (set(xrange(len(discr))) -
                            set(flatten(grid_node_num_to_nodes.itervalues())))

        if unassigned_nodes:
            raise RuntimeError(
                "dep_grid_find: unassigned mesh nodes found. "
                "you should specify a mesh_margin when generating "
                "bricks")

        usecounts = numpy.zeros((backend.grid_node_count(), ))
        for gnn in xrange(backend.grid_node_count()):
            grid_nodes = grid_node_num_to_nodes.get(gnn, [])
            usecounts[gnn] = len(grid_nodes)
            backend.node_number_list_starts.append(
                len(backend.node_number_lists))
            backend.node_number_lists.extend(grid_nodes)
        backend.node_number_list_starts.append(len(backend.node_number_lists))

        if "depositor" in method.debug:
            from hedge.visualization import SiloVisualizer
            vis = SiloVisualizer(discr)
            visf = vis.make_file("grid-find-debug")
            vis.add_data(visf, [])
            self.visualize_grid_quantities(visf, [("usecounts", usecounts)])
            visf.close()

            if "interactive" in cloud.debug:
                from matplotlib.pylab import hist, show
                hist(usecounts, bins=20)
                show()
Exemplo n.º 20
0
def main():
    import logging
    logging.basicConfig(level=logging.INFO)

    from hedge.backends import guess_run_context
    rcon = guess_run_context()

    if rcon.is_head_rank:
        if True:
            mesh = make_squaremesh()
        else:
            from hedge.mesh import make_rect_mesh
            mesh = make_rect_mesh(
                   boundary_tagger=lambda fvi, el, fn, all_v: ["inflow"],
                   max_area=0.1)

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

    from pytools import add_python_path_relative_to_script
    add_python_path_relative_to_script(".")

    for order in [3]:
        from gas_dynamics_initials import UniformMachFlow
        square = UniformMachFlow(gaussian_pulse_at=numpy.array([-2, 2]),
                pulse_magnitude=0.003)

        from hedge.models.gas_dynamics import (
                GasDynamicsOperator,
                GammaLawEOS)

        op = GasDynamicsOperator(dimensions=2,
                equation_of_state=GammaLawEOS(square.gamma), mu=square.mu,
                prandtl=square.prandtl, spec_gas_const=square.spec_gas_const,
                bc_inflow=square, bc_outflow=square, bc_noslip=square,
                inflow_tag="inflow", outflow_tag="outflow", noslip_tag="noslip")

        discr = rcon.make_discretization(mesh_data, order=order,
                        debug=["cuda_no_plan",
                            "cuda_dump_kernels",
                            #"dump_dataflow_graph",
                            #"dump_optemplate_stages",
                            #"dump_dataflow_graph",
                            #"dump_op_code"
                            #"cuda_no_plan_el_local"
                            ],
                        default_scalar_type=numpy.float64,
                        tune_for=op.op_template(),
                        quad_min_degrees={
                            "gasdyn_vol": 3*order,
                            "gasdyn_face": 3*order,
                            }
                        )

        from hedge.visualization import SiloVisualizer, VtkVisualizer
        #vis = VtkVisualizer(discr, rcon, "shearflow-%d" % order)
        vis = SiloVisualizer(discr, rcon)

        from hedge.timestep.runge_kutta import (
                LSRK4TimeStepper, ODE23TimeStepper, ODE45TimeStepper)
        from hedge.timestep.dumka3 import Dumka3TimeStepper
        #stepper = LSRK4TimeStepper(dtype=discr.default_scalar_type,
                #vector_primitive_factory=discr.get_vector_primitive_factory())

        stepper = ODE23TimeStepper(dtype=discr.default_scalar_type,
                rtol=1e-6,
                vector_primitive_factory=discr.get_vector_primitive_factory())
        # Dumka works kind of poorly
        #stepper = Dumka3TimeStepper(dtype=discr.default_scalar_type,
                #rtol=1e-7, pol_index=2,
                #vector_primitive_factory=discr.get_vector_primitive_factory())

        #from hedge.timestep.dumka3 import Dumka3TimeStepper
        #stepper = Dumka3TimeStepper(3, rtol=1e-7)

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

        logmgr = LogManager("cns-square-sp-%d.dat" % order, "w", rcon.communicator)

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

        from pytools.log import LogQuantity
        class ChangeSinceLastStep(LogQuantity):
            """Records the change of a variable between a time step and the previous
               one"""

            def __init__(self, name="change"):
                LogQuantity.__init__(self, name, "1", "Change since last time step")

                self.old_fields = 0

            def __call__(self):
                result = discr.norm(fields - self.old_fields)
                self.old_fields = fields
                return result

        #logmgr.add_quantity(ChangeSinceLastStep())

        add_simulation_quantities(logmgr)
        logmgr.add_watches(["step.max", "t_sim.max", "t_step.max"])

        # filter setup ------------------------------------------------------------
        from hedge.discretization import Filter, ExponentialFilterResponseFunction
        mode_filter = Filter(discr,
                ExponentialFilterResponseFunction(min_amplification=0.95, order=6))

        # timestep loop -------------------------------------------------------
        fields = square.volume_interpolant(0, discr)

        navierstokes_ex = op.bind(discr)

        max_eigval = [0]
        def rhs(t, q):
            ode_rhs, speed = navierstokes_ex(t, q)
            max_eigval[0] = speed
            return ode_rhs
        rhs(0, fields)

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

        try:
            from hedge.timestep import times_and_steps
            step_it = times_and_steps(
                    final_time=1000,
                    #max_steps=500,
                    logmgr=logmgr,
                    max_dt_getter=lambda t: next_dt,
                    taken_dt_getter=lambda: taken_dt)

            model_stepper = LSRK4TimeStepper()
            next_dt = op.estimate_timestep(discr,
                    stepper=model_stepper, t=0, 
                    max_eigenvalue=max_eigval[0])

            for step, t, dt in step_it:
                #if (step % 10000 == 0): #and step < 950000) or (step % 500 == 0 and step > 950000):
                #if False:
                if step % 5 == 0:
                    visf = vis.make_file("square-%d-%06d" % (order, step))

                    #from pyvisfile.silo import DB_VARTYPE_VECTOR
                    vis.add_data(visf,
                            [
                                ("rho", discr.convert_volume(op.rho(fields), kind="numpy")),
                                ("e", discr.convert_volume(op.e(fields), kind="numpy")),
                                ("rho_u", discr.convert_volume(op.rho_u(fields), kind="numpy")),
                                ("u", discr.convert_volume(op.u(fields), kind="numpy")),
                            ],
                            expressions=[
                                ("p", "(0.4)*(e- 0.5*(rho_u*u))"),
                                ],
                            time=t, step=step
                            )
                    visf.close()

                if stepper.adaptive:
                    fields, t, taken_dt, next_dt = stepper(fields, t, dt, rhs)
                else:
                    taken_dt = dt
                    fields = stepper(fields, t, dt, rhs)
                    dt = op.estimate_timestep(discr,
                            stepper=model_stepper, t=0,
                            max_eigenvalue=max_eigval[0])

                #fields = mode_filter(fields)

        finally:
            vis.close()
            logmgr.save()
            discr.close()
Exemplo n.º 21
0
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
Exemplo n.º 22
0
    def inner_run(self): 
        t = 0
        
        setup = self.setup
        setup.hook_startup(self)

        vis_order = setup.vis_order
        if vis_order is None:
            vis_order = setup.element_order

        if vis_order != setup.element_order:
            vis_discr = self.rcon.make_discretization(self.discr.mesh, 
                            order=vis_order, debug=setup.dg_debug)

            from hedge.discretization import Projector
            vis_proj = Projector(self.discr, vis_discr)
        else:
            vis_discr = self.discr

            def vis_proj(f):
                return f

        from hedge.visualization import SiloVisualizer
        vis = SiloVisualizer(vis_discr)

        fields = self.fields
        self.observer.set_fields_and_state(fields, self.state)

        from hedge.tools import make_obj_array
        from pyrticle.cloud import TimesteppablePicState

        def visualize(observer):
            sub_timer = self.vis_timer.start_sub_timer()
            import os.path
            visf = vis.make_file(os.path.join(
                setup.output_path, setup.vis_pattern % step))

            self.method.add_to_vis(vis, visf, observer.state, time=t, step=step)
            vis.add_data(visf, 
                    [(name, vis_proj(fld))
                        for name, fld in setup.hook_vis_quantities(observer)],
                    time=t, step=step)
            setup.hook_visualize(self, vis, visf, observer)

            visf.close()
            sub_timer.stop().submit()

        from hedge.timestep.multirate_ab import TwoRateAdamsBashforthTimeStepper 
        if not isinstance(self.stepper, TwoRateAdamsBashforthTimeStepper): 
            def rhs(t, fields_and_state):
                fields, ts_state = fields_and_state
                state_f = lambda: ts_state.state
                fields_f = lambda: fields

                fields_rhs = (
                        self.f_rhs_calculator(t, fields_f, state_f)
                        + self.p2f_rhs_calculator(t, fields_f, state_f))
                state_rhs = (
                        self.p_rhs_calculator(t, fields_f, state_f)
                        + self.f2p_rhs_calculator(t, fields_f, state_f))

                return make_obj_array([fields_rhs, state_rhs])
            step_args = (self.dt, rhs)
        else:
            def add_unwrap(rhs):
                def unwrapping_rhs(t, fields, ts_state):
                    return rhs(t, fields, lambda: ts_state().state)
                return unwrapping_rhs

            step_args = ((
                    add_unwrap(self.f_rhs_calculator),
                    add_unwrap(self.p2f_rhs_calculator),
                    add_unwrap(self.f2p_rhs_calculator),
                    add_unwrap(self.p_rhs_calculator),
                    ),)

        y = make_obj_array([
            fields, 
            TimesteppablePicState(self.method, self.state)
            ])
        del self.state

        try:
            from hedge.timestep import times_and_steps
            step_it = times_and_steps(
                    max_steps=self.nsteps,
                    logmgr=self.logmgr,
                    max_dt_getter=lambda t: self.dt)

            for step, t, dt in step_it:
                self.method.upkeep(y[1].state)

                if step % setup.vis_interval == 0:
                    visualize(self.observer)

                y = self.stepper(y, t, *step_args)

                fields, ts_state = y
                self.observer.set_fields_and_state(fields, ts_state.state)

                setup.hook_after_step(self, self.observer)
        finally:
            vis.close()
            self.discr.close()
            self.logmgr.save()

        setup.hook_when_done(self)
Exemplo n.º 23
0
def run_setup(units, casename, setup, discr, pusher, visualize=False):
    from hedge.timestep.runge_kutta import LSRK4TimeStepper
    from hedge.visualization import SiloVisualizer
    from hedge.models.em import MaxwellOperator

    vis = SiloVisualizer(discr)

    from pyrticle.cloud import PicMethod
    from pyrticle.deposition.shape import ShapeFunctionDepositor
    method = PicMethod(discr, units, 
            ShapeFunctionDepositor(),
            pusher(),
            3, 3, debug=set(["verbose_vis"]))

    e, h = setup.fields(discr)
    b = units.MU0 * h

    init_positions = setup.positions(0)
    init_velocities = setup.velocities(0)

    nparticles = len(init_positions)

    state = method.make_state()
    method.add_particles(state,
            zip(init_positions, init_velocities, 
                nparticles * [setup.charge],
                nparticles  * [units.EL_MASS],
                ),
            nparticles)

    final_time = setup.final_time()
    nsteps = setup.nsteps()
    dt = final_time/nsteps

    # timestepping ------------------------------------------------------------
    from hedge.models.em import MaxwellOperator
    max_op = MaxwellOperator(
            epsilon=units.EPSILON0, 
            mu=units.MU0, 
            flux_type=1)

    fields = max_op.assemble_eh(e, h)

    from pyrticle.cloud import \
            FieldToParticleRhsCalculator, \
            ParticleRhsCalculator
    p_rhs_calculator = ParticleRhsCalculator(method, max_op)
    f2p_rhs_calculator = FieldToParticleRhsCalculator(method, max_op)

    def rhs(t, ts_state):
        return (p_rhs_calculator(t, lambda: fields, lambda: ts_state.state)
                + f2p_rhs_calculator(t, lambda: fields, lambda: ts_state.state))

    stepper = LSRK4TimeStepper()
    t = 0

    bbox = discr.mesh.bounding_box()
    z_period = bbox[1][2] - bbox[0][2]

    def check_result():
        from hedge.tools import cross

        deriv_dt = 1e-12

        dim = discr.dimensions
        true_x = setup.positions(t)
        true_v = setup.velocities(t)
        true_f = [(p2-p1)/(2*deriv_dt)
                for p1, p2 in zip(setup.momenta(t-deriv_dt), setup.momenta(t+deriv_dt))]

        state = ts_state.state

        from pyrticle.tools import NumberShiftableVector
        vis_info = state.vis_listener.particle_vis_map
        sim_x = state.positions
        sim_v = method.velocities(state)
        sim_f = NumberShiftableVector.unwrap(
                vis_info["mag_force"] + vis_info["el_force"])
        sim_el_f = NumberShiftableVector.unwrap(vis_info["el_force"])
        sim_mag_f = NumberShiftableVector.unwrap(vis_info["mag_force"])

        local_e = setup.e()
        local_b = units.MU0 * setup.h()

        x_err = 0
        v_err = 0
        f_err = 0

        for i in range(len(state)):
            #real_f = numpy.array(cross(sim_v, setup.charge*local_b)) + setup.charge*local_e

            my_true_x = true_x[i]
            my_true_x[2] = my_true_x[2] % z_period
            if False and i == 0:
                #print "particle %d" % i
                print "pos:", la.norm(true_x[i]-sim_x[i])/la.norm(true_x[i])
                #print "vel:", la.norm(true_v[i]-sim_v[i])/la.norm(true_v[i])
                #print "force:", la.norm(true_f[i]-sim_f[i])/la.norm(true_f[i])
                print "pos:", true_x[i], sim_x[i]
                #print "vel:", true_v[i], sim_v[i]
                #print "force:", true_f[i], sim_f[i]
                #print "forces%d:..." % i, sim_el_f[i], sim_mag_f[i]
                #print "acc%d:" % i, la.norm(a-sim_a)
                #u = numpy.vstack((v, sim_v, f, sim_f, real_f))
                #print "acc%d:\n%s" % (i, u)
                #raw_input()

            def rel_err(sim, true):
                return la.norm(true-sim)/la.norm(true)

            x_err = max(x_err, rel_err(sim_x[i], my_true_x))
            v_err = max(v_err, rel_err(sim_v[i], true_v[i]))
            f_err = max(f_err, rel_err(sim_f[i], true_f[i]))

        return x_err, v_err, f_err

    # make sure verbose-vis fields are filled
    from pyrticle.cloud import TimesteppablePicState
    ts_state = TimesteppablePicState(method, state)
    del state

    rhs(t, ts_state)

    errors = (0, 0, 0)

    for step in xrange(nsteps):
        if step % int(setup.nsteps()/300) == 0:
            errors = tuple(
                    max(old_err, new_err) 
                    for old_err, new_err in zip(errors, check_result()))

            if visualize:
                visf = vis.make_file("%s-%04d" % (casename, step))

                method.add_to_vis(vis, visf, ts_state.state, time=t, step=step)

                if True:
                    vis.add_data(visf, [ ("e", e), ("h", h), ],
                            time=t, step=step)
                else:
                    vis.add_data(visf, [], time=t, step=step)
                visf.close()

        method.upkeep(ts_state.state)

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

        t += dt

    assert errors[0] < 2e-12, casename+"-pos"
    assert errors[1] < 2e-13, casename+"-vel"
    assert errors[2] < 2e-4, casename+"-acc"

    vis.close()
Exemplo n.º 24
0
def check_time_harmonic_solution(discr, mode, c_sol):
    from hedge.discretization import bind_nabla, bind_mass_matrix
    from hedge.visualization import SiloVisualizer
    from hedge.silo import SiloFile
    from hedge.tools import dot, cross
    from hedge.silo import DB_VARTYPE_VECTOR

    def curl(field):
        return cross(nabla, field)

    vis = SiloVisualizer(discr)

    nabla = bind_nabla(discr)
    mass = bind_mass_matrix(discr)

    def rel_l2_error(err, base):
        def l2_norm(field):
            return sqrt(dot(field, mass * field))

        base_l2 = l2_norm(base)
        err_l2 = l2_norm(err)
        if base_l2 == 0:
            if err_l2 == 0:
                return 0.
            else:
                return float("inf")
        else:
            return err_l2 / base_l2

    dt = 0.1

    for step in range(10):
        t = step * dt
        mode.set_time(t)
        fields = discr.interpolate_volume_function(c_sol)

        er = fields[0:3]
        hr = fields[3:6]
        ei = fields[6:9]
        hi = fields[9:12]

        silo = SiloFile("em-complex-%04d.silo" % step)
        vis.add_to_silo(silo,
                        vectors=[
                            ("curl_er", curl(er)),
                            ("om_hi", -mode.mu * mode.omega * hi),
                            ("curl_hr", curl(hr)),
                            ("om_ei", mode.epsilon * mode.omega * hi),
                        ],
                        expressions=[
                            ("diff_er", "curl_er-om_hi", DB_VARTYPE_VECTOR),
                            ("diff_hr", "curl_hr-om_ei", DB_VARTYPE_VECTOR),
                        ],
                        write_coarse_mesh=True,
                        time=t,
                        step=step)

        er_res = curl(er) + mode.mu * mode.omega * hi
        ei_res = curl(ei) - mode.mu * mode.omega * hr
        hr_res = curl(hr) - mode.epsilon * mode.omega * ei
        hi_res = curl(hi) + mode.epsilon * mode.omega * er

        print "time=%f, rel l2 residual in Re[E]=%g\tIm[E]=%g\tRe[H]=%g\tIm[H]=%g" % (
            t,
            rel_l2_error(er_res, er),
            rel_l2_error(ei_res, ei),
            rel_l2_error(hr_res, hr),
            rel_l2_error(hi_res, hi),
        )
Exemplo n.º 25
0
def main():
    from hedge.backends import guess_run_context
    rcon = guess_run_context(["cuda"])

    if rcon.is_head_rank:
        mesh = make_boxmesh()
        #from hedge.mesh import make_rect_mesh
        #mesh = make_rect_mesh(
        #       boundary_tagger=lambda fvi, el, fn, all_v: ["inflow"])
        mesh_data = rcon.distribute_mesh(mesh)
    else:
        mesh_data = rcon.receive_mesh()

    for order in [3]:
        from pytools import add_python_path_relative_to_script
        add_python_path_relative_to_script("..")

        from gas_dynamics_initials import UniformMachFlow
        box = UniformMachFlow(angle_of_attack=0)

        from hedge.models.gas_dynamics import GasDynamicsOperator
        op = GasDynamicsOperator(dimensions=3,
                gamma=box.gamma, mu=box.mu,
                prandtl=box.prandtl, spec_gas_const=box.spec_gas_const,
                bc_inflow=box, bc_outflow=box, bc_noslip=box,
                inflow_tag="inflow", outflow_tag="outflow", noslip_tag="noslip")

        discr = rcon.make_discretization(mesh_data, order=order,
                        debug=[
                            #"cuda_no_plan",
                            #"cuda_dump_kernels",
                            #"dump_dataflow_graph",
                            #"dump_optemplate_stages",
                            #"dump_dataflow_graph",
                            #"print_op_code",
                            "cuda_no_plan_el_local",
                            ],
                        default_scalar_type=numpy.float32,
                        tune_for=op.op_template())

        from hedge.visualization import SiloVisualizer, VtkVisualizer  # noqa
        #vis = VtkVisualizer(discr, rcon, "shearflow-%d" % order)
        vis = SiloVisualizer(discr, rcon)

        fields = box.volume_interpolant(0, discr)

        navierstokes_ex = op.bind(discr)

        max_eigval = [0]

        def rhs(t, q):
            ode_rhs, speed = navierstokes_ex(t, q)
            max_eigval[0] = speed
            return ode_rhs

        rhs(0, fields)

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

        from hedge.timestep import RK4TimeStepper
        stepper = RK4TimeStepper()

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

        logmgr = LogManager("navierstokes-%d.dat" % order, "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"])

        from pytools.log import LogQuantity

        class ChangeSinceLastStep(LogQuantity):
            """Records the change of a variable between a time step and the previous
               one"""

            def __init__(self, name="change"):
                LogQuantity.__init__(self, name, "1", "Change since last time step")

                self.old_fields = 0

            def __call__(self):
                result = discr.norm(fields - self.old_fields)
                self.old_fields = fields
                return result

        logmgr.add_quantity(ChangeSinceLastStep())

        # timestep loop -------------------------------------------------------
        try:
            from hedge.timestep import times_and_steps
            step_it = times_and_steps(
                    final_time=200,
                    #max_steps=500,
                    logmgr=logmgr,
                    max_dt_getter=lambda t: op.estimate_timestep(discr,
                        stepper=stepper, t=t, max_eigenvalue=max_eigval[0]))

            for step, t, dt in step_it:
                if step % 200 == 0:
                #if False:
                    visf = vis.make_file("box-%d-%06d" % (order, step))

                    #rhs_fields = rhs(t, fields)

                    vis.add_data(visf,
                            [
                                ("rho", discr.convert_volume(
                                    op.rho(fields), kind="numpy")),
                                ("e", discr.convert_volume(
                                    op.e(fields), kind="numpy")),
                                ("rho_u", discr.convert_volume(
                                    op.rho_u(fields), kind="numpy")),
                                ("u", discr.convert_volume(
                                    op.u(fields), kind="numpy")),

                                # ("rhs_rho", discr.convert_volume(
                                #     op.rho(rhs_fields), kind="numpy")),
                                # ("rhs_e", discr.convert_volume(
                                #     op.e(rhs_fields), kind="numpy")),
                                # ("rhs_rho_u", discr.convert_volume(
                                #     op.rho_u(rhs_fields), kind="numpy")),
                                ],
                            expressions=[
                                ("p", "(0.4)*(e- 0.5*(rho_u*u))"),
                                ],
                            time=t, step=step
                            )
                    visf.close()

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

        finally:
            vis.close()
            logmgr.save()
            discr.close()
Exemplo n.º 26
0
    def initialize(self, method):
        Depositor.initialize(self, method)

        backend_class = getattr(_internal, "GridFindDepositor" 
                + method.get_dimensionality_suffix())
        backend = self.backend = backend_class(method.mesh_data)

        discr = method.discretization

        grid_node_num_to_nodes = {}

        if self.brick_generator is None:
            bbox_min, bbox_max = discr.mesh.bounding_box()
            max_bbox_size = max(bbox_max-bbox_min)
            self.brick_generator = SingleBrickGenerator(
                    mesh_margin=1e-3*max_bbox_size,
                    overresolve=0.2)

        from pyrticle._internal import Brick
        for i, (stepwidths, origin, dims) in enumerate(
                self.brick_generator(discr)):
            backend.bricks.append(
                    Brick(i, backend.grid_node_count(), stepwidths, origin, dims))

        from pyrticle._internal import BoxFloat
        for eg in discr.element_groups:
            ldis = eg.local_discretization

            for el in eg.members:
                el_bbox = BoxFloat(*el.bounding_box(discr.mesh.points))
                el_slice = discr.find_el_range(el.id)

                for brk in backend.bricks:
                    if brk.bounding_box().intersect(el_bbox).is_empty():
                        continue

                    for node_num in range(el_slice.start, el_slice.stop):
                        try:
                            cell_number = brk.which_cell(
                                        discr.nodes[node_num])
                        except ValueError:
                            pass
                        else:
                            grid_node_num_to_nodes.setdefault(
                                    brk.index(cell_number), []).append(node_num)

        from pytools import flatten
        unassigned_nodes = (set(xrange(len(discr))) 
                - set(flatten(grid_node_num_to_nodes.itervalues())))

        if unassigned_nodes:
            raise RuntimeError("dep_grid_find: unassigned mesh nodes found. "
                    "you should specify a mesh_margin when generating "
                    "bricks")

        usecounts = numpy.zeros(
                (backend.grid_node_count(),))
        for gnn in xrange(backend.grid_node_count()):
            grid_nodes = grid_node_num_to_nodes.get(gnn, [])
            usecounts[gnn] = len(grid_nodes)
            backend.node_number_list_starts.append(len(backend.node_number_lists))
            backend.node_number_lists.extend(grid_nodes)
        backend.node_number_list_starts.append(len(backend.node_number_lists))

        if "depositor" in method.debug:
            from hedge.visualization import SiloVisualizer
            vis = SiloVisualizer(discr)
            visf = vis.make_file("grid-find-debug")
            vis.add_data(visf, [])
            self.visualize_grid_quantities(visf, [
                    ("usecounts", usecounts)
                    ])
            visf.close()

            if "interactive" in cloud.debug:
                from matplotlib.pylab import hist, show
                hist(usecounts, bins=20)
                show()
Exemplo n.º 27
0
def compute_initial_condition(rcon,
                              discr,
                              method,
                              state,
                              maxwell_op,
                              potential_bc,
                              force_zero=False):
    from hedge.models.poisson import PoissonOperator
    from hedge.mesh import TAG_ALL, TAG_NONE
    from hedge.data import ConstantGivenFunction, GivenVolumeInterpolant

    def rel_l2_error(field, true):
        from hedge.tools import relative_error
        return relative_error(discr.norm(field - true), discr.norm(true))

    mean_beta = method.mean_beta(state)
    gamma = method.units.gamma_from_beta(mean_beta)

    # see doc/notes.tm for derivation of IC

    def make_scaling_matrix(beta_scale, other_scale):
        if la.norm(mean_beta) < 1e-10:
            return other_scale * numpy.eye(discr.dimensions)
        else:
            beta_unit = mean_beta / la.norm(mean_beta)
            return (
                other_scale * numpy.identity(discr.dimensions) +
                (beta_scale - other_scale) * numpy.outer(beta_unit, beta_unit))

    poisson_op = PoissonOperator(discr.dimensions,
                                 diffusion_tensor=make_scaling_matrix(
                                     1 / gamma**2, 1),
                                 dirichlet_tag=TAG_ALL,
                                 neumann_tag=TAG_NONE,
                                 dirichlet_bc=potential_bc)

    rho_prime = method.deposit_rho(state)
    rho_tilde = rho_prime / gamma

    bound_poisson = poisson_op.bind(discr)
    if force_zero:
        phi_tilde = discr.volume_zeros()
    else:
        from hedge.iterative import parallel_cg
        phi_tilde = -parallel_cg(
            rcon,
            -bound_poisson,
            bound_poisson.prepare_rhs(rho_tilde / maxwell_op.epsilon),
            debug=40 if "poisson" in method.debug else False,
            tol=1e-10)

    from hedge.tools import ptwise_dot
    from hedge.models.nd_calculus import GradientOperator
    e_tilde = ptwise_dot(
        2, 1, make_scaling_matrix(1 / gamma, 1),
        GradientOperator(discr.dimensions).bind(discr)(phi_tilde))
    e_prime = ptwise_dot(2, 1, make_scaling_matrix(1, gamma), e_tilde)

    from pyrticle.tools import make_cross_product
    v_e_to_h_cross = make_cross_product(method, maxwell_op, "v", "e", "h")
    h_prime = (1 / maxwell_op.mu) * gamma / maxwell_op.c * v_e_to_h_cross(
        mean_beta, e_tilde)

    if "ic" in method.debug:
        deposited_charge = discr.integral(rho_prime)

        real_charge = numpy.sum(state.charges)
        print "charge: supposed=%g deposited=%g error=%g %%" % (
            real_charge, deposited_charge,
            100 * abs(deposited_charge - real_charge) / abs(real_charge))

        from hedge.models.nd_calculus import DivergenceOperator

        bound_div_op = DivergenceOperator(discr.dimensions).bind(discr)

        d_tilde = maxwell_op.epsilon * e_tilde
        d_prime = maxwell_op.epsilon * e_prime

        #divD_prime_ldg = bound_poisson.div(d_prime)
        #divD_prime_ldg2 = bound_poisson.div(d_prime, maxwell_op.epsilon*gamma*phi_tilde)
        from hedge.optemplate import InverseMassOperator
        divD_prime_ldg3 = maxwell_op.epsilon*\
                (InverseMassOperator().apply(discr, bound_poisson.op(gamma*phi_tilde)))
        divD_prime_central = bound_div_op(d_prime)

        print "l2 div D_prime error central: %g" % \
                rel_l2_error(divD_prime_central, rho_prime)
        #print "l2 div D_prime error ldg: %g" % \
        #rel_l2_error(divD_prime_ldg, rho_prime)
        #print "l2 div D_prime error ldg with phi: %g" % \
        #rel_l2_error(divD_prime_ldg2, rho_prime)
        print "l2 div D_prime error ldg with phi 3: %g" % \
                rel_l2_error(divD_prime_ldg3, rho_prime)

        if "vis_files" in method.debug:
            from hedge.visualization import SiloVisualizer
            vis = SiloVisualizer(discr)
            visf = vis.make_file("ic")
            vis.add_data(
                visf,
                [
                    ("phi_moving", phi_tilde),
                    ("rho_moving", rho_tilde),
                    ("e_moving", e_tilde),
                    ("rho_lab", rho_prime),
                    #("divD_lab_ldg", divD_prime_ldg),
                    #("divD_lab_ldg2", divD_prime_ldg2),
                    #("divD_lab_ldg3", divD_prime_ldg3),
                    ("divD_lab_central", divD_prime_central),
                    ("e_lab", e_prime),
                    ("h_lab", h_prime),
                ],
            )
            method.add_to_vis(vis, visf, state)
            visf.close()

    return maxwell_op.assemble_fields(e=e_prime, h=h_prime, discr=discr)
Exemplo n.º 28
0
def check_time_harmonic_solution(discr, mode, c_sol):
    from hedge.discretization import bind_nabla, bind_mass_matrix
    from hedge.visualization import SiloVisualizer
    from hedge.silo import SiloFile
    from hedge.tools import dot, cross
    from hedge.silo import DB_VARTYPE_VECTOR

    def curl(field):
        return cross(nabla, field)

    vis = SiloVisualizer(discr)

    nabla = bind_nabla(discr)
    mass = bind_mass_matrix(discr)

    def rel_l2_error(err, base):
        def l2_norm(field):
            return sqrt(dot(field, mass*field))

        base_l2 = l2_norm(base)
        err_l2 = l2_norm(err)
        if base_l2 == 0:
            if err_l2 == 0:
                return 0.
            else:
                return float("inf")
        else:
            return err_l2/base_l2

    dt = 0.1

    for step in range(10):
        t = step*dt
        mode.set_time(t)
        fields = discr.interpolate_volume_function(c_sol)

        er = fields[0:3]
        hr = fields[3:6]
        ei = fields[6:9]
        hi = fields[9:12]

        silo = SiloFile("em-complex-%04d.silo" % step)
        vis.add_to_silo(silo,
                vectors=[
                    ("curl_er", curl(er)), 
                    ("om_hi", -mode.mu*mode.omega*hi), 
                    ("curl_hr", curl(hr)), 
                    ("om_ei", mode.epsilon*mode.omega*hi), 
                    ],
                expressions=[
                ("diff_er", "curl_er-om_hi", DB_VARTYPE_VECTOR),
                ("diff_hr", "curl_hr-om_ei", DB_VARTYPE_VECTOR),
                ],
                write_coarse_mesh=True,
                time=t, step=step
                )

        er_res = curl(er) + mode.mu     *mode.omega*hi
        ei_res = curl(ei) - mode.mu     *mode.omega*hr
        hr_res = curl(hr) - mode.epsilon*mode.omega*ei
        hi_res = curl(hi) + mode.epsilon*mode.omega*er

        print "time=%f, rel l2 residual in Re[E]=%g\tIm[E]=%g\tRe[H]=%g\tIm[H]=%g" % (
                t,
                rel_l2_error(er_res, er),
                rel_l2_error(ei_res, ei),
                rel_l2_error(hr_res, hr),
                rel_l2_error(hi_res, hi),
                )
Exemplo n.º 29
0
def run_setup(units, casename, setup, discr, pusher, visualize=False):
    from hedge.timestep.runge_kutta import LSRK4TimeStepper
    from hedge.visualization import SiloVisualizer
    from hedge.models.em import MaxwellOperator

    vis = SiloVisualizer(discr)

    from pyrticle.cloud import PicMethod
    from pyrticle.deposition.shape import ShapeFunctionDepositor
    method = PicMethod(discr,
                       units,
                       ShapeFunctionDepositor(),
                       pusher(),
                       3,
                       3,
                       debug=set(["verbose_vis"]))

    e, h = setup.fields(discr)
    b = units.MU0 * h

    init_positions = setup.positions(0)
    init_velocities = setup.velocities(0)

    nparticles = len(init_positions)

    state = method.make_state()
    method.add_particles(
        state,
        zip(
            init_positions,
            init_velocities,
            nparticles * [setup.charge],
            nparticles * [units.EL_MASS],
        ), nparticles)

    final_time = setup.final_time()
    nsteps = setup.nsteps()
    dt = final_time / nsteps

    # timestepping ------------------------------------------------------------
    from hedge.models.em import MaxwellOperator
    max_op = MaxwellOperator(epsilon=units.EPSILON0, mu=units.MU0, flux_type=1)

    fields = max_op.assemble_eh(e, h)

    from pyrticle.cloud import \
            FieldToParticleRhsCalculator, \
            ParticleRhsCalculator
    p_rhs_calculator = ParticleRhsCalculator(method, max_op)
    f2p_rhs_calculator = FieldToParticleRhsCalculator(method, max_op)

    def rhs(t, ts_state):
        return (p_rhs_calculator(t, lambda: fields, lambda: ts_state.state) +
                f2p_rhs_calculator(t, lambda: fields, lambda: ts_state.state))

    stepper = LSRK4TimeStepper()
    t = 0

    bbox = discr.mesh.bounding_box()
    z_period = bbox[1][2] - bbox[0][2]

    def check_result():
        from hedge.tools import cross

        deriv_dt = 1e-12

        dim = discr.dimensions
        true_x = setup.positions(t)
        true_v = setup.velocities(t)
        true_f = [(p2 - p1) / (2 * deriv_dt) for p1, p2 in zip(
            setup.momenta(t - deriv_dt), setup.momenta(t + deriv_dt))]

        state = ts_state.state

        from pyrticle.tools import NumberShiftableVector
        vis_info = state.vis_listener.particle_vis_map
        sim_x = state.positions
        sim_v = method.velocities(state)
        sim_f = NumberShiftableVector.unwrap(vis_info["mag_force"] +
                                             vis_info["el_force"])
        sim_el_f = NumberShiftableVector.unwrap(vis_info["el_force"])
        sim_mag_f = NumberShiftableVector.unwrap(vis_info["mag_force"])

        local_e = setup.e()
        local_b = units.MU0 * setup.h()

        x_err = 0
        v_err = 0
        f_err = 0

        for i in range(len(state)):
            #real_f = numpy.array(cross(sim_v, setup.charge*local_b)) + setup.charge*local_e

            my_true_x = true_x[i]
            my_true_x[2] = my_true_x[2] % z_period
            if False and i == 0:
                #print "particle %d" % i
                print "pos:", la.norm(true_x[i] - sim_x[i]) / la.norm(
                    true_x[i])
                #print "vel:", la.norm(true_v[i]-sim_v[i])/la.norm(true_v[i])
                #print "force:", la.norm(true_f[i]-sim_f[i])/la.norm(true_f[i])
                print "pos:", true_x[i], sim_x[i]
                #print "vel:", true_v[i], sim_v[i]
                #print "force:", true_f[i], sim_f[i]
                #print "forces%d:..." % i, sim_el_f[i], sim_mag_f[i]
                #print "acc%d:" % i, la.norm(a-sim_a)
                #u = numpy.vstack((v, sim_v, f, sim_f, real_f))
                #print "acc%d:\n%s" % (i, u)
                #raw_input()

            def rel_err(sim, true):
                return la.norm(true - sim) / la.norm(true)

            x_err = max(x_err, rel_err(sim_x[i], my_true_x))
            v_err = max(v_err, rel_err(sim_v[i], true_v[i]))
            f_err = max(f_err, rel_err(sim_f[i], true_f[i]))

        return x_err, v_err, f_err

    # make sure verbose-vis fields are filled
    from pyrticle.cloud import TimesteppablePicState
    ts_state = TimesteppablePicState(method, state)
    del state

    rhs(t, ts_state)

    errors = (0, 0, 0)

    for step in xrange(nsteps):
        if step % int(setup.nsteps() / 300) == 0:
            errors = tuple(
                max(old_err, new_err)
                for old_err, new_err in zip(errors, check_result()))

            if visualize:
                visf = vis.make_file("%s-%04d" % (casename, step))

                method.add_to_vis(vis, visf, ts_state.state, time=t, step=step)

                if True:
                    vis.add_data(visf, [
                        ("e", e),
                        ("h", h),
                    ],
                                 time=t,
                                 step=step)
                else:
                    vis.add_data(visf, [], time=t, step=step)
                visf.close()

        method.upkeep(ts_state.state)

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

        t += dt

    assert errors[0] < 2e-12, casename + "-pos"
    assert errors[1] < 2e-13, casename + "-vel"
    assert errors[2] < 2e-4, casename + "-acc"

    vis.close()
Exemplo n.º 30
0
def main():
    from hedge.backends import guess_run_context
    rcon = guess_run_context(
    #["cuda"]
    )

    from hedge.tools import EOCRecorder, to_obj_array
    eoc_rec = EOCRecorder()

    def boundary_tagger(vertices, el, face_nr, all_v):
        return ["inflow"]

    if rcon.is_head_rank:
        from hedge.mesh import make_rect_mesh, \
                               make_centered_regular_rect_mesh
        #mesh = make_rect_mesh((0,0), (10,1), max_area=0.01)
        refine = 1
        mesh = make_centered_regular_rect_mesh((0,0), (10,1), n=(20,4),
                            #periodicity=(True, False),
                            post_refine_factor=refine,
                            boundary_tagger=boundary_tagger)
        mesh_data = rcon.distribute_mesh(mesh)
    else:
        mesh_data = rcon.receive_mesh()

    for order in [3]:
        discr = rcon.make_discretization(mesh_data, order=order,
                        default_scalar_type=numpy.float64)

        from hedge.visualization import SiloVisualizer, VtkVisualizer
        #vis = VtkVisualizer(discr, rcon, "shearflow-%d" % order)
        vis = SiloVisualizer(discr, rcon)

        shearflow = SteadyShearFlow()
        fields = shearflow.volume_interpolant(0, discr)
        gamma, mu, prandtl, spec_gas_const = shearflow.properties()

        from hedge.models.gas_dynamics import GasDynamicsOperator
        op = GasDynamicsOperator(dimensions=2, gamma=gamma, mu=mu,
                prandtl=prandtl, spec_gas_const=spec_gas_const,
                bc_inflow=shearflow, bc_outflow=shearflow, bc_noslip=shearflow,
                inflow_tag="inflow", outflow_tag="outflow", noslip_tag="noslip")

        navierstokes_ex = op.bind(discr)

        max_eigval = [0]
        def rhs(t, q):
            ode_rhs, speed = navierstokes_ex(t, q)
            max_eigval[0] = speed
            return ode_rhs

        # needed to get first estimate of maximum eigenvalue
        rhs(0, fields)

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

        from hedge.timestep import RK4TimeStepper
        stepper = RK4TimeStepper()

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

        logmgr = LogManager("navierstokes-cpu-%d-%d.dat" % (order, refine),
                            "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 -------------------------------------------------------
        try:
            from hedge.timestep import times_and_steps
            step_it = times_and_steps(
                    final_time=0.3,
                    #max_steps=500,
                    logmgr=logmgr,
                    max_dt_getter=lambda t: op.estimate_timestep(discr,
                        stepper=stepper, t=t, max_eigenvalue=max_eigval[0]))

            for step, t, dt in step_it:
                if step % 10 == 0:
                #if False:
                    visf = vis.make_file("shearflow-%d-%04d" % (order, step))

                    #true_fields = shearflow.volume_interpolant(t, discr)

                    from pyvisfile.silo import DB_VARTYPE_VECTOR
                    vis.add_data(visf,
                            [
                                ("rho", discr.convert_volume(op.rho(fields), kind="numpy")),
                                ("e", discr.convert_volume(op.e(fields), kind="numpy")),
                                ("rho_u", discr.convert_volume(op.rho_u(fields), kind="numpy")),
                                ("u", discr.convert_volume(op.u(fields), kind="numpy")),

                                #("true_rho", discr.convert_volume(op.rho(true_fields), kind="numpy")),
                                #("true_e", discr.convert_volume(op.e(true_fields), kind="numpy")),
                                #("true_rho_u", discr.convert_volume(op.rho_u(true_fields), kind="numpy")),
                                #("true_u", discr.convert_volume(op.u(true_fields), kind="numpy")),
                                ],
                            expressions=[
                                #("diff_rho", "rho-true_rho"),
                                #("diff_e", "e-true_e"),
                                #("diff_rho_u", "rho_u-true_rho_u", DB_VARTYPE_VECTOR),

                                ("p", "0.4*(e- 0.5*(rho_u*u))"),
                                ],
                            time=t, step=step
                            )
                    visf.close()

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

            true_fields = shearflow.volume_interpolant(t, discr)
            l2_error = discr.norm(op.u(fields)-op.u(true_fields))
            eoc_rec.add_data_point(order, l2_error)
            print
            print eoc_rec.pretty_print("P.Deg.", "L2 Error")

            logmgr.set_constant("l2_error", l2_error)

        finally:
            vis.close()
            logmgr.save()
            discr.close()
Exemplo n.º 31
0
    def prepare_with_pointwise_projection_and_enlargement(self):
        tolerance_bound = 1.5

        discr = self.method.discretization
        backend = self.backend

        backend.elements_on_grid.reserve(
            sum(len(eg.members) for eg in discr.element_groups))

        cond_claims = 0
        min_s_values = []
        max_s_values = []
        cond_s_values = []

        from hedge.discretization import Projector, Discretization
        fine_discr = Discretization(discr.mesh, order=8)
        proj = Projector(discr, fine_discr)

        from hedge.visualization import SiloVisualizer
        vis = SiloVisualizer(fine_discr)

        # Iterate over all elements
        for eg in discr.element_groups:
            ldis = eg.local_discretization

            for el in eg.members:
                # If the structured Vandermonde matrix is singular,
                # enlarge the element tolerance

                my_tolerance = self.el_tolerance

                orig_point_count = None

                while True:
                    eog, points = self.find_points_in_element(el, my_tolerance)
                    if orig_point_count is None:
                        orig_point_count = len(points)

                    scaled_vdm = self.scaled_vandermonde(
                        el, eog, points, ldis.basis_functions())

                    bad_vdm = len(points) < ldis.node_count()
                    if not bad_vdm:
                        try:
                            u, s, vt = svd = la.svd(scaled_vdm)
                            thresh = (numpy.finfo(float).eps *
                                      max(scaled_vdm.shape) * s[0])
                            zero_indices = [
                                i for i, si in enumerate(s) if abs(si) < thresh
                            ]
                            bad_vdm = bool(zero_indices)
                        except la.LinAlgError:
                            bad_vdm = True

                    if not bad_vdm:
                        break

                    my_tolerance += 0.03
                    if my_tolerance >= tolerance_bound:
                        from warnings import warn
                        warn("rec_grid: could not regularize structured "
                             "vandermonde matrix for el #%d by enlargement" %
                             el.id)
                        break

                #from pytools import average
                #print average(eog.weight_factors), min(s)
                #raw_input()

                if my_tolerance > self.el_tolerance:
                    print "element %d: #nodes=%d, orig #sgridpt=%d, extra tol=%g, #extra points=%d" % (
                        el.id, ldis.node_count(),
                        orig_point_count, my_tolerance - self.el_tolerance,
                        len(points) - orig_point_count)
                    cond_claims += len(points) - orig_point_count
                min_s_values.append(min(s))
                max_s_values.append(max(s))
                cond_s_values.append(max(s) / min(s))

                if max(s) / min(s) > 1e2:
                    for i in range(len(s)):
                        if s[0] / s[i] > 1e2:
                            zeroed_mode = vt[i]
                            zeroed_mode_nodal = numpy.dot(
                                ldis.vandermonde(), zeroed_mode)
                            print el.id, i, s[0] / s[i]
                            fromvec = discr.volume_zeros()
                            fromvec[discr.find_el_range(
                                el.id)] = zeroed_mode_nodal

                            gn = list(eog.grid_nodes)
                            assert len(gn) == len(u[i])

                            tovec = numpy.zeros(
                                (backend.grid_node_count_with_extra(), ),
                                dtype=float)
                            tovec[gn] = s[i] * u[i]

                            usevec = numpy.zeros(
                                (backend.grid_node_count_with_extra(), ),
                                dtype=float)
                            usevec[gn] = 1

                            visf = vis.make_file("nulled-%04d%02d" %
                                                 (el.id, i))
                            vis.add_data(visf, [("meshmode", proj(fromvec))],
                                         expressions=[
                                             ("absmesh", "abs(meshmode)"),
                                             ("absgrid", "abs(gridmode)"),
                                         ])
                            self.visualize_grid_quantities(
                                visf,
                                [
                                    ("gridmode", tovec),
                                    ("usevec", usevec),
                                ],
                            )
                            visf.close()
                    #print s
                    #raw_input()

                self.make_pointwise_interpolation_matrix(
                    eog, eg, el, ldis, svd, scaled_vdm)

                backend.elements_on_grid.append(eog)

        # we don't need no stinkin' extra points
        backend.extra_point_brick_starts.extend([0] *
                                                (len(backend.bricks) + 1))

        # print some statistics
        self.generate_point_statistics(cond_claims)
Exemplo n.º 32
0
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
Exemplo n.º 33
0
def main(write_output=True):
    from hedge.backends import guess_run_context
    rcon = guess_run_context(
                    #["cuda"]
                    )

    gamma = 1.4

    # at A=1 we have case of isentropic vortex, source terms 
    # arise for other values
    densityA = 2.0

    from hedge.tools import EOCRecorder, to_obj_array
    eoc_rec = EOCRecorder()

    if rcon.is_head_rank:
        from hedge.mesh import \
                make_rect_mesh, \
                make_centered_regular_rect_mesh

        refine = 1
        mesh = make_centered_regular_rect_mesh((0,-5), (10,5), n=(9,9),
                post_refine_factor=refine)
        mesh_data = rcon.distribute_mesh(mesh)
    else:
        mesh_data = rcon.receive_mesh()

    for order in [4,5]:
        discr = rcon.make_discretization(mesh_data, order=order,
                        debug=[#"cuda_no_plan",
                        #"print_op_code"
                        ],
                        default_scalar_type=numpy.float64)

        from hedge.visualization import SiloVisualizer, VtkVisualizer
        #vis = VtkVisualizer(discr, rcon, "vortex-%d" % order)
        vis = SiloVisualizer(discr, rcon)

        vortex = Vortex(beta=5, gamma=gamma,
                center=[5,0],
                velocity=[1,0], densityA=densityA)
        fields = vortex.volume_interpolant(0, discr)
        sources=SourceTerms(beta=5, gamma=gamma,
                center=[5,0],
                velocity=[1,0], densityA=densityA)

        from hedge.models.gas_dynamics import (
                GasDynamicsOperator, GammaLawEOS)
        from hedge.mesh import TAG_ALL

        op = GasDynamicsOperator(dimensions=2,
                mu=0.0, prandtl=0.72, spec_gas_const=287.1, 
                equation_of_state=GammaLawEOS(vortex.gamma),
                bc_inflow=vortex, bc_outflow=vortex, bc_noslip=vortex,
                inflow_tag=TAG_ALL, source=sources)

        euler_ex = op.bind(discr)

        max_eigval = [0]
        def rhs(t, q):
            ode_rhs, speed = euler_ex(t, q)
            max_eigval[0] = speed
            return ode_rhs
        rhs(0, fields)

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

        # limiter setup -------------------------------------------------------
        from hedge.models.gas_dynamics import SlopeLimiter1NEuler
        limiter = SlopeLimiter1NEuler(discr, gamma, 2, op)

        # time stepper --------------------------------------------------------
        from hedge.timestep import SSPRK3TimeStepper, RK4TimeStepper
        #stepper = SSPRK3TimeStepper(limiter=limiter)
        #stepper = SSPRK3TimeStepper()
        stepper = RK4TimeStepper()

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

        if write_output:
            log_file_name = "euler-%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)

        logmgr.add_watches(["step.max", "t_sim.max", "t_step.max"])

        # timestep loop -------------------------------------------------------
        t = 0

        #fields = limiter(fields)

        try:
            from hedge.timestep import times_and_steps
            step_it = times_and_steps(
                    final_time=.1,
                    #max_steps=500,
                    logmgr=logmgr,
                    max_dt_getter=lambda t: 0.4*op.estimate_timestep(discr,
                        stepper=stepper, t=t, max_eigenvalue=max_eigval[0]))

            for step, t, dt in step_it:
                if step % 1 == 0 and write_output:
                #if False:
                    visf = vis.make_file("vortex-%d-%04d" % (order, step))

                    true_fields = vortex.volume_interpolant(t, discr)

                    #rhs_fields = rhs(t, fields)

                    from pyvisfile.silo import DB_VARTYPE_VECTOR
                    vis.add_data(visf,
                            [
                                ("rho", discr.convert_volume(op.rho(fields), kind="numpy")),
                                ("e", discr.convert_volume(op.e(fields), kind="numpy")),
                                ("rho_u", discr.convert_volume(op.rho_u(fields), kind="numpy")),
                                ("u", discr.convert_volume(op.u(fields), kind="numpy")),

                                #("true_rho", discr.convert_volume(op.rho(true_fields), kind="numpy")),
                                #("true_e", discr.convert_volume(op.e(true_fields), kind="numpy")),
                                #("true_rho_u", discr.convert_volume(op.rho_u(true_fields), kind="numpy")),
                                #("true_u", discr.convert_volume(op.u(true_fields), kind="numpy")),

                                #("rhs_rho", discr.convert_volume(op.rho(rhs_fields), kind="numpy")),
                                #("rhs_e", discr.convert_volume(op.e(rhs_fields), kind="numpy")),
                                #("rhs_rho_u", discr.convert_volume(op.rho_u(rhs_fields), kind="numpy")),
                                ],
                            expressions=[
                                #("diff_rho", "rho-true_rho"),
                                #("diff_e", "e-true_e"),
                                #("diff_rho_u", "rho_u-true_rho_u", DB_VARTYPE_VECTOR),

                                ("p", "0.4*(e- 0.5*(rho_u*u))"),
                                ],
                            time=t, step=step
                            )
                    visf.close()

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

            true_fields = vortex.volume_interpolant(t, discr)
            l2_error = discr.norm(fields-true_fields)
            l2_error_rho = discr.norm(op.rho(fields)-op.rho(true_fields))
            l2_error_e = discr.norm(op.e(fields)-op.e(true_fields))
            l2_error_rhou = discr.norm(op.rho_u(fields)-op.rho_u(true_fields))
            l2_error_u = discr.norm(op.u(fields)-op.u(true_fields))

            eoc_rec.add_data_point(order, l2_error_rho)
            print
            print eoc_rec.pretty_print("P.Deg.", "L2 Error")

            logmgr.set_constant("l2_error", l2_error)
            logmgr.set_constant("l2_error_rho", l2_error_rho)
            logmgr.set_constant("l2_error_e", l2_error_e)
            logmgr.set_constant("l2_error_rhou", l2_error_rhou)
            logmgr.set_constant("l2_error_u", l2_error_u)
            logmgr.set_constant("refinement", refine)

        finally:
            if write_output:
                vis.close()

            logmgr.close()
            discr.close()
Exemplo n.º 34
0
def main():
    import logging
    logging.basicConfig(level=logging.INFO)

    from hedge.backends import guess_run_context
    rcon = guess_run_context()

    if rcon.is_head_rank:
        if True:
            mesh = make_squaremesh()
        else:
            from hedge.mesh import make_rect_mesh
            mesh = make_rect_mesh(
                boundary_tagger=lambda fvi, el, fn, all_v: ["inflow"],
                max_area=0.1)

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

    from pytools import add_python_path_relative_to_script
    add_python_path_relative_to_script(".")

    for order in [3]:
        from gas_dynamics_initials import UniformMachFlow
        square = UniformMachFlow(gaussian_pulse_at=numpy.array([-2, 2]),
                                 pulse_magnitude=0.003)

        from hedge.models.gas_dynamics import (GasDynamicsOperator,
                                               GammaLawEOS)

        op = GasDynamicsOperator(dimensions=2,
                                 equation_of_state=GammaLawEOS(square.gamma),
                                 mu=square.mu,
                                 prandtl=square.prandtl,
                                 spec_gas_const=square.spec_gas_const,
                                 bc_inflow=square,
                                 bc_outflow=square,
                                 bc_noslip=square,
                                 inflow_tag="inflow",
                                 outflow_tag="outflow",
                                 noslip_tag="noslip")

        discr = rcon.make_discretization(
            mesh_data,
            order=order,
            debug=[
                "cuda_no_plan",
                "cuda_dump_kernels",
                #"dump_dataflow_graph",
                #"dump_optemplate_stages",
                #"dump_dataflow_graph",
                #"dump_op_code"
                #"cuda_no_plan_el_local"
            ],
            default_scalar_type=numpy.float64,
            tune_for=op.op_template(),
            quad_min_degrees={
                "gasdyn_vol": 3 * order,
                "gasdyn_face": 3 * order,
            })

        from hedge.visualization import SiloVisualizer, VtkVisualizer
        #vis = VtkVisualizer(discr, rcon, "shearflow-%d" % order)
        vis = SiloVisualizer(discr, rcon)

        from hedge.timestep.runge_kutta import (LSRK4TimeStepper,
                                                ODE23TimeStepper,
                                                ODE45TimeStepper)
        from hedge.timestep.dumka3 import Dumka3TimeStepper
        #stepper = LSRK4TimeStepper(dtype=discr.default_scalar_type,
        #vector_primitive_factory=discr.get_vector_primitive_factory())

        stepper = ODE23TimeStepper(
            dtype=discr.default_scalar_type,
            rtol=1e-6,
            vector_primitive_factory=discr.get_vector_primitive_factory())
        # Dumka works kind of poorly
        #stepper = Dumka3TimeStepper(dtype=discr.default_scalar_type,
        #rtol=1e-7, pol_index=2,
        #vector_primitive_factory=discr.get_vector_primitive_factory())

        #from hedge.timestep.dumka3 import Dumka3TimeStepper
        #stepper = Dumka3TimeStepper(3, rtol=1e-7)

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

        logmgr = LogManager("cns-square-sp-%d.dat" % order, "w",
                            rcon.communicator)

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

        from pytools.log import LogQuantity

        class ChangeSinceLastStep(LogQuantity):
            """Records the change of a variable between a time step and the previous
               one"""
            def __init__(self, name="change"):
                LogQuantity.__init__(self, name, "1",
                                     "Change since last time step")

                self.old_fields = 0

            def __call__(self):
                result = discr.norm(fields - self.old_fields)
                self.old_fields = fields
                return result

        #logmgr.add_quantity(ChangeSinceLastStep())

        add_simulation_quantities(logmgr)
        logmgr.add_watches(["step.max", "t_sim.max", "t_step.max"])

        # filter setup ------------------------------------------------------------
        from hedge.discretization import Filter, ExponentialFilterResponseFunction
        mode_filter = Filter(
            discr,
            ExponentialFilterResponseFunction(min_amplification=0.95, order=6))

        # timestep loop -------------------------------------------------------
        fields = square.volume_interpolant(0, discr)

        navierstokes_ex = op.bind(discr)

        max_eigval = [0]

        def rhs(t, q):
            ode_rhs, speed = navierstokes_ex(t, q)
            max_eigval[0] = speed
            return ode_rhs

        rhs(0, fields)

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

        try:
            from hedge.timestep import times_and_steps
            step_it = times_and_steps(
                final_time=1000,
                #max_steps=500,
                logmgr=logmgr,
                max_dt_getter=lambda t: next_dt,
                taken_dt_getter=lambda: taken_dt)

            model_stepper = LSRK4TimeStepper()
            next_dt = op.estimate_timestep(discr,
                                           stepper=model_stepper,
                                           t=0,
                                           max_eigenvalue=max_eigval[0])

            for step, t, dt in step_it:
                #if (step % 10000 == 0): #and step < 950000) or (step % 500 == 0 and step > 950000):
                #if False:
                if step % 5 == 0:
                    visf = vis.make_file("square-%d-%06d" % (order, step))

                    #from pyvisfile.silo import DB_VARTYPE_VECTOR
                    vis.add_data(visf, [
                        ("rho",
                         discr.convert_volume(op.rho(fields), kind="numpy")),
                        ("e", discr.convert_volume(op.e(fields),
                                                   kind="numpy")),
                        ("rho_u",
                         discr.convert_volume(op.rho_u(fields), kind="numpy")),
                        ("u", discr.convert_volume(op.u(fields),
                                                   kind="numpy")),
                    ],
                                 expressions=[
                                     ("p", "(0.4)*(e- 0.5*(rho_u*u))"),
                                 ],
                                 time=t,
                                 step=step)
                    visf.close()

                if stepper.adaptive:
                    fields, t, taken_dt, next_dt = stepper(fields, t, dt, rhs)
                else:
                    taken_dt = dt
                    fields = stepper(fields, t, dt, rhs)
                    dt = op.estimate_timestep(discr,
                                              stepper=model_stepper,
                                              t=0,
                                              max_eigenvalue=max_eigval[0])

                #fields = mode_filter(fields)

        finally:
            vis.close()
            logmgr.save()
            discr.close()