diff --git a/bfps/cpp/particles.cpp b/bfps/cpp/particles.cpp index 6d7e14290f1bd69decff1ffa5c38d0e015001d90..04a143786a920940a22f1221c7f301fbfc53b395 100644 --- a/bfps/cpp/particles.cpp +++ b/bfps/cpp/particles.cpp @@ -26,7 +26,6 @@ #define NDEBUG - #include <cmath> #include <cassert> #include <cstring> @@ -40,11 +39,10 @@ extern int myrank, nprocs; -template <int particle_type, class rnumber, bool multistep, int interp_neighbours> -particles<particle_type, rnumber, multistep, interp_neighbours>::particles( +template <int particle_type, class rnumber, int interp_neighbours> +particles<particle_type, rnumber, interp_neighbours>::particles( const char *NAME, - fluid_solver_base<rnumber> *FSOLVER, - interpolator<rnumber, interp_neighbours> *FIELD, + interpolator_base<rnumber, interp_neighbours> *FIELD, const int NPARTICLES, const int TRAJ_SKIP, const int INTEGRATION_STEPS) @@ -61,7 +59,6 @@ particles<particle_type, rnumber, multistep, interp_neighbours>::particles( assert((INTEGRATION_STEPS <= 6) && (INTEGRATION_STEPS >= 1)); strncpy(this->name, NAME, 256); - this->fs = FSOLVER; this->nparticles = NPARTICLES; this->vel = FIELD; this->integration_steps = INTEGRATION_STEPS; @@ -70,281 +67,38 @@ particles<particle_type, rnumber, multistep, interp_neighbours>::particles( this->nprocs = this->vel->descriptor->nprocs; this->comm = this->vel->descriptor->comm; this->array_size = this->nparticles * this->ncomponents; - this->state = fftw_alloc_real(this->array_size); + this->state = new double[this->array_size]; std::fill_n(this->state, this->array_size, 0.0); for (int i=0; i < this->integration_steps; i++) { - this->rhs[i] = fftw_alloc_real(this->array_size); + this->rhs[i] = new double[this->array_size]; std::fill_n(this->rhs[i], this->array_size, 0.0); } - this->watching = new bool[this->fs->rd->nprocs*nparticles]; - std::fill_n(this->watching, this->fs->rd->nprocs*this->nparticles, false); - this->computing = new int[nparticles]; - - // compute dx, dy, dz; - this->dx = 4*acos(0) / (this->fs->dkx*this->fs->rd->sizes[2]); - this->dy = 4*acos(0) / (this->fs->dky*this->fs->rd->sizes[1]); - this->dz = 4*acos(0) / (this->fs->dkz*this->fs->rd->sizes[0]); - - // compute lower and upper bounds - this->lbound = new double[nprocs]; - this->ubound = new double[nprocs]; - double *tbound = new double[nprocs]; - std::fill_n(tbound, nprocs, 0.0); - tbound[this->myrank] = this->fs->rd->starts[0]*this->dz; - MPI_Allreduce( - tbound, - this->lbound, - nprocs, - MPI_DOUBLE, - MPI_SUM, - this->comm); - std::fill_n(tbound, nprocs, 0.0); - tbound[this->myrank] = (this->fs->rd->starts[0] + this->fs->rd->subsizes[0])*this->dz; - MPI_Allreduce( - tbound, - this->ubound, - nprocs, - MPI_DOUBLE, - MPI_SUM, - this->comm); - delete[] tbound; - //for (int r = 0; r<nprocs; r++) - // DEBUG_MSG( - // "lbound[%d] = %lg, ubound[%d] = %lg\n", - // r, this->lbound[r], - // r, this->ubound[r] - // ); } -template <int particle_type, class rnumber, bool multistep, int interp_neighbours> -particles<particle_type, rnumber, multistep, interp_neighbours>::~particles() +template <int particle_type, class rnumber, int interp_neighbours> +particles<particle_type, rnumber, interp_neighbours>::~particles() { - delete[] this->computing; - delete[] this->watching; - fftw_free(this->state); + delete[] this->state; for (int i=0; i < this->integration_steps; i++) { - fftw_free(this->rhs[i]); + delete[] this->rhs[i]; } - delete[] this->lbound; - delete[] this->ubound; } -template <int particle_type, class rnumber, bool multistep, int interp_neighbours> -void particles<particle_type, rnumber, multistep, interp_neighbours>::sample_vec_field( - interpolator<rnumber, interp_neighbours> *vec, - double t, - double *x, - double *y, - const bool synch, - int *deriv) -{ - /* get grid coordinates */ - int *xg = new int[3*this->nparticles]; - double *xx = new double[3*this->nparticles]; - this->get_grid_coordinates(x, xg, xx); - /* perform interpolation */ - std::fill_n(y, 3*this->nparticles, 0.0); - if (multistep) - { - for (int p=0; p<this->nparticles; p++) - { - if (this->myrank == this->computing[p]) - (*vec)(t, xg + p*3, xx + p*3, y + p*3, deriv); - } - } - else - { - for (int p=0; p<this->nparticles; p++) - { - if (this->watching[this->myrank*this->nparticles+p]) - { - int crank = this->get_rank(x[p*3 + 2]); - if (this->myrank == crank) - (*vec)(t, xg + p*3, xx + p*3, y + p*3, deriv); - if (crank != this->computing[p]) - this->synchronize_single_particle_state(p, y, crank); - } - } - } - if (synch) - { - double *yy = new double[3*this->nparticles]; - std::fill_n(yy, 3*this->nparticles, 0.0); - for (int p=0; p<this->nparticles; p++) - { - if (this->myrank == this->computing[p]) - std::copy(y+3*p, y+3*(p+1), yy+3*p); - } - MPI_Allreduce( - yy, - y, - 3*this->nparticles, - MPI_DOUBLE, - MPI_SUM, - this->comm); - delete[] yy; - } - delete[] xg; - delete[] xx; -} - -template <int particle_type, class rnumber, bool multistep, int interp_neighbours> -void particles<particle_type, rnumber, multistep, interp_neighbours>::get_rhs(double t, double *x, double *y) +template <int particle_type, class rnumber, int interp_neighbours> +void particles<particle_type, rnumber, interp_neighbours>::get_rhs(double *x, double *y) { switch(particle_type) { case VELOCITY_TRACER: - this->sample_vec_field(this->vel, t, x, y, false); - break; - } -} - -template <int particle_type, class rnumber, bool multistep, int interp_neighbours> -void particles<particle_type, rnumber, multistep, interp_neighbours>::jump_estimate(double *jump) -{ - std::fill_n(jump, this->nparticles, 0.0); - switch(particle_type) - { - case VELOCITY_TRACER: - double *y = new double[3*this->nparticles]; - this->sample_vec_field(this->vel, 1.0, this->state, y, false); - for (int p=0; p<this->nparticles; p++) if (this->myrank == this->computing[p]) - { - jump[p] = fabs(2*this->dt * y[3*p+2]); - if (jump[p] < this->dz*1.01) - jump[p] = this->dz*1.01; - } - delete[] y; + this->vel->sample(this->nparticles, this->ncomponents, x, y); break; } } -template <int particle_type, class rnumber, bool multistep, int interp_neighbours> -int particles<particle_type, rnumber, multistep, interp_neighbours>::get_rank(double z) -{ - int tmp = this->fs->rd->rank[MOD(int(floor(z/this->dz)), this->fs->rd->sizes[0])]; - assert(tmp >= 0 && tmp < this->fs->rd->nprocs); - return tmp; -} - -template <int particle_type, class rnumber, bool multistep, int interp_neighbours> -void particles<particle_type, rnumber, multistep, interp_neighbours>::synchronize_single_particle_state(int p, double *x, int source) -{ - if (!multistep) - { - if (source == -1) source = this->computing[p]; - if (this->watching[this->myrank*this->nparticles+p]) for (int r=0; r<this->fs->rd->nprocs; r++) - if (r != source && - this->watching[r*this->nparticles+p]) - { - //DEBUG_MSG("synchronizing state %d from %d to %d\n", p, this->computing[p], r); - if (this->myrank == source) - MPI_Send( - x+p*this->ncomponents, - this->ncomponents, - MPI_DOUBLE, - r, - p+this->computing[p]*this->nparticles, - this->comm); - if (this->myrank == r) - MPI_Recv( - x+p*this->ncomponents, - this->ncomponents, - MPI_DOUBLE, - source, - p+this->computing[p]*this->nparticles, - this->comm, - MPI_STATUS_IGNORE); - } - } -} - -template <int particle_type, class rnumber, bool multistep, int interp_neighbours> -void particles<particle_type, rnumber, multistep, interp_neighbours>::synchronize() -{ - double *tstate = fftw_alloc_real(this->array_size); - // first, synchronize state and jump across CPUs - std::fill_n(tstate, this->array_size, 0.0); - for (int p=0; p<this->nparticles; p++) - { - //if (this->watching[this->myrank*this->nparticles + p]) - //DEBUG_MSG( - // "in synchronize, position for particle %d is %g %g %g\n", - // p, - // this->state[p*this->ncomponents], - // this->state[p*this->ncomponents+1], - // this->state[p*this->ncomponents+2]); - if (this->myrank == this->computing[p]) - std::copy(this->state + p*this->ncomponents, - this->state + (p+1)*this->ncomponents, - tstate + p*this->ncomponents); - } - MPI_Allreduce( - tstate, - this->state, - this->array_size, - MPI_DOUBLE, - MPI_SUM, - this->comm); - if (this->integration_steps >= 1 && multistep) - { - for (int i=0; i<this->integration_steps; i++) - { - std::fill_n(tstate, this->array_size, 0.0); - for (int p=0; p<this->nparticles; p++) if (this->myrank == this->computing[p]) - std::copy(this->rhs[i] + p*this->ncomponents, - this->rhs[i] + (p+1)*this->ncomponents, - tstate + p*this->ncomponents); - std::fill_n(this->rhs[i], this->array_size, 0.0); - MPI_Allreduce( - tstate, - this->rhs[i], - this->array_size, - MPI_DOUBLE, - MPI_SUM, - this->comm); - } - } - fftw_free(tstate); - // assignment of particles - for (int p=0; p<this->nparticles; p++) - { - this->computing[p] = this->get_rank(this->state[p*this->ncomponents + 2]); - for (int r=0; r<this->nprocs; r++) - this->watching[r*this->nparticles+p] = (r == this->computing[p]); - //DEBUG_MSG("synchronizing particles, particle %d computing is %d\n", p, this->computing[p]); - } - if (!multistep) - { - double *jump = fftw_alloc_real(this->nparticles); - this->jump_estimate(jump); - // now, see who needs to watch - bool *local_watching = new bool[this->fs->rd->nprocs*this->nparticles]; - std::fill_n(local_watching, this->fs->rd->nprocs*this->nparticles, false); - for (int p=0; p<this->nparticles; p++) - if (this->myrank == this->computing[p]) - { - local_watching[this->get_rank(this->state[this->ncomponents*p+2] )*this->nparticles+p] = true; - local_watching[this->get_rank(this->state[this->ncomponents*p+2]-jump[p])*this->nparticles+p] = true; - local_watching[this->get_rank(this->state[this->ncomponents*p+2]+jump[p])*this->nparticles+p] = true; - } - fftw_free(jump); - MPI_Allreduce( - local_watching, - this->watching, - this->nparticles*this->fs->rd->nprocs, - MPI_C_BOOL, - MPI_LOR, - this->comm); - delete[] local_watching; - } -} - - -template <int particle_type, class rnumber, bool multistep, int interp_neighbours> -void particles<particle_type, rnumber, multistep, interp_neighbours>::roll_rhs() +template <int particle_type, class rnumber, int interp_neighbours> +void particles<particle_type, rnumber, interp_neighbours>::roll_rhs() { for (int i=this->integration_steps-2; i>=0; i--) std::copy(this->rhs[i], @@ -354,15 +108,16 @@ void particles<particle_type, rnumber, multistep, interp_neighbours>::roll_rhs() -template <int particle_type, class rnumber, bool multistep, int interp_neighbours> -void particles<particle_type, rnumber, multistep, interp_neighbours>::AdamsBashforth(int nsteps) +template <int particle_type, class rnumber, int interp_neighbours> +void particles<particle_type, rnumber, interp_neighbours>::AdamsBashforth( + const int nsteps) { ptrdiff_t ii; - this->get_rhs(0, this->state, this->rhs[0]); + this->get_rhs(this->state, this->rhs[0]); switch(nsteps) { case 1: - for (int p=0; p<this->nparticles; p++) if (this->myrank == this->computing[p]) + for (int p=0; p<this->nparticles; p++) for (int i=0; i<this->ncomponents; i++) { ii = p*this->ncomponents+i; @@ -370,7 +125,7 @@ void particles<particle_type, rnumber, multistep, interp_neighbours>::AdamsBashf } break; case 2: - for (int p=0; p<this->nparticles; p++) if (this->myrank == this->computing[p]) + for (int p=0; p<this->nparticles; p++) for (int i=0; i<this->ncomponents; i++) { ii = p*this->ncomponents+i; @@ -379,7 +134,7 @@ void particles<particle_type, rnumber, multistep, interp_neighbours>::AdamsBashf } break; case 3: - for (int p=0; p<this->nparticles; p++) if (this->myrank == this->computing[p]) + for (int p=0; p<this->nparticles; p++) for (int i=0; i<this->ncomponents; i++) { ii = p*this->ncomponents+i; @@ -389,7 +144,7 @@ void particles<particle_type, rnumber, multistep, interp_neighbours>::AdamsBashf } break; case 4: - for (int p=0; p<this->nparticles; p++) if (this->myrank == this->computing[p]) + for (int p=0; p<this->nparticles; p++) for (int i=0; i<this->ncomponents; i++) { ii = p*this->ncomponents+i; @@ -400,7 +155,7 @@ void particles<particle_type, rnumber, multistep, interp_neighbours>::AdamsBashf } break; case 5: - for (int p=0; p<this->nparticles; p++) if (this->myrank == this->computing[p]) + for (int p=0; p<this->nparticles; p++) for (int i=0; i<this->ncomponents; i++) { ii = p*this->ncomponents+i; @@ -412,7 +167,7 @@ void particles<particle_type, rnumber, multistep, interp_neighbours>::AdamsBashf } break; case 6: - for (int p=0; p<this->nparticles; p++) if (this->myrank == this->computing[p]) + for (int p=0; p<this->nparticles; p++) for (int i=0; i<this->ncomponents; i++) { ii = p*this->ncomponents+i; @@ -429,145 +184,23 @@ void particles<particle_type, rnumber, multistep, interp_neighbours>::AdamsBashf } -template <int particle_type, class rnumber, bool multistep, int interp_neighbours> -void particles<particle_type, rnumber, multistep, interp_neighbours>::step() +template <int particle_type, class rnumber, int interp_neighbours> +void particles<particle_type, rnumber, interp_neighbours>::step() { - if (multistep) - this->AdamsBashforth((this->iteration < this->integration_steps) ? - this->iteration+1 : - this->integration_steps); - else - this->Heun(); + this->AdamsBashforth((this->iteration < this->integration_steps) ? + this->iteration+1 : + this->integration_steps); this->iteration++; - this->synchronize(); -} - - - -template <int particle_type, class rnumber, bool multistep, int interp_neighbours> -void particles<particle_type, rnumber, multistep, interp_neighbours>::Heun() -{ - if (!multistep) - { - double *y = new double[this->array_size]; - double dtfactor[2]; - double factor[] = {0.0, 1.0}; - dtfactor[0] = factor[0]*this->dt; - dtfactor[1] = factor[1]*this->dt; - this->get_rhs(0, this->state, this->rhs[0]); - for (int p=0; p<this->nparticles; p++) - this->synchronize_single_particle_state(p, this->rhs[0]); - for (int kindex = 1; kindex < 2; kindex++) - { - for (int p=0; p<this->nparticles; p++) - { - if (this->watching[this->myrank*this->nparticles+p]) - for (int i=0; i<this->ncomponents; i++) - { - ptrdiff_t tindex = ptrdiff_t(p)*this->ncomponents + i; - y[tindex] = this->state[tindex] + dtfactor[kindex]*this->rhs[kindex-1][tindex]; - } - } - for (int p=0; p<this->nparticles; p++) - this->synchronize_single_particle_state(p, y); - this->get_rhs(factor[kindex], y, this->rhs[kindex]); - for (int p=0; p<this->nparticles; p++) - this->synchronize_single_particle_state(p, this->rhs[kindex]); - } - for (int p=0; p<this->nparticles; p++) - { - if (this->watching[this->myrank*this->nparticles+p]) - { - for (int i=0; i<this->ncomponents; i++) - { - ptrdiff_t tindex = ptrdiff_t(p)*this->ncomponents + i; - this->state[tindex] += this->dt*(this->rhs[0][tindex] + this->rhs[1][tindex])/2; - } - } - } - delete[] y; - } -} - - -template <int particle_type, class rnumber, bool multistep, int interp_neighbours> -void particles<particle_type, rnumber, multistep, interp_neighbours>::cRK4() -{ - if (!multistep) - { - static double factor[] = {0.0, 0.5, 0.5, 1.0}; - static double dtfactor[] = {0.0, this->dt/2, this->dt/2, this->dt}; - double *y = new double[this->array_size]; - this->get_rhs(0, this->state, this->rhs[0]); - for (int p=0; p<this->nparticles; p++) - this->synchronize_single_particle_state(p, this->rhs[0]); - for (int kindex = 1; kindex < 4; kindex++) - { - for (int p=0; p<this->nparticles; p++) - { - if (this->watching[this->myrank*this->nparticles+p]) - for (int i=0; i<this->ncomponents; i++) - { - ptrdiff_t tindex = ptrdiff_t(p)*this->ncomponents + i; - y[tindex] = this->state[tindex] + dtfactor[kindex]*this->rhs[kindex-1][tindex]; - } - } - for (int p=0; p<this->nparticles; p++) - this->synchronize_single_particle_state(p, y); - this->get_rhs(factor[kindex], y, this->rhs[kindex]); - for (int p=0; p<this->nparticles; p++) - this->synchronize_single_particle_state(p, this->rhs[kindex]); - } - for (int p=0; p<this->nparticles; p++) - { - if (this->watching[this->myrank*this->nparticles+p]) - for (int i=0; i<this->ncomponents; i++) - { - ptrdiff_t tindex = ptrdiff_t(p)*this->ncomponents + i; - this->state[tindex] += this->dt*(this->rhs[0][tindex] + - 2*(this->rhs[1][tindex] + this->rhs[2][tindex]) + - this->rhs[3][tindex])/6; - } - } - delete[] y; - } } -template <int particle_type, class rnumber, bool multistep, int interp_neighbours> -void particles<particle_type, rnumber, multistep, interp_neighbours>::get_grid_coordinates(double *x, int *xg, double *xx) -{ - static double grid_size[] = {this->dx, this->dy, this->dz}; - double tval; - std::fill_n(xg, this->nparticles*3, 0); - std::fill_n(xx, this->nparticles*3, 0.0); - for (int p=0; p<this->nparticles; p++) if (this->watching[this->myrank*this->nparticles+p]) - { - for (int c=0; c<3; c++) - { - tval = floor(x[p*this->ncomponents+c]/grid_size[c]); - xg[p*3+c] = MOD(int(tval), this->fs->rd->sizes[2-c]); - xx[p*3+c] = (x[p*this->ncomponents+c] - tval*grid_size[c]) / grid_size[c]; - } - xg[p*3+2] -= this->fs->rd->starts[0]; - if (this->myrank == this->fs->rd->rank[0] && - xg[p*3+2] > this->fs->rd->subsizes[0]) - xg[p*3+2] -= this->fs->rd->sizes[0]; - //DEBUG_MSG( - // "particle %d x is %lg %lg %lg xx is %lg %lg %lg xg is %d %d %d\n", - // p, - // x[p*3], x[p*3+1], x[p*3+2], - // xx[p*3], xx[p*3+1], xx[p*3+2], - // xg[p*3], xg[p*3+1], xg[p*3+2]); - } -} -template <int particle_type, class rnumber, bool multistep, int interp_neighbours> -void particles<particle_type, rnumber, multistep, interp_neighbours>::read(hid_t data_file_id) +template <int particle_type, class rnumber, int interp_neighbours> +void particles<particle_type, rnumber, interp_neighbours>::read( + const hid_t data_file_id) { - //DEBUG_MSG("aloha\n"); if (this->myrank == 0) { - std::string temp_string = (std::string("/particles/") + + std::string temp_string = (std::string("/") + std::string(this->name) + std::string("/state")); hid_t dset = H5Dopen(data_file_id, temp_string.c_str(), H5P_DEFAULT); @@ -585,9 +218,9 @@ void particles<particle_type, rnumber, multistep, interp_neighbours>::read(hid_t H5Sclose(mspace); H5Sclose(rspace); H5Dclose(dset); - if (this->iteration > 0 && multistep) + if (this->iteration > 0) { - temp_string = (std::string("/particles/") + + temp_string = (std::string("/") + std::string(this->name) + std::string("/rhs")); dset = H5Dopen(data_file_id, temp_string.c_str(), H5P_DEFAULT); @@ -616,60 +249,67 @@ void particles<particle_type, rnumber, multistep, interp_neighbours>::read(hid_t MPI_DOUBLE, 0, this->comm); - if (multistep) for (int i = 0; i<this->integration_steps; i++) + for (int i = 0; i<this->integration_steps; i++) MPI_Bcast( this->rhs[i], this->array_size, MPI_DOUBLE, 0, this->comm); - // initial assignment of particles - for (int p=0; p<this->nparticles; p++) - { - this->computing[p] = this->get_rank(this->state[p*this->ncomponents + 2]); - //DEBUG_MSG("reading particles, particle %d computing is %d\n", p, this->computing[p]); - } - // now actual synchronization - this->synchronize(); } -template <int particle_type, class rnumber, bool multistep, int interp_neighbours> -void particles<particle_type, rnumber, multistep, interp_neighbours>::write(hid_t data_file_id, bool write_rhs) +template <int particle_type, class rnumber, int interp_neighbours> +void particles<particle_type, rnumber, interp_neighbours>::write( + const hid_t data_file_id, + const char *dset_name, + const double *data) +{ + std::string temp_string = (std::string(this->name) + + std::string("/") + + std::string(dset_name)); + hid_t dset = H5Dopen(data_file_id, temp_string.c_str(), H5P_DEFAULT); + hid_t mspace, wspace; + hsize_t count[3], offset[3]; + wspace = H5Dget_space(dset); + H5Sget_simple_extent_dims(wspace, count, NULL); + count[0] = 1; + offset[0] = this->iteration / this->traj_skip; + offset[1] = 0; + offset[2] = 0; + mspace = H5Screate_simple(3, count, NULL); + H5Sselect_hyperslab(wspace, H5S_SELECT_SET, offset, NULL, count, NULL); + H5Dwrite(dset, H5T_NATIVE_DOUBLE, mspace, wspace, H5P_DEFAULT, data); + H5Sclose(mspace); + H5Sclose(wspace); + H5Dclose(dset); +} + +template <int particle_type, class rnumber, int interp_neighbours> +void particles<particle_type, rnumber, interp_neighbours>::write( + const hid_t data_file_id, + const bool write_rhs) { if (this->myrank == 0) { - std::string temp_string = (std::string("/particles/") + - std::string(this->name) + - std::string("/state")); - hid_t dset = H5Dopen(data_file_id, temp_string.c_str(), H5P_DEFAULT); - hid_t mspace, wspace; - hsize_t count[4], offset[4]; - wspace = H5Dget_space(dset); - H5Sget_simple_extent_dims(wspace, count, NULL); - count[0] = 1; - offset[0] = this->iteration / this->traj_skip; - offset[1] = 0; - offset[2] = 0; - mspace = H5Screate_simple(3, count, NULL); - H5Sselect_hyperslab(wspace, H5S_SELECT_SET, offset, NULL, count, NULL); - H5Dwrite(dset, H5T_NATIVE_DOUBLE, mspace, wspace, H5P_DEFAULT, this->state); - H5Sclose(mspace); - H5Sclose(wspace); - H5Dclose(dset); - if (write_rhs && multistep) + this->write(data_file_id, "state", this->state); + if (write_rhs) { - temp_string = (std::string("/particles/") + - std::string(this->name) + - std::string("/rhs")); - dset = H5Dopen(data_file_id, temp_string.c_str(), H5P_DEFAULT); - wspace = H5Dget_space(dset); + std::string temp_string = ( + std::string("/") + + std::string(this->name) + + std::string("/rhs")); + hid_t dset = H5Dopen(data_file_id, temp_string.c_str(), H5P_DEFAULT); + hid_t wspace = H5Dget_space(dset); + hsize_t count[4], offset[4]; H5Sget_simple_extent_dims(wspace, count, NULL); //writing to last available position offset[0] = count[0] - 1; + offset[1] = 0; + offset[2] = 0; + offset[3] = 0; count[0] = 1; count[1] = 1; - offset[3] = 0; - mspace = H5Screate_simple(4, count, NULL); + hid_t mspace = H5Screate_simple(4, count, NULL); for (int i=0; i<this->integration_steps; i++) { offset[1] = i; @@ -685,28 +325,16 @@ void particles<particle_type, rnumber, multistep, interp_neighbours>::write(hid_ /*****************************************************************************/ -template class particles<VELOCITY_TRACER, float, true, 1>; -template class particles<VELOCITY_TRACER, float, true, 2>; -template class particles<VELOCITY_TRACER, float, true, 3>; -template class particles<VELOCITY_TRACER, float, true, 4>; -template class particles<VELOCITY_TRACER, float, true, 5>; -template class particles<VELOCITY_TRACER, float, true, 6>; -template class particles<VELOCITY_TRACER, float, false, 1>; -template class particles<VELOCITY_TRACER, float, false, 2>; -template class particles<VELOCITY_TRACER, float, false, 3>; -template class particles<VELOCITY_TRACER, float, false, 4>; -template class particles<VELOCITY_TRACER, float, false, 5>; -template class particles<VELOCITY_TRACER, float, false, 6>; -template class particles<VELOCITY_TRACER, double, true, 1>; -template class particles<VELOCITY_TRACER, double, true, 2>; -template class particles<VELOCITY_TRACER, double, true, 3>; -template class particles<VELOCITY_TRACER, double, true, 4>; -template class particles<VELOCITY_TRACER, double, true, 5>; -template class particles<VELOCITY_TRACER, double, true, 6>; -template class particles<VELOCITY_TRACER, double, false, 1>; -template class particles<VELOCITY_TRACER, double, false, 2>; -template class particles<VELOCITY_TRACER, double, false, 3>; -template class particles<VELOCITY_TRACER, double, false, 4>; -template class particles<VELOCITY_TRACER, double, false, 5>; -template class particles<VELOCITY_TRACER, double, false, 6>; +template class particles<VELOCITY_TRACER, float, 1>; +template class particles<VELOCITY_TRACER, float, 2>; +template class particles<VELOCITY_TRACER, float, 3>; +template class particles<VELOCITY_TRACER, float, 4>; +template class particles<VELOCITY_TRACER, float, 5>; +template class particles<VELOCITY_TRACER, float, 6>; +template class particles<VELOCITY_TRACER, double, 1>; +template class particles<VELOCITY_TRACER, double, 2>; +template class particles<VELOCITY_TRACER, double, 3>; +template class particles<VELOCITY_TRACER, double, 4>; +template class particles<VELOCITY_TRACER, double, 5>; +template class particles<VELOCITY_TRACER, double, 6>; /*****************************************************************************/ diff --git a/bfps/cpp/particles.hpp b/bfps/cpp/particles.hpp index 6fa379c458f38d364765efa4d7e58bb25e9daff5..3334591fbeca673dc8905bae17d3179f7120058c 100644 --- a/bfps/cpp/particles.hpp +++ b/bfps/cpp/particles.hpp @@ -31,32 +31,20 @@ #include "base.hpp" #include "particles_base.hpp" #include "fluid_solver_base.hpp" -#include "interpolator.hpp" +#include "interpolator_base.hpp" #ifndef PARTICLES #define PARTICLES -template <int particle_type, class rnumber, bool multistep, int interp_neighbours> +template <int particle_type, class rnumber, int interp_neighbours> class particles { public: int myrank, nprocs; MPI_Comm comm; - fluid_solver_base<rnumber> *fs; rnumber *data; - /* watching is an array of shape [nparticles], with - * watching[p] being true if particle p is in the domain of myrank - * or in the buffer regions. - * only used if multistep is false. - * */ - bool *watching; - /* computing is an array of shape [nparticles], with - * computing[p] being the rank that is currently working on particle p - * */ - int *computing; - /* state will generally hold all the information about the particles. * in the beginning, we will only need to solve 3D ODEs, but I figured * a general ncomponents is better, since we may change our minds. @@ -68,73 +56,41 @@ class particles int array_size; int integration_steps; int traj_skip; - int buffer_width; - ptrdiff_t buffer_size; - double *lbound; - double *ubound; - interpolator<rnumber, interp_neighbours> *vel; + interpolator_base<rnumber, interp_neighbours> *vel; /* simulation parameters */ char name[256]; int iteration; double dt; - /* physical parameters of field */ - double dx, dy, dz; - /* methods */ /* constructor and destructor. * allocate and deallocate: * this->state * this->rhs - * this->lbound - * this->ubound - * this->computing - * this->watching * */ particles( const char *NAME, - fluid_solver_base<rnumber> *FSOLVER, - interpolator<rnumber, interp_neighbours> *FIELD, + interpolator_base<rnumber, interp_neighbours> *FIELD, const int NPARTICLES, const int TRAJ_SKIP, const int INTEGRATION_STEPS = 2); ~particles(); - /* an Euler step is needed to compute an estimate of future positions, - * which is needed for synchronization. - * */ - void jump_estimate(double *__restrict__ jump_length); - void get_rhs(double *__restrict__ x, double *__restrict__ rhs); - void get_rhs(double t, double *__restrict__ x, double *__restrict__ rhs); - - int get_rank(double z); // get rank for given value of z - void synchronize(); - void synchronize_single_particle_state(int p, double *__restrict__ x, int source_id = -1); - void get_grid_coordinates(double *__restrict__ x, int *__restrict__ xg, double *__restrict__ xx); - void sample_vec_field( - interpolator<rnumber, interp_neighbours> *vec, - double t, - double *__restrict__ x, - double *__restrict__ y, - const bool synch = false, - int *deriv = NULL); - inline void sample_vec_field(interpolator<rnumber, interp_neighbours> *field, double *vec_values) - { - this->sample_vec_field(field, 1.0, this->state, vec_values, true, NULL); - } + void get_rhs( + double *__restrict__ x, + double *__restrict__ rhs); /* input/output */ - void read(hid_t data_file_id); - void write(hid_t data_file_id, bool write_rhs = true); + void read(const hid_t data_file_id); + void write(const hid_t data_file_id, const char *dset_name, const double *data); + void write(const hid_t data_file_id, const bool write_rhs = true); /* solvers */ void step(); void roll_rhs(); - void AdamsBashforth(int nsteps); - void Heun(); - void cRK4(); + void AdamsBashforth(const int nsteps); }; #endif//PARTICLES diff --git a/setup.py b/setup.py index cda297d7c74201e1eba2570004478c724f3c6c90..3affff2ea0bcea3b1c7a42a72ca965b98863706f 100644 --- a/setup.py +++ b/setup.py @@ -96,7 +96,7 @@ src_file_list = ['field_descriptor', 'rFFTW_interpolator', 'rFFTW_particles', 'interpolator', - #'particles', + 'particles', 'fftw_tools', 'spline_n1', 'spline_n2',