Actual source code: vmatlab.c

      1: #define PETSC_DLL

     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/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(), PetscViewerSetFilename(), PetscViewerSetFileType()

     39: M*/

     41: typedef struct {
     42:   MATFile             *ep;
     43:   PetscMPIInt         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: PetscErrorCode PETSC_DLLEXPORT 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:     PetscLogInfo((0,"PetscViewerMatlabPutArray: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,"PetscViewerMatlabPutArray:Put Matlab array %s\n",name));
     83:   }
     84:   return(0);
     85: }

     89: PetscErrorCode PETSC_DLLEXPORT 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 PETSC_DLLEXPORT 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:     PetscLogInfo((0,"PetscViewerMatlabGetArray: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:     PetscLogInfo((0,"PetscViewerMatlabGetArray:Got Matlab array %s\n",name));
    129:   }
    130:   return(0);
    131: }

    136: PetscErrorCode PETSC_DLLEXPORT PetscViewerSetFileType_Matlab(PetscViewer viewer,PetscViewerFileType 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 PETSC_DLLEXPORT PetscViewerSetFilename_Matlab(PetscViewer viewer,const char name[])
    153: {
    154:   PetscViewer_Matlab  *vmatlab = (PetscViewer_Matlab*)viewer->data;
    155:   PetscViewerFileType type = vmatlab->btype;

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

    162:   /* only first processor opens file */
    163:   if (!vmatlab->rank){
    164:     if (type == PETSC_FILE_RDONLY){
    165:       vmatlab->ep = matOpen(name,"r");
    166:     } else 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 PETSC_DLLEXPORT 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 PETSC_DLLEXPORT 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_DLLEXPORT 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: }