Actual source code: vmatlab.c

petsc-master 2016-12-09
Report Typos and Errors

  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;

 14: /*@C
 15:     PetscViewerMatlabPutArray - Puts an array into the MATLAB viewer.

 17:       Not collective: only processor zero saves the array

 19:     Input Parameters:
 20: +    mfile - the viewer
 21: .    m,n - the dimensions of the array
 22: .    array - the array (represented in one dimension)
 23: -    name - the name of the array

 25:    Level: advanced

 27:      Notes: Only writes array values on processor 0.

 29: @*/
 30: PetscErrorCode  PetscViewerMatlabPutArray(PetscViewer mfile,int m,int n,const PetscScalar *array,const char *name)
 31: {
 32:   PetscErrorCode     ierr;
 33:   PetscViewer_Matlab *ml = (PetscViewer_Matlab*)mfile->data;
 34:   mxArray            *mat;

 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:     PetscMemcpy(mxGetPr(mat),array,m*n*sizeof(PetscScalar));
 45:     matPutVariable(ml->ep,name,mat);

 47:     PetscInfo1(mfile,"Put MATLAB array %s\n",name);
 48:   }
 49:   return(0);
 50: }

 54: PetscErrorCode  PetscViewerMatlabPutVariable(PetscViewer viewer,const char *name,void *mat)
 55: {
 56:   PetscViewer_Matlab *ml = (PetscViewer_Matlab*)viewer->data;

 59:   matPutVariable(ml->ep,name,(mxArray*)mat);
 60:   return(0);
 61: }

 65: /*@C
 66:     PetscViewerMatlabGetArray - Gets a variable from a MATLAB viewer into an array

 68:     Not Collective; only processor zero reads in the array

 70:     Input Parameters:
 71: +    mfile - the MATLAB file viewer
 72: .    m,n - the dimensions of the array
 73: .    array - the array (represented in one dimension)
 74: -    name - the name of the array

 76:    Level: advanced

 78:      Notes: Only reads in array values on processor 0.

 80: @*/
 81: PetscErrorCode  PetscViewerMatlabGetArray(PetscViewer mfile,int m,int n,PetscScalar *array,const char *name)
 82: {
 83:   PetscErrorCode     ierr;
 84:   PetscViewer_Matlab *ml = (PetscViewer_Matlab*)mfile->data;
 85:   mxArray            *mat;

 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:     PetscMemcpy(array,mxGetPr(mat),m*n*sizeof(PetscScalar));
 93:     PetscInfo1(mfile,"Got MATLAB array %s\n",name);
 94:   }
 95:   return(0);
 96: }

100: PetscErrorCode  PetscViewerFileSetMode_Matlab(PetscViewer viewer,PetscFileMode type)
101: {
102:   PetscViewer_Matlab *vmatlab = (PetscViewer_Matlab*)viewer->data;

105:   vmatlab->btype = type;
106:   return(0);
107: }

109: /*
110:         Actually opens the file
111: */
114: PetscErrorCode  PetscViewerFileSetName_Matlab(PetscViewer viewer,const char name[])
115: {
116:   PetscViewer_Matlab *vmatlab = (PetscViewer_Matlab*)viewer->data;
117:   PetscFileMode      type     = vmatlab->btype;

120:   if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode() before PetscViewerFileSetName()");
121:   if (vmatlab->ep) matClose(vmatlab->ep);

123:   /* only first processor opens file */
124:   if (!vmatlab->rank) {
125:     if (type == FILE_MODE_READ) vmatlab->ep = matOpen(name,"r");
126:     else if (type == FILE_MODE_WRITE || type == FILE_MODE_WRITE) vmatlab->ep = matOpen(name,"w");
127:     else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
128:   }
129:   return(0);
130: }

134: PetscErrorCode PetscViewerDestroy_Matlab(PetscViewer v)
135: {
136:   PetscErrorCode     ierr;
137:   PetscViewer_Matlab *vf = (PetscViewer_Matlab*)v->data;

140:   if (vf->ep) matClose(vf->ep);
141:   PetscFree(vf);
142:   return(0);
143: }

145: /*MC
146:    PETSCVIEWERMATLAB - A viewer that saves the variables into a MATLAB .mat file that may be read into MATLAB
147:        with load('filename').

149:    Level: intermediate

151:        Note: Currently can only save PETSc vectors to .mat files, not matrices (use the PETSCVIEWERBINARY and
152:              ${PETSC_DIR}/share/petsc/matlab/PetscBinaryRead.m to read matrices into MATLAB).

154:              For parallel vectors obtained with DMCreateGlobalVector() or DMGetGlobalVector() the vectors are saved to
155:              the .mat file in natural ordering. You can use DMView() to save the DMDA information to the .mat file
156:              the fields in the MATLAB loaded da variable give the array dimensions so you can reshape the MATLAB
157:              vector to the same multidimensional shape as it had in PETSc for plotting etc. For example,

159: $             In your PETSc C/C++ code (assuming a two dimensional DMDA with one degree of freedom per node)
160: $                PetscObjectSetName((PetscObject)x,"x");
161: $                VecView(x,PETSC_VIEWER_MATLAB_WORLD);
162: $                PetscObjectSetName((PetscObject)da,"da");
163: $                DMView(x,PETSC_VIEWER_MATLAB_WORLD);
164: $             Then from MATLAB
165: $                load('matlaboutput.mat')   % matlaboutput.mat is the default filename
166: $                xnew = zeros(da.n,da.m);
167: $                xnew(:) = x;    % reshape one dimensional vector back to two dimensions

169:               If you wish to put the same variable into the .mat file several times you need to give it a new
170:               name before each call to view.

172:               Use PetscViewerMatlabPutArray() to just put an array of doubles into the .mat file

174: .seealso:  PETSC_VIEWER_MATLAB_(),PETSC_VIEWER_MATLAB_SELF, PETSC_VIEWER_MATLAB_WORLD,PetscViewerCreate(),
175:            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERASCII, PETSCVIEWERDRAW,
176:            PETSC_VIEWER_STDOUT_(), PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat

178: M*/
181: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Matlab(PetscViewer viewer)
182: {
183:   PetscErrorCode     ierr;
184:   PetscViewer_Matlab *e;

187:   PetscNewLog(viewer,&e);
188:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&e->rank);
189:   e->btype     = (PetscFileMode)-1;
190:   viewer->data = (void*) e;

192:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_Matlab);
193:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Matlab);

195:   viewer->ops->destroy = PetscViewerDestroy_Matlab;
196:   return(0);
197: }

201: /*@C
202:    PetscViewerMatlabOpen - Opens a Matlab .mat file for output

204:    Collective on MPI_Comm

206:    Input Parameters:
207: +  comm - MPI communicator
208: .  name - name of file
209: -  type - type of file
210: $    FILE_MODE_WRITE - create new file for MATLAB output
211: $    FILE_MODE_READ - open existing file for MATLAB input
212: $    FILE_MODE_WRITE - open existing file for MATLAB output

214:    Output Parameter:
215: .  binv - PetscViewer for MATLAB output to use with the specified file

217:    Level: beginner

219:    Note: This PetscViewer should be destroyed with PetscViewerDestroy().

221:     For writing files it only opens the file on processor 0 in the communicator.

223:      This only saves Vecs it cannot be used to save Mats. We recommend using the PETSCVIEWERBINARY to save objects to be loaded into MATLAB
224:      instead of this routine.

226:    Concepts: MATLAB .mat files
227:    Concepts: PetscViewerMatlab^creating

229: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), PETSCVIEWERBINARY, PetscViewerBinaryOpen()
230:           VecView(), MatView(), VecLoad(), MatLoad()
231: @*/
232: PetscErrorCode  PetscViewerMatlabOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv)
233: {

237:   PetscViewerCreate(comm,binv);
238:   PetscViewerSetType(*binv,PETSCVIEWERMATLAB);
239:   PetscViewerFileSetMode(*binv,type);
240:   PetscViewerFileSetName(*binv,name);
241:   return(0);
242: }

244: static PetscMPIInt Petsc_Viewer_Matlab_keyval = MPI_KEYVAL_INVALID;

248: /*@C
249:      PETSC_VIEWER_MATLAB_ - Creates a Matlab PetscViewer shared by all processors
250:                      in a communicator.

252:      Collective on MPI_Comm

254:      Input Parameter:
255: .    comm - the MPI communicator to share the Matlab PetscViewer

257:      Level: intermediate

259:    Options Database Keys:
260: .    -viewer_matlab_filename <name>

262:    Environmental variables:
263: .   PETSC_VIEWER_MATLAB_FILENAME

265:      Notes:
266:      Unlike almost all other PETSc routines, PETSC_VIEWER_MATLAB_ does not return
267:      an error code.  The matlab PetscViewer is usually used in the form
268: $       XXXView(XXX object,PETSC_VIEWER_MATLAB_(comm));

270:      Use PETSC_VIEWER_SOCKET_() or PetscViewerSocketOpen() to communicator with an interactive MATLAB session.

272: .seealso: PETSC_VIEWER_MATLAB_WORLD, PETSC_VIEWER_MATLAB_SELF, PetscViewerMatlabOpen(), PetscViewerCreate(),
273:           PetscViewerDestroy()
274: @*/
275: PetscViewer  PETSC_VIEWER_MATLAB_(MPI_Comm comm)
276: {
278:   PetscBool      flg;
279:   PetscViewer    viewer;
280:   char           fname[PETSC_MAX_PATH_LEN];
281:   MPI_Comm       ncomm;

284:   PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
285:   if (Petsc_Viewer_Matlab_keyval == MPI_KEYVAL_INVALID) {
286:     MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Matlab_keyval,0);
287:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
288:   }
289:   MPI_Attr_get(ncomm,Petsc_Viewer_Matlab_keyval,(void**)&viewer,(int*)&flg);
290:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
291:   if (!flg) { /* PetscViewer not yet created */
292:     PetscOptionsGetenv(ncomm,"PETSC_VIEWER_MATLAB_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
293:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
294:     if (!flg) {
295:       PetscStrcpy(fname,"matlaboutput.mat");
296:       if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
297:     }
298:     PetscViewerMatlabOpen(ncomm,fname,FILE_MODE_WRITE,&viewer);
299:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
300:     PetscObjectRegisterDestroy((PetscObject)viewer);
301:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
302:     MPI_Attr_put(ncomm,Petsc_Viewer_Matlab_keyval,(void*)viewer);
303:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
304:   }
305:   PetscCommDestroy(&ncomm);
306:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
307:   PetscFunctionReturn(viewer);
308: }