12#if !defined(HAVE_MUELU_MATLAB) || !defined(HAVE_MUELU_TPETRA)
13#error "Muemex types require MATLAB and Tpetra."
17#if (defined(MX_API_VER) && MX_API_VER >= 0x07030000)
28template class MuemexData<RCP<Xpetra::MultiVector<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
29template class MuemexData<RCP<Xpetra::MultiVector<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
30template class MuemexData<RCP<Xpetra::Matrix<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
31template class MuemexData<RCP<Xpetra::Matrix<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
32template class MuemexData<RCP<MAggregates> >;
33template class MuemexData<RCP<MAmalInfo> >;
34template class MuemexData<int>;
35template class MuemexData<bool>;
36template class MuemexData<complex_t>;
37template class MuemexData<string>;
38template class MuemexData<double>;
39template class MuemexData<RCP<Tpetra::CrsMatrix<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
40template class MuemexData<RCP<Tpetra::CrsMatrix<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
41#ifdef HAVE_MUELU_EPETRA
42template class MuemexData<RCP<Epetra_MultiVector> >;
44template class MuemexData<RCP<Tpetra::MultiVector<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
45template class MuemexData<RCP<Tpetra::MultiVector<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
46template class MuemexData<RCP<Xpetra::Vector<mm_LocalOrd, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
54 for (
int i = 0; i < N; i++)
55 rv[i] = (
int)mwi_array[i];
65 return mxCreateSparse(numRows, numCols, nnz, mxREAL);
70 return mxCreateSparse(numRows, numCols, nnz, mxCOMPLEX);
75 memcpy(mxGetPr(mxa), array, n *
sizeof(
double));
80 double* pr = mxGetPr(mxa);
81 double* pi = mxGetPi(mxa);
82 for (
int i = 0; i < n; i++) {
83 pr[i] = std::real<double>(array[i]);
84 pi[i] = std::imag<double>(array[i]);
93 int result = mexEvalString(function.c_str());
95 mexPrintf(
"An error occurred while running a MATLAB command.");
98std::vector<RCP<MuemexArg> >
callMatlab(std::string function,
int numOutputs, std::vector<RCP<MuemexArg> > args) {
99 using Teuchos::rcp_static_cast;
102 std::vector<RCP<MuemexArg> > output;
104 for (
int i = 0; i < int(args.size()); i++) {
106 switch (args[i]->type) {
108 matlabArgs[i] = rcp_static_cast<MuemexData<bool>,
MuemexArg>(args[i])->convertToMatlab();
111 matlabArgs[i] = rcp_static_cast<MuemexData<int>,
MuemexArg>(args[i])->convertToMatlab();
114 matlabArgs[i] = rcp_static_cast<MuemexData<double>,
MuemexArg>(args[i])->convertToMatlab();
117 matlabArgs[i] = rcp_static_cast<MuemexData<std::string>,
MuemexArg>(args[i])->convertToMatlab();
120 matlabArgs[i] = rcp_static_cast<MuemexData<complex_t>,
MuemexArg>(args[i])->convertToMatlab();
123 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Xpetra_map> >,
MuemexArg>(args[i])->convertToMatlab();
126 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Xpetra_ordinal_vector> >,
MuemexArg>(args[i])->convertToMatlab();
129 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Tpetra::MultiVector<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >,
MuemexArg>(args[i])->convertToMatlab();
132 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Tpetra::MultiVector<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >,
MuemexArg>(args[i])->convertToMatlab();
135 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Tpetra::CrsMatrix<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >,
MuemexArg>(args[i])->convertToMatlab();
138 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Tpetra::CrsMatrix<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >,
MuemexArg>(args[i])->convertToMatlab();
141 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Xpetra_Matrix_double> >,
MuemexArg>(args[i])->convertToMatlab();
144 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Xpetra_Matrix_complex> >,
MuemexArg>(args[i])->convertToMatlab();
147 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Xpetra_MultiVector_double> >,
MuemexArg>(args[i])->convertToMatlab();
150 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Xpetra_MultiVector_complex> >,
MuemexArg>(args[i])->convertToMatlab();
152#ifdef HAVE_MUELU_EPETRA
154 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Epetra_CrsMatrix> >,
MuemexArg>(args[i])->convertToMatlab();
157 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Epetra_MultiVector> >,
MuemexArg>(args[i])->convertToMatlab();
161 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<MAggregates> >,
MuemexArg>(args[i])->convertToMatlab();
164 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<MAmalInfo> >,
MuemexArg>(args[i])->convertToMatlab();
167 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<MGraph> >,
MuemexArg>(args[i])->convertToMatlab();
168#ifdef HAVE_MUELU_INTREPID2
169 case FIELDCONTAINER_ORDINAL:
170 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<FieldContainer_ordinal> >,
MuemexArg>(args[i])->convertToMatlab();
174 }
catch (std::exception& e) {
175 mexPrintf(
"An error occurred while converting arg #%d to MATLAB:\n", i);
176 std::cout << e.what() << std::endl;
177 mexPrintf(
"Passing 0 instead.\n");
178 matlabArgs[i] = mxCreateDoubleScalar(0);
182 int result = mexCallMATLAB(numOutputs, matlabOutput, args.size(), matlabArgs, function.c_str());
184 mexPrintf(
"Matlab encountered an error while running command through muemexCallbacks.\n");
186 for (
int i = 0; i < numOutputs; i++) {
189 }
catch (std::exception& e) {
190 mexPrintf(
"An error occurred while converting output #%d from MATLAB:\n", i);
191 std::cout << e.what() << std::endl;
194 delete[] matlabOutput;
205 return mxCreateDoubleMatrix(numRows, numCols, mxREAL);
210 return mxCreateDoubleMatrix(numRows, numCols, mxCOMPLEX);
214 throw runtime_error(
"AmalgamationInfo not supported in MueMex yet.");
215 return mxCreateDoubleScalar(0);
219 bool isValidAggregates =
true;
220 if (!mxIsStruct(mxa))
222 int numFields = mxGetNumberOfFields(mxa);
224 isValidAggregates =
false;
225 if (isValidAggregates) {
226 const char* mem1 = mxGetFieldNameByNumber(mxa, 0);
227 if (mem1 == NULL || strcmp(mem1,
"nVertices") != 0)
228 isValidAggregates =
false;
229 const char* mem2 = mxGetFieldNameByNumber(mxa, 1);
230 if (mem2 == NULL || strcmp(mem2,
"nAggregates") != 0)
231 isValidAggregates =
false;
232 const char* mem3 = mxGetFieldNameByNumber(mxa, 2);
233 if (mem3 == NULL || strcmp(mem3,
"vertexToAggID") != 0)
234 isValidAggregates =
false;
235 const char* mem4 = mxGetFieldNameByNumber(mxa, 3);
236 if (mem3 == NULL || strcmp(mem4,
"rootNodes") != 0)
237 isValidAggregates =
false;
238 const char* mem5 = mxGetFieldNameByNumber(mxa, 4);
239 if (mem4 == NULL || strcmp(mem5,
"aggSizes") != 0)
240 isValidAggregates =
false;
242 return isValidAggregates;
246 bool isValidGraph =
true;
247 if (!mxIsStruct(mxa))
249 int numFields = mxGetNumberOfFields(mxa);
251 isValidGraph =
false;
253 const char* mem1 = mxGetFieldNameByNumber(mxa, 0);
254 if (mem1 == NULL || strcmp(mem1,
"edges") != 0)
255 isValidGraph =
false;
256 const char* mem2 = mxGetFieldNameByNumber(mxa, 1);
257 if (mem2 == NULL || strcmp(mem2,
"boundaryNodes") != 0)
258 isValidGraph =
false;
265 vector<string> rlist;
266 const char* delims =
",";
267 char* copy = (
char*)malloc(params.length() + 1);
268 strcpy(copy, params.c_str());
269 char* mark = (
char*)strtok(copy, delims);
270 while (mark != NULL) {
272 char* tail = mark + strlen(mark) - 1;
275 while (*tail ==
' ' && tail > mark)
280 rlist.push_back(tok);
281 mark = strtok(NULL, delims);
289 RCP<ParameterList> validParamList = rcp(
new ParameterList());
290 validParamList->set<RCP<const FactoryBase> >(
"A", Teuchos::null,
"Factory for the matrix A.");
291 validParamList->set<RCP<const FactoryBase> >(
"P", Teuchos::null,
"Factory for the prolongator.");
292 validParamList->set<RCP<const FactoryBase> >(
"R", Teuchos::null,
"Factory for the restrictor.");
293 validParamList->set<RCP<const FactoryBase> >(
"Ptent", Teuchos::null,
"Factory for the tentative (unsmoothed) prolongator.");
294 validParamList->set<RCP<const FactoryBase> >(
"Coordinates", Teuchos::null,
"Factory for the node coordinates.");
295 validParamList->set<RCP<const FactoryBase> >(
"Nullspace", Teuchos::null,
"Factory for the nullspace.");
296 validParamList->set<RCP<const FactoryBase> >(
"Aggregates", Teuchos::null,
"Factory for the aggregates.");
297 validParamList->set<RCP<const FactoryBase> >(
"UnamalgamationInfo", Teuchos::null,
"Factory for amalgamation.");
298#ifdef HAVE_MUELU_INTREPID2
299 validParamList->set<RCP<const FactoryBase> >(
"pcoarsen: element to node map", Teuchos::null,
"Generating factory of the element to node map");
301 return validParamList;
305 switch (mxGetClassID(mxa)) {
310 case mxLOGICAL_CLASS:
315 if (mxGetM(mxa) == 1 && mxGetN(mxa) == 1)
318 else if (mxGetM(mxa) != 1 || mxGetN(mxa) != 1)
320 return rcp_implicit_cast<MuemexArg>(rcp(
new MuemexData<RCP<Xpetra_ordinal_vector> >(mxa)));
322 throw std::runtime_error(
"Error: Don't know what to do with integer array.\n");
325 if (mxGetM(mxa) == 1 && mxGetN(mxa) == 1) {
326 if (mxIsComplex(mxa))
332 }
else if (mxIsSparse(mxa))
335 if (mxIsComplex(mxa))
337 return rcp_implicit_cast<MuemexArg>(rcp(
new MuemexData<RCP<Xpetra_Matrix_complex> >(mxa)));
340 return rcp_implicit_cast<MuemexArg>(rcp(
new MuemexData<RCP<Xpetra_Matrix_double> >(mxa)));
343 if (mxIsComplex(mxa))
344 return rcp_implicit_cast<MuemexArg>(rcp(
new MuemexData<RCP<Xpetra::MultiVector<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >(mxa)));
346 return rcp_implicit_cast<MuemexArg>(rcp(
new MuemexData<RCP<Xpetra::MultiVector<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >(mxa)));
349 case mxSTRUCT_CLASS: {
354 return rcp_implicit_cast<MuemexArg>(rcp(
new MuemexData<RCP<MAggregates> >(mxa)));
356 return rcp_implicit_cast<MuemexArg>(rcp(
new MuemexData<RCP<MGraph> >(mxa)));
358 throw runtime_error(
"Invalid aggregates or graph struct passed in from MATLAB.");
359 return Teuchos::null;
364 throw std::runtime_error(
"MATLAB returned an unsupported type as a function output.\n");
365 return Teuchos::null;
378template RCP<Xpetra_ordinal_vector> loadDataFromMatlab<RCP<Xpetra_ordinal_vector> >(
const mxArray* mxa);
379template RCP<Tpetra_MultiVector_double> loadDataFromMatlab<RCP<Tpetra_MultiVector_double> >(
const mxArray* mxa);
380template RCP<Tpetra_MultiVector_complex> loadDataFromMatlab<RCP<Tpetra_MultiVector_complex> >(
const mxArray* mxa);
381template RCP<Tpetra_CrsMatrix_double> loadDataFromMatlab<RCP<Tpetra_CrsMatrix_double> >(
const mxArray* mxa);
382template RCP<Tpetra_CrsMatrix_complex> loadDataFromMatlab<RCP<Tpetra_CrsMatrix_complex> >(
const mxArray* mxa);
383template RCP<Xpetra_Matrix_double> loadDataFromMatlab<RCP<Xpetra_Matrix_double> >(
const mxArray* mxa);
384template RCP<Xpetra_Matrix_complex> loadDataFromMatlab<RCP<Xpetra_Matrix_complex> >(
const mxArray* mxa);
385template RCP<Xpetra_MultiVector_double> loadDataFromMatlab<RCP<Xpetra_MultiVector_double> >(
const mxArray* mxa);
386template RCP<Xpetra_MultiVector_complex> loadDataFromMatlab<RCP<Xpetra_MultiVector_complex> >(
const mxArray* mxa);
387#ifdef HAVE_MUELU_EPETRA
388template RCP<Epetra_CrsMatrix> loadDataFromMatlab<RCP<Epetra_CrsMatrix> >(
const mxArray* mxa);
389template RCP<Epetra_MultiVector> loadDataFromMatlab<RCP<Epetra_MultiVector> >(
const mxArray* mxa);
391template RCP<MAggregates> loadDataFromMatlab<RCP<MAggregates> >(
const mxArray* mxa);
392template RCP<MAmalInfo> loadDataFromMatlab<RCP<MAmalInfo> >(
const mxArray* mxa);
408#ifdef HAVE_MUELU_EPETRA
struct mxArray_tag mxArray
Class that holds all level-specific information.
Namespace for MueLu classes and methods.
template int loadDataFromMatlab< int >(const mxArray *mxa)
bool isValidMatlabGraph(const mxArray *mxa)
Teuchos::RCP< Teuchos::ParameterList > getInputParamList()
Teuchos::RCP< MuemexArg > convertMatlabVar(const mxArray *mxa)
template double loadDataFromMatlab< double >(const mxArray *mxa)
mxArray * createMatlabSparse< double >(int numRows, int numCols, int nnz)
template bool loadDataFromMatlab< bool >(const mxArray *mxa)
template vector< RCP< MuemexArg > > processNeeds< double >(const Factory *factory, string &needsParam, Level &lvl)
bool isValidMatlabAggregates(const mxArray *mxa)
std::vector< RCP< MuemexArg > > callMatlab(std::string function, int numOutputs, std::vector< RCP< MuemexArg > > args)
template string loadDataFromMatlab< string >(const mxArray *mxa)
template complex_t loadDataFromMatlab< complex_t >(const mxArray *mxa)
@ XPETRA_MULTIVECTOR_DOUBLE
@ XPETRA_MULTIVECTOR_COMPLEX
@ TPETRA_MULTIVECTOR_COMPLEX
@ TPETRA_MULTIVECTOR_DOUBLE
int * mwIndex_to_int(int N, mwIndex *mwi_array)
void fillMatlabArray< double >(double *array, const mxArray *mxa, int n)
template void processProvides< double >(vector< RCP< MuemexArg > > &mexOutput, const Factory *factory, string &providesParam, Level &lvl)
mxArray * saveAmalInfo(RCP< MAmalInfo > &amalInfo)
template void processProvides< complex_t >(vector< RCP< MuemexArg > > &mexOutput, const Factory *factory, string &providesParam, Level &lvl)
void fillMatlabArray< complex_t >(complex_t *array, const mxArray *mxa, int n)
mxArray * createMatlabMultiVector< complex_t >(int numRows, int numCols)
std::complex< double > complex_t
std::vector< std::string > tokenizeList(const std::string ¶ms)
mxArray * createMatlabSparse< complex_t >(int numRows, int numCols, int nnz)
void callMatlabNoArgs(std::string function)
mxArray * createMatlabMultiVector< double >(int numRows, int numCols)
template vector< RCP< MuemexArg > > processNeeds< complex_t >(const Factory *factory, string &needsParam, Level &lvl)
template mxArray * saveDataToMatlab(bool &data)