OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
FieldView.hpp
Go to the documentation of this file.
1 // -*- C++ -*-
2 /***************************************************************************
3  *
4  * The IPPL Framework
5  *
6  * This program was prepared by PSI.
7  * All rights in the program are reserved by PSI.
8  * Neither PSI nor the author(s)
9  * makes any warranty, express or implied, or assumes any liability or
10  * responsibility for the use of this software
11  *
12  * Visit www.amas.web.psi for more details
13  *
14  ***************************************************************************/
15 
16 // -*- C++ -*-
17 /***************************************************************************
18  *
19  * The IPPL Framework
20  *
21  *
22  * Visit http://people.web.psi.ch/adelmann/ for more details
23  *
24  ***************************************************************************/
25 
26 // include files
27 #include "Utility/FieldView.h"
28 #include "Utility/IpplInfo.h"
29 #include "Utility/PAssert.h"
30 #include "Field/BrickExpression.h"
31 #include "Field/Field.h"
32 #include "Field/LField.h"
33 #include "Message/Message.h"
34 
35 
36 #ifdef IPPL_GDL
37 #include <gdl.h>
38 #endif
39 
40 //------------------------------------------------------------------
41 // attach a 2D Field to a FieldView
42 template<class T, unsigned Dim, class Mesh, class Centering >
44  unsigned scaleX,
45  unsigned scaleY,
46  unsigned minSizeX,
47  unsigned minSizeY,
48  unsigned parent) :
49  MyField(f), SliceDim(0),ScaleX(scaleX), ScaleY(scaleY),
50  MinSizeX(minSizeX), MinSizeY(minSizeY), Parent(parent)
51 {
52 
53 #ifdef IPPL_GDL
54  if (Ippl::Comm->myNode() == Parent) {
55  dummy = GDL_OpenDisplay(X11FB);
56  GDL_SetColormap(RAINBOW_BLUE,NULL);
57  PInsist(Dim == 2,
58  "This FieldView constructor only works for a 2D Field!!");
59  // construct the LField which will be used to coalesce the data
60  NDIndex<2U> sliceDomain;
61  sliceDomain[0] = MyField.getDomain()[0];
62  sliceDomain[1] = MyField.getDomain()[1];
63  MyLField = new LField<T,2U>(sliceDomain, sliceDomain);
64  // since all LFields are born compressed, we need
65  // to explicitly uncompress the field
67  init_map();
68  }
69 #endif // IPPL_GDL
70 }
71 //------------------------------------------------------------------
72 // attach a 3D Field to a FieldView
73 template<class T, unsigned Dim, class Mesh, class Centering >
76  unsigned scaleX,
77  unsigned scaleY,
78  unsigned minSizeX,
79  unsigned minSizeY,
80  unsigned parent) :
81  MyField(f), SliceDim(sliceDim),ScaleX(scaleX), ScaleY(scaleY),
82  MinSizeX(minSizeX), MinSizeY(minSizeY), Parent(parent)
83 {
84 
85 #ifdef IPPL_GDL
86  if (Ippl::Comm->myNode() == Parent) {
87  dummy = GDL_OpenDisplay(X11FB);
88  GDL_SetColormap(RAINBOW_BLUE,NULL);
90  "Invalid slice dimension specified in FieldView constructor!!");
91  PInsist(Dim == 3,
92  "This FieldView constructor only works for a 3D Field!!");
93  // construct the LField which will be used to coalesce the data
94  NDIndex<2U> sliceDomain;
95  unsigned ix = SliceDim < 1 ? 1 : 0;
96  unsigned iy = SliceDim < 2 ? 2 : 1;
97  sliceDomain[0] = MyField.getDomain()[ix];
98  sliceDomain[1] = MyField.getDomain()[iy];
99  MyLField = new LField<T,2U>(sliceDomain, sliceDomain);
100  // since all LFields are born compressed, we need
101  // to explicitly uncompress the field
102  MyLField->Uncompress();
103  init_map();
104  }
105 #endif // IPPL_GDL
106 }
107 //------------------------------------------------------------------
108 template<class T, unsigned Dim, class Mesh, class Centering >
110 {
111 
112 
113 #ifdef IPPL_GDL
114  delete MyLField;
115  delete [] MapX;
116  delete [] MapY;
117  delete [] Data;
118 #endif // IPPL_GDL
119 }
120 //------------------------------------------------------------------
121 // view the 2D data in a GDL window
122 template<class T, unsigned Dim, class Mesh, class Centering >
124 {
125 
126 
127 #ifdef IPPL_GDL
128  update_2D_data();
129  /* only 0 should do apply map */
130  if (Ippl::Comm->myNode() == Parent)
131  r = apply_map();
132  else
133  r = 1;
134 #endif // IPPL_GDL
135 }
136 //------------------------------------------------------------------
137 // view a slice of a 3D field in a GDL window
138 template<class T, unsigned Dim, class Mesh, class Centering >
139 void FieldView<T,Dim,Mesh,Centering>::void_view(unsigned slice, int &r)
140 {
141 
142 
143 
144 #ifdef IPPL_GDL
145  update_3D_data(slice);
146  /* only 0 should do apply map */
147  if (Ippl::Comm->myNode() == Parent)
148  r = apply_map();
149  else
150  r = 1;
151 #endif // IPPL_GDL
152 }
153 //------------------------------------------------------------------
154 // view a slice of a 3D field in a GDL window
155 template<class T, unsigned Dim, class Mesh, class Centering >
157 {
158 
159 #ifdef IPPL_GDL
160  int icount = 0;
161  LField<T,2U>::iterator liter = MyLField->begin();
162  // make the origin at the lower left
163  int domainY = MyField.getLayout().getDomain()[1].length();
164  for( int j = 0 ; j < SizeY ; j++) {
165  for( int i = 0 ; i < SizeX ; i++) {
166  Data[icount++] = liter.offset(MapX[i],domainY-MapY[j]-1);
167  }
168  }
169 #endif // IPPL_GDL
170 #ifdef IPPL_GDL
171  r = GDL_Display_double(Data, SizeX, SizeY);
172 #else
173  r = dummy;
174 #endif // IPPL_GDL
175 }
176 //------------------------------------------------------------------
177 // draw all the data together onto the Parent process for viewing
178 template<class T, unsigned Dim, class Mesh, class Centering >
179 void
181 {
182 
183 #ifdef IPPL_GDL
184  int tag = Ippl::Comm->next_tag( FV_2D_TAG, FV_TAG_CYCLE );
185  typedef LField<T,Dim>::iterator LFI;
186 
187  // ----------------------------------------
188  // First loop over all the local nodes and send
190  for (local = MyField.begin_if(); local != MyField.end_if(); ++local) {
191  // Cache some information about this local field.
192  LField<T,Dim> &l = *(*local).second;
193  NDIndex<Dim>& lo = (NDIndex<Dim>&) l.getOwned();
195  l.Uncompress();
196  T* lp = l.getP();
197 
198  // Build a message containing the owned LocalField data
199  Message *mess = new Message();
200  ::putMessage(*mess, lo);
201  LFI msgval(lp,lo,la);
202  ::putMessage(*mess, msgval);
203 
204  // Send it.
205  Ippl::Comm->send(mess, Parent, tag);
206  }
207 
208  // ----------------------------------------
209  // Receive all the messages.
210  if( Ippl::Comm->myNode() == Parent ) {
211  // we expect to receive one message from each vnode
212  int numVnodes = MyField.getLayout().size_iv() +
213  MyField.getLayout().size_rdv();
214  for (int remaining = numVnodes; remaining>0; --remaining) {
215  // Receive the generic message.
216  int any_node = COMM_ANY_NODE;
217  Message *mess = Ippl::Comm->receive_block(any_node, tag);
218  PAssert(mess);
219 
220  // Extract the rhs BrickIterator from it.
221  NDIndex<Dim> localBlock;
222  T rhs_compressed_data;
223  LFI rhs(rhs_compressed_data);
224  localBlock.getMessage(*mess);
225  rhs.getMessage(*mess);
226 
227  // Build the lhs brick iterator.
228  LFI lhs(MyLField->getP(), localBlock, MyLField->getAllocated());
229 
230  // Do the assignment.
231  BrickExpression<Dim,LFI,LFI,OpAssign > (lhs,rhs).apply();
232 
233  // Free the memory.
234  delete mess;
235  }
236  }
237 #endif // IPPL_GDL
238 }
239 //------------------------------------------------------------------
240 template<class T, unsigned Dim, class Mesh, class Centering >
241 void
243 {
244 
245 #ifdef IPPL_GDL
246  Inform testmsg("FieldView");
247  PInsist(Dim == 3,
248  "FieldView::update_3D_data is only valid for a 3D Field!!");
249  int tag = Ippl::Comm->next_tag( FV_3D_TAG, FV_TAG_CYCLE );
250  typedef LField<T,3U>::iterator LFI;
251 
252  const Index& sl = MyField.getDomain()[SliceDim];
253  if ((slice < sl.first()) || (slice >= sl.first() + sl.length())) {
254  ERRORMSG("FieldView: bad slice choice of "<< slice << " in dim ");
255  ERRORMSG(SliceDim << endl);
256  return;
257  }
258  // find the domain which represents the 2D slice plane
259  NDIndex<3U> sliceDomain(MyField.getDomain());
260  sliceDomain[SliceDim] = Index(slice,slice);
261  // testmsg << " Slice is " << sliceDomain << endl;
262  // ----------------------------------------
263  // First loop over all the local nodes and send
265  int vnode = 0;
266  for (local = MyField.begin_if(); local != MyField.end_if(); ++local) {
267  // testmsg << " vnode = " << vnode << endl;
268  // Cache some information about this local field.
269  // testmsg << " vnode is " << vnode << endl;
270  LField<T,3U> &l = *(*local).second;
271  NDIndex<3U>& lo = (NDIndex<3U>&) l.getOwned();
272  NDIndex<3U>& la = (NDIndex<3U>&) l.getAllocated();
273  l.Uncompress();
274  T* lp = l.getP();
275 
276  // find the intersection with the slice
277  NDIndex<3U> intersection = lo.intersect( sliceDomain );
278  // testmsg << " intersection is " << intersection << endl;
279 
280  // Build a message containing a slice of the owned LocalField data
281  Message *mess = new Message();
282  // mess->put(intersection);
283  ::putMessage(*mess, intersection);
284  // testmsg << " sending: " << endl;
285  // testmsg << " lo = " << intersection << endl;
286  // testmsg << " la = " << la << endl;
287  LFI msgval(lp,intersection,la);
288 
289  // LFI data = l.begin();
290  // print out the whole field:
291  // int i,j,k;
292  // for( i = 0 ; i < data.size(0) ; i++) {
293  // for( j = 0 ; j < data.size(1) ; j++) {
294  // for( k = 0 ; k < data.size(2) ; k++) {
295  // testmsg << "data["<<i<<"]["<<j<<"]["<<k<<"]= "<<data.offset(i,j,k)<<endl;
296  // }
297  // }
298  // }
299 
300  // mess->put(msgval);
301  ::putMessage(*mess, msgval);
302 
303  // vnode++;
304  // Send it.
305  Ippl::Comm->send(mess, Parent, tag);
306  }
307 
308  // ----------------------------------------
309  // Receive all the messages.
310  if( Ippl::Comm->myNode() == Parent ) {
311  // we expect to receive one message from each vnode
312  int numVnodes = MyField.getLayout().size_iv() +
313  MyField.getLayout().size_rdv();
314  for (int remaining = numVnodes; remaining>0; --remaining) {
315  // Receive the generic message.
316  int any_node = COMM_ANY_NODE;
317  Message *mess = Ippl::Comm->receive_block(any_node, tag);
318  PAssert(mess);
319 
320  // Extract the rhs BrickIterator from it.
321  NDIndex<3U> localBlock;
322  T rhs_compressed_data;
323  LFI rhs(rhs_compressed_data);
324  localBlock.getMessage(*mess);
325  rhs.getMessage(*mess);
326 
327  unsigned ix = SliceDim < 1 ? 1 : 0;
328  unsigned iy = SliceDim < 2 ? 2 : 1;
329 
330  LField<double,2U>::iterator liter = MyLField->begin();
331 
332  if(rhs.size(SliceDim) > 0) {
333  int f0 = localBlock[ix].first();
334  int f1 = localBlock[iy].first();
335  int n0 = localBlock[ix].length();
336  int n1 = localBlock[iy].length();
337  // cout << " f0 = " << f0;
338  // cout << " f1 = " << f1;
339  // cout << " n0 = " << n0;
340  // cout << " n1 = " << n1;
341 
342  for (int i1=0; i1<n1; ++i1)
343  for (int i0=0; i0<n0; ++i0) {
344  // cout << "rhs["<<i0<<"]["<<i1<<"]= "<< *rhs << endl;
345  liter.offset(f0+i0,f1+i1) = *rhs;
346  ++rhs;
347  }
348  }
349 
350  // Free the memory.
351  delete mess;
352  }
353  }
354 #endif // IPPL_GDL
355 }
356 //------------------------------------------------------------------
357 // helper functions to fit the data into the viewing port
358 template<class T, unsigned Dim, class Mesh, class Centering >
359 void
361 {
362 
363 
364 #ifdef IPPL_GDL
365  int i,j;
366 
367  int domainX, domainY;
368  unsigned ix, iy;
369  switch(Dim) {
370  case 2:
371  domainX = MyField.getLayout().getDomain()[0].length();
372  domainY = MyField.getLayout().getDomain()[1].length();
373  break;
374  case 3:
375  ix = SliceDim < 1 ? 1 : 0;
376  iy = SliceDim < 2 ? 2 : 1;
377  domainX = MyField.getLayout().getDomain()[ix].length();
378  domainY = MyField.getLayout().getDomain()[iy].length();
379  break;
380  default:
381  ERRORMSG("FieldView: bad dimension " << Dim << " for FieldView mapping");
382  ERRORMSG(endl);
383  break;
384  }
385  // set scale factors in x and y directions
386  SizeX = domainX;
387  while(SizeX < MinSizeX) {
388  ScaleX++;
389  SizeX = ScaleX * domainX;
390  }
391  SizeY = domainY;
392  while(SizeY < MinSizeY) {
393  ScaleY++;
394  SizeY = ScaleY * domainY;
395  }
396  // allocate memory
397  MapX = new int[SizeX];
398  MapY = new int[SizeY];
399  Data = new T[SizeX*SizeY];
400 
401  int icount = 0;
402  for( i = 0 ; i < domainX ; i++) {
403  for( j = 0 ; j < ScaleX ; j++) {
404  MapX[icount++] = i;
405  }
406  }
407  icount = 0;
408  for( i = 0 ; i < domainY ; i++) {
409  for( j = 0 ; j < ScaleY ; j++) {
410  MapY[icount++] = i;
411  }
412  }
413 #endif // IPPL_GDL
414 }
415 //------------------------------------------------------------------
416 /***************************************************************************
417  * $RCSfile: FieldView.cpp,v $ $Author: adelmann $
418  * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:33 $
419  * IPPL_VERSION_ID: $Id: FieldView.cpp,v 1.1.1.1 2003/01/23 07:40:33 adelmann Exp $
420  ***************************************************************************/
void void_apply_map(int &r)
Definition: FieldView.hpp:156
ac_id_larray::iterator iterator_if
Definition: BareField.h:91
void update_3D_data(unsigned slice)
Definition: FieldView.hpp:242
Definition: rbendmap.h:8
void update_2D_data()
Definition: FieldView.hpp:180
const NDIndex< Dim > & getOwned() const
Definition: LField.h:93
int dummy
Definition: FieldView.h:79
T & offset(int i) const
#define ERRORMSG(msg)
Definition: IpplInfo.h:399
#define FV_2D_TAG
Definition: Tags.h:56
unsigned SliceDim
Definition: FieldView.h:83
Message & getMessage(Message &m)
Definition: NDIndex.h:147
FieldView(Field< T, Dim, Mesh, Centering > &f, unsigned scaleX=4, unsigned scaleY=4, unsigned minSizeX=200, unsigned minSizeY=200, unsigned parent=0)
Definition: FieldView.hpp:43
const int COMM_ANY_NODE
Definition: Communicate.h:40
void Uncompress(bool fill_domain=true)
Definition: LField.h:166
int next_tag(int t, int s=1000)
Definition: TagMaker.h:43
const iterator & begin() const
Definition: LField.h:104
unsigned int length() const
Definition: IndexInlines.h:131
#define FV_3D_TAG
Definition: Tags.h:57
iterator_if end_if()
Definition: BareField.h:100
Definition: Index.h:236
#define FV_TAG_CYCLE
Definition: Tags.h:58
const NDIndex< Dim > & getAllocated() const
Definition: LField.h:92
void void_view(int &r)
Definition: FieldView.hpp:123
void init_map()
Definition: FieldView.hpp:360
LField< T, 2U > * MyLField
Definition: FieldView.h:81
unsigned Parent
Definition: FieldView.h:86
NDIndex< Dim > intersect(const NDIndex< Dim > &) const
int first() const
Definition: IndexInlines.h:116
#define PAssert(c)
Definition: PAssert.h:117
#define PInsist(c, m)
Definition: PAssert.h:135
const unsigned Dim
void putMessage(Message &m, const T &t)
Definition: Message.h:557
iterator_if begin_if()
Definition: BareField.h:99
Message * receive_block(int &node, int &tag)
Definition: Inform.h:41
T * getP()
Definition: LField.h:94
static Communicate * Comm
Definition: IpplInfo.h:93
bool send(Message *, int node, int tag, bool delmsg=true)
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
Field< T, Dim, Mesh, Centering > & MyField
Definition: FieldView.h:80