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 EXTERN_C_BEGIN 133 #undef __FUNCT__ 134 #define __FUNCT__ "PetscViewerFileSetMode_Matlab" 135 PetscErrorCode PetscViewerFileSetMode_Matlab(PetscViewer viewer,PetscFileMode type) 136 { 137 PetscViewer_Matlab *vmatlab = (PetscViewer_Matlab*)viewer->data; 138 139 PetscFunctionBegin; 140 vmatlab->btype = type; 141 PetscFunctionReturn(0); 142 } 143 EXTERN_C_END 144 145 /* 146 Actually opens the file 147 */ 148 EXTERN_C_BEGIN 149 #undef __FUNCT__ 150 #define __FUNCT__ "PetscViewerFileSetName_Matlab" 151 PetscErrorCode PetscViewerFileSetName_Matlab(PetscViewer viewer,const char name[]) 152 { 153 PetscViewer_Matlab *vmatlab = (PetscViewer_Matlab*)viewer->data; 154 PetscFileMode type = vmatlab->btype; 155 156 PetscFunctionBegin; 157 if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode() before PetscViewerFileSetName()"); 158 if (vmatlab->ep) matClose(vmatlab->ep); 159 160 /* only first processor opens file */ 161 if (!vmatlab->rank) { 162 if (type == FILE_MODE_READ) { 163 vmatlab->ep = matOpen(name,"r"); 164 } else if (type == FILE_MODE_WRITE || type == FILE_MODE_WRITE) { 165 vmatlab->ep = matOpen(name,"w"); 166 } else { 167 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type"); 168 } 169 } 170 PetscFunctionReturn(0); 171 } 172 EXTERN_C_END 173 174 #undef __FUNCT__ 175 #define __FUNCT__ "PetscViewerDestroy_Matlab" 176 PetscErrorCode PetscViewerDestroy_Matlab(PetscViewer v) 177 { 178 PetscErrorCode ierr; 179 PetscViewer_Matlab *vf = (PetscViewer_Matlab*)v->data; 180 181 PetscFunctionBegin; 182 if (vf->ep) matClose(vf->ep); 183 ierr = PetscFree(vf);CHKERRQ(ierr); 184 PetscFunctionReturn(0); 185 } 186 187 EXTERN_C_BEGIN 188 #undef __FUNCT__ 189 #define __FUNCT__ "PetscViewerCreate_Matlab" 190 PetscErrorCode PetscViewerCreate_Matlab(PetscViewer viewer) 191 { 192 PetscErrorCode ierr; 193 PetscViewer_Matlab *e; 194 195 PetscFunctionBegin; 196 ierr = PetscNewLog(viewer,PetscViewer_Matlab,&e);CHKERRQ(ierr); 197 ierr = MPI_Comm_rank(((PetscObject)viewer)->comm,&e->rank);CHKERRQ(ierr); 198 e->btype = (PetscFileMode)-1; 199 viewer->data = (void*) e; 200 ierr = PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_Matlab", 201 PetscViewerFileSetName_Matlab);CHKERRQ(ierr); 202 ierr = PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetMode_C","PetscViewerFileSetMode_Matlab", 203 PetscViewerFileSetMode_Matlab);CHKERRQ(ierr); 204 viewer->ops->destroy = PetscViewerDestroy_Matlab; 205 PetscFunctionReturn(0); 206 } 207 EXTERN_C_END 208 209 #undef __FUNCT__ 210 #define __FUNCT__ "PetscViewerMatlabOpen" 211 /*@C 212 PetscViewerMatlabOpen - Opens a Matlab .mat file for output 213 214 Collective on MPI_Comm 215 216 Input Parameters: 217 + comm - MPI communicator 218 . name - name of file 219 - type - type of file 220 $ FILE_MODE_WRITE - create new file for MATLAB output 221 $ FILE_MODE_READ - open existing file for MATLAB input 222 $ FILE_MODE_WRITE - open existing file for MATLAB output 223 224 Output Parameter: 225 . binv - PetscViewer for MATLAB output to use with the specified file 226 227 Level: beginner 228 229 Note: This PetscViewer should be destroyed with PetscViewerDestroy(). 230 231 For writing files it only opens the file on processor 0 in the communicator. 232 233 This only saves Vecs it cannot be used to save Mats. We recommend using the PETSCVIEWERBINARY to save objects to be loaded into MATLAB 234 instead of this routine. 235 236 Concepts: MATLAB .mat files 237 Concepts: PetscViewerMatlab^creating 238 239 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(), PETSCVIEWERBINARY, PetscViewerBinaryOpen() 240 VecView(), MatView(), VecLoad(), MatLoad() 241 @*/ 242 PetscErrorCode PetscViewerMatlabOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv) 243 { 244 PetscErrorCode ierr; 245 246 PetscFunctionBegin; 247 ierr = PetscViewerCreate(comm,binv);CHKERRQ(ierr); 248 ierr = PetscViewerSetType(*binv,PETSCVIEWERMATLAB);CHKERRQ(ierr); 249 ierr = PetscViewerFileSetMode(*binv,type);CHKERRQ(ierr); 250 ierr = PetscViewerFileSetName(*binv,name);CHKERRQ(ierr); 251 PetscFunctionReturn(0); 252 } 253 254 static PetscMPIInt Petsc_Viewer_Matlab_keyval = MPI_KEYVAL_INVALID; 255 256 #undef __FUNCT__ 257 #define __FUNCT__ "PETSC_VIEWER_MATLAB_" 258 /*@C 259 PETSC_VIEWER_MATLAB_ - Creates a Matlab PetscViewer shared by all processors 260 in a communicator. 261 262 Collective on MPI_Comm 263 264 Input Parameter: 265 . comm - the MPI communicator to share the Matlab PetscViewer 266 267 Level: intermediate 268 269 Options Database Keys: 270 $ -viewer_matlab_filename <name> 271 272 Environmental variables: 273 - PETSC_VIEWER_MATLAB_FILENAME 274 275 Notes: 276 Unlike almost all other PETSc routines, PETSC_VIEWER_MATLAB_ does not return 277 an error code. The matlab PetscViewer is usually used in the form 278 $ XXXView(XXX object,PETSC_VIEWER_MATLAB_(comm)); 279 280 Use PETSC_VIEWER_SOCKET_() or PetscViewerSocketOpen() to communicator with an interactive MATLAB session. 281 282 .seealso: PETSC_VIEWER_MATLAB_WORLD, PETSC_VIEWER_MATLAB_SELF, PetscViewerMatlabOpen(), PetscViewerCreate(), 283 PetscViewerDestroy() 284 @*/ 285 PetscViewer PETSC_VIEWER_MATLAB_(MPI_Comm comm) 286 { 287 PetscErrorCode ierr; 288 PetscBool flg; 289 PetscViewer viewer; 290 char fname[PETSC_MAX_PATH_LEN]; 291 MPI_Comm ncomm; 292 293 PetscFunctionBegin; 294 ierr = PetscCommDuplicate(comm,&ncomm,PETSC_NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 295 if (Petsc_Viewer_Matlab_keyval == MPI_KEYVAL_INVALID) { 296 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Matlab_keyval,0); 297 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 298 } 299 ierr = MPI_Attr_get(ncomm,Petsc_Viewer_Matlab_keyval,(void **)&viewer,(int*)&flg); 300 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 301 if (!flg) { /* PetscViewer not yet created */ 302 ierr = PetscOptionsGetenv(ncomm,"PETSC_VIEWER_MATLAB_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg); 303 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 304 if (!flg) { 305 ierr = PetscStrcpy(fname,"matlaboutput.mat"); 306 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 307 } 308 ierr = PetscViewerMatlabOpen(ncomm,fname,FILE_MODE_WRITE,&viewer); 309 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 310 ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 311 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 312 ierr = MPI_Attr_put(ncomm,Petsc_Viewer_Matlab_keyval,(void*)viewer); 313 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 314 } 315 ierr = PetscCommDestroy(&ncomm); 316 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 317 PetscFunctionReturn(viewer); 318 } 319 320 321 322 323 324