def test_heat_ball_cart(Nmax, Lmax, dtype): # Bases dealias = 1 c, d, b, phi, theta, r, x, y, z = build_ball(2 * (Lmax + 1), Lmax + 1, Nmax + 1, dealias=dealias, dtype=dtype) xr = radius_ball * np.cos(phi) * np.sin(theta) yr = radius_ball * np.sin(phi) * np.sin(theta) zr = radius_ball * np.cos(theta) # Fields u = field.Field(name='u', dist=d, bases=(b, ), dtype=dtype) τu = field.Field(name='u', dist=d, bases=(b.S2_basis(), ), dtype=dtype) f = field.Field(name='a', dist=d, bases=(b, ), dtype=dtype) f['g'] = 12 * x**2 - 6 * y + 2 g = field.Field(name='a', dist=d, bases=(b.S2_basis(), ), dtype=dtype) g['g'] = xr**4 - yr**3 + zr**2 # Problem Lap = lambda A: operators.Laplacian(A, c) Lift = lambda A: operators.Lift(A, b, -1) problem = problems.LBVP([u, τu]) problem.add_equation((Lap(u) + Lift(τu), f)) problem.add_equation((u(r=radius_ball), g)) # Solver solver = solvers.LinearBoundaryValueSolver(problem) solver.solve() # Check solution u_true = x**4 - y**3 + z**2 assert np.allclose(u['g'], u_true)
def test_heat_shell(Nmax, Lmax, dtype): # Bases dealias = 1 c, d, b, phi, theta, r, x, y, z = build_shell(2 * (Lmax + 1), Lmax + 1, Nmax + 1, dealias=dealias, dtype=dtype) r0, r1 = b.radial_basis.radii # Fields u = field.Field(name='u', dist=d, bases=(b, ), dtype=dtype) τu1 = field.Field(name='τu1', dist=d, bases=(b.S2_basis(), ), dtype=dtype) τu2 = field.Field(name='τu2', dist=d, bases=(b.S2_basis(), ), dtype=dtype) F = field.Field(name='a', dist=d, bases=(b, ), dtype=dtype) F['g'] = 6 # Problem Lap = lambda A: operators.Laplacian(A, c) Lift = lambda A, n: operators.Lift(A, b, n) problem = problems.LBVP([u, τu1, τu2]) problem.add_equation((Lap(u) + Lift(τu1, -1) + Lift(τu2, -2), F)) problem.add_equation((u(r=r0), 0)) problem.add_equation((u(r=r1), 0)) # Solver solver = solvers.LinearBoundaryValueSolver(problem) solver.solve() # Check solution u_true = r**2 + 6 / r - 7 assert np.allclose(u['g'], u_true)
def test_vector_heat_disk_dirichlet(Nr, Nphi, dtype): # Bases dealias = 1 c, d, b, phi, r, x, y = build_disk(Nphi, Nr, dealias=dealias, dtype=dtype) # Fields u = field.Field(name='u', dist=d, bases=(b, ), tensorsig=(c, ), dtype=dtype) τu = field.Field(name='u', dist=d, bases=(b.S1_basis(), ), tensorsig=(c, ), dtype=dtype) v = field.Field(name='u', dist=d, bases=(b, ), tensorsig=(c, ), dtype=dtype) ex = np.array([-np.sin(phi), np.cos(phi)]) ey = np.array([np.cos(phi), np.sin(phi)]) v['g'] = (x + 4 * y) * ex vr = operators.RadialComponent(v(r=radius_disk)) vph = operators.AzimuthalComponent(v(r=radius_disk)) # Problem Lap = lambda A: operators.Laplacian(A, c) Lift = lambda A: operators.Lift(A, b, -1) problem = problems.LBVP([u, τu]) problem.add_equation((Lap(u) + Lift(τu), 0)) problem.add_equation((u(r=radius_disk), v(r=radius_disk))) # Solver solver = solvers.LinearBoundaryValueSolver(problem) solver.solve() assert np.allclose(u['g'], v['g'])
def test_heat_ball(Nmax, Lmax, dtype): # Bases dealias = 1 c, d, b, phi, theta, r, x, y, z = build_ball(2 * (Lmax + 1), Lmax + 1, Nmax + 1, dealias=dealias, dtype=dtype) # Fields u = field.Field(name='u', dist=d, bases=(b, ), dtype=dtype) τu = field.Field(name='u', dist=d, bases=(b.S2_basis(), ), dtype=dtype) F = field.Field(name='a', dist=d, bases=(b, ), dtype=dtype) F['g'] = 6 # Problem Lap = lambda A: operators.Laplacian(A, c) Lift = lambda A: operators.Lift(A, b, -1) problem = problems.LBVP([u, τu]) problem.add_equation((Lap(u) + Lift(τu), F)) problem.add_equation((u(r=radius_ball), 0)) # Solver solver = solvers.LinearBoundaryValueSolver(problem) solver.solve() # Check solution u_true = r**2 - 1 assert np.allclose(u['g'], u_true)
def test_disk_bessel_zeros(Nphi, Nr, m, radius, dtype): # Bases c = coords.PolarCoordinates('phi', 'r') d = distributor.Distributor((c, )) b = basis.DiskBasis(c, (Nphi, Nr), radius=radius, dtype=dtype) b_S1 = b.S1_basis() phi, r = b.local_grids((1, 1)) # Fields f = field.Field(dist=d, bases=(b, ), dtype=dtype) τ_f = field.Field(dist=d, bases=(b_S1, ), dtype=dtype) k2 = field.Field(name='k2', dist=d, dtype=dtype) # Parameters and operators lap = lambda A: operators.Laplacian(A, c) Lift = lambda A: operators.Lift(A, b, -1) # Bessel equation: k^2*f + lap(f) = 0 problem = problems.EVP([f, τ_f], k2) problem.add_equation((k2 * f + lap(f) + Lift(τ_f), 0)) problem.add_equation((f(r=radius), 0)) # Solver solver = solvers.EigenvalueSolver(problem) print(solver.subproblems[0].group) for sp in solver.subproblems: if sp.group[0] == m: break else: raise ValueError("Could not find subproblem with m = %i" % m) solver.solve_dense(sp) # Compare eigenvalues n_compare = 5 selected_eigenvalues = np.sort(solver.eigenvalues)[:n_compare] analytic_eigenvalues = (spec.jn_zeros(m, n_compare) / radius)**2 assert np.allclose(selected_eigenvalues, analytic_eigenvalues)
def test_scalar_heat_disk(Nr, Nphi, dtype): # Bases dealias = 1 c, d, b, phi, r, x, y = build_disk(Nphi, Nr, dealias=dealias, dtype=dtype) xr = radius_disk * np.cos(phi) yr = radius_disk * np.sin(phi) # Fields u = field.Field(name='u', dist=d, bases=(b, ), dtype=dtype) τu = field.Field(name='u', dist=d, bases=(b.S1_basis(), ), dtype=dtype) f = field.Field(dist=d, bases=(b, ), dtype=dtype) f['g'] = 6 * x - 2 g = field.Field(dist=d, bases=(b.S1_basis(), ), dtype=dtype) g['g'] = xr**3 - yr**2 # Problem Lap = lambda A: operators.Laplacian(A, c) Lift = lambda A: operators.Lift(A, b, -1) problem = problems.LBVP([u, τu]) problem.add_equation((Lap(u) + Lift(τu), f)) problem.add_equation((u(r=radius_disk), g)) # Solver solver = solvers.LinearBoundaryValueSolver(problem) solver.solve() # Check solution u_true = x**3 - y**2 assert np.allclose(u['g'], u_true)
def test_mag_BC(N, dtype): # Bases c, d, b, phi, theta, r, x, y, z = build_ball(N, N, N, 1, 1, dtype, grid_scale=1) # Fields A = d.VectorField(c, name='A', bases=b) Phi = d.Field(name='Phi', bases=b) tau_A = d.VectorField(c, name='A_tau', bases=b.S2_basis()) Lift = lambda A: operators.Lift(A, b, -1) # Problem problem = problems.IVP([A, Phi, tau_A], namespace=locals()) problem.add_equation("div(A) = 0") problem.add_equation("dt(A) - grad(Phi) - lap(A) + Lift(tau_A) = 0") problem.add_equation("angular(A(r=1), index=0) = 0") problem.add_equation("Phi(r=1) = 0") # Solver solver = solvers.InitialValueSolver(problem, timesteppers.SBDF1) dt = 1e-5 iter = 10 for i in range(iter): solver.step(dt)
def test_heat_ball_nlbvp(Nr, dtype, dealias): radius = 2 ncc_cutoff = 1e-10 tolerance = 1e-10 # Bases c = coords.SphericalCoordinates('phi', 'theta', 'r') d = distributor.Distributor((c,)) b = basis.BallBasis(c, (1, 1, Nr), radius=radius, dtype=dtype, dealias=dealias) bs = b.S2_basis(radius=radius) phi, theta, r = b.local_grids((1, 1, 1)) # Fields u = field.Field(name='u', dist=d, bases=(b,), dtype=dtype) τ = field.Field(name='τ', dist=d, bases=(bs,), dtype=dtype) F = field.Field(name='F', dist=d, bases=(b,), dtype=dtype) # todo: make this constant F['g'] = 6 # Problem Lap = lambda A: operators.Laplacian(A, c) Lift = lambda A: operators.Lift(A, b, -1) problem = problems.NLBVP([u, τ]) problem.add_equation((Lap(u) + Lift(τ), F)) problem.add_equation((u(r=radius), 0)) # Solver solver = solvers.NonlinearBoundaryValueSolver(problem, ncc_cutoff=ncc_cutoff) # Initial guess u['g'] = 1 # Iterations def error(perts): return np.sum([np.sum(np.abs(pert['c'])) for pert in perts]) err = np.inf while err > tolerance: solver.newton_iteration() err = error(solver.perturbations) u_true = r**2 - radius**2 u.change_scales(1) assert np.allclose(u['g'], u_true)
def test_ball_diffusion(Lmax, Nmax, Leig, radius, bc, dtype): # Bases c = coords.SphericalCoordinates('phi', 'theta', 'r') d = distributor.Distributor((c, )) b = basis.BallBasis(c, (2 * (Lmax + 1), Lmax + 1, Nmax + 1), radius=radius, dtype=dtype) b_S2 = b.S2_basis() phi, theta, r = b.local_grids((1, 1, 1)) # Fields A = field.Field(dist=d, bases=(b, ), tensorsig=(c, ), dtype=dtype) φ = field.Field(dist=d, bases=(b, ), dtype=dtype) τ_A = field.Field(dist=d, bases=(b_S2, ), tensorsig=(c, ), dtype=dtype) λ = field.Field(name='λ', dist=d, dtype=dtype) # Parameters and operators div = lambda A: operators.Divergence(A) grad = lambda A: operators.Gradient(A, c) curl = lambda A: operators.Curl(A) lap = lambda A: operators.Laplacian(A, c) trans = lambda A: operators.TransposeComponents(A) radial = lambda A, index: operators.RadialComponent(A, index=index) angular = lambda A, index: operators.AngularComponent(A, index=index) Lift = lambda A: operators.Lift(A, b, -1) # Problem problem = problems.EVP([φ, A, τ_A], λ) problem.add_equation((div(A), 0)) problem.add_equation((-λ * A + grad(φ) - lap(A) + Lift(τ_A), 0)) if bc == 'no-slip': problem.add_equation((A(r=radius), 0)) elif bc == 'stress-free': E = 1 / 2 * (grad(A) + trans(grad(A))) problem.add_equation((radial(A(r=radius), 0), 0)) problem.add_equation((radial(angular(E(r=radius), 0), 1), 0)) elif bc == 'potential': ell_func = lambda ell: ell + 1 ell_1 = lambda A: operators.SphericalEllProduct(A, c, ell_func) problem.add_equation( (radial(grad(A)(r=radius), 0) + ell_1(A)(r=radius) / radius, 0)) elif bc == 'conducting': problem.add_equation((φ(r=radius), 0)) problem.add_equation((angular(A(r=radius), 0), 0)) elif bc == 'pseudo': problem.add_equation((radial(A(r=radius), 0), 0)) problem.add_equation((angular(curl(A)(r=radius), 0), 0)) # Solver solver = solvers.EigenvalueSolver(problem) if not solver.subproblems[Leig].group[1] == Leig: raise ValueError("subproblems indexed in a strange way") solver.solve_dense(solver.subproblems[Leig]) i_sort = np.argsort(solver.eigenvalues) solver.eigenvalues = solver.eigenvalues[i_sort] λ_analytic = analytic_eigenvalues(Leig, Nmax + 1, bc, r0=radius) if (bc == 'stress-free' and Leig == 1): # add null space solution λ_analytic = np.append(0, λ_analytic) assert np.allclose(solver.eigenvalues[:Nmax // 4], λ_analytic[:Nmax // 4])
def test_lane_emden_floating_R(Nr, dtype, dealias): n = 3.0 ncc_cutoff = 1e-10 tolerance = 1e-10 # Bases c = coords.SphericalCoordinates('phi', 'theta', 'r') d = distributor.Distributor((c,)) b = basis.BallBasis(c, (1, 1, Nr), radius=1, dtype=dtype, dealias=dealias) bs = b.S2_basis(radius=1) bs0 = b.S2_basis(radius=0) phi, theta, r = b.local_grids((1, 1, 1)) # Fields f = field.Field(dist=d, bases=(b,), dtype=dtype, name='f') R = field.Field(dist=d, dtype=dtype, name='R') τ = field.Field(dist=d, bases=(bs,), dtype=dtype, name='τ') one = field.Field(dist=d, bases=(bs0,), dtype=dtype) one['g'] = 1 # Problem lap = lambda A: operators.Laplacian(A, c) Lift = lambda A: operators.Lift(A, b, -1) problem = problems.NLBVP([f, R, τ]) problem.add_equation((lap(f) + Lift(τ), - R**2 * f**n)) problem.add_equation((f(r=0), one)) problem.add_equation((f(r=1), 0)) # Solver solver = solvers.NonlinearBoundaryValueSolver(problem, ncc_cutoff=ncc_cutoff) # Initial guess f['g'] = np.cos(np.pi/2 * r)**2 R['g'] = 5 # Iterations def error(perts): return np.sum([np.sum(np.abs(pert['c'])) for pert in perts]) err = np.inf while err > tolerance: solver.newton_iteration() err = error(solver.perturbations) # Compare to reference solutions from Boyd R_ref = {0.0: np.sqrt(6), 0.5: 2.752698054065, 1.0: np.pi, 1.5: 3.65375373621912608, 2.0: 4.3528745959461246769735700, 2.5: 5.355275459010779, 3.0: 6.896848619376960375454528, 3.25: 8.018937527, 3.5: 9.535805344244850444, 4.0: 14.971546348838095097611066, 4.5: 31.836463244694285264} assert np.allclose(R['g'].ravel(), R_ref[n])
def test_heat_ncc_shell(Nmax, Lmax, ncc_exponent, ncc_location, ncc_scale, dtype): # Bases dealias = 1 c, d, b, phi, theta, r, x, y, z = build_shell(2 * (Lmax + 1), Lmax + 1, Nmax + 1, dealias=dealias, dtype=dtype) r0, r1 = b.radial_basis.radii # Fields u = field.Field(name='u', dist=d, bases=(b, ), dtype=dtype) τu1 = field.Field(name='τu1', dist=d, bases=(b.S2_basis(), ), dtype=dtype) τu2 = field.Field(name='τu2', dist=d, bases=(b.S2_basis(), ), dtype=dtype) ncc = field.Field(name='ncc', dist=d, bases=(b.radial_basis, ), dtype=dtype) F = field.Field(name='a', dist=d, bases=(b, ), dtype=dtype) # Test Parameters F_value = {0: 6, 1: 2, 2: 1, 3 / 2: 3 / 4} analytic = { 0: r**2 + 6 / r - 7, 1: r + 2 / r - 3, 2: np.log(r) + np.log(4) / r - np.log(4), 3 / 2: np.sqrt(r) + 0.82842712 / r - 1.82842712 } if ncc_location == 'RHS': ncc['g'] = 1 F['g'] = F_value[ncc_exponent] * r**(-ncc_exponent) else: ncc['g'] = r**ncc_exponent F['g'] = F_value[ncc_exponent] u_true = analytic[ncc_exponent] ncc.change_scales(ncc_scale) ncc['g'] # force transform # Problem Lap = lambda A: operators.Laplacian(A, c) Lift = lambda A, n: operators.Lift(A, b, n) problem = problems.LBVP([u, τu1, τu2]) problem.add_equation((ncc * Lap(u) + Lift(τu1, -1) + Lift(τu2, -2), F)) problem.add_equation((u(r=r0), 0)) problem.add_equation((u(r=r1), 0)) # Solver solver = solvers.LinearBoundaryValueSolver(problem) solver.solve() # Check solution assert np.allclose(u['g'], u_true)
def test_ball_bessel_eigenfunction(Lmax, Nmax, Leig, Neig, radius, dtype): # Bases c = coords.SphericalCoordinates('phi', 'theta', 'r') d = distributor.Distributor((c, )) b = basis.BallBasis(c, (2 * (Lmax + 1), Lmax + 1, Nmax + 1), radius=radius, dtype=dtype) b_S2 = b.S2_basis() phi, theta, r = b.local_grids((1, 1, 1)) # Fields f = field.Field(dist=d, bases=(b, ), dtype=dtype) τ_f = field.Field(dist=d, bases=(b_S2, ), dtype=dtype) k2 = field.Field(name='k2', dist=d, dtype=dtype) # Parameters and operators lap = lambda A: operators.Laplacian(A, c) Lift = lambda A: operators.Lift(A, b, -1) # Bessel equation: k^2*f + lap(f) = 0 problem = problems.EVP([f, τ_f], k2) problem.add_equation((k2 * f + lap(f) + Lift(τ_f), 0)) problem.add_equation((f(r=radius), 0)) # Solver solver = solvers.EigenvalueSolver(problem) if not solver.subproblems[Leig].group[1] == Leig: raise ValueError("subproblems indexed in a strange way") solver.solve_dense(solver.subproblems[Leig]) i_sort = np.argsort(solver.eigenvalues) solver.eigenvalues = solver.eigenvalues[i_sort] solver.eigenvectors = solver.eigenvectors[:, i_sort] solver.set_state(Neig, solver.subproblems[Leig].subsystems[0]) # m = 0 mode f.change_layout(d.layouts[1]) local_m, local_ell, local_n = f.layout.local_group_arrays( f.domain, f.scales) radial_eigenfunction = f.data[(local_m == 0) * (local_ell == Leig)] i_max = np.argmax(np.abs(radial_eigenfunction)) radial_eigenfunction /= radial_eigenfunction[i_max] k = np.sqrt(solver.eigenvalues[Neig]) sol = spec.jv(Leig + 1 / 2, k * r) / np.sqrt(k * r) sol = sol.ravel() sol /= sol[i_max] assert np.allclose(radial_eigenfunction, sol)
def test_scalar_heat_disk_axisymm(Nr, Nphi, dtype): # Bases dealias = 1 c, d, b, phi, r, x, y = build_disk(Nphi, Nr, dealias=dealias, dtype=dtype) # Fields u = field.Field(name='u', dist=d, bases=(b, ), dtype=dtype) τu = field.Field(name='u', dist=d, bases=(b.S1_basis(), ), dtype=dtype) F = field.Field(name='a', dist=d, bases=(b, ), dtype=dtype) F['g'] = 4 # Problem Lap = lambda A: operators.Laplacian(A, c) Lift = lambda A: operators.Lift(A, b, -1) problem = problems.LBVP([u, τu]) problem.add_equation((Lap(u) + Lift(τu), F)) problem.add_equation((u(r=radius_disk), 0)) # Solver solver = solvers.LinearBoundaryValueSolver(problem) solver.solve() # Check solution u_true = r**2 - 1 assert np.allclose(u['g'], u_true)
def test_heat_ncc_cos_ball(Nmax, Lmax, ncc_scale, dtype): # Bases dealias = 1 c, d, b, phi, theta, r, x, y, z = build_ball(2 * (Lmax + 1), Lmax + 1, Nmax + 1, dealias=dealias, dtype=dtype) # Fields u = field.Field(name='u', dist=d, bases=(b, ), dtype=dtype) τu = field.Field(name='u', dist=d, bases=(b.S2_basis(), ), dtype=dtype) ncc = field.Field(name='ncc', dist=d, bases=(b.radial_basis, ), dtype=dtype) F = field.Field(name='a', dist=d, bases=(b, ), dtype=dtype) # Test Parameters R = radius_ball u_true = np.cos(np.pi / 2 * (r / R)**2) g = -np.pi / 2 / R**2 * (4 * np.pi / 2 * (r / R)**2 * np.cos(np.pi / 2 * (r / R)**2) + 6 * np.sin(np.pi / 2 * (r / R)**2)) ncc['g'] = u_true F['g'] = u_true * g ncc.change_scales(ncc_scale) ncc['g'] # force transform # Problem Lap = lambda A: operators.Laplacian(A, c) Lift = lambda A: operators.Lift(A, b, -1) problem = problems.LBVP([u, τu]) problem.add_equation((ncc * Lap(u) + Lift(τu), F)) problem.add_equation((u(r=radius_ball), 0)) # Solver solver = solvers.LinearBoundaryValueSolver(problem) solver.solve() # Check solution assert np.allclose(u['g'], u_true)
def test_lane_emden_first_order(Nr, dtype, dealias): n = 3.0 ncc_cutoff = 1e-10 tolerance = 1e-10 # Bases c = coords.SphericalCoordinates('phi', 'theta', 'r') d = distributor.Distributor((c,)) b = basis.BallBasis(c, (1, 1, Nr), radius=1, dtype=dtype, dealias=dealias) br = b.radial_basis phi, theta, r = b.local_grids((1, 1, 1)) # Fields p = field.Field(dist=d, bases=(br,), dtype=dtype, name='p') ρ = field.Field(dist=d, bases=(br,), dtype=dtype, name='ρ') φ = field.Field(dist=d, bases=(br,), dtype=dtype, name='φ') τ = field.Field(dist=d, dtype=dtype, name='τ') τ2 = field.Field(dist=d, dtype=dtype, name='τ2') rf = field.Field(dist=d, bases=(br,), tensorsig=(c,), dtype=dtype, name='r') rf['g'][2] = r # Problem lap = lambda A: operators.Laplacian(A, c) grad = lambda A: operators.Gradient(A, c) div = lambda A: operators.Divergence(A) Lift = lambda A: operators.Lift(A, br, -1) dot = lambda A, B: arithmetic.DotProduct(A, B) rdr = lambda A: dot(rf, grad(A)) problem = problems.NLBVP([p, ρ, φ, τ, τ2]) problem.add_equation((p, ρ**(1+1/n))) problem.add_equation((lap(φ) + Lift(τ), ρ)) problem.add_equation((φ(r=1), 0)) # This works # problem.add_equation((-φ, (n+1) * ρ**(1/n))) # problem.add_equation((τ2, 0)) # Also works when near correct solution # problem.add_equation((-φ**n, (n+1)**n * ρ)) # problem.add_equation((τ2, 0)) # Doesn't work well problem.add_equation((rdr(p) + Lift(τ2), -ρ*rdr(φ))) problem.add_equation((p(r=1), 0)) # Also doesn't work well # problem.add_equation((lap(p) + Lift(τ2), -div(ρ*grad(φ)))) # problem.add_equation((p(r=1), 0)) # Solver solver = solvers.NonlinearBoundaryValueSolver(problem, ncc_cutoff=ncc_cutoff) # Initial guess #φ['g'] = - 55 * np.cos(np.pi/2 * r) #φ['g'] = - 50 * (1 - r) * (1 + r) φ['g'] = np.array([[[-5.49184941e+01-2.10742982e-38j, -5.41628923e+01-5.32970546e-38j, -5.29461420e+01-5.04522267e-38j, -5.13265949e+01-2.97780743e-38j, -4.93761552e+01-2.61880274e-38j, -4.71730013e+01-3.43967627e-38j, -4.47948939e+01-3.04186813e-38j, -4.23139098e+01-1.79113018e-38j, -3.97929639e+01-1.43996160e-38j, -3.72840673e+01-1.63817277e-38j, -3.48280092e+01-9.99537738e-39j, -3.24550394e+01-3.17721047e-40j, -3.01861437e+01-5.81373831e-42j, -2.80345785e+01-3.10228717e-39j, -2.60074301e+01+1.28594534e-39j, -2.41070531e+01+7.60758754e-39j, -2.23323155e+01+7.97312927e-39j, -2.06796271e+01+5.81693170e-39j, -1.91437566e+01+6.56252079e-39j, -1.77184618e+01+1.10908840e-38j, -1.63969611e+01+1.53872437e-38j, -1.51722763e+01+1.39129399e-38j, -1.40374741e+01+9.43669477e-39j, -1.29858304e+01+9.30920868e-39j, -1.20109359e+01+1.23602737e-38j, -1.11067589e+01+1.41710050e-38j, -1.02676773e+01+1.60717088e-38j, -9.48848876e+00+1.77178302e-38j, -8.76440610e+00+1.48647842e-38j, -8.09104289e+00+1.01146628e-38j, -7.46439287e+00+1.11622279e-38j, -6.88080593e+00+1.66263627e-38j, -6.33696251e+00+1.79488585e-38j, -5.82984767e+00+1.46579657e-38j, -5.35672567e+00+1.34603496e-38j, -4.91511565e+00+1.50574167e-38j, -4.50276874e+00+1.54259944e-38j, -4.11764669e+00+1.52307339e-38j, -3.75790229e+00+1.61072571e-38j, -3.42186130e+00+1.52968997e-38j, -3.10800611e+00+1.33188351e-38j, -2.81496085e+00+1.46531686e-38j, -2.54147800e+00+1.65381249e-38j, -2.28642630e+00+1.48467159e-38j, -2.04877987e+00+1.49987605e-38j, -1.82760852e+00+1.83704612e-38j, -1.62206896e+00+1.68020109e-38j, -1.43139709e+00+1.17510410e-38j, -1.25490103e+00+1.25754442e-38j, -1.09195489e+00+1.71504952e-38j, -9.41993349e-01+1.76972495e-38j, -8.04506695e-01+1.53368883e-38j, -6.79036552e-01+1.46402303e-38j, -5.65172039e-01+1.54974386e-38j, -4.62546411e-01+1.60642465e-38j, -3.70834105e-01+1.59758147e-38j, -2.89748169e-01+1.49361039e-38j, -2.19038018e-01+1.32679253e-38j, -1.58487515e-01+1.40338570e-38j, -1.07913330e-01+1.83256446e-38j, -6.71635483e-02+2.05950514e-38j, -3.61164846e-02+1.65676365e-38j, -1.46794435e-02+1.02374473e-38j, -2.78432418e-03+6.69851727e-39j]]]) ρ['g'] = (-φ['g']/(n+1))**n p['g'] = ρ['g']**(1+1/n) # Iterations def error(perts): return np.sum([np.sum(np.abs(pert['c'])) for pert in perts]) err = np.inf while err > tolerance and solver.iteration < 20: solver.newton_iteration() err = error(solver.perturbations) φcen = φ(r=0).evaluate()['g'][0,0,0] R = -φcen / (n+1)**(3/2) print(solver.iteration, φcen, R, err) dH = solver.subproblems[0].dH_min print('%.2e' %np.linalg.cond(dH.A)) if err > tolerance: raise ValueError("Did not converge") # Compare to reference solutions from Boyd R_ref = {0.0: np.sqrt(6), 0.5: 2.752698054065, 1.0: np.pi, 1.5: 3.65375373621912608, 2.0: 4.3528745959461246769735700, 2.5: 5.355275459010779, 3.0: 6.896848619376960375454528, 3.25: 8.018937527, 3.5: 9.535805344244850444, 4.0: 14.971546348838095097611066, 4.5: 31.836463244694285264} assert np.allclose(R, R_ref[n])