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