#ifndef __FFT_OPERATORS_HH #define __FFT_OPERATORS_HH struct fft_interp{ template< typename m1, typename m2 > void interpolate( m1& V, m2& v, bool fourier_splice = false ) const { int oxc = V.offset(0), oyc = V.offset(1), ozc = V.offset(2); int oxf = v.offset(0), oyf = v.offset(1), ozf = v.offset(2); size_t nxf = v.size(0), nyf = v.size(1), nzf = v.size(2), nzfp = nzf+2; // cut out piece of coarse grid that overlaps the fine: assert( nxf%2==0 && nyf%2==0 && nzf%2==0 ); size_t nxc = nxf/2, nyc = nyf/2, nzc = nzf/2, nzcp = nzf/2+2; fftw_real *rcoarse = new fftw_real[ nxc * nyc * nzcp ]; fftw_complex *ccoarse = reinterpret_cast (rcoarse); fftw_real *rfine = new fftw_real[ nxf * nyf * nzfp]; fftw_complex *cfine = reinterpret_cast (rfine); #pragma omp parallel for for( int i=0; i<(int)nxc; ++i ) for( int j=0; j<(int)nyc; ++j ) for( int k=0; k<(int)nzc; ++k ) { size_t q = ((size_t)i*nyc+(size_t)j)*nzcp+(size_t)k; rcoarse[q] = V( oxf+i, oyf+j, ozf+k ); } if( fourier_splice ) { #pragma omp parallel for for( int i=0; i<(int)nxf; ++i ) for( int j=0; j<(int)nyf; ++j ) for( int k=0; k<(int)nzf; ++k ) { size_t q = ((size_t)i*nyf+(size_t)j)*nzfp+(size_t)k; rfine[q] = v(i,j,k); } } else { #pragma omp parallel for for( size_t i=0; i