matmgnt3d_mpi.cpp

Go to the documentation of this file.
00001 /* Kernel Independent Fast Multipole Method
00002    Copyright (C) 2004 Lexing Ying, New York University
00003 
00004 This program is free software; you can redistribute it and/or modify
00005 it under the terms of the GNU General Public License as published by
00006 the Free Software Foundation; either version 2, or (at your option)
00007 any later version.
00008 
00009 This program is distributed in the hope that it will be useful, but WITHOUT
00010 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00011 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00012 for more details.
00013 
00014 You should have received a copy of the GNU General Public License
00015 along with this program; see the file COPYING.  If not, write to the Free
00016 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
00017 02111-1307, USA.  */
00018 #include "matmgnt3d_mpi.hpp"
00019 #include "common/vecmatop.hpp"
00020 
00021 using std::cerr;
00022 using std::endl;
00023 
00024 // ---------------------------------------------------------------------- 
00025 double MatMgnt3d_MPI::_wsbuf[16384];
00026 
00027 // ---------------------------------------------------------------------- 
00028 MatMgnt3d_MPI::MatMgnt3d_MPI(): _np(6)
00029 {
00030 }
00031 // ---------------------------------------------------------------------- 
00032 MatMgnt3d_MPI::~MatMgnt3d_MPI()
00033 {
00034 }
00035 
00036 double MatMgnt3d_MPI::alt()
00037 {
00038   return pow(0.1, _np+1);
00039 }
00040 // ---------------------------------------------------------------------- 
00041 // ---------------------------------------------------------------------- 
00042 int MatMgnt3d_MPI::setup()
00043 {
00044   //--------------------------------------------------------
00045   _homogeneous = _knl.homogeneous();
00046   if(_homogeneous==true) {
00047          _knl.homogeneousDeg(_degVec); pA(_degVec.size()==srcDOF());
00048   }
00049   pC( samPosCal(_np,   1.0, _samPos[UE]) );
00050   pC( samPosCal(_np+2, 3.0, _samPos[UC]) );
00051   pC( samPosCal(_np,   3.0, _samPos[DE]) );
00052   pC( samPosCal(_np,   1.0, _samPos[DC]) );
00053   
00054   pC( regPosCal(_np,   1.0, _regPos    ) ); //only one regPos
00055   //--------------------------------------------------------
00056   return (0);
00057 }
00058 // ---------------------------------------------------------------------- 
00059 int MatMgnt3d_MPI::report()
00060 {
00061   cerr<<"matrix map size"<<endl;
00062   cerr<<_upwChk2UpwEqu.size()<<" "<<_upwEqu2UpwChk.size()<<" "<<_dwnChk2DwnEqu.size()<<" "<<_dwnEqu2DwnChk.size()<<" "<<_upwEqu2DwnChk.size()<<endl;
00063   return (0);
00064 }
00065 
00066 // ---------------------------------------------------------------------- 
00067 int MatMgnt3d_MPI::plnDatSze(int tp)
00068 {
00069   if(tp==UE || tp==DE)
00070          return _samPos[tp].n()*srcDOF();
00071   else
00072          return _samPos[tp].n()*trgDOF();
00073 }
00074 // ---------------------------------------------------------------------- 
00075 int MatMgnt3d_MPI::effDatSze(int tp)
00076 {
00077   //int et = eq().et();
00078   int effnum = (2*_np+2)*(2*_np)*(2*_np);
00079   if(tp==UE || tp==DE)
00080          return effnum*srcDOF();
00081   else
00082          return effnum*trgDOF();
00083 }
00084 
00085 // ---------------------------------------------------------------------- 
00086 int MatMgnt3d_MPI::UpwChk2UpwEqu_dgemv(int l, const DblNumVec& chk, DblNumVec& den)
00087 {
00088   DblNumMat& _UpwChk2UpwEqu = (_homogeneous==true) ? _upwChk2UpwEqu[0] : _upwChk2UpwEqu[l];
00089   double R = (_homogeneous==true) ? 1 : 1.0/pow(2.0,l);
00090   //---------compute matrix
00091   if(_UpwChk2UpwEqu.m()==0) {   
00092          //set matrix
00093          DblNumMat ud2c(plnDatSze(UC), plnDatSze(UE));
00094          DblNumMat chkPos(dim(),samPos(UC).n());
00095          clear(chkPos);
00096          pC( daxpy(R, samPos(UC), chkPos) ); //scale
00097 
00098          DblNumMat denPos(dim(),samPos(UE).n());
00099          clear(denPos);
00100          pC( daxpy(R, samPos(UE), denPos) ); //scale
00101          
00102          pC( _knl.buildKnlIntCtx(denPos, denPos, chkPos, ud2c) );
00103          _UpwChk2UpwEqu.resize(plnDatSze(UE), plnDatSze(UC));
00104          /* pseudoinverse */
00105          pC( pinv(ud2c, alt(), _UpwChk2UpwEqu) );
00106   }
00107   //---------matvec
00108   if(_homogeneous==true) {
00109          //matvec
00110          int srcDOF = this->srcDOF();
00111          DblNumVec tmpDen(srcDOF*samPos(UE).n(), false, _wsbuf);         clear(tmpDen);
00112          pC( dgemv(1.0, _UpwChk2UpwEqu, chk, 1.0, tmpDen) );
00113          //scale
00114          vector<double> sclvec(srcDOF);
00115          for(int s=0; s<srcDOF; s++)
00116                 sclvec[s] = pow(2.0, - l*_degVec[s]);
00117          int cnt = 0;
00118          for(int i=0; i<samPos(UE).n(); i++) {
00119                 for(int s=0; s<srcDOF; s++) {
00120                   den(cnt) = den(cnt) + tmpDen(cnt) * sclvec[s];
00121                   cnt++;
00122                 }
00123          }
00124   } else {
00125          pC( dgemv(1.0, _UpwChk2UpwEqu, chk, 1.0, den) );
00126   }
00127   return (0);
00128 }
00129 // ---------------------------------------------------------------------- 
00130 int MatMgnt3d_MPI::UpwEqu2UpwChk_dgemv(int l, Index3 idx, const DblNumVec& den, DblNumVec& chk)
00131 {
00132   NumTns<DblNumMat>& _UpwEqu2UpwChk = (_homogeneous==true) ? _upwEqu2UpwChk[0] : _upwEqu2UpwChk[l];
00133   double R = (_homogeneous==true) ? 1 : 1.0/pow(2.0, l);  
00134   if(_UpwEqu2UpwChk.m()==0)      _UpwEqu2UpwChk.resize(2,2,2);
00135   DblNumMat& _UpwEqu2UpwChkii = _UpwEqu2UpwChk(idx(0), idx(1), idx(2));
00136   //---------compute matrix
00137   if(_UpwEqu2UpwChkii.m()==0) {  
00138          _UpwEqu2UpwChkii.resize(plnDatSze(UC), plnDatSze(UE)); 
00139          DblNumMat chkPos(dim(),samPos(UC).n());
00140          clear(chkPos);
00141          pC( daxpy(2.0*R, samPos(UC), chkPos) ); //scale
00142 
00143          DblNumMat denPos(dim(),samPos(UE).n());
00144          clear(denPos);
00145          pC( daxpy(R, samPos(UE), denPos) ); //scale
00146 
00147          for(int i=0; i<dim(); i++) {
00148                 for(int j=0; j<samPos(UE).n(); j++)     {
00149                   denPos(i,j) = denPos(i,j) + (2*idx(i)-1)*R;//shift
00150                 }
00151          }
00152          pC( _knl.buildKnlIntCtx(denPos, denPos, chkPos, _UpwEqu2UpwChkii) );
00153   }
00154   //---------matvec
00155   if(_homogeneous==true) {
00156          int srcDOF = this->srcDOF();
00157          DblNumVec tmpDen(srcDOF*samPos(UE).n(), false, _wsbuf);         clear(tmpDen);
00158          vector<double> sclvec(srcDOF);
00159          for(int s=0; s<srcDOF; s++)
00160                 sclvec[s] = pow(2.0, l*_degVec[s]);
00161          int cnt = 0;
00162          for(int i=0; i<samPos(UE).n(); i++) {
00163                 for(int s=0; s<srcDOF; s++) {
00164                   tmpDen(cnt) = den(cnt) * sclvec[s];             cnt++;
00165                 }
00166          }
00167          pC( dgemv(1.0, _UpwEqu2UpwChkii, tmpDen, 1.0, chk) );
00168   } else {
00169          pC( dgemv(1.0, _UpwEqu2UpwChkii, den, 1.0, chk) );
00170   }
00171   return (0);
00172 }
00173 
00174 // ---------------------------------------------------------------------- 
00175 int MatMgnt3d_MPI::DwnChk2DwnEqu_dgemv(int l, const DblNumVec& chk, DblNumVec& den)
00176 {
00177   DblNumMat& _DwnEqu2DwnChk = (_homogeneous==true) ? _dwnChk2DwnEqu[0]: _dwnChk2DwnEqu[l];
00178   double R = (_homogeneous==true) ? 1 : 1.0/pow(2.0,l);
00179   //---------compute matrix
00180   if(_DwnEqu2DwnChk.m()==0) {    
00181          DblNumMat dd2c(plnDatSze(DC), plnDatSze(DE));
00182          DblNumMat chkPos(dim(),samPos(DC).n());                clear(chkPos);   pC( daxpy(R, samPos(DC), chkPos) ); //scale
00183          DblNumMat denPos(dim(),samPos(DE).n());                clear(denPos);   pC( daxpy(R, samPos(DE), denPos) ); //scale
00184          
00185          pC( _knl.buildKnlIntCtx(denPos, denPos, chkPos, dd2c) );//matrix
00186          _DwnEqu2DwnChk.resize(plnDatSze(DE), plnDatSze(DC));
00187          /* psuedoinverse */
00188          pC( pinv(dd2c, alt(), _DwnEqu2DwnChk) );
00189   }
00190   //---------matvec
00191   if(_homogeneous==true) {
00192          int srcDOF = this->srcDOF();
00193          DblNumVec tmpDen(srcDOF*samPos(DE).n(), false, _wsbuf);         clear(tmpDen);
00194          pC( dgemv(1.0, _DwnEqu2DwnChk, chk, 1.0, tmpDen) );
00195          //scale
00196          vector<double> sclvec(srcDOF);
00197          for(int s=0; s<srcDOF; s++)
00198                 sclvec[s] = pow(2.0, - l*_degVec[s]);
00199          int cnt = 0;
00200          for(int i=0; i<samPos(DE).n(); i++)
00201                 for(int s=0; s<srcDOF; s++) {
00202                   den(cnt) = den(cnt) + tmpDen(cnt) * sclvec[s];                  cnt++;
00203                 }
00204   } else {
00205          pC( dgemv(1.0, _DwnEqu2DwnChk, chk, 1.0, den) );
00206   }
00207   return 0;
00208 }
00209 // ---------------------------------------------------------------------- 
00210 int MatMgnt3d_MPI::DwnEqu2DwnChk_dgemv(int l, Index3 idx, const DblNumVec& den, DblNumVec& chk)
00211 {
00212   NumTns<DblNumMat>& _DwnEqu2DwnChk = (_homogeneous==true) ? _dwnEqu2DwnChk[0] : _dwnEqu2DwnChk[l];
00213   double R = (_homogeneous==true) ? 1 : 1.0/pow(2.0, l);  
00214   if(_DwnEqu2DwnChk.m()==0)      _DwnEqu2DwnChk.resize(2,2,2);
00215   DblNumMat& _DwnEqu2DwnChkii = _DwnEqu2DwnChk(idx[0], idx[1], idx[2]);
00216   
00217   //---------compute matrix
00218   if(_DwnEqu2DwnChkii.m()==0) {  
00219          _DwnEqu2DwnChkii.resize(plnDatSze(DC), plnDatSze(DE)); 
00220          DblNumMat denPos(dim(),samPos(DE).n());
00221          clear(denPos);
00222          pC( daxpy(R, samPos(DE), denPos) ); //scale
00223 
00224          DblNumMat chkPos(dim(),samPos(DC).n());
00225          clear(chkPos);
00226          pC( daxpy(0.5*R, samPos(DC), chkPos) ); //scale
00227 
00228          for(int i=0; i<dim(); i++) {
00229                 for(int j=0; j<samPos(DC).n(); j++) {
00230                   chkPos(i,j) = chkPos(i,j) + (double(idx(i))-0.5)*R;
00231                 }
00232          }
00233          pC( _knl.buildKnlIntCtx(denPos, denPos, chkPos, _DwnEqu2DwnChkii) );
00234   }
00235   //---------matvec
00236   if(_homogeneous==true) {
00237          int srcDOF = this->srcDOF();
00238          DblNumVec tmpDen(srcDOF*samPos(DE).n(), false, _wsbuf);         clear(tmpDen);
00239          vector<double> sclvec(srcDOF);
00240          for(int s=0; s<srcDOF; s++)
00241                 sclvec[s] = pow(2.0, l*_degVec[s]);
00242          int cnt = 0;
00243          for(int i=0; i<samPos(DE).n(); i++) {
00244                 for(int s=0; s<srcDOF; s++) {
00245                   tmpDen(cnt) = den(cnt) * sclvec[s];             cnt++;
00246                 }
00247          }
00248          pC( dgemv(1.0, _DwnEqu2DwnChkii, tmpDen, 1.0, chk) );
00249   } else {
00250          pC( dgemv(1.0, _DwnEqu2DwnChkii, den, 1.0, chk) );
00251   }
00252   return (0);
00253 }
00254 // ---------------------------------------------------------------------- 
00255 int MatMgnt3d_MPI::plnDen2EffDen(int l, const DblNumVec& plnDen, DblNumVec& effDen)
00256 {
00257   DblNumVec regDen(regPos().n()*srcDOF());
00258   clear(regDen);
00259   if(_homogeneous==true) {
00260          int srcDOF = this->srcDOF();
00261          DblNumVec tmpDen(srcDOF*samPos(UE).n(), false, _wsbuf);         clear(tmpDen);
00262          vector<double> sclvec(srcDOF);
00263          for(int s=0; s<srcDOF; s++)
00264                 sclvec[s] = pow(2.0, l*_degVec[s]);
00265          int cnt = 0;
00266          for(int i=0; i<samPos(UE).n(); i++) {
00267                 for(int s=0; s<srcDOF; s++) {
00268                   tmpDen(cnt) = plnDen(cnt) * sclvec[s];                  cnt++;
00269                 }
00270          }
00271          pC( samDen2RegDen(tmpDen, regDen) );
00272   } else {
00273          pC( samDen2RegDen(plnDen, regDen) );
00274   }
00275   
00276   int nnn[3];
00277   nnn[0] = 2*_np;
00278   nnn[1] = 2*_np;
00279   nnn[2] = 2*_np;
00280 
00281   fftw_plan forplan = fftw_plan_many_dft_r2c(3,nnn,srcDOF(), regDen.data(),NULL, srcDOF(),1, (fftw_complex*)(effDen.data()),NULL, srcDOF(),1, FFTW_ESTIMATE);
00282   fftw_execute(forplan);
00283   fftw_destroy_plan(forplan);  
00284   
00285   return (0);
00286 }
00287 // ---------------------------------------------------------------------- 
00288 int MatMgnt3d_MPI::samDen2RegDen(const DblNumVec& samDen, DblNumVec& regDen)
00289 {
00290   int np = _np;
00291   int rgnum = 2*np;
00292   int srcDOF = this->srcDOF();
00293   int count=0;
00294   //the order of iterating is the same as SampleGrid
00295   for(int i=0; i<np; i++) {
00296          for(int j=0; j<np; j++) {
00297                 for(int k=0; k<np; k++) {
00298                   if(i==0 || i==np-1 || j==0 || j==np-1 || k==0 || k==np-1) {
00299                          //the position is fortran style
00300                          int rgoff = (k+np/2)*rgnum*rgnum + (j+np/2)*rgnum + (i+np/2);
00301                          for(int f=0; f<srcDOF; f++) {
00302                                 regDen(srcDOF*rgoff + f) += samDen(srcDOF*count + f);
00303                          }      
00304                          count++;
00305                   }
00306                 }
00307          }
00308   }
00309   return 0;
00310 }
00311 // ---------------------------------------------------------------------- 
00312 int MatMgnt3d_MPI::effVal2PlnVal(int level, const DblNumVec& effVal, DblNumVec& plnVal)
00313 {
00314   DblNumVec regVal(regPos().n()*trgDOF());
00315   int nnn[3];
00316   nnn[0] = 2*_np;
00317   nnn[1] = 2*_np;
00318   nnn[2] = 2*_np;
00319   
00320   fftw_plan invplan = fftw_plan_many_dft_c2r(3,nnn,trgDOF(), (fftw_complex*)(effVal.data()),NULL, trgDOF(),1, regVal.data(),NULL, trgDOF(),1, FFTW_ESTIMATE);
00321   fftw_execute(invplan);
00322   fftw_destroy_plan(invplan); 
00323   
00324   pC( regVal2SamVal(regVal, plnVal) );
00325   return (0);
00326 }
00327 // ---------------------------------------------------------------------- 
00328 int MatMgnt3d_MPI::regVal2SamVal(const DblNumVec& regVal, DblNumVec& samVal)
00329 {
00330   int np = _np;
00331   int rgnum = 2*np;
00332   int trgDOF = this->trgDOF();
00333   int count=0;
00334   //the order of iterating is the same as SampleGrid
00335   for(int i=0; i<np; i++) {
00336          for(int j=0; j<np; j++) {
00337                 for(int k=0; k<np; k++) {
00338                   if(i==0 || i==np-1 || j==0 || j==np-1 || k==0 || k==np-1) {
00339                          //the position is fortran style
00340                          int rgoff = (k+np/2)*rgnum*rgnum + (j+np/2)*rgnum + (i+np/2);
00341                          for(int f=0; f<trgDOF; f++) {
00342                                 samVal(trgDOF*count + f) += regVal(trgDOF*rgoff + f);
00343                          }
00344                          count++;
00345                   }
00346                 }
00347          }
00348   }
00349   return 0;
00350 }
00351 // ---------------------------------------------------------------------- 
00352 int MatMgnt3d_MPI::UpwEqu2DwnChk_dgemv(int l, Index3 idx, const DblNumVec& effDen, DblNumVec& effVal)
00353 {
00354   OffTns<DblNumMat>& _UpwEqu2DwnChk = (_homogeneous==true) ? _upwEqu2DwnChk[0] : _upwEqu2DwnChk[l];
00355   double R = (_homogeneous==true) ? 1.0 : 1.0/pow(2.0, l); 
00356   if(_UpwEqu2DwnChk.m()==0)      _UpwEqu2DwnChk.resize(7,7,7,-3,-3,-3);
00357   DblNumMat& _UpwEqu2DwnChkii = _UpwEqu2DwnChk(idx[0], idx[1], idx[2]);
00358   
00359   int effnum = (2*_np+2)*(2*_np)*(2*_np);
00360   int srcDOF = this->srcDOF();
00361   int trgDOF = this->trgDOF();
00362   
00363   //---------compute matrix
00364   if(_UpwEqu2DwnChkii.m()==0) { 
00365          //-----------------------       
00366          pA( idx.linfty()>1 );
00367          DblNumMat denPos(dim(),1);      for(int i=0; i<dim(); i++)             denPos(i,0) = double(idx(i))*2.0*R; //shift
00368          DblNumMat chkPos(dim(),regPos().n());   clear(chkPos);  pC( daxpy(R, regPos(), chkPos) );
00369          DblNumMat tt(regPos().n()*trgDOF, srcDOF);
00370          pC( _knl.buildKnlIntCtx(denPos, denPos, chkPos, tt) );
00371          // move data to tmp
00372          DblNumMat tmp(trgDOF,regPos().n()*srcDOF);
00373          for(int k=0; k<regPos().n();k++) {
00374                 for(int i=0; i<trgDOF; i++)
00375                   for(int j=0; j<srcDOF; j++) {
00376                          tmp(i,j+k*srcDOF) = tt(i+k*trgDOF,j);
00377                   }
00378          }
00379          _UpwEqu2DwnChkii.resize(trgDOF*srcDOF, effnum); 
00380          //forward FFT from tmp to _UpwEqu2DwnChkii;
00381          
00382          int nnn[3];
00383          nnn[0] = 2*_np;
00384          nnn[1] = 2*_np;
00385          nnn[2] = 2*_np;
00386 
00387          fftw_plan forplan = fftw_plan_many_dft_r2c(3,nnn,srcDOF*trgDOF, tmp.data(),NULL, srcDOF*trgDOF,1, (fftw_complex*)(_UpwEqu2DwnChkii.data()),NULL, srcDOF*trgDOF,1, FFTW_ESTIMATE);
00388          fftw_execute(forplan);
00389          fftw_destroy_plan(forplan);     
00390   }
00391   //---------matvec
00392   //fft mult
00393   double nrmfc = 1.0/double(regPos().n());
00394   fftw_complex* matptr = (fftw_complex*)(_UpwEqu2DwnChkii.data());
00395   fftw_complex* denptr = (fftw_complex*)(effDen.data());
00396   fftw_complex* chkptr = (fftw_complex*)(effVal.data());
00397   int matstp = srcDOF*trgDOF;
00398   int denstp = srcDOF;
00399   int chkstp = trgDOF;
00400   
00401   double newalpha = nrmfc;
00402   for(int i=0; i<trgDOF; i++)
00403          for(int j=0; j<srcDOF; j++) {
00404                 int matoff = j*trgDOF + i;
00405                 int denoff = j;
00406                 int chkoff = i;
00407                 pC( cptwvv(effnum/2, newalpha, matptr+matoff, matstp, denptr+denoff, denstp, chkptr+chkoff, chkstp) );
00408          }
00409   return (0);
00410 }
00411 
00412 // ---------------------------------------------------------------------- 
00413 int MatMgnt3d_MPI::locPos(int tp, Point3 ctr, double rad, DblNumMat& pos)
00414 {
00415   /* Get sample positions associated with UC, UE, DC, or DE */
00416   const DblNumMat& bas = samPos(tp);
00417   pos.resize(dim(), bas.n());
00418   /* Build pos matrix, which will hold the sample positions as
00419         * desired by the "tp" argument, but these sample positions
00420         * will be translated by the center ctr and radius rad of the target */
00421   for(int i=0; i<dim(); i++) {
00422          for(int j=0; j<pos.n(); j++) {
00423                 pos(i,j) = ctr(i) + rad * bas(i,j);
00424          }
00425   }
00426   return (0);
00427 }
00428 
00429 // ---------------------------------------------------------------------- 
00430 int MatMgnt3d_MPI::samPosCal(int np, double R, DblNumMat& pos)
00431 {
00432   int n = np*np*np - (np-2)*(np-2)*(np-2);
00433   pos.resize(dim(),n);
00434   double step = 2.0/(np-1);
00435   double init = -1.0;
00436   int count = 0;
00437   for(int i=0; i<np; i++) {
00438          for(int j=0; j<np; j++) {
00439                 for(int k=0; k<np; k++) {
00440                   if(i==0 || i==np-1 || j==0 || j==np-1 || k==0 || k==np-1) {
00441                          double x = init + i*step;
00442                          double y = init + j*step;
00443                          double z = init + k*step;
00444                          pos(0,count) = R*x;
00445                          pos(1,count) = R*y;
00446                          pos(2,count) = R*z;
00447                          count++;
00448                   }
00449                 }       
00450          }      
00451   }
00452   pA(count==n);
00453   return 0;
00454 }
00455 
00456 // ---------------------------------------------------------------------- 
00457 int MatMgnt3d_MPI::regPosCal(int np, double R, DblNumMat& pos)
00458 {
00459   int n = 2*np*2*np*2*np;
00460   pos.resize(dim(), n);
00461   double step = 2.0/(np-1);
00462   int count = 0;
00463   for(int k=0; k<2*np; k++) {
00464          for(int j=0; j<2*np; j++) {
00465                 for(int i=0; i<2*np; i++) {
00466                   int gi = (i<np) ? i : i-2*np;
00467                   int gj = (j<np) ? j : j-2*np;
00468                   int gk = (k<np) ? k : k-2*np;
00469                   pos(0, count) = R * gi*step;
00470                   pos(1, count) = R * gj*step;
00471                   pos(2, count) = R * gk*step;
00472                   count ++;
00473                 }
00474          }
00475   }
00476   pA(count==n);
00477   return 0;
00478 }
00479 
00480 // ---------------------------------------------------------------------- 
00481 inline int MatMgnt3d_MPI::cptwvv(int n, double alpha, fftw_complex* x, int incx, fftw_complex* y, int incy, fftw_complex* z, int incz)
00482 {
00483   for(int i=0; i<n; i++) {
00484          (*z)[0] += alpha * ( (*x)[0] * (*y)[0] - (*x)[1] * (*y)[1]);
00485          (*z)[1] += alpha * ( (*x)[0] * (*y)[1] + (*x)[1] * (*y)[0]);
00486          x = x + incx;
00487          y = y + incy;
00488          z = z + incz;
00489   }  
00490   return 0;
00491 }
00492 
00493 //-----------------------------------------------------------------------------
00494 //-----------------------------------------------------------------------------
00495 //-----------------------------------------------------------------------------
00496 //-----------------------------------------------------------------------------
00497 vector<MatMgnt3d_MPI> MatMgnt3d_MPI::_mmvec;
00498 
00499 MatMgnt3d_MPI* MatMgnt3d_MPI::getmmptr(Kernel3d_MPI knl, int np)
00500 {
00501   for(int i=0; i<_mmvec.size(); i++) {
00502          if(_mmvec[i].knl()==knl && _mmvec[i].np()==np) {
00503                 return &(_mmvec[i]);
00504          }
00505   }
00506   
00507   _mmvec.push_back( MatMgnt3d_MPI() );
00508   int last = _mmvec.size()-1;
00509   MatMgnt3d_MPI* tmp = &(_mmvec[last]); //get the last one
00510   tmp->knl() = knl;
00511   tmp->np() = np;
00512   tmp->setup();
00513   return tmp;
00514 }

Generated on Sun Dec 4 21:12:40 2005 for fmm3d_mpi by  doxygen 1.4.5