void linear_diffusion_AOS(T& g, double delta_t, C2DImage<double>& g_n)
{
    int j, k; 
    double *d, *out, *L, *M, *R; 
    double *alpha, *beta, *gamma; 
    
    
    // Along the column direction. 
    NEW_MACRO(g.m_dims[1]);
    div_AOS_1D(delta_t, g.m_dims[1],alpha, gamma, L, M, R);
    for(j = 0; j < g.m_dims[0]; j++)
    {
        g.GetColon2(d, j);
        ac_tridiagonal_Thomas_solution(L, M, R, d, out, g.m_dims[1]);
        g_n.AddColon2(out, j);
        
    }
    DELETE_MACRO;
    
    // Along the row direction. 
    NEW_MACRO(g.m_dims[0]);
    div_AOS_1D(delta_t, g.m_dims[0],alpha, gamma, L, M, R);  
    for(j = 0; j < g.m_dims[1]; j++)
    {
        g.GetColon1(d, j);
        ac_tridiagonal_Thomas_solution(L, M, R, d, out, g.m_dims[0]);
        g_n.AddColon1(out, j);
    }
    DELETE_MACRO;
}
void div_AOS_3D(C3DImage<double>& phi,  T& g, double delta_t,
    C3DImage<double>& phi_n)
{
    int j, k; 
    double *p, *d, *out, *L, *M, *R; 
    double *alpha, *beta, *gamma; 
    
    // Along the plane direction. 
    NEW_MACRO(g.m_dims[2]);
    for(j = 0; j < g.m_dims[0]; j++)
    {
        for(k = 0; k < g.m_dims[1]; k++)
        {
            g.GetColon3(p, j, k); 
            div_AOS_1D(p, delta_t, g.m_dims[2],alpha, beta, gamma, L, M, R);  
//             PRINT_MACRO(" L : ", L, g.m_dims[2]-1);
//             PRINT_MACRO(" M : ", M, g.m_dims[2]);
//             PRINT_MACRO(" R : ", R, g.m_dims[2]-1);
            phi.GetColon3(d, j, k); 
            ac_tridiagonal_Thomas_solution(L, M, R, d, out, g.m_dims[2]);
            phi_n.SetColon3(out, j, k);
        }
    }
    DELETE_MACRO;
    
    // Along the column direction. 
    NEW_MACRO(g.m_dims[1]);
    for(j = 0; j < g.m_dims[0]; j++)
    {
        for(k = 0; k < g.m_dims[2]; k++)
        {
            g.GetColon2(p, j, k); 
            div_AOS_1D(p, delta_t, g.m_dims[1],alpha, beta, gamma, L, M, R);  
            phi.GetColon2(d, j, k); 
            ac_tridiagonal_Thomas_solution(L, M, R, d, out, g.m_dims[1]);
            phi_n.AddColon2(out, j, k);
        }
    }
    DELETE_MACRO;
    
    // Along the row direction. 
    NEW_MACRO(g.m_dims[0]);
    for(j = 0; j < g.m_dims[1]; j++)
    {
        for(k = 0; k < g.m_dims[2]; k++)
        {
            g.GetColon1(p, j, k); 
            div_AOS_1D(p, delta_t, g.m_dims[0],alpha, beta, gamma, L, M, R);  
            phi.GetColon1(d, j, k); 
            ac_tridiagonal_Thomas_solution(L, M, R, d, out, g.m_dims[0]);
            phi_n.AddColon1(out, j, k);
        }
    }
    DELETE_MACRO;
}