Esempio n. 1
0
def initialize(solver, context):
    c = context
    # Create mask with ones where |k| < Kf2 and zeros elsewhere
    kf = config.params.Kf2
    c.k2_mask = np.where(c.K2 <= kf**2, 1, 0)
    np.random.seed(solver.rank)
    k = np.sqrt(c.K2)
    k = np.where(k == 0, 1, k)
    kk = c.K2.copy()
    kk = np.where(kk == 0, 1, kk)
    k1, k2, k3 = c.K[0], c.K[1], c.K[2]
    ksq = np.sqrt(k1**2 + k2**2)
    ksq = np.where(ksq == 0, 1, ksq)

    E0 = np.sqrt(9. / 11. / kf * c.K2 / kf**2) * c.k2_mask
    E1 = np.sqrt(9. / 11. / kf * (k / kf)**(-5. / 3.)) * (1 - c.k2_mask)
    Ek = E0 + E1
    # theta1, theta2, phi, alpha and beta from [1]
    theta1, theta2, phi = np.random.sample(c.U_hat.shape) * 2j * np.pi
    alpha = np.sqrt(Ek / 4. / np.pi / kk) * np.exp(1j * theta1) * np.cos(phi)
    beta = np.sqrt(Ek / 4. / np.pi / kk) * np.exp(1j * theta2) * np.sin(phi)
    c.U_hat[0] = (alpha * k * k2 + beta * k1 * k3) / (k * ksq)
    c.U_hat[1] = (beta * k2 * k3 - alpha * k * k1) / (k * ksq)
    c.U_hat[2] = beta * ksq / k
    c.mask = c.T.get_mask_nyquist()
    c.T.mask_nyquist(c.U_hat, c.mask)

    solver.get_velocity(**c)
    U_hat = solver.set_velocity(**c)

    K = c.K
    # project to zero divergence
    U_hat[:] -= (K[0] * U_hat[0] + K[1] * U_hat[1] +
                 K[2] * U_hat[2]) * c.K_over_K2

    if solver.rank == 0:
        c.U_hat[:, 0, 0, 0] = 0.0

    # Scale to get correct kinetic energy. Target from [2]
    energy = 0.5 * energy_fourier(c.U_hat, c.T)
    target = config.params.Re_lam * (config.params.nu *
                                     config.params.kd)**2 / np.sqrt(20. / 3.)
    c.U_hat *= np.sqrt(target / energy)

    if 'VV' in config.params.solver:
        c.W_hat = solver.cross2(c.W_hat, c.K, c.U_hat)

    config.params.t = 0.0
    config.params.tstep = 0
    c.target_energy = energy_fourier(c.U_hat, c.T)
Esempio n. 2
0
def init_from_file(filename, solver, context):
    f = h5py.File(filename, driver="mpio", comm=solver.comm)
    assert "0" in f["U/3D"]
    U_hat = context.U_hat
    s = context.T.local_slice(True)

    U_hat[:] = f["U/3D/0"][:, s[0], s[1], s[2]]
    if solver.rank == 0:
        U_hat[:, 0, 0, 0] = 0.0

    if 'VV' in config.params.solver:
        context.W_hat = solver.cross2(context.W_hat, context.K, context.U_hat)

    context.target_energy = energy_fourier(U_hat, context.T)

    f.close()
Esempio n. 3
0
def test_energy_fourier(N):
    B0 = FunctionSpace(N[0], 'F', dtype='D')
    B1 = FunctionSpace(N[1], 'F', dtype='D')
    B2 = FunctionSpace(N[2], 'F', dtype='d')
    for bases, axes in zip(((B0, B1, B2), (B0, B2, B1)),
                           ((0, 1, 2), (2, 0, 1))):
        T = TensorProductSpace(comm, bases, axes=axes)
        u_hat = Function(T)
        u_hat[:] = np.random.random(
            u_hat.shape) + 1j * np.random.random(u_hat.shape)
        u = u_hat.backward()
        u_hat = u.forward(u_hat)
        u = u_hat.backward(u)
        e0 = comm.allreduce(np.sum(u.v * u.v) / np.prod(N))
        e1 = fourier.energy_fourier(u_hat, T)
        assert abs(e0 - e1) < 1e-10
Esempio n. 4
0
def update(context):
    global k, w, im1
    c = context
    params = config.params
    solver = config.solver

    if (params.tstep % params.compute_energy == 0
            or params.tstep % params.plot_step == 0 and params.plot_step > 0):
        U = solver.get_velocity(**c)
        curl = solver.get_curl(**c)
        if 'NS' in params.solver:
            solver.get_pressure(**c)

    if plt is not None:
        if params.tstep % params.plot_step == 0 and solver.rank == 0 and params.plot_step > 0:
            if im1 is None:
                plt.figure()
                im1 = plt.contourf(c.X[1][:, :, 0], c.X[0][:, :, 0],
                                   U[0, :, :, 10], 100)
                plt.colorbar(im1)
                plt.draw()
                globals().update(im1=im1)
            else:
                im1.ax.clear()
                im1.ax.contourf(c.X[1][:, :, 0], c.X[0][:, :, 0], U[0, :, :,
                                                                    10], 100)
                im1.autoscale()
            plt.pause(1e-6)

    if params.tstep == 1:
        from spectralDNS.utilities import reset_profile
        try:
            reset_profile(profile)
            print("Reset profile")
        except:
            pass

    if params.tstep % params.compute_energy == 0:
        #dx, L = params.dx, params.L
        #if 'NS' in params.solver:
        #ww = comm.reduce(sum(curl*curl)/prod(params.N)/2)

        #duidxj = work[(((3,3)+FFT.real_shape()), FFT.float, 0)]
        #for i in range(3):
        #for j in range(3):
        #duidxj[i,j] = FFT.ifftn(1j*K[j]*U_hat[i], duidxj[i,j])
        #ww2 = comm.reduce(sum(duidxj*duidxj)/prod(params.N)/2)

        #ddU = work[(((3,)+FFT.real_shape()), FFT.float, 0)]
        #dU = ComputeRHS(dU, U_hat)
        #for i in range(3):
        #ddU[i] = FFT.ifftn(dU[i], ddU[i])
        #ww3 = comm.reduce(sum(ddU*U)/prod(params.N)/2)

        #if rank == 0:
        #print ww, params.nu*ww2, ww3, ww-ww2

        ww = solver.comm.reduce(
            sum(curl.astype(float64) * curl.astype(float64)) / prod(params.N) /
            2)
        kk = solver.comm.reduce(
            sum(U.astype(float64) * U.astype(float64)) / prod(params.N) /
            2)  # Compute energy with double precision
        if not 'NS' in params.solver:
            c.U_hat = c.U.forward(c.U_hat)
        ww2 = energy_fourier(c.U_hat, c.T) / 2
        divu = solver.get_divergence(**context)
        divu = solver.comm.reduce(
            sum(divu.astype(float64) * divu.astype(float64)) / prod(params.N) /
            2)

        kold[0] = kk
        if solver.rank == 0:
            k.append(kk)
            w.append(ww)
            print("%2.2f %2.8f %2.8e %2.8e" %
                  (params.t, float(kk), float(ww2 - kk), float(divu)))
Esempio n. 5
0
def update(context):
    global k, w, im1, energy_new
    c = context
    params = config.params
    solver = config.solver
    curl_hat = Function(c.VT, buffer=c.work[(c.U_hat, 2, True)])

    if solver.rank == 0:
        c.U_hat[:, 0, 0, 0] = 0

    if params.solver == 'VV':
        c.U_hat = solver.cross2(c.U_hat, c.K_over_K2, c.W_hat)

    energy_new = energy_fourier(c.U_hat, c.T)
    energy_lower = energy_fourier(c.U_hat * c.k2_mask, c.T)
    energy_upper = energy_new - energy_lower

    alpha2 = (c.target_energy - energy_upper) / energy_lower
    alpha = np.sqrt(alpha2)

    #du = c.U_hat*c.k2_mask*(alpha)
    #dus = energy_fourier(du*c.U_hat, c.T)

    energy_old = energy_new

    #c.dU[:] = alpha*c.k2_mask*c.U_hat
    c.U_hat *= (alpha * c.k2_mask + (1 - c.k2_mask))

    energy_new = energy_fourier(c.U_hat, c.T)

    assert np.sqrt((energy_new - c.target_energy)**2) < 1e-7, np.sqrt(
        (energy_new - c.target_energy)**2)

    if params.solver == 'VV':
        c.W_hat = solver.cross2(c.W_hat, c.K, c.U_hat)

    if (params.tstep % params.compute_energy == 0
            or params.tstep % params.plot_step == 0 and params.plot_step > 0):
        solver.get_velocity(**c)
        solver.get_curl(**c)
        if 'NS' in params.solver:
            solver.get_pressure(**c)

    K = c.K
    if plt is not None:
        if params.tstep % params.plot_step == 0 and solver.rank == 0 and params.plot_step > 0:
            #div_u = solver.get_divergence(**c)

            if not plt.fignum_exists(1):
                plt.figure(1)
                #im1 = plt.contourf(c.X[1][:,:,0], c.X[0][:,:,0], div_u[:,:,10], 100)
                im1 = plt.contourf(c.X[1][..., 0], c.X[0][..., 0],
                                   c.U[0, ..., 10], 100)
                plt.colorbar(im1)
                plt.draw()
            else:
                im1.ax.clear()
                #im1.ax.contourf(c.X[1][:,:,0], c.X[0][:,:,0], div_u[:,:,10], 100)
                im1.ax.contourf(c.X[1][..., 0], c.X[0][..., 0], c.U[0, ...,
                                                                    10], 100)
                im1.autoscale()
            plt.pause(1e-6)

    if params.tstep % params.compute_spectrum == 0:
        Ek, _, _, _, _ = spectrum(solver, context)
        f = h5py.File(context.spectrumname, driver='mpio', comm=solver.comm)
        f['Turbulence/Ek'].create_dataset(str(params.tstep), data=Ek)
        f.close()

    if params.tstep % params.compute_energy == 0:
        dx, L = params.dx, params.L
        #ww = solver.comm.reduce(sum(curl*curl)/np.prod(params.N)/2)

        duidxj = np.zeros(((3, 3) + c.U[0].shape), dtype=c.float)
        for i in range(3):
            for j in range(3):
                duidxj[i, j] = c.T.backward(1j * K[j] * c.U_hat[i], duidxj[i,
                                                                           j])

        ww2 = L2_norm(solver.comm, duidxj) * params.nu
        #ww2 = solver.comm.reduce(sum(duidxj*duidxj))

        ddU = np.zeros(((3, ) + c.U[0].shape), dtype=c.float)
        dU = solver.ComputeRHS(c.dU, c.U_hat, solver, **c)
        for i in range(3):
            ddU[i] = c.T.backward(dU[i], ddU[i])

        ww3 = solver.comm.allreduce(sum(ddU * c.U)) / np.prod(params.N)

        ##if solver.rank == 0:
        ##print('W ', params.nu*ww, params.nu*ww2, ww3, ww-ww2)
        curl_hat = solver.cross2(curl_hat, K, c.U_hat)
        dissipation = energy_fourier(curl_hat, c.T)
        div_u = solver.get_divergence(**c)
        #du = 1j*(c.K[0]*c.U_hat[0]+c.K[1]*c.U_hat[1]+c.K[2]*c.U_hat[2])
        div_u = L2_norm(solver.comm, div_u)
        #div_u2 = energy_fourier(solver.comm, 1j*(K[0]*c.U_hat[0]+K[1]*c.U_hat[1]+K[2]*c.U_hat[2]))

        kk = 0.5 * energy_new
        eps = dissipation * params.nu
        Re_lam = np.sqrt(20 * kk**2 / (3 * params.nu * eps))
        Re_lam2 = kk * np.sqrt(20. / 3.) / (params.nu * params.kd)**2

        kold[0] = energy_new
        e0, e1 = energy_new, L2_norm(solver.comm, c.U)
        ww4 = (energy_new - energy_old) / 2 / params.dt
        if solver.rank == 0:
            k.append(energy_new)
            w.append(dissipation)
            print('%2.4f %2.6e %2.6e %2.6e %2.6e %2.6e %2.6e %2.6e %2.6e' %
                  (params.t, e0, e1, eps, ww2, ww3, ww4, Re_lam, Re_lam2))