コード例 #1
0
N_dealias = 1
dt = 0.01
t_end = 3
ts = timesteppers.CNAB2

# Bases
c = coords.SphericalCoordinates('phi', 'theta', 'r')
d = distributor.Distributor((c, ))
b = basis.BallBasis(c, (2 * (Lmax + 1), Lmax + 1, Nmax + 1),
                    radius=radius,
                    dealias=(L_dealias, L_dealias, N_dealias))
b_S2 = b.S2_basis()
phi, theta, r = b.local_grids((1, 1, 1))

# Fields
T = field.Field(dist=d, bases=(b, ), dtype=np.complex128)
tau = field.Field(dist=d, bases=(b_S2, ), dtype=np.complex128)

prefactor = field.Field(dist=d, bases=(b.radial_basis, ), dtype=np.complex128)
prefactor['g'] = 1 / (1 + r**4)

forcing = field.Field(dist=d, bases=(b, ), dtype=np.complex128)
forcing['g'] = 1 / (1 + r**2)

# Parameters and operators
ez = field.Field(dist=d, bases=(b, ), tensorsig=(c, ), dtype=np.complex128)
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)
コード例 #2
0
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])
コード例 #3
0
ファイル: GT_dirichlet.py プロジェクト: thoeschler/shenfun
def main(N, alpha, method, tau):
    # Bases
    c = coords.Coordinate('x')
    d = distributor.Distributor((c,))
    xb = basis.ChebyshevT(c, size=N, bounds=(-1, 1))
    x = xb.local_grid(1)
    # Fields
    u = field.Field(name='u', dist=d, bases=(xb,), dtype=np.float64)
    ux = field.Field(name='ux', dist=d, bases=(xb,), dtype=np.float64)
    f = field.Field(name='f', dist=d, bases=(xb,), dtype=np.float64)
    t1 = field.Field(name='t1', dist=d, dtype=np.float64)
    t2 = field.Field(name='t2', dist=d, dtype=np.float64)
    pi, sin, cos = np.pi, np.sin, np.cos
    f['g'] = 64*pi**3*(4*pi*sin(4*pi*x)**2*sin(4*pi*cos(4*pi*x)) + cos(4*pi*x)*cos(4*pi*cos(4*pi*x))) + alpha*sin(4*pi*cos(4*pi*x))
    # Tau polynomials
    xb1 = xb._new_a_b(xb.a+1, xb.b+1)
    xb2 = xb._new_a_b(xb.a+2, xb.b+2)
    if tau == 0:
        # First-order classical Chebyshev tau: T[-1], dx(T[-1])
        p1 = field.Field(name='p1', dist=d, bases=(xb,), dtype=np.float64)
        p2 = field.Field(name='p2', dist=d, bases=(xb,), dtype=np.float64)
        p1['c'][-1] = 1
        p2['c'][-1] = 1
    elif tau == 1:
        # First-order ultraspherical tau: U[-1], dx(U[-1])
        p1 = field.Field(name='p1', dist=d, bases=(xb1,), dtype=np.float64)
        p2 = field.Field(name='p2', dist=d, bases=(xb1,), dtype=np.float64)
        p1['c'][-1] = 1
        p2['c'][-1] = 1
    # Problem
    dx = lambda A: operators.Differentiate(A, c)
    problem = problems.LBVP([u, ux, t1, t2])
    problem.add_equation((alpha*u - dx(ux) + t1*p1, f))
    problem.add_equation((ux - dx(u) + t2*p2, 0))
    problem.add_equation((u(x=-1), 0))
    problem.add_equation((u(x=+1), 0))
    solver = solvers.LinearBoundaryValueSolver(problem)
    # Methods
    if method == 0:
        # Condition number
        L_exp = solver.subproblems[0].L_exp
        result = np.linalg.cond(L_exp.A)
    elif method == 1:
        # Roundtrip roundoff with uniform u
        A = solver.subproblems[0].L_exp
        v = np.random.rand(A.shape[1])
        f = A * v
        u = solver.subproblem_matsolvers[solver.subproblems[0]].solve(f)
        result = np.max(np.abs(u-v))
    elif method == 2:
        # Manufactured solution
        from mpi4py_fft import fftw as mpi4py_fftw
        solver.solve()
        ue = np.sin(4*np.pi*np.cos(4*np.pi*x))
        d = mpi4py_fftw.aligned(N, fill=0)
        k = 2*(1 + np.arange((N-1)//2))
        d[::2] = (2./N)/np.hstack((1., 1.-k*k))
        w = mpi4py_fftw.aligned_like(d)
        dct = mpi4py_fftw.dctn(w, axes=(0,), type=3)
        weights = dct(d, w)
        result = np.sqrt(np.sum(weights*(u['g']-ue)**2))
    elif method == 3:
        # Roundtrip roundoff with uniform f
        A = solver.subproblems[0].L_exp
        g = np.random.rand(A.shape[0])
        v = solver.subproblem_matsolvers[solver.subproblems[0]].solve(g)
        f = A * v
        u = solver.subproblem_matsolvers[solver.subproblems[0]].solve(f)
        result = np.max(np.abs(u-v))
    return result
コード例 #4
0
c = coords.SphericalCoordinates('phi', 'theta', 'r')
c_S2 = c.S2coordsys
d = distributor.Distributor((c, ), mesh=mesh)
bB = basis.BallBasis(c, (2 * (Lmax + 1), Lmax + 1, Nmax + 1),
                     radius=radius / 2,
                     dtype=dtype)
bS = basis.SphericalShellBasis(c, (2 * (Lmax + 1), Lmax + 1, Nmax + 1),
                               radii=(radius / 2, radius),
                               dtype=dtype)
bmid = bB.S2_basis(radius=radius / 2)
btop = bS.S2_basis(radius=radius)
phi_B, theta_B, r_B = bB.local_grids((1, 1, 1))
phi_S, theta_S, r_S = bS.local_grids((1, 1, 1))

# Fields
uB = field.Field(dist=d, bases=(bB, ), dtype=dtype, tensorsig=(c, ))
pB = field.Field(dist=d, bases=(bB, ), dtype=dtype)
tB = field.Field(dist=d, bases=(bmid, ), dtype=dtype, tensorsig=(c, ))
uS = field.Field(dist=d, bases=(bS, ), dtype=dtype, tensorsig=(c, ))
pS = field.Field(dist=d, bases=(bS, ), dtype=dtype)
tS1 = field.Field(dist=d, bases=(bmid, ), dtype=dtype, tensorsig=(c, ))
tS2 = field.Field(dist=d, bases=(btop, ), dtype=dtype, tensorsig=(c, ))

# Boundary conditions
utop = field.Field(dist=d, bases=(btop, ), dtype=dtype, tensorsig=(c, ))
utop['g'][2] = 0.  # u_r = 0
utop['g'][1] = -u0 * np.cos(theta_S) * np.cos(phi_S)
utop['g'][0] = u0 * np.sin(phi_S)

# Parameters and operators
ezB = field.Field(dist=d, bases=(bB, ), dtype=dtype, tensorsig=(c, ))
コード例 #5
0
Nx, Nz = 32, 32
Prandtl = 1
Rayleigh = 1e5
timestep = 0.01
stop_iteration = 10

# Bases
c = coords.CartesianCoordinates('x', 'z')
d = distributor.Distributor((c, ))
xb = basis.ComplexFourier(c.coords[0], size=Nx, bounds=(0, Lx))
zb = basis.ChebyshevT(c.coords[1], size=Nz, bounds=(0, Lz))
x = xb.local_grid(1)
z = zb.local_grid(1)

# Fields
p = field.Field(name='p', dist=d, bases=(xb, zb), dtype=np.complex128)
b = field.Field(name='b', dist=d, bases=(xb, zb), dtype=np.complex128)
u = field.Field(name='u',
                dist=d,
                bases=(xb, zb),
                dtype=np.complex128,
                tensorsig=(c, ))
bz = field.Field(name='bz', dist=d, bases=(xb, zb), dtype=np.complex128)
uz = field.Field(name='uz',
                 dist=d,
                 bases=(xb, zb),
                 dtype=np.complex128,
                 tensorsig=(c, ))

# Taus
zb1 = basis.ChebyshevU(c.coords[1], size=Nz, bounds=(0, Lz), alpha0=0)
コード例 #6
0
# Bases
c = coords.SphericalCoordinates('phi', 'theta', 'r')
d = distributor.Distributor((c, ), mesh=None)
b = basis.SphericalShellBasis(c, (2 * (Lmax + 1), Lmax + 1, Nmax + 1),
                              radii=radii)
b_inner = b.S2_basis(radius=radii[0])
b_outer = b.S2_basis(radius=radii[1])
phi, theta, r = b.local_grids((1, 1, 1))
phig, thetag, rg = b.global_grids((1, 1, 1))
theta_target = thetag[0, (Lmax + 1) // 2, 0]
x = r * np.sin(theta) * np.cos(phi)
y = r * np.sin(theta) * np.sin(phi)
z = r * np.cos(theta)

# Fields
u = field.Field(dist=d, bases=(b, ), tensorsig=(c, ), dtype=np.complex128)
T = field.Field(dist=d, bases=(b, ), dtype=np.complex128)

# solid body rotation
Omega = 2 * np.pi
u['g'][0] = Omega * r * np.sin(theta)

# perturbation
x0 = 1.75
y0 = 0
z0 = 0
T['g'] = T_init = np.exp(-((x - x0)**2 + (y - y0)**2 + (z - z0)**2) / 0.5**2)

# Parameters and operators
div = lambda A: operators.Divergence(A, index=0)
lap = lambda A: operators.Laplacian(A, c)