1 2 #include <petsc/private/viewerimpl.h> 3 #include <mat.h> 4 5 typedef struct { 6 MATFile *ep; 7 PetscMPIInt rank; 8 PetscFileMode btype; 9 } PetscViewer_Matlab; 10 11 /*@C 12 PetscViewerMatlabPutArray - Puts an array into the MATLAB viewer. 13 14 Not collective: only processor zero saves the array 15 16 Input Parameters: 17 + mfile - the viewer 18 . m,n - the dimensions of the array 19 . array - the array (represented in one dimension) 20 - name - the name of the array 21 22 Level: advanced 23 24 Notes: 25 Only writes array values on processor 0. 26 27 @*/ 28 PetscErrorCode PetscViewerMatlabPutArray(PetscViewer mfile,int m,int n,const PetscScalar *array,const char *name) 29 { 30 PetscErrorCode ierr; 31 PetscViewer_Matlab *ml; 32 mxArray *mat; 33 34 PetscFunctionBegin; 35 PetscCheckFalse(!mfile,PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null argument: probably PETSC_VIEWER_MATLAB_() failed"); 36 ml = (PetscViewer_Matlab*)mfile->data; 37 if (!ml->rank) { 38 ierr = PetscInfo(mfile,"Putting MATLAB array %s\n",name);CHKERRQ(ierr); 39 #if !defined(PETSC_USE_COMPLEX) 40 mat = mxCreateDoubleMatrix(m,n,mxREAL); 41 #else 42 mat = mxCreateDoubleMatrix(m,n,mxCOMPLEX); 43 #endif 44 ierr = PetscArraycpy(mxGetPr(mat),array,m*n);CHKERRQ(ierr); 45 matPutVariable(ml->ep,name,mat); 46 47 ierr = PetscInfo(mfile,"Put MATLAB array %s\n",name);CHKERRQ(ierr); 48 } 49 PetscFunctionReturn(0); 50 } 51 52 PetscErrorCode PetscViewerMatlabPutVariable(PetscViewer viewer,const char *name,void *mat) 53 { 54 PetscViewer_Matlab *ml = (PetscViewer_Matlab*)viewer->data; 55 56 PetscFunctionBegin; 57 matPutVariable(ml->ep,name,(mxArray*)mat); 58 PetscFunctionReturn(0); 59 } 60 61 /*@C 62 PetscViewerMatlabGetArray - Gets a variable from a MATLAB viewer into an array 63 64 Not Collective; only processor zero reads in the array 65 66 Input Parameters: 67 + mfile - the MATLAB file viewer 68 . m,n - the dimensions of the array 69 . array - the array (represented in one dimension) 70 - name - the name of the array 71 72 Level: advanced 73 74 Notes: 75 Only reads in array values on processor 0. 76 77 @*/ 78 PetscErrorCode PetscViewerMatlabGetArray(PetscViewer mfile,int m,int n,PetscScalar *array,const char *name) 79 { 80 PetscErrorCode ierr; 81 PetscViewer_Matlab *ml; 82 mxArray *mat; 83 84 PetscFunctionBegin; 85 PetscCheckFalse(!mfile,PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null argument: probably PETSC_VIEWER_MATLAB_() failed"); 86 ml = (PetscViewer_Matlab*)mfile->data; 87 if (!ml->rank) { 88 ierr = PetscInfo(mfile,"Getting MATLAB array %s\n",name);CHKERRQ(ierr); 89 mat = matGetVariable(ml->ep,name); 90 PetscCheckFalse(!mat,PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to get array %s from matlab",name); 91 ierr = PetscArraycpy(array,mxGetPr(mat),m*n);CHKERRQ(ierr); 92 ierr = PetscInfo(mfile,"Got MATLAB array %s\n",name);CHKERRQ(ierr); 93 } 94 PetscFunctionReturn(0); 95 } 96 97 PetscErrorCode PetscViewerFileSetMode_Matlab(PetscViewer viewer,PetscFileMode type) 98 { 99 PetscViewer_Matlab *vmatlab = (PetscViewer_Matlab*)viewer->data; 100 101 PetscFunctionBegin; 102 vmatlab->btype = type; 103 PetscFunctionReturn(0); 104 } 105 106 /* 107 Actually opens the file 108 */ 109 PetscErrorCode PetscViewerFileSetName_Matlab(PetscViewer viewer,const char name[]) 110 { 111 PetscViewer_Matlab *vmatlab = (PetscViewer_Matlab*)viewer->data; 112 PetscFileMode type = vmatlab->btype; 113 114 PetscFunctionBegin; 115 PetscCheckFalse(type == (PetscFileMode) -1,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode() before PetscViewerFileSetName()"); 116 if (vmatlab->ep) matClose(vmatlab->ep); 117 118 /* only first processor opens file */ 119 if (!vmatlab->rank) { 120 if (type == FILE_MODE_READ) vmatlab->ep = matOpen(name,"r"); 121 else if (type == FILE_MODE_WRITE) vmatlab->ep = matOpen(name,"w"); 122 else PetscCheckFalse(type == FILE_MODE_UNDEFINED,PetscObjectComm((PetscObject)viewer),PETSC_ERR_ORDER, "Must call PetscViewerFileSetMode() before PetscViewerFileSetName()"); 123 else SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP, "Unsupported file mode %s",PetscFileModes[type]); 124 } 125 PetscFunctionReturn(0); 126 } 127 128 PetscErrorCode PetscViewerDestroy_Matlab(PetscViewer v) 129 { 130 PetscErrorCode ierr; 131 PetscViewer_Matlab *vf = (PetscViewer_Matlab*)v->data; 132 133 PetscFunctionBegin; 134 if (vf->ep) matClose(vf->ep); 135 ierr = PetscFree(vf);CHKERRQ(ierr); 136 PetscFunctionReturn(0); 137 } 138 139 /*MC 140 PETSCVIEWERMATLAB - A viewer that saves the variables into a MATLAB .mat file that may be read into MATLAB 141 with load('filename'). 142 143 Level: intermediate 144 145 Note: Currently can only save PETSc vectors to .mat files, not matrices (use the PETSCVIEWERBINARY and 146 ${PETSC_DIR}/share/petsc/matlab/PetscBinaryRead.m to read matrices into MATLAB). 147 148 For parallel vectors obtained with DMCreateGlobalVector() or DMGetGlobalVector() the vectors are saved to 149 the .mat file in natural ordering. You can use DMView() to save the DMDA information to the .mat file 150 the fields in the MATLAB loaded da variable give the array dimensions so you can reshape the MATLAB 151 vector to the same multidimensional shape as it had in PETSc for plotting etc. For example, 152 153 $ In your PETSc C/C++ code (assuming a two dimensional DMDA with one degree of freedom per node) 154 $ PetscObjectSetName((PetscObject)x,"x"); 155 $ VecView(x,PETSC_VIEWER_MATLAB_WORLD); 156 $ PetscObjectSetName((PetscObject)da,"da"); 157 $ DMView(x,PETSC_VIEWER_MATLAB_WORLD); 158 $ Then from MATLAB 159 $ load('matlaboutput.mat') % matlaboutput.mat is the default filename 160 $ xnew = zeros(da.n,da.m); 161 $ xnew(:) = x; % reshape one dimensional vector back to two dimensions 162 163 If you wish to put the same variable into the .mat file several times you need to give it a new 164 name before each call to view. 165 166 Use PetscViewerMatlabPutArray() to just put an array of doubles into the .mat file 167 168 .seealso: PETSC_VIEWER_MATLAB_(),PETSC_VIEWER_MATLAB_SELF, PETSC_VIEWER_MATLAB_WORLD,PetscViewerCreate(), 169 PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERASCII, PETSCVIEWERDRAW, 170 PETSC_VIEWER_STDOUT_(), PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat 171 172 M*/ 173 PETSC_EXTERN PetscErrorCode PetscViewerCreate_Matlab(PetscViewer viewer) 174 { 175 PetscErrorCode ierr; 176 PetscViewer_Matlab *e; 177 178 PetscFunctionBegin; 179 ierr = PetscNewLog(viewer,&e);CHKERRQ(ierr); 180 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&e->rank);CHKERRMPI(ierr); 181 e->btype = FILE_MODE_UNDEFINED; 182 viewer->data = (void*) e; 183 184 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_Matlab);CHKERRQ(ierr); 185 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Matlab);CHKERRQ(ierr); 186 187 viewer->ops->destroy = PetscViewerDestroy_Matlab; 188 PetscFunctionReturn(0); 189 } 190 191 /*@C 192 PetscViewerMatlabOpen - Opens a Matlab .mat file for output 193 194 Collective 195 196 Input Parameters: 197 + comm - MPI communicator 198 . name - name of file 199 - type - type of file 200 $ FILE_MODE_WRITE - create new file for MATLAB output 201 $ FILE_MODE_READ - open existing file for MATLAB input 202 $ FILE_MODE_WRITE - open existing file for MATLAB output 203 204 Output Parameter: 205 . binv - PetscViewer for MATLAB output to use with the specified file 206 207 Level: beginner 208 209 Note: This PetscViewer should be destroyed with PetscViewerDestroy(). 210 211 For writing files it only opens the file on processor 0 in the communicator. 212 213 This only saves Vecs it cannot be used to save Mats. We recommend using the PETSCVIEWERBINARY to save objects to be loaded into MATLAB 214 instead of this routine. 215 216 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), PETSCVIEWERBINARY, PetscViewerBinaryOpen() 217 VecView(), MatView(), VecLoad(), MatLoad() 218 @*/ 219 PetscErrorCode PetscViewerMatlabOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv) 220 { 221 PetscErrorCode ierr; 222 223 PetscFunctionBegin; 224 ierr = PetscViewerCreate(comm,binv);CHKERRQ(ierr); 225 ierr = PetscViewerSetType(*binv,PETSCVIEWERMATLAB);CHKERRQ(ierr); 226 ierr = PetscViewerFileSetMode(*binv,type);CHKERRQ(ierr); 227 ierr = PetscViewerFileSetName(*binv,name);CHKERRQ(ierr); 228 PetscFunctionReturn(0); 229 } 230 231 static PetscMPIInt Petsc_Viewer_Matlab_keyval = MPI_KEYVAL_INVALID; 232 233 /*@C 234 PETSC_VIEWER_MATLAB_ - Creates a Matlab PetscViewer shared by all processors 235 in a communicator. 236 237 Collective 238 239 Input Parameter: 240 . comm - the MPI communicator to share the Matlab PetscViewer 241 242 Level: intermediate 243 244 Options Database Keys: 245 . -viewer_matlab_filename <name> - name of the Matlab file 246 247 Environmental variables: 248 . PETSC_VIEWER_MATLAB_FILENAME - name of the Matlab file 249 250 Notes: 251 Unlike almost all other PETSc routines, PETSC_VIEWER_MATLAB_ does not return 252 an error code. The matlab PetscViewer is usually used in the form 253 $ XXXView(XXX object,PETSC_VIEWER_MATLAB_(comm)); 254 255 Use PETSC_VIEWER_SOCKET_() or PetscViewerSocketOpen() to communicator with an interactive MATLAB session. 256 257 .seealso: PETSC_VIEWER_MATLAB_WORLD, PETSC_VIEWER_MATLAB_SELF, PetscViewerMatlabOpen(), PetscViewerCreate(), 258 PetscViewerDestroy() 259 @*/ 260 PetscViewer PETSC_VIEWER_MATLAB_(MPI_Comm comm) 261 { 262 PetscErrorCode ierr; 263 PetscBool flg; 264 PetscViewer viewer; 265 char fname[PETSC_MAX_PATH_LEN]; 266 MPI_Comm ncomm; 267 268 PetscFunctionBegin; 269 ierr = PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 270 if (Petsc_Viewer_Matlab_keyval == MPI_KEYVAL_INVALID) { 271 ierr = MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Matlab_keyval,0); 272 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 273 } 274 ierr = MPI_Comm_get_attr(ncomm,Petsc_Viewer_Matlab_keyval,(void**)&viewer,(int*)&flg); 275 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 276 if (!flg) { /* PetscViewer not yet created */ 277 ierr = PetscOptionsGetenv(ncomm,"PETSC_VIEWER_MATLAB_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg); 278 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);} 279 if (!flg) { 280 ierr = PetscStrcpy(fname,"matlaboutput.mat"); 281 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);} 282 } 283 ierr = PetscViewerMatlabOpen(ncomm,fname,FILE_MODE_WRITE,&viewer); 284 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);} 285 ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 286 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);} 287 ierr = MPI_Comm_set_attr(ncomm,Petsc_Viewer_Matlab_keyval,(void*)viewer); 288 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 289 } 290 ierr = PetscCommDestroy(&ncomm); 291 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);} 292 PetscFunctionReturn(viewer); 293 } 294 295