diff --git a/makefile b/makefile index 9eb470ce27518da157a908ec4e0e5455977e8bf2..3c163b9fc93aa176c525e323a442be7673e08cb3 100644 --- a/makefile +++ b/makefile @@ -61,6 +61,7 @@ base_files := \ fftw_tools \ Morton_shuffler \ p3DFFT_to_iR \ + vector_field \ fluid_solver #headers := $(patsubst %, ./src/%.hpp, ${base_files}) diff --git a/py_template/test_FFT.cpp b/py_template/test_FFT.cpp index 34d6f95453898b065654cea34a5f67f5a8dfbd0e..23d7e104d5b2456c5187c811f923aefd1eceafcb 100644 --- a/py_template/test_FFT.cpp +++ b/py_template/test_FFT.cpp @@ -2,15 +2,22 @@ fluid_solver<float> *fs; fs = new fluid_solver<float>(32, 32, 32); DEBUG_MSG("fluid_solver object created\n"); -fs->fc->read( +vector_field<float> cv(fs->cd, fs->cvorticity); +vector_field<float> rv(fs->cd, fs->rvorticity); + +fs->cd->read( "Kdata0", (void*)fs->cvorticity); fftwf_execute(*(fftwf_plan*)fs->c2r_vorticity); +//rv*(1. / (fs->rd->sizes[0]*fs->rd->sizes[1]*fs->rd->sizes[2])); fftwf_execute(*(fftwf_plan*)fs->r2c_vorticity); -fs->fc->write( +cv = cv*(1. / (fs->rd->sizes[0]*fs->rd->sizes[1]*fs->rd->sizes[2])); +fs->cd->write( "Kdata1", (void*)fs->cvorticity); +DEBUG_MSG("full size is %ld\n", fs->rd->full_size); + delete fs; DEBUG_MSG("fluid_solver object deleted\n"); diff --git a/src/fluid_solver.cpp b/src/fluid_solver.cpp index e24827858a9a4dbb878967886afe32f5b56686d4..d10e6960bb72b301ee9b71bc056b6d87c6894e1c 100644 --- a/src/fluid_solver.cpp +++ b/src/fluid_solver.cpp @@ -28,7 +28,7 @@ /*****************************************************************************/ /* macro for specializations to numeric types compatible with FFTW */ -#define FLUID_SOLVER_DEFINITIONS(FFTW, R, C) \ +#define FLUID_SOLVER_DEFINITIONS(FFTW, R, C, MPI_RNUM, MPI_CNUM) \ \ template<> \ fluid_solver<R>::fluid_solver( \ @@ -36,20 +36,29 @@ fluid_solver<R>::fluid_solver( \ int ny, \ int nz) \ { \ - get_descriptors_3D<R>(nz, ny, nx, &this->fr, &this->fc);\ - this->cvorticity = FFTW(alloc_complex)(this->fc->local_size*3);\ - this->cvelocity = FFTW(alloc_complex)(this->fc->local_size*3);\ - this->rvorticity = FFTW(alloc_real)(this->fc->local_size*6);\ - this->rvelocity = FFTW(alloc_real)(this->fc->local_size*6);\ + int ntmp[4]; \ + ntmp[0] = nz; \ + ntmp[1] = ny; \ + ntmp[2] = nx; \ + ntmp[3] = 3; \ + this->rd = new field_descriptor<R>( \ + 4, ntmp, MPI_RNUM, MPI_COMM_WORLD);\ + ntmp[2] = nx/2 + 1; \ + this->cd = new field_descriptor<R>( \ + 4, ntmp, MPI_CNUM, MPI_COMM_WORLD);\ + this->cvorticity = FFTW(alloc_complex)(this->cd->local_size);\ + this->cvelocity = FFTW(alloc_complex)(this->cd->local_size);\ + this->rvorticity = FFTW(alloc_real)(this->cd->local_size*2);\ + this->rvelocity = FFTW(alloc_real)(this->cd->local_size*2);\ \ this->c2r_vorticity = new FFTW(plan);\ this->r2c_vorticity = new FFTW(plan);\ this->c2r_velocity = new FFTW(plan);\ this->r2c_velocity = new FFTW(plan);\ \ - ptrdiff_t sizes[] = {this->fr->sizes[0], \ - this->fr->sizes[1], \ - this->fr->sizes[2]};\ + ptrdiff_t sizes[] = {nz, \ + ny, \ + nx};\ \ *(FFTW(plan)*)this->c2r_vorticity = FFTW(mpi_plan_many_dft_c2r)( \ 3, sizes, 3, \ @@ -101,6 +110,9 @@ fluid_solver<R>::~fluid_solver() \ FFTW(free)(this->rvorticity);\ FFTW(free)(this->cvelocity);\ FFTW(free)(this->rvelocity);\ + \ + delete this->cd; \ + delete this->rd; \ } \ \ template<> \ @@ -112,10 +124,16 @@ void fluid_solver<R>::step() \ /*****************************************************************************/ /* now actually use the macro defined above */ -FLUID_SOLVER_DEFINITIONS(FFTW_MANGLE_FLOAT, float, fftwf_complex) -FLUID_SOLVER_DEFINITIONS(FFTW_MANGLE_DOUBLE, double, fftw_complex) -//FLUID_SOLVER_DEFINITIONS(FFTW_MANGLE_LONG_DOUBLE, long double, fftwl_complex) -//FLUID_SOLVER_DEFINITIONS(FFTW_MANGLE_QUAD, __float128, fftwq_complex) +FLUID_SOLVER_DEFINITIONS(FFTW_MANGLE_FLOAT, + float, + fftwf_complex, + MPI_REAL4, + MPI_COMPLEX8) +FLUID_SOLVER_DEFINITIONS(FFTW_MANGLE_DOUBLE, + double, + fftw_complex, + MPI_REAL8, + MPI_COMPLEX16) /*****************************************************************************/ diff --git a/src/fluid_solver.hpp b/src/fluid_solver.hpp index 06e34240d06419cb510da0b884cf88004cce6ba0..0104e6bf9917ba099826b6c9ff2de7be8de01e77 100644 --- a/src/fluid_solver.hpp +++ b/src/fluid_solver.hpp @@ -22,6 +22,7 @@ #include <stdlib.h> #include <iostream> #include "field_descriptor.hpp" +#include "vector_field.hpp" #ifndef FLUID_SOLVER @@ -41,7 +42,7 @@ class fluid_solver private: typedef rnumber cnumber[2]; public: - field_descriptor<rnumber> *fc, *fr; + field_descriptor<rnumber> *cd, *rd; /* fields */ rnumber *rvorticity; diff --git a/src/vector_field.cpp b/src/vector_field.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3a9412522fef80ec024d0cb7ec1c01df97cb4dde --- /dev/null +++ b/src/vector_field.cpp @@ -0,0 +1,42 @@ +#include "vector_field.hpp" + +/* destructor doesn't actually do anything */ +template <class rnumber> +vector_field<rnumber>::~vector_field() +{} + + +template <class rnumber> +vector_field<rnumber>::vector_field( + field_descriptor<rnumber> *d, + rnumber *data) +{ + this->is_real = true; + this->cdata = (rnumber (*)[2])(data); + this->rdata = data; + this->descriptor = d; +} + +template <class rnumber> +vector_field<rnumber>::vector_field( + field_descriptor<rnumber> *d, + rnumber (*data)[2]) +{ + this->is_real = false; + this->rdata = (rnumber*)(&data[0][0]); + this->cdata = data; + this->descriptor = d; +} + +template <class rnumber> +vector_field<rnumber>& vector_field<rnumber>::operator*(rnumber factor) +{ + ptrdiff_t i; + for (i = 0; + i < this->descriptor->local_size * 2; + i++) + *(this->rdata + i) *= factor; + return *this; +} + +template class vector_field<float>; diff --git a/src/vector_field.hpp b/src/vector_field.hpp new file mode 100644 index 0000000000000000000000000000000000000000..0d8aa70c13cd063fbe8bb01adf2f32bfee52c5ac --- /dev/null +++ b/src/vector_field.hpp @@ -0,0 +1,19 @@ +#include "field_descriptor.hpp" + +template <class rnumber> +class vector_field +{ + private: + field_descriptor<rnumber> *descriptor; + rnumber *rdata; + rnumber (*cdata)[2]; + bool is_real; + public: + vector_field(field_descriptor<rnumber> *d, rnumber *data); + vector_field(field_descriptor<rnumber> *d, rnumber (*data)[2]); + ~vector_field(); + + /* various operators */ + vector_field &operator*(rnumber factor); +}; + diff --git a/test.py b/test.py old mode 100644 new mode 100755 index bc3d31ff2443e747768397a246e5183f4419b00a..94cfa417882591616e8b10afccec856a980c94ee --- a/test.py +++ b/test.py @@ -1,6 +1,9 @@ +#! /usr/bin/env python2 + import numpy as np import subprocess import pyfftw +import matplotlib.pyplot as plt def run_test( test_name = 'test_FFT', @@ -46,13 +49,29 @@ def generate_data_3D( a[ii] = 0 return a -Kdata0 = generate_data_3D(32, p = 2).astype(np.complex64) +n = 32 +Kdata00 = generate_data_3D(n, p = 2).astype(np.complex64) +Kdata01 = generate_data_3D(n, p = 2).astype(np.complex64) +Kdata02 = generate_data_3D(n, p = 2).astype(np.complex64) +Kdata0 = np.zeros( + Kdata00.shape + (3,), + Kdata00.dtype) +Kdata0[..., 0] = Kdata00 +Kdata0[..., 1] = Kdata01 +Kdata0[..., 2] = Kdata02 Kdata0.tofile("Kdata0") run_test('test_FFT') Kdata1 = np.fromfile('Kdata1', dtype = np.complex64).reshape(Kdata0.shape) print np.max(np.abs(Kdata0 - Kdata1)) +print np.max(np.abs(Kdata0)) +fig = plt.figure(figsize=(12, 6)) +a = fig.add_subplot(121) +a.imshow(abs(Kdata0[4, :, :, 2]), interpolation = 'none') +a = fig.add_subplot(122) +a.imshow(abs(Kdata1[4, :, :, 2]), interpolation = 'none') +fig.savefig('tmp.pdf', format = 'pdf')