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> > >;
41template class MuemexData<RCP<Tpetra::MultiVector<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
42template class MuemexData<RCP<Tpetra::MultiVector<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
43template class MuemexData<RCP<Xpetra::Vector<mm_LocalOrd, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
51 for (
int i = 0; i < N; i++)
52 rv[i] = (
int)mwi_array[i];
62 return mxCreateSparse(numRows, numCols, nnz, mxREAL);
67 return mxCreateSparse(numRows, numCols, nnz, mxCOMPLEX);
72 memcpy(mxGetPr(mxa), array, n *
sizeof(
double));
77 double* pr = mxGetPr(mxa);
78 double* pi = mxGetPi(mxa);
79 for (
int i = 0; i < n; i++) {
80 pr[i] = std::real<double>(array[i]);
81 pi[i] = std::imag<double>(array[i]);
90 int result = mexEvalString(function.c_str());
92 mexPrintf(
"An error occurred while running a MATLAB command.");
95std::vector<RCP<MuemexArg> >
callMatlab(std::string function,
int numOutputs, std::vector<RCP<MuemexArg> > args) {
96 using Teuchos::rcp_static_cast;
99 std::vector<RCP<MuemexArg> > output;
101 for (
int i = 0; i < int(args.size()); i++) {
103 switch (args[i]->type) {
105 matlabArgs[i] = rcp_static_cast<MuemexData<bool>,
MuemexArg>(args[i])->convertToMatlab();
108 matlabArgs[i] = rcp_static_cast<MuemexData<int>,
MuemexArg>(args[i])->convertToMatlab();
111 matlabArgs[i] = rcp_static_cast<MuemexData<double>,
MuemexArg>(args[i])->convertToMatlab();
114 matlabArgs[i] = rcp_static_cast<MuemexData<std::string>,
MuemexArg>(args[i])->convertToMatlab();
117 matlabArgs[i] = rcp_static_cast<MuemexData<complex_t>,
MuemexArg>(args[i])->convertToMatlab();
120 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Xpetra_map> >,
MuemexArg>(args[i])->convertToMatlab();
123 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Xpetra_ordinal_vector> >,
MuemexArg>(args[i])->convertToMatlab();
126 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Tpetra::MultiVector<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >,
MuemexArg>(args[i])->convertToMatlab();
129 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Tpetra::MultiVector<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >,
MuemexArg>(args[i])->convertToMatlab();
132 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Tpetra::CrsMatrix<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >,
MuemexArg>(args[i])->convertToMatlab();
135 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Tpetra::CrsMatrix<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >,
MuemexArg>(args[i])->convertToMatlab();
138 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Xpetra_Matrix_double> >,
MuemexArg>(args[i])->convertToMatlab();
141 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Xpetra_Matrix_complex> >,
MuemexArg>(args[i])->convertToMatlab();
144 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Xpetra_MultiVector_double> >,
MuemexArg>(args[i])->convertToMatlab();
147 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Xpetra_MultiVector_complex> >,
MuemexArg>(args[i])->convertToMatlab();
150 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<MAggregates> >,
MuemexArg>(args[i])->convertToMatlab();
153 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<MAmalInfo> >,
MuemexArg>(args[i])->convertToMatlab();
156 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<MGraph> >,
MuemexArg>(args[i])->convertToMatlab();
157#ifdef HAVE_MUELU_INTREPID2
158 case FIELDCONTAINER_ORDINAL:
159 matlabArgs[i] = rcp_static_cast<MuemexData<RCP<FieldContainer_ordinal> >,
MuemexArg>(args[i])->convertToMatlab();
163 }
catch (std::exception& e) {
164 mexPrintf(
"An error occurred while converting arg #%d to MATLAB:\n", i);
165 std::cout << e.what() << std::endl;
166 mexPrintf(
"Passing 0 instead.\n");
167 matlabArgs[i] = mxCreateDoubleScalar(0);
171 int result = mexCallMATLAB(numOutputs, matlabOutput, args.size(), matlabArgs, function.c_str());
173 mexPrintf(
"Matlab encountered an error while running command through muemexCallbacks.\n");
175 for (
int i = 0; i < numOutputs; i++) {
178 }
catch (std::exception& e) {
179 mexPrintf(
"An error occurred while converting output #%d from MATLAB:\n", i);
180 std::cout << e.what() << std::endl;
183 delete[] matlabOutput;
194 return mxCreateDoubleMatrix(numRows, numCols, mxREAL);
199 return mxCreateDoubleMatrix(numRows, numCols, mxCOMPLEX);
203 throw runtime_error(
"AmalgamationInfo not supported in MueMex yet.");
204 return mxCreateDoubleScalar(0);
208 bool isValidAggregates =
true;
209 if (!mxIsStruct(mxa))
211 int numFields = mxGetNumberOfFields(mxa);
213 isValidAggregates =
false;
214 if (isValidAggregates) {
215 const char* mem1 = mxGetFieldNameByNumber(mxa, 0);
216 if (mem1 == NULL || strcmp(mem1,
"nVertices") != 0)
217 isValidAggregates =
false;
218 const char* mem2 = mxGetFieldNameByNumber(mxa, 1);
219 if (mem2 == NULL || strcmp(mem2,
"nAggregates") != 0)
220 isValidAggregates =
false;
221 const char* mem3 = mxGetFieldNameByNumber(mxa, 2);
222 if (mem3 == NULL || strcmp(mem3,
"vertexToAggID") != 0)
223 isValidAggregates =
false;
224 const char* mem4 = mxGetFieldNameByNumber(mxa, 3);
225 if (mem3 == NULL || strcmp(mem4,
"rootNodes") != 0)
226 isValidAggregates =
false;
227 const char* mem5 = mxGetFieldNameByNumber(mxa, 4);
228 if (mem4 == NULL || strcmp(mem5,
"aggSizes") != 0)
229 isValidAggregates =
false;
231 return isValidAggregates;
235 bool isValidGraph =
true;
236 if (!mxIsStruct(mxa))
238 int numFields = mxGetNumberOfFields(mxa);
240 isValidGraph =
false;
242 const char* mem1 = mxGetFieldNameByNumber(mxa, 0);
243 if (mem1 == NULL || strcmp(mem1,
"edges") != 0)
244 isValidGraph =
false;
245 const char* mem2 = mxGetFieldNameByNumber(mxa, 1);
246 if (mem2 == NULL || strcmp(mem2,
"boundaryNodes") != 0)
247 isValidGraph =
false;
254 vector<string> rlist;
255 const char* delims =
",";
256 char* copy = (
char*)malloc(params.length() + 1);
257 strcpy(copy, params.c_str());
258 char* mark = (
char*)strtok(copy, delims);
259 while (mark != NULL) {
261 char* tail = mark + strlen(mark) - 1;
264 while (*tail ==
' ' && tail > mark)
269 rlist.push_back(tok);
270 mark = strtok(NULL, delims);
278 RCP<ParameterList> validParamList = rcp(
new ParameterList());
279 validParamList->set<RCP<const FactoryBase> >(
"A", Teuchos::null,
"Factory for the matrix A.");
280 validParamList->set<RCP<const FactoryBase> >(
"P", Teuchos::null,
"Factory for the prolongator.");
281 validParamList->set<RCP<const FactoryBase> >(
"R", Teuchos::null,
"Factory for the restrictor.");
282 validParamList->set<RCP<const FactoryBase> >(
"Ptent", Teuchos::null,
"Factory for the tentative (unsmoothed) prolongator.");
283 validParamList->set<RCP<const FactoryBase> >(
"Coordinates", Teuchos::null,
"Factory for the node coordinates.");
284 validParamList->set<RCP<const FactoryBase> >(
"Nullspace", Teuchos::null,
"Factory for the nullspace.");
285 validParamList->set<RCP<const FactoryBase> >(
"Aggregates", Teuchos::null,
"Factory for the aggregates.");
286 validParamList->set<RCP<const FactoryBase> >(
"UnamalgamationInfo", Teuchos::null,
"Factory for amalgamation.");
287#ifdef HAVE_MUELU_INTREPID2
288 validParamList->set<RCP<const FactoryBase> >(
"pcoarsen: element to node map", Teuchos::null,
"Generating factory of the element to node map");
290 return validParamList;
294 switch (mxGetClassID(mxa)) {
299 case mxLOGICAL_CLASS:
304 if (mxGetM(mxa) == 1 && mxGetN(mxa) == 1)
307 else if (mxGetM(mxa) != 1 || mxGetN(mxa) != 1)
309 return rcp_implicit_cast<MuemexArg>(rcp(
new MuemexData<RCP<Xpetra_ordinal_vector> >(mxa)));
311 throw std::runtime_error(
"Error: Don't know what to do with integer array.\n");
314 if (mxGetM(mxa) == 1 && mxGetN(mxa) == 1) {
315 if (mxIsComplex(mxa))
321 }
else if (mxIsSparse(mxa))
324 if (mxIsComplex(mxa))
326 return rcp_implicit_cast<MuemexArg>(rcp(
new MuemexData<RCP<Xpetra_Matrix_complex> >(mxa)));
329 return rcp_implicit_cast<MuemexArg>(rcp(
new MuemexData<RCP<Xpetra_Matrix_double> >(mxa)));
332 if (mxIsComplex(mxa))
333 return rcp_implicit_cast<MuemexArg>(rcp(
new MuemexData<RCP<Xpetra::MultiVector<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >(mxa)));
335 return rcp_implicit_cast<MuemexArg>(rcp(
new MuemexData<RCP<Xpetra::MultiVector<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >(mxa)));
338 case mxSTRUCT_CLASS: {
343 return rcp_implicit_cast<MuemexArg>(rcp(
new MuemexData<RCP<MAggregates> >(mxa)));
345 return rcp_implicit_cast<MuemexArg>(rcp(
new MuemexData<RCP<MGraph> >(mxa)));
347 throw runtime_error(
"Invalid aggregates or graph struct passed in from MATLAB.");
348 return Teuchos::null;
353 throw std::runtime_error(
"MATLAB returned an unsupported type as a function output.\n");
354 return Teuchos::null;
367template RCP<Xpetra_ordinal_vector> loadDataFromMatlab<RCP<Xpetra_ordinal_vector> >(
const mxArray* mxa);
368template RCP<Tpetra_MultiVector_double> loadDataFromMatlab<RCP<Tpetra_MultiVector_double> >(
const mxArray* mxa);
369template RCP<Tpetra_MultiVector_complex> loadDataFromMatlab<RCP<Tpetra_MultiVector_complex> >(
const mxArray* mxa);
370template RCP<Tpetra_CrsMatrix_double> loadDataFromMatlab<RCP<Tpetra_CrsMatrix_double> >(
const mxArray* mxa);
371template RCP<Tpetra_CrsMatrix_complex> loadDataFromMatlab<RCP<Tpetra_CrsMatrix_complex> >(
const mxArray* mxa);
372template RCP<Xpetra_Matrix_double> loadDataFromMatlab<RCP<Xpetra_Matrix_double> >(
const mxArray* mxa);
373template RCP<Xpetra_Matrix_complex> loadDataFromMatlab<RCP<Xpetra_Matrix_complex> >(
const mxArray* mxa);
374template RCP<Xpetra_MultiVector_double> loadDataFromMatlab<RCP<Xpetra_MultiVector_double> >(
const mxArray* mxa);
375template RCP<Xpetra_MultiVector_complex> loadDataFromMatlab<RCP<Xpetra_MultiVector_complex> >(
const mxArray* mxa);
376template RCP<MAggregates> loadDataFromMatlab<RCP<MAggregates> >(
const mxArray* mxa);
377template RCP<MAmalInfo> loadDataFromMatlab<RCP<MAmalInfo> >(
const mxArray* mxa);
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)