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_spherical_ell_product_scalar(Nphi, Ntheta, Nr, k, dealias, basis, dtype): c, d, b, phi, theta, r, x, y, z = basis(Nphi, Ntheta, Nr, k, dealias, dtype) f = field.Field(dist=d, bases=(b, ), dtype=dtype) g = field.Field(dist=d, bases=(b, ), dtype=dtype) f.preset_scales(b.domain.dealias) f['g'] = 3 * x**2 + 2 * y * z for ell, m_ind, ell_ind in b.ell_maps: g['c'][m_ind, ell_ind, :] = (ell + 3) * f['c'][m_ind, ell_ind, :] func = lambda ell: ell + 3 h = operators.SphericalEllProduct(f, c, func).evaluate() g.preset_scales(b.domain.dealias) assert np.allclose(h['g'], g['g'])
def test_spherical_ell_product_vector(Nphi, Ntheta, Nr, k, dealias, basis, dtype): c, d, b, phi, theta, r, x, y, z = basis(Nphi, Ntheta, Nr, k, dealias, dtype) f = field.Field(dist=d, bases=(b, ), dtype=dtype) f.preset_scales(b.domain.dealias) f['g'] = 3 * x**2 + 2 * y * z u = operators.Gradient(f, c).evaluate() uk0 = field.Field(dist=d, bases=(b, ), tensorsig=(c, ), dtype=dtype) uk0.preset_scales(b.domain.dealias) uk0['g'] = u['g'] v = field.Field(dist=d, bases=(b, ), tensorsig=(c, ), dtype=dtype) v.preset_scales(b.domain.dealias) for ell, m_ind, ell_ind in b.ell_maps: v['c'][0, m_ind, ell_ind, :] = (ell + 2) * uk0['c'][0, m_ind, ell_ind, :] v['c'][1, m_ind, ell_ind, :] = (ell + 4) * uk0['c'][1, m_ind, ell_ind, :] v['c'][2, m_ind, ell_ind, :] = (ell + 3) * uk0['c'][2, m_ind, ell_ind, :] func = lambda ell: ell + 3 w = operators.SphericalEllProduct(u, c, func).evaluate() assert np.allclose(w['g'], v['g'])
# initial toroidal magnetic field B['g'][1] = -3. / 2. * r * (-1 + 4 * r**2 - 6 * r**4 + 3 * r**6) * (np.cos(phi) + np.sin(phi)) B['g'][0] = -3./4.*r*(-1+r**2)*np.cos(theta)* \ ( 3*r*(2-5*r**2+4*r**4)*np.sin(theta) +2*(1-3*r**2+3*r**4)*(np.cos(phi)-np.sin(phi))) # Potential BC on A ell_func = lambda ell: ell + 1 # Parameters and operators div = lambda A: operators.Divergence(A) grad = lambda A: operators.Gradient(A, c) curl = lambda A: operators.Curl(A) LiftTau = lambda A: operators.LiftTau(A, b, -1) ellp1 = lambda A: operators.SphericalEllProduct(A, c, ell_func) radial = lambda A: operators.RadialComponent(A) angular = lambda A: operators.AngularComponent(A, index=1) # BVP for initial A BVP = problems.LBVP([φ, A, τ_A, τ_φ]) #BVP.add_equation((angular(τ_A),0)) BVP.add_equation((div(A) + LiftTau(τ_φ), 0)) BVP.add_equation((curl(A) + grad(φ) + LiftTau(τ_A), B)) BVP.add_equation((radial(grad(A)(r=radius)) + ellp1(A)(r=radius) / radius, 0)) #, condition = "ntheta != 0") BVP.add_equation((φ(r=radius), 0)) #, condition = "ntheta == 0") solver = solvers.LinearBoundaryValueSolver(BVP) solver.solve() plot_matrices = False
# Boundary conditions u_r_bc = operators.RadialComponent(operators.interpolate(u, r=1)) stress = operators.Gradient(u, c) + operators.TransposeComponents( operators.Gradient(u, c)) u_perp_bc = operators.RadialComponent( operators.AngularComponent(operators.interpolate(stress, r=1), index=1)) # Potential BC on B r_out = 1 ell_func = lambda ell: ell + 1 A_potential_bc = operators.RadialComponent( operators.interpolate(operators.Gradient( A, c), r=1)) + operators.interpolate( operators.SphericalEllProduct(A, c, ell_func), r=1) / r_out # Parameters and operators ez = field.Field(dist=d, bases=(b, ), tensorsig=(c, ), dtype=dtype) ez['g'][1] = -np.sin(theta) ez['g'][2] = np.cos(theta) div = lambda A: operators.Divergence(A, index=0) lap = lambda A: operators.Laplacian(A, c) grad = lambda A: operators.Gradient(A, c) dot = lambda A, B: arithmetic.DotProduct(A, B) cross = lambda A, B: arithmetic.CrossProduct(A, B) ddt = lambda A: operators.TimeDerivative(A) curl = lambda A: operators.Curl(A) LiftTau = lambda A: operators.LiftTau(A, b, -1)
2 * r_inner**4 / r**3) * np.cos(theta) # Parameters and operators div = lambda A: operators.Divergence(A, index=0) lap = lambda A: operators.Laplacian(A, c) grad = lambda A: operators.Gradient(A, c) dot = lambda A, B: arithmetic.DotProduct(A, B) cross = lambda A, B: arithmetic.CrossProduct(A, B) ddt = lambda A: operators.TimeDerivative(A) curl = lambda A: operators.Curl(A) ell_func = lambda ell: ell + 1 A_potential_bc_outer = operators.RadialComponent( operators.interpolate(operators.Gradient( A, c), r=r_outer)) + operators.interpolate( operators.SphericalEllProduct(A, c, ell_func), r=r_outer) / r_outer A_potential_bc_inner = operators.RadialComponent( operators.interpolate(operators.Gradient( A, c), r=r_inner)) + operators.interpolate( operators.SphericalEllProduct(A, c, ell_func), r=r_inner) / r_inner # Problem def eq_eval(eq_str): return [eval(expr) for expr in split_equation(eq_str)] V = de.field.Field(dist=d, bases=(b, ), dtype=np.complex128) BVP = problems.LBVP([A, V, tau_A_inner, tau_A_outer])