xref: /petsc/src/sys/classes/viewer/impls/matlab/vmatlab.c (revision 5c6c1daec53e1d9ab0bec9db5309fd8fc7645b8d)
1*5c6c1daeSBarry Smith 
2*5c6c1daeSBarry Smith #include <petsc-private/viewerimpl.h>
3*5c6c1daeSBarry Smith #include <mat.h>
4*5c6c1daeSBarry Smith 
5*5c6c1daeSBarry Smith /*MC
6*5c6c1daeSBarry Smith    PETSCVIEWERMATLAB - A viewer that saves the variables into a MATLAB .mat file that may be read into MATLAB
7*5c6c1daeSBarry Smith        with load('filename').
8*5c6c1daeSBarry Smith 
9*5c6c1daeSBarry Smith    Level: intermediate
10*5c6c1daeSBarry Smith 
11*5c6c1daeSBarry Smith        Note: Currently can only save PETSc vectors to .mat files, not matrices (use the PETSCVIEWERBINARY and
12*5c6c1daeSBarry Smith              ${PETSC_DIR}/bin/matlab/PetscBinaryRead.m to read matrices into matlab).
13*5c6c1daeSBarry Smith 
14*5c6c1daeSBarry Smith              For parallel vectors obtained with DMCreateGlobalVector() or DMGetGlobalVector() the vectors are saved to
15*5c6c1daeSBarry Smith              the .mat file in natural ordering. You can use DMView() to save the DMDA information to the .mat file
16*5c6c1daeSBarry Smith              the fields in the MATLAB loaded da variable give the array dimensions so you can reshape the MATLAB
17*5c6c1daeSBarry Smith              vector to the same multidimensional shape as it had in PETSc for plotting etc. For example,
18*5c6c1daeSBarry Smith 
19*5c6c1daeSBarry Smith $             In your PETSc C/C++ code (assuming a two dimensional DMDA with one degree of freedom per node)
20*5c6c1daeSBarry Smith $                PetscObjectSetName((PetscObject)x,"x");
21*5c6c1daeSBarry Smith $                VecView(x,PETSC_VIEWER_MATLAB_WORLD);
22*5c6c1daeSBarry Smith $                PetscObjectSetName((PetscObject)da,"da");
23*5c6c1daeSBarry Smith $                DMView(x,PETSC_VIEWER_MATLAB_WORLD);
24*5c6c1daeSBarry Smith $             Then from MATLAB
25*5c6c1daeSBarry Smith $                load('matlaboutput.mat')   % matlaboutput.mat is the default filename
26*5c6c1daeSBarry Smith $                xnew = zeros(da.n,da.m);
27*5c6c1daeSBarry Smith $                xnew(:) = x;    % reshape one dimensional vector back to two dimensions
28*5c6c1daeSBarry Smith 
29*5c6c1daeSBarry Smith               If you wish to put the same variable into the .mat file several times you need to give it a new
30*5c6c1daeSBarry Smith               name before each call to view.
31*5c6c1daeSBarry Smith 
32*5c6c1daeSBarry Smith               Use PetscViewerMatlabPutArray() to just put an array of doubles into the .mat file
33*5c6c1daeSBarry Smith 
34*5c6c1daeSBarry Smith .seealso:  PETSC_VIEWER_MATLAB_(),PETSC_VIEWER_MATLAB_SELF(), PETSC_VIEWER_MATLAB_WORLD(),PetscViewerCreate(),
35*5c6c1daeSBarry Smith            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY,
36*5c6c1daeSBarry Smith            PETSC_ASCII_VIEWER, PetscViewerFileSetName(), PetscViewerFileSetMode()
37*5c6c1daeSBarry Smith 
38*5c6c1daeSBarry Smith M*/
39*5c6c1daeSBarry Smith 
40*5c6c1daeSBarry Smith typedef struct {
41*5c6c1daeSBarry Smith   MATFile       *ep;
42*5c6c1daeSBarry Smith   PetscMPIInt   rank;
43*5c6c1daeSBarry Smith   PetscFileMode btype;
44*5c6c1daeSBarry Smith } PetscViewer_Matlab;
45*5c6c1daeSBarry Smith 
46*5c6c1daeSBarry Smith #undef __FUNCT__
47*5c6c1daeSBarry Smith #define __FUNCT__ "PetscViewerMatlabPutArray"
48*5c6c1daeSBarry Smith /*@C
49*5c6c1daeSBarry Smith     PetscViewerMatlabPutArray - Puts an array into the MATLAB viewer.
50*5c6c1daeSBarry Smith 
51*5c6c1daeSBarry Smith       Not collective: only processor zero saves the array
52*5c6c1daeSBarry Smith 
53*5c6c1daeSBarry Smith     Input Parameters:
54*5c6c1daeSBarry Smith +    mfile - the viewer
55*5c6c1daeSBarry Smith .    m,n - the dimensions of the array
56*5c6c1daeSBarry Smith .    array - the array (represented in one dimension)
57*5c6c1daeSBarry Smith -    name - the name of the array
58*5c6c1daeSBarry Smith 
59*5c6c1daeSBarry Smith    Level: advanced
60*5c6c1daeSBarry Smith 
61*5c6c1daeSBarry Smith      Notes: Only writes array values on processor 0.
62*5c6c1daeSBarry Smith 
63*5c6c1daeSBarry Smith @*/
64*5c6c1daeSBarry Smith PetscErrorCode  PetscViewerMatlabPutArray(PetscViewer mfile,int m,int n,const PetscScalar *array,const char *name)
65*5c6c1daeSBarry Smith {
66*5c6c1daeSBarry Smith   PetscErrorCode     ierr;
67*5c6c1daeSBarry Smith   PetscViewer_Matlab *ml = (PetscViewer_Matlab*)mfile->data;
68*5c6c1daeSBarry Smith   mxArray            *mat;
69*5c6c1daeSBarry Smith 
70*5c6c1daeSBarry Smith   PetscFunctionBegin;
71*5c6c1daeSBarry Smith   if (!ml->rank) {
72*5c6c1daeSBarry Smith     ierr = PetscInfo1(mfile,"Putting MATLAB array %s\n",name);CHKERRQ(ierr);
73*5c6c1daeSBarry Smith #if !defined(PETSC_USE_COMPLEX)
74*5c6c1daeSBarry Smith     mat  = mxCreateDoubleMatrix(m,n,mxREAL);
75*5c6c1daeSBarry Smith #else
76*5c6c1daeSBarry Smith     mat  = mxCreateDoubleMatrix(m,n,mxCOMPLEX);
77*5c6c1daeSBarry Smith #endif
78*5c6c1daeSBarry Smith     ierr = PetscMemcpy(mxGetPr(mat),array,m*n*sizeof(PetscScalar));CHKERRQ(ierr);
79*5c6c1daeSBarry Smith     matPutVariable(ml->ep,name,mat);
80*5c6c1daeSBarry Smith 
81*5c6c1daeSBarry Smith     ierr = PetscInfo1(mfile,"Put MATLAB array %s\n",name);CHKERRQ(ierr);
82*5c6c1daeSBarry Smith   }
83*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
84*5c6c1daeSBarry Smith }
85*5c6c1daeSBarry Smith 
86*5c6c1daeSBarry Smith #undef __FUNCT__
87*5c6c1daeSBarry Smith #define __FUNCT__ "PetscViewerMatlabPutVariable"
88*5c6c1daeSBarry Smith PetscErrorCode  PetscViewerMatlabPutVariable(PetscViewer viewer,const char* name,void* mat)
89*5c6c1daeSBarry Smith {
90*5c6c1daeSBarry Smith   PetscViewer_Matlab *ml = (PetscViewer_Matlab*)viewer->data; ;
91*5c6c1daeSBarry Smith 
92*5c6c1daeSBarry Smith   PetscFunctionBegin;
93*5c6c1daeSBarry Smith   matPutVariable(ml->ep,name,(mxArray*)mat);
94*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
95*5c6c1daeSBarry Smith }
96*5c6c1daeSBarry Smith 
97*5c6c1daeSBarry Smith #undef __FUNCT__
98*5c6c1daeSBarry Smith #define __FUNCT__ "PetscViewerMatlabGetArray"
99*5c6c1daeSBarry Smith /*@C
100*5c6c1daeSBarry Smith     PetscViewerMatlabGetArray - Gets a variable from a MATLAB viewer into an array
101*5c6c1daeSBarry Smith 
102*5c6c1daeSBarry Smith     Not Collective; only processor zero reads in the array
103*5c6c1daeSBarry Smith 
104*5c6c1daeSBarry Smith     Input Parameters:
105*5c6c1daeSBarry Smith +    mfile - the MATLAB file viewer
106*5c6c1daeSBarry Smith .    m,n - the dimensions of the array
107*5c6c1daeSBarry Smith .    array - the array (represented in one dimension)
108*5c6c1daeSBarry Smith -    name - the name of the array
109*5c6c1daeSBarry Smith 
110*5c6c1daeSBarry Smith    Level: advanced
111*5c6c1daeSBarry Smith 
112*5c6c1daeSBarry Smith      Notes: Only reads in array values on processor 0.
113*5c6c1daeSBarry Smith 
114*5c6c1daeSBarry Smith @*/
115*5c6c1daeSBarry Smith PetscErrorCode  PetscViewerMatlabGetArray(PetscViewer mfile,int m,int n,PetscScalar *array,const char *name)
116*5c6c1daeSBarry Smith {
117*5c6c1daeSBarry Smith   PetscErrorCode     ierr;
118*5c6c1daeSBarry Smith   PetscViewer_Matlab *ml = (PetscViewer_Matlab*)mfile->data;
119*5c6c1daeSBarry Smith   mxArray            *mat;
120*5c6c1daeSBarry Smith 
121*5c6c1daeSBarry Smith   PetscFunctionBegin;
122*5c6c1daeSBarry Smith   if (!ml->rank) {
123*5c6c1daeSBarry Smith     ierr = PetscInfo1(mfile,"Getting MATLAB array %s\n",name);CHKERRQ(ierr);
124*5c6c1daeSBarry Smith     mat  = matGetVariable(ml->ep,name);
125*5c6c1daeSBarry Smith     if (!mat) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to get array %s from matlab",name);
126*5c6c1daeSBarry Smith     ierr = PetscMemcpy(array,mxGetPr(mat),m*n*sizeof(PetscScalar));CHKERRQ(ierr);
127*5c6c1daeSBarry Smith     ierr = PetscInfo1(mfile,"Got MATLAB array %s\n",name);CHKERRQ(ierr);
128*5c6c1daeSBarry Smith   }
129*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
130*5c6c1daeSBarry Smith }
131*5c6c1daeSBarry Smith 
132*5c6c1daeSBarry Smith EXTERN_C_BEGIN
133*5c6c1daeSBarry Smith #undef __FUNCT__
134*5c6c1daeSBarry Smith #define __FUNCT__ "PetscViewerFileSetMode_Matlab"
135*5c6c1daeSBarry Smith PetscErrorCode  PetscViewerFileSetMode_Matlab(PetscViewer viewer,PetscFileMode type)
136*5c6c1daeSBarry Smith {
137*5c6c1daeSBarry Smith   PetscViewer_Matlab *vmatlab = (PetscViewer_Matlab*)viewer->data;
138*5c6c1daeSBarry Smith 
139*5c6c1daeSBarry Smith   PetscFunctionBegin;
140*5c6c1daeSBarry Smith   vmatlab->btype = type;
141*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
142*5c6c1daeSBarry Smith }
143*5c6c1daeSBarry Smith EXTERN_C_END
144*5c6c1daeSBarry Smith 
145*5c6c1daeSBarry Smith /*
146*5c6c1daeSBarry Smith         Actually opens the file
147*5c6c1daeSBarry Smith */
148*5c6c1daeSBarry Smith EXTERN_C_BEGIN
149*5c6c1daeSBarry Smith #undef __FUNCT__
150*5c6c1daeSBarry Smith #define __FUNCT__ "PetscViewerFileSetName_Matlab"
151*5c6c1daeSBarry Smith PetscErrorCode  PetscViewerFileSetName_Matlab(PetscViewer viewer,const char name[])
152*5c6c1daeSBarry Smith {
153*5c6c1daeSBarry Smith   PetscViewer_Matlab  *vmatlab = (PetscViewer_Matlab*)viewer->data;
154*5c6c1daeSBarry Smith   PetscFileMode       type = vmatlab->btype;
155*5c6c1daeSBarry Smith 
156*5c6c1daeSBarry Smith   PetscFunctionBegin;
157*5c6c1daeSBarry Smith   if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode() before PetscViewerFileSetName()");
158*5c6c1daeSBarry Smith   if (vmatlab->ep) matClose(vmatlab->ep);
159*5c6c1daeSBarry Smith 
160*5c6c1daeSBarry Smith   /* only first processor opens file */
161*5c6c1daeSBarry Smith   if (!vmatlab->rank){
162*5c6c1daeSBarry Smith     if (type == FILE_MODE_READ){
163*5c6c1daeSBarry Smith       vmatlab->ep = matOpen(name,"r");
164*5c6c1daeSBarry Smith     } else if (type == FILE_MODE_WRITE || type == FILE_MODE_WRITE) {
165*5c6c1daeSBarry Smith       vmatlab->ep = matOpen(name,"w");
166*5c6c1daeSBarry Smith     } else {
167*5c6c1daeSBarry Smith       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
168*5c6c1daeSBarry Smith     }
169*5c6c1daeSBarry Smith   }
170*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
171*5c6c1daeSBarry Smith }
172*5c6c1daeSBarry Smith EXTERN_C_END
173*5c6c1daeSBarry Smith 
174*5c6c1daeSBarry Smith #undef __FUNCT__
175*5c6c1daeSBarry Smith #define __FUNCT__ "PetscViewerDestroy_Matlab"
176*5c6c1daeSBarry Smith PetscErrorCode PetscViewerDestroy_Matlab(PetscViewer v)
177*5c6c1daeSBarry Smith {
178*5c6c1daeSBarry Smith   PetscErrorCode     ierr;
179*5c6c1daeSBarry Smith   PetscViewer_Matlab *vf = (PetscViewer_Matlab*)v->data;
180*5c6c1daeSBarry Smith 
181*5c6c1daeSBarry Smith   PetscFunctionBegin;
182*5c6c1daeSBarry Smith   if (vf->ep) matClose(vf->ep);
183*5c6c1daeSBarry Smith   ierr = PetscFree(vf);CHKERRQ(ierr);
184*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
185*5c6c1daeSBarry Smith }
186*5c6c1daeSBarry Smith 
187*5c6c1daeSBarry Smith EXTERN_C_BEGIN
188*5c6c1daeSBarry Smith #undef __FUNCT__
189*5c6c1daeSBarry Smith #define __FUNCT__ "PetscViewerCreate_Matlab"
190*5c6c1daeSBarry Smith PetscErrorCode  PetscViewerCreate_Matlab(PetscViewer viewer)
191*5c6c1daeSBarry Smith {
192*5c6c1daeSBarry Smith   PetscErrorCode     ierr;
193*5c6c1daeSBarry Smith   PetscViewer_Matlab *e;
194*5c6c1daeSBarry Smith 
195*5c6c1daeSBarry Smith   PetscFunctionBegin;
196*5c6c1daeSBarry Smith   ierr         = PetscNewLog(viewer,PetscViewer_Matlab,&e);CHKERRQ(ierr);
197*5c6c1daeSBarry Smith   ierr         = MPI_Comm_rank(((PetscObject)viewer)->comm,&e->rank);CHKERRQ(ierr);
198*5c6c1daeSBarry Smith   e->btype     = (PetscFileMode)-1;
199*5c6c1daeSBarry Smith   viewer->data = (void*) e;
200*5c6c1daeSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_Matlab",
201*5c6c1daeSBarry Smith                                      PetscViewerFileSetName_Matlab);CHKERRQ(ierr);
202*5c6c1daeSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetMode_C","PetscViewerFileSetMode_Matlab",
203*5c6c1daeSBarry Smith                                      PetscViewerFileSetMode_Matlab);CHKERRQ(ierr);
204*5c6c1daeSBarry Smith   viewer->ops->destroy = PetscViewerDestroy_Matlab;
205*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
206*5c6c1daeSBarry Smith }
207*5c6c1daeSBarry Smith EXTERN_C_END
208*5c6c1daeSBarry Smith 
209*5c6c1daeSBarry Smith #undef __FUNCT__
210*5c6c1daeSBarry Smith #define __FUNCT__ "PetscViewerMatlabOpen"
211*5c6c1daeSBarry Smith /*@C
212*5c6c1daeSBarry Smith    PetscViewerMatlabOpen - Opens a Matlab .mat file for output
213*5c6c1daeSBarry Smith 
214*5c6c1daeSBarry Smith    Collective on MPI_Comm
215*5c6c1daeSBarry Smith 
216*5c6c1daeSBarry Smith    Input Parameters:
217*5c6c1daeSBarry Smith +  comm - MPI communicator
218*5c6c1daeSBarry Smith .  name - name of file
219*5c6c1daeSBarry Smith -  type - type of file
220*5c6c1daeSBarry Smith $    FILE_MODE_WRITE - create new file for MATLAB output
221*5c6c1daeSBarry Smith $    FILE_MODE_READ - open existing file for MATLAB input
222*5c6c1daeSBarry Smith $    FILE_MODE_WRITE - open existing file for MATLAB output
223*5c6c1daeSBarry Smith 
224*5c6c1daeSBarry Smith    Output Parameter:
225*5c6c1daeSBarry Smith .  binv - PetscViewer for MATLAB output to use with the specified file
226*5c6c1daeSBarry Smith 
227*5c6c1daeSBarry Smith    Level: beginner
228*5c6c1daeSBarry Smith 
229*5c6c1daeSBarry Smith    Note: This PetscViewer should be destroyed with PetscViewerDestroy().
230*5c6c1daeSBarry Smith 
231*5c6c1daeSBarry Smith     For writing files it only opens the file on processor 0 in the communicator.
232*5c6c1daeSBarry Smith 
233*5c6c1daeSBarry Smith      This only saves Vecs it cannot be used to save Mats. We recommend using the PETSCVIEWERBINARY to save objects to be loaded into MATLAB
234*5c6c1daeSBarry Smith      instead of this routine.
235*5c6c1daeSBarry Smith 
236*5c6c1daeSBarry Smith    Concepts: MATLAB .mat files
237*5c6c1daeSBarry Smith    Concepts: PetscViewerMatlab^creating
238*5c6c1daeSBarry Smith 
239*5c6c1daeSBarry Smith .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(), PETSCVIEWERBINARY, PetscViewerBinaryOpen()
240*5c6c1daeSBarry Smith           VecView(), MatView(), VecLoad(), MatLoad()
241*5c6c1daeSBarry Smith @*/
242*5c6c1daeSBarry Smith PetscErrorCode  PetscViewerMatlabOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv)
243*5c6c1daeSBarry Smith {
244*5c6c1daeSBarry Smith   PetscErrorCode ierr;
245*5c6c1daeSBarry Smith 
246*5c6c1daeSBarry Smith   PetscFunctionBegin;
247*5c6c1daeSBarry Smith   ierr = PetscViewerCreate(comm,binv);CHKERRQ(ierr);
248*5c6c1daeSBarry Smith   ierr = PetscViewerSetType(*binv,PETSCVIEWERMATLAB);CHKERRQ(ierr);
249*5c6c1daeSBarry Smith   ierr = PetscViewerFileSetMode(*binv,type);CHKERRQ(ierr);
250*5c6c1daeSBarry Smith   ierr = PetscViewerFileSetName(*binv,name);CHKERRQ(ierr);
251*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
252*5c6c1daeSBarry Smith }
253*5c6c1daeSBarry Smith 
254*5c6c1daeSBarry Smith static PetscMPIInt Petsc_Viewer_Matlab_keyval = MPI_KEYVAL_INVALID;
255*5c6c1daeSBarry Smith 
256*5c6c1daeSBarry Smith #undef __FUNCT__
257*5c6c1daeSBarry Smith #define __FUNCT__ "PETSC_VIEWER_MATLAB_"
258*5c6c1daeSBarry Smith /*@C
259*5c6c1daeSBarry Smith      PETSC_VIEWER_MATLAB_ - Creates a Matlab PetscViewer shared by all processors
260*5c6c1daeSBarry Smith                      in a communicator.
261*5c6c1daeSBarry Smith 
262*5c6c1daeSBarry Smith      Collective on MPI_Comm
263*5c6c1daeSBarry Smith 
264*5c6c1daeSBarry Smith      Input Parameter:
265*5c6c1daeSBarry Smith .    comm - the MPI communicator to share the Matlab PetscViewer
266*5c6c1daeSBarry Smith 
267*5c6c1daeSBarry Smith      Level: intermediate
268*5c6c1daeSBarry Smith 
269*5c6c1daeSBarry Smith    Options Database Keys:
270*5c6c1daeSBarry Smith $    -viewer_matlab_filename <name>
271*5c6c1daeSBarry Smith 
272*5c6c1daeSBarry Smith    Environmental variables:
273*5c6c1daeSBarry Smith -   PETSC_VIEWER_MATLAB_FILENAME
274*5c6c1daeSBarry Smith 
275*5c6c1daeSBarry Smith      Notes:
276*5c6c1daeSBarry Smith      Unlike almost all other PETSc routines, PETSC_VIEWER_MATLAB_ does not return
277*5c6c1daeSBarry Smith      an error code.  The matlab PetscViewer is usually used in the form
278*5c6c1daeSBarry Smith $       XXXView(XXX object,PETSC_VIEWER_MATLAB_(comm));
279*5c6c1daeSBarry Smith 
280*5c6c1daeSBarry Smith      Use PETSC_VIEWER_SOCKET_() or PetscViewerSocketOpen() to communicator with an interactive MATLAB session.
281*5c6c1daeSBarry Smith 
282*5c6c1daeSBarry Smith .seealso: PETSC_VIEWER_MATLAB_WORLD, PETSC_VIEWER_MATLAB_SELF, PetscViewerMatlabOpen(), PetscViewerCreate(),
283*5c6c1daeSBarry Smith           PetscViewerDestroy()
284*5c6c1daeSBarry Smith @*/
285*5c6c1daeSBarry Smith PetscViewer  PETSC_VIEWER_MATLAB_(MPI_Comm comm)
286*5c6c1daeSBarry Smith {
287*5c6c1daeSBarry Smith   PetscErrorCode ierr;
288*5c6c1daeSBarry Smith   PetscBool      flg;
289*5c6c1daeSBarry Smith   PetscViewer    viewer;
290*5c6c1daeSBarry Smith   char           fname[PETSC_MAX_PATH_LEN];
291*5c6c1daeSBarry Smith   MPI_Comm       ncomm;
292*5c6c1daeSBarry Smith 
293*5c6c1daeSBarry Smith   PetscFunctionBegin;
294*5c6c1daeSBarry Smith   ierr = PetscCommDuplicate(comm,&ncomm,PETSC_NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
295*5c6c1daeSBarry Smith   if (Petsc_Viewer_Matlab_keyval == MPI_KEYVAL_INVALID) {
296*5c6c1daeSBarry Smith     ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Matlab_keyval,0);
297*5c6c1daeSBarry Smith     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
298*5c6c1daeSBarry Smith   }
299*5c6c1daeSBarry Smith   ierr = MPI_Attr_get(ncomm,Petsc_Viewer_Matlab_keyval,(void **)&viewer,(int*)&flg);
300*5c6c1daeSBarry Smith   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
301*5c6c1daeSBarry Smith   if (!flg) { /* PetscViewer not yet created */
302*5c6c1daeSBarry Smith     ierr = PetscOptionsGetenv(ncomm,"PETSC_VIEWER_MATLAB_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
303*5c6c1daeSBarry Smith     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
304*5c6c1daeSBarry Smith     if (!flg) {
305*5c6c1daeSBarry Smith       ierr = PetscStrcpy(fname,"matlaboutput.mat");
306*5c6c1daeSBarry Smith       if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
307*5c6c1daeSBarry Smith     }
308*5c6c1daeSBarry Smith     ierr = PetscViewerMatlabOpen(ncomm,fname,FILE_MODE_WRITE,&viewer);
309*5c6c1daeSBarry Smith     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
310*5c6c1daeSBarry Smith     ierr = PetscObjectRegisterDestroy((PetscObject)viewer);
311*5c6c1daeSBarry Smith     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
312*5c6c1daeSBarry Smith     ierr = MPI_Attr_put(ncomm,Petsc_Viewer_Matlab_keyval,(void*)viewer);
313*5c6c1daeSBarry Smith     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
314*5c6c1daeSBarry Smith   }
315*5c6c1daeSBarry Smith   ierr = PetscCommDestroy(&ncomm);
316*5c6c1daeSBarry Smith   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
317*5c6c1daeSBarry Smith   PetscFunctionReturn(viewer);
318*5c6c1daeSBarry Smith }
319*5c6c1daeSBarry Smith 
320*5c6c1daeSBarry Smith 
321*5c6c1daeSBarry Smith 
322*5c6c1daeSBarry Smith 
323*5c6c1daeSBarry Smith 
324