src/Utility/FieldView.cpp

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  * This program was prepared by PSI. 
00007  * All rights in the program are reserved by PSI.
00008  * Neither PSI nor the author(s)
00009  * makes any warranty, express or implied, or assumes any liability or
00010  * responsibility for the use of this software
00011  *
00012  * Visit http://www.acl.lanl.gov/POOMS for more details
00013  *
00014  ***************************************************************************/
00015 
00016 // -*- C++ -*-
00017 /***************************************************************************
00018  *
00019  * The IPPL Framework
00020  * 
00021  *
00022  * Visit http://people.web.psi.ch/adelmann/ for more details
00023  *
00024  ***************************************************************************/
00025 
00026 // include files
00027 #include "Utility/FieldView.h"
00028 #include "Utility/IpplInfo.h"
00029 #include "Utility/PAssert.h"
00030 #include "Field/BrickExpression.h"
00031 #include "Field/Field.h"
00032 #include "Field/LField.h"
00033 #include "Message/Message.h"
00034 #include "Profile/Profiler.h"
00035 
00036 #ifdef IPPL_GDL
00037 #include <gdl.h>
00038 #endif
00039 
00040 //------------------------------------------------------------------
00041 // attach a 2D Field to a FieldView
00042 template<class T, unsigned Dim, class Mesh, class Centering >
00043 FieldView<T,Dim,Mesh,Centering>::FieldView(Field<T,Dim,Mesh,Centering>& f, 
00044                                            unsigned scaleX, 
00045                                            unsigned scaleY, 
00046                                            unsigned minSizeX,
00047                                            unsigned minSizeY,
00048                                            unsigned parent) : 
00049   MyField(f), SliceDim(0),ScaleX(scaleX), ScaleY(scaleY), 
00050   MinSizeX(minSizeX), MinSizeY(minSizeY), Parent(parent) 
00051 {
00052   TAU_TYPE_STRING(taustr, "void (" + CT(f) 
00053     + ", unsigned, unsigned, unsigned, unsigned, unsigned )" );
00054   TAU_PROFILE("FieldView::FieldView()", taustr, TAU_UTILITY | TAU_FIELD);
00055 
00056 #ifdef IPPL_GDL
00057   if (Ippl::Comm->myNode() == Parent) {
00058     dummy = GDL_OpenDisplay(X11FB);
00059     GDL_SetColormap(RAINBOW_BLUE,NULL);
00060     PInsist(Dim == 2,
00061             "This FieldView constructor only works for a 2D Field!!");
00062     // construct the LField which will be used to coalesce the data
00063     NDIndex<2U> sliceDomain;
00064     sliceDomain[0] = MyField.getDomain()[0];
00065     sliceDomain[1] = MyField.getDomain()[1];
00066     MyLField = new LField<T,2U>(sliceDomain, sliceDomain);
00067     // since all LFields are born compressed, we need
00068     // to explicitly uncompress the field
00069     MyLField->Uncompress();
00070     init_map();
00071   }
00072 #endif // IPPL_GDL
00073 }
00074 //------------------------------------------------------------------
00075 // attach a 3D Field to a FieldView 
00076 template<class T, unsigned Dim, class Mesh, class Centering >
00077 FieldView<T,Dim,Mesh,Centering>::FieldView(unsigned sliceDim,
00078                                            Field<T,Dim,Mesh,Centering>& f, 
00079                                            unsigned scaleX, 
00080                                            unsigned scaleY, 
00081                                            unsigned minSizeX,
00082                                            unsigned minSizeY,
00083                                            unsigned parent) : 
00084   MyField(f), SliceDim(sliceDim),ScaleX(scaleX), ScaleY(scaleY), 
00085   MinSizeX(minSizeX), MinSizeY(minSizeY), Parent(parent) 
00086 {
00087   TAU_TYPE_STRING(taustr, "void (unsigned, " + CT(f) 
00088     + ", unsigned, unsigned, unsigned, unsigned, unsigned )" );
00089   TAU_PROFILE("FieldView::FieldView()", taustr, TAU_UTILITY | TAU_FIELD);
00090 
00091 #ifdef IPPL_GDL
00092   if (Ippl::Comm->myNode() == Parent) {
00093     dummy = GDL_OpenDisplay(X11FB);
00094     GDL_SetColormap(RAINBOW_BLUE,NULL);
00095     PInsist(SliceDim < Dim,
00096             "Invalid slice dimension specified in FieldView constructor!!"); 
00097     PInsist(Dim == 3,
00098             "This FieldView constructor only works for a 3D Field!!");
00099     // construct the LField which will be used to coalesce the data
00100     NDIndex<2U> sliceDomain;
00101     unsigned ix = SliceDim < 1 ? 1 : 0;
00102     unsigned iy = SliceDim < 2 ? 2 : 1;
00103     sliceDomain[0] = MyField.getDomain()[ix];
00104     sliceDomain[1] = MyField.getDomain()[iy];
00105     MyLField = new LField<T,2U>(sliceDomain, sliceDomain);
00106     // since all LFields are born compressed, we need
00107     // to explicitly uncompress the field
00108     MyLField->Uncompress();
00109     init_map();
00110   }
00111 #endif // IPPL_GDL
00112 }
00113 //------------------------------------------------------------------
00114 template<class T, unsigned Dim, class Mesh, class Centering >
00115 FieldView<T,Dim,Mesh,Centering>::~FieldView() 
00116 {
00117   TAU_TYPE_STRING(taustr, CT(*this) + " void ()" );
00118   TAU_PROFILE("FieldView::FieldView()", taustr, TAU_UTILITY | TAU_FIELD);
00119 #ifdef IPPL_GDL
00120   delete MyLField; 
00121   delete [] MapX;
00122   delete [] MapY;
00123   delete [] Data;
00124 #endif // IPPL_GDL
00125 }
00126 //------------------------------------------------------------------
00127 // view the 2D data in a GDL window
00128 template<class T, unsigned Dim, class Mesh, class Centering >
00129 void FieldView<T,Dim,Mesh,Centering>::void_view(int &r) 
00130 {
00131   TAU_TYPE_STRING(taustr, CT(*this) + " void (int )" );
00132   TAU_PROFILE("FieldView::void_view()", taustr, TAU_UTILITY | TAU_FIELD);
00133 #ifdef IPPL_GDL
00134   update_2D_data();
00135   /* only 0 should do apply map */
00136   if (Ippl::Comm->myNode() == Parent) 
00137     r = apply_map();
00138   else
00139     r = 1;
00140 #endif // IPPL_GDL
00141 }
00142 //------------------------------------------------------------------
00143 // view a slice of a 3D field in a GDL window
00144 template<class T, unsigned Dim, class Mesh, class Centering >
00145 void FieldView<T,Dim,Mesh,Centering>::void_view(unsigned slice, int &r) 
00146 {
00147   TAU_TYPE_STRING(taustr, CT(*this) + " void (unsigned, int )" );
00148   TAU_PROFILE("FieldView::void_view()", taustr, TAU_UTILITY | TAU_FIELD);
00149 
00150 #ifdef IPPL_GDL
00151   update_3D_data(slice);
00152   /* only 0 should do apply map */
00153   if (Ippl::Comm->myNode() == Parent)
00154     r = apply_map();
00155   else
00156     r = 1;
00157 #endif // IPPL_GDL
00158 }
00159 //------------------------------------------------------------------
00160 // view a slice of a 3D field in a GDL window
00161 template<class T, unsigned Dim, class Mesh, class Centering >
00162 void FieldView<T,Dim,Mesh,Centering>::void_apply_map(int &r)
00163 {
00164   TAU_TYPE_STRING(taustr, CT(*this) + " void (int )" );
00165   TAU_PROFILE("FieldView::void_apply_map()", taustr, 
00166     TAU_UTILITY | TAU_FIELD);
00167 
00168 #ifdef IPPL_GDL
00169   int icount = 0;
00170   LField<T,2U>::iterator liter = MyLField->begin();
00171   // make the origin at the lower left
00172   int domainY = MyField.getLayout().getDomain()[1].length();
00173   for( int j = 0 ; j < SizeY ; j++) {
00174     for( int i = 0 ; i < SizeX ; i++) {
00175       Data[icount++] = liter.offset(MapX[i],domainY-MapY[j]-1);
00176     }
00177   }
00178 #endif // IPPL_GDL
00179 #ifdef IPPL_GDL
00180   r = GDL_Display_double(Data, SizeX, SizeY);
00181 #else
00182   r = dummy;
00183 #endif // IPPL_GDL
00184 }
00185 //------------------------------------------------------------------
00186 // draw all the data together onto the Parent process for viewing
00187 template<class T, unsigned Dim, class Mesh, class Centering >
00188 void 
00189 FieldView<T,Dim,Mesh,Centering>::update_2D_data(void) 
00190 {
00191   TAU_TYPE_STRING(taustr, CT(*this) + " void ()" );
00192   TAU_PROFILE("FieldView::update_2D_data()", taustr, 
00193     TAU_UTILITY | TAU_FIELD);
00194 
00195 #ifdef IPPL_GDL
00196   int tag = Ippl::Comm->next_tag( FV_2D_TAG, FV_TAG_CYCLE );
00197   typedef LField<T,Dim>::iterator LFI;
00198   
00199   // ----------------------------------------
00200   // First loop over all the local nodes and send
00201   Field<T,Dim,Mesh,Centering>::iterator_if local;
00202   for (local = MyField.begin_if(); local != MyField.end_if(); ++local) {
00203     // Cache some information about this local field.
00204     LField<T,Dim> &l = *(*local).second;
00205     NDIndex<Dim>& lo = (NDIndex<Dim>&) l.getOwned();
00206     NDIndex<Dim>& la = (NDIndex<Dim>&) l.getAllocated();
00207     l.Uncompress();
00208     T* lp = l.getP();
00209 
00210     // Build a message containing the owned LocalField data
00211     Message *mess = new Message();
00212     ::putMessage(*mess, lo);
00213     LFI msgval(lp,lo,la);
00214     ::putMessage(*mess, msgval);
00215 
00216     // Send it.
00217     Ippl::Comm->send(mess, Parent, tag);
00218   }
00219   
00220   // ----------------------------------------
00221   // Receive all the messages.
00222   if( Ippl::Comm->myNode() == Parent ) {
00223     // we expect to receive one message from each vnode
00224     int numVnodes = MyField.getLayout().size_iv() + 
00225       MyField.getLayout().size_rdv();
00226     for (int remaining = numVnodes; remaining>0; --remaining) {
00227       // Receive the generic message.
00228       int any_node = COMM_ANY_NODE;
00229       Message *mess = Ippl::Comm->receive_block(any_node, tag);
00230       PAssert(mess != 0);
00231 
00232       // Extract the rhs BrickIterator from it.
00233       NDIndex<Dim> localBlock;
00234       T rhs_compressed_data;
00235       LFI rhs(rhs_compressed_data);
00236       localBlock.getMessage(*mess);
00237       rhs.getMessage(*mess);
00238 
00239       // Build the lhs brick iterator.
00240       LFI lhs(MyLField->getP(), localBlock, MyLField->getAllocated());
00241 
00242       // Do the assignment.
00243       BrickExpression<Dim,LFI,LFI,OpAssign > (lhs,rhs).apply();
00244 
00245       // Free the memory.
00246       delete mess;
00247     }
00248   }
00249 #endif // IPPL_GDL
00250 }
00251 //------------------------------------------------------------------
00252 template<class T, unsigned Dim, class Mesh, class Centering >
00253 void 
00254 FieldView<T,Dim,Mesh,Centering>::update_3D_data(unsigned slice) 
00255 {
00256   TAU_TYPE_STRING(taustr, CT(*this) + " void (unsigned )" );
00257   TAU_PROFILE("FieldView::update_3D_data()", taustr, 
00258     TAU_UTILITY | TAU_FIELD);
00259 
00260 #ifdef IPPL_GDL
00261   Inform testmsg("FieldView");
00262   PInsist(Dim == 3,
00263           "FieldView::update_3D_data is only valid for a 3D Field!!");
00264   int tag = Ippl::Comm->next_tag( FV_3D_TAG, FV_TAG_CYCLE );
00265   typedef LField<T,3U>::iterator LFI;
00266   
00267   const Index& sl = MyField.getDomain()[SliceDim];
00268   if ((slice < sl.first()) || (slice >= sl.first() + sl.length())) {
00269     ERRORMSG("FieldView: bad slice choice of "<< slice << " in dim ");
00270     ERRORMSG(SliceDim << endl);
00271     return;
00272   }
00273   // find the domain which represents the 2D slice plane
00274   NDIndex<3U> sliceDomain(MyField.getDomain());
00275   sliceDomain[SliceDim] = Index(slice,slice);
00276   //  testmsg << " Slice is " << sliceDomain << endl;
00277   // ----------------------------------------
00278   // First loop over all the local nodes and send
00279   Field<T,3U,Mesh,Centering>::iterator_if local;
00280   int vnode = 0;
00281   for (local = MyField.begin_if(); local != MyField.end_if(); ++local) {
00282     //    testmsg << " vnode = " << vnode << endl;
00283     // Cache some information about this local field.
00284     // testmsg << " vnode is " << vnode << endl;
00285     LField<T,3U> &l = *(*local).second;
00286     NDIndex<3U>& lo = (NDIndex<3U>&) l.getOwned();
00287     NDIndex<3U>& la = (NDIndex<3U>&) l.getAllocated();
00288     l.Uncompress();
00289     T* lp = l.getP();
00290 
00291     // find the intersection with the slice
00292     NDIndex<3U> intersection = lo.intersect( sliceDomain );
00293     // testmsg << " intersection is " << intersection << endl;
00294 
00295     // Build a message containing a slice of the owned LocalField data
00296     Message *mess = new Message();
00297     //    mess->put(intersection);
00298     ::putMessage(*mess, intersection);
00299     // testmsg << " sending: " << endl;
00300     // testmsg << " lo = " << intersection << endl;
00301     // testmsg << " la = " << la << endl;
00302     LFI msgval(lp,intersection,la);
00303 
00304     //    LFI data = l.begin();
00305     // print out the whole field:
00306     //    int i,j,k;
00307     //    for( i = 0 ; i < data.size(0) ; i++) {
00308     //      for( j = 0 ; j < data.size(1) ; j++) {
00309     //  for( k = 0 ; k < data.size(2) ; k++) {
00310     //    testmsg << "data["<<i<<"]["<<j<<"]["<<k<<"]= "<<data.offset(i,j,k)<<endl;
00311     //  }
00312     //      }
00313     //    }
00314 
00315     //    mess->put(msgval);
00316     ::putMessage(*mess, msgval);
00317 
00318     //    vnode++;
00319     // Send it.
00320     Ippl::Comm->send(mess, Parent, tag);
00321   }
00322   
00323   // ----------------------------------------
00324   // Receive all the messages.
00325   if( Ippl::Comm->myNode() == Parent ) {
00326     // we expect to receive one message from each vnode
00327     int numVnodes = MyField.getLayout().size_iv() + 
00328       MyField.getLayout().size_rdv();
00329     for (int remaining = numVnodes; remaining>0; --remaining) {
00330       // Receive the generic message.
00331       int any_node = COMM_ANY_NODE;
00332       Message *mess = Ippl::Comm->receive_block(any_node, tag);
00333       PAssert(mess != 0);
00334 
00335       // Extract the rhs BrickIterator from it.
00336       NDIndex<3U> localBlock;
00337       T rhs_compressed_data;
00338       LFI rhs(rhs_compressed_data);
00339       localBlock.getMessage(*mess);
00340       rhs.getMessage(*mess);
00341 
00342       unsigned ix = SliceDim < 1 ? 1 : 0;
00343       unsigned iy = SliceDim < 2 ? 2 : 1;
00344 
00345       LField<double,2U>::iterator liter = MyLField->begin();
00346 
00347       if(rhs.size(SliceDim) > 0) {
00348         int f0 = localBlock[ix].first();
00349         int f1 = localBlock[iy].first();
00350         int n0 = localBlock[ix].length();
00351         int n1 = localBlock[iy].length();
00352         //      cout << " f0 = " << f0;
00353         //      cout << " f1 = " << f1;
00354         //      cout << " n0 = " << n0;
00355         //      cout << " n1 = " << n1;
00356 
00357         for (int i1=0; i1<n1; ++i1)
00358           for (int i0=0; i0<n0; ++i0) {
00359             //      cout << "rhs["<<i0<<"]["<<i1<<"]= "<< *rhs << endl;
00360               liter.offset(f0+i0,f1+i1) = *rhs;
00361               ++rhs;
00362             }
00363       }
00364 
00365       // Free the memory.
00366       delete mess;
00367     }
00368   }
00369 #endif // IPPL_GDL
00370 }
00371 //------------------------------------------------------------------
00372 // helper functions to fit the data into the viewing port
00373 template<class T, unsigned Dim, class Mesh, class Centering >
00374 void 
00375 FieldView<T,Dim,Mesh,Centering>::init_map(void) 
00376 {
00377   TAU_TYPE_STRING(taustr, CT(*this) + " void()" );
00378   TAU_PROFILE("FieldView::init_map()", taustr, TAU_UTILITY | TAU_FIELD);
00379 #ifdef IPPL_GDL
00380   int i,j;
00381 
00382   int domainX, domainY;
00383   unsigned ix, iy;
00384   switch(Dim) {
00385   case 2:
00386     domainX = MyField.getLayout().getDomain()[0].length();
00387     domainY = MyField.getLayout().getDomain()[1].length();
00388     break;
00389   case 3:
00390     ix = SliceDim < 1 ? 1 : 0;
00391     iy = SliceDim < 2 ? 2 : 1;
00392     domainX = MyField.getLayout().getDomain()[ix].length();
00393     domainY = MyField.getLayout().getDomain()[iy].length();
00394     break;
00395   default:
00396     ERRORMSG("FieldView: bad dimension " << Dim << " for FieldView mapping");
00397     ERRORMSG(endl);
00398     break;
00399   }
00400   // set scale factors in x and y directions
00401   SizeX = domainX;
00402   while(SizeX < MinSizeX) {
00403     ScaleX++;
00404     SizeX = ScaleX * domainX;
00405   }
00406   SizeY = domainY;
00407   while(SizeY < MinSizeY) {
00408     ScaleY++;
00409     SizeY = ScaleY * domainY;
00410   }
00411   // allocate memory
00412   MapX = new int[SizeX];
00413   MapY = new int[SizeY];
00414   Data = new T[SizeX*SizeY];
00415   
00416   int icount = 0;
00417   for( i = 0 ; i < domainX ; i++) {
00418     for( j = 0 ; j < ScaleX ; j++) {
00419       MapX[icount++] = i;
00420     }
00421   }
00422   icount = 0;
00423   for( i = 0 ; i < domainY ; i++) {
00424     for( j = 0 ; j < ScaleY ; j++) {
00425       MapY[icount++] = i;
00426     }
00427   }
00428 #endif // IPPL_GDL
00429 }
00430 //------------------------------------------------------------------
00431 /***************************************************************************
00432  * $RCSfile: FieldView.cpp,v $   $Author: adelmann $
00433  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:33 $
00434  * IPPL_VERSION_ID: $Id: FieldView.cpp,v 1.1.1.1 2003/01/23 07:40:33 adelmann Exp $ 
00435  ***************************************************************************/

Generated on Mon Jan 16 13:23:58 2006 for IPPL by  doxygen 1.4.6