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 `PETSCVIEWERMATLAB` 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: Note:
25: Only writes array values on processor 0.
27: .seealso: `PETSCVIEWERMATLAB`, `PetscViewerMatlabGetArray()`
28: @*/
29: PetscErrorCode PetscViewerMatlabPutArray(PetscViewer mfile, int m, int n, const PetscScalar *array, const char *name)
30: {
31: PetscViewer_Matlab *ml;
32: mxArray *mat;
35: ml = (PetscViewer_Matlab *)mfile->data;
36: if (!ml->rank) {
37: PetscInfo(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: PetscInfo(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;
55: matPutVariable(ml->ep, name, (mxArray *)mat);
56: return 0;
57: }
59: /*@C
60: PetscViewerMatlabGetArray - Gets a variable from a `PETSCVIEWERMATLAB` viewer into an array
62: Not Collective; only processor zero reads in the array
64: Input Parameters:
65: + mfile - the MATLAB file viewer
66: . m,n - the dimensions of the array
67: . array - the array (represented in one dimension)
68: - name - the name of the array
70: Level: advanced
72: Note:
73: Only reads in array values on processor 0.
75: .seealso: `PETSCVIEWERMATLAB`, `PetscViewerMatlabPutArray()`
76: @*/
77: PetscErrorCode PetscViewerMatlabGetArray(PetscViewer mfile, int m, int n, PetscScalar *array, const char *name)
78: {
79: PetscViewer_Matlab *ml;
80: mxArray *mat;
83: ml = (PetscViewer_Matlab *)mfile->data;
84: if (!ml->rank) {
85: PetscInfo(mfile, "Getting MATLAB array %s\n", name);
86: mat = matGetVariable(ml->ep, name);
88: PetscArraycpy(array, mxGetPr(mat), m * n);
89: PetscInfo(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;
98: vmatlab->btype = type;
99: return 0;
100: }
102: /*
103: Actually opens the file
104: */
105: PetscErrorCode PetscViewerFileSetName_Matlab(PetscViewer viewer, const char name[])
106: {
107: PetscViewer_Matlab *vmatlab = (PetscViewer_Matlab *)viewer->data;
108: PetscFileMode type = vmatlab->btype;
111: if (vmatlab->ep) matClose(vmatlab->ep);
113: /* only first processor opens file */
114: if (!vmatlab->rank) {
115: if (type == FILE_MODE_READ) vmatlab->ep = matOpen(name, "r");
116: else if (type == FILE_MODE_WRITE) vmatlab->ep = matOpen(name, "w");
117: else {
119: SETERRQ(PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Unsupported file mode %s", PetscFileModes[type]);
120: }
121: }
122: return 0;
123: }
125: PetscErrorCode PetscViewerDestroy_Matlab(PetscViewer v)
126: {
127: PetscViewer_Matlab *vf = (PetscViewer_Matlab *)v->data;
129: if (vf->ep) matClose(vf->ep);
130: PetscFree(vf);
131: PetscObjectComposeFunction((PetscObject)v, "PetscViewerFileSetName_C", NULL);
132: PetscObjectComposeFunction((PetscObject)v, "PetscViewerFileSetMode_C", NULL);
133: return 0;
134: }
136: /*MC
137: PETSCVIEWERMATLAB - A viewer that saves the variables into a MATLAB .mat file that may be read into MATLAB
138: with load('filename').
140: Level: intermediate
142: Notes:
143: Currently can only save PETSc vectors to .mat files, not matrices (use the `PETSCVIEWERBINARY` and
144: ${PETSC_DIR}/share/petsc/matlab/PetscBinaryRead.m to read matrices into MATLAB).
146: For parallel vectors obtained with `DMCreateGlobalVector()` or `DMGetGlobalVector()` the vectors are saved to
147: the .mat file in natural ordering. You can use DMView() to save the `DMDA` information to the .mat file
148: the fields in the MATLAB loaded da variable give the array dimensions so you can reshape the MATLAB
149: vector to the same multidimensional shape as it had in PETSc for plotting etc. For example,
151: In your PETSc C/C++ code (assuming a two dimensional `DMDA` with one degree of freedom per node)
152: .vb
153: PetscObjectSetName((PetscObject)x,"x");
154: VecView(x,PETSC_VIEWER_MATLAB_WORLD);
155: PetscObjectSetName((PetscObject)da,"da");
156: DMView(x,PETSC_VIEWER_MATLAB_WORLD);
157: .ve
158: Then from MATLAB
159: .vb
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
163: .ve
165: If you wish to put the same variable into the .mat file several times you need to give it a new
166: name before each call to view.
168: Use `PetscViewerMatlabPutArray()` to just put an array of doubles into the .mat file
170: .seealso: `PETSC_VIEWER_MATLAB_()`, `PETSC_VIEWER_MATLAB_SELF`, `PETSC_VIEWER_MATLAB_WORLD`, `PetscViewerCreate()`,
171: `PetscViewerMatlabOpen()`, `VecView()`, `DMView()`, `PetscViewerMatlabPutArray()`, `PETSCVIEWERBINARY`, `PETSCVIEWERASCII`, `PETSCVIEWERDRAW`,
172: `PETSC_VIEWER_STDOUT_()`, `PetscViewerFileSetName()`, `PetscViewerFileSetMode()`, `PetscViewerFormat`, `PetscMatlabEngine`
173: M*/
174: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Matlab(PetscViewer viewer)
175: {
176: PetscViewer_Matlab *e;
178: PetscNew(&e);
179: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &e->rank);
180: e->btype = FILE_MODE_UNDEFINED;
181: viewer->data = (void *)e;
183: PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetName_C", PetscViewerFileSetName_Matlab);
184: PetscObjectComposeFunction((PetscObject)viewer, "PetscViewerFileSetMode_C", PetscViewerFileSetMode_Matlab);
186: viewer->ops->destroy = PetscViewerDestroy_Matlab;
187: return 0;
188: }
190: /*@C
191: PetscViewerMatlabOpen - Opens a Matlab .mat file for output
193: Collective
195: Input Parameters:
196: + comm - MPI communicator
197: . name - name of file
198: - type - type of file
199: $ `FILE_MODE_WRITE` - create new file for MATLAB output
200: $ `FILE_MODE_READ` - open existing file for MATLAB input
201: $ `FILE_MODE_WRITE` - open existing file for MATLAB output
203: Output Parameter:
204: . binv - PetscViewer for MATLAB output to use with the specified file
206: Level: beginner
208: Notes:
209: 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 `Vec`s it cannot be used to save `Mat`s. We recommend using the `PETSCVIEWERBINARY` to save objects to be loaded into MATLAB
214: instead of this routine.
216: PETSc must be configured with the option -with-matlab for this functionality
218: .seealso: `PETSCVIEWERMATLAB`, `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: {
223: PetscViewerCreate(comm, binv);
224: PetscViewerSetType(*binv, PETSCVIEWERMATLAB);
225: PetscViewerFileSetMode(*binv, type);
226: PetscViewerFileSetName(*binv, name);
227: return 0;
228: }
230: static PetscMPIInt Petsc_Viewer_Matlab_keyval = MPI_KEYVAL_INVALID;
232: /*@C
233: PETSC_VIEWER_MATLAB_ - Creates a `PETSCVIEWERMATLAB` `PetscViewer` shared by all processors
234: in a communicator.
236: Collective
238: Input Parameter:
239: . comm - the MPI communicator to share the Matlab `PetscViewer`
241: Options Database Key:
242: . -viewer_matlab_filename <name> - name of the Matlab file
244: Environmental variable:
245: . `PETSC_VIEWER_MATLAB_FILENAME` - name of the Matlab file
247: Level: intermediate
249: Note:
250: Unlike almost all other PETSc routines, `PETSC_VIEWER_MATLAB_()` does not return
251: an error code. The matlab PetscViewer is usually used in the form
252: $ XXXView(XXX object,PETSC_VIEWER_MATLAB_(comm));
254: Use `PETSC_VIEWER_SOCKET_()` or `PetscViewerSocketOpen()` to communicator with an interactive MATLAB session.
256: .seealso: `PETSC_VIEWER_MATLAB_WORLD`, `PETSC_VIEWER_MATLAB_SELF`, `PetscViewerMatlabOpen()`, `PetscViewerCreate()`,
257: `PetscViewerDestroy()`
258: @*/
259: PetscViewer PETSC_VIEWER_MATLAB_(MPI_Comm comm)
260: {
262: PetscBool flg;
263: PetscViewer viewer;
264: char fname[PETSC_MAX_PATH_LEN];
265: MPI_Comm ncomm;
267: PetscCommDuplicate(comm, &ncomm, NULL);
268: if (ierr) {
269: PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_MATLAB_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_INITIAL, " ");
270: return 0;
271: }
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) {
275: PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_MATLAB_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_INITIAL, " ");
276: return NULL;
277: }
278: }
279: MPI_Comm_get_attr(ncomm, Petsc_Viewer_Matlab_keyval, (void **)&viewer, (int *)&flg);
280: if (ierr) {
281: PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_MATLAB_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_INITIAL, " ");
282: return NULL;
283: }
284: if (!flg) { /* PetscViewer not yet created */
285: PetscOptionsGetenv(ncomm, "PETSC_VIEWER_MATLAB_FILENAME", fname, PETSC_MAX_PATH_LEN, &flg);
286: if (ierr) {
287: PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_MATLAB_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_REPEAT, " ");
288: return NULL;
289: }
290: if (!flg) {
291: PetscStrcpy(fname, "matlaboutput.mat");
292: if (ierr) {
293: PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_MATLAB_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_REPEAT, " ");
294: return NULL;
295: }
296: }
297: PetscViewerMatlabOpen(ncomm, fname, FILE_MODE_WRITE, &viewer);
298: if (ierr) {
299: PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_MATLAB_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_REPEAT, " ");
300: return NULL;
301: }
302: PetscObjectRegisterDestroy((PetscObject)viewer);
303: if (ierr) {
304: PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_MATLAB_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_REPEAT, " ");
305: return NULL;
306: }
307: MPI_Comm_set_attr(ncomm, Petsc_Viewer_Matlab_keyval, (void *)viewer);
308: if (ierr) {
309: PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_MATLAB_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_INITIAL, " ");
310: return NULL;
311: }
312: }
313: PetscCommDestroy(&ncomm);
314: if (ierr) {
315: PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_MATLAB_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_REPEAT, " ");
316: return NULL;
317: }
318: return viewer;
319: }