diff --git a/bfps/NavierStokes.py b/bfps/NavierStokes.py index c77cb3098f204a39ab5cc47de9337b2e66feaea5..8b3a30ca6881a8051c039c1b39cb07b8d59579a5 100644 --- a/bfps/NavierStokes.py +++ b/bfps/NavierStokes.py @@ -230,6 +230,33 @@ class NavierStokes(bfps.fluid_base.fluid_particle_base): self.fluid_output + '\n}\n' + 'delete fs;\n') return None + def add_particle_fields( + self, + kcut = None, + neighbours = 1, + name = 'particle_field'): + self.particle_variables += ('buffered_vec_field<{0}> *vel_{1}, *acc_{1};\n' + + '{0} *{1}_tmp;\n').format(self.C_dtype, name) + self.particle_start += ('vel_{0} = new buffered_vec_field<{1}>(fs, {2});\n' + + 'acc_{0} = new buffered_vec_field<{1}>(fs, {2});\n' + + '{0}_tmp = new {1}[acc_{0}->src_descriptor->local_size];\n').format(name, self.C_dtype, neighbours+1) + self.particle_end += ('delete vel_{0};\n' + + 'delete acc_{0};\n' + + 'delete[] {0}_tmp;\n').format(name) + update_fields = 'fs->compute_velocity(fs->cvorticity);\n' + if not type(kcut) == type(None): + update_fields += 'fs->low_pass_Fourier(fs->cvelocity, 3, {0});\n'.format(kcut) + update_fields += ('fs->ift_velocity();\n' + + 'clip_zero_padding(fs->rd, fs->rvelocity, 3);\n' + + 'vel_{0}->read_rFFTW(fs->rvelocity);\n' + + 'fs->compute_velocity(fs->cvorticity);\n' + + 'fs->ift_velocity();\n' + + 'fs->compute_Lagrangian_acceleration({0}_tmp);\n' + + 'clip_zero_padding(fs->rd, {0}_tmp, 3);\n' + + 'acc_{0}->read_rFFTW({0}_tmp);\n').format(name) + self.particle_start += update_fields + self.particle_loop += update_fields + return None def add_particles( self, neighbours = 1, @@ -239,7 +266,12 @@ class NavierStokes(bfps.fluid_base.fluid_particle_base): integration_steps = 2, kcut = 'fs->kM', frozen_particles = False, - particle_type = 'old_tracers'): + particle_type = 'old_tracers', + fields_name = None): + if integration_method == 'cRK4': + integration_steps = 4 + elif integration_method == 'Heun': + integration_steps = 2 self.parameters['integration_method{0}'.format(self.particle_species)] = integration_method self.parameters['interp_type{0}'.format(self.particle_species)] = interp_type self.parameters['neighbours{0}'.format(self.particle_species)] = neighbours @@ -255,21 +287,25 @@ class NavierStokes(bfps.fluid_base.fluid_particle_base): H5Gclose(group); //endcpp """.format(self.particle_species) - update_field = 'fs->compute_velocity(fs->cvorticity);\n' - if kcut != 'fs->kM': - update_field += 'fs->low_pass_Fourier(fs->cvelocity, 3, {0});\n'.format(kcut) - update_field += ('fs->ift_velocity();\n' + - 'clip_zero_padding(fs->rd, fs->rvelocity, 3);\n' + - 'ps{0}->rFFTW_to_buffered(fs->rvelocity, ps{0}->data);\n').format(self.particle_species) + if particle_type == 'old_tracers': + update_field = 'fs->compute_velocity(fs->cvorticity);\n' + if kcut != 'fs->kM': + update_field += 'fs->low_pass_Fourier(fs->cvelocity, 3, {0});\n'.format(kcut) + update_field += ('fs->ift_velocity();\n' + + 'clip_zero_padding(fs->rd, fs->rvelocity, 3);\n' + + 'ps{0}->rFFTW_to_buffered(fs->rvelocity, ps{0}->data);\n').format(self.particle_species) + compute_acc = ('{0} *acc_field_tmp = {1}_alloc_real(fs->rd->local_size);\n' + + 'fs->compute_Lagrangian_acceleration(acc_field_tmp);\n' + + 'ps{2}->rFFTW_to_buffered(acc_field_tmp, ps{2}->data);\n' + + 'ps{2}->sample_vec_field(ps{2}->data, acceleration);\n' + + '{1}_free(acc_field_tmp);\n').format(self.C_dtype, FFTW, self.particle_species) + else: + update_field = '' + compute_acc = 'ps{0}->sample_vec_field(acc_{1}->f+acc_{1}->buffer_size, acceleration);\n'.format(self.particle_species, fields_name) if self.dtype == np.float32: FFTW = 'fftwf' elif self.dtype == np.float64: FFTW = 'fftw' - compute_acc = ('{0} *acc_field_tmp = {1}_alloc_real(fs->rd->local_size);\n' + - 'fs->compute_Lagrangian_acceleration(acc_field_tmp);\n' + - 'ps{2}->rFFTW_to_buffered(acc_field_tmp, ps{2}->data);\n' + - 'ps{2}->sample_vec_field(ps{2}->data, acceleration);\n' + - '{1}_free(acc_field_tmp);\n').format(self.C_dtype, FFTW, self.particle_species) output_vel_acc = """ //begincpp {{ @@ -342,16 +378,13 @@ class NavierStokes(bfps.fluid_base.fluid_particle_base): multistep, neighbours, self.particle_species) - self.particle_variables += '{0} *particle_field{1};\n'.format(self.C_dtype, self.particle_species) self.particle_start += ('ps{0} = new particles<VELOCITY_TRACER, {1}, {2}, 3, {3}>(\n' + 'fname, fs,\n' + 'nparticles,\n' + '{4},\n' + 'niter_part, integration_steps{0});\n').format( self.particle_species, self.C_dtype, multistep, neighbours, beta_name) - self.particle_start += ('particle_field{0} = {1}_alloc_real(ps{0}->buffered_field_descriptor->local_size);\n' + - 'ps{0}->data = particle_field{0};\n').format(self.particle_species, FFTW) - self.particle_end += '{0}_free(particle_field{1});\n'.format(FFTW, self.particle_species) + self.particle_start += ('ps{0}->data = vel_{1}->f+vel_{1}->buffer_size;\n').format(self.particle_species, fields_name) self.particle_start += ('ps{0}->dt = dt;\n' + 'ps{0}->iteration = iteration;\n' + update_field + diff --git a/bfps/cpp/interpolations.hpp b/bfps/cpp/interpolations.hpp index 73ae78b9a48b1d0dd931c7d6e0583cdfc6fb3cfd..426ac20be6e3cc82752489ea072b5872dbb084e7 100644 --- a/bfps/cpp/interpolations.hpp +++ b/bfps/cpp/interpolations.hpp @@ -24,6 +24,8 @@ +#include "field_descriptor.hpp" +#include "fluid_solver_base.hpp" #include "spline_n1.hpp" #include "spline_n2.hpp" #include "spline_n3.hpp" @@ -41,5 +43,24 @@ typedef void (*base_polynomial_values)( double fraction, double *destination); +template <class rnumber> +class buffered_vec_field +{ + public: + int buffer_width; + ptrdiff_t buffer_size; + field_descriptor<rnumber> *descriptor; + field_descriptor<rnumber> *src_descriptor; + rnumber *f; + + buffered_vec_field( + fluid_solver_base<rnumber> *FSOLVER, + const int BUFFER_WIDTH); + ~buffered_vec_field(); + + /* destroys input */ + int read_rFFTW(void *src); +}; + #endif//INTERPOLATIONS diff --git a/bfps/cpp/particles.cpp b/bfps/cpp/particles.cpp index 6e412300a221a39c3075b440bc9e61e57c158464..0ffbdc0bb36b39e9101aa02f077ffd93bbc83c28 100644 --- a/bfps/cpp/particles.cpp +++ b/bfps/cpp/particles.cpp @@ -147,7 +147,6 @@ void particles<particle_type, rnumber, multistep, ncomponents, interp_neighbours /* get grid coordinates */ int *xg = new int[this->array_size]; double *xx = new double[this->array_size]; - rnumber *vel = this->data + this->buffer_size; this->get_grid_coordinates(x, xg, xx); for (int p=0; p<this->nparticles; p++) { @@ -156,7 +155,7 @@ void particles<particle_type, rnumber, multistep, ncomponents, interp_neighbours int crank = this->get_rank(x[p*3 + 2]); if (this->fs->rd->myrank == crank) { - this->interpolation_formula(vel, xg + p*3, xx + p*3, y + p*3, deriv); + this->interpolation_formula(this->data, xg + p*3, xx + p*3, y + p*3, deriv); DEBUG_MSG( "position is %g %g %g %d %d %d %g %g %g, result is %g %g %g\n", x[p*3], x[p*3+1], x[p*3+2], @@ -192,7 +191,6 @@ void particles<particle_type, rnumber, multistep, ncomponents, interp_neighbours int deriv[] = {0, 0, 0}; int *xg = new int[this->array_size]; double *xx = new double[this->array_size]; - rnumber *vel = this->data + this->buffer_size; double tmp[3]; /* get grid coordinates */ this->get_grid_coordinates(this->state, xg, xx); @@ -200,7 +198,7 @@ void particles<particle_type, rnumber, multistep, ncomponents, interp_neighbours /* perform interpolation */ for (int p=0; p<this->nparticles; p++) if (this->fs->rd->myrank == this->computing[p]) { - this->interpolation_formula(vel, xg + p*3, xx + p*3, tmp, deriv); + this->interpolation_formula(this->data, xg + p*3, xx + p*3, tmp, deriv); jump[p] = fabs(3*this->dt * tmp[2]); if (jump[p] < this->dz*1.01) jump[p] = this->dz*1.01; @@ -693,7 +691,7 @@ void particles<particle_type, rnumber, multistep, ncomponents, interp_neighbours template <int particle_type, class rnumber, bool multistep, int ncomponents, int interp_neighbours> void particles<particle_type, rnumber, multistep, ncomponents, interp_neighbours>::sample_vec_field(void *vec_field, double *vec_values) { - rnumber *tmp_field = ((rnumber*)vec_field) + this->buffer_size; + rnumber *tmp_field = ((rnumber*)vec_field); double *vec_local = new double[3*this->nparticles]; std::fill_n(vec_local, 3*this->nparticles, 0.0); int deriv[] = {0, 0, 0}; @@ -722,66 +720,6 @@ void particles<particle_type, rnumber, multistep, ncomponents, interp_neighbours delete[] vec_local; } -template <int particle_type, class rnumber, bool multistep, int ncomponents, int interp_neighbours> -void particles<particle_type, rnumber, multistep, ncomponents, interp_neighbours>::rFFTW_to_buffered(void *void_src, void *void_dst) -{ - rnumber *src = (rnumber*)void_src; - rnumber *dst = (rnumber*)void_dst; - /* do big copy of middle stuff */ - std::copy(src, - src + this->fs->rd->local_size, - dst + this->buffer_size); - MPI_Datatype MPI_RNUM = (sizeof(rnumber) == 4) ? MPI_FLOAT : MPI_DOUBLE; - int rsrc; - /* get upper slices */ - for (int rdst = 0; rdst < this->fs->rd->nprocs; rdst++) - { - rsrc = this->fs->rd->rank[(this->fs->rd->all_start0[rdst] + - this->fs->rd->all_size0[rdst]) % - this->fs->rd->sizes[0]]; - if (this->fs->rd->myrank == rsrc) - MPI_Send( - src, - this->buffer_size, - MPI_RNUM, - rdst, - 2*(rsrc*this->fs->rd->nprocs + rdst), - this->fs->rd->comm); - if (this->fs->rd->myrank == rdst) - MPI_Recv( - dst + this->buffer_size + this->fs->rd->local_size, - this->buffer_size, - MPI_RNUM, - rsrc, - 2*(rsrc*this->fs->rd->nprocs + rdst), - this->fs->rd->comm, - MPI_STATUS_IGNORE); - } - /* get lower slices */ - for (int rdst = 0; rdst < this->fs->rd->nprocs; rdst++) - { - rsrc = this->fs->rd->rank[MOD(this->fs->rd->all_start0[rdst] - 1, - this->fs->rd->sizes[0])]; - if (this->fs->rd->myrank == rsrc) - MPI_Send( - src + this->fs->rd->local_size - this->buffer_size, - this->buffer_size, - MPI_RNUM, - rdst, - 2*(rsrc*this->fs->rd->nprocs + rdst)+1, - this->fs->rd->comm); - if (this->fs->rd->myrank == rdst) - MPI_Recv( - dst, - this->buffer_size, - MPI_RNUM, - rsrc, - 2*(rsrc*this->fs->rd->nprocs + rdst)+1, - this->fs->rd->comm, - MPI_STATUS_IGNORE); - } -} - /*****************************************************************************/ template class particles<VELOCITY_TRACER, float, true, 3, 1>; diff --git a/setup.py b/setup.py index 3910cec7a87642ebaf6573f12379981180b09a99..9b387cf9af9b8f1a345e395d1ca3eeb1c5e80d9d 100644 --- a/setup.py +++ b/setup.py @@ -46,6 +46,7 @@ except: VERSION = date_name src_file_list = ['field_descriptor', + 'interpolations', 'fftw_tools', 'fluid_solver_base', 'fluid_solver', @@ -60,7 +61,7 @@ src_file_list = ['field_descriptor', 'spline_n6', 'Lagrange_polys'] -header_list = ['cpp/base.hpp', 'cpp/interpolations.hpp'] + ['cpp/' + fname + '.hpp' for fname in src_file_list] +header_list = ['cpp/base.hpp'] + ['cpp/' + fname + '.hpp' for fname in src_file_list] # not sure we need the MANIFEST.in file, but I might as well #with open('MANIFEST.in', 'w') as manifest_in_file: diff --git a/tests/test_base.py b/tests/test_base.py index 4e7ae85050305e190a9dbc85cb5b580f83af3b13..bf85671d8189aadfc47b74bbd2a42bef25c66f52 100755 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -92,38 +92,42 @@ def launch( c.parameters['niter_part'] = 1 c.parameters['famplitude'] = 0.2 if c.parameters['nparticles'] > 0: - c.add_particles( - kcut = 'fs->kM/2', - integration_steps = 1, neighbours = opt.neighbours, smoothness = opt.smoothness, - particle_type = 'new_tracers') #c.add_particles( # kcut = 'fs->kM/2', # integration_steps = 1, neighbours = opt.neighbours, smoothness = opt.smoothness, # particle_type = 'old_tracers') + c.add_particle_fields(name = 'regular', neighbours = 6) + c.add_particle_fields(kcut = 'fs->kM/2', name = 'filtered', neighbours = opt.neighbours) + c.add_particles( + kcut = 'fs->kM/2', + integration_steps = 1, neighbours = opt.neighbours, smoothness = opt.smoothness, + particle_type = 'new_tracers', + fields_name = 'filtered') for integr_steps in range(1, 7): c.add_particles( integration_steps = 1, neighbours = opt.neighbours, smoothness = opt.smoothness, - particle_type = 'new_tracers') - for info in [(2, 1, 0), (2, 1, 1), (2, 6, 1), (2, 6, 2)]: + particle_type = 'new_tracers', + fields_name = 'regular') + for info in [(2, 1, 0, 'spline', 'AdamsBashforth'), + (2, 1, 1, 'spline', 'AdamsBashforth'), + (2, 6, 1, 'spline', 'AdamsBashforth'), + (2, 6, 2, 'spline', 'AdamsBashforth'), + (2, 6, 1, 'spline', 'Heun'), + (4, 6, 1, 'spline', 'cRK4'), + (2, 1, 1, 'Lagrange', 'AdamsBashforth'), + (2, 6, 1, 'Lagrange', 'AdamsBashforth'), + (2, 6, 1, 'Lagrange', 'Heun'), + (4, 6, 1, 'Lagrange', 'cRK4')]: c.add_particles( integration_steps = info[0], neighbours = info[1], smoothness = info[2], - particle_type = 'new_tracers') - c.add_particles(integration_steps = 2, neighbours = 6, smoothness = 1, integration_method = 'Heun', - particle_type = 'new_tracers') - c.add_particles(integration_steps = 4, neighbours = 6, smoothness = 1, integration_method = 'cRK4', - particle_type = 'new_tracers') - c.add_particles(integration_steps = 2, neighbours = 1, interp_type = 'Lagrange', - particle_type = 'new_tracers') - c.add_particles(integration_steps = 2, neighbours = 6, interp_type = 'Lagrange', - particle_type = 'new_tracers') - c.add_particles(integration_steps = 2, neighbours = 6, interp_type = 'Lagrange', integration_method = 'Heun', - particle_type = 'new_tracers') - c.add_particles(integration_steps = 4, neighbours = 6, interp_type = 'Lagrange', integration_method = 'cRK4', - particle_type = 'new_tracers') + interp_type = info[3], + integration_method = info[4], + particle_type = 'new_tracers', + fields_name = 'regular') c.fill_up_fluid_code() c.finalize_code() c.write_src()