fmm3d_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 
00024 #include "common/vecmatop.hpp"
00025 #include "fmm3d_mpi.hpp"
00026 
00027 /* Initialize all variables necessary for FMM3d, mostlt to NULL.
00028  * All of these will be built as necessary during setup.  See fmm3d_setup_mpi.cpp
00029  * for more information on where these get built.
00030  */
00031 FMM3d_MPI::FMM3d_MPI(const string& p):
00032   KnlMat3d_MPI(p), _ctr(0,0,0), _rootLevel(0),
00033   _np(6),
00034   _let(NULL), _matmgnt(NULL),
00035   _glbSrcExaPos(NULL), _glbSrcExaNor(NULL), _glbSrcExaDen(NULL), _glbSrcUpwEquDen(NULL),
00036   _ctbSrcExaPos(NULL), _ctbSrcExaNor(NULL), _ctbSrcExaDen(NULL), _ctbSrcUpwEquDen(NULL),
00037   _ctbSrcUpwChkVal(NULL), _ctb2GlbSrcExaPos(NULL), _ctb2GlbSrcExaDen(NULL), _ctb2GlbSrcUpwEquDen(NULL),
00038   _evaTrgExaPos(NULL), _evaTrgExaVal(NULL), _evaTrgDwnEquDen(NULL), _evaTrgDwnChkVal(NULL),
00039   _usrSrcExaPos(NULL), _usrSrcExaNor(NULL), _usrSrcExaDen(NULL), _usrSrcUpwEquDen(NULL),
00040   _usr2GlbSrcExaPos(NULL), _usr2GlbSrcExaDen(NULL), _usr2GlbSrcUpwEquDen(NULL)
00041 {
00042 }
00043 
00044 /* Destroy everything */
00045 FMM3d_MPI::~FMM3d_MPI()
00046 {
00047   if(_let!=NULL)         delete _let;
00048   
00049   if(_glbSrcExaPos!=NULL) { iC( VecDestroy(_glbSrcExaPos) ); _glbSrcExaPos=NULL; }
00050   if(_glbSrcExaNor!=NULL) { iC( VecDestroy(_glbSrcExaNor) ); _glbSrcExaPos=NULL; }
00051   if(_glbSrcExaDen!=NULL) { iC( VecDestroy(_glbSrcExaDen) ); _glbSrcExaDen=NULL; }
00052   if(_glbSrcUpwEquDen!=NULL) { iC( VecDestroy(_glbSrcUpwEquDen) ); _glbSrcUpwEquDen=NULL; }
00053   
00054   if(_ctbSrcExaPos!=NULL) { iC( VecDestroy(_ctbSrcExaPos) ); _ctbSrcExaPos=NULL; }
00055   if(_ctbSrcExaNor!=NULL) { iC( VecDestroy(_ctbSrcExaNor) ); _ctbSrcExaNor=NULL; }
00056   if(_ctbSrcExaDen!=NULL) { iC( VecDestroy(_ctbSrcExaDen) ); _ctbSrcExaDen=NULL; }
00057   if(_ctbSrcUpwEquDen!=NULL) { iC( VecDestroy(_ctbSrcUpwEquDen) ); _ctbSrcUpwEquDen=NULL; }
00058   if(_ctbSrcUpwChkVal!=NULL) { iC( VecDestroy(_ctbSrcUpwChkVal) ); _ctbSrcUpwChkVal=NULL; }
00059   if(_ctb2GlbSrcExaPos!=NULL) { iC( VecScatterDestroy(_ctb2GlbSrcExaPos) ); _ctb2GlbSrcExaPos=NULL; }
00060   if(_ctb2GlbSrcExaDen!=NULL) { iC( VecScatterDestroy(_ctb2GlbSrcExaDen) ); _ctb2GlbSrcExaDen=NULL; }
00061   if(_ctb2GlbSrcUpwEquDen!=NULL) { iC( VecScatterDestroy(_ctb2GlbSrcUpwEquDen) ); _ctb2GlbSrcUpwEquDen=NULL; }
00062   
00063   if(_evaTrgExaPos!=NULL) { iC( VecDestroy(_evaTrgExaPos) ); _evaTrgExaPos=NULL; }
00064   if(_evaTrgExaVal!=NULL) { iC( VecDestroy(_evaTrgExaVal) ); _evaTrgExaVal=NULL; }
00065   if(_evaTrgDwnEquDen!=NULL) { iC( VecDestroy(_evaTrgDwnEquDen) ); _evaTrgDwnEquDen=NULL; }
00066   if(_evaTrgDwnChkVal!=NULL) { iC( VecDestroy(_evaTrgDwnChkVal) ); _evaTrgDwnChkVal=NULL; }
00067   
00068   if(_usrSrcExaPos!=NULL) { iC( VecDestroy(_usrSrcExaPos) ); _usrSrcExaPos=NULL; }
00069   if(_usrSrcExaNor!=NULL) { iC( VecDestroy(_usrSrcExaNor) ); _usrSrcExaNor=NULL; }
00070   if(_usrSrcExaDen!=NULL) { iC( VecDestroy(_usrSrcExaDen) ); _usrSrcExaDen=NULL; }
00071   if(_usrSrcUpwEquDen!=NULL) { iC( VecDestroy(_usrSrcUpwEquDen) ); _usrSrcUpwEquDen=NULL; }
00072   if(_usr2GlbSrcExaPos!=NULL) { iC( VecScatterDestroy(_usr2GlbSrcExaPos) ); _usr2GlbSrcExaPos=NULL; }
00073   if(_usr2GlbSrcExaDen!=NULL) { iC( VecScatterDestroy(_usr2GlbSrcExaDen) ); _usr2GlbSrcExaDen=NULL; }
00074   if(_usr2GlbSrcUpwEquDen!=NULL) { iC( VecScatterDestroy(_usr2GlbSrcUpwEquDen) ); _usr2GlbSrcUpwEquDen=NULL; }
00075 }
00076 
00077 // ----------------------------------------------------------------------
00078 /* This function computes the source equivalent to target check multiplication */
00079 #undef __FUNCT__
00080 #define __FUNCT__ "FMM3d_MPI::SrcEqu2TrgChk_dgemv"
00081 int FMM3d_MPI::SrcEqu2TrgChk_dgemv(const DblNumMat& srcPos, const DblNumMat& srcNor, const DblNumMat& trgPos, const DblNumVec& srcDen, DblNumVec& trgVal)
00082 {
00083   int TMAX = 1024;
00084   /* If the number of target positions is small, do one run */
00085   if(trgPos.n()<=TMAX) {
00086          int M = trgPos.n() * _knl.trgDOF();
00087          int N = srcPos.n() * _knl.srcDOF();
00088          DblNumMat tmp(M,N);
00089          /* Compute context in tmp for computation */
00090          pC( _knl.buildKnlIntCtx(srcPos, srcNor, trgPos, tmp) );
00091          /* Compute 1.0*tmp*srcDen + 1.0*trgVal */
00092          pC( dgemv(1.0, tmp, srcDen, 1.0, trgVal) );
00093   }
00094   /* If the number of target positions is large, split up the multiplications over several smaller steps */
00095   else {
00096          /* Number of runs */
00097          int RUNS = (trgPos.n()-1) / TMAX + 1;
00098          for(int r=0; r<RUNS; r++) {
00099                 /* Where to start */
00100                 int stt = r*TMAX;
00101                 /* Where to end */
00102                 int end = min((r+1)*TMAX, trgPos.n());
00103                 /* Number of elements in the multiplcation process */
00104                 int num = end-stt;
00105                 int M = num * _knl.trgDOF();
00106                 int N = srcPos.n() * _knl.srcDOF();
00107                 /* Matrix of target positions */
00108                 DblNumMat tps(dim(), num, false, trgPos.data() + stt*dim() );
00109                 /* Vewctor of target values */
00110                 DblNumVec tvl(num*_knl.trgDOF(), false, trgVal.data() + stt*_knl.trgDOF());
00111                 DblNumMat tmp(M,N);
00112                 /* Build the Kernel matrix and multiply for result */
00113                 pC( _knl.buildKnlIntCtx(srcPos, srcNor, tps, tmp) );
00114                 /* Compute 1.0*tmp*srcDen + 1.0*tvl */
00115                 pC( dgemv(1.0, tmp, srcDen, 1.0, tvl) );
00116          }
00117   }
00118   return(0);
00119 }
00120 // ----------------------------------------------------------------------
00121 /* Compute Source Equivalent to Upward Check Multiplication */
00122 #undef __FUNCT__
00123 #define __FUNCT__ "FMM3d_MPI::SrcEqu2UpwChk_dgemv"
00124 int FMM3d_MPI::SrcEqu2UpwChk_dgemv(const DblNumMat& srcPos, const DblNumMat& srcNor, Point3 trgCtr, double trgRad, const DblNumVec& srcDen, DblNumVec& trgVal)
00125 {
00126   /* Build the target sample positions based on the upward check sample positions
00127         * as well as the target node's center and radius.  The resulting trgPos target
00128         * positions will be the UC sample positions for the requested node */
00129   DblNumMat trgPos; pC( _matmgnt->locPos(UC, trgCtr, trgRad, trgPos) );
00130   int M = trgPos.n() * _knl.trgDOF();
00131   int N = srcPos.n() * _knl.srcDOF();
00132   DblNumMat tmp(M,N);
00133   pC( _knl.buildKnlIntCtx(srcPos, srcNor, trgPos, tmp) );
00134   /* Compute 1.0*tmp*srcDen + 1.0*trgVal */
00135   pC( dgemv(1.0, tmp, srcDen, 1.0, trgVal) );
00136   return(0);
00137 }
00138 // ----------------------------------------------------------------------
00139 /* Compute Equivalent Source to Downward Check Multiplication */
00140 #undef __FUNCT__
00141 #define __FUNCT__ "FMM3d_MPI::SrcEqu2DwnChk_dgemv"
00142 int FMM3d_MPI::SrcEqu2DwnChk_dgemv(const DblNumMat& srcPos, const DblNumMat& srcNor, Point3 trgCtr, double trgRad, const DblNumVec& srcDen, DblNumVec& trgVal)
00143 {
00144   /* Build the target positions based on the downward check sample positions
00145         * and the node with center trgCtr and radius trgRad */
00146   DblNumMat trgPos; pC( _matmgnt->locPos(DC, trgCtr, trgRad, trgPos) );
00147   int M = trgPos.n() * _knl.trgDOF();
00148   int N = srcPos.n() * _knl.srcDOF();
00149   DblNumMat tmp(M,N);
00150   pC( _knl.buildKnlIntCtx(srcPos, srcNor, trgPos, tmp) );
00151   /* Compute 1.0*tmp*srcDen + 1.0*trgVal */
00152   pC( dgemv(1.0, tmp, srcDen, 1.0, trgVal) );
00153   return(0);
00154 }
00155 // ----------------------------------------------------------------------
00156 /* Compute Downward Equivalent to Target Check Multiplication */
00157 #undef __FUNCT__
00158 #define __FUNCT__ "FMM3d_MPI::DwnEqu2TrgChk_dgemv"
00159 int FMM3d_MPI::DwnEqu2TrgChk_dgemv(Point3 srcCtr, double srcRad, const DblNumMat& trgPos, const DblNumVec& srcDen, DblNumVec& trgVal)
00160 {
00161   /* Target Max = 1024 */
00162   int TMAX = 1024;
00163   /* If the number of positions in trgPos is small, do one run.  Otherwise, we will break up the multiplication */
00164   if(trgPos.n()<=TMAX) {
00165          /* Build sample source positions at the Downward Equivalent location
00166           * based on the source node's center srcCtr and radius srcRad */
00167          DblNumMat srcPos; pC( _matmgnt->locPos(DE, srcCtr, srcRad, srcPos) );
00168          int M = trgPos.n() * _knl_mm.trgDOF();
00169          int N = srcPos.n() * _knl_mm.srcDOF();
00170          DblNumMat tmp(M,N);
00171          /* Build kernel multiplier context and store in tmp */
00172          pC( _knl_mm.buildKnlIntCtx(srcPos, srcPos, trgPos, tmp) );
00173          /* Compute 1.0*tmp*srcDen + 1.0*trgVal */
00174          pC( dgemv(1.0, tmp, srcDen, 1.0, trgVal) );
00175   }
00176   /* Break up multiplication into smaller steps */
00177   else {
00178          /* Build sample source positions at the Downward Equivalent location
00179           * based on the source node's center srcCtr and radius srcRad */
00180          DblNumMat srcPos; pC( _matmgnt->locPos(DE, srcCtr, srcRad, srcPos) );
00181          /* Decide how many runs we will break the multiplication into */
00182          int RUNS = (trgPos.n()-1) / TMAX + 1;
00183          for(int r=0; r<RUNS; r++) {
00184                 /* Find start and end locations as well as number of elements being used */
00185                 int stt = r*TMAX;
00186                 int end = min((r+1)*TMAX, trgPos.n());
00187                 int num = end-stt;
00188                 int M = num * _knl_mm.trgDOF();
00189                 int N = srcPos.n() * _knl_mm.srcDOF();
00190                 /* Target positions matrix */
00191                 DblNumMat tps(dim(), num, false, trgPos.data() + stt*dim());
00192                 /* Target values vector */
00193                 DblNumVec tvl(num*_knl_mm.trgDOF(), false, trgVal.data() + stt*_knl_mm.trgDOF());
00194                 DblNumMat tmp(M, N);
00195                 /* Build multiplier context */
00196                 pC( _knl_mm.buildKnlIntCtx(srcPos, srcPos, tps, tmp) );
00197                 /* Compute 1.0*tmp*srcDen + 1.0*tvl */
00198                 pC( dgemv(1.0, tmp, srcDen, 1.0, tvl) );
00199          }
00200   }
00201   return(0);
00202 }
00203 
00204 // ----------------------------------------------------------------------
00205 /* Compute Upward Equivalent to Target Check Multiplication */
00206 #undef __FUNCT__
00207 #define __FUNCT__ "FMM3d_MPI::UpwEqu2TrgChk_dgemv"
00208 int FMM3d_MPI::UpwEqu2TrgChk_dgemv(Point3 srcCtr, double srcRad, const DblNumMat& trgPos, const DblNumVec& srcDen, DblNumVec& trgVal)
00209 {
00210   /* Target Max = 1024 */
00211   int TMAX = 1024;
00212   /* If the number of positions in trgPos is small, do one run.  Otherwise, we will break up the multiplication */
00213   if(trgPos.n()<=TMAX) {
00214          /* Build sample source positions at the Upward Equivalent location
00215           * based on the source node's center srcCtr and radius srcRad */
00216          DblNumMat srcPos; pC( _matmgnt->locPos(UE, srcCtr, srcRad, srcPos) );
00217          int M = trgPos.n() * _knl_mm.trgDOF();
00218          int N = srcPos.n() * _knl_mm.srcDOF();
00219          DblNumMat tmp(M,N);
00220          /* Build multiplier context for this kernel and store in tmp */
00221          pC( _knl_mm.buildKnlIntCtx(srcPos, srcPos, trgPos, tmp) );
00222          /* Compute 1.0*tmp*srcDen + 1.0*trgVal */
00223          pC( dgemv(1.0, tmp, srcDen, 1.0, trgVal) );
00224   }/* Break up multiplication into smaller steps */
00225   else {
00226          /* Build sample source positions at the Upward Equivalent location
00227           * based on the source node's center srcCtr and radius srcRad */
00228          DblNumMat srcPos; pC( _matmgnt->locPos(UE, srcCtr, srcRad, srcPos) );
00229          int RUNS = (trgPos.n()-1) / TMAX + 1;
00230          for(int r=0; r<RUNS; r++) {
00231                 /* Find start and end locations as well as number of elements being used */
00232                 int stt = r*TMAX;
00233                 int end = min((r+1)*TMAX, trgPos.n());
00234                 int num = end-stt;
00235                 int M = num * _knl_mm.trgDOF();
00236                 int N = srcPos.n() * _knl_mm.srcDOF();
00237                 /* Target positions matrix */
00238                 DblNumMat tps(dim(), num, false, trgPos.data() + stt*dim());
00239                 /* Target values vector */
00240                 DblNumVec tvl(num*_knl_mm.trgDOF(), false, trgVal.data() + stt*_knl_mm.trgDOF());
00241                 DblNumMat tmp(M,N);
00242                 /* Build multiplier context for this kernel and store in tmp */
00243                 pC( _knl_mm.buildKnlIntCtx(srcPos, srcPos, tps, tmp) );
00244                 /* Compute 1.0*tmp*srcDen + 1.0*tvl */
00245                 pC( dgemv(1.0, tmp, srcDen, 1.0, tvl) );
00246          }
00247   }
00248   return(0);
00249 }
00250 
00251 // ----------------------------------------------------------------------
00252 /* For a specific node, return a matrix of exact source positions for this processor as a contributor */
00253 DblNumMat FMM3d_MPI::ctbSrcExaPos(int gNodeIdx) 
00254 {
00255   Let3d_MPI::Node& node = _let->node(gNodeIdx);
00256   int beg = node.ctbSrcExaBeg();
00257   int num = node.ctbSrcExaNum();
00258   double* arr;     VecGetArray(    _ctbSrcExaPos, &arr);
00259   double* buf=arr; VecRestoreArray(_ctbSrcExaPos, &arr);
00260   return DblNumMat(dim(), num, false, buf+beg*dim());
00261 }
00262 /* For a specific node, return a matrix of exact source normals for this processor as a contributor */
00263 DblNumMat FMM3d_MPI::ctbSrcExaNor(int gNodeIdx)
00264 {
00265   Let3d_MPI::Node& node = _let->node(gNodeIdx);
00266   int beg = node.ctbSrcExaBeg();
00267   int num = node.ctbSrcExaNum();
00268   double* arr;     VecGetArray(    _ctbSrcExaNor, &arr);
00269   double* buf=arr; VecRestoreArray(_ctbSrcExaNor, &arr);
00270   return DblNumMat(dim(), num, false, buf+beg*dim());
00271 }
00272 /* For a specific node, return a vector of exact source densities for this processor as a contributor */
00273 DblNumVec FMM3d_MPI::ctbSrcExaDen(int gNodeIdx)
00274 {
00275   Let3d_MPI::Node& node = _let->node(gNodeIdx);
00276   int beg = node.ctbSrcExaBeg();
00277   int num = node.ctbSrcExaNum();
00278   double* arr;     VecGetArray(    _ctbSrcExaDen, &arr);
00279   double* buf=arr; VecRestoreArray(_ctbSrcExaDen, &arr);
00280   return DblNumVec(srcDOF()*num, false, buf+beg*srcDOF());
00281 }
00282 /* For a specific node, return a vector of contributor source upward equivalent densities */
00283 DblNumVec FMM3d_MPI::ctbSrcUpwEquDen(int gNodeIdx)
00284 {
00285   Let3d_MPI::Node& node = _let->node(gNodeIdx);
00286   int idx = node.ctbSrcNodeIdx();
00287   double* arr;     VecGetArray(    _ctbSrcUpwEquDen, &arr);
00288   double* buf=arr; VecRestoreArray(_ctbSrcUpwEquDen, &arr);
00289   return DblNumVec(datSze(UE), false, buf+idx*datSze(UE));
00290 }
00291 /* For a specific node, return a vector of contributor source upward check values*/
00292 DblNumVec FMM3d_MPI::ctbSrcUpwChkVal(int gNodeIdx)
00293 {
00294   Let3d_MPI::Node& node = _let->node(gNodeIdx);
00295   int idx = node.ctbSrcNodeIdx();
00296   double* arr;     VecGetArray(    _ctbSrcUpwChkVal, &arr);
00297   double* buf=arr; VecRestoreArray(_ctbSrcUpwChkVal, &arr);
00298   return DblNumVec(datSze(UC), false, buf+idx*datSze(UC));
00299 }
00300 // ----------------------------------------------------------------------
00301 /* For a specific node, return matrix of exact source positions for which this processor is a user */
00302 DblNumMat FMM3d_MPI::usrSrcExaPos(int gNodeIdx)
00303 {
00304   Let3d_MPI::Node& node = _let->node(gNodeIdx);
00305   int beg = node.usrSrcExaBeg();
00306   int num = node.usrSrcExaNum();
00307   double* arr;     VecGetArray(    _usrSrcExaPos, &arr);
00308   double* buf=arr; VecRestoreArray(_usrSrcExaPos, &arr);
00309   return DblNumMat(dim(), num, false, buf+beg*dim());
00310 }
00311 /* For a specific node, return matrix of exact source normals for which this processor is a user */
00312 DblNumMat FMM3d_MPI::usrSrcExaNor(int gNodeIdx)
00313 {
00314   Let3d_MPI::Node& node = _let->node(gNodeIdx);
00315   int beg = node.usrSrcExaBeg();
00316   int num = node.usrSrcExaNum();
00317   double* arr;     VecGetArray(    _usrSrcExaNor, &arr);
00318   double* buf=arr; VecRestoreArray(_usrSrcExaNor, &arr);
00319   return DblNumMat(dim(), num, false, buf+beg*dim());
00320 }
00321 /* For a specific node, return vector of exact source normals for which this processor is a user */
00322 DblNumVec FMM3d_MPI::usrSrcExaDen(int gNodeIdx)
00323 {
00324   Let3d_MPI::Node& node = _let->node(gNodeIdx);
00325   int beg = node.usrSrcExaBeg();
00326   int num = node.usrSrcExaNum();
00327   double* arr;     VecGetArray(    _usrSrcExaDen, &arr);
00328   double* buf=arr; VecRestoreArray(_usrSrcExaDen, &arr);
00329   return DblNumVec(srcDOF()*num, false, buf+beg*srcDOF());
00330 }
00331 /* For a specific node, return upward equivalent source densities for which this processor is a user */
00332 DblNumVec FMM3d_MPI::usrSrcUpwEquDen(int gNodeIdx)
00333 {
00334   Let3d_MPI::Node& node = _let->node(gNodeIdx);
00335   int idx = node.usrSrcNodeIdx();
00336   double* arr;     VecGetArray(    _usrSrcUpwEquDen, &arr);
00337   double* buf=arr; VecRestoreArray(_usrSrcUpwEquDen, &arr);
00338   return DblNumVec(datSze(UE), false, buf+idx*datSze(UE));
00339 }
00340 // ----------------------------------------------------------------------
00341 /* For a specific node, return matrix of exact target positions for which this processor is an evaluator */
00342 DblNumMat FMM3d_MPI::evaTrgExaPos(int gNodeIdx)
00343 {
00344   Let3d_MPI::Node& node = _let->node(gNodeIdx);
00345   int beg = node.evaTrgExaBeg();
00346   int num = node.evaTrgExaNum();
00347   double* arr;     VecGetArray(    _evaTrgExaPos, &arr);
00348   double* buf=arr; VecRestoreArray(_evaTrgExaPos, &arr);
00349   return DblNumMat(dim(), num, false, buf+beg*dim());
00350 }
00351 /* For a specific node, return vector of exact target values for which this processor is an evaluator */
00352 DblNumVec FMM3d_MPI::evaTrgExaVal(int gNodeIdx)
00353 {
00354   Let3d_MPI::Node& node = _let->node(gNodeIdx);
00355   int beg = node.evaTrgExaBeg();
00356   int num = node.evaTrgExaNum();
00357   double* arr;     VecGetArray(    _evaTrgExaVal, &arr);
00358   double* buf=arr; VecRestoreArray(_evaTrgExaVal, &arr);
00359   return DblNumVec(trgDOF()*num, false, buf+beg*trgDOF());
00360 }
00361 /* For a specific node, return vector of downward equivalent target densities for which this processor is an evaluator */
00362 DblNumVec FMM3d_MPI::evaTrgDwnEquDen(int gNodeIdx)
00363 {
00364   Let3d_MPI::Node& node = _let->node(gNodeIdx);
00365   int idx = node.evaTrgNodeIdx();
00366   double* arr;     VecGetArray(    _evaTrgDwnEquDen, &arr);
00367   double* buf=arr; VecRestoreArray(_evaTrgDwnEquDen, &arr);
00368   return DblNumVec(datSze(DE), false, buf+idx*datSze(DE));
00369 }
00370 /* For a specific node, return vector of downward check target values for which this processor is an evaluator */
00371 DblNumVec FMM3d_MPI::evaTrgDwnChkVal(int gNodeIdx)
00372 {
00373   Let3d_MPI::Node& node = _let->node(gNodeIdx);
00374   int idx = node.evaTrgNodeIdx();
00375   double* arr;     VecGetArray(    _evaTrgDwnChkVal, &arr);
00376   double* buf=arr; VecRestoreArray(_evaTrgDwnChkVal, &arr);
00377   return DblNumVec(datSze(DC), false, buf+idx*datSze(DC));
00378 }
00379 
00380 

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