1 2 #include <petsc-private/viewerimpl.h> 3 #include <mat.h> 4 5 /*MC 6 PETSCVIEWERMATLAB - A viewer that saves the variables into a MATLAB .mat file that may be read into MATLAB 7 with load('filename'). 8 9 Level: intermediate 10 11 Note: Currently can only save PETSc vectors to .mat files, not matrices (use the PETSCVIEWERBINARY and 12 ${PETSC_DIR}/bin/matlab/PetscBinaryRead.m to read matrices into matlab). 13 14 For parallel vectors obtained with DMCreateGlobalVector() or DMGetGlobalVector() the vectors are saved to 15 the .mat file in natural ordering. You can use DMView() to save the DMDA 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, 18 19 $ In your PETSc C/C++ code (assuming a two dimensional DMDA 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 $ DMView(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 28 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. 31 32 Use PetscViewerMatlabPutArray() to just put an array of doubles into the .mat file 33 34 .seealso: PETSC_VIEWER_MATLAB_(),PETSC_VIEWER_MATLAB_SELF(), PETSC_VIEWER_MATLAB_WORLD(),PetscViewerCreate(), 35 PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, 36 PETSC_ASCII_VIEWER, PetscViewerFileSetName(), PetscViewerFileSetMode() 37 38 M*/ 39 40 typedef struct { 41 MATFile *ep; 42 PetscMPIInt rank; 43 PetscFileMode btype; 44 } PetscViewer_Matlab; 45 46 #undef __FUNCT__ 47 #define __FUNCT__ "PetscViewerMatlabPutArray" 48 /*@C 49 PetscViewerMatlabPutArray - Puts an array into the MATLAB viewer. 50 51 Not collective: only processor zero saves the array 52 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 58 59 Level: advanced 60 61 Notes: Only writes array values on processor 0. 62 63 @*/ 64 PetscErrorCode PetscViewerMatlabPutArray(PetscViewer mfile,int m,int n,const PetscScalar *array,const char *name) 65 { 66 PetscErrorCode ierr; 67 PetscViewer_Matlab *ml = (PetscViewer_Matlab*)mfile->data; 68 mxArray *mat; 69 70 PetscFunctionBegin; 71 if (!ml->rank) { 72 ierr = PetscInfo1(mfile,"Putting MATLAB array %s\n",name);CHKERRQ(ierr); 73 #if !defined(PETSC_USE_COMPLEX) 74 mat = mxCreateDoubleMatrix(m,n,mxREAL); 75 #else 76 mat = mxCreateDoubleMatrix(m,n,mxCOMPLEX); 77 #endif 78 ierr = PetscMemcpy(mxGetPr(mat),array,m*n*sizeof(PetscScalar));CHKERRQ(ierr); 79 matPutVariable(ml->ep,name,mat); 80 81 ierr = PetscInfo1(mfile,"Put MATLAB array %s\n",name);CHKERRQ(ierr); 82 } 83 PetscFunctionReturn(0); 84 } 85 86 #undef __FUNCT__ 87 #define __FUNCT__ "PetscViewerMatlabPutVariable" 88 PetscErrorCode PetscViewerMatlabPutVariable(PetscViewer viewer,const char *name,void *mat) 89 { 90 PetscViewer_Matlab *ml = (PetscViewer_Matlab*)viewer->data; 91 92 PetscFunctionBegin; 93 matPutVariable(ml->ep,name,(mxArray*)mat); 94 PetscFunctionReturn(0); 95 } 96 97 #undef __FUNCT__ 98 #define __FUNCT__ "PetscViewerMatlabGetArray" 99 /*@C 100 PetscViewerMatlabGetArray - Gets a variable from a MATLAB viewer into an array 101 102 Not Collective; only processor zero reads in the array 103 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 109 110 Level: advanced 111 112 Notes: Only reads in array values on processor 0. 113 114 @*/ 115 PetscErrorCode PetscViewerMatlabGetArray(PetscViewer mfile,int m,int n,PetscScalar *array,const char *name) 116 { 117 PetscErrorCode ierr; 118 PetscViewer_Matlab *ml = (PetscViewer_Matlab*)mfile->data; 119 mxArray *mat; 120 121 PetscFunctionBegin; 122 if (!ml->rank) { 123 ierr = PetscInfo1(mfile,"Getting MATLAB array %s\n",name);CHKERRQ(ierr); 124 mat = matGetVariable(ml->ep,name); 125 if (!mat) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to get array %s from matlab",name); 126 ierr = PetscMemcpy(array,mxGetPr(mat),m*n*sizeof(PetscScalar));CHKERRQ(ierr); 127 ierr = PetscInfo1(mfile,"Got MATLAB array %s\n",name);CHKERRQ(ierr); 128 } 129 PetscFunctionReturn(0); 130 } 131 132 #undef __FUNCT__ 133 #define __FUNCT__ "PetscViewerFileSetMode_Matlab" 134 PetscErrorCode PetscViewerFileSetMode_Matlab(PetscViewer viewer,PetscFileMode type) 135 { 136 PetscViewer_Matlab *vmatlab = (PetscViewer_Matlab*)viewer->data; 137 138 PetscFunctionBegin; 139 vmatlab->btype = type; 140 PetscFunctionReturn(0); 141 } 142 143 /* 144 Actually opens the file 145 */ 146 #undef __FUNCT__ 147 #define __FUNCT__ "PetscViewerFileSetName_Matlab" 148 PetscErrorCode PetscViewerFileSetName_Matlab(PetscViewer viewer,const char name[]) 149 { 150 PetscViewer_Matlab *vmatlab = (PetscViewer_Matlab*)viewer->data; 151 PetscFileMode type = vmatlab->btype; 152 153 PetscFunctionBegin; 154 if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode() before PetscViewerFileSetName()"); 155 if (vmatlab->ep) matClose(vmatlab->ep); 156 157 /* only first processor opens file */ 158 if (!vmatlab->rank) { 159 if (type == FILE_MODE_READ) vmatlab->ep = matOpen(name,"r"); 160 else if (type == FILE_MODE_WRITE || type == FILE_MODE_WRITE) vmatlab->ep = matOpen(name,"w"); 161 else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type"); 162 } 163 PetscFunctionReturn(0); 164 } 165 166 #undef __FUNCT__ 167 #define __FUNCT__ "PetscViewerDestroy_Matlab" 168 PetscErrorCode PetscViewerDestroy_Matlab(PetscViewer v) 169 { 170 PetscErrorCode ierr; 171 PetscViewer_Matlab *vf = (PetscViewer_Matlab*)v->data; 172 173 PetscFunctionBegin; 174 if (vf->ep) matClose(vf->ep); 175 ierr = PetscFree(vf);CHKERRQ(ierr); 176 PetscFunctionReturn(0); 177 } 178 179 #undef __FUNCT__ 180 #define __FUNCT__ "PetscViewerCreate_Matlab" 181 PETSC_EXTERN PetscErrorCode PetscViewerCreate_Matlab(PetscViewer viewer) 182 { 183 PetscErrorCode ierr; 184 PetscViewer_Matlab *e; 185 186 PetscFunctionBegin; 187 ierr = PetscNewLog(viewer,PetscViewer_Matlab,&e);CHKERRQ(ierr); 188 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&e->rank);CHKERRQ(ierr); 189 e->btype = (PetscFileMode)-1; 190 viewer->data = (void*) e; 191 192 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_Matlab);CHKERRQ(ierr); 193 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Matlab);CHKERRQ(ierr); 194 195 viewer->ops->destroy = PetscViewerDestroy_Matlab; 196 PetscFunctionReturn(0); 197 } 198 199 #undef __FUNCT__ 200 #define __FUNCT__ "PetscViewerMatlabOpen" 201 /*@C 202 PetscViewerMatlabOpen - Opens a Matlab .mat file for output 203 204 Collective on MPI_Comm 205 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 213 214 Output Parameter: 215 . binv - PetscViewer for MATLAB output to use with the specified file 216 217 Level: beginner 218 219 Note: This PetscViewer should be destroyed with PetscViewerDestroy(). 220 221 For writing files it only opens the file on processor 0 in the communicator. 222 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. 225 226 Concepts: MATLAB .mat files 227 Concepts: PetscViewerMatlab^creating 228 229 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(), PETSCVIEWERBINARY, PetscViewerBinaryOpen() 230 VecView(), MatView(), VecLoad(), MatLoad() 231 @*/ 232 PetscErrorCode PetscViewerMatlabOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv) 233 { 234 PetscErrorCode ierr; 235 236 PetscFunctionBegin; 237 ierr = PetscViewerCreate(comm,binv);CHKERRQ(ierr); 238 ierr = PetscViewerSetType(*binv,PETSCVIEWERMATLAB);CHKERRQ(ierr); 239 ierr = PetscViewerFileSetMode(*binv,type);CHKERRQ(ierr); 240 ierr = PetscViewerFileSetName(*binv,name);CHKERRQ(ierr); 241 PetscFunctionReturn(0); 242 } 243 244 static PetscMPIInt Petsc_Viewer_Matlab_keyval = MPI_KEYVAL_INVALID; 245 246 #undef __FUNCT__ 247 #define __FUNCT__ "PETSC_VIEWER_MATLAB_" 248 /*@C 249 PETSC_VIEWER_MATLAB_ - Creates a Matlab PetscViewer shared by all processors 250 in a communicator. 251 252 Collective on MPI_Comm 253 254 Input Parameter: 255 . comm - the MPI communicator to share the Matlab PetscViewer 256 257 Level: intermediate 258 259 Options Database Keys: 260 $ -viewer_matlab_filename <name> 261 262 Environmental variables: 263 - PETSC_VIEWER_MATLAB_FILENAME 264 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)); 269 270 Use PETSC_VIEWER_SOCKET_() or PetscViewerSocketOpen() to communicator with an interactive MATLAB session. 271 272 .seealso: PETSC_VIEWER_MATLAB_WORLD, PETSC_VIEWER_MATLAB_SELF, PetscViewerMatlabOpen(), PetscViewerCreate(), 273 PetscViewerDestroy() 274 @*/ 275 PetscViewer PETSC_VIEWER_MATLAB_(MPI_Comm comm) 276 { 277 PetscErrorCode ierr; 278 PetscBool flg; 279 PetscViewer viewer; 280 char fname[PETSC_MAX_PATH_LEN]; 281 MPI_Comm ncomm; 282 283 PetscFunctionBegin; 284 ierr = PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 285 if (Petsc_Viewer_Matlab_keyval == MPI_KEYVAL_INVALID) { 286 ierr = 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__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 288 } 289 ierr = MPI_Attr_get(ncomm,Petsc_Viewer_Matlab_keyval,(void**)&viewer,(int*)&flg); 290 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 291 if (!flg) { /* PetscViewer not yet created */ 292 ierr = PetscOptionsGetenv(ncomm,"PETSC_VIEWER_MATLAB_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg); 293 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 294 if (!flg) { 295 ierr = PetscStrcpy(fname,"matlaboutput.mat"); 296 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 297 } 298 ierr = PetscViewerMatlabOpen(ncomm,fname,FILE_MODE_WRITE,&viewer); 299 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 300 ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 301 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 302 ierr = MPI_Attr_put(ncomm,Petsc_Viewer_Matlab_keyval,(void*)viewer); 303 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 304 } 305 ierr = PetscCommDestroy(&ncomm); 306 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 307 PetscFunctionReturn(viewer); 308 } 309 310 311 312 313 314