from compact import CompactFiniteDifferenceSolver
import matplotlib.pyplot as plt

comm = MPI.COMM_WORLD
da = DA(comm, (8, 32, 16), (2, 2, 2), 1)
x, y, z = DA_arange(da, (0, 2 * np.pi), (0, 2 * np.pi), (0, 2 * np.pi))
f = y * np.cos(x * y) + np.sin(z) * y
dfdx_true = (-y**2) * np.sin(x * y)
dfdy_true = -(x * y) * np.sin(x * y) + np.cos(x * y) + np.sin(z)
dfdz_true = y * np.cos(z)

dz = z[1, 0, 0] - z[0, 0, 0]
dy = y[0, 1, 0] - y[0, 0, 0]
dx = x[0, 0, 1] - x[0, 0, 0]

cfd = CompactFiniteDifferenceSolver(da)

dfdx = cfd.dfdx(f, dx)
dfdx_global = np.zeros([16, 64, 32], dtype=np.float64)
dfdx_true_global = np.zeros([16, 64, 32], dtype=np.float64)

DA_gather_blocks(da, dfdx, dfdx_global)
DA_gather_blocks(da, dfdx_true, dfdx_true_global)

if comm.Get_rank() == 0:
    plt.plot(np.linspace(0, 2 * np.pi, 32), dfdx_global[8, 32, :], 'o-')
    plt.plot(np.linspace(0, 2 * np.pi, 32), dfdx_true_global[8, 32, :])

dfdy = cfd.dfdy(f, dy)
dfdy_global = np.zeros([16, 64, 32], dtype=np.float64)
dfdy_true_global = np.zeros([16, 64, 32], dtype=np.float64)
from compact import CompactFiniteDifferenceSolver
from numpy.testing import *
from pycuda import autoinit
import pycuda.gpuarray as gpuarray    

comm = MPI.COMM_WORLD 
rank = comm.Get_rank()

mean_errs = []
max_errs = []
sizes = [16, 32, 64, 128, 256]

for i, N in enumerate(sizes):
    da = DA(comm, (N, N, N), (2, 2, 2), 1)
    line_da = da.get_line_DA(0)
    cfd = CompactFiniteDifferenceSolver(line_da)
    x, y, z = DA_arange(da, (0, 2*np.pi), (0, 2*np.pi), (0, 2*np.pi))
    f = np.sin(x) + np.cos(y*x) + z*x
    f_d = gpuarray.to_gpu(f)
    x_d = da.create_global_vector()
    f_local_d = da.create_local_vector()
    dfdx_true = np.cos(x) + -y*np.sin(y*x) + z
    dx = x[0, 0, 1] - x[0, 0, 0]
    cfd.dfdx(f_d, dx, x_d, f_local_d)
    dfdx = x_d.get()
    err = np.abs(dfdx-dfdx_true)/np.max(abs(dfdx))
    mean_err = np.mean(np.abs(dfdx-dfdx_true)/np.max(abs(dfdx)))
    max_err = np.max(np.abs(dfdx-dfdx_true)/np.max(abs(dfdx)))
    mean_errs.append(mean_err)
    max_errs.append(max_err)
import sys
sys.path.append('..')
import numpy as np
from mpi4py import MPI
from mpi_util import *
from compact import CompactFiniteDifferenceSolver
from numpy.testing import *

comm = MPI.COMM_WORLD 
da_regular = DA(comm, (8, 8, 8), (2, 2, 2), 1)
da_irregular = DA(comm, (8, 32, 16), (2, 2, 2), 1)
cfd_regular = CompactFiniteDifferenceSolver(da_regular)
cfd_irregular = CompactFiniteDifferenceSolver(da_irregular)

def test_dfdx_sine_regular():
    x, y, z = DA_arange(da_regular, (0, 2*np.pi), (0, 2*np.pi), (0, 2*np.pi))
    f = np.sin(x) 
    dfdx_true = np.cos(x) 
    dx = x[0, 0, 1] - x[0, 0, 0]
    dfdx = cfd_regular.dfdx(f, dx)
    assert_almost_equal(dfdx_true, dfdx, decimal=2)
    if comm.Get_rank() == 0:
        print 'pass'

def test_dfdx_sine_irregular():
    x, y, z = DA_arange(da_irregular, (0, 2*np.pi), (0, 2*np.pi), (0, 2*np.pi))
    f = np.sin(x) 
    dfdx_true = np.cos(x) 
    dx = x[0, 0, 1] - x[0, 0, 0]
    dfdx = cfd_irregular.dfdx(f, dx)
    assert_almost_equal(dfdx_true, dfdx, decimal=2)
from compact import CompactFiniteDifferenceSolver
import matplotlib.pyplot as plt

comm = MPI.COMM_WORLD 
da = DA(comm, (8, 32, 16), (2, 2, 2), 1)
x, y, z = DA_arange(da, (0, 2*np.pi), (0, 2*np.pi), (0, 2*np.pi))
f = y*np.cos(x*y) + np.sin(z)*y
dfdx_true = (-y**2)*np.sin(x*y)
dfdy_true = -(x*y)*np.sin(x*y) + np.cos(x*y) + np.sin(z)
dfdz_true = y*np.cos(z)

dz = z[1, 0, 0] - z[0, 0, 0]
dy = y[0, 1, 0] - y[0, 0, 0]
dx = x[0, 0, 1] - x[0, 0, 0]

cfd = CompactFiniteDifferenceSolver(da)

dfdx = cfd.dfdx(f, dx)
dfdx_global = np.zeros([16, 64, 32], dtype=np.float64)
dfdx_true_global = np.zeros([16, 64, 32], dtype=np.float64)

DA_gather_blocks(da, dfdx, dfdx_global)
DA_gather_blocks(da, dfdx_true, dfdx_true_global)

if comm.Get_rank() == 0:
    plt.plot(np.linspace(0, 2*np.pi, 32), dfdx_global[8, 32, :], 'o-')
    plt.plot(np.linspace(0, 2*np.pi, 32), dfdx_true_global[8, 32, :])

dfdy = cfd.dfdy(f, dy)
dfdy_global = np.zeros([16, 64, 32], dtype=np.float64)
dfdy_true_global = np.zeros([16, 64, 32], dtype=np.float64)
from compact import CompactFiniteDifferenceSolver
from numpy.testing import *
from pycuda import autoinit
import pycuda.gpuarray as gpuarray

comm = MPI.COMM_WORLD
rank = comm.Get_rank()

mean_errs = []
max_errs = []
sizes = [16, 32, 64, 128, 256]

for i, N in enumerate(sizes):
    da = DA(comm, (N, N, N), (2, 2, 2), 1)
    line_da = da.get_line_DA(0)
    cfd = CompactFiniteDifferenceSolver(line_da)
    x, y, z = DA_arange(da, (0, 2 * np.pi), (0, 2 * np.pi), (0, 2 * np.pi))
    f = np.sin(x) + np.cos(y * x) + z * x
    f_d = gpuarray.to_gpu(f)
    x_d = da.create_global_vector()
    f_local_d = da.create_local_vector()
    dfdx_true = np.cos(x) + -y * np.sin(y * x) + z
    dx = x[0, 0, 1] - x[0, 0, 0]
    cfd.dfdx(f_d, dx, x_d, f_local_d)
    dfdx = x_d.get()
    err = np.abs(dfdx - dfdx_true) / np.max(abs(dfdx))
    mean_err = np.mean(np.abs(dfdx - dfdx_true) / np.max(abs(dfdx)))
    max_err = np.max(np.abs(dfdx - dfdx_true) / np.max(abs(dfdx)))
    mean_errs.append(mean_err)
    max_errs.append(max_err)