OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
ParticleLayoutFromGrid.cpp
Go to the documentation of this file.
1 //
2 // C++ Implementation: ParticleLayoutFromGrid
3 //
4 // Description:
5 //
6 //
7 //
8 // Author: Roman Geus <geus@maxwell>, (C) 2005
9 //
10 // Copyright: See COPYING file that comes with this distribution
11 //
12 #include <cassert>
13 #include "ParticleLayoutFromGrid.h"
14 
16  unsigned num_procs = Ippl::getNodes();
17  unsigned my_id = Ippl::myNode();
18  size_t num_my_particles = particles.getLocalNum();
19 
20  // Delete particles in destroy list, update local num
21  size_t num_destroyed_particles = particles.getDestroyNum();
22  particles.performDestroy();
23  num_my_particles -= num_destroyed_particles;
24 
25  // FIXME: This should be done in IpplParticleBase::performDestroy()
26  particles.setLocalNum(num_my_particles);
27 
28  // Apply boundary conditions to the particle positions
29  // apply_bconds(particles.R);
30 
31  // Redistribute particles, such that particles that have moved outside the
32  // local domain are moved to the corresponding processor.
33  unsigned num_active_procs = grid_->give_number_of_active_processes();
34  if (num_active_procs > 1)
35  num_my_particles = redistribute_particles(particles);
36 
37  // Update total number of particles in particle container
38  size_t num_total_particles;
39  reduce(num_my_particles, num_total_particles, OpAddAssign());
40  particles.setTotalNum(num_total_particles);
41 }
42 
44 {
45  Inform msg("update");
46  size_t num_my_particles = R.size();
47 
48  for (size_t ip = 0; ip < num_my_particles; ++ ip) {
49  D3vector pos(R[ip](0), R[ip](1), R[ip](2));
50  if (!geom_domain_->point_in_domain(pos)) {
51  msg << "Particle " << ip << " moved outside domain." << endl;
52  }
53  }
54 }
55 
57 {
58  unsigned num_procs = Ippl::getNodes();
59  unsigned my_id = Ippl::myNode();
60  size_t num_my_particles = particles.getLocalNum();
61 
62  // FIXME: How do I test if I am an active processor?
63  // FIXME: Assume that active processors are assigned the ids 0..num_active_procs-1.
64  unsigned num_active_procs = grid_->give_number_of_active_processes();
65 
66  // Non-active processors return here!
67  if (my_id >= num_active_procs)
68  return num_my_particles;
69 
70  std::vector<D3vector> bb_min;
71  std::vector<D3vector> bb_max;
72  for (int p = 0; p < num_active_procs; ++ p) {
73  double xmin[3], xmax[3];
74  grid_->localbox(xmin, xmax, p);
75  bb_min.push_back(D3vector(xmin[0], xmin[1], xmin[2]));
76  bb_max.push_back(D3vector(xmax[0], xmax[1], xmax[2]));
77  }
78  // FIXME: Bounding boxes could be sorted, such that neighbors are close the beginning.
79  // FIXME: Should the local bounding box be removed from this list?
80 
81  // num_active_procs Message objects
82  std::vector<Message> messages(num_active_procs);
83  // List of particles for each message
84  std::vector<size_t>* put_list = new std::vector<size_t>[num_active_procs];
85 
86  for (size_t ip = 0; ip < num_my_particles; ++ ip) {
87  D3vector pos(particles.R[ip][0], particles.R[ip][1], particles.R[ip][2]);
88 
89  if (!is_local_pos(pos))
90  {
91  // Particle has moved outside the local domain
92 
93  // Identify processor which should receive the particle (linear search)
94  unsigned target_id = num_active_procs;
95  for (unsigned p = 0; p < num_active_procs; ++ p) {
96  if (is_inside_box(bb_min[p], bb_max[p], pos)) {
97  target_id = p;
98  break;
99  }
100  }
101  assert(target_id != num_active_procs && target_id != my_id);
102  put_list[target_id].push_back(ip);
103 
104  // Mark particle for deletion
105  particles.destroy(1, ip);
106  }
107  }
108 
109  // Send particles to their destination nodes
111  for (int p = 0; p < num_active_procs; ++ p) {
112  if (p != my_id) {
113  // Put data for particles on this put list into message and add sentinel
114  particles.putMessage(messages[p], put_list[p]);
115  particles.putMessage(messages[p], (size_t) 0, (size_t) 0);
116  // Send message
117  // Note: The last parameter is set to false, to prevent send() from destroying the Message object
118  Ippl::Comm->send(&messages[p], p, tag, false);
119  }
120  put_list[p].clear();
121  }
122 
123  // Delete sent particles.
124  num_my_particles -= particles.getDestroyNum();
125  particles.performDestroy();
126 
127  // FIXME: This should be done in IpplParticleBase::performDestroy()
128  particles.setLocalNum(num_my_particles);
129 
130  // Receive particles
131  unsigned sendnum = num_active_procs - 1;
132  while (sendnum-- > 0) {
133  int node = Communicate::COMM_ANY_NODE;
134  Message *recmsg = Ippl::Comm->receive_block(node, tag);
135  size_t recvd;
136  size_t total_recvd = 0;
137  while ((recvd = particles.getMessage(*recmsg)) > 0)
138  total_recvd += recvd;
139  num_my_particles += total_recvd;
140  delete recmsg;
141  }
142 
143  // FIXME: This should be done in IpplParticleBase::getMessage()
144  particles.setLocalNum(num_my_particles);
145 
146  delete[] put_list;
147  return num_my_particles;
148 }
static int getNodes()
Definition: IpplInfo.cpp:773
size_t size(void) const
void destroy(size_t, size_t, bool=false)
static int myNode()
Definition: IpplInfo.cpp:794
void performDestroy(bool updateLocalNum=false)
static bool is_inside_box(const D3vector &corner_min, const D3vector &corner_max, const D3vector &x)
size_t getDestroyNum() const
int next_tag(int t, int s=1000)
Definition: TagMaker.h:43
size_t getMessage(Message &)
bool reduce(Communicate &, InputIterator, InputIterator, OutputIterator, const ReduceOp &, bool *IncludeVal=0)
Definition: GlobalComm.hpp:55
void setLocalNum(size_t n)
void apply_bconds(ParticlePos_t &R)
bool is_local_pos(const Vector_t &x) const
#define P_LAYOUT_CYCLE
Definition: Tags.h:86
size_t redistribute_particles(IpplParticleBase< ParticleLayoutFromGrid > &particles)
void update(IpplParticleBase< ParticleLayoutFromGrid > &particles)
size_t getLocalNum() const
size_t putMessage(Message &, size_t, size_t)
Message * receive_block(int &node, int &tag)
Definition: Inform.h:41
static Communicate * Comm
Definition: IpplInfo.h:93
#define P_SPATIAL_TRANSFER_TAG
Definition: Tags.h:82
bool send(Message *, int node, int tag, bool delmsg=true)
void setTotalNum(size_t n)
Inform & endl(Inform &inf)
Definition: Inform.cpp:42