Actual source code: vmatlab.c
2: #include <petsc/private/viewerimpl.h>
3: #include <mat.h>
5: typedef struct {
6: MATFile *ep;
7: PetscMPIInt rank;
8: PetscFileMode btype;
9: } PetscViewer_Matlab;
11: /*@C
12: PetscViewerMatlabPutArray - Puts an array into the MATLAB viewer.
14: Not collective: only processor zero saves the array
16: Input Parameters:
17: + mfile - the viewer
18: . m,n - the dimensions of the array
19: . array - the array (represented in one dimension)
20: - name - the name of the array
22: Level: advanced
24: Notes:
25: Only writes array values on processor 0.
27: @*/
28: PetscErrorCode PetscViewerMatlabPutArray(PetscViewer mfile,int m,int n,const PetscScalar *array,const char *name)
29: {
30: PetscErrorCode ierr;
31: PetscViewer_Matlab *ml;
32: mxArray *mat;
35: if (!mfile) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null argument: probably PETSC_VIEWER_MATLAB_() failed");
36: ml = (PetscViewer_Matlab*)mfile->data;
37: if (!ml->rank) {
38: PetscInfo1(mfile,"Putting MATLAB array %s\n",name);
39: #if !defined(PETSC_USE_COMPLEX)
40: mat = mxCreateDoubleMatrix(m,n,mxREAL);
41: #else
42: mat = mxCreateDoubleMatrix(m,n,mxCOMPLEX);
43: #endif
44: PetscArraycpy(mxGetPr(mat),array,m*n);
45: matPutVariable(ml->ep,name,mat);
47: PetscInfo1(mfile,"Put MATLAB array %s\n",name);
48: }
49: return(0);
50: }
52: PetscErrorCode PetscViewerMatlabPutVariable(PetscViewer viewer,const char *name,void *mat)
53: {
54: PetscViewer_Matlab *ml = (PetscViewer_Matlab*)viewer->data;
57: matPutVariable(ml->ep,name,(mxArray*)mat);
58: return(0);
59: }
61: /*@C
62: PetscViewerMatlabGetArray - Gets a variable from a MATLAB viewer into an array
64: Not Collective; only processor zero reads in the array
66: Input Parameters:
67: + mfile - the MATLAB file viewer
68: . m,n - the dimensions of the array
69: . array - the array (represented in one dimension)
70: - name - the name of the array
72: Level: advanced
74: Notes:
75: Only reads in array values on processor 0.
77: @*/
78: PetscErrorCode PetscViewerMatlabGetArray(PetscViewer mfile,int m,int n,PetscScalar *array,const char *name)
79: {
80: PetscErrorCode ierr;
81: PetscViewer_Matlab *ml;
82: mxArray *mat;
85: if (!mfile) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null argument: probably PETSC_VIEWER_MATLAB_() failed");
86: ml = (PetscViewer_Matlab*)mfile->data;
87: if (!ml->rank) {
88: PetscInfo1(mfile,"Getting MATLAB array %s\n",name);
89: mat = matGetVariable(ml->ep,name);
90: if (!mat) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to get array %s from matlab",name);
91: PetscArraycpy(array,mxGetPr(mat),m*n);
92: PetscInfo1(mfile,"Got MATLAB array %s\n",name);
93: }
94: return(0);
95: }
97: PetscErrorCode PetscViewerFileSetMode_Matlab(PetscViewer viewer,PetscFileMode type)
98: {
99: PetscViewer_Matlab *vmatlab = (PetscViewer_Matlab*)viewer->data;
102: vmatlab->btype = type;
103: return(0);
104: }
106: /*
107: Actually opens the file
108: */
109: PetscErrorCode PetscViewerFileSetName_Matlab(PetscViewer viewer,const char name[])
110: {
111: PetscViewer_Matlab *vmatlab = (PetscViewer_Matlab*)viewer->data;
112: PetscFileMode type = vmatlab->btype;
115: if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode() before PetscViewerFileSetName()");
116: if (vmatlab->ep) matClose(vmatlab->ep);
118: /* only first processor opens file */
119: if (!vmatlab->rank) {
120: if (type == FILE_MODE_READ) vmatlab->ep = matOpen(name,"r");
121: else if (type == FILE_MODE_WRITE) vmatlab->ep = matOpen(name,"w");
122: else if (type == FILE_MODE_UNDEFINED) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ORDER, "Must call PetscViewerFileSetMode() before PetscViewerFileSetName()");
123: else SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP, "Unsupported file mode %s",PetscFileModes[type]);
124: }
125: return(0);
126: }
128: PetscErrorCode PetscViewerDestroy_Matlab(PetscViewer v)
129: {
130: PetscErrorCode ierr;
131: PetscViewer_Matlab *vf = (PetscViewer_Matlab*)v->data;
134: if (vf->ep) matClose(vf->ep);
135: PetscFree(vf);
136: return(0);
137: }
139: /*MC
140: PETSCVIEWERMATLAB - A viewer that saves the variables into a MATLAB .mat file that may be read into MATLAB
141: with load('filename').
143: Level: intermediate
145: Note: Currently can only save PETSc vectors to .mat files, not matrices (use the PETSCVIEWERBINARY and
146: ${PETSC_DIR}/share/petsc/matlab/PetscBinaryRead.m to read matrices into MATLAB).
148: For parallel vectors obtained with DMCreateGlobalVector() or DMGetGlobalVector() the vectors are saved to
149: the .mat file in natural ordering. You can use DMView() to save the DMDA information to the .mat file
150: the fields in the MATLAB loaded da variable give the array dimensions so you can reshape the MATLAB
151: vector to the same multidimensional shape as it had in PETSc for plotting etc. For example,
153: $ In your PETSc C/C++ code (assuming a two dimensional DMDA with one degree of freedom per node)
154: $ PetscObjectSetName((PetscObject)x,"x");
155: $ VecView(x,PETSC_VIEWER_MATLAB_WORLD);
156: $ PetscObjectSetName((PetscObject)da,"da");
157: $ DMView(x,PETSC_VIEWER_MATLAB_WORLD);
158: $ Then from MATLAB
159: $ load('matlaboutput.mat') % matlaboutput.mat is the default filename
160: $ xnew = zeros(da.n,da.m);
161: $ xnew(:) = x; % reshape one dimensional vector back to two dimensions
163: If you wish to put the same variable into the .mat file several times you need to give it a new
164: name before each call to view.
166: Use PetscViewerMatlabPutArray() to just put an array of doubles into the .mat file
168: .seealso: PETSC_VIEWER_MATLAB_(),PETSC_VIEWER_MATLAB_SELF, PETSC_VIEWER_MATLAB_WORLD,PetscViewerCreate(),
169: PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERASCII, PETSCVIEWERDRAW,
170: PETSC_VIEWER_STDOUT_(), PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat
172: M*/
173: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Matlab(PetscViewer viewer)
174: {
175: PetscErrorCode ierr;
176: PetscViewer_Matlab *e;
179: PetscNewLog(viewer,&e);
180: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&e->rank);
181: e->btype = FILE_MODE_UNDEFINED;
182: viewer->data = (void*) e;
184: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_Matlab);
185: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Matlab);
187: viewer->ops->destroy = PetscViewerDestroy_Matlab;
188: return(0);
189: }
191: /*@C
192: PetscViewerMatlabOpen - Opens a Matlab .mat file for output
194: Collective
196: Input Parameters:
197: + comm - MPI communicator
198: . name - name of file
199: - type - type of file
200: $ FILE_MODE_WRITE - create new file for MATLAB output
201: $ FILE_MODE_READ - open existing file for MATLAB input
202: $ FILE_MODE_WRITE - open existing file for MATLAB output
204: Output Parameter:
205: . binv - PetscViewer for MATLAB output to use with the specified file
207: Level: beginner
209: Note: This PetscViewer should be destroyed with PetscViewerDestroy().
211: For writing files it only opens the file on processor 0 in the communicator.
213: This only saves Vecs it cannot be used to save Mats. We recommend using the PETSCVIEWERBINARY to save objects to be loaded into MATLAB
214: instead of this routine.
216: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), PETSCVIEWERBINARY, PetscViewerBinaryOpen()
217: VecView(), MatView(), VecLoad(), MatLoad()
218: @*/
219: PetscErrorCode PetscViewerMatlabOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv)
220: {
224: PetscViewerCreate(comm,binv);
225: PetscViewerSetType(*binv,PETSCVIEWERMATLAB);
226: PetscViewerFileSetMode(*binv,type);
227: PetscViewerFileSetName(*binv,name);
228: return(0);
229: }
231: static PetscMPIInt Petsc_Viewer_Matlab_keyval = MPI_KEYVAL_INVALID;
233: /*@C
234: PETSC_VIEWER_MATLAB_ - Creates a Matlab PetscViewer shared by all processors
235: in a communicator.
237: Collective
239: Input Parameter:
240: . comm - the MPI communicator to share the Matlab PetscViewer
242: Level: intermediate
244: Options Database Keys:
245: . -viewer_matlab_filename <name> - name of the Matlab file
247: Environmental variables:
248: . PETSC_VIEWER_MATLAB_FILENAME - name of the Matlab file
250: Notes:
251: Unlike almost all other PETSc routines, PETSC_VIEWER_MATLAB_ does not return
252: an error code. The matlab PetscViewer is usually used in the form
253: $ XXXView(XXX object,PETSC_VIEWER_MATLAB_(comm));
255: Use PETSC_VIEWER_SOCKET_() or PetscViewerSocketOpen() to communicator with an interactive MATLAB session.
257: .seealso: PETSC_VIEWER_MATLAB_WORLD, PETSC_VIEWER_MATLAB_SELF, PetscViewerMatlabOpen(), PetscViewerCreate(),
258: PetscViewerDestroy()
259: @*/
260: PetscViewer PETSC_VIEWER_MATLAB_(MPI_Comm comm)
261: {
263: PetscBool flg;
264: PetscViewer viewer;
265: char fname[PETSC_MAX_PATH_LEN];
266: MPI_Comm ncomm;
269: PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
270: if (Petsc_Viewer_Matlab_keyval == MPI_KEYVAL_INVALID) {
271: MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Matlab_keyval,0);
272: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
273: }
274: MPI_Comm_get_attr(ncomm,Petsc_Viewer_Matlab_keyval,(void**)&viewer,(int*)&flg);
275: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
276: if (!flg) { /* PetscViewer not yet created */
277: PetscOptionsGetenv(ncomm,"PETSC_VIEWER_MATLAB_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
278: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
279: if (!flg) {
280: PetscStrcpy(fname,"matlaboutput.mat");
281: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
282: }
283: PetscViewerMatlabOpen(ncomm,fname,FILE_MODE_WRITE,&viewer);
284: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
285: PetscObjectRegisterDestroy((PetscObject)viewer);
286: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
287: MPI_Comm_set_attr(ncomm,Petsc_Viewer_Matlab_keyval,(void*)viewer);
288: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
289: }
290: PetscCommDestroy(&ncomm);
291: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
292: PetscFunctionReturn(viewer);
293: }