Actual source code: vmatlab.c

 2:  #include src/sys/src/viewer/viewerimpl.h
  3: #include "mat.h"

  5: /*MC
  6:    PETSC_VIEWER_MATLAB - A viewer that saves the variables into a Matlab .mat file that may be read into Matlab
  7:        with load('filename').

  9:    Level: intermediate

 11:        Note: Currently can only save PETSc vectors to .mat files, not matrices (use the PETSC_VIEWER_BINARY and 
 12:              ${PETSC_DIR}/bin/matlab/PetscReadBinary.m to read matrices into matlab).

 14:              For parallel vectors obtained with DACreateGlobalVector() or DAGetGlobalVector() the vectors are saved to
 15:              the .mat file in natural ordering. You can use DAView() to save the DA information to the .mat file
 16:              the fields in the Matlab loaded da variable give the array dimensions so you can reshape the Matlab
 17:              vector to the same multidimensional shape as it had in PETSc for plotting etc. For example,

 19: $             In your PETSc C/C++ code (assuming a two dimensional DA with one degree of freedom per node)
 20: $                PetscObjectSetName((PetscObject)x,"x");
 21: $                VecView(x,PETSC_VIEWER_MATLAB_WORLD);
 22: $                PetscObjectSetName((PetscObject)da,"da");
 23: $                DAView(x,PETSC_VIEWER_MATLAB_WORLD);
 24: $             Then from Matlab
 25: $                load('matlaboutput.mat')   % matlaboutput.mat is the default filename
 26: $                xnew = zeros(da.n,da.m);
 27: $                xnew(:) = x;    % reshape one dimensional vector back to two dimensions

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

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

 34: .seealso:  PETSC_VIEWER_MATLAB_(),PETSC_VIEWER_MATLAB_SELF(), PETSC_VIEWER_MATLAB_WORLD(),PetscViewerCreate(),
 35:            PetscViewerMatlabOpen(), VecView(), DAView(), PetscViewerMatlabPutArray(), PETSC_VIEWER_BINARY,
 36:            PETSC_ASCII_VIEWER, DAView(), PetscViewerSetFilename(), PetscViewerSetFileType()

 38: M*/

 40: typedef struct {
 41:   MATFile             *ep;
 42:   PetscMPIInt         rank;
 43:   PetscViewerFileType btype;
 44: } PetscViewer_Matlab;

 48: /*@C
 49:     PetscViewerMatlabPutArray - Puts an array into the Matlab viewer.

 51:       Not collective: only processor zero saves the array

 53:     Input Parameters:
 54: +    mfile - the viewer
 55: .    m,n - the dimensions of the array
 56: .    array - the array (represented in one dimension)
 57: -    name - the name of the array

 59:    Level: advanced

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

 63: @*/
 64: PetscErrorCode PetscViewerMatlabPutArray(PetscViewer mfile,int m,int n,PetscScalar *array,char *name)
 65: {
 66:   PetscErrorCode     ierr;
 67:   PetscViewer_Matlab *ml = (PetscViewer_Matlab*)mfile->data;
 68:   mxArray            *mat;
 69: 
 71:   if (!ml->rank) {
 72:     PetscLogInfo(0,"Putting Matlab array %s\n",name);
 73: #if !defined(PETSC_USE_COMPLEX)
 74:     mat  = mxCreateDoubleMatrix(m,n,mxREAL);
 75: #else
 76:     mat  = mxCreateDoubleMatrix(m,n,mxCOMPLEX);
 77: #endif
 78:     PetscMemcpy(mxGetPr(mat),array,m*n*sizeof(PetscScalar));
 79:     matPutVariable(ml->ep,name,mat);

 81:     PetscLogInfo(0,"Put Matlab array %s\n",name);
 82:   }
 83:   return(0);
 84: }

 88: PetscErrorCode PetscViewerMatlabPutVariable(PetscViewer viewer,const char* name,void* mat)
 89: {
 90:   PetscViewer_Matlab *ml = (PetscViewer_Matlab*)viewer->data; ;

 93:   matPutVariable(ml->ep,name,(mxArray*)mat);
 94:   return(0);
 95: }
 96: 
 99: /*@C
100:     PetscViewerMatlabGetArray - Gets a variable from a Matlab viewer into an array

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

104:     Input Parameters:
105: +    mfile - the Matlab file viewer
106: .    m,n - the dimensions of the array
107: .    array - the array (represented in one dimension)
108: -    name - the name of the array

110:    Level: advanced

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

114: @*/
115: PetscErrorCode PetscViewerMatlabGetArray(PetscViewer mfile,int m,int n,PetscScalar *array,char *name)
116: {
117:   PetscErrorCode     ierr;
118:   PetscViewer_Matlab *ml = (PetscViewer_Matlab*)mfile->data;
119:   mxArray            *mat;
120: 
122:   if (!ml->rank) {
123:     PetscLogInfo(0,"Getting Matlab array %s\n",name);
124:     mat  = matGetVariable(ml->ep,name);
125:     if (!mat) SETERRQ1(PETSC_ERR_LIB,"Unable to get array %s from matlab",name);
126:     PetscMemcpy(array,mxGetPr(mat),m*n*sizeof(PetscScalar));
127:     PetscLogInfo(0,"Got Matlab array %s\n",name);
128:   }
129:   return(0);
130: }

135: PetscErrorCode PetscViewerSetFileType_Matlab(PetscViewer viewer,PetscViewerFileType type)
136: {
137:   PetscViewer_Matlab *vmatlab = (PetscViewer_Matlab*)viewer->data;

140:   vmatlab->btype = type;
141:   return(0);
142: }

145: /*
146:         Actually opens the file 
147: */
151: PetscErrorCode PetscViewerSetFilename_Matlab(PetscViewer viewer,const char name[])
152: {
153:   PetscViewer_Matlab  *vmatlab = (PetscViewer_Matlab*)viewer->data;
154:   PetscViewerFileType type = vmatlab->btype;

157:   if (type == (PetscViewerFileType) -1) {
158:     SETERRQ(PETSC_ERR_ORDER,"Must call PetscViewerSetFileType() before PetscViewerSetFilename()");
159:   }

161:   /* only first processor opens file */
162:   if (!vmatlab->rank){
163:     if (type == PETSC_FILE_RDONLY){
164:       vmatlab->ep = matOpen(name,"r");
165:     }
166:     if (type == PETSC_FILE_CREATE || type == PETSC_FILE_WRONLY) {
167:       vmatlab->ep = matOpen(name,"w");
168:     } else {
169:       SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
170:     }
171:   }
172:   return(0);
173: }

178: PetscErrorCode PetscViewerDestroy_Matlab(PetscViewer v)
179: {
180:   PetscErrorCode     ierr;
181:   PetscViewer_Matlab *vf = (PetscViewer_Matlab*)v->data;

184:   if (vf->ep) matClose(vf->ep);
185:   PetscFree(vf);
186:   return(0);
187: }

192: PetscErrorCode PetscViewerCreate_Matlab(PetscViewer viewer)
193: {
194:   PetscErrorCode     ierr;
195:   PetscViewer_Matlab *e;

198:   PetscNew(PetscViewer_Matlab,&e);
199:   MPI_Comm_rank(viewer->comm,&e->rank);
200:   e->btype     = (PetscViewerFileType)-1;
201:   viewer->data = (void*) e;
202:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerSetFilename_C","PetscViewerSetFilename_Matlab",
203:                                      PetscViewerSetFilename_Matlab);
204:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerSetFileType_C","PetscViewerSetFileType_Matlab",
205:                                      PetscViewerSetFileType_Matlab);
206:   viewer->ops->destroy = PetscViewerDestroy_Matlab;
207:   return(0);
208: }

213: /*@C
214:    PetscViewerMatlabOpen - Opens a Matlab .mat file for input or output.

216:    Collective on MPI_Comm

218:    Input Parameters:
219: +  comm - MPI communicator
220: .  name - name of file 
221: -  type - type of file
222: $    PETSC_FILE_CREATE - create new file for Matlab output
223: $    PETSC_FILE_RDONLY - open existing file for Matlab input
224: $    PETSC_FILE_WRONLY - open existing file for Matlab output

226:    Output Parameter:
227: .  binv - PetscViewer for Matlab input/output to use with the specified file

229:    Level: beginner

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

234:     For writing files it only opens the file on processor 0 in the communicator.
235:     For readable files it opens the file on all nodes that have the file. If 
236:     node 0 does not have the file it generates an error even if other nodes
237:     do have the file.

239:    Concepts: Matlab .mat files
240:    Concepts: PetscViewerMatlab^creating

242: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
243:           VecView(), MatView(), VecLoad(), MatLoad()
244: @*/
245: PetscErrorCode PetscViewerMatlabOpen(MPI_Comm comm,const char name[],PetscViewerFileType type,PetscViewer *binv)
246: {
248: 
250:   PetscViewerCreate(comm,binv);
251:   PetscViewerSetType(*binv,PETSC_VIEWER_MATLAB);
252:   PetscViewerSetFileType(*binv,type);
253:   PetscViewerSetFilename(*binv,name);
254:   return(0);
255: }

257: static PetscMPIInt Petsc_Viewer_Matlab_keyval = MPI_KEYVAL_INVALID;

261: /*@C
262:      PETSC_VIEWER_MATLAB_ - Creates a Matlab PetscViewer shared by all processors 
263:                      in a communicator.

265:      Collective on MPI_Comm

267:      Input Parameter:
268: .    comm - the MPI communicator to share the Matlab PetscViewer
269:     
270:      Level: intermediate

272:    Options Database Keys:
273: $    -viewer_matlab_filename <name>

275:    Environmental variables:
276: -   PETSC_VIEWER_MATLAB_FILENAME

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

283: .seealso: PETSC_VIEWER_MATLAB_WORLD, PETSC_VIEWER_MATLAB_SELF, PetscViewerMatlabOpen(), PetscViewerCreate(),
284:           PetscViewerDestroy()
285: @*/
286: PetscViewer PETSC_VIEWER_MATLAB_(MPI_Comm comm)
287: {
289:   PetscTruth     flg;
290:   PetscViewer    viewer;
291:   char           fname[PETSC_MAX_PATH_LEN];

294:   if (Petsc_Viewer_Matlab_keyval == MPI_KEYVAL_INVALID) {
295:     MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Matlab_keyval,0);
296:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
297:   }
298:   MPI_Attr_get(comm,Petsc_Viewer_Matlab_keyval,(void **)&viewer,(int*)&flg);
299:   if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
300:   if (!flg) { /* PetscViewer not yet created */
301:     PetscOptionsGetenv(comm,"PETSC_VIEWER_MATLAB_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
302:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
303:     if (!flg) {
304:       PetscStrcpy(fname,"matlaboutput.mat");
305:       if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
306:     }
307:     PetscViewerMatlabOpen(comm,fname,PETSC_FILE_CREATE,&viewer);
308:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
309:     PetscObjectRegisterDestroy((PetscObject)viewer);
310:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
311:     MPI_Attr_put(comm,Petsc_Viewer_Matlab_keyval,(void*)viewer);
312:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
313:   }
314:   PetscFunctionReturn(viewer);
315: }