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)
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
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
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)
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()
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()
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)
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]
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
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()
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)
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
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
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:
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]
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")