/* tests.hh - This file is part of MUSIC - a code to generate multi-scale initial conditions for cosmological simulations Copyright (C) 2010 Oliver Hahn */ #ifndef __TESTS_HH #define __TESTS_HH #include inline double CIC_interp_back( const MeshvarBnd& A, double x, double y, double z ) { int ix = (int)x, iy = (int)y, iz = (int)z, ix1 = (ix+1), iy1 = (iy+1), iz1 = (iz+1); double dx = (double)(x - (double)ix), dy = (double)(y - (double)iy), dz = (double)(z - (double)iz), tx = 1.0-dx, ty = 1.0-dy, tz = 1.0-dz; double f_xyz = A(ix,iy,iz)*tx*ty*tz, f_Xyz = A(ix1,iy,iz)*dx*ty*tz, f_xYz = A(ix,iy1,iz)*tx*dy*tz, f_xyZ = A(ix,iy,iz1)*tx*ty*dz, f_XYz = A(ix1,iy1,iz)*dx*dy*tz, f_XyZ = A(ix1,iy,iz1)*dx*ty*dz, f_xYZ = A(ix,iy1,iz1)*tx*dy*dz, f_XYZ = A(ix1,iy1,iz1)*dx*dy*dz; return f_xyz + f_Xyz + f_xYz + f_xyZ + f_XYz + f_XyZ + f_xYZ + f_XYZ; } inline double TSC_interp_back( const MeshvarBnd& A, double x, double y, double z ) { double val = 0.0; int xngp = (int)x, yngp = (int)y, zngp = (int)z; for( int xx = xngp-1; xx <= xngp+1; ++xx ) { double weightx = 1.0; double dx = fabs(x-(double)xx); int axx(xx); if( xx==xngp ) weightx *= 0.75-dx*dx; else{ weightx *= 1.125 - 1.5*dx + 0.5*dx*dx; } for( int yy = yngp-1; yy <= yngp+1; ++yy ) { double weighty = weightx; double dy = fabs(y-(double)yy); int ayy(yy); if( yy==yngp ) weighty *= 0.75-dy*dy; else{ weighty *= 1.125 - 1.5*dy + 0.5*dy*dy; } for( int zz = zngp-1; zz <= zngp+1; ++zz ) { double weightz = weighty; double dz = fabs(z-(double)zz); int azz(zz); if( zz==zngp ) weightz *= 0.75-dz*dz; else{ weightz *= 1.125 - 1.5*dz + 0.5*dz*dz; } val += A(axx,ayy,azz) * weightz; } } } return val; } class TestProblem{ public: MeshvarBnd m_rho, m_uana, m_ubnd, m_xgrad, m_ygrad, m_zgrad; int m_nb, m_nres; double m_h; TestProblem( int nb, int nres ) : m_rho( nb, nres ), m_uana( nb, nres ), m_ubnd( nb, nres ), m_xgrad( nb, nres ), m_ygrad( nb, nres ), m_zgrad( nb, nres ), m_nb( nb ), m_nres( nres ), m_h( 1.0/((double)nres ) )//m_h( 1.0/((double)nres+1.0 ) ) { } }; class TSC_Test : public TestProblem{ public: double m_q; class TSCcube{ public: std::vector m_data; TSCcube() { m_data.assign(27,0.0); //.. center (*this)( 0, 0, 0) = 27./64.; //.. faces (*this)(-1, 0, 0) = (*this)(+1, 0, 0) = (*this)( 0,-1, 0) = (*this)( 0,+1, 0) = (*this)( 0, 0,-1) = (*this)( 0, 0,+1) = 9./128.; //.. edges (*this)(-1,-1, 0) = (*this)(-1,+1, 0) = (*this)(+1,-1, 0) = (*this)(+1,+1, 0) = (*this)(-1, 0,-1) = (*this)(-1, 0,+1) = (*this)(+1, 0,-1) = (*this)(+1, 0,+1) = (*this)( 0,-1,-1) = (*this)( 0,-1,+1) = (*this)( 0,+1,-1) = (*this)( 0,+1,+1) = 3./256.; //.. corners (*this)(-1,-1,-1) = (*this)(-1,+1,-1) = (*this)(-1,-1,+1) = (*this)(-1,+1,+1) = (*this)(+1,-1,-1) = (*this)(+1,+1,-1) = (*this)(+1,-1,+1) = (*this)(+1,+1,+1) = 1./512.; } double& operator()(int i, int j, int k) { return m_data[ ((i+1)*3+(j+1))*3 +(k+1)]; } const double& operator()(int i, int j, int k) const { return m_data[ ((i+1)*3+(j+1))*3 +(k+1)]; } }; TSC_Test( int nb, int nres, double q=-1.0 ) : TestProblem(nb, nres), m_q(q) { TSCcube c; int xm(nres/2-1), ym(nres/2-1), zm(nres/2-1); double xxm((double)xm*m_h), yym((double)ym*m_h), zzm((double)zm*m_h); double fourpi = 4.0*M_PI; m_uana.zero(); m_ubnd.zero(); m_xgrad.zero(); m_ygrad.zero(); m_zgrad.zero(); for( int i=-nb; i