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 || type == FILE_MODE_WRITE) vmatlab->ep = matOpen(name,"w"); 123 else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file 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);CHKERRQ(ierr); 181 e->btype = (PetscFileMode)-1; 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 217 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), PETSCVIEWERBINARY, PetscViewerBinaryOpen() 218 VecView(), MatView(), VecLoad(), MatLoad() 219 @*/ 220 PetscErrorCode PetscViewerMatlabOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv) 221 { 222 PetscErrorCode ierr; 223 224 PetscFunctionBegin; 225 ierr = PetscViewerCreate(comm,binv);CHKERRQ(ierr); 226 ierr = PetscViewerSetType(*binv,PETSCVIEWERMATLAB);CHKERRQ(ierr); 227 ierr = PetscViewerFileSetMode(*binv,type);CHKERRQ(ierr); 228 ierr = PetscViewerFileSetName(*binv,name);CHKERRQ(ierr); 229 PetscFunctionReturn(0); 230 } 231 232 static PetscMPIInt Petsc_Viewer_Matlab_keyval = MPI_KEYVAL_INVALID; 233 234 /*@C 235 PETSC_VIEWER_MATLAB_ - Creates a Matlab PetscViewer shared by all processors 236 in a communicator. 237 238 Collective 239 240 Input Parameter: 241 . comm - the MPI communicator to share the Matlab PetscViewer 242 243 Level: intermediate 244 245 Options Database Keys: 246 . -viewer_matlab_filename <name> 247 248 Environmental variables: 249 . PETSC_VIEWER_MATLAB_FILENAME 250 251 Notes: 252 Unlike almost all other PETSc routines, PETSC_VIEWER_MATLAB_ does not return 253 an error code. The matlab PetscViewer is usually used in the form 254 $ XXXView(XXX object,PETSC_VIEWER_MATLAB_(comm)); 255 256 Use PETSC_VIEWER_SOCKET_() or PetscViewerSocketOpen() to communicator with an interactive MATLAB session. 257 258 .seealso: PETSC_VIEWER_MATLAB_WORLD, PETSC_VIEWER_MATLAB_SELF, PetscViewerMatlabOpen(), PetscViewerCreate(), 259 PetscViewerDestroy() 260 @*/ 261 PetscViewer PETSC_VIEWER_MATLAB_(MPI_Comm comm) 262 { 263 PetscErrorCode ierr; 264 PetscBool flg; 265 PetscViewer viewer; 266 char fname[PETSC_MAX_PATH_LEN]; 267 MPI_Comm ncomm; 268 269 PetscFunctionBegin; 270 ierr = PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 271 if (Petsc_Viewer_Matlab_keyval == MPI_KEYVAL_INVALID) { 272 ierr = MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Matlab_keyval,0); 273 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 274 } 275 ierr = MPI_Comm_get_attr(ncomm,Petsc_Viewer_Matlab_keyval,(void**)&viewer,(int*)&flg); 276 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 277 if (!flg) { /* PetscViewer not yet created */ 278 ierr = PetscOptionsGetenv(ncomm,"PETSC_VIEWER_MATLAB_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg); 279 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);} 280 if (!flg) { 281 ierr = PetscStrcpy(fname,"matlaboutput.mat"); 282 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);} 283 } 284 ierr = PetscViewerMatlabOpen(ncomm,fname,FILE_MODE_WRITE,&viewer); 285 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);} 286 ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 287 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);} 288 ierr = MPI_Comm_set_attr(ncomm,Petsc_Viewer_Matlab_keyval,(void*)viewer); 289 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 290 } 291 ierr = PetscCommDestroy(&ncomm); 292 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_MATLAB_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);} 293 PetscFunctionReturn(viewer); 294 } 295 296 297 298 299 300