47 #ifndef MUELU_MATLABUTILS_DEF_HPP
48 #define MUELU_MATLABUTILS_DEF_HPP
52 #if !defined(HAVE_MUELU_MATLAB) || !defined(HAVE_MUELU_EPETRA) || !defined(HAVE_MUELU_TPETRA)
53 #error "Muemex types require MATLAB, Epetra and Tpetra."
128 #ifdef HAVE_MUELU_INTREPID2
130 template<>
MuemexType getMuemexType<RCP<FieldContainer_ordinal>>() {
return FIELDCONTAINER_ORDINAL;}
153 mxClassID probIDtype = mxGetClassID(mxa);
155 if(probIDtype == mxINT32_CLASS)
157 rv = *((
int*) mxGetData(mxa));
159 else if(probIDtype == mxLOGICAL_CLASS)
161 rv = (int) *((
bool*) mxGetData(mxa));
163 else if(probIDtype == mxDOUBLE_CLASS)
165 rv = (int) *((
double*) mxGetData(mxa));
167 else if(probIDtype == mxUINT32_CLASS)
169 rv = (int) *((
unsigned int*) mxGetData(mxa));
174 throw std::runtime_error(
"Error: Unrecognized numerical type.");
182 return *((
bool*) mxGetData(mxa));
188 return *((
double*) mxGetPr(mxa));
194 double realpart = real<double>(*((
double*) mxGetPr(mxa)));
195 double imagpart = imag<double>(*((
double*) mxGetPi(mxa)));
203 if (mxGetClassID(mxa) != mxCHAR_CLASS)
205 throw runtime_error(
"Can't construct string from anything but a char array.");
207 rv = string(mxArrayToString(mxa));
215 int nr = mxGetM(mxa);
216 int nc = mxGetN(mxa);
218 throw std::runtime_error(
"A Xpetra::Map representation from MATLAB must be a single row vector.");
219 double* pr = mxGetPr(mxa);
222 std::vector<mm_GlobalOrd> localGIDs(numGlobalIndices);
223 for(
int i = 0; i < int(numGlobalIndices); i++) {
224 localGIDs[i] = Teuchos::as<mm_GlobalOrd>(pr[i]);
236 throw runtime_error(
"Failed to create Xpetra::Map.");
244 if(mxGetN(mxa) != 1 && mxGetM(mxa) != 1)
245 throw std::runtime_error(
"An OrdinalVector from MATLAB must be a single row or column vector.");
246 mm_GlobalOrd numGlobalIndices = mxGetM(mxa) * mxGetN(mxa);
248 if(mxGetClassID(mxa) != mxINT32_CLASS)
249 throw std::runtime_error(
"Can only construct LOVector with int32 data.");
250 int* array = (
int*) mxGetData(mxa);
252 throw runtime_error(
"Failed to create map for Xpetra ordinal vector.");
255 throw runtime_error(
"Failed to create ordinal vector with Xpetra::VectorFactory.");
256 for(
int i = 0; i < int(numGlobalIndices); i++)
258 loVec->replaceGlobalValue(i, 0, array[i]);
269 int nr = mxGetM(mxa);
270 int nc = mxGetN(mxa);
271 double* pr = mxGetPr(mxa);
277 mv =
rcp(
new Tpetra::MultiVector<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t>(map, arrView,
size_t(nr),
size_t(nc)));
279 catch(std::exception& e)
281 mexPrintf(
"Error constructing Tpetra MultiVector.\n");
282 std::cout << e.what() << std::endl;
293 int nr = mxGetM(mxa);
294 int nc = mxGetN(mxa);
295 double* pr = mxGetPr(mxa);
296 double* pi = mxGetPi(mxa);
302 for(
int n = 0; n < nc; n++)
304 for(
int m = 0; m < nr; m++)
306 myArr[n * nr + m] =
complex_t(pr[n * nr + m], pi[n * nr + m]);
310 mv =
rcp(
new Tpetra::MultiVector<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t>(map, arrView, nr, nc));
312 catch(std::exception& e)
314 mexPrintf(
"Error constructing Tpetra MultiVector.\n");
315 std::cout << e.what() << std::endl;
323 bool success =
false;
333 const Tpetra::global_size_t numGlobalIndices = mxGetM(mxa);
337 A = Tpetra::createCrsMatrix<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t>(rowMap);
338 double* valueArray = mxGetPr(mxa);
339 int nc = mxGetN(mxa);
348 rowind = (
int*) mxGetIr(mxa);
349 colptr = (
int*) mxGetJc(mxa);
351 for(
int i = 0; i < nc; i++)
353 for(
int j = colptr[i]; j < colptr[i + 1]; j++)
359 A->insertGlobalValues(rowind[j], cols, vals);
362 A->fillComplete(domainMap, rowMap);
365 delete[] rowind; rowind = NULL;
366 delete[] colptr; colptr = NULL;
370 catch(std::exception& e)
374 if(rowind!=NULL)
delete[] rowind;
375 if(colptr!=NULL)
delete[] colptr;
379 mexPrintf(
"Error while constructing Tpetra matrix:\n");
380 std::cout << e.what() << std::endl;
383 mexErrMsgTxt(
"An error occurred while setting up a Tpetra matrix.\n");
395 const Tpetra::global_size_t numGlobalIndices = mxGetM(mxa);
399 A = Tpetra::createCrsMatrix<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t>(rowMap);
400 double* realArray = mxGetPr(mxa);
401 double* imagArray = mxGetPi(mxa);
404 int nc = mxGetN(mxa);
413 rowind = (
int*) mxGetIr(mxa);
414 colptr = (
int*) mxGetJc(mxa);
416 for(
int i = 0; i < nc; i++)
418 for(
int j = colptr[i]; j < colptr[i + 1]; j++)
422 complex_t value = std::complex<double>(realArray[j], imagArray[j]);
425 A->insertGlobalValues(rowind[j], cols, vals);
428 A->fillComplete(domainMap, rowMap);
435 catch(std::exception& e)
437 mexPrintf(
"Error while constructing tpetra matrix:\n");
438 std::cout << e.what() << std::endl;
447 return MueLu::TpetraCrs_To_XpetraMatrix<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t>(tmat);
454 return MueLu::TpetraCrs_To_XpetraMatrix<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t>(tmat);
461 return MueLu::TpetraMultiVector_To_XpetraMultiVector<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t>(tpetraMV);
468 return MueLu::TpetraMultiVector_To_XpetraMultiVector<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t>(tpetraMV);
479 double* vals = mxGetPr(mxa);
480 int nr = mxGetM(mxa);
481 int nc = mxGetN(mxa);
489 rowind = (
int*) mxGetIr(mxa);
490 colptr = (
int*) mxGetJc(mxa);
497 for(
int i = 0; i < nc; i++)
499 for(
int j = colptr[i]; j < colptr[i + 1]; j++)
512 catch(std::exception& e)
514 mexPrintf(
"An error occurred while setting up an Epetra matrix:\n");
515 std::cout << e.what() << std::endl;
523 int nr = mxGetM(mxa);
524 int nc = mxGetN(mxa);
533 if(mxGetNumberOfElements(mxa) != 1)
534 throw runtime_error(
"Aggregates must be individual structs in MATLAB.");
536 throw runtime_error(
"Trying to pull aggregates from non-struct MATLAB object.");
539 const int correctNumFields = 5;
540 if(mxGetNumberOfFields(mxa) != correctNumFields)
541 throw runtime_error(
"Aggregates structure has wrong number of fields.");
543 int nVert = *(
int*) mxGetData(mxGetField(mxa, 0,
"nVertices"));
544 int nAgg = *(
int*) mxGetData(mxGetField(mxa, 0,
"nAggregates"));
548 int myRank = comm->getRank();
552 agg->SetNumAggregates(nAgg);
560 mxArray* vertToAggID_in = mxGetField(mxa, 0,
"vertexToAggID");
561 int* vertToAggID_inArray = (
int*) mxGetData(vertToAggID_in);
562 mxArray* rootNodes_in = mxGetField(mxa, 0,
"rootNodes");
563 int* rootNodes_inArray = (
int*) mxGetData(rootNodes_in);
564 for(
int i = 0; i < nVert; i++)
566 vertex2AggId[i] = vertToAggID_inArray[i];
567 procWinner[i] = myRank;
568 agg->SetIsRoot(i,
false);
570 for(
int i = 0; i < nAgg; i++)
572 agg->SetIsRoot(rootNodes_inArray[i],
true);
575 agg->ComputeAggregateSizes(
true);
576 agg->AggregatesCrossProcessors(
false);
584 throw runtime_error(
"AmalgamationInfo not supported in Muemex yet.");
592 mxArray* edges = mxGetField(mxa, 0,
"edges");
593 mxArray* boundaryNodes = mxGetField(mxa, 0,
"boundaryNodes");
595 throw runtime_error(
"Graph structure in MATLAB must have a field called 'edges' (logical sparse matrix)");
596 if(boundaryNodes == NULL)
597 throw runtime_error(
"Graph structure in MATLAB must have a field called 'boundaryNodes' (int32 array containing list of boundary nodes)");
598 int* boundaryList = (
int*) mxGetData(boundaryNodes);
599 if(!mxIsSparse(edges) || mxGetClassID(edges) != mxLOGICAL_CLASS)
600 throw runtime_error(
"Graph edges must be stored as a logical sparse matrix.");
602 mwIndex* matlabColPtrs = mxGetJc(edges);
603 mwIndex* matlabRowIndices = mxGetIr(edges);
610 int nnz = matlabColPtrs[mxGetN(edges)];
611 for(
int i = 0; i < nnz; i++)
612 entriesPerRow[matlabRowIndices[i]]++;
617 for(
int i = 0; i < nRows; i++)
618 rows[i+1] = rows[i] + entriesPerRow[i];
621 int ncols = mxGetN(edges);
622 for (
int colNum=0; colNum<ncols; ++colNum) {
623 int ci = matlabColPtrs[colNum];
624 for (
int j=ci; j<Teuchos::as<int>(matlabColPtrs[colNum+1]); ++j) {
625 int rowNum = matlabRowIndices[j];
626 cols[ rows[rowNum] + insertionsPerRow[rowNum] ] = colNum;
627 insertionsPerRow[rowNum]++;
632 for(
int i = 0; i < nRows; i++) {
633 if(maxNzPerRow < entriesPerRow[i])
634 maxNzPerRow = entriesPerRow[i];
643 for(
int i = 0; i < nRows; ++i) {
644 tgraph->insertGlobalIndices((
mm_GlobalOrd) i, cols(rows[i],entriesPerRow[i]));
646 tgraph->fillComplete(map, map);
649 int numBoundaryNodes = mxGetNumberOfElements(boundaryNodes);
650 bool* boundaryFlags =
new bool[nRows];
651 for(
int i = 0; i < nRows; i++)
653 boundaryFlags[i] =
false;
655 for(
int i = 0; i < numBoundaryNodes; i++)
657 boundaryFlags[boundaryList[i]] =
true;
660 mgraph->SetBoundaryNodeMap(boundaryNodesInput);
665 #ifdef HAVE_MUELU_INTREPID2
669 if(mxGetClassID(mxa) != mxINT32_CLASS)
670 throw runtime_error(
"FieldContainer must have integer storage entries");
672 int *data = (
int *) mxGetData(mxa);
673 int nr = mxGetM(mxa);
674 int nc = mxGetN(mxa);
677 for(
int col = 0; col < nc; col++)
679 for(
int row = 0; row < nr; row++)
681 (*fc)(row,col) = data[col * nr + row];
695 mwSize dims[] = {1, 1};
696 mxArray* mxa = mxCreateNumericArray(2, dims, mxINT32_CLASS, mxREAL);
697 *((
int*) mxGetData(mxa)) = data;
704 mwSize dims[] = {1, 1};
705 mxArray* mxa = mxCreateLogicalArray(2, dims);
706 *((
bool*) mxGetData(mxa)) = data;
713 return mxCreateDoubleScalar(data);
719 mwSize dims[] = {1, 1};
720 mxArray* mxa = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxCOMPLEX);
721 *((
double*) mxGetPr(mxa)) = real<double>(data);
722 *((
double*) mxGetPi(mxa)) = imag<double>(data);
729 return mxCreateString(data.c_str());
736 int nc = data->getGlobalNumElements();
739 double* array = (
double*) malloc(
sizeof(
double) * nr * nc);
740 for(
int col = 0; col < nc; col++)
743 array[col] = Teuchos::as<double>(gid);
753 mwSize len = data->getGlobalLength();
755 mwSize dimensions[] = {len, 1};
756 mxArray* rv = mxCreateNumericArray(2, dimensions, mxINT32_CLASS, mxREAL);
757 int* dataPtr = (
int*) mxGetData(rv);
759 for(
int i = 0; i < int(data->getGlobalLength()); i++)
774 mxArray*
saveDataToMatlab(
RCP<Tpetra::MultiVector<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t>>& data)
797 typedef double Scalar;
799 Teuchos::rcp_const_cast<
Xpetra_CrsGraph>(data->getCrsGraph())->computeGlobalConstants();
801 int nr = data->getGlobalNumRows();
802 int nc = data->getGlobalNumCols();
803 int nnz = data->getGlobalNumEntries();
805 #ifdef VERBOSE_OUTPUT
809 mxArray* mxa = createMatlabSparse<Scalar>(nr, nc, nnz);
812 for(
int i = 0; i < nc + 1; i++)
817 size_t maxEntriesPerRow = data->getGlobalMaxNumRowEntries();
820 int* rowProgress =
new int[nc];
822 Scalar* sparseVals =
new Scalar[nnz];
824 if(data->isLocallyIndexed())
826 Scalar* rowValArray =
new Scalar[maxEntriesPerRow];
832 data->getLocalRowCopy(m, rowIndices, rowVals, numEntries);
833 for(
mm_LocalOrd entry = 0; entry < int(numEntries); entry++)
835 jc[rowIndices[entry] + 1]++;
840 int entriesAccum = 0;
841 for(
int n = 0; n <= nc; n++)
843 int temp = entriesAccum;
844 entriesAccum += jc[n];
848 for(
int i = 0; i < nc; i++)
855 data->getLocalRowCopy(m, rowIndices, rowVals, numEntries);
860 sparseVals[jc[col] + rowProgress[col]] = rowVals[i];
861 ir[jc[col] + rowProgress[col]] = m;
865 delete[] rowIndicesArray;
873 data->getGlobalRowView(m, rowIndices, rowVals);
876 jc[rowIndices[n] + 1]++;
882 for(
int i = 0; i < nc; i++)
886 int entriesAccum = 0;
887 for(
int n = 0; n <= nc; n++)
889 int temp = entriesAccum;
890 entriesAccum += jc[n];
896 data->getGlobalRowView(m, rowIndices, rowVals);
900 sparseVals[jc[col] + rowProgress[col]] = rowVals[i];
901 ir[jc[col] + rowProgress[col]] = m;
907 fillMatlabArray<Scalar>(sparseVals, mxa, nnz);
909 delete[] rowProgress;
919 Teuchos::rcp_const_cast<
Xpetra_CrsGraph>(data->getCrsGraph())->computeGlobalConstants();
921 int nr = data->getGlobalNumRows();
922 int nc = data->getGlobalNumCols();
923 int nnz = data->getGlobalNumEntries();
924 #ifdef VERBOSE_OUTPUT
928 mxArray* mxa = createMatlabSparse<Scalar>(nr, nc, nnz);
931 for(
int i = 0; i < nc + 1; i++)
935 size_t maxEntriesPerRow = data->getGlobalMaxNumRowEntries();
936 int* rowProgress =
new int[nc];
938 Scalar* sparseVals =
new Scalar[nnz];
940 if(data->isLocallyIndexed())
942 Scalar* rowValArray =
new Scalar[maxEntriesPerRow];
948 data->getLocalRowCopy(m, rowIndices, rowVals, numEntries);
949 for(
mm_LocalOrd entry = 0; entry < int(numEntries); entry++)
951 jc[rowIndices[entry] + 1]++;
955 int entriesAccum = 0;
956 for(
int n = 0; n <= nc; n++)
958 int temp = entriesAccum;
959 entriesAccum += jc[n];
963 for(
int i = 0; i < nc; i++)
970 data->getLocalRowCopy(m, rowIndices, rowVals, numEntries);
975 sparseVals[jc[col] + rowProgress[col]] = rowVals[i];
976 ir[jc[col] + rowProgress[col]] = m;
980 delete[] rowIndicesArray;
988 data->getGlobalRowView(m, rowIndices, rowVals);
991 jc[rowIndices[n] + 1]++;
997 for(
int i = 0; i < nc; i++)
1001 int entriesAccum = 0;
1002 for(
int n = 0; n <= nc; n++)
1004 int temp = entriesAccum;
1005 entriesAccum += jc[n];
1011 data->getGlobalRowView(m, rowIndices, rowVals);
1015 sparseVals[jc[col] + rowProgress[col]] = rowVals[i];
1016 ir[jc[col] + rowProgress[col]] = m;
1022 fillMatlabArray<Scalar>(sparseVals, mxa, nnz);
1023 delete[] sparseVals;
1024 delete[] rowProgress;
1055 int nr = data->getGlobalLength();
1056 int nc = data->getNumVectors();
1058 double* array = (
double*) malloc(
sizeof(
double) * nr * nc);
1059 for(
int col = 0; col < nc; col++)
1062 for(
int row = 0; row < nr; row++)
1064 array[col * nr + row] = colData[row];
1076 int nr = data->getGlobalLength();
1077 int nc = data->getNumVectors();
1080 for(
int col = 0; col < nc; col++)
1083 for(
int row = 0; row < nr; row++)
1085 array[col * nr + row] = colData[row];
1103 mxArray* output = mxCreateDoubleMatrix(data->GlobalLength(), data->NumVectors(), mxREAL);
1104 double* dataPtr = mxGetPr(output);
1105 data->ExtractCopy(dataPtr, data->GlobalLength());
1113 int numNodes = data->GetVertex2AggId()->getData(0).size();
1114 int numAggs = data->GetNumAggregates();
1116 mwSize singleton[] = {1, 1};
1117 dataIn[0] = mxCreateNumericArray(2, singleton, mxINT32_CLASS, mxREAL);
1118 *((
int*) mxGetData(dataIn[0])) = numNodes;
1119 dataIn[1] = mxCreateNumericArray(2, singleton, mxINT32_CLASS, mxREAL);
1120 *((
int*) mxGetData(dataIn[1])) = numAggs;
1121 mwSize nodeArrayDims[] = {(mwSize) numNodes, 1};
1122 dataIn[2] = mxCreateNumericArray(2, nodeArrayDims, mxINT32_CLASS, mxREAL);
1123 int* vtaid = (
int*) mxGetData(dataIn[2]);
1125 for(
int i = 0; i < numNodes; i++)
1127 vtaid[i] = vertexToAggID[i];
1129 mwSize aggArrayDims[] = {(mwSize) numAggs, 1};
1130 dataIn[3] = mxCreateNumericArray(2, aggArrayDims, mxINT32_CLASS, mxREAL);
1133 for(
int i = 0; i < numNodes; i++)
1138 bool reassignRoots =
false;
1139 if(totalRoots != numAggs)
1141 cout << endl <<
"Warning: Number of root nodes and number of aggregates do not match." << endl;
1142 cout <<
"Will reassign root nodes when writing aggregates to matlab." << endl << endl;
1143 reassignRoots =
true;
1145 int* rn = (
int*) mxGetData(dataIn[3]);
1150 int lastFoundNode = 0;
1151 for(
int i = 0; i < numAggs; i++)
1154 for(
int j = lastFoundNode; j < lastFoundNode + numNodes; j++)
1156 int index = j % numNodes;
1157 if(vertexToAggID[index] == i)
1160 lastFoundNode = index;
1163 TEUCHOS_TEST_FOR_EXCEPTION(rn[i] == -1, runtime_error,
"Invalid aggregates: Couldn't find any node in aggregate #" << i <<
".");
1169 for(
int j = 0; j < numNodes; j++)
1174 throw runtime_error(
"Cannot store invalid aggregates in MATLAB - more root nodes than aggregates.");
1180 throw runtime_error(
"Cannot store invalid aggregates in MATLAB - fewer root nodes than aggregates.");
1183 dataIn[4] = mxCreateNumericArray(1, aggArrayDims, mxINT32_CLASS, mxREAL);
1184 int*
as = (
int*) mxGetData(dataIn[4]);
1186 for(
int i = 0; i < numAggs; i++)
1188 as[i] = aggSizes[i];
1190 mxArray* matlabAggs[1];
1191 int result = mexCallMATLAB(1, matlabAggs, 5, dataIn,
"constructAggregates");
1193 throw runtime_error(
"Matlab encountered an error while constructing aggregates struct.");
1194 return matlabAggs[0];
1200 throw runtime_error(
"AmalgamationInfo not supported in MueMex yet.");
1201 return mxCreateDoubleScalar(0);
1207 int numEntries = (int) data->GetGlobalNumEdges();
1208 int numRows = (int) data->GetDomainMap()->getGlobalNumElements();
1209 mxArray* mat = mxCreateSparseLogicalMatrix(numRows, numRows, numEntries);
1210 mxLogical* outData = (mxLogical*) mxGetData(mat);
1211 mwIndex* rowInds = mxGetIr(mat);
1212 mwIndex* colPtrs = mxGetJc(mat);
1215 int* entriesPerRow =
new int[numRows];
1216 int* entriesPerCol =
new int[numRows];
1217 for(
int i = 0; i < numRows; i++)
1219 entriesPerRow[i] = 0;
1220 entriesPerCol[i] = 0;
1222 for(
int i = 0; i < numRows; i++)
1226 entriesPerRow[i] = neighbors.
size();
1227 for(
int j = 0; j < neighbors.
size(); j++)
1229 entriesPerCol[neighbors[j]]++;
1231 iter += neighbors.
size();
1234 mxLogical** valuesByColumn =
new mxLogical*[numRows];
1235 int* numEnteredPerCol =
new int[numRows];
1237 for(
int i = 0; i < numRows; i++)
1239 rowIndsByColumn[i] = &rowInds[accum];
1241 valuesByColumn[i] = &outData[accum];
1242 accum += entriesPerCol[i];
1243 if(accum > numEntries)
1244 throw runtime_error(
"potato");
1246 for(
int i = 0; i < numRows; i++)
1248 numEnteredPerCol[i] = 0;
1252 for(
int row = 0; row < numRows; row++)
1254 for(
int entryInRow = 0; entryInRow < entriesPerRow[row]; entryInRow++)
1256 int col = dataCopy[accum];
1258 rowIndsByColumn[col][numEnteredPerCol[col]] = row;
1259 valuesByColumn[col][numEnteredPerCol[col]] = (mxLogical) 1;
1260 numEnteredPerCol[col]++;
1264 for(
int col = 0; col < numRows; col++)
1266 colPtrs[col] = accum;
1267 accum += entriesPerCol[col];
1269 colPtrs[numRows] = accum;
1270 delete[] numEnteredPerCol;
1271 delete[] rowIndsByColumn;
1272 delete[] valuesByColumn;
1274 delete[] entriesPerRow;
1275 delete[] entriesPerCol;
1278 int numBoundaryNodes = 0;
1279 for(
int i = 0; i < boundaryFlags.
size(); i++)
1281 if(boundaryFlags[i])
1284 cout <<
"Graph has " << numBoundaryNodes <<
" Dirichlet boundary nodes." << endl;
1285 mwSize dims[] = {(mwSize) numBoundaryNodes, 1};
1286 mxArray* boundaryList = mxCreateNumericArray(2, dims, mxINT32_CLASS, mxREAL);
1287 int* dest = (
int*) mxGetData(boundaryList);
1288 int* destIter = dest;
1289 for(
int i = 0; i < boundaryFlags.
size(); i++)
1291 if(boundaryFlags[i])
1297 mxArray* constructArgs[] = {mat, boundaryList};
1299 mexCallMATLAB(1, out, 2, constructArgs,
"constructGraph");
1303 #ifdef HAVE_MUELU_INTREPID2
1307 int rank = data->rank();
1310 throw std::runtime_error(
"Error: Only rank two FieldContainers are supported.");
1312 int nr = data->dimension(0);
1313 int nc = data->dimension(1);
1315 mwSize dims[]={(mwSize)nr,(mwSize)nc};
1316 mxArray* mxa = mxCreateNumericArray(2,dims, mxINT32_CLASS, mxREAL);
1317 int *array = (
int*) mxGetData(mxa);
1319 for(
int col = 0; col < nc; col++)
1321 for(
int row = 0; row < nr; row++)
1323 array[col * nr + row] = (*data)(row,col);
1331 template<
typename T>
1334 data = loadDataFromMatlab<T>(mxa);
1337 template<
typename T>
1340 return saveDataToMatlab<T>(data);
1343 template<
typename T>
1349 template<
typename T>
1352 template<
typename T>
1358 template<
typename T>
1361 this->data = newData;
1368 template<
typename T>
1372 lvl.
Set<T>(name, data, fact);
1375 template<
typename T>
1380 return lvl.
Get<T>(name);
1382 catch(std::exception& e)
1384 throw std::runtime_error(
"Requested custom variable " + name +
" is not in the level.");
1389 template<
typename Scalar,
typename LocalOrdinal,
typename GlobalOrdinal,
typename Node>
1392 using namespace std;
1393 using namespace Teuchos;
1400 vector<RCP<MuemexArg>> args;
1401 for(
size_t i = 0; i < needsList.size(); i++)
1403 if(needsList[i] ==
"A" || needsList[i] ==
"P" || needsList[i] ==
"R" || needsList[i]==
"Ptent")
1405 Matrix_t mydata = lvl.
Get<Matrix_t>(needsList[i], factory->
GetFactory(needsList[i]).get());
1408 else if(needsList[i] ==
"Nullspace" || needsList[i] ==
"Coordinates")
1410 MultiVector_t mydata = lvl.
Get<MultiVector_t>(needsList[i], factory->
GetFactory(needsList[i]).get());
1413 else if(needsList[i] ==
"Aggregates")
1415 Aggregates_t mydata = lvl.
Get<Aggregates_t>(needsList[i], factory->
GetFactory(needsList[i]).get());
1418 else if(needsList[i] ==
"UnAmalgamationInfo")
1420 AmalgamationInfo_t mydata = lvl.
Get<AmalgamationInfo_t>(needsList[i], factory->
GetFactory(needsList[i]).get());
1423 else if(needsList[i] ==
"Level")
1428 else if(needsList[i] ==
"Graph")
1430 Graph_t mydata = lvl.
Get<Graph_t>(needsList[i], factory->
GetFactory(needsList[i]).get());
1435 vector<string> words;
1436 string badNameMsg =
"Custom Muemex variables in \"Needs\" list require a type and a name, e.g. \"double myVal\". \n Leading and trailing spaces are OK. \n Don't know how to handle \"" + needsList[i] +
"\".\n";
1438 char* buf = (
char*) malloc(needsList[i].size() + 1);
1439 strcpy(buf, needsList[i].c_str());
1440 for(
char* iter = buf; *iter !=
' '; iter++)
1445 throw runtime_error(badNameMsg);
1447 *iter = (char)
tolower(*iter);
1449 const char* wordDelim =
" ";
1450 char* mark = strtok(buf, wordDelim);
1453 string wordStr(mark);
1454 words.push_back(wordStr);
1455 mark = strtok(NULL, wordDelim);
1457 if(words.size() != 2)
1460 throw runtime_error(badNameMsg);
1462 char* typeStr = (
char*) words[0].c_str();
1463 if(strstr(typeStr,
"ordinalvector"))
1466 LOVector_t mydata = getLevelVariable<LOVector_t>(needsList[i], lvl);
1469 else if(strstr(typeStr,
"map"))
1472 Map_t mydata = getLevelVariable<Map_t>(needsList[i], lvl);
1475 else if(strstr(typeStr,
"scalar"))
1477 Scalar mydata = getLevelVariable<Scalar>(needsList[i], lvl);
1480 else if(strstr(typeStr,
"double"))
1482 double mydata = getLevelVariable<double>(needsList[i], lvl);
1485 else if(strstr(typeStr,
"complex"))
1487 complex_t mydata = getLevelVariable<complex_t>(needsList[i], lvl);
1490 else if(strstr(typeStr,
"matrix"))
1492 Matrix_t mydata = getLevelVariable<Matrix_t>(needsList[i], lvl);
1495 else if(strstr(typeStr,
"multivector"))
1497 MultiVector_t mydata = getLevelVariable<MultiVector_t>(needsList[i], lvl);
1500 else if(strstr(typeStr,
"int"))
1502 int mydata = getLevelVariable<int>(needsList[i], lvl);
1505 else if(strstr(typeStr,
"string"))
1507 string mydata = getLevelVariable<string>(needsList[i], lvl);
1513 throw std::runtime_error(words[0] +
" is not a known variable type.");
1521 template<
typename Scalar,
typename LocalOrdinal,
typename GlobalOrdinal,
typename Node>
1524 using namespace std;
1525 using namespace Teuchos;
1532 for(
size_t i = 0; i < size_t(provides.size()); i++)
1534 if(provides[i] ==
"A" || provides[i] ==
"P" || provides[i] ==
"R" || provides[i]==
"Ptent")
1537 lvl.
Set(provides[i], mydata->getData(), factory);
1539 else if(provides[i] ==
"Nullspace" || provides[i] ==
"Coordinates")
1542 lvl.
Set(provides[i], mydata->getData(), factory);
1544 else if(provides[i] ==
"Aggregates")
1547 lvl.
Set(provides[i], mydata->getData(), factory);
1549 else if(provides[i] ==
"UnAmalgamationInfo")
1552 lvl.
Set(provides[i], mydata->getData(), factory);
1554 else if(provides[i] ==
"Graph")
1557 lvl.
Set(provides[i], mydata->getData(), factory);
1561 vector<string> words;
1562 string badNameMsg =
"Custom Muemex variables in \"Provides\" list require a type and a name, e.g. \"double myVal\". \n Leading and trailing spaces are OK. \n Don't know how to handle \"" + provides[i] +
"\".\n";
1564 char* buf = (
char*) malloc(provides[i].size() + 1);
1565 strcpy(buf, provides[i].c_str());
1566 for(
char* iter = buf; *iter !=
' '; iter++)
1571 throw runtime_error(badNameMsg);
1573 *iter = (char)
tolower(*iter);
1575 const char* wordDelim =
" ";
1576 char* mark = strtok(buf, wordDelim);
1579 string wordStr(mark);
1580 words.push_back(wordStr);
1581 mark = strtok(NULL, wordDelim);
1583 if(words.size() != 2)
1586 throw runtime_error(badNameMsg);
1588 const char* typeStr = words[0].c_str();
1589 if(strstr(typeStr,
"ordinalvector"))
1593 addLevelVariable<LOVector_t>(mydata->getData(), words[1], lvl, factory);
1595 else if(strstr(typeStr,
"map"))
1599 addLevelVariable<Map_t>(mydata->getData(), words[1], lvl, factory);
1601 else if(strstr(typeStr,
"scalar"))
1604 addLevelVariable<Scalar>(mydata->getData(), words[1], lvl, factory);
1606 else if(strstr(typeStr,
"double"))
1609 addLevelVariable<double>(mydata->getData(), words[1], lvl, factory);
1611 else if(strstr(typeStr,
"complex"))
1614 addLevelVariable<complex_t>(mydata->getData(), words[1], lvl, factory);
1616 else if(strstr(typeStr,
"matrix"))
1619 addLevelVariable<Matrix_t>(mydata->getData(), words[1], lvl, factory);
1621 else if(strstr(typeStr,
"multivector"))
1624 addLevelVariable<MultiVector_t>(mydata->getData(), words[1], lvl, factory);
1626 else if(strstr(typeStr,
"int"))
1629 addLevelVariable<int>(mydata->getData(), words[1], lvl, factory);
1631 else if(strstr(typeStr,
"bool"))
1634 addLevelVariable<bool>(mydata->getData(), words[1], lvl, factory);
1636 else if(strstr(typeStr,
"string"))
1639 addLevelVariable<string>(mydata->getData(), words[1], lvl, factory);
1644 throw std::runtime_error(words[0] +
" is not a known variable type.");
1655 throw std::runtime_error(
"Muemex does not support long long for global indices");
1660 throw std::runtime_error(
"Muemex does not support long long for global indices");
1665 throw std::runtime_error(
"Muemex does not support long long for global indices");
1670 throw std::runtime_error(
"Muemex does not support long long for global indices");
1675 #endif //HAVE_MUELU_MATLAB error handler
1676 #endif //MUELU_MATLABUTILS_DEF_HPP guard
mxArray * convertToMatlab()
std::vector< Teuchos::RCP< MuemexArg > > processNeeds< double, mm_LocalOrd, long long, mm_node_t >(const Factory *factory, std::string &needsParam, Level &lvl)
template mxArray * saveDataToMatlab(bool &data)
std::vector< std::string > tokenizeList(const std::string ¶ms)
T & Get(const std::string &ename, const FactoryBase *factory=NoFactory::get())
Get data without decrementing associated storage counter (i.e., read-only access). Usage: Level->Get< RCP<Matrix> >("A", factory) if factory == NULL => use default factory.
mxArray * createMatlabSparse< complex_t >(int numRows, int numCols, int nnz)
MuemexType getMuemexType< string >()
MueLu representation of a compressed row storage graph.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void processProvides< complex_t, mm_LocalOrd, long long, mm_node_t >(std::vector< Teuchos::RCP< MuemexArg >> &mexOutput, const Factory *factory, std::string &providesParam, Level &lvl)
User data are always kept. This flag is set automatically when Level::Set("data", data) is used...
std::string tolower(const std::string &str)
void fillMatlabArray< double >(double *array, const mxArray *mxa, int n)
static Teuchos::RCP< const Comm< OrdinalType > > getComm()
template string loadDataFromMatlab< string >(const mxArray *mxa)
MuemexType getMuemexType(const T &data)
std::vector< Teuchos::RCP< MuemexArg > > processNeeds(const Factory *factory, std::string &needsParam, Level &lvl)
void addLevelVariable(const T &data, std::string &name, Level &lvl, const FactoryBase *fact=NoFactory::get())
int FillComplete(bool OptimizeDataStorage=true)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
void fillMatlabArray< complex_t >(complex_t *array, const mxArray *mxa, int n)
void processProvides< double, mm_LocalOrd, long long, mm_node_t >(std::vector< Teuchos::RCP< MuemexArg >> &mexOutput, const Factory *factory, std::string &providesParam, Level &lvl)
mxArray * createMatlabSparse< double >(int numRows, int numCols, int nnz)
int * mwIndex_to_int(int N, mwIndex *mwi_array)
Class that holds all level-specific information.
template complex_t loadDataFromMatlab< complex_t >(const mxArray *mxa)
template int loadDataFromMatlab< int >(const mxArray *mxa)
template bool loadDataFromMatlab< bool >(const mxArray *mxa)
const T & getLevelVariable(std::string &name, Level &lvl)
MuemexType getMuemexType< int >()
mxArray * createMatlabMultiVector< complex_t >(int numRows, int numCols)
std::vector< Teuchos::RCP< MuemexArg > > processNeeds< complex_t, mm_LocalOrd, long long, mm_node_t >(const Factory *factory, std::string &needsParam, Level &lvl)
void AddKeepFlag(const std::string &ename, const FactoryBase *factory=NoFactory::get(), KeepType keep=MueLu::Keep)
MuemexType getMuemexType< bool >()
void Set(const std::string &ename, const T &entry, const FactoryBase *factory=NoFactory::get())
static RCP< Vector > Build(const Teuchos::RCP< const Map > &map, bool zeroOut=true)
virtual int InsertGlobalValues(int GlobalRow, int NumEntries, const double *Values, const int *Indices)
std::complex< double > complex_t
mxArray * createMatlabMultiVector< double >(int numRows, int numCols)
template double loadDataFromMatlab< double >(const mxArray *mxa)
MueLu::Aggregates< mm_LocalOrd, mm_GlobalOrd, mm_node_t > MAggregates
TypeTo as(const TypeFrom &t)
MuemexType getMuemexType< double >()
Tpetra::Map muemex_map_type
void processProvides(std::vector< Teuchos::RCP< MuemexArg >> &mexOutput, const Factory *factory, std::string &providesParam, Level &lvl)
RCP< Xpetra::Matrix< SC, LO, GO, NO > > TpetraCrs_To_XpetraMatrix(const Teuchos::RCP< Tpetra::CrsMatrix< SC, LO, GO, NO > > &Atpetra)
virtual const RCP< const FactoryBase > GetFactory(const std::string &varName) const =0
int GetLevelID() const
Return level number.
static Teuchos::RCP< Map< LocalOrdinal, GlobalOrdinal, Node > > Build(UnderlyingLib lib, global_size_t numGlobalElements, GlobalOrdinal indexBase, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, LocalGlobal lg=Xpetra::GloballyDistributed)
MuemexType getMuemexType< complex_t >()
RCP< Xpetra::MultiVector< SC, LO, GO, NO > > TpetraMultiVector_To_XpetraMultiVector(const Teuchos::RCP< Tpetra::MultiVector< SC, LO, GO, NO > > &Vtpetra)