Actual source code: vmatlab.c

  1: #define PETSC_DLL

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

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

 10:    Level: intermediate

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

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

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

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

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

 35: .seealso:  PETSC_VIEWER_MATLAB_(),PETSC_VIEWER_MATLAB_SELF(), PETSC_VIEWER_MATLAB_WORLD(),PetscViewerCreate(),
 36:            PetscViewerMatlabOpen(), VecView(), DAView(), PetscViewerMatlabPutArray(), PETSC_VIEWER_BINARY,
 37:            PETSC_ASCII_VIEWER, DAView(), PetscViewerFileSetName(), PetscViewerFileSetMode()

 39: M*/

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

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

 52:       Not collective: only processor zero saves the array

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

 60:    Level: advanced

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

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

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

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

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

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

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

111:    Level: advanced

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

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

136: PetscErrorCode  PetscViewerFileSetMode_Matlab(PetscViewer viewer,PetscFileMode type)
137: {
138:   PetscViewer_Matlab *vmatlab = (PetscViewer_Matlab*)viewer->data;

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

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

158:   if (type == (PetscFileMode) -1) {
159:     SETERRQ(PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode() before PetscViewerFileSetName()");
160:   }

162:   /* only first processor opens file */
163:   if (!vmatlab->rank){
164:     if (type == FILE_MODE_READ){
165:       vmatlab->ep = matOpen(name,"r");
166:     } else if (type == FILE_MODE_WRITE || type == FILE_MODE_WRITE) {
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     = (PetscFileMode)-1;
201:   viewer->data = (void*) e;
202:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_Matlab",
203:                                      PetscViewerFileSetName_Matlab);
204:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetMode_C","PetscViewerFileSetMode_Matlab",
205:                                      PetscViewerFileSetMode_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: $    FILE_MODE_WRITE - create new file for Matlab output
223: $    FILE_MODE_READ - open existing file for Matlab input
224: $    FILE_MODE_WRITE - 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[],PetscFileMode type,PetscViewer *binv)
246: {
248: 
250:   PetscViewerCreate(comm,binv);
251:   PetscViewerSetType(*binv,PETSC_VIEWER_MATLAB);
252:   PetscViewerFileSetMode(*binv,type);
253:   PetscViewerFileSetName(*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," ");return(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," ");return(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," ");return(0);}
303:     if (!flg) {
304:       PetscStrcpy(fname,"matlaboutput.mat");
305:       if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,1,1," ");return(0);}
306:     }
307:     PetscViewerMatlabOpen(comm,fname,FILE_MODE_WRITE,&viewer);
308:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,1,1," ");return(0);}
309:     PetscObjectRegisterDestroy((PetscObject)viewer);
310:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,1,1," ");return(0);}
311:     MPI_Attr_put(comm,Petsc_Viewer_Matlab_keyval,(void*)viewer);
312:     if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,1,1," ");return(0);}
313:   }
314:   PetscFunctionReturn(viewer);
315: }