xref: /petsc/src/sys/classes/viewer/impls/matlab/vmatlab.c (revision c4762a1b19cd2af06abeed90e8f9d34fb975dd94)
1 
2 #include <petsc/private/viewerimpl.h>
3 #include <mat.h>
4 
5 
6 typedef struct {
7   MATFile       *ep;
8   PetscMPIInt   rank;
9   PetscFileMode btype;
10 } PetscViewer_Matlab;
11 
12 /*@C
13     PetscViewerMatlabPutArray - Puts an array into the MATLAB viewer.
14 
15       Not collective: only processor zero saves the array
16 
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
22 
23    Level: advanced
24 
25      Notes:
26     Only writes array values on processor 0.
27 
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;
34 
35   PetscFunctionBegin;
36   if (!ml->rank) {
37     ierr = PetscInfo1(mfile,"Putting MATLAB array %s\n",name);CHKERRQ(ierr);
38 #if !defined(PETSC_USE_COMPLEX)
39     mat  = mxCreateDoubleMatrix(m,n,mxREAL);
40 #else
41     mat  = mxCreateDoubleMatrix(m,n,mxCOMPLEX);
42 #endif
43     ierr = PetscArraycpy(mxGetPr(mat),array,m*n);CHKERRQ(ierr);
44     matPutVariable(ml->ep,name,mat);
45 
46     ierr = PetscInfo1(mfile,"Put MATLAB array %s\n",name);CHKERRQ(ierr);
47   }
48   PetscFunctionReturn(0);
49 }
50 
51 PetscErrorCode  PetscViewerMatlabPutVariable(PetscViewer viewer,const char *name,void *mat)
52 {
53   PetscViewer_Matlab *ml = (PetscViewer_Matlab*)viewer->data;
54 
55   PetscFunctionBegin;
56   matPutVariable(ml->ep,name,(mxArray*)mat);
57   PetscFunctionReturn(0);
58 }
59 
60 /*@C
61     PetscViewerMatlabGetArray - Gets a variable from a MATLAB viewer into an array
62 
63     Not Collective; only processor zero reads in the array
64 
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
70 
71    Level: advanced
72 
73      Notes:
74     Only reads in array values on processor 0.
75 
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;
82 
83   PetscFunctionBegin;
84   if (!ml->rank) {
85     ierr = PetscInfo1(mfile,"Getting MATLAB array %s\n",name);CHKERRQ(ierr);
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     ierr = PetscArraycpy(array,mxGetPr(mat),m*n);CHKERRQ(ierr);
89     ierr = PetscInfo1(mfile,"Got MATLAB array %s\n",name);CHKERRQ(ierr);
90   }
91   PetscFunctionReturn(0);
92 }
93 
94 PetscErrorCode  PetscViewerFileSetMode_Matlab(PetscViewer viewer,PetscFileMode type)
95 {
96   PetscViewer_Matlab *vmatlab = (PetscViewer_Matlab*)viewer->data;
97 
98   PetscFunctionBegin;
99   vmatlab->btype = type;
100   PetscFunctionReturn(0);
101 }
102 
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;
110 
111   PetscFunctionBegin;
112   if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode() before PetscViewerFileSetName()");
113   if (vmatlab->ep) matClose(vmatlab->ep);
114 
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   PetscFunctionReturn(0);
122 }
123 
124 PetscErrorCode PetscViewerDestroy_Matlab(PetscViewer v)
125 {
126   PetscErrorCode     ierr;
127   PetscViewer_Matlab *vf = (PetscViewer_Matlab*)v->data;
128 
129   PetscFunctionBegin;
130   if (vf->ep) matClose(vf->ep);
131   ierr = PetscFree(vf);CHKERRQ(ierr);
132   PetscFunctionReturn(0);
133 }
134 
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').
138 
139    Level: intermediate
140 
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).
143 
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,
148 
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
158 
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.
161 
162               Use PetscViewerMatlabPutArray() to just put an array of doubles into the .mat file
163 
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
167 
168 M*/
169 PETSC_EXTERN PetscErrorCode PetscViewerCreate_Matlab(PetscViewer viewer)
170 {
171   PetscErrorCode     ierr;
172   PetscViewer_Matlab *e;
173 
174   PetscFunctionBegin;
175   ierr         = PetscNewLog(viewer,&e);CHKERRQ(ierr);
176   ierr         = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&e->rank);CHKERRQ(ierr);
177   e->btype     = (PetscFileMode)-1;
178   viewer->data = (void*) e;
179 
180   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_Matlab);CHKERRQ(ierr);
181   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Matlab);CHKERRQ(ierr);
182 
183   viewer->ops->destroy = PetscViewerDestroy_Matlab;
184   PetscFunctionReturn(0);
185 }
186 
187 /*@C
188    PetscViewerMatlabOpen - Opens a Matlab .mat file for output
189 
190    Collective
191 
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
199 
200    Output Parameter:
201 .  binv - PetscViewer for MATLAB output to use with the specified file
202 
203    Level: beginner
204 
205    Note: This PetscViewer should be destroyed with PetscViewerDestroy().
206 
207     For writing files it only opens the file on processor 0 in the communicator.
208 
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.
211 
212 
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 {
218   PetscErrorCode ierr;
219 
220   PetscFunctionBegin;
221   ierr = PetscViewerCreate(comm,binv);CHKERRQ(ierr);
222   ierr = PetscViewerSetType(*binv,PETSCVIEWERMATLAB);CHKERRQ(ierr);
223   ierr = PetscViewerFileSetMode(*binv,type);CHKERRQ(ierr);
224   ierr = PetscViewerFileSetName(*binv,name);CHKERRQ(ierr);
225   PetscFunctionReturn(0);
226 }
227 
228 static PetscMPIInt Petsc_Viewer_Matlab_keyval = MPI_KEYVAL_INVALID;
229 
230 /*@C
231      PETSC_VIEWER_MATLAB_ - Creates a Matlab PetscViewer shared by all processors
232                      in a communicator.
233 
234      Collective
235 
236      Input Parameter:
237 .    comm - the MPI communicator to share the Matlab PetscViewer
238 
239      Level: intermediate
240 
241    Options Database Keys:
242 .    -viewer_matlab_filename <name>
243 
244    Environmental variables:
245 .   PETSC_VIEWER_MATLAB_FILENAME
246 
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));
251 
252      Use PETSC_VIEWER_SOCKET_() or PetscViewerSocketOpen() to communicator with an interactive MATLAB session.
253 
254 .seealso: PETSC_VIEWER_MATLAB_WORLD, PETSC_VIEWER_MATLAB_SELF, PetscViewerMatlabOpen(), PetscViewerCreate(),
255           PetscViewerDestroy()
256 @*/
257 PetscViewer  PETSC_VIEWER_MATLAB_(MPI_Comm comm)
258 {
259   PetscErrorCode ierr;
260   PetscBool      flg;
261   PetscViewer    viewer;
262   char           fname[PETSC_MAX_PATH_LEN];
263   MPI_Comm       ncomm;
264 
265   PetscFunctionBegin;
266   ierr = PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
267   if (Petsc_Viewer_Matlab_keyval == MPI_KEYVAL_INVALID) {
268     ierr = 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," ");PetscFunctionReturn(0);}
270   }
271   ierr = 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," ");PetscFunctionReturn(0);}
273   if (!flg) { /* PetscViewer not yet created */
274     ierr = 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," ");PetscFunctionReturn(0);}
276     if (!flg) {
277       ierr = PetscStrcpy(fname,"matlaboutput.mat");
278       if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
279     }
280     ierr = 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," ");PetscFunctionReturn(0);}
282     ierr = PetscObjectRegisterDestroy((PetscObject)viewer);
283     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
284     ierr = 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," ");PetscFunctionReturn(0);}
286   }
287   ierr = PetscCommDestroy(&ncomm);
288   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);}
289   PetscFunctionReturn(viewer);
290 }
291 
292 
293 
294 
295 
296