Actual source code: vmatlab.c
petsc-3.15.0 2021-03-30
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;
33: mxArray *mat;
36: if (!mfile) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null argument: probably PETSC_VIEWER_MATLAB_() failed");
37: ml = (PetscViewer_Matlab*)mfile->data;
38: if (!ml->rank) {
39: PetscInfo1(mfile,"Putting MATLAB array %s\n",name);
40: #if !defined(PETSC_USE_COMPLEX)
41: mat = mxCreateDoubleMatrix(m,n,mxREAL);
42: #else
43: mat = mxCreateDoubleMatrix(m,n,mxCOMPLEX);
44: #endif
45: PetscArraycpy(mxGetPr(mat),array,m*n);
46: matPutVariable(ml->ep,name,mat);
48: PetscInfo1(mfile,"Put MATLAB array %s\n",name);
49: }
50: return(0);
51: }
53: PetscErrorCode PetscViewerMatlabPutVariable(PetscViewer viewer,const char *name,void *mat)
54: {
55: PetscViewer_Matlab *ml = (PetscViewer_Matlab*)viewer->data;
58: matPutVariable(ml->ep,name,(mxArray*)mat);
59: return(0);
60: }
62: /*@C
63: PetscViewerMatlabGetArray - Gets a variable from a MATLAB viewer into an array
65: Not Collective; only processor zero reads in the array
67: Input Parameters:
68: + mfile - the MATLAB file viewer
69: . m,n - the dimensions of the array
70: . array - the array (represented in one dimension)
71: - name - the name of the array
73: Level: advanced
75: Notes:
76: Only reads in array values on processor 0.
78: @*/
79: PetscErrorCode PetscViewerMatlabGetArray(PetscViewer mfile,int m,int n,PetscScalar *array,const char *name)
80: {
81: PetscErrorCode ierr;
82: PetscViewer_Matlab *ml;
83: mxArray *mat;
86: if (!mfile) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null argument: probably PETSC_VIEWER_MATLAB_() failed");
87: ml = (PetscViewer_Matlab*)mfile->data;
88: if (!ml->rank) {
89: PetscInfo1(mfile,"Getting MATLAB array %s\n",name);
90: mat = matGetVariable(ml->ep,name);
91: if (!mat) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to get array %s from matlab",name);
92: PetscArraycpy(array,mxGetPr(mat),m*n);
93: PetscInfo1(mfile,"Got MATLAB array %s\n",name);
94: }
95: return(0);
96: }
98: PetscErrorCode PetscViewerFileSetMode_Matlab(PetscViewer viewer,PetscFileMode type)
99: {
100: PetscViewer_Matlab *vmatlab = (PetscViewer_Matlab*)viewer->data;
103: vmatlab->btype = type;
104: return(0);
105: }
107: /*
108: Actually opens the file
109: */
110: PetscErrorCode PetscViewerFileSetName_Matlab(PetscViewer viewer,const char name[])
111: {
112: PetscViewer_Matlab *vmatlab = (PetscViewer_Matlab*)viewer->data;
113: PetscFileMode type = vmatlab->btype;
116: if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode() before PetscViewerFileSetName()");
117: if (vmatlab->ep) matClose(vmatlab->ep);
119: /* only first processor opens file */
120: if (!vmatlab->rank) {
121: if (type == FILE_MODE_READ) vmatlab->ep = matOpen(name,"r");
122: else if (type == FILE_MODE_WRITE) vmatlab->ep = matOpen(name,"w");
123: else if (type == FILE_MODE_UNDEFINED) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ORDER, "Must call PetscViewerFileSetMode() before PetscViewerFileSetName()");
124: else SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP, "Unsupported file mode %s",PetscFileModes[type]);
125: }
126: return(0);
127: }
129: PetscErrorCode PetscViewerDestroy_Matlab(PetscViewer v)
130: {
131: PetscErrorCode ierr;
132: PetscViewer_Matlab *vf = (PetscViewer_Matlab*)v->data;
135: if (vf->ep) matClose(vf->ep);
136: PetscFree(vf);
137: return(0);
138: }
140: /*MC
141: PETSCVIEWERMATLAB - A viewer that saves the variables into a MATLAB .mat file that may be read into MATLAB
142: with load('filename').
144: Level: intermediate
146: Note: Currently can only save PETSc vectors to .mat files, not matrices (use the PETSCVIEWERBINARY and
147: ${PETSC_DIR}/share/petsc/matlab/PetscBinaryRead.m to read matrices into MATLAB).
149: For parallel vectors obtained with DMCreateGlobalVector() or DMGetGlobalVector() the vectors are saved to
150: the .mat file in natural ordering. You can use DMView() to save the DMDA information to the .mat file
151: the fields in the MATLAB loaded da variable give the array dimensions so you can reshape the MATLAB
152: vector to the same multidimensional shape as it had in PETSc for plotting etc. For example,
154: $ In your PETSc C/C++ code (assuming a two dimensional DMDA with one degree of freedom per node)
155: $ PetscObjectSetName((PetscObject)x,"x");
156: $ VecView(x,PETSC_VIEWER_MATLAB_WORLD);
157: $ PetscObjectSetName((PetscObject)da,"da");
158: $ DMView(x,PETSC_VIEWER_MATLAB_WORLD);
159: $ Then from MATLAB
160: $ load('matlaboutput.mat') % matlaboutput.mat is the default filename
161: $ xnew = zeros(da.n,da.m);
162: $ xnew(:) = x; % reshape one dimensional vector back to two dimensions
164: If you wish to put the same variable into the .mat file several times you need to give it a new
165: name before each call to view.
167: Use PetscViewerMatlabPutArray() to just put an array of doubles into the .mat file
169: .seealso: PETSC_VIEWER_MATLAB_(),PETSC_VIEWER_MATLAB_SELF, PETSC_VIEWER_MATLAB_WORLD,PetscViewerCreate(),
170: PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERASCII, PETSCVIEWERDRAW,
171: PETSC_VIEWER_STDOUT_(), PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat
173: M*/
174: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Matlab(PetscViewer viewer)
175: {
176: PetscErrorCode ierr;
177: PetscViewer_Matlab *e;
180: PetscNewLog(viewer,&e);
181: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&e->rank);
182: e->btype = FILE_MODE_UNDEFINED;
183: viewer->data = (void*) e;
185: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_Matlab);
186: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Matlab);
188: viewer->ops->destroy = PetscViewerDestroy_Matlab;
189: return(0);
190: }
192: /*@C
193: PetscViewerMatlabOpen - Opens a Matlab .mat file for output
195: Collective
197: Input Parameters:
198: + comm - MPI communicator
199: . name - name of file
200: - type - type of file
201: $ FILE_MODE_WRITE - create new file for MATLAB output
202: $ FILE_MODE_READ - open existing file for MATLAB input
203: $ FILE_MODE_WRITE - open existing file for MATLAB output
205: Output Parameter:
206: . binv - PetscViewer for MATLAB output to use with the specified file
208: Level: beginner
210: Note: This PetscViewer should be destroyed with PetscViewerDestroy().
212: For writing files it only opens the file on processor 0 in the communicator.
214: This only saves Vecs it cannot be used to save Mats. We recommend using the PETSCVIEWERBINARY to save objects to be loaded into MATLAB
215: instead of this routine.
218: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), PETSCVIEWERBINARY, PetscViewerBinaryOpen()
219: VecView(), MatView(), VecLoad(), MatLoad()
220: @*/
221: PetscErrorCode PetscViewerMatlabOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv)
222: {
226: PetscViewerCreate(comm,binv);
227: PetscViewerSetType(*binv,PETSCVIEWERMATLAB);
228: PetscViewerFileSetMode(*binv,type);
229: PetscViewerFileSetName(*binv,name);
230: return(0);
231: }
233: static PetscMPIInt Petsc_Viewer_Matlab_keyval = MPI_KEYVAL_INVALID;
235: /*@C
236: PETSC_VIEWER_MATLAB_ - Creates a Matlab PetscViewer shared by all processors
237: in a communicator.
239: Collective
241: Input Parameter:
242: . comm - the MPI communicator to share the Matlab PetscViewer
244: Level: intermediate
246: Options Database Keys:
247: . -viewer_matlab_filename <name>
249: Environmental variables:
250: . PETSC_VIEWER_MATLAB_FILENAME
252: Notes:
253: Unlike almost all other PETSc routines, PETSC_VIEWER_MATLAB_ does not return
254: an error code. The matlab PetscViewer is usually used in the form
255: $ XXXView(XXX object,PETSC_VIEWER_MATLAB_(comm));
257: Use PETSC_VIEWER_SOCKET_() or PetscViewerSocketOpen() to communicator with an interactive MATLAB session.
259: .seealso: PETSC_VIEWER_MATLAB_WORLD, PETSC_VIEWER_MATLAB_SELF, PetscViewerMatlabOpen(), PetscViewerCreate(),
260: PetscViewerDestroy()
261: @*/
262: PetscViewer PETSC_VIEWER_MATLAB_(MPI_Comm comm)
263: {
265: PetscBool flg;
266: PetscViewer viewer;
267: char fname[PETSC_MAX_PATH_LEN];
268: MPI_Comm ncomm;
271: PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
272: if (Petsc_Viewer_Matlab_keyval == MPI_KEYVAL_INVALID) {
273: MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Matlab_keyval,0);
274: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
275: }
276: MPI_Comm_get_attr(ncomm,Petsc_Viewer_Matlab_keyval,(void**)&viewer,(int*)&flg);
277: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
278: if (!flg) { /* PetscViewer not yet created */
279: PetscOptionsGetenv(ncomm,"PETSC_VIEWER_MATLAB_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
280: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
281: if (!flg) {
282: PetscStrcpy(fname,"matlaboutput.mat");
283: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
284: }
285: PetscViewerMatlabOpen(ncomm,fname,FILE_MODE_WRITE,&viewer);
286: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
287: PetscObjectRegisterDestroy((PetscObject)viewer);
288: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
289: MPI_Comm_set_attr(ncomm,Petsc_Viewer_Matlab_keyval,(void*)viewer);
290: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
291: }
292: PetscCommDestroy(&ncomm);
293: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
294: PetscFunctionReturn(viewer);
295: }