Actual source code: vmatlab.c

  1: /* $Id: matlab.c,v 1.17 2001/08/06 21:14:26 bsmith Exp $ #include "petsc.h" */

 3:  #include src/sys/src/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/PetscReadBinary.m to read matrices into matlab).

 15:              For parallel vectors obtained with DACreateGlobalVec() or DAGetGlobalVec() 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(), PetscViewerSetFilename(), PetscViewerSetFileType()

 39: M*/

 41: typedef struct {
 42:   MATFile             *ep;
 43:   int                 rank;
 44:   PetscViewerFileType 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: int PetscViewerMatlabPutArray(PetscViewer mfile,int m,int n,PetscScalar *array,char *name)
 66: {
 67:   int                ierr;
 68:   PetscViewer_Matlab *ml = (PetscViewer_Matlab*)mfile->data;
 69:   mxArray            *mat;
 70: 
 72:   if (ml->rank) return(0);
 73:   PetscLogInfo(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:   PetscLogInfo(0,"Put Matlab array %s\n",name);
 83:   return(0);
 84: }

 88: int 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: int PetscViewerMatlabGetArray(PetscViewer mfile,int m,int n,PetscScalar *array,char *name)
116: {
117:   int                ierr;
118:   PetscViewer_Matlab *ml = (PetscViewer_Matlab*)mfile->data;
119:   mxArray            *mat;
120: 
122:   if (ml->rank) return(0);
123:   PetscLogInfo(0,"Getting Matlab array %s\n",name);
124:   mat  = matGetVariable(ml->ep,name);
125:   if (!mat) SETERRQ1(1,"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:   return(0);
129: }

131: EXTERN_C_BEGIN
134: int PetscViewerSetFileType_Matlab(PetscViewer viewer,PetscViewerFileType type)
135: {
136:   PetscViewer_Matlab *vmatlab = (PetscViewer_Matlab*)viewer->data;

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

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

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

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

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

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

188: EXTERN_C_BEGIN
191: int PetscViewerCreate_Matlab(PetscViewer viewer)
192: {
193:   int                ierr;
194:   PetscViewer_Matlab *e;

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

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

217:    Collective on MPI_Comm

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

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

230:    Level: beginner

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

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

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

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


259: static int Petsc_Viewer_Matlab_keyval = MPI_KEYVAL_INVALID;

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

267:      Collective on MPI_Comm

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

274:    Options Database Keys:
275: $    -viewer_matlab_filename <name>

277:    Environmental variables:
278: -   PETSC_VIEWER_MATLAB_FILENAME

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

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

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