diff --git a/cpp/particles/interpolation/abstract_particle_set.hpp b/cpp/particles/interpolation/abstract_particle_set.hpp index 79ee01e27c315a7af66c0ab120cc08db3a7b7971..343991283bbdcfa1962b012adc47915de14c0d44 100644 --- a/cpp/particles/interpolation/abstract_particle_set.hpp +++ b/cpp/particles/interpolation/abstract_particle_set.hpp @@ -97,6 +97,28 @@ class abstract_particle_set return EXIT_SUCCESS; } + int copy_state_tofrom( + particle_rnumber *dst, + const particle_rnumber *src) + { + return this->LOOP( + [&](const partsize_t idx) + { + dst[idx] = src[idx]; + }); + } + + int copy_state_tofrom( + std::unique_ptr<particle_rnumber[]> &dst, + const std::unique_ptr<particle_rnumber[]> &src) + { + return this->LOOP( + [&](const partsize_t idx) + { + dst[idx] = src[idx]; + }); + } + /** Reorganize particles within MPI domain. * * Based on current particle locations, redistribute the full state diff --git a/cpp/particles/particle_solver.cpp b/cpp/particles/particle_solver.cpp index 65ec05704c8be78f2b4a2de7643a9832ed831638..3783bf1ae9382aa762f7d7892e485e0f810ee81d 100644 --- a/cpp/particles/particle_solver.cpp +++ b/cpp/particles/particle_solver.cpp @@ -90,25 +90,27 @@ int particle_solver::Heun( // so we must put everything in the same vector. std::vector<std::unique_ptr<particle_rnumber[]>> tvalues; std::unique_ptr<particle_rnumber[]> xx, x0, k1, k2; - // allocate k0 - x0.reset(new particle_rnumber[this->pset->getLocalNumberOfParticles()*(this->pset->getStateSize())]); - // allocate k1 - k1.reset(new particle_rnumber[this->pset->getLocalNumberOfParticles()*(this->pset->getStateSize())]); - // allocate k2 - k2.reset(new particle_rnumber[this->pset->getLocalNumberOfParticles()*(this->pset->getStateSize())]); - // allocate xx - xx.reset(new particle_rnumber[this->pset->getLocalNumberOfParticles()*(this->pset->getStateSize())]); + // allocate x0 + x0.reset(new particle_rnumber[this->pset->getLocalNumberOfParticles()*(this->pset->getStateSize())]); // store initial condition this->pset->getParticleState(x0.get()); tvalues.resize(1); - tvalues[0].reset(new particle_rnumber[1]); - tvalues[0].swap(x0); + tvalues[0].reset(new particle_rnumber[ + this->pset->getLocalNumberOfParticles()* + this->pset->getStateSize()]); + this->pset->copy_state_tofrom(tvalues[0], x0); + // allocate k1 + k1.reset(new particle_rnumber[this->pset->getLocalNumberOfParticles()*(this->pset->getStateSize())]); // compute k1 + // possibly change local ordering, but size of particle state remains the same rhs(0, *(this->pset), k1.get(), tvalues); - x0.swap(tvalues[0]); + // copy back initial date to x0 + this->pset->copy_state_tofrom(x0, tvalues[0]); + // allocate xx + xx.reset(new particle_rnumber[this->pset->getLocalNumberOfParticles()*(this->pset->getStateSize())]); // compute xn+h*k1 in particle set this->pset->LOOP( [&](const partsize_t idx){ @@ -120,18 +122,28 @@ int particle_solver::Heun( // the subsequent computations are meaningless (and can lead to segfaults). this->pset->setParticleState(xx.get()); tvalues.resize(2); - tvalues[0].reset(new particle_rnumber[1]); - tvalues[1].reset(new particle_rnumber[1]); - tvalues[0].swap(x0); - tvalues[1].swap(k1); + tvalues[0].reset(new particle_rnumber[ + this->pset->getLocalNumberOfParticles()* + this->pset->getStateSize()]); + tvalues[1].reset(new particle_rnumber[ + this->pset->getLocalNumberOfParticles()* + this->pset->getStateSize()]); + this->pset->copy_state_tofrom(tvalues[0], x0); + this->pset->copy_state_tofrom(tvalues[1], k1); this->pset->redistribute(tvalues); // impose model constraints, so that rhs is computed correctly rhs.imposeModelConstraints(*(this->pset)); + // allocate k2 + k2.reset(new particle_rnumber[this->pset->getLocalNumberOfParticles()*(this->pset->getStateSize())]); // compute k2 // note the temporal interpolation is at `1`, i.e. end of time-step rhs(1, *(this->pset), k2.get(), tvalues); - x0.swap(tvalues[0]); - k1.swap(tvalues[1]); + // reallocate k0 + x0.reset(new particle_rnumber[this->pset->getLocalNumberOfParticles()*(this->pset->getStateSize())]); + // reallocate k1 + k1.reset(new particle_rnumber[this->pset->getLocalNumberOfParticles()*(this->pset->getStateSize())]); + this->pset->copy_state_tofrom(x0, tvalues[0]); + this->pset->copy_state_tofrom(k1, tvalues[1]); // tvalues no longer required tvalues.resize(0); diff --git a/cpp/particles/rhs/tracer_with_collision_counter_rhs.hpp b/cpp/particles/rhs/tracer_with_collision_counter_rhs.hpp index 200fcdeb80c5bbe39568264b83b7c2591d4076f5..639d3aa85393d5735c30551764bebb2760957e16 100644 --- a/cpp/particles/rhs/tracer_with_collision_counter_rhs.hpp +++ b/cpp/particles/rhs/tracer_with_collision_counter_rhs.hpp @@ -56,20 +56,16 @@ class tracer_with_collision_counter_rhs: public tracer_rhs<rnumber, be, tt> additional_data.push_back(std::unique_ptr<abstract_particle_set::particle_rnumber[]>( new abstract_particle_set::particle_rnumber[pset.getLocalNumberOfParticles()*pset.getStateSize()])); // copy rhs values to temporary array - pset.LOOP( - [&](const abstract_particle_set::partsize_t idx) - { - additional_data[additional_data.size()-1][idx] = result[idx]; - }); + pset.copy_state_tofrom( + additional_data[additional_data.size()-1].get(), + result); pset.template applyP2PKernel<3, p2p_ghost_collisions<abstract_particle_set::particle_rnumber, abstract_particle_set::partsize_t>>( this->p2p_gc, additional_data); // copy shuffled rhs values - pset.LOOP( - [&](const abstract_particle_set::partsize_t idx) - { - result[idx] = additional_data[additional_data.size()-1][idx]; - }); + pset.copy_state_tofrom( + result, + additional_data[additional_data.size()-1].get()); // clear temporary array additional_data.pop_back(); return interpolation_result;