00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "EpetraExt_PutMultiVector.h"
00030 #include "Epetra_Comm.h"
00031 #include "Epetra_BlockMap.h"
00032 #include "Epetra_Map.h"
00033 #include "Epetra_Vector.h"
00034 #include "Epetra_IntVector.h"
00035 #include "Epetra_IntSerialDenseVector.h"
00036 #include "Epetra_Import.h"
00037
00038 using namespace Matlab;
00039 namespace Matlab {
00040 int CopyMultiVector(double** matlabApr, const Epetra_MultiVector& A) {
00041
00042 Epetra_BlockMap bmap = A.Map();
00043 const Epetra_Comm & comm = bmap.Comm();
00044 int numProc = comm.NumProc();
00045
00046 if (numProc==1)
00047 DoCopyMultiVector(matlabApr, A);
00048 else {
00049
00050
00051
00052
00053
00054 if (A.NumVectors() > 1) {
00055 for (int i=0; i < A.NumVectors(); i++)
00056 if (CopyMultiVector(matlabApr, *(A(i)))) return(-1);
00057 return(0);
00058 }
00059
00060 Epetra_Map map(-1, bmap.NumMyPoints(), 0, comm);
00061
00062 Epetra_MultiVector A1(View, map, A.Pointers(), A.NumVectors());
00063 int numRows = map.NumMyElements();
00064
00065 Epetra_Map allGidsMap(-1, numRows, 0,comm);
00066
00067 Epetra_IntVector allGids(allGidsMap);
00068 for (int i=0; i<numRows; i++) allGids[i] = map.GID(i);
00069
00070
00071 int numChunks = numProc;
00072 int stripSize = allGids.GlobalLength()/numChunks;
00073 int remainder = allGids.GlobalLength()%numChunks;
00074 int curStart = 0;
00075 int curStripSize = 0;
00076 Epetra_IntSerialDenseVector importGidList;
00077 int numImportGids = 0;
00078 if (comm.MyPID()==0)
00079 importGidList.Size(stripSize+1);
00080 for (int i=0; i<numChunks; i++) {
00081 if (comm.MyPID()==0) {
00082 curStripSize = stripSize;
00083 if (i<remainder) curStripSize++;
00084 for (int j=0; j<curStripSize; j++) importGidList[j] = j + curStart;
00085 curStart += curStripSize;
00086 }
00087
00088 Epetra_Map importGidMap(-1, curStripSize, importGidList.Values(), 0, comm);
00089 Epetra_Import gidImporter(importGidMap, allGidsMap);
00090 Epetra_IntVector importGids(importGidMap);
00091 if (importGids.Import(allGids, gidImporter, Insert)) return(-1);
00092
00093
00094
00095
00096
00097 Epetra_Map importMap(-1, importGids.MyLength(), importGids.Values(), 0, comm);
00098 Epetra_Import importer(importMap, map);
00099 Epetra_MultiVector importA(importMap, A1.NumVectors());
00100 if (importA.Import(A1, importer, Insert)) return(-1);
00101
00102
00103 if (DoCopyMultiVector(matlabApr, importA)) return(-1);
00104 }
00105 }
00106 return(0);
00107 }
00108
00109 int DoCopyMultiVector(double** matlabApr, const Epetra_MultiVector& A) {
00110
00111 int ierr = 0;
00112 int length = A.GlobalLength();
00113 int numVectors = A.NumVectors();
00114 const Epetra_Comm & comm = A.Map().Comm();
00115 if (comm.MyPID()!=0) {
00116 if (A.MyLength()!=0) ierr = -1;
00117 }
00118 else {
00119 if (length!=A.MyLength()) ierr = -1;
00120 double* matlabAvalues = *matlabApr;
00121 double* Aptr = A.Values();
00122 memcpy((void *)matlabAvalues, (void *)Aptr, sizeof(*Aptr) * length * numVectors);
00123 *matlabApr += length;
00124 }
00125 int ierrGlobal;
00126 comm.MinAll(&ierr, &ierrGlobal, 1);
00127 return(ierrGlobal);
00128 }
00129 }