Actual source code: vmatlab.c
2: #include src/sys/src/viewer/viewerimpl.h
3: #include "mat.h"
5: /*MC
6: PETSC_VIEWER_MATLAB - 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 PETSC_VIEWER_BINARY and
12: ${PETSC_DIR}/bin/matlab/PetscReadBinary.m to read matrices into matlab).
14: For parallel vectors obtained with DACreateGlobalVector() or DAGetGlobalVector() the vectors are saved to
15: the .mat file in natural ordering. You can use DAView() to save the DA 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 DA 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: $ DAView(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(), DAView(), PetscViewerMatlabPutArray(), PETSC_VIEWER_BINARY,
36: PETSC_ASCII_VIEWER, DAView(), PetscViewerSetFilename(), PetscViewerSetFileType()
38: M*/
40: typedef struct {
41: MATFile *ep;
42: PetscMPIInt rank;
43: PetscViewerFileType 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,PetscScalar *array,char *name)
65: {
66: PetscErrorCode ierr;
67: PetscViewer_Matlab *ml = (PetscViewer_Matlab*)mfile->data;
68: mxArray *mat;
69:
71: if (!ml->rank) {
72: PetscLogInfo(0,"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: PetscLogInfo(0,"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,char *name)
116: {
117: PetscErrorCode ierr;
118: PetscViewer_Matlab *ml = (PetscViewer_Matlab*)mfile->data;
119: mxArray *mat;
120:
122: if (!ml->rank) {
123: PetscLogInfo(0,"Getting Matlab array %s\n",name);
124: mat = matGetVariable(ml->ep,name);
125: if (!mat) SETERRQ1(PETSC_ERR_LIB,"Unable to get array %s from matlab",name);
126: PetscMemcpy(array,mxGetPr(mat),m*n*sizeof(PetscScalar));
127: PetscLogInfo(0,"Got Matlab array %s\n",name);
128: }
129: return(0);
130: }
135: PetscErrorCode PetscViewerSetFileType_Matlab(PetscViewer viewer,PetscViewerFileType type)
136: {
137: PetscViewer_Matlab *vmatlab = (PetscViewer_Matlab*)viewer->data;
140: vmatlab->btype = type;
141: return(0);
142: }
145: /*
146: Actually opens the file
147: */
151: PetscErrorCode PetscViewerSetFilename_Matlab(PetscViewer viewer,const char name[])
152: {
153: PetscViewer_Matlab *vmatlab = (PetscViewer_Matlab*)viewer->data;
154: PetscViewerFileType type = vmatlab->btype;
157: if (type == (PetscViewerFileType) -1) {
158: SETERRQ(PETSC_ERR_ORDER,"Must call PetscViewerSetFileType() before PetscViewerSetFilename()");
159: }
161: /* only first processor opens file */
162: if (!vmatlab->rank){
163: if (type == PETSC_FILE_RDONLY){
164: vmatlab->ep = matOpen(name,"r");
165: }
166: if (type == PETSC_FILE_CREATE || type == PETSC_FILE_WRONLY) {
167: vmatlab->ep = matOpen(name,"w");
168: } else {
169: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
170: }
171: }
172: return(0);
173: }
178: PetscErrorCode PetscViewerDestroy_Matlab(PetscViewer v)
179: {
180: PetscErrorCode ierr;
181: PetscViewer_Matlab *vf = (PetscViewer_Matlab*)v->data;
184: if (vf->ep) matClose(vf->ep);
185: PetscFree(vf);
186: return(0);
187: }
192: PetscErrorCode PetscViewerCreate_Matlab(PetscViewer viewer)
193: {
194: PetscErrorCode ierr;
195: PetscViewer_Matlab *e;
198: PetscNew(PetscViewer_Matlab,&e);
199: MPI_Comm_rank(viewer->comm,&e->rank);
200: e->btype = (PetscViewerFileType)-1;
201: viewer->data = (void*) e;
202: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerSetFilename_C","PetscViewerSetFilename_Matlab",
203: PetscViewerSetFilename_Matlab);
204: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerSetFileType_C","PetscViewerSetFileType_Matlab",
205: PetscViewerSetFileType_Matlab);
206: viewer->ops->destroy = PetscViewerDestroy_Matlab;
207: return(0);
208: }
213: /*@C
214: PetscViewerMatlabOpen - Opens a Matlab .mat file for input or output.
216: Collective on MPI_Comm
218: Input Parameters:
219: + comm - MPI communicator
220: . name - name of file
221: - type - type of file
222: $ PETSC_FILE_CREATE - create new file for Matlab output
223: $ PETSC_FILE_RDONLY - open existing file for Matlab input
224: $ PETSC_FILE_WRONLY - open existing file for Matlab output
226: Output Parameter:
227: . binv - PetscViewer for Matlab input/output to use with the specified file
229: Level: beginner
231: Note:
232: This PetscViewer should be destroyed with PetscViewerDestroy().
234: For writing files it only opens the file on processor 0 in the communicator.
235: For readable files it opens the file on all nodes that have the file. If
236: node 0 does not have the file it generates an error even if other nodes
237: do have the file.
239: Concepts: Matlab .mat files
240: Concepts: PetscViewerMatlab^creating
242: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
243: VecView(), MatView(), VecLoad(), MatLoad()
244: @*/
245: PetscErrorCode PetscViewerMatlabOpen(MPI_Comm comm,const char name[],PetscViewerFileType type,PetscViewer *binv)
246: {
248:
250: PetscViewerCreate(comm,binv);
251: PetscViewerSetType(*binv,PETSC_VIEWER_MATLAB);
252: PetscViewerSetFileType(*binv,type);
253: PetscViewerSetFilename(*binv,name);
254: return(0);
255: }
257: static PetscMPIInt Petsc_Viewer_Matlab_keyval = MPI_KEYVAL_INVALID;
261: /*@C
262: PETSC_VIEWER_MATLAB_ - Creates a Matlab PetscViewer shared by all processors
263: in a communicator.
265: Collective on MPI_Comm
267: Input Parameter:
268: . comm - the MPI communicator to share the Matlab PetscViewer
269:
270: Level: intermediate
272: Options Database Keys:
273: $ -viewer_matlab_filename <name>
275: Environmental variables:
276: - PETSC_VIEWER_MATLAB_FILENAME
278: Notes:
279: Unlike almost all other PETSc routines, PETSC_VIEWER_MATLAB_ does not return
280: an error code. The matlab PetscViewer is usually used in the form
281: $ XXXView(XXX object,PETSC_VIEWER_MATLAB_(comm));
283: .seealso: PETSC_VIEWER_MATLAB_WORLD, PETSC_VIEWER_MATLAB_SELF, PetscViewerMatlabOpen(), PetscViewerCreate(),
284: PetscViewerDestroy()
285: @*/
286: PetscViewer PETSC_VIEWER_MATLAB_(MPI_Comm comm)
287: {
289: PetscTruth flg;
290: PetscViewer viewer;
291: char fname[PETSC_MAX_PATH_LEN];
294: if (Petsc_Viewer_Matlab_keyval == MPI_KEYVAL_INVALID) {
295: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Matlab_keyval,0);
296: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
297: }
298: MPI_Attr_get(comm,Petsc_Viewer_Matlab_keyval,(void **)&viewer,(int*)&flg);
299: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
300: if (!flg) { /* PetscViewer not yet created */
301: PetscOptionsGetenv(comm,"PETSC_VIEWER_MATLAB_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
302: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
303: if (!flg) {
304: PetscStrcpy(fname,"matlaboutput.mat");
305: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
306: }
307: PetscViewerMatlabOpen(comm,fname,PETSC_FILE_CREATE,&viewer);
308: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
309: PetscObjectRegisterDestroy((PetscObject)viewer);
310: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
311: MPI_Attr_put(comm,Petsc_Viewer_Matlab_keyval,(void*)viewer);
312: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
313: }
314: PetscFunctionReturn(viewer);
315: }