Actual source code: vmatlab.c
1: #define PETSC_DLL
3: #include src/sys/viewer/viewerimpl.h
4: #include "mat.h"
6: /*MC
7: PETSC_VIEWER_MATLAB - A viewer that saves the variables into a Matlab .mat file that may be read into Matlab
8: with load('filename').
10: Level: intermediate
12: Note: Currently can only save PETSc vectors to .mat files, not matrices (use the PETSC_VIEWER_BINARY and
13: ${PETSC_DIR}/bin/matlab/PetscBinaryRead.m to read matrices into matlab).
15: For parallel vectors obtained with DACreateGlobalVector() or DAGetGlobalVector() the vectors are saved to
16: the .mat file in natural ordering. You can use DAView() to save the DA information to the .mat file
17: the fields in the Matlab loaded da variable give the array dimensions so you can reshape the Matlab
18: vector to the same multidimensional shape as it had in PETSc for plotting etc. For example,
20: $ In your PETSc C/C++ code (assuming a two dimensional DA with one degree of freedom per node)
21: $ PetscObjectSetName((PetscObject)x,"x");
22: $ VecView(x,PETSC_VIEWER_MATLAB_WORLD);
23: $ PetscObjectSetName((PetscObject)da,"da");
24: $ DAView(x,PETSC_VIEWER_MATLAB_WORLD);
25: $ Then from Matlab
26: $ load('matlaboutput.mat') % matlaboutput.mat is the default filename
27: $ xnew = zeros(da.n,da.m);
28: $ xnew(:) = x; % reshape one dimensional vector back to two dimensions
30: If you wish to put the same variable into the .mat file several times you need to give it a new
31: name before each call to view.
33: Use PetscViewerMatlabPutArray() to just put an array of doubles into the .mat file
35: .seealso: PETSC_VIEWER_MATLAB_(),PETSC_VIEWER_MATLAB_SELF(), PETSC_VIEWER_MATLAB_WORLD(),PetscViewerCreate(),
36: PetscViewerMatlabOpen(), VecView(), DAView(), PetscViewerMatlabPutArray(), PETSC_VIEWER_BINARY,
37: PETSC_ASCII_VIEWER, DAView(), PetscViewerFileSetName(), PetscViewerFileSetMode()
39: M*/
41: typedef struct {
42: MATFile *ep;
43: PetscMPIInt rank;
44: PetscFileMode btype;
45: } PetscViewer_Matlab;
49: /*@C
50: PetscViewerMatlabPutArray - Puts an array into the Matlab viewer.
52: Not collective: only processor zero saves the array
54: Input Parameters:
55: + mfile - the viewer
56: . m,n - the dimensions of the array
57: . array - the array (represented in one dimension)
58: - name - the name of the array
60: Level: advanced
62: Notes: Only writes array values on processor 0.
64: @*/
65: PetscErrorCode PetscViewerMatlabPutArray(PetscViewer mfile,int m,int n,PetscScalar *array,char *name)
66: {
67: PetscErrorCode ierr;
68: PetscViewer_Matlab *ml = (PetscViewer_Matlab*)mfile->data;
69: mxArray *mat;
70:
72: if (!ml->rank) {
73: PetscInfo1(0,"Putting Matlab array %s\n",name);
74: #if !defined(PETSC_USE_COMPLEX)
75: mat = mxCreateDoubleMatrix(m,n,mxREAL);
76: #else
77: mat = mxCreateDoubleMatrix(m,n,mxCOMPLEX);
78: #endif
79: PetscMemcpy(mxGetPr(mat),array,m*n*sizeof(PetscScalar));
80: matPutVariable(ml->ep,name,mat);
82: PetscInfo1(0,"Put Matlab array %s\n",name);
83: }
84: return(0);
85: }
89: PetscErrorCode PetscViewerMatlabPutVariable(PetscViewer viewer,const char* name,void* mat)
90: {
91: PetscViewer_Matlab *ml = (PetscViewer_Matlab*)viewer->data; ;
94: matPutVariable(ml->ep,name,(mxArray*)mat);
95: return(0);
96: }
97:
100: /*@C
101: PetscViewerMatlabGetArray - Gets a variable from a Matlab viewer into an array
103: Not Collective; only processor zero reads in the array
105: Input Parameters:
106: + mfile - the Matlab file viewer
107: . m,n - the dimensions of the array
108: . array - the array (represented in one dimension)
109: - name - the name of the array
111: Level: advanced
113: Notes: Only reads in array values on processor 0.
115: @*/
116: PetscErrorCode PetscViewerMatlabGetArray(PetscViewer mfile,int m,int n,PetscScalar *array,char *name)
117: {
118: PetscErrorCode ierr;
119: PetscViewer_Matlab *ml = (PetscViewer_Matlab*)mfile->data;
120: mxArray *mat;
121:
123: if (!ml->rank) {
124: PetscInfo1(0,"Getting Matlab array %s\n",name);
125: mat = matGetVariable(ml->ep,name);
126: if (!mat) SETERRQ1(PETSC_ERR_LIB,"Unable to get array %s from matlab",name);
127: PetscMemcpy(array,mxGetPr(mat),m*n*sizeof(PetscScalar));
128: PetscInfo1(0,"Got Matlab array %s\n",name);
129: }
130: return(0);
131: }
136: PetscErrorCode PetscViewerFileSetMode_Matlab(PetscViewer viewer,PetscFileMode type)
137: {
138: PetscViewer_Matlab *vmatlab = (PetscViewer_Matlab*)viewer->data;
141: vmatlab->btype = type;
142: return(0);
143: }
146: /*
147: Actually opens the file
148: */
152: PetscErrorCode PetscViewerFileSetName_Matlab(PetscViewer viewer,const char name[])
153: {
154: PetscViewer_Matlab *vmatlab = (PetscViewer_Matlab*)viewer->data;
155: PetscFileMode type = vmatlab->btype;
158: if (type == (PetscFileMode) -1) {
159: SETERRQ(PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode() before PetscViewerFileSetName()");
160: }
162: /* only first processor opens file */
163: if (!vmatlab->rank){
164: if (type == FILE_MODE_READ){
165: vmatlab->ep = matOpen(name,"r");
166: } else if (type == FILE_MODE_WRITE || type == FILE_MODE_WRITE) {
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 = (PetscFileMode)-1;
201: viewer->data = (void*) e;
202: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_Matlab",
203: PetscViewerFileSetName_Matlab);
204: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetMode_C","PetscViewerFileSetMode_Matlab",
205: PetscViewerFileSetMode_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: $ FILE_MODE_WRITE - create new file for Matlab output
223: $ FILE_MODE_READ - open existing file for Matlab input
224: $ FILE_MODE_WRITE - 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[],PetscFileMode type,PetscViewer *binv)
246: {
248:
250: PetscViewerCreate(comm,binv);
251: PetscViewerSetType(*binv,PETSC_VIEWER_MATLAB);
252: PetscViewerFileSetMode(*binv,type);
253: PetscViewerFileSetName(*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," ");return(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," ");return(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," ");return(0);}
303: if (!flg) {
304: PetscStrcpy(fname,"matlaboutput.mat");
305: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,1,1," ");return(0);}
306: }
307: PetscViewerMatlabOpen(comm,fname,FILE_MODE_WRITE,&viewer);
308: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,1,1," ");return(0);}
309: PetscObjectRegisterDestroy((PetscObject)viewer);
310: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,1,1," ");return(0);}
311: MPI_Attr_put(comm,Petsc_Viewer_Matlab_keyval,(void*)viewer);
312: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,1,1," ");return(0);}
313: }
314: PetscFunctionReturn(viewer);
315: }