48 #if !defined(HAVE_MUELU_MATLAB) || !defined(HAVE_MUELU_EPETRA) || !defined(HAVE_MUELU_TPETRA) 49 #error "Muemex types require MATLAB, Epetra and Tpetra." 53 #if(defined(MX_API_VER) && MX_API_VER >= 0x07030000) 64 template class MuemexData<RCP<Xpetra::MultiVector<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
65 template class MuemexData<RCP<Xpetra::MultiVector<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
66 template class MuemexData<RCP<Xpetra::Matrix<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
67 template class MuemexData<RCP<Xpetra::Matrix<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
68 template class MuemexData<RCP<MAggregates>>;
69 template class MuemexData<RCP<MAmalInfo>>;
70 template class MuemexData<int>;
71 template class MuemexData<bool>;
72 template class MuemexData<complex_t>;
73 template class MuemexData<string>;
74 template class MuemexData<double>;
75 template class MuemexData<RCP<Tpetra::CrsMatrix<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
76 template class MuemexData<RCP<Tpetra::CrsMatrix<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
77 template class MuemexData<RCP<Epetra_MultiVector> >;
78 template class MuemexData<RCP<Tpetra::MultiVector<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
79 template class MuemexData<RCP<Tpetra::MultiVector<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
80 template class MuemexData<RCP<Xpetra::Vector<mm_LocalOrd, mm_LocalOrd, mm_GlobalOrd, mm_node_t>>>;
89 for(
int i = 0; i < N; i++)
90 rv[i] = (
int) mwi_array[i];
100 return mxCreateSparse(numRows, numCols, nnz, mxREAL);
105 return mxCreateSparse(numRows, numCols, nnz, mxCOMPLEX);
110 memcpy(mxGetPr(mxa), array, n *
sizeof(
double));
115 double* pr = mxGetPr(mxa);
116 double* pi = mxGetPi(mxa);
117 for(
int i = 0; i < n; i++)
119 pr[i] = std::real<double>(array[i]);
120 pi[i] = std::imag<double>(array[i]);
130 int result = mexEvalString(
function.c_str());
132 mexPrintf(
"An error occurred while running a MATLAB command.");\
135 std::vector<RCP<MuemexArg>>
callMatlab(std::string
function,
int numOutputs, std::vector<RCP<MuemexArg>> args)
137 using Teuchos::rcp_static_cast;
138 mxArray** matlabArgs =
new mxArray* [args.size()];
139 mxArray** matlabOutput =
new mxArray* [numOutputs];
140 std::vector<RCP<MuemexArg>> output;
142 for(
int i = 0; i < int(args.size()); i++)
146 switch(args[i]->type)
210 catch (std::exception& e)
212 mexPrintf(
"An error occurred while converting arg #%d to MATLAB:\n", i);
213 std::cout << e.what() << std::endl;
214 mexPrintf(
"Passing 0 instead.\n");
215 matlabArgs[i] = mxCreateDoubleScalar(0);
219 int result = mexCallMATLAB(numOutputs, matlabOutput, args.size(), matlabArgs,
function.c_str());
221 mexPrintf(
"Matlab encountered an error while running command through muemexCallbacks.\n");
223 for(
int i = 0; i < numOutputs; i++)
229 catch(std::exception& e)
231 mexPrintf(
"An error occurred while converting output #%d from MATLAB:\n", i);
232 std::cout << e.what() << std::endl;
235 delete[] matlabOutput;
246 return mxCreateDoubleMatrix(numRows, numCols, mxREAL);
251 return mxCreateDoubleMatrix(numRows, numCols, mxCOMPLEX);
256 throw runtime_error(
"AmalgamationInfo not supported in MueMex yet.");
257 return mxCreateDoubleScalar(0);
262 bool isValidAggregates =
true;
265 int numFields = mxGetNumberOfFields(mxa);
267 isValidAggregates =
false;
268 if(isValidAggregates)
270 const char* mem1 = mxGetFieldNameByNumber(mxa, 0);
271 if(mem1 == NULL || strcmp(mem1,
"nVertices") != 0)
272 isValidAggregates =
false;
273 const char* mem2 = mxGetFieldNameByNumber(mxa, 1);
274 if(mem2 == NULL || strcmp(mem2,
"nAggregates") != 0)
275 isValidAggregates =
false;
276 const char* mem3 = mxGetFieldNameByNumber(mxa, 2);
277 if(mem3 == NULL || strcmp(mem3,
"vertexToAggID") != 0)
278 isValidAggregates =
false;
279 const char* mem4 = mxGetFieldNameByNumber(mxa, 3);
280 if(mem3 == NULL || strcmp(mem4,
"rootNodes") != 0)
281 isValidAggregates =
false;
282 const char* mem5 = mxGetFieldNameByNumber(mxa, 4);
283 if(mem4 == NULL || strcmp(mem5,
"aggSizes") != 0)
284 isValidAggregates =
false;
286 return isValidAggregates;
291 bool isValidGraph =
true;
294 int numFields = mxGetNumberOfFields(mxa);
296 isValidGraph =
false;
299 const char* mem1 = mxGetFieldNameByNumber(mxa, 0);
300 if(mem1 == NULL || strcmp(mem1,
"edges") != 0)
301 isValidGraph =
false;
302 const char* mem2 = mxGetFieldNameByNumber(mxa, 1);
303 if(mem2 == NULL || strcmp(mem2,
"boundaryNodes") != 0)
304 isValidGraph =
false;
312 vector<string> rlist;
313 const char* delims =
",";
314 char* copy = (
char*) malloc(params.length() + 1);
315 strcpy(copy, params.c_str());
316 char* mark = (
char*) strtok(copy, delims);
320 char* tail = mark + strlen(mark) - 1;
323 while(*tail ==
' ' && tail > mark)
328 rlist.push_back(tok);
329 mark = strtok(NULL, delims);
338 RCP<ParameterList> validParamList = rcp(
new ParameterList());
339 validParamList->set<RCP<const FactoryBase>>(
"A", Teuchos::null,
"Factory for the matrix A.");
340 validParamList->set<RCP<const FactoryBase>>(
"P", Teuchos::null,
"Factory for the prolongator.");
341 validParamList->set<RCP<const FactoryBase>>(
"R", Teuchos::null,
"Factory for the restrictor.");
342 validParamList->set<RCP<const FactoryBase>>(
"Ptent", Teuchos::null,
"Factory for the tentative (unsmoothed) prolongator.");
343 validParamList->set<RCP<const FactoryBase>>(
"Coordinates", Teuchos::null,
"Factory for the node coordinates.");
344 validParamList->set<RCP<const FactoryBase>>(
"Nullspace", Teuchos::null,
"Factory for the nullspace.");
345 validParamList->set<RCP<const FactoryBase>>(
"Aggregates", Teuchos::null,
"Factory for the aggregates.");
346 validParamList->set<RCP<const FactoryBase>>(
"UnamalgamationInfo", Teuchos::null,
"Factory for amalgamation.");
347 return validParamList;
352 switch(mxGetClassID(mxa))
358 case mxLOGICAL_CLASS:
363 if(mxGetM(mxa) == 1 && mxGetN(mxa) == 1)
366 else if(mxGetM(mxa) != 1 || mxGetN(mxa) != 1)
368 return rcp_implicit_cast<MuemexArg>(rcp(
new MuemexData<RCP<Xpetra_ordinal_vector>>(mxa)));
370 throw std::runtime_error(
"Error: Don't know what to do with integer array.\n");
373 if(mxGetM(mxa) == 1 && mxGetN(mxa) == 1)
382 else if(mxIsSparse(mxa))
387 return rcp_implicit_cast<MuemexArg>(rcp(
new MuemexData<RCP<Xpetra_Matrix_complex>>(mxa)));
411 throw runtime_error(
"Invalid aggregates or graph struct passed in from MATLAB.");
412 return Teuchos::null;
417 throw std::runtime_error(
"MATLAB returned an unsupported type as a function output.\n");
418 return Teuchos::null;
431 template RCP<Xpetra_ordinal_vector> loadDataFromMatlab<RCP<Xpetra_ordinal_vector>>(
const mxArray* mxa);
432 template RCP<Tpetra_MultiVector_double> loadDataFromMatlab<RCP<Tpetra_MultiVector_double>>(
const mxArray* mxa);
433 template RCP<Tpetra_MultiVector_complex> loadDataFromMatlab<RCP<Tpetra_MultiVector_complex>>(
const mxArray* mxa);
434 template RCP<Tpetra_CrsMatrix_double> loadDataFromMatlab<RCP<Tpetra_CrsMatrix_double>>(
const mxArray* mxa);
435 template RCP<Tpetra_CrsMatrix_complex> loadDataFromMatlab<RCP<Tpetra_CrsMatrix_complex>>(
const mxArray* mxa);
436 template RCP<Xpetra_Matrix_double> loadDataFromMatlab<RCP<Xpetra_Matrix_double>>(
const mxArray* mxa);
437 template RCP<Xpetra_Matrix_complex> loadDataFromMatlab<RCP<Xpetra_Matrix_complex>>(
const mxArray* mxa);
438 template RCP<Xpetra_MultiVector_double> loadDataFromMatlab<RCP<Xpetra_MultiVector_double>>(
const mxArray* mxa);
439 template RCP<Xpetra_MultiVector_complex> loadDataFromMatlab<RCP<Xpetra_MultiVector_complex>>(
const mxArray* mxa);
440 template RCP<Epetra_CrsMatrix> loadDataFromMatlab<RCP<Epetra_CrsMatrix>>(
const mxArray* mxa);
441 template RCP<Epetra_MultiVector> loadDataFromMatlab<RCP<Epetra_MultiVector>>(
const mxArray* mxa);
442 template RCP<MAggregates> loadDataFromMatlab<RCP<MAggregates>>(
const mxArray* mxa);
443 template RCP<MAmalInfo> loadDataFromMatlab<RCP<MAmalInfo>>(
const mxArray* mxa);
464 template vector<RCP<MuemexArg>>
processNeeds<double>(
const Factory* factory,
string& needsParam, Level& lvl);
465 template vector<RCP<MuemexArg>>
processNeeds<complex_t>(
const Factory* factory,
string& needsParam, Level& lvl);
466 template void processProvides<double>(vector<RCP<MuemexArg>>& mexOutput,
const Factory* factory,
string& providesParam, Level& lvl);
467 template void processProvides<complex_t>(vector<RCP<MuemexArg>>& mexOutput,
const Factory* factory,
string& providesParam, Level& lvl);
470 #endif // HAVE_MUELU_MATLAB
template mxArray * saveDataToMatlab(RCP< MAmalInfo > &data)
bool isValidMatlabAggregates(const mxArray *mxa)
std::vector< std::string > tokenizeList(const std::string ¶ms)
mxArray * createMatlabSparse< complex_t >(int numRows, int numCols, int nnz)
template vector< RCP< MuemexArg > > processNeeds< complex_t >(const Factory *factory, string &needsParam, Level &lvl)
mxArray * saveAmalInfo(RCP< MAmalInfo > &amalInfo)
template vector< RCP< MuemexArg > > processNeeds< double >(const Factory *factory, string &needsParam, Level &lvl)
Namespace for MueLu classes and methods.
void fillMatlabArray< double >(double *array, const mxArray *mxa, int n)
bool isValidMatlabGraph(const mxArray *mxa)
template string loadDataFromMatlab< string >(const mxArray *mxa)
Teuchos::RCP< Teuchos::ParameterList > getInputParamList()
void fillMatlabArray< complex_t >(complex_t *array, const mxArray *mxa, int n)
mxArray * createMatlabSparse< double >(int numRows, int numCols, int nnz)
int * mwIndex_to_int(int N, mwIndex *mwi_array)
template complex_t loadDataFromMatlab< complex_t >(const mxArray *mxa)
template int loadDataFromMatlab< int >(const mxArray *mxa)
template bool loadDataFromMatlab< bool >(const mxArray *mxa)
mxArray * createMatlabMultiVector< complex_t >(int numRows, int numCols)
template void processProvides< complex_t >(vector< RCP< MuemexArg >> &mexOutput, const Factory *factory, string &providesParam, Level &lvl)
void callMatlabNoArgs(std::string function)
std::complex< double > complex_t
mxArray * createMatlabMultiVector< double >(int numRows, int numCols)
template double loadDataFromMatlab< double >(const mxArray *mxa)
template void processProvides< double >(vector< RCP< MuemexArg >> &mexOutput, const Factory *factory, string &providesParam, Level &lvl)
std::vector< RCP< MuemexArg > > callMatlab(std::string function, int numOutputs, std::vector< RCP< MuemexArg >> args)
Teuchos::RCP< MuemexArg > convertMatlabVar(const mxArray *mxa)