xref: /petsc/src/sys/classes/viewer/impls/matlab/vmatlab.c (revision 51b144c619aff302b570817d6f78637b8418d403)
1cc4c1da9SBarry Smith #include <petsc/private/viewerimpl.h> /*I    "petscviewer.h"   I*/
2cc4c1da9SBarry Smith #include <mat.h>                      /*I    "petscmat.h"      I*/
35c6c1daeSBarry Smith 
45c6c1daeSBarry Smith typedef struct {
55c6c1daeSBarry Smith   MATFile      *ep;
65c6c1daeSBarry Smith   PetscMPIInt   rank;
75c6c1daeSBarry Smith   PetscFileMode btype;
85c6c1daeSBarry Smith } PetscViewer_Matlab;
95c6c1daeSBarry Smith 
105d83a8b1SBarry Smith /*@
11811af0c4SBarry Smith   PetscViewerMatlabPutArray - Puts an array into the `PETSCVIEWERMATLAB` viewer.
125c6c1daeSBarry Smith 
1310450e9eSJacob Faibussowitsch   Not Collective, only processor zero saves `array`
145c6c1daeSBarry Smith 
155c6c1daeSBarry Smith   Input Parameters:
165c6c1daeSBarry Smith + mfile - the viewer
1720f4b53cSBarry Smith . m     - the first dimensions of `array`
1820f4b53cSBarry Smith . n     - the second dimensions of `array`
195c6c1daeSBarry Smith . array - the array (represented in one dimension)
203f423023SBarry Smith - name  - the MATLAB name of `array`
215c6c1daeSBarry Smith 
225c6c1daeSBarry Smith   Level: advanced
235c6c1daeSBarry Smith 
24811af0c4SBarry Smith   Note:
253f423023SBarry Smith   Only writes `array` values on processor 0.
265c6c1daeSBarry Smith 
27811af0c4SBarry Smith .seealso: `PETSCVIEWERMATLAB`, `PetscViewerMatlabGetArray()`
285c6c1daeSBarry Smith @*/
PetscViewerMatlabPutArray(PetscViewer mfile,int m,int n,const PetscScalar * array,const char * name)29d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerMatlabPutArray(PetscViewer mfile, int m, int n, const PetscScalar *array, const char *name)
30d71ae5a4SJacob Faibussowitsch {
312cb5e1ccSBarry Smith   PetscViewer_Matlab *ml;
325c6c1daeSBarry Smith   mxArray            *mat;
335c6c1daeSBarry Smith 
345c6c1daeSBarry Smith   PetscFunctionBegin;
3528b400f6SJacob Faibussowitsch   PetscCheck(mfile, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Null argument: probably PETSC_VIEWER_MATLAB_() failed");
362cb5e1ccSBarry Smith   ml = (PetscViewer_Matlab *)mfile->data;
375c6c1daeSBarry Smith   if (!ml->rank) {
389566063dSJacob Faibussowitsch     PetscCall(PetscInfo(mfile, "Putting MATLAB array %s\n", name));
395c6c1daeSBarry Smith #if !defined(PETSC_USE_COMPLEX)
405c6c1daeSBarry Smith     mat = mxCreateDoubleMatrix(m, n, mxREAL);
415c6c1daeSBarry Smith #else
425c6c1daeSBarry Smith     mat = mxCreateDoubleMatrix(m, n, mxCOMPLEX);
435c6c1daeSBarry Smith #endif
449566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(mxGetPr(mat), array, m * n));
455c6c1daeSBarry Smith     matPutVariable(ml->ep, name, mat);
465c6c1daeSBarry Smith 
479566063dSJacob Faibussowitsch     PetscCall(PetscInfo(mfile, "Put MATLAB array %s\n", name));
485c6c1daeSBarry Smith   }
493ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
505c6c1daeSBarry Smith }
515c6c1daeSBarry Smith 
PetscViewerMatlabPutVariable(PetscViewer viewer,const char * name,void * mat)52d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerMatlabPutVariable(PetscViewer viewer, const char *name, void *mat)
53d71ae5a4SJacob Faibussowitsch {
54a297a907SKarl Rupp   PetscViewer_Matlab *ml = (PetscViewer_Matlab *)viewer->data;
555c6c1daeSBarry Smith 
565c6c1daeSBarry Smith   PetscFunctionBegin;
575c6c1daeSBarry Smith   matPutVariable(ml->ep, name, (mxArray *)mat);
583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
595c6c1daeSBarry Smith }
605c6c1daeSBarry Smith 
615d83a8b1SBarry Smith /*@
62811af0c4SBarry Smith   PetscViewerMatlabGetArray - Gets a variable from a `PETSCVIEWERMATLAB` viewer into an array
635c6c1daeSBarry Smith 
645c6c1daeSBarry Smith   Not Collective; only processor zero reads in the array
655c6c1daeSBarry Smith 
665c6c1daeSBarry Smith   Input Parameters:
675c6c1daeSBarry Smith + mfile - the MATLAB file viewer
6820f4b53cSBarry Smith . m     - the first dimensions of `array`
6920f4b53cSBarry Smith . n     - the second dimensions of `array`
70f13dfd9eSBarry Smith . array - the array (represented in one dimension), must of be length `m` * `n`
713f423023SBarry Smith - name  - the MATLAB name of `array`
725c6c1daeSBarry Smith 
735c6c1daeSBarry Smith   Level: advanced
745c6c1daeSBarry Smith 
75811af0c4SBarry Smith   Note:
763f423023SBarry Smith   Only reads in `array` values on processor 0.
775c6c1daeSBarry Smith 
78811af0c4SBarry Smith .seealso: `PETSCVIEWERMATLAB`, `PetscViewerMatlabPutArray()`
795c6c1daeSBarry Smith @*/
PetscViewerMatlabGetArray(PetscViewer mfile,int m,int n,PetscScalar array[],const char * name)805d83a8b1SBarry Smith PetscErrorCode PetscViewerMatlabGetArray(PetscViewer mfile, int m, int n, PetscScalar array[], const char *name)
81d71ae5a4SJacob Faibussowitsch {
822cb5e1ccSBarry Smith   PetscViewer_Matlab *ml;
835c6c1daeSBarry Smith   mxArray            *mat;
845c6c1daeSBarry Smith 
855c6c1daeSBarry Smith   PetscFunctionBegin;
8628b400f6SJacob Faibussowitsch   PetscCheck(mfile, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Null argument: probably PETSC_VIEWER_MATLAB_() failed");
872cb5e1ccSBarry Smith   ml = (PetscViewer_Matlab *)mfile->data;
885c6c1daeSBarry Smith   if (!ml->rank) {
899566063dSJacob Faibussowitsch     PetscCall(PetscInfo(mfile, "Getting MATLAB array %s\n", name));
905c6c1daeSBarry Smith     mat = matGetVariable(ml->ep, name);
9128b400f6SJacob Faibussowitsch     PetscCheck(mat, PETSC_COMM_SELF, PETSC_ERR_LIB, "Unable to get array %s from matlab", name);
929566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(array, mxGetPr(mat), m * n));
939566063dSJacob Faibussowitsch     PetscCall(PetscInfo(mfile, "Got MATLAB array %s\n", name));
945c6c1daeSBarry Smith   }
953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
965c6c1daeSBarry Smith }
975c6c1daeSBarry Smith 
PetscViewerFileSetMode_Matlab(PetscViewer viewer,PetscFileMode type)9866976f2fSJacob Faibussowitsch static PetscErrorCode PetscViewerFileSetMode_Matlab(PetscViewer viewer, PetscFileMode type)
99d71ae5a4SJacob Faibussowitsch {
1005c6c1daeSBarry Smith   PetscViewer_Matlab *vmatlab = (PetscViewer_Matlab *)viewer->data;
1015c6c1daeSBarry Smith 
1025c6c1daeSBarry Smith   PetscFunctionBegin;
1035c6c1daeSBarry Smith   vmatlab->btype = type;
1043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1055c6c1daeSBarry Smith }
1065c6c1daeSBarry Smith 
1075c6c1daeSBarry Smith /*
1085c6c1daeSBarry Smith         Actually opens the file
1095c6c1daeSBarry Smith */
PetscViewerFileSetName_Matlab(PetscViewer viewer,const char name[])11066976f2fSJacob Faibussowitsch static PetscErrorCode PetscViewerFileSetName_Matlab(PetscViewer viewer, const char name[])
111d71ae5a4SJacob Faibussowitsch {
1125c6c1daeSBarry Smith   PetscViewer_Matlab *vmatlab = (PetscViewer_Matlab *)viewer->data;
1135c6c1daeSBarry Smith   PetscFileMode       type    = vmatlab->btype;
1145c6c1daeSBarry Smith 
1155c6c1daeSBarry Smith   PetscFunctionBegin;
116cc73adaaSBarry Smith   PetscCheck(type != (PetscFileMode)-1, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Must call PetscViewerFileSetMode() before PetscViewerFileSetName()");
1175c6c1daeSBarry Smith   if (vmatlab->ep) matClose(vmatlab->ep);
1185c6c1daeSBarry Smith 
1195c6c1daeSBarry Smith   /* only first processor opens file */
1205c6c1daeSBarry Smith   if (!vmatlab->rank) {
121a297a907SKarl Rupp     if (type == FILE_MODE_READ) vmatlab->ep = matOpen(name, "r");
1227e4fd573SVaclav Hapla     else if (type == FILE_MODE_WRITE) vmatlab->ep = matOpen(name, "w");
123f7d195e4SLawrence Mitchell     else {
124f7d195e4SLawrence Mitchell       PetscCheck(type != FILE_MODE_UNDEFINED, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ORDER, "Must call PetscViewerFileSetMode() before PetscViewerFileSetName()");
125f7d195e4SLawrence Mitchell       SETERRQ(PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Unsupported file mode %s", PetscFileModes[type]);
126f7d195e4SLawrence Mitchell     }
1275c6c1daeSBarry Smith   }
1283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1295c6c1daeSBarry Smith }
1305c6c1daeSBarry Smith 
PetscViewerDestroy_Matlab(PetscViewer v)13166976f2fSJacob Faibussowitsch static PetscErrorCode PetscViewerDestroy_Matlab(PetscViewer v)
132d71ae5a4SJacob Faibussowitsch {
1335c6c1daeSBarry Smith   PetscViewer_Matlab *vf = (PetscViewer_Matlab *)v->data;
1345c6c1daeSBarry Smith 
1355c6c1daeSBarry Smith   PetscFunctionBegin;
1365c6c1daeSBarry Smith   if (vf->ep) matClose(vf->ep);
1379566063dSJacob Faibussowitsch   PetscCall(PetscFree(vf));
1382e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)v, "PetscViewerFileSetName_C", NULL));
1392e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)v, "PetscViewerFileSetMode_C", NULL));
1403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1415c6c1daeSBarry Smith }
1425c6c1daeSBarry Smith 
1438556b5ebSBarry Smith /*MC
1448556b5ebSBarry Smith    PETSCVIEWERMATLAB - A viewer that saves the variables into a MATLAB .mat file that may be read into MATLAB
1458556b5ebSBarry Smith        with load('filename').
1468556b5ebSBarry Smith 
1478556b5ebSBarry Smith    Level: intermediate
1488556b5ebSBarry Smith 
149b0f901b8SJose E. Roman        Notes:
150b0f901b8SJose E. Roman              Currently can only save PETSc vectors to .mat files, not matrices (use the `PETSCVIEWERBINARY` and
1518556b5ebSBarry Smith              ${PETSC_DIR}/share/petsc/matlab/PetscBinaryRead.m to read matrices into MATLAB).
1528556b5ebSBarry Smith 
153811af0c4SBarry Smith              For parallel vectors obtained with `DMCreateGlobalVector()` or `DMGetGlobalVector()` the vectors are saved to
154811af0c4SBarry Smith              the .mat file in natural ordering. You can use DMView() to save the `DMDA` information to the .mat file
155b0f901b8SJose E. Roman              the fields in the MATLAB loaded da variable give the array dimensions so you can reshape the MATLAB
1568556b5ebSBarry Smith              vector to the same multidimensional shape as it had in PETSc for plotting etc. For example,
1578556b5ebSBarry Smith 
158b0f901b8SJose E. Roman              In your PETSc C/C++ code (assuming a two dimensional `DMDA` with one degree of freedom per node)
159b0f901b8SJose E. Roman .vb
160b0f901b8SJose E. Roman                 PetscObjectSetName((PetscObject)x,"x");
161b0f901b8SJose E. Roman                 VecView(x,PETSC_VIEWER_MATLAB_WORLD);
162b0f901b8SJose E. Roman                 PetscObjectSetName((PetscObject)da,"da");
163b0f901b8SJose E. Roman                 DMView(x,PETSC_VIEWER_MATLAB_WORLD);
164b0f901b8SJose E. Roman .ve
165b0f901b8SJose E. Roman              Then from MATLAB
166b0f901b8SJose E. Roman .vb
167b0f901b8SJose E. Roman                 load('matlaboutput.mat')   % matlaboutput.mat is the default filename
168b0f901b8SJose E. Roman                 xnew = zeros(da.n,da.m);
169b0f901b8SJose E. Roman                 xnew(:) = x;    % reshape one dimensional vector back to two dimensions
170b0f901b8SJose E. Roman .ve
1718556b5ebSBarry Smith 
1728556b5ebSBarry Smith               If you wish to put the same variable into the .mat file several times you need to give it a new
1738556b5ebSBarry Smith               name before each call to view.
1748556b5ebSBarry Smith 
175811af0c4SBarry Smith               Use `PetscViewerMatlabPutArray()` to just put an array of doubles into the .mat file
1768556b5ebSBarry Smith 
177c2e3fba1SPatrick Sanan .seealso: `PETSC_VIEWER_MATLAB_()`, `PETSC_VIEWER_MATLAB_SELF`, `PETSC_VIEWER_MATLAB_WORLD`, `PetscViewerCreate()`,
178db781477SPatrick Sanan           `PetscViewerMatlabOpen()`, `VecView()`, `DMView()`, `PetscViewerMatlabPutArray()`, `PETSCVIEWERBINARY`, `PETSCVIEWERASCII`, `PETSCVIEWERDRAW`,
179811af0c4SBarry Smith           `PETSC_VIEWER_STDOUT_()`, `PetscViewerFileSetName()`, `PetscViewerFileSetMode()`, `PetscViewerFormat`, `PetscMatlabEngine`
1808556b5ebSBarry Smith M*/
PetscViewerCreate_Matlab(PetscViewer viewer)181d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscViewerCreate_Matlab(PetscViewer viewer)
182d71ae5a4SJacob Faibussowitsch {
1835c6c1daeSBarry Smith   PetscViewer_Matlab *e;
1845c6c1daeSBarry Smith 
1855c6c1daeSBarry Smith   PetscFunctionBegin;
1864dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&e));
1879566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &e->rank));
1887e4fd573SVaclav Hapla   e->btype     = FILE_MODE_UNDEFINED;
1895c6c1daeSBarry Smith   viewer->data = (void *)e;
190a297a907SKarl Rupp 
1919566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetName_C", PetscViewerFileSetName_Matlab));
1929566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetMode_C", PetscViewerFileSetMode_Matlab));
193a297a907SKarl Rupp 
1945c6c1daeSBarry Smith   viewer->ops->destroy = PetscViewerDestroy_Matlab;
1953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1965c6c1daeSBarry Smith }
1975c6c1daeSBarry Smith 
198cc4c1da9SBarry Smith /*@
19921afe8ebSBarry Smith   PetscViewerMatlabOpen - Opens a MATLAB .mat file for output
2005c6c1daeSBarry Smith 
201d083f849SBarry Smith   Collective
2025c6c1daeSBarry Smith 
2035c6c1daeSBarry Smith   Input Parameters:
2045c6c1daeSBarry Smith + comm - MPI communicator
2055c6c1daeSBarry Smith . name - name of file
2065c6c1daeSBarry Smith - type - type of file
2073f423023SBarry Smith .vb
2083f423023SBarry Smith     FILE_MODE_WRITE - create new file for MATLAB output
2093f423023SBarry Smith     FILE_MODE_READ - open existing file for MATLAB input
2103f423023SBarry Smith     FILE_MODE_WRITE - open existing file for MATLAB output
2113f423023SBarry Smith .ve
2125c6c1daeSBarry Smith 
2135c6c1daeSBarry Smith   Output Parameter:
2145c6c1daeSBarry Smith . binv - PetscViewer for MATLAB output to use with the specified file
2155c6c1daeSBarry Smith 
2165c6c1daeSBarry Smith   Level: beginner
2175c6c1daeSBarry Smith 
218811af0c4SBarry Smith   Notes:
219811af0c4SBarry Smith   This `PetscViewer` should be destroyed with `PetscViewerDestroy()`.
2205c6c1daeSBarry Smith 
2215c6c1daeSBarry Smith   For writing files it only opens the file on processor 0 in the communicator.
2225c6c1daeSBarry Smith 
223811af0c4SBarry Smith   This only saves `Vec`s it cannot be used to save `Mat`s. We recommend using the `PETSCVIEWERBINARY` to save objects to be loaded into MATLAB
2245c6c1daeSBarry Smith   instead of this routine.
2255c6c1daeSBarry Smith 
2263f423023SBarry Smith   PETSc must be configured with the option `--with-matlab` for this functionality
227750b007cSBarry Smith 
228811af0c4SBarry Smith .seealso: `PETSCVIEWERMATLAB`, `PetscViewerASCIIOpen()`, `PetscViewerPushFormat()`, `PetscViewerDestroy()`, `PETSCVIEWERBINARY`, `PetscViewerBinaryOpen()`
229db781477SPatrick Sanan           `VecView()`, `MatView()`, `VecLoad()`, `MatLoad()`
2305c6c1daeSBarry Smith @*/
PetscViewerMatlabOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer * binv)231d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerMatlabOpen(MPI_Comm comm, const char name[], PetscFileMode type, PetscViewer *binv)
232d71ae5a4SJacob Faibussowitsch {
2335c6c1daeSBarry Smith   PetscFunctionBegin;
2349566063dSJacob Faibussowitsch   PetscCall(PetscViewerCreate(comm, binv));
2359566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetType(*binv, PETSCVIEWERMATLAB));
2369566063dSJacob Faibussowitsch   PetscCall(PetscViewerFileSetMode(*binv, type));
2379566063dSJacob Faibussowitsch   PetscCall(PetscViewerFileSetName(*binv, name));
2383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2395c6c1daeSBarry Smith }
2405c6c1daeSBarry Smith 
2415c6c1daeSBarry Smith static PetscMPIInt Petsc_Viewer_Matlab_keyval = MPI_KEYVAL_INVALID;
2425c6c1daeSBarry Smith 
2435c6c1daeSBarry Smith /*@C
244811af0c4SBarry Smith    PETSC_VIEWER_MATLAB_ - Creates a `PETSCVIEWERMATLAB` `PetscViewer` shared by all processors
2455c6c1daeSBarry Smith    in a communicator.
2465c6c1daeSBarry Smith 
247d083f849SBarry Smith    Collective
2485c6c1daeSBarry Smith 
2495c6c1daeSBarry Smith    Input Parameter:
25021afe8ebSBarry Smith .  comm - the MPI communicator to share the MATLAB `PetscViewer`
251811af0c4SBarry Smith 
252811af0c4SBarry Smith    Options Database Key:
25321afe8ebSBarry Smith .    -viewer_matlab_filename <name> - name of the MATLAB file
254811af0c4SBarry Smith 
255811af0c4SBarry Smith    Environmental variable:
25621afe8ebSBarry Smith .  `PETSC_VIEWER_MATLAB_FILENAME` - name of the MATLAB file
2575c6c1daeSBarry Smith 
2585c6c1daeSBarry Smith    Level: intermediate
2595c6c1daeSBarry Smith 
26034fa283eSBarry Smith    Notes:
26134fa283eSBarry Smith    This object is destroyed in `PetscFinalize()`, `PetscViewerDestroy()` should never be called on it
26234fa283eSBarry Smith 
263811af0c4SBarry Smith    Unlike almost all other PETSc routines, `PETSC_VIEWER_MATLAB_()` does not return
264a3b724e8SBarry Smith    an error code.  The MATLAB `PetscViewer` is usually used in the form `XXXView(XXX object, PETSC_VIEWER_MATLAB_(comm))`
2655c6c1daeSBarry Smith 
266811af0c4SBarry Smith    Use `PETSC_VIEWER_SOCKET_()` or `PetscViewerSocketOpen()` to communicator with an interactive MATLAB session.
2675c6c1daeSBarry Smith 
268db781477SPatrick Sanan .seealso: `PETSC_VIEWER_MATLAB_WORLD`, `PETSC_VIEWER_MATLAB_SELF`, `PetscViewerMatlabOpen()`, `PetscViewerCreate()`,
269db781477SPatrick Sanan           `PetscViewerDestroy()`
2705c6c1daeSBarry Smith @*/
PETSC_VIEWER_MATLAB_(MPI_Comm comm)271d71ae5a4SJacob Faibussowitsch PetscViewer PETSC_VIEWER_MATLAB_(MPI_Comm comm)
272d71ae5a4SJacob Faibussowitsch {
2735c6c1daeSBarry Smith   PetscBool   flg;
274*b8b5be36SMartin Diehl   PetscMPIInt iflg;
2755c6c1daeSBarry Smith   PetscViewer viewer;
2765c6c1daeSBarry Smith   char        fname[PETSC_MAX_PATH_LEN];
2775c6c1daeSBarry Smith   MPI_Comm    ncomm;
2785c6c1daeSBarry Smith 
2795c6c1daeSBarry Smith   PetscFunctionBegin;
280648c30bcSBarry Smith   PetscCallNull(PetscCommDuplicate(comm, &ncomm, NULL));
2813a7d0413SPierre Jolivet   if (Petsc_Viewer_Matlab_keyval == MPI_KEYVAL_INVALID) PetscCallMPINull(MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, MPI_COMM_NULL_DELETE_FN, &Petsc_Viewer_Matlab_keyval, 0));
282*b8b5be36SMartin Diehl   PetscCallMPINull(MPI_Comm_get_attr(ncomm, Petsc_Viewer_Matlab_keyval, (void **)&viewer, &iflg));
283*b8b5be36SMartin Diehl   if (!iflg) { /* PetscViewer not yet created */
284648c30bcSBarry Smith     PetscCallNull(PetscOptionsGetenv(ncomm, "PETSC_VIEWER_MATLAB_FILENAME", fname, PETSC_MAX_PATH_LEN, &flg));
2853a7d0413SPierre Jolivet     if (!flg) PetscCallNull(PetscStrncpy(fname, "matlaboutput.mat", sizeof(fname)));
286648c30bcSBarry Smith     PetscCallNull(PetscViewerMatlabOpen(ncomm, fname, FILE_MODE_WRITE, &viewer));
287648c30bcSBarry Smith     PetscCallNull(PetscObjectRegisterDestroy((PetscObject)viewer));
288648c30bcSBarry Smith     PetscCallMPINull(MPI_Comm_set_attr(ncomm, Petsc_Viewer_Matlab_keyval, (void *)viewer));
2899371c9d4SSatish Balay   }
290648c30bcSBarry Smith   PetscCallNull(PetscCommDestroy(&ncomm));
2915c6c1daeSBarry Smith   PetscFunctionReturn(viewer);
2925c6c1daeSBarry Smith }
293