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