10 #ifndef MUELU_MATLABUTILS_DEF_HPP
11 #define MUELU_MATLABUTILS_DEF_HPP
15 #if !defined(HAVE_MUELU_MATLAB) || !defined(HAVE_MUELU_EPETRA)
16 #error "Muemex types require MATLAB, Epetra and Tpetra."
131 #ifdef HAVE_MUELU_INTREPID2
135 MuemexType getMuemexType<RCP<FieldContainer_ordinal> >() {
return FIELDCONTAINER_ORDINAL; }
167 mxClassID probIDtype = mxGetClassID(mxa);
169 if (probIDtype == mxINT32_CLASS) {
170 rv = *((
int*)mxGetData(mxa));
171 }
else if (probIDtype == mxLOGICAL_CLASS) {
172 rv = (int)*((
bool*)mxGetData(mxa));
173 }
else if (probIDtype == mxDOUBLE_CLASS) {
174 rv = (int)*((
double*)mxGetData(mxa));
175 }
else if (probIDtype == mxUINT32_CLASS) {
176 rv = (int)*((
unsigned int*)mxGetData(mxa));
179 throw std::runtime_error(
"Error: Unrecognized numerical type.");
186 return *((
bool*)mxGetData(mxa));
191 return *((
double*)mxGetPr(mxa));
196 double realpart = real<double>(*((
double*)mxGetPr(mxa)));
197 double imagpart = imag<double>(*((
double*)mxGetPi(mxa)));
204 if (mxGetClassID(mxa) != mxCHAR_CLASS) {
205 throw runtime_error(
"Can't construct string from anything but a char array.");
207 rv = string(mxArrayToString(mxa));
214 int nr = mxGetM(mxa);
215 int nc = mxGetN(mxa);
217 throw std::runtime_error(
"A Xpetra::Map representation from MATLAB must be a single row vector.");
218 double* pr = mxGetPr(mxa);
221 std::vector<mm_GlobalOrd> localGIDs(numGlobalIndices);
222 for (
int i = 0; i < int(numGlobalIndices); i++) {
223 localGIDs[i] = Teuchos::as<mm_GlobalOrd>(pr[i]);
235 throw runtime_error(
"Failed to create Xpetra::Map.");
242 if (mxGetN(mxa) != 1 && mxGetM(mxa) != 1)
243 throw std::runtime_error(
"An OrdinalVector from MATLAB must be a single row or column vector.");
244 mm_GlobalOrd numGlobalIndices = mxGetM(mxa) * mxGetN(mxa);
246 if (mxGetClassID(mxa) != mxINT32_CLASS)
247 throw std::runtime_error(
"Can only construct LOVector with int32 data.");
248 int* array = (
int*)mxGetData(mxa);
250 throw runtime_error(
"Failed to create map for Xpetra ordinal vector.");
253 throw runtime_error(
"Failed to create ordinal vector with Xpetra::VectorFactory.");
254 for (
int i = 0; i < int(numGlobalIndices); i++) {
255 loVec->replaceGlobalValue(i, 0, array[i]);
264 int nr = mxGetM(mxa);
265 int nc = mxGetN(mxa);
266 double* pr = mxGetPr(mxa);
273 }
catch (std::exception& e) {
274 mexPrintf(
"Error constructing Tpetra MultiVector.\n");
275 std::cout << e.what() << std::endl;
284 int nr = mxGetM(mxa);
285 int nc = mxGetN(mxa);
286 double* pr = mxGetPr(mxa);
287 double* pi = mxGetPi(mxa);
293 for (
int n = 0; n < nc; n++) {
294 for (
int m = 0; m < nr; m++) {
295 myArr[n * nr + m] =
complex_t(pr[n * nr + m], pi[n * nr + m]);
300 }
catch (std::exception& e) {
301 mexPrintf(
"Error constructing Tpetra MultiVector.\n");
302 std::cout << e.what() << std::endl;
309 bool success =
false;
318 const size_t numGlobalIndices = mxGetM(mxa);
321 double* valueArray = mxGetPr(mxa);
322 int nc = mxGetN(mxa);
328 rowind = (
int*)mxGetIr(mxa);
329 colptr = (
int*)mxGetJc(mxa);
333 for (
int i = 0; i < nc; i++) {
334 for (
int j = colptr[i]; j < colptr[i + 1]; j++) {
335 rowCounts[rowind[j]]++;
339 for (
int i = 0; i < nc; i++) {
340 for (
int j = colptr[i]; j < colptr[i + 1]; j++) {
345 A->insertGlobalValues(rowind[j], cols, vals);
348 A->fillComplete(domainMap, rowMap);
356 }
catch (std::exception& e) {
358 if (rowind != NULL)
delete[] rowind;
359 if (colptr != NULL)
delete[] colptr;
363 mexPrintf(
"Error while constructing Tpetra matrix:\n");
364 std::cout << e.what() << std::endl;
367 mexErrMsgTxt(
"An error occurred while setting up a Tpetra matrix.\n");
381 double* realArray = mxGetPr(mxa);
382 double* imagArray = mxGetPi(mxa);
385 int nc = mxGetN(mxa);
391 rowind = (
int*)mxGetIr(mxa);
392 colptr = (
int*)mxGetJc(mxa);
396 for (
int i = 0; i < nc; i++) {
397 for (
int j = colptr[i]; j < colptr[i + 1]; j++) {
398 rowCounts[rowind[j]]++;
402 for (
int i = 0; i < nc; i++) {
403 for (
int j = colptr[i]; j < colptr[i + 1]; j++) {
406 complex_t value = std::complex<double>(realArray[j], imagArray[j]);
409 A->insertGlobalValues(rowind[j], cols, vals);
412 A->fillComplete(domainMap, rowMap);
417 }
catch (std::exception& e) {
418 mexPrintf(
"Error while constructing tpetra matrix:\n");
419 std::cout << e.what() << std::endl;
427 return MueLu::TpetraCrs_To_XpetraMatrix<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t>(tmat);
433 return MueLu::TpetraCrs_To_XpetraMatrix<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t>(tmat);
439 return MueLu::TpetraMultiVector_To_XpetraMultiVector<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t>(tpetraMV);
445 return MueLu::TpetraMultiVector_To_XpetraMultiVector<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t>(tpetraMV);
454 double* vals = mxGetPr(mxa);
455 int nr = mxGetM(mxa);
456 int nc = mxGetN(mxa);
461 rowind = (
int*)mxGetIr(mxa);
462 colptr = (
int*)mxGetJc(mxa);
469 for (
int i = 0; i < nc; i++) {
470 for (
int j = colptr[i]; j < colptr[i + 1]; j++) {
480 }
catch (std::exception& e) {
481 mexPrintf(
"An error occurred while setting up an Epetra matrix:\n");
482 std::cout << e.what() << std::endl;
489 int nr = mxGetM(mxa);
490 int nc = mxGetN(mxa);
498 if (mxGetNumberOfElements(mxa) != 1)
499 throw runtime_error(
"Aggregates must be individual structs in MATLAB.");
500 if (!mxIsStruct(mxa))
501 throw runtime_error(
"Trying to pull aggregates from non-struct MATLAB object.");
504 const int correctNumFields = 5;
505 if (mxGetNumberOfFields(mxa) != correctNumFields)
506 throw runtime_error(
"Aggregates structure has wrong number of fields.");
508 int nVert = *(
int*)mxGetData(mxGetField(mxa, 0,
"nVertices"));
509 int nAgg = *(
int*)mxGetData(mxGetField(mxa, 0,
"nAggregates"));
513 int myRank = comm->getRank();
517 agg->SetNumAggregates(nAgg);
525 mxArray* vertToAggID_in = mxGetField(mxa, 0,
"vertexToAggID");
526 int* vertToAggID_inArray = (
int*)mxGetData(vertToAggID_in);
527 mxArray* rootNodes_in = mxGetField(mxa, 0,
"rootNodes");
528 int* rootNodes_inArray = (
int*)mxGetData(rootNodes_in);
529 for (
int i = 0; i < nVert; i++) {
530 vertex2AggId[i] = vertToAggID_inArray[i];
531 procWinner[i] = myRank;
532 agg->SetIsRoot(i,
false);
534 for (
int i = 0; i < nAgg; i++)
536 agg->SetIsRoot(rootNodes_inArray[i],
true);
539 agg->ComputeAggregateSizes(
true);
540 agg->AggregatesCrossProcessors(
false);
547 throw runtime_error(
"AmalgamationInfo not supported in Muemex yet.");
552 RCP<MGraph> loadDataFromMatlab<RCP<MGraph> >(
const mxArray* mxa) {
554 mxArray* edges = mxGetField(mxa, 0,
"edges");
555 mxArray* boundaryNodes = mxGetField(mxa, 0,
"boundaryNodes");
557 throw runtime_error(
"Graph structure in MATLAB must have a field called 'edges' (logical sparse matrix)");
558 if (boundaryNodes == NULL)
559 throw runtime_error(
"Graph structure in MATLAB must have a field called 'boundaryNodes' (int32 array containing list of boundary nodes)");
560 int* boundaryList = (
int*)mxGetData(boundaryNodes);
561 if (!mxIsSparse(edges) || mxGetClassID(edges) != mxLOGICAL_CLASS)
562 throw runtime_error(
"Graph edges must be stored as a logical sparse matrix.");
564 mwIndex* matlabColPtrs = mxGetJc(edges);
565 mwIndex* matlabRowIndices = mxGetIr(edges);
572 int nnz = matlabColPtrs[mxGetN(edges)];
573 for (
int i = 0; i < nnz; i++)
574 entriesPerRow[matlabRowIndices[i]]++;
579 for (
int i = 0; i < nRows; i++)
580 rows[i + 1] = rows[i] + entriesPerRow[i];
583 int ncols = mxGetN(edges);
584 for (
int colNum = 0; colNum < ncols; ++colNum) {
585 int ci = matlabColPtrs[colNum];
586 for (
int j = ci; j < Teuchos::as<int>(matlabColPtrs[colNum + 1]); ++j) {
587 int rowNum = matlabRowIndices[j];
588 cols[rows[rowNum] + insertionsPerRow[rowNum]] = colNum;
589 insertionsPerRow[rowNum]++;
594 for (
int i = 0; i < nRows; i++) {
595 if (maxNzPerRow < entriesPerRow[i])
596 maxNzPerRow = entriesPerRow[i];
605 for (
int i = 0; i < nRows; ++i) {
606 tgraph->insertGlobalIndices((
mm_GlobalOrd)i, cols(rows[i], entriesPerRow[i]));
608 tgraph->fillComplete(map, map);
611 int numBoundaryNodes = mxGetNumberOfElements(boundaryNodes);
612 bool* boundaryFlags =
new bool[nRows];
613 for (
int i = 0; i < nRows; i++) {
614 boundaryFlags[i] =
false;
616 for (
int i = 0; i < numBoundaryNodes; i++) {
617 boundaryFlags[boundaryList[i]] =
true;
620 mgraph->SetBoundaryNodeMap(boundaryNodesInput);
624 #ifdef HAVE_MUELU_INTREPID2
627 if (mxGetClassID(mxa) != mxINT32_CLASS)
628 throw runtime_error(
"FieldContainer must have integer storage entries");
630 int* data = (
int*)mxGetData(mxa);
631 int nr = mxGetM(mxa);
632 int nc = mxGetN(mxa);
635 for (
int col = 0; col < nc; col++) {
636 for (
int row = 0; row < nr; row++) {
637 (*fc)(row, col) = data[col * nr + row];
650 mwSize dims[] = {1, 1};
651 mxArray* mxa = mxCreateNumericArray(2, dims, mxINT32_CLASS, mxREAL);
652 *((
int*)mxGetData(mxa)) = data;
658 mwSize dims[] = {1, 1};
659 mxArray* mxa = mxCreateLogicalArray(2, dims);
660 *((
bool*)mxGetData(mxa)) = data;
666 return mxCreateDoubleScalar(data);
671 mwSize dims[] = {1, 1};
672 mxArray* mxa = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxCOMPLEX);
673 *((
double*)mxGetPr(mxa)) = real<double>(data);
674 *((
double*)mxGetPi(mxa)) = imag<double>(data);
680 return mxCreateString(data.c_str());
686 int nc = data->getGlobalNumElements();
689 double* array = (
double*)malloc(
sizeof(
double) * nr * nc);
690 for (
int col = 0; col < nc; col++) {
692 array[col] = Teuchos::as<double>(gid);
701 mwSize len = data->getGlobalLength();
703 mwSize dimensions[] = {len, 1};
704 mxArray* rv = mxCreateNumericArray(2, dimensions, mxINT32_CLASS, mxREAL);
705 int* dataPtr = (
int*)mxGetData(rv);
707 for (
int i = 0; i < int(data->getGlobalLength()); i++) {
741 Teuchos::rcp_const_cast<
Xpetra_CrsGraph>(data->getCrsGraph())->computeGlobalConstants();
743 int nr = data->getGlobalNumRows();
744 int nc = data->getGlobalNumCols();
745 int nnz = data->getGlobalNumEntries();
747 #ifdef VERBOSE_OUTPUT
751 mxArray* mxa = createMatlabSparse<Scalar>(nr, nc, nnz);
754 for (
int i = 0; i < nc + 1; i++) {
758 size_t maxEntriesPerRow = data->getGlobalMaxNumRowEntries();
761 int* rowProgress =
new int[nc];
763 Scalar* sparseVals =
new Scalar[nnz];
765 if (data->isLocallyIndexed()) {
766 Scalar* rowValArray =
new Scalar[maxEntriesPerRow];
772 data->getLocalRowCopy(m, rowIndices, rowVals, numEntries);
773 for (
mm_LocalOrd entry = 0; entry < int(numEntries); entry++)
775 jc[rowIndices[entry] + 1]++;
780 int entriesAccum = 0;
781 for (
int n = 0; n <= nc; n++) {
782 int temp = entriesAccum;
783 entriesAccum += jc[n];
787 for (
int i = 0; i < nc; i++) {
793 data->getLocalRowCopy(m, rowIndices, rowVals, numEntries);
798 sparseVals[jc[col] + rowProgress[col]] = rowVals[i];
799 ir[jc[col] + rowProgress[col]] = m;
803 delete[] rowIndicesArray;
808 data->getGlobalRowView(m, rowIndices, rowVals);
810 jc[rowIndices[n] + 1]++;
816 for (
int i = 0; i < nc; i++) {
819 int entriesAccum = 0;
820 for (
int n = 0; n <= nc; n++) {
821 int temp = entriesAccum;
822 entriesAccum += jc[n];
828 data->getGlobalRowView(m, rowIndices, rowVals);
832 sparseVals[jc[col] + rowProgress[col]] = rowVals[i];
833 ir[jc[col] + rowProgress[col]] = m;
839 fillMatlabArray<Scalar>(sparseVals, mxa, nnz);
841 delete[] rowProgress;
850 Teuchos::rcp_const_cast<
Xpetra_CrsGraph>(data->getCrsGraph())->computeGlobalConstants();
852 int nr = data->getGlobalNumRows();
853 int nc = data->getGlobalNumCols();
854 int nnz = data->getGlobalNumEntries();
855 #ifdef VERBOSE_OUTPUT
859 mxArray* mxa = createMatlabSparse<Scalar>(nr, nc, nnz);
862 for (
int i = 0; i < nc + 1; i++) {
865 size_t maxEntriesPerRow = data->getGlobalMaxNumRowEntries();
866 int* rowProgress =
new int[nc];
868 Scalar* sparseVals =
new Scalar[nnz];
870 if (data->isLocallyIndexed()) {
871 Scalar* rowValArray =
new Scalar[maxEntriesPerRow];
877 data->getLocalRowCopy(m, rowIndices, rowVals, numEntries);
878 for (
mm_LocalOrd entry = 0; entry < int(numEntries); entry++)
880 jc[rowIndices[entry] + 1]++;
884 int entriesAccum = 0;
885 for (
int n = 0; n <= nc; n++) {
886 int temp = entriesAccum;
887 entriesAccum += jc[n];
891 for (
int i = 0; i < nc; i++) {
897 data->getLocalRowCopy(m, rowIndices, rowVals, numEntries);
902 sparseVals[jc[col] + rowProgress[col]] = rowVals[i];
903 ir[jc[col] + rowProgress[col]] = m;
907 delete[] rowIndicesArray;
912 data->getGlobalRowView(m, rowIndices, rowVals);
914 jc[rowIndices[n] + 1]++;
920 for (
int i = 0; i < nc; i++) {
923 int entriesAccum = 0;
924 for (
int n = 0; n <= nc; n++) {
925 int temp = entriesAccum;
926 entriesAccum += jc[n];
932 data->getGlobalRowView(m, rowIndices, rowVals);
936 sparseVals[jc[col] + rowProgress[col]] = rowVals[i];
937 ir[jc[col] + rowProgress[col]] = m;
943 fillMatlabArray<Scalar>(sparseVals, mxa, nnz);
945 delete[] rowProgress;
975 int nr = data->getGlobalLength();
976 int nc = data->getNumVectors();
978 double* array = (
double*)malloc(
sizeof(
double) * nr * nc);
979 for (
int col = 0; col < nc; col++) {
981 for (
int row = 0; row < nr; row++) {
982 array[col * nr + row] = colData[row];
993 int nr = data->getGlobalLength();
994 int nc = data->getNumVectors();
997 for (
int col = 0; col < nc; col++) {
999 for (
int row = 0; row < nr; row++) {
1000 array[col * nr + row] = colData[row];
1016 mxArray* output = mxCreateDoubleMatrix(data->GlobalLength(), data->NumVectors(), mxREAL);
1017 double* dataPtr = mxGetPr(output);
1018 data->ExtractCopy(dataPtr, data->GlobalLength());
1025 int numNodes = data->GetVertex2AggId()->getData(0).size();
1026 int numAggs = data->GetNumAggregates();
1028 mwSize singleton[] = {1, 1};
1029 dataIn[0] = mxCreateNumericArray(2, singleton, mxINT32_CLASS, mxREAL);
1030 *((
int*)mxGetData(dataIn[0])) = numNodes;
1031 dataIn[1] = mxCreateNumericArray(2, singleton, mxINT32_CLASS, mxREAL);
1032 *((
int*)mxGetData(dataIn[1])) = numAggs;
1033 mwSize nodeArrayDims[] = {(mwSize)numNodes, 1};
1034 dataIn[2] = mxCreateNumericArray(2, nodeArrayDims, mxINT32_CLASS, mxREAL);
1035 int* vtaid = (
int*)mxGetData(dataIn[2]);
1037 for (
int i = 0; i < numNodes; i++) {
1038 vtaid[i] = vertexToAggID[i];
1040 mwSize aggArrayDims[] = {(mwSize)numAggs, 1};
1041 dataIn[3] = mxCreateNumericArray(2, aggArrayDims, mxINT32_CLASS, mxREAL);
1044 for (
int i = 0; i < numNodes; i++) {
1045 if (data->IsRoot(i))
1048 bool reassignRoots =
false;
1049 if (totalRoots != numAggs) {
1051 <<
"Warning: Number of root nodes and number of aggregates do not match." << endl;
1052 cout <<
"Will reassign root nodes when writing aggregates to matlab." << endl
1054 reassignRoots =
true;
1056 int* rn = (
int*)mxGetData(dataIn[3]);
1058 if (reassignRoots) {
1060 int lastFoundNode = 0;
1061 for (
int i = 0; i < numAggs; i++) {
1063 for (
int j = lastFoundNode; j < lastFoundNode + numNodes; j++) {
1064 int index = j % numNodes;
1065 if (vertexToAggID[index] == i) {
1067 lastFoundNode = index;
1070 TEUCHOS_TEST_FOR_EXCEPTION(rn[i] == -1, runtime_error,
"Invalid aggregates: Couldn't find any node in aggregate #" << i <<
".");
1074 for (
int j = 0; j < numNodes; j++) {
1075 if (data->IsRoot(j)) {
1077 throw runtime_error(
"Cannot store invalid aggregates in MATLAB - more root nodes than aggregates.");
1082 if (i + 1 < numAggs)
1083 throw runtime_error(
"Cannot store invalid aggregates in MATLAB - fewer root nodes than aggregates.");
1086 dataIn[4] = mxCreateNumericArray(1, aggArrayDims, mxINT32_CLASS, mxREAL);
1087 int*
as = (
int*)mxGetData(dataIn[4]);
1089 for (
int i = 0; i < numAggs; i++) {
1090 as[i] = aggSizes[i];
1092 mxArray* matlabAggs[1];
1093 int result = mexCallMATLAB(1, matlabAggs, 5, dataIn,
"constructAggregates");
1095 throw runtime_error(
"Matlab encountered an error while constructing aggregates struct.");
1096 return matlabAggs[0];
1101 throw runtime_error(
"AmalgamationInfo not supported in MueMex yet.");
1102 return mxCreateDoubleScalar(0);
1107 int numEntries = (int)data->GetGlobalNumEdges();
1108 int numRows = (int)data->GetDomainMap()->getGlobalNumElements();
1109 mxArray* mat = mxCreateSparseLogicalMatrix(numRows, numRows, numEntries);
1110 mxLogical* outData = (mxLogical*)mxGetData(mat);
1111 mwIndex* rowInds = mxGetIr(mat);
1112 mwIndex* colPtrs = mxGetJc(mat);
1115 int* entriesPerRow =
new int[numRows];
1116 int* entriesPerCol =
new int[numRows];
1117 for (
int i = 0; i < numRows; i++) {
1118 entriesPerRow[i] = 0;
1119 entriesPerCol[i] = 0;
1121 for (
int i = 0; i < numRows; i++) {
1124 entriesPerRow[i] = neighbors.
size();
1125 for (
int j = 0; j < neighbors.
size(); j++) {
1126 entriesPerCol[neighbors[j]]++;
1128 iter += neighbors.
size();
1131 mxLogical** valuesByColumn =
new mxLogical*[numRows];
1132 int* numEnteredPerCol =
new int[numRows];
1134 for (
int i = 0; i < numRows; i++) {
1135 rowIndsByColumn[i] = &rowInds[accum];
1137 valuesByColumn[i] = &outData[accum];
1138 accum += entriesPerCol[i];
1139 if (accum > numEntries)
1140 throw runtime_error(
"potato");
1142 for (
int i = 0; i < numRows; i++) {
1143 numEnteredPerCol[i] = 0;
1147 for (
int row = 0; row < numRows; row++) {
1148 for (
int entryInRow = 0; entryInRow < entriesPerRow[row]; entryInRow++) {
1149 int col = dataCopy[accum];
1151 rowIndsByColumn[col][numEnteredPerCol[col]] = row;
1152 valuesByColumn[col][numEnteredPerCol[col]] = (mxLogical)1;
1153 numEnteredPerCol[col]++;
1157 for (
int col = 0; col < numRows; col++) {
1158 colPtrs[col] = accum;
1159 accum += entriesPerCol[col];
1161 colPtrs[numRows] = accum;
1162 delete[] numEnteredPerCol;
1163 delete[] rowIndsByColumn;
1164 delete[] valuesByColumn;
1166 delete[] entriesPerRow;
1167 delete[] entriesPerCol;
1170 int numBoundaryNodes = 0;
1171 for (
int i = 0; i < boundaryFlags.
size(); i++) {
1172 if (boundaryFlags[i])
1175 cout <<
"Graph has " << numBoundaryNodes <<
" Dirichlet boundary nodes." << endl;
1176 mwSize dims[] = {(mwSize)numBoundaryNodes, 1};
1177 mxArray* boundaryList = mxCreateNumericArray(2, dims, mxINT32_CLASS, mxREAL);
1178 int* dest = (
int*)mxGetData(boundaryList);
1179 int* destIter = dest;
1180 for (
int i = 0; i < boundaryFlags.
size(); i++) {
1181 if (boundaryFlags[i]) {
1186 mxArray* constructArgs[] = {mat, boundaryList};
1188 mexCallMATLAB(1, out, 2, constructArgs,
"constructGraph");
1192 #ifdef HAVE_MUELU_INTREPID2
1195 int rank = data->rank();
1198 throw std::runtime_error(
"Error: Only rank two FieldContainers are supported.");
1200 int nr = data->extent(0);
1201 int nc = data->extent(1);
1203 mwSize dims[] = {(mwSize)nr, (mwSize)nc};
1204 mxArray* mxa = mxCreateNumericArray(2, dims, mxINT32_CLASS, mxREAL);
1205 int* array = (
int*)mxGetData(mxa);
1207 for (
int col = 0; col < nc; col++) {
1208 for (
int row = 0; row < nr; row++) {
1209 array[col * nr + row] = (*data)(row, col);
1216 template <
typename T>
1219 data = loadDataFromMatlab<T>(mxa);
1222 template <
typename T>
1224 return saveDataToMatlab<T>(data);
1227 template <
typename T>
1233 template <
typename T>
1237 template <
typename T>
1242 template <
typename T>
1244 this->data = newData;
1251 template <
typename T>
1254 lvl.
Set<T>(name, data, fact);
1257 template <
typename T>
1260 return lvl.
Get<T>(name);
1261 }
catch (std::exception& e) {
1262 throw std::runtime_error(
"Requested custom variable " + name +
" is not in the level.");
1267 template <
typename Scalar,
typename LocalOrdinal,
typename GlobalOrdinal,
typename Node>
1269 using namespace std;
1270 using namespace Teuchos;
1277 vector<RCP<MuemexArg> > args;
1278 for (
size_t i = 0; i < needsList.size(); i++) {
1279 if (needsList[i] ==
"A" || needsList[i] ==
"P" || needsList[i] ==
"R" || needsList[i] ==
"Ptent") {
1280 Matrix_t mydata = lvl.
Get<Matrix_t>(needsList[i], factory->
GetFactory(needsList[i]).get());
1282 }
else if (needsList[i] ==
"Nullspace" || needsList[i] ==
"Coordinates") {
1283 MultiVector_t mydata = lvl.
Get<MultiVector_t>(needsList[i], factory->
GetFactory(needsList[i]).get());
1285 }
else if (needsList[i] ==
"Aggregates") {
1286 Aggregates_t mydata = lvl.
Get<Aggregates_t>(needsList[i], factory->
GetFactory(needsList[i]).get());
1288 }
else if (needsList[i] ==
"UnAmalgamationInfo") {
1289 AmalgamationInfo_t mydata = lvl.
Get<AmalgamationInfo_t>(needsList[i], factory->
GetFactory(needsList[i]).get());
1291 }
else if (needsList[i] ==
"Level") {
1294 }
else if (needsList[i] ==
"Graph") {
1295 Graph_t mydata = lvl.
Get<Graph_t>(needsList[i], factory->
GetFactory(needsList[i]).get());
1298 vector<string> words;
1299 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";
1301 char* buf = (
char*)malloc(needsList[i].size() + 1);
1302 strcpy(buf, needsList[i].c_str());
1303 for (
char* iter = buf; *iter !=
' '; iter++) {
1306 throw runtime_error(badNameMsg);
1310 const char* wordDelim =
" ";
1311 char* mark = strtok(buf, wordDelim);
1312 while (mark != NULL) {
1313 string wordStr(mark);
1314 words.push_back(wordStr);
1315 mark = strtok(NULL, wordDelim);
1317 if (words.size() != 2) {
1319 throw runtime_error(badNameMsg);
1321 char* typeStr = (
char*)words[0].c_str();
1322 if (strstr(typeStr,
"ordinalvector")) {
1324 LOVector_t mydata = getLevelVariable<LOVector_t>(needsList[i], lvl);
1326 }
else if (strstr(typeStr,
"map")) {
1328 Map_t mydata = getLevelVariable<Map_t>(needsList[i], lvl);
1330 }
else if (strstr(typeStr,
"scalar")) {
1331 Scalar mydata = getLevelVariable<Scalar>(needsList[i], lvl);
1333 }
else if (strstr(typeStr,
"double")) {
1334 double mydata = getLevelVariable<double>(needsList[i], lvl);
1336 }
else if (strstr(typeStr,
"complex")) {
1337 complex_t mydata = getLevelVariable<complex_t>(needsList[i], lvl);
1339 }
else if (strstr(typeStr,
"matrix")) {
1340 Matrix_t mydata = getLevelVariable<Matrix_t>(needsList[i], lvl);
1342 }
else if (strstr(typeStr,
"multivector")) {
1343 MultiVector_t mydata = getLevelVariable<MultiVector_t>(needsList[i], lvl);
1345 }
else if (strstr(typeStr,
"int")) {
1346 int mydata = getLevelVariable<int>(needsList[i], lvl);
1348 }
else if (strstr(typeStr,
"string")) {
1349 string mydata = getLevelVariable<string>(needsList[i], lvl);
1353 throw std::runtime_error(words[0] +
" is not a known variable type.");
1361 template <
typename Scalar,
typename LocalOrdinal,
typename GlobalOrdinal,
typename Node>
1363 using namespace std;
1364 using namespace Teuchos;
1371 for (
size_t i = 0; i < size_t(provides.size()); i++) {
1372 if (provides[i] ==
"A" || provides[i] ==
"P" || provides[i] ==
"R" || provides[i] ==
"Ptent") {
1374 lvl.
Set(provides[i], mydata->getData(), factory);
1375 }
else if (provides[i] ==
"Nullspace" || provides[i] ==
"Coordinates") {
1377 lvl.
Set(provides[i], mydata->getData(), factory);
1378 }
else if (provides[i] ==
"Aggregates") {
1380 lvl.
Set(provides[i], mydata->getData(), factory);
1381 }
else if (provides[i] ==
"UnAmalgamationInfo") {
1383 lvl.
Set(provides[i], mydata->getData(), factory);
1384 }
else if (provides[i] ==
"Graph") {
1386 lvl.
Set(provides[i], mydata->getData(), factory);
1388 vector<string> words;
1389 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";
1391 char* buf = (
char*)malloc(provides[i].size() + 1);
1392 strcpy(buf, provides[i].c_str());
1393 for (
char* iter = buf; *iter !=
' '; iter++) {
1396 throw runtime_error(badNameMsg);
1400 const char* wordDelim =
" ";
1401 char* mark = strtok(buf, wordDelim);
1402 while (mark != NULL) {
1403 string wordStr(mark);
1404 words.push_back(wordStr);
1405 mark = strtok(NULL, wordDelim);
1407 if (words.size() != 2) {
1409 throw runtime_error(badNameMsg);
1411 const char* typeStr = words[0].c_str();
1412 if (strstr(typeStr,
"ordinalvector")) {
1415 addLevelVariable<LOVector_t>(mydata->getData(), words[1], lvl, factory);
1416 }
else if (strstr(typeStr,
"map")) {
1419 addLevelVariable<Map_t>(mydata->getData(), words[1], lvl, factory);
1420 }
else if (strstr(typeStr,
"scalar")) {
1422 addLevelVariable<Scalar>(mydata->getData(), words[1], lvl, factory);
1423 }
else if (strstr(typeStr,
"double")) {
1425 addLevelVariable<double>(mydata->getData(), words[1], lvl, factory);
1426 }
else if (strstr(typeStr,
"complex")) {
1428 addLevelVariable<complex_t>(mydata->getData(), words[1], lvl, factory);
1429 }
else if (strstr(typeStr,
"matrix")) {
1431 addLevelVariable<Matrix_t>(mydata->getData(), words[1], lvl, factory);
1432 }
else if (strstr(typeStr,
"multivector")) {
1434 addLevelVariable<MultiVector_t>(mydata->getData(), words[1], lvl, factory);
1435 }
else if (strstr(typeStr,
"int")) {
1437 addLevelVariable<int>(mydata->getData(), words[1], lvl, factory);
1438 }
else if (strstr(typeStr,
"bool")) {
1440 addLevelVariable<bool>(mydata->getData(), words[1], lvl, factory);
1441 }
else if (strstr(typeStr,
"string")) {
1443 addLevelVariable<string>(mydata->getData(), words[1], lvl, factory);
1446 throw std::runtime_error(words[0] +
" is not a known variable type.");
1457 throw std::runtime_error(
"Muemex does not support long long for global indices");
1462 throw std::runtime_error(
"Muemex does not support long long for global indices");
1467 throw std::runtime_error(
"Muemex does not support long long for global indices");
1472 throw std::runtime_error(
"Muemex does not support long long for global indices");
1476 #endif // HAVE_MUELU_MATLAB error handler
1477 #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 >()
Tpetra::Map::local_ordinal_type mm_LocalOrd
Tpetra::Map::global_ordinal_type mm_GlobalOrd
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
RCP< Xpetra::MultiVector< SC, LO, GO, NO > > TpetraMultiVector_To_XpetraMultiVector(const Teuchos::RCP< Tpetra::MultiVector< SC, LO, GO, NO >> &Vtpetra)
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)
mxArray * createMatlabSparse< double >(int numRows, int numCols, int nnz)
MueLu::DefaultScalar Scalar
int * mwIndex_to_int(int N, mwIndex *mwi_array)
Class that holds all level-specific information.
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)
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)
template complex_t loadDataFromMatlab< complex_t >(const mxArray *mxa)
template int loadDataFromMatlab< int >(const mxArray *mxa)
RCP< Xpetra::Matrix< SC, LO, GO, NO > > TpetraCrs_To_XpetraMatrix(const Teuchos::RCP< Tpetra::CrsMatrix< SC, LO, GO, NO >> &Atpetra)
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)
void processProvides< double, mm_LocalOrd, long long, mm_node_t >(std::vector< Teuchos::RCP< MuemexArg > > &mexOutput, const Factory *factory, std::string &providesParam, Level &lvl)
virtual int InsertGlobalValues(int GlobalRow, int NumEntries, const double *Values, const int *Indices)
Teuchos::RCP< const Teuchos::Comm< int > > getDefaultComm()
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
int GetLevelID() const
Return level number.
MuemexType getMuemexType< complex_t >()
void processProvides(std::vector< Teuchos::RCP< MuemexArg > > &mexOutput, const Factory *factory, std::string &providesParam, Level &lvl)
const RCP< const FactoryBase > GetFactory(const std::string &varName) const
Default implementation of FactoryAcceptor::GetFactory()