Example #1
0
def test_mesh1():
    m = Mesh(-1, 1, 5, 2)
    pts, p = m.get_mesh_data()
    assert (abs(pts - array([-1, -0.6, -0.2, 0.2, 0.6, 1])) < eps).all()
    assert (abs(p - array([2, 2, 2, 2, 2])) < eps).all()

    m = Mesh(-1, 1, 4, 1)
    pts, p = m.get_mesh_data()
    assert (abs(pts - array([-1, -0.5, 0, 0.5, 1])) < eps).all()
    assert (abs(p - array([1, 1, 1, 1])) < eps).all()
Example #2
0
def test_mesh3():
    m = Mesh([0, 1, 3, 4], [2, 2, 2])
    pts, p = m.get_mesh_data()
    assert (abs(pts - array([0, 1, 3, 4])) < eps).all()
    assert (abs(p - array([2, 2, 2])) < eps).all()

    m = Mesh([-1, -0.5, 0, 0.5, 1], [2, 2, 2, 2])
    pts, p = m.get_mesh_data()
    assert (abs(pts - array([-1, -0.5, 0, 0.5, 1])) < eps).all()
    assert (abs(p - array([2, 2, 2, 2])) < eps).all()
Example #3
0
def radial_dirac_equation_adapt(params, error_tol=1e-8):
    if params["mesh_uniform"]:
        pts = create_uniform_mesh(params["a"],
                                  params["b"],
                                  n_elem=params["el_num"])
    else:
        pts = create_log_mesh(params["a"],
                              params["b"],
                              par=params["mesh_par1"],
                              n_elem=params["el_num"])
    orders = [params["el_order"]] * (len(pts) - 1)
    mesh = Mesh(pts, orders)
    conv_graph = []
    l = params["l"]
    Z = params["Z"]
    N_eig = params["eig_num"]
    #exact_energies=[-1.*Z**2/(2*n**2) for n in range(1+l,N_eig+1+l)]
    #old_energies = None
    try:
        for i in range(10000):
            print "-" * 80
            print "adaptivity iteration:", i
            mesh.set_bc_right_dirichlet(0, 0)
            pts, orders = mesh.get_mesh_data()
            print "Current mesh:"
            print pts
            print orders
            #stop
            N_dof, energies, eigs = solve_dirac(mesh,
                                                l=l,
                                                Z=Z,
                                                eqn_type=eqn_type,
                                                eig_num=N_eig)
            for n in range(1, 51):
                print "%d  %10.5f" % (n, energies[n - 1])
            break
            conv_graph.append((N_dof, energies))
            # This doesn't work well:
            if old_energies is not None:
                err = max(abs(old_energies - energies))
                print "Maximum error in energies:", err
                if err < error_tol:
                    break
            #err = max(abs(energies - exact_energies))
            #print "Maximum error in energies:", err
            #if err < error_tol:
            #    break
            old_energies = energies
            #    exact_energies = array(exact_energies)
            #    print energies - exact_energies
            mesh = adapt_mesh(mesh,
                              eigs,
                              l=l,
                              Z=Z,
                              adapt_type=params["adapt_type"])
    finally:
        plot_conv(conv_graph, exact=exact_energies, l=l)
Example #4
0
def refine_mesh(mesh, els2refine):
    new_pts = []
    pts, orders = mesh.get_mesh_data()
    new_pts.append(pts[0])
    for id in range(len(orders)):
        if id in els2refine:
            new_pts.append((pts[id] + pts[id + 1]) / 2.)
        new_pts.append(pts[id + 1])
    # assumes uniform order:
    orders = [orders[0]] * (len(new_pts) - 1)
    return Mesh(new_pts, orders)
Example #5
0
def main():
    params_hydrogen_p_L = dict(l=0,
                               Z=1,
                               a=0,
                               b=100,
                               el_num=4,
                               el_order=1,
                               eig_num=3,
                               mesh_uniform=False,
                               mesh_par1=20,
                               adapt_type="p")

    #radial_dirac_equation_adapt(params_hydrogen_uniform_p_L, error_tol=1e-5)
    #pts = create_uniform_mesh(0, 50, 40)
    pts = create_log_mesh(0, 150, 10000, 40)
    orders = [20] * (len(pts) - 1)
    mesh = Mesh(pts, orders, eq_num=2)
    N_dof, energies, eigs = solve_dirac(mesh, kappa=1, Z=47, eig_num=50)
    for i, E in enumerate(energies):
        print i + 1, E
Example #6
0
def radial_schroedinger_equation_adapt(params, error_tol=1e-8):
    if params["mesh_uniform"]:
        pts = create_uniform_mesh(params["a"],
                                  params["b"],
                                  n_elem=params["el_num"])
    else:
        pts = create_log_mesh(params["a"],
                              params["b"],
                              par=params["mesh_par1"],
                              n_elem=params["el_num"])
    orders = [params["el_order"]] * (len(pts) - 1)
    mesh = Mesh(pts, orders)
    conv_graph = []
    l = params["l"]
    Z = params["Z"]
    N_eig = params["eig_num"]
    exact_energies = [
        -1. * Z**2 / (2 * n**2) for n in range(1 + l, N_eig + 1 + l)
    ]
    old_energies = None
    eqn_type = params["eqn_type"]
    try:
        for i in range(10000):
            print "-" * 80
            print "adaptivity iteration:", i
            if eqn_type == "rR":
                mesh.set_bc_left_dirichlet(0, 0)
                mesh.set_bc_right_dirichlet(0, 0)
            # Use zero dirichlet for eqn_type="R" as well, just to make sure
            # that we agree with sle1d
            mesh.set_bc_right_dirichlet(0, 0)
            pts, orders = mesh.get_mesh_data()
            print "Current mesh:"
            print pts
            print orders
            #stop
            N_dof, energies, eigs = solve_schroedinger(mesh,
                                                       l=l,
                                                       Z=Z,
                                                       eqn_type=eqn_type,
                                                       eig_num=N_eig)
            for n in range(1, N_eig + 1):
                print "%d  %10.5f" % (n, energies[n - 1])
            conv_graph.append((N_dof, energies))
            # This doesn't work well:
            if old_energies is not None:
                err = max(abs(old_energies - energies))
                print "Maximum error in energies:", err
                if err < error_tol:
                    break
            #err = max(abs(energies - exact_energies))
            #print "Maximum error in energies:", err
            #if err < error_tol:
            #    break
            old_energies = energies
            #    exact_energies = array(exact_energies)
            #    print energies - exact_energies
            mesh = adapt_mesh(mesh,
                              eigs,
                              l=l,
                              Z=Z,
                              adapt_type=params["adapt_type"])
    finally:
        pass
        #plot_conv(conv_graph, exact=exact_energies, l=l)
    return [e for e in energies if e < 0]
Example #7
0
def adapt_mesh(mesh, eigs, l=0, Z=1, adapt_type="hp", eqn_type="R"):
    """
    Adapts the mesh using the adaptivity type 'adapt_type'.

    Returns a new instance of the H1D mesh.

    adapt_type .... one of: h, hp, p, uniform-p, romanowski
    """
    if adapt_type == "romanowski":
        m = refine_mesh_romanowski(mesh, eigs)
        pts, orders = m.get_mesh_data()
        return Mesh(pts, orders)
    elif adapt_type == "uniform-p":
        pts, orders = mesh.get_mesh_data()
        orders = array(orders) + 1
        return Mesh(pts, orders)
    elif adapt_type in ["h", "p", "hp"]:
        NORM = 1  # 1 ... H1; 0 ... L2;
        THRESHOLD = 0.7
        mesh_ref = mesh.reference_refinement()
        print "Fine mesh created (%d DOF)." % mesh_ref.get_n_dof()
        N_dof, energies, eigs_ref = solve_schroedinger(mesh_ref,
                                                       l=l,
                                                       Z=Z,
                                                       eqn_type=eqn_type,
                                                       eig_num=len(eigs))
        flip_vectors(mesh, eigs, mesh_ref, eigs_ref)
        print "    Done."
        sols = []
        sols_ref = []
        print "Normalizing solutions..."
        for i in range(len(eigs)):
            e = (eigs[i]).copy()
            coarse_h1_norm = FESolution(mesh, e).h1_norm()
            e /= coarse_h1_norm
            sols.append(e)
            e = (eigs_ref[i]).copy()
            reference_h1_norm = FESolution(mesh_ref, e).h1_norm()
            e /= reference_h1_norm
            sols_ref.append(e)
            #print "H1 norms:"
            #print "coarse    (%d):" % i, coarse_h1_norm
            #print "reference (%d):" % i, reference_h1_norm
        print "    Done."
        meshes = []
        mesh_orig = mesh.copy()
        mesh_orig.assign_dofs()
        errors = []
        for sol, sol_ref in zip(sols, sols_ref):
            mesh = mesh_orig.copy()
            mesh.assign_dofs()
            mesh_ref = mesh.reference_refinement()
            mesh_ref.assign_dofs()
            mesh.copy_vector_to_mesh(sol, 0)
            mesh_ref.copy_vector_to_mesh(sol_ref, 0)
            err_est_total, err_est_array = calc_error_estimate(
                NORM, mesh, mesh_ref)
            ref_sol_norm = calc_solution_norm(NORM, mesh_ref)
            err_est_rel = err_est_total / ref_sol_norm
            print "Relative error (est) = %g %%\n" % (100. * err_est_rel)
            errors.append(err_est_rel)
            # TODO: adapt using all the vectors:
            # 0 ... hp, 1 ... h, 2 ... p
            if adapt_type == "hp":
                ADAPT_TYPE = 0
            elif adapt_type == "h":
                ADAPT_TYPE = 1
            elif adapt_type == "p":
                ADAPT_TYPE = 2
            else:
                raise ValueError("Unkown adapt_type")
            adapt(NORM, ADAPT_TYPE, THRESHOLD, err_est_array, mesh, mesh_ref)
            meshes.append(mesh)
        pts, orders = mesh_orig.get_mesh_data()
        mesh = Mesh1D(pts, orders)
        for m in meshes:
            pts, orders = m.get_mesh_data()
            m = Mesh1D(pts, orders)
            mesh = mesh.union(m)
        pts, orders = mesh.get_mesh_data()
        mesh = Mesh(pts, orders)
        return mesh
    else:
        raise ValueError("Unknown adapt_type")