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