Beispiel #1
0
def main(write_output=True):
    from hedge.data import GivenFunction, ConstantGivenFunction

    from hedge.backends import guess_run_context
    rcon = guess_run_context()

    dim = 2

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

    if dim == 2:
        if rcon.is_head_rank:
            from hedge.mesh.generator import make_disk_mesh
            mesh = make_disk_mesh(r=0.5, boundary_tagger=boundary_tagger,
                    max_area=1e-2)
    elif dim == 3:
        if rcon.is_head_rank:
            from hedge.mesh.generator import make_ball_mesh
            mesh = make_ball_mesh(max_volume=0.0001,
                    boundary_tagger=lambda fvi, el, fn, points:
                    ["dirichlet"])
    else:
        raise RuntimeError, "bad number of dimensions"

    if rcon.is_head_rank:
        print "%d elements" % len(mesh.elements)
        mesh_data = rcon.distribute_mesh(mesh)
    else:
        mesh_data = rcon.receive_mesh()

    discr = rcon.make_discretization(mesh_data, order=5, 
            debug=[])

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

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

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

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

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

                dirichlet_tag=TAG_ALL,
                neumann_tag=TAG_NONE, 

                #dirichlet_tag=TAG_ALL,
                #neumann_tag=TAG_NONE, 

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

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

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

        if write_output:
            from hedge.visualization import SiloVisualizer, VtkVisualizer
            vis = VtkVisualizer(discr, rcon)
            visf = vis.make_file("fld")
            vis.add_data(visf, [ ("sol", discr.convert_volume(u, kind="numpy")), ])
            visf.close()
    finally:
        discr.close()
Beispiel #2
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)
def test_elliptic():
    """Test various properties of elliptic operators."""

    from hedge.tools import unit_vector

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

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

        grad_mat = op.grad_matrix()

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

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

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

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

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

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

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

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

    from hedge.backends import CPURunContext
    rcon = CPURunContext()

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

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

            bound_op = op.bind(discr)

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

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

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

    #print eocrec.pretty_print()
    assert eocrec.estimate_order_of_convergence()[0, 1] > 8
def test_elliptic():
    """Test various properties of elliptic operators."""

    from hedge.tools import unit_vector

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

    def check_grad_mat():
        import pyublas

        if not pyublas.has_sparse_wrappers():
            return

        grad_mat = op.grad_matrix()

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

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

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

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

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

    import pymbolic

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

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

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

    from hedge.backends import CPURunContext

    rcon = CPURunContext()

    from hedge.tools import EOCRecorder

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

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

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

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

            bound_op = op.bind(discr)

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

            from hedge.iterative import parallel_cg

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

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

    # print eocrec.pretty_print()
    assert eocrec.estimate_order_of_convergence()[0, 1] > 8
Beispiel #5
0
def main(write_output=True):
    from hedge.data import GivenFunction, ConstantGivenFunction

    from hedge.backends import guess_run_context
    rcon = guess_run_context()

    dim = 2

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

    if dim == 2:
        if rcon.is_head_rank:
            from hedge.mesh.generator import make_disk_mesh
            mesh = make_disk_mesh(r=0.5,
                                  boundary_tagger=boundary_tagger,
                                  max_area=1e-2)
    elif dim == 3:
        if rcon.is_head_rank:
            from hedge.mesh.generator import make_ball_mesh
            mesh = make_ball_mesh(
                max_volume=0.0001,
                boundary_tagger=lambda fvi, el, fn, points: ["dirichlet"])
    else:
        raise RuntimeError, "bad number of dimensions"

    if rcon.is_head_rank:
        print "%d elements" % len(mesh.elements)
        mesh_data = rcon.distribute_mesh(mesh)
    else:
        mesh_data = rcon.receive_mesh()

    discr = rcon.make_discretization(mesh_data, order=5, debug=[])

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

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

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

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

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

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

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

        if write_output:
            from hedge.visualization import SiloVisualizer, VtkVisualizer
            vis = VtkVisualizer(discr, rcon)
            visf = vis.make_file("fld")
            vis.add_data(visf, [
                ("sol", discr.convert_volume(u, kind="numpy")),
            ])
            visf.close()
    finally:
        discr.close()
Beispiel #6
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)