Actual source code: vmatlab.c
petsc-3.12.5 2020-03-29
2: #include <petsc/private/viewerimpl.h>
3: #include <mat.h>
6: typedef struct {
7: MATFile *ep;
8: PetscMPIInt rank;
9: PetscFileMode btype;
10: } PetscViewer_Matlab;
12: /*@C
13: PetscViewerMatlabPutArray - Puts an array into the MATLAB viewer.
15: Not collective: only processor zero saves the array
17: Input Parameters:
18: + mfile - the viewer
19: . m,n - the dimensions of the array
20: . array - the array (represented in one dimension)
21: - name - the name of the array
23: Level: advanced
25: Notes:
26: Only writes array values on processor 0.
28: @*/
29: PetscErrorCode PetscViewerMatlabPutArray(PetscViewer mfile,int m,int n,const PetscScalar *array,const char *name)
30: {
31: PetscErrorCode ierr;
32: PetscViewer_Matlab *ml = (PetscViewer_Matlab*)mfile->data;
33: mxArray *mat;
36: if (!ml->rank) {
37: PetscInfo1(mfile,"Putting MATLAB array %s\n",name);
38: #if !defined(PETSC_USE_COMPLEX)
39: mat = mxCreateDoubleMatrix(m,n,mxREAL);
40: #else
41: mat = mxCreateDoubleMatrix(m,n,mxCOMPLEX);
42: #endif
43: PetscArraycpy(mxGetPr(mat),array,m*n);
44: matPutVariable(ml->ep,name,mat);
46: PetscInfo1(mfile,"Put MATLAB array %s\n",name);
47: }
48: return(0);
49: }
51: PetscErrorCode PetscViewerMatlabPutVariable(PetscViewer viewer,const char *name,void *mat)
52: {
53: PetscViewer_Matlab *ml = (PetscViewer_Matlab*)viewer->data;
56: matPutVariable(ml->ep,name,(mxArray*)mat);
57: return(0);
58: }
60: /*@C
61: PetscViewerMatlabGetArray - Gets a variable from a MATLAB viewer into an array
63: Not Collective; only processor zero reads in the array
65: Input Parameters:
66: + mfile - the MATLAB file viewer
67: . m,n - the dimensions of the array
68: . array - the array (represented in one dimension)
69: - name - the name of the array
71: Level: advanced
73: Notes:
74: Only reads in array values on processor 0.
76: @*/
77: PetscErrorCode PetscViewerMatlabGetArray(PetscViewer mfile,int m,int n,PetscScalar *array,const char *name)
78: {
79: PetscErrorCode ierr;
80: PetscViewer_Matlab *ml = (PetscViewer_Matlab*)mfile->data;
81: mxArray *mat;
84: if (!ml->rank) {
85: PetscInfo1(mfile,"Getting MATLAB array %s\n",name);
86: mat = matGetVariable(ml->ep,name);
87: if (!mat) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to get array %s from matlab",name);
88: PetscArraycpy(array,mxGetPr(mat),m*n);
89: PetscInfo1(mfile,"Got MATLAB array %s\n",name);
90: }
91: return(0);
92: }
94: PetscErrorCode PetscViewerFileSetMode_Matlab(PetscViewer viewer,PetscFileMode type)
95: {
96: PetscViewer_Matlab *vmatlab = (PetscViewer_Matlab*)viewer->data;
99: vmatlab->btype = type;
100: return(0);
101: }
103: /*
104: Actually opens the file
105: */
106: PetscErrorCode PetscViewerFileSetName_Matlab(PetscViewer viewer,const char name[])
107: {
108: PetscViewer_Matlab *vmatlab = (PetscViewer_Matlab*)viewer->data;
109: PetscFileMode type = vmatlab->btype;
112: if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode() before PetscViewerFileSetName()");
113: if (vmatlab->ep) matClose(vmatlab->ep);
115: /* only first processor opens file */
116: if (!vmatlab->rank) {
117: if (type == FILE_MODE_READ) vmatlab->ep = matOpen(name,"r");
118: else if (type == FILE_MODE_WRITE || type == FILE_MODE_WRITE) vmatlab->ep = matOpen(name,"w");
119: else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
120: }
121: return(0);
122: }
124: PetscErrorCode PetscViewerDestroy_Matlab(PetscViewer v)
125: {
126: PetscErrorCode ierr;
127: PetscViewer_Matlab *vf = (PetscViewer_Matlab*)v->data;
130: if (vf->ep) matClose(vf->ep);
131: PetscFree(vf);
132: return(0);
133: }
135: /*MC
136: PETSCVIEWERMATLAB - A viewer that saves the variables into a MATLAB .mat file that may be read into MATLAB
137: with load('filename').
139: Level: intermediate
141: Note: Currently can only save PETSc vectors to .mat files, not matrices (use the PETSCVIEWERBINARY and
142: ${PETSC_DIR}/share/petsc/matlab/PetscBinaryRead.m to read matrices into MATLAB).
144: For parallel vectors obtained with DMCreateGlobalVector() or DMGetGlobalVector() the vectors are saved to
145: the .mat file in natural ordering. You can use DMView() to save the DMDA information to the .mat file
146: the fields in the MATLAB loaded da variable give the array dimensions so you can reshape the MATLAB
147: vector to the same multidimensional shape as it had in PETSc for plotting etc. For example,
149: $ In your PETSc C/C++ code (assuming a two dimensional DMDA with one degree of freedom per node)
150: $ PetscObjectSetName((PetscObject)x,"x");
151: $ VecView(x,PETSC_VIEWER_MATLAB_WORLD);
152: $ PetscObjectSetName((PetscObject)da,"da");
153: $ DMView(x,PETSC_VIEWER_MATLAB_WORLD);
154: $ Then from MATLAB
155: $ load('matlaboutput.mat') % matlaboutput.mat is the default filename
156: $ xnew = zeros(da.n,da.m);
157: $ xnew(:) = x; % reshape one dimensional vector back to two dimensions
159: If you wish to put the same variable into the .mat file several times you need to give it a new
160: name before each call to view.
162: Use PetscViewerMatlabPutArray() to just put an array of doubles into the .mat file
164: .seealso: PETSC_VIEWER_MATLAB_(),PETSC_VIEWER_MATLAB_SELF, PETSC_VIEWER_MATLAB_WORLD,PetscViewerCreate(),
165: PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERASCII, PETSCVIEWERDRAW,
166: PETSC_VIEWER_STDOUT_(), PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat
168: M*/
169: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Matlab(PetscViewer viewer)
170: {
171: PetscErrorCode ierr;
172: PetscViewer_Matlab *e;
175: PetscNewLog(viewer,&e);
176: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&e->rank);
177: e->btype = (PetscFileMode)-1;
178: viewer->data = (void*) e;
180: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_Matlab);
181: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Matlab);
183: viewer->ops->destroy = PetscViewerDestroy_Matlab;
184: return(0);
185: }
187: /*@C
188: PetscViewerMatlabOpen - Opens a Matlab .mat file for output
190: Collective
192: Input Parameters:
193: + comm - MPI communicator
194: . name - name of file
195: - type - type of file
196: $ FILE_MODE_WRITE - create new file for MATLAB output
197: $ FILE_MODE_READ - open existing file for MATLAB input
198: $ FILE_MODE_WRITE - open existing file for MATLAB output
200: Output Parameter:
201: . binv - PetscViewer for MATLAB output to use with the specified file
203: Level: beginner
205: Note: This PetscViewer should be destroyed with PetscViewerDestroy().
207: For writing files it only opens the file on processor 0 in the communicator.
209: This only saves Vecs it cannot be used to save Mats. We recommend using the PETSCVIEWERBINARY to save objects to be loaded into MATLAB
210: instead of this routine.
213: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), PETSCVIEWERBINARY, PetscViewerBinaryOpen()
214: VecView(), MatView(), VecLoad(), MatLoad()
215: @*/
216: PetscErrorCode PetscViewerMatlabOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv)
217: {
221: PetscViewerCreate(comm,binv);
222: PetscViewerSetType(*binv,PETSCVIEWERMATLAB);
223: PetscViewerFileSetMode(*binv,type);
224: PetscViewerFileSetName(*binv,name);
225: return(0);
226: }
228: static PetscMPIInt Petsc_Viewer_Matlab_keyval = MPI_KEYVAL_INVALID;
230: /*@C
231: PETSC_VIEWER_MATLAB_ - Creates a Matlab PetscViewer shared by all processors
232: in a communicator.
234: Collective
236: Input Parameter:
237: . comm - the MPI communicator to share the Matlab PetscViewer
239: Level: intermediate
241: Options Database Keys:
242: . -viewer_matlab_filename <name>
244: Environmental variables:
245: . PETSC_VIEWER_MATLAB_FILENAME
247: Notes:
248: Unlike almost all other PETSc routines, PETSC_VIEWER_MATLAB_ does not return
249: an error code. The matlab PetscViewer is usually used in the form
250: $ XXXView(XXX object,PETSC_VIEWER_MATLAB_(comm));
252: Use PETSC_VIEWER_SOCKET_() or PetscViewerSocketOpen() to communicator with an interactive MATLAB session.
254: .seealso: PETSC_VIEWER_MATLAB_WORLD, PETSC_VIEWER_MATLAB_SELF, PetscViewerMatlabOpen(), PetscViewerCreate(),
255: PetscViewerDestroy()
256: @*/
257: PetscViewer PETSC_VIEWER_MATLAB_(MPI_Comm comm)
258: {
260: PetscBool flg;
261: PetscViewer viewer;
262: char fname[PETSC_MAX_PATH_LEN];
263: MPI_Comm ncomm;
266: PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
267: if (Petsc_Viewer_Matlab_keyval == MPI_KEYVAL_INVALID) {
268: MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Matlab_keyval,0);
269: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
270: }
271: MPI_Comm_get_attr(ncomm,Petsc_Viewer_Matlab_keyval,(void**)&viewer,(int*)&flg);
272: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
273: if (!flg) { /* PetscViewer not yet created */
274: PetscOptionsGetenv(ncomm,"PETSC_VIEWER_MATLAB_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
275: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
276: if (!flg) {
277: PetscStrcpy(fname,"matlaboutput.mat");
278: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
279: }
280: PetscViewerMatlabOpen(ncomm,fname,FILE_MODE_WRITE,&viewer);
281: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
282: PetscObjectRegisterDestroy((PetscObject)viewer);
283: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
284: MPI_Comm_set_attr(ncomm,Petsc_Viewer_Matlab_keyval,(void*)viewer);
285: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
286: }
287: PetscCommDestroy(&ncomm);
288: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
289: PetscFunctionReturn(viewer);
290: }