Commit a330077b authored by gsell's avatar gsell
Browse files

cleanup: HAVE_EXPDE related code removed

parent 37fa3cde
......@@ -87,10 +87,6 @@
#include "Particle/IntTSC.h"
#include "Particle/IntSUDS.h"
#ifdef HAVE_EXPDE
#include "Particle/ParticleLayoutFromGrid.h"
#endif
// IPPL sparse index expression operations
#include "SubField/SubFieldAssign.h"
#include "SubParticle/SubParticleAssign.h"
......
//
// C++ Implementation: ParticleLayoutFromGrid
//
// Description:
//
//
//
// Author: Roman Geus <geus@maxwell>, (C) 2005
//
// Copyright: See COPYING file that comes with this distribution
//
#include <cassert>
#include "ParticleLayoutFromGrid.h"
void ParticleLayoutFromGrid::update(IpplParticleBase< ParticleLayoutFromGrid >& particles) {
unsigned num_procs = Ippl::getNodes();
unsigned my_id = Ippl::myNode();
size_t num_my_particles = particles.getLocalNum();
// Delete particles in destroy list, update local num
size_t num_destroyed_particles = particles.getDestroyNum();
particles.performDestroy();
num_my_particles -= num_destroyed_particles;
// FIXME: This should be done in IpplParticleBase::performDestroy()
particles.setLocalNum(num_my_particles);
// Apply boundary conditions to the particle positions
// apply_bconds(particles.R);
// Redistribute particles, such that particles that have moved outside the
// local domain are moved to the corresponding processor.
unsigned num_active_procs = grid_->give_number_of_active_processes();
if (num_active_procs > 1)
num_my_particles = redistribute_particles(particles);
// Update total number of particles in particle container
size_t num_total_particles;
reduce(num_my_particles, num_total_particles, OpAddAssign());
particles.setTotalNum(num_total_particles);
}
void ParticleLayoutFromGrid::apply_bconds(ParticlePos_t& R)
{
Inform msg("update");
size_t num_my_particles = R.size();
for (size_t ip = 0; ip < num_my_particles; ++ ip) {
D3vector pos(R[ip](0), R[ip](1), R[ip](2));
if (!geom_domain_->point_in_domain(pos)) {
msg << "Particle " << ip << " moved outside domain." << endl;
}
}
}
size_t ParticleLayoutFromGrid::redistribute_particles(IpplParticleBase< ParticleLayoutFromGrid >& particles)
{
unsigned num_procs = Ippl::getNodes();
unsigned my_id = Ippl::myNode();
size_t num_my_particles = particles.getLocalNum();
// FIXME: How do I test if I am an active processor?
// FIXME: Assume that active processors are assigned the ids 0..num_active_procs-1.
unsigned num_active_procs = grid_->give_number_of_active_processes();
// Non-active processors return here!
if (my_id >= num_active_procs)
return num_my_particles;
std::vector<D3vector> bb_min;
std::vector<D3vector> bb_max;
for (int p = 0; p < num_active_procs; ++ p) {
double xmin[3], xmax[3];
grid_->localbox(xmin, xmax, p);
bb_min.push_back(D3vector(xmin[0], xmin[1], xmin[2]));
bb_max.push_back(D3vector(xmax[0], xmax[1], xmax[2]));
}
// FIXME: Bounding boxes could be sorted, such that neighbors are close the beginning.
// FIXME: Should the local bounding box be removed from this list?
// num_active_procs Message objects
std::vector<Message> messages(num_active_procs);
// List of particles for each message
std::vector<size_t>* put_list = new std::vector<size_t>[num_active_procs];
for (size_t ip = 0; ip < num_my_particles; ++ ip) {
D3vector pos(particles.R[ip][0], particles.R[ip][1], particles.R[ip][2]);
if (!is_local_pos(pos))
{
// Particle has moved outside the local domain
// Identify processor which should receive the particle (linear search)
unsigned target_id = num_active_procs;
for (unsigned p = 0; p < num_active_procs; ++ p) {
if (is_inside_box(bb_min[p], bb_max[p], pos)) {
target_id = p;
break;
}
}
assert(target_id != num_active_procs && target_id != my_id);
put_list[target_id].push_back(ip);
// Mark particle for deletion
particles.destroy(1, ip);
}
}
// Send particles to their destination nodes
int tag = Ippl::Comm->next_tag(P_SPATIAL_TRANSFER_TAG, P_LAYOUT_CYCLE);
for (int p = 0; p < num_active_procs; ++ p) {
if (p != my_id) {
// Put data for particles on this put list into message and add sentinel
particles.putMessage(messages[p], put_list[p]);
particles.putMessage(messages[p], (size_t) 0, (size_t) 0);
// Send message
// Note: The last parameter is set to false, to prevent send() from destroying the Message object
Ippl::Comm->send(&messages[p], p, tag, false);
}
put_list[p].clear();
}
// Delete sent particles.
num_my_particles -= particles.getDestroyNum();
particles.performDestroy();
// FIXME: This should be done in IpplParticleBase::performDestroy()
particles.setLocalNum(num_my_particles);
// Receive particles
unsigned sendnum = num_active_procs - 1;
while (sendnum-- > 0) {
int node = Communicate::COMM_ANY_NODE;
Message *recmsg = Ippl::Comm->receive_block(node, tag);
size_t recvd;
size_t total_recvd = 0;
while ((recvd = particles.getMessage(*recmsg)) > 0)
total_recvd += recvd;
num_my_particles += total_recvd;
delete recmsg;
}
// FIXME: This should be done in IpplParticleBase::getMessage()
particles.setLocalNum(num_my_particles);
delete[] put_list;
return num_my_particles;
}
\ No newline at end of file
//
// C++ Interface: ParticleLayoutFromGrid
//
// Description:
//
//
// Author: Roman Geus <geus@maxwell>, (C) 2005
//
// Copyright: See COPYING file that comes with this distribution
//
//
#ifndef ParticleLayoutFromGrid_H
#define ParticleLayoutFromGrid_H
#include "Ippl.h"
#include "extpde.h"
class ParticleLayoutFromGrid : public ParticleLayout<double,3> {
public:
typedef int pair_t;
typedef pair_t* pair_iterator;
typedef ParticleAttrib<SingleParticlePos_t> ParticlePos_t;
typedef ParticleAttrib<Index_t> ParticleIndex_t;
typedef Vektor<double,3> Vector_t;
/**
* Constructor.
* @param grid Grid.
* @param domain Domain on which the grid is based.
* @param local_min Corner of axiparallel box defining local domain (with minimal coordinates)
* @param local_max Corner of axiparallel box defining local domain (with maximal coordinates)
*/
ParticleLayoutFromGrid(Grid* grid, Domain* domain, D3vector& local_min, D3vector& local_max) :
grid_(grid),
geom_domain_(domain),
my_corner_min_(local_min),
my_corner_max_(local_max)
{}
/**
* Does "book--keeping" after particles have been integrated one time step.
*
* "Book--keeping" includes
* - Detecting particles which have moved across a boundary and
* taking appropriate measures. (not yet implemented)
* - Redistributing particles which have moved out of the domain
* assigned to the local processor.
* - Updating the total particle count.
* @param particles Particle container.
*/
void update(IpplParticleBase< ParticleLayoutFromGrid >& particles);
/**
* Test if x is inside the domain assigned to my processor.
* @param x Position to test.
* @return True if inside.
*/
inline bool is_local_pos(const Vector_t& x) const {
const D3vector y(x[0],x[1],x[2]);
return is_inside_box(my_corner_min_, my_corner_max_, y);
}
/**
* Test if x is inside the domain assigned to my processor.
* @param x Position to test.
* @return True if inside.
*/
inline bool is_local_pos(const D3vector& x) const {
return is_inside_box(my_corner_min_, my_corner_max_, x);
}
/**
* Test if x is inside the geometric domain
* @param x Position to test.
* @return True if inside.
*/
bool is_in_domain(const D3vector& x) const {
return geom_domain_->point_in_domain(x);
}
/**
* Test if x is inside the geometric domain
* @param x Position to test.
* @return True if inside.
*/
bool is_in_domain(const Vector_t& x) const {
const D3vector y(x[0],x[1],x[2]);
return geom_domain_->point_in_domain(y);
}
/**
* Test whether x is inside axiparalllel box defined by corner_min and corner_max.
* @param corner_min Coordinates of box corner with minimal values.
* @param corner_max Coordinates of box corner with maximal values.
* @param x Position to test.
* @return True if x is inside.
*/
inline static bool is_inside_box(const D3vector& corner_min, const D3vector& corner_max, const D3vector& x) {
return corner_min[0] <= x[0] && x[0] < corner_max[0] &&
corner_min[1] <= x[1] && x[1] < corner_max[1] &&
corner_min[2] <= x[2] && x[2] < corner_max[2];
}
private:
/**
* Dummy function for boundary treatment (currently not used)
* @param R Particle positions.
*/
void apply_bconds(ParticlePos_t& R);
/**
* Go through all local particles, and send particles which are no longer in
* the local bounding box to the corresponding processors.
*
* @param particles Particle container
* @return Number of locally stored particles after redistribution
*/
size_t redistribute_particles(IpplParticleBase< ParticleLayoutFromGrid >& particles);
/**
* Pointer to the grid data structure.
*/
Grid* grid_;
/**
* Pointer to the geometric domain data structure.
*/
Domain* geom_domain_;
/**
* Corner of axiparallel box defining local domain (with minimal coordinates).
*/
D3vector my_corner_min_;
/**
* Corner of axiparallel box defining local domain (with maximal coordinates).
*/
D3vector my_corner_max_;
};
#endif
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment