Example #1
0
def test_discrete_problem2():
    n1 = Node(0)
    n2 = Node(1)
    n3 = Node(2)
    n4 = Node(3)
    e1 = Element(n1, n2, order=1)
    e2 = Element(n2, n3, order=1)
    e3 = Element(n3, n4, order=1)
    nodes = (n1, n2, n3, n4)
    elements = (e1, e2, e3)
    m1 = Mesh(nodes, elements)
    m1.set_bc(left=True, value=1)

    d = DiscreteProblem(meshes=[m1])
    def F(i, Y, t):
        if i == 0:
            return -Y[0]
        raise ValueError("Wrong i (i=%d)." % (i))
    def DFDY(i, j, Y, t):
        if i == 0 and j == 0:
            return -1
        raise ValueError("Wrong i, j (i=%d, j=%d)." % (i, j))
    d.define_ode(F, DFDY)
    d.assign_dofs()
    Y = zeros((d.ndofs,))
    J = d.assemble_J(Y)
    F = d.assemble_F()
    x = d.solve(J, F)
Example #2
0
def test_mesh7():
    n1 = Node(1)
    n2 = Node(3)
    n3 = Node(4)
    n4 = Node(5)
    e1 = Element(n1, n2, order=3)
    e2 = Element(n2, n3, order=1)
    e3 = Element(n3, n4, order=2)
    nodes = (n1, n2, n3, n4)
    elements = (e1, e2, e3)
    m = Mesh(nodes, elements)
    m.set_bc(left=False, value=1)
    ndofs = m.assign_dofs()
    assert m.elements[0].dofs[0] == 0
    assert m.elements[0].dofs[1] == 1
    assert m.elements[0].dofs[2] == 3
    assert m.elements[0].dofs[3] == 4

    assert m.elements[1].dofs[0] == 1
    assert m.elements[1].dofs[1] == 2

    assert m.elements[2].dofs[0] == 2
    assert m.elements[2].dofs[1] == -1
    assert m.elements[2].dofs[2] == 5

    assert ndofs == 6
Example #3
0
def test_mesh4():
    n1 = Node(1)
    n2 = Node(3)
    n3 = Node(4)
    n4 = Node(5)
    e1 = Element(n1, n2, order=3)
    e2 = Element(n2, n3, order=3)
    e3 = Element(n3, n4, order=3)
    nodes = (n1, n2, n3, n4)
    elements = (e1, e2, e3)
    m = Mesh(nodes, elements)
    ndofs = m.assign_dofs()
    assert m.elements[0].dofs[0] == 0
    assert m.elements[0].dofs[1] == 1
    assert m.elements[0].dofs[2] == 4
    assert m.elements[0].dofs[3] == 5

    assert m.elements[1].dofs[0] == 1
    assert m.elements[1].dofs[1] == 2
    assert m.elements[1].dofs[2] == 6
    assert m.elements[1].dofs[3] == 7

    assert m.elements[2].dofs[0] == 2
    assert m.elements[2].dofs[1] == 3
    assert m.elements[2].dofs[2] == 8
    assert m.elements[2].dofs[3] == 9

    assert ndofs == 10
Example #4
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 #5
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 #6
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 #7
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 #8
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 #9
0
def test_mesh8():
    n1 = Node(1)
    n2 = Node(3)
    n3 = Node(4)
    n4 = Node(5)
    e1 = Element(n1, n2, order=3)
    e2 = Element(n2, n3, order=1)
    e3 = Element(n3, n4, order=2)
    nodes = (n1, n2, n3, n4)
    elements = (e1, e2, e3)
    m1 = Mesh(nodes, elements)
    m1.set_bc(left=False, value=1)
    e4 = Element(n1, n2, order=3)
    e5 = Element(n2, n3, order=1)
    e6 = Element(n3, n4, order=2)
    elements = (e4, e5, e6)
    m2 = Mesh(nodes, elements)
    m2.set_bc(left=True, value=1)

    m1.assign_dofs()
    m2.assign_dofs()

    assert m1.elements[0].dofs[0] == 0
    assert m1.elements[0].dofs[1] == 1
    assert m1.elements[0].dofs[2] == 3
    assert m1.elements[0].dofs[3] == 4

    assert m1.elements[1].dofs[0] == 1
    assert m1.elements[1].dofs[1] == 2

    assert m1.elements[2].dofs[0] == 2
    assert m1.elements[2].dofs[1] == -1
    assert m1.elements[2].dofs[2] == 5

    assert m2.elements[0].dofs[0] == -1
    assert m2.elements[0].dofs[1] == 0
    assert m2.elements[0].dofs[2] == 3
    assert m2.elements[0].dofs[3] == 4

    assert m2.elements[1].dofs[0] == 0
    assert m2.elements[1].dofs[1] == 1

    assert m2.elements[2].dofs[0] == 1
    assert m2.elements[2].dofs[1] == 2
    assert m2.elements[2].dofs[2] == 5
Example #10
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()

    m = Mesh([-1, -0.5, 0, 0.5, 1], [2, 2, 3, 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, 3, 2])) < eps).all()
Example #11
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 #12
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 #13
0
def test_mesh9():
    n1 = Node(1)
    n2 = Node(3)
    n3 = Node(4)
    n4 = Node(5)
    e1 = Element(n1, n2, order=3)
    e2 = Element(n2, n3, order=1)
    e3 = Element(n3, n4, order=2)
    nodes = (n1, n2, n3, n4)
    elements = (e1, e2, e3)
    m1 = Mesh(nodes, elements)
    m1.set_bc(left=False, value=1)
    e4 = Element(n1, n2, order=3)
    e5 = Element(n2, n3, order=1)
    e6 = Element(n3, n4, order=2)
    elements = (e4, e5, e6)
    m2 = Mesh(nodes, elements)
    m2.set_bc(left=True, value=1)

    d = DiscreteProblem(meshes=[m1, m2])
    ndofs = d.assign_dofs()

    assert m1.elements[0].dofs[0] == 0
    assert m1.elements[0].dofs[1] == 1
    assert m1.elements[0].dofs[2] == 3
    assert m1.elements[0].dofs[3] == 4

    assert m1.elements[1].dofs[0] == 1
    assert m1.elements[1].dofs[1] == 2

    assert m1.elements[2].dofs[0] == 2
    assert m1.elements[2].dofs[1] == -1
    assert m1.elements[2].dofs[2] == 5

    assert m2.elements[0].dofs[0] == -1
    assert m2.elements[0].dofs[1] == 0 + 6
    assert m2.elements[0].dofs[2] == 3 + 6
    assert m2.elements[0].dofs[3] == 4 + 6

    assert m2.elements[1].dofs[0] == 0 + 6
    assert m2.elements[1].dofs[1] == 1 + 6

    assert m2.elements[2].dofs[0] == 1 + 6
    assert m2.elements[2].dofs[1] == 2 + 6
    assert m2.elements[2].dofs[2] == 5 + 6

    assert ndofs == 12
    assert d.get_mesh_number(0) == 0
    assert d.get_mesh_number(4) == 0
    assert d.get_mesh_number(5) == 0
    assert d.get_mesh_number(6) == 1
    assert d.get_mesh_number(11) == 1
Example #14
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 #15
0
def _test_discrete_problem1():
    n1 = Node(0)
    n2 = Node(1)
    n3 = Node(2)
    n4 = Node(3)
    e1 = Element(n1, n2, order=1)
    e2 = Element(n2, n3, order=1)
    e3 = Element(n3, n4, order=1)
    nodes = (n1, n2, n3, n4)
    elements = (e1, e2, e3)
    m1 = Mesh(nodes, elements)
    m1.set_bc(left=True, value=0)
    e4 = Element(n1, n2, order=1)
    e5 = Element(n2, n3, order=1)
    e6 = Element(n3, n4, order=1)
    elements = (e4, e5, e6)
    m2 = Mesh(nodes, elements)
    m2.set_bc(left=True, value=1)

    d = DiscreteProblem(meshes=[m1, m2])
    def F(i, Y, t):
        if i == 0:
            return Y[1]
        elif i == 1:
            k = 2.0
            return -k**2 * Y[0]
        raise ValueError("Wrong i (i=%d)." % (i))
    def DFDY(i, j, Y, t):
        k = 2.0
        if i == 0 and j == 0:
            return 0.
        elif i == 0 and j == 1:
            return 1.
        elif i == 1 and j == 0:
            return -k**2
        elif i == 1 and j == 1:
            return 0.
        raise ValueError("Wrong i, j (i=%d, j=%d)." % (i, j))
    d.set_rhs(F, DFDY)
    d.assign_dofs()
    J = d.assemble_J()
    F = d.assemble_F()
    x = d.solve(J, F)
"""
Solves the system of ODE, that are coupled by a triangular matrix.
"""
from hermes1d import Node, Element, Mesh, DiscreteProblem

from numpy import zeros
a = 0.
b = 1.
N = 10
nodes = [Node((b-a)/N * i) for i in range(N)]
elements = [Element(nodes[i], nodes[i+1], order=1) for i in range(N-1)]
m1 = Mesh(nodes, elements)
m1.set_bc(left=True, value=1)
elements = [Element(nodes[i], nodes[i+1], order=1) for i in range(N-1)]
m2 = Mesh(nodes, elements)
m2.set_bc(left=True, value=2)

d = DiscreteProblem(meshes=[m1, m2])
k = 1.0
def F(i, Y, t):
    if i == 0:
        return -Y[0]+Y[1]
    elif i == 1:
        return Y[1]
    raise ValueError("Wrong i (i=%d)." % (i))
def DFDY(i, j, Y, t):
    if i == 0 and j == 0:
        return -1
    elif i == 0 and j == 1:
        return 1
    elif i == 1 and j == 0:
Example #17
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 #18
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")