1 2 #include <petsc/private/viewerimpl.h> /*I "petscviewer.h" I*/ 3 #if defined(PETSC_HAVE_SAWS) 4 #include <petscviewersaws.h> 5 #endif 6 7 PetscFunctionList PetscViewerList = 0; 8 9 /* 10 Use a hash set to prevent the same help message from being printed multiple times 11 */ 12 13 #include "../src/sys/utils/hash.h" 14 15 KHASH_SET_INIT_STR(PetscOptionsGetViewerPrinted) 16 static khash_t(PetscOptionsGetViewerPrinted) *PrintedOptions = NULL; 17 static PetscSegBuffer strings = NULL; 18 19 static PetscErrorCode PetscOptionsGetViewerPrintedDestroy(void) 20 { 21 PetscErrorCode ierr; 22 kh_destroy(PetscOptionsGetViewerPrinted,PrintedOptions); 23 ierr = PetscSegBufferDestroy(&strings);CHKERRQ(ierr); 24 return 0; 25 } 26 27 #undef __FUNCT__ 28 #define __FUNCT__ "PetscOptionsGetViewer" 29 /*@C 30 PetscOptionsGetViewer - Gets a viewer appropriate for the type indicated by the user 31 32 Collective on MPI_Comm 33 34 Input Parameters: 35 + comm - the communicator to own the viewer 36 . pre - the string to prepend to the name or NULL 37 - name - the option one is seeking 38 39 Output Parameter: 40 + viewer - the viewer, pass NULL if not needed 41 . format - the PetscViewerFormat requested by the user, pass NULL if not needed 42 - set - PETSC_TRUE if found, else PETSC_FALSE 43 44 Level: intermediate 45 46 Notes: If no value is provided ascii:stdout is used 47 $ ascii[:[filename][:[format][:append]]] defaults to stdout - format can be one of ascii_info, ascii_info_detail, or ascii_matlab, 48 for example ascii::ascii_info prints just the information about the object not all details 49 unless :append is given filename opens in write mode, overwriting what was already there 50 $ binary[:[filename][:[format][:append]]] defaults to the file binaryoutput 51 $ draw[:drawtype] for example, draw:tikz or draw:x 52 $ socket[:port] defaults to the standard output port 53 $ saws[:communicatorname] publishes object to the Scientific Application Webserver (SAWs) 54 55 Use PetscViewerDestroy() after using the viewer, otherwise a memory leak will occur 56 57 If PETSc is configured with --with-viewfromoptions=0 this function always returns with *set of PETSC_FALSE 58 59 .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), 60 PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool() 61 PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), 62 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 63 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 64 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 65 PetscOptionsFList(), PetscOptionsEList() 66 @*/ 67 PetscErrorCode PetscOptionsGetViewer(MPI_Comm comm,const char pre[],const char name[],PetscViewer *viewer,PetscViewerFormat *format,PetscBool *set) 68 { 69 char *value; 70 PetscErrorCode ierr; 71 PetscBool flag,hashelp; 72 73 PetscFunctionBegin; 74 PetscValidCharPointer(name,3); 75 76 if (set) *set = PETSC_FALSE; 77 #if defined(PETSC_SKIP_VIEWFROMOPTIONS) 78 PetscFunctionReturn(0); 79 #endif 80 81 ierr = PetscOptionsHasName(NULL,NULL,"-help",&hashelp);CHKERRQ(ierr); 82 if (hashelp) { 83 khint_t newitem; 84 if (!PrintedOptions) { 85 PrintedOptions = kh_init(PetscOptionsGetViewerPrinted); 86 ierr = PetscSegBufferCreate(sizeof(char),10000,&strings);CHKERRQ(ierr); 87 ierr = PetscRegisterFinalize(PetscOptionsGetViewerPrintedDestroy);CHKERRQ(ierr); 88 } 89 if (!pre) { 90 kh_put(PetscOptionsGetViewerPrinted,PrintedOptions,name+1,&newitem); 91 } else { 92 size_t l1,l2; 93 char *both; 94 95 ierr = PetscStrlen(pre,&l1);CHKERRQ(ierr); 96 ierr = PetscStrlen(name+1,&l2);CHKERRQ(ierr); 97 ierr = PetscSegBufferGet(strings,l1+l2+1,&both);CHKERRQ(ierr); 98 ierr = PetscStrcpy(both,pre);CHKERRQ(ierr); 99 ierr = PetscStrcat(both,name+1);CHKERRQ(ierr); 100 kh_put(PetscOptionsGetViewerPrinted,PrintedOptions,both,&newitem); 101 } 102 if (newitem) { 103 if (viewer) { 104 ierr = (*PetscHelpPrintf)(comm,"\n -%s%s ascii[:[filename][:[format][:append]]]: %s (%s)\n",pre ? pre : "",name+1,"Prints object to stdout or ASCII file","PetscOptionsGetViewer");CHKERRQ(ierr); 105 ierr = (*PetscHelpPrintf)(comm," -%s%s binary[:[filename][:[format][:append]]]: %s (%s)\n",pre ? pre : "",name+1,"Saves object to a binary file","PetscOptionsGetViewer");CHKERRQ(ierr); 106 ierr = (*PetscHelpPrintf)(comm," -%s%s draw[:drawtype]: %s (%s)\n",pre ? pre : "",name+1,"Draws object","PetscOptionsGetViewer");CHKERRQ(ierr); 107 ierr = (*PetscHelpPrintf)(comm," -%s%s socket[:port]: %s (%s)\n",pre ? pre : "",name+1,"Pushes object to a Unix socket","PetscOptionsGetViewer");CHKERRQ(ierr); 108 ierr = (*PetscHelpPrintf)(comm," -%s%s saws[:communicatorname]: %s (%s)\n\n",pre ? pre : "",name+1,"Publishes object to SAWs","PetscOptionsGetViewer");CHKERRQ(ierr); 109 } else { 110 ierr = (*PetscHelpPrintf)(comm," -%s%s\n",pre ? pre : "",name+1);CHKERRQ(ierr); 111 } 112 } 113 } 114 115 if (format) *format = PETSC_VIEWER_DEFAULT; 116 ierr = PetscOptionsFindPair_Private(NULL,pre,name,&value,&flag);CHKERRQ(ierr); 117 if (flag) { 118 if (set) *set = PETSC_TRUE; 119 if (!value) { 120 if (viewer) { 121 ierr = PetscViewerASCIIGetStdout(comm,viewer);CHKERRQ(ierr); 122 ierr = PetscObjectReference((PetscObject)*viewer);CHKERRQ(ierr); 123 } 124 } else { 125 char *loc0_vtype,*loc1_fname,*loc2_fmt = NULL,*loc3_fmode = NULL; 126 PetscInt cnt; 127 const char *viewers[] = {PETSCVIEWERASCII,PETSCVIEWERBINARY,PETSCVIEWERDRAW,PETSCVIEWERSOCKET,PETSCVIEWERMATLAB,PETSCVIEWERSAWS,PETSCVIEWERVTK,PETSCVIEWERHDF5,0}; 128 129 ierr = PetscStrallocpy(value,&loc0_vtype);CHKERRQ(ierr); 130 ierr = PetscStrchr(loc0_vtype,':',&loc1_fname);CHKERRQ(ierr); 131 if (loc1_fname) { 132 *loc1_fname++ = 0; 133 ierr = PetscStrchr(loc1_fname,':',&loc2_fmt);CHKERRQ(ierr); 134 } 135 if (loc2_fmt) { 136 *loc2_fmt++ = 0; 137 ierr = PetscStrchr(loc2_fmt,':',&loc3_fmode);CHKERRQ(ierr); 138 } 139 if (loc3_fmode) *loc3_fmode++ = 0; 140 ierr = PetscStrendswithwhich(*loc0_vtype ? loc0_vtype : "ascii",viewers,&cnt);CHKERRQ(ierr); 141 if (cnt > (PetscInt) sizeof(viewers)-1) SETERRQ1(comm,PETSC_ERR_ARG_OUTOFRANGE,"Unknown viewer type: %s",loc0_vtype); 142 if (viewer) { 143 if (!loc1_fname) { 144 switch (cnt) { 145 case 0: 146 ierr = PetscViewerASCIIGetStdout(comm,viewer);CHKERRQ(ierr); 147 break; 148 case 1: 149 if (!(*viewer = PETSC_VIEWER_BINARY_(comm))) CHKERRQ(PETSC_ERR_PLIB); 150 break; 151 case 2: 152 if (!(*viewer = PETSC_VIEWER_DRAW_(comm))) CHKERRQ(PETSC_ERR_PLIB); 153 break; 154 #if defined(PETSC_USE_SOCKET_VIEWER) 155 case 3: 156 if (!(*viewer = PETSC_VIEWER_SOCKET_(comm))) CHKERRQ(PETSC_ERR_PLIB); 157 break; 158 #endif 159 #if defined(PETSC_HAVE_MATLAB_ENGINE) 160 case 4: 161 if (!(*viewer = PETSC_VIEWER_MATLAB_(comm))) CHKERRQ(PETSC_ERR_PLIB); 162 break; 163 #endif 164 #if defined(PETSC_HAVE_SAWS) 165 case 5: 166 if (!(*viewer = PETSC_VIEWER_SAWS_(comm))) CHKERRQ(PETSC_ERR_PLIB); 167 break; 168 #endif 169 #if defined(PETSC_HAVE_HDF5) 170 case 7: 171 if (!(*viewer = PETSC_VIEWER_HDF5_(comm))) CHKERRQ(PETSC_ERR_PLIB); 172 break; 173 #endif 174 default: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported viewer %s",loc0_vtype); 175 } 176 ierr = PetscObjectReference((PetscObject)*viewer);CHKERRQ(ierr); 177 } else { 178 if (loc2_fmt && !*loc1_fname && (cnt == 0)) { /* ASCII format without file name */ 179 ierr = PetscViewerASCIIGetStdout(comm,viewer);CHKERRQ(ierr); 180 ierr = PetscObjectReference((PetscObject)*viewer);CHKERRQ(ierr); 181 } else { 182 PetscFileMode fmode; 183 ierr = PetscViewerCreate(comm,viewer);CHKERRQ(ierr); 184 ierr = PetscViewerSetType(*viewer,*loc0_vtype ? loc0_vtype : "ascii");CHKERRQ(ierr); 185 fmode = FILE_MODE_WRITE; 186 if (loc3_fmode && *loc3_fmode) { /* Has non-empty file mode ("write" or "append") */ 187 ierr = PetscEnumFind(PetscFileModes,loc3_fmode,(PetscEnum*)&fmode,&flag);CHKERRQ(ierr); 188 if (!flag) SETERRQ1(comm,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown file mode: %s",loc3_fmode); 189 } 190 ierr = PetscViewerFileSetMode(*viewer,flag?fmode:FILE_MODE_WRITE);CHKERRQ(ierr); 191 ierr = PetscViewerFileSetName(*viewer,loc1_fname);CHKERRQ(ierr); 192 ierr = PetscViewerDrawSetDrawType(*viewer,loc1_fname);CHKERRQ(ierr); 193 } 194 } 195 } 196 if (viewer) { 197 ierr = PetscViewerSetUp(*viewer);CHKERRQ(ierr); 198 } 199 if (loc2_fmt && *loc2_fmt) { 200 ierr = PetscEnumFind(PetscViewerFormats,loc2_fmt,(PetscEnum*)format,&flag);CHKERRQ(ierr); 201 if (!flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unknown viewer format %s",loc2_fmt);CHKERRQ(ierr); 202 } 203 ierr = PetscFree(loc0_vtype);CHKERRQ(ierr); 204 } 205 } 206 PetscFunctionReturn(0); 207 } 208 209 #undef __FUNCT__ 210 #define __FUNCT__ "PetscViewerCreate" 211 /*@ 212 PetscViewerCreate - Creates a viewing context 213 214 Collective on MPI_Comm 215 216 Input Parameter: 217 . comm - MPI communicator 218 219 Output Parameter: 220 . inviewer - location to put the PetscViewer context 221 222 Level: advanced 223 224 Concepts: graphics^creating PetscViewer 225 Concepts: file input/output^creating PetscViewer 226 Concepts: sockets^creating PetscViewer 227 228 .seealso: PetscViewerDestroy(), PetscViewerSetType(), PetscViewerType 229 230 @*/ 231 PetscErrorCode PetscViewerCreate(MPI_Comm comm,PetscViewer *inviewer) 232 { 233 PetscViewer viewer; 234 PetscErrorCode ierr; 235 236 PetscFunctionBegin; 237 *inviewer = 0; 238 ierr = PetscViewerInitializePackage();CHKERRQ(ierr); 239 ierr = PetscHeaderCreate(viewer,PETSC_VIEWER_CLASSID,"PetscViewer","PetscViewer","Viewer",comm,PetscViewerDestroy,NULL);CHKERRQ(ierr); 240 *inviewer = viewer; 241 viewer->data = 0; 242 PetscFunctionReturn(0); 243 } 244 245 #undef __FUNCT__ 246 #define __FUNCT__ "PetscViewerSetType" 247 /*@C 248 PetscViewerSetType - Builds PetscViewer for a particular implementation. 249 250 Collective on PetscViewer 251 252 Input Parameter: 253 + viewer - the PetscViewer context 254 - type - for example, PETSCVIEWERASCII 255 256 Options Database Command: 257 . -draw_type <type> - Sets the type; use -help for a list 258 of available methods (for instance, ascii) 259 260 Level: advanced 261 262 Notes: 263 See "include/petscviewer.h" for available methods (for instance, 264 PETSCVIEWERSOCKET) 265 266 .seealso: PetscViewerCreate(), PetscViewerGetType(), PetscViewerType, PetscViewerPushFormat() 267 @*/ 268 PetscErrorCode PetscViewerSetType(PetscViewer viewer,PetscViewerType type) 269 { 270 PetscErrorCode ierr,(*r)(PetscViewer); 271 PetscBool match; 272 273 PetscFunctionBegin; 274 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 275 PetscValidCharPointer(type,2); 276 ierr = PetscObjectTypeCompare((PetscObject)viewer,type,&match);CHKERRQ(ierr); 277 if (match) PetscFunctionReturn(0); 278 279 /* cleanup any old type that may be there */ 280 if (viewer->data) { 281 ierr = (*viewer->ops->destroy)(viewer);CHKERRQ(ierr); 282 283 viewer->ops->destroy = NULL; 284 viewer->data = 0; 285 } 286 ierr = PetscMemzero(viewer->ops,sizeof(struct _PetscViewerOps));CHKERRQ(ierr); 287 288 ierr = PetscFunctionListFind(PetscViewerList,type,&r);CHKERRQ(ierr); 289 if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown PetscViewer type given: %s",type); 290 291 ierr = PetscObjectChangeTypeName((PetscObject)viewer,type);CHKERRQ(ierr); 292 ierr = (*r)(viewer);CHKERRQ(ierr); 293 PetscFunctionReturn(0); 294 } 295 296 #undef __FUNCT__ 297 #define __FUNCT__ "PetscViewerRegister" 298 /*@C 299 PetscViewerRegister - Adds a viewer 300 301 Not Collective 302 303 Input Parameters: 304 + name_solver - name of a new user-defined viewer 305 - routine_create - routine to create method context 306 307 Level: developer 308 Notes: 309 PetscViewerRegister() may be called multiple times to add several user-defined viewers. 310 311 Sample usage: 312 .vb 313 PetscViewerRegister("my_viewer_type",MyViewerCreate); 314 .ve 315 316 Then, your solver can be chosen with the procedural interface via 317 $ PetscViewerSetType(viewer,"my_viewer_type") 318 or at runtime via the option 319 $ -viewer_type my_viewer_type 320 321 Concepts: registering^Viewers 322 323 .seealso: PetscViewerRegisterAll(), PetscViewerRegisterDestroy() 324 @*/ 325 PetscErrorCode PetscViewerRegister(const char *sname,PetscErrorCode (*function)(PetscViewer)) 326 { 327 PetscErrorCode ierr; 328 329 PetscFunctionBegin; 330 ierr = PetscFunctionListAdd(&PetscViewerList,sname,function);CHKERRQ(ierr); 331 PetscFunctionReturn(0); 332 } 333 334 #undef __FUNCT__ 335 #define __FUNCT__ "PetscViewerSetFromOptions" 336 /*@C 337 PetscViewerSetFromOptions - Sets the graphics type from the options database. 338 Defaults to a PETSc X windows graphics. 339 340 Collective on PetscViewer 341 342 Input Parameter: 343 . PetscViewer - the graphics context 344 345 Level: intermediate 346 347 Notes: 348 Must be called after PetscViewerCreate() before the PetscViewer is used. 349 350 Concepts: PetscViewer^setting options 351 352 .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerType 353 354 @*/ 355 PetscErrorCode PetscViewerSetFromOptions(PetscViewer viewer) 356 { 357 PetscErrorCode ierr; 358 char vtype[256]; 359 PetscBool flg; 360 361 PetscFunctionBegin; 362 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 363 364 if (!PetscViewerList) { 365 ierr = PetscViewerRegisterAll();CHKERRQ(ierr); 366 } 367 ierr = PetscObjectOptionsBegin((PetscObject)viewer);CHKERRQ(ierr); 368 ierr = PetscOptionsFList("-viewer_type","Type of PetscViewer","None",PetscViewerList,(char*)(((PetscObject)viewer)->type_name ? ((PetscObject)viewer)->type_name : PETSCVIEWERASCII),vtype,256,&flg);CHKERRQ(ierr); 369 if (flg) { 370 ierr = PetscViewerSetType(viewer,vtype);CHKERRQ(ierr); 371 } 372 /* type has not been set? */ 373 if (!((PetscObject)viewer)->type_name) { 374 ierr = PetscViewerSetType(viewer,PETSCVIEWERASCII);CHKERRQ(ierr); 375 } 376 if (viewer->ops->setfromoptions) { 377 ierr = (*viewer->ops->setfromoptions)(PetscOptionsObject,viewer);CHKERRQ(ierr); 378 } 379 380 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 381 ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)viewer);CHKERRQ(ierr); 382 ierr = PetscViewerViewFromOptions(viewer,NULL,"-viewer_view");CHKERRQ(ierr); 383 ierr = PetscOptionsEnd();CHKERRQ(ierr); 384 PetscFunctionReturn(0); 385 } 386 387 #undef __FUNCT__ 388 #define __FUNCT__ "PetscViewerFlowControlStart" 389 PetscErrorCode PetscViewerFlowControlStart(PetscViewer viewer,PetscInt *mcnt,PetscInt *cnt) 390 { 391 PetscErrorCode ierr; 392 PetscFunctionBegin; 393 ierr = PetscViewerBinaryGetFlowControl(viewer,mcnt);CHKERRQ(ierr); 394 ierr = PetscViewerBinaryGetFlowControl(viewer,cnt);CHKERRQ(ierr); 395 PetscFunctionReturn(0); 396 } 397 398 #undef __FUNCT__ 399 #define __FUNCT__ "PetscViewerFlowControlStepMaster" 400 PetscErrorCode PetscViewerFlowControlStepMaster(PetscViewer viewer,PetscInt i,PetscInt *mcnt,PetscInt cnt) 401 { 402 PetscErrorCode ierr; 403 MPI_Comm comm; 404 405 PetscFunctionBegin; 406 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 407 if (i >= *mcnt) { 408 *mcnt += cnt; 409 ierr = MPI_Bcast(mcnt,1,MPIU_INT,0,comm);CHKERRQ(ierr); 410 } 411 PetscFunctionReturn(0); 412 } 413 414 #undef __FUNCT__ 415 #define __FUNCT__ "PetscViewerFlowControlEndMaster" 416 PetscErrorCode PetscViewerFlowControlEndMaster(PetscViewer viewer,PetscInt *mcnt) 417 { 418 PetscErrorCode ierr; 419 MPI_Comm comm; 420 PetscFunctionBegin; 421 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 422 *mcnt = 0; 423 ierr = MPI_Bcast(mcnt,1,MPIU_INT,0,comm);CHKERRQ(ierr); 424 PetscFunctionReturn(0); 425 } 426 427 #undef __FUNCT__ 428 #define __FUNCT__ "PetscViewerFlowControlStepWorker" 429 PetscErrorCode PetscViewerFlowControlStepWorker(PetscViewer viewer,PetscMPIInt rank,PetscInt *mcnt) 430 { 431 PetscErrorCode ierr; 432 MPI_Comm comm; 433 PetscFunctionBegin; 434 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 435 while (PETSC_TRUE) { 436 if (rank < *mcnt) break; 437 ierr = MPI_Bcast(mcnt,1,MPIU_INT,0,comm);CHKERRQ(ierr); 438 } 439 PetscFunctionReturn(0); 440 } 441 442 #undef __FUNCT__ 443 #define __FUNCT__ "PetscViewerFlowControlEndWorker" 444 PetscErrorCode PetscViewerFlowControlEndWorker(PetscViewer viewer,PetscInt *mcnt) 445 { 446 PetscErrorCode ierr; 447 MPI_Comm comm; 448 PetscFunctionBegin; 449 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 450 while (PETSC_TRUE) { 451 ierr = MPI_Bcast(mcnt,1,MPIU_INT,0,comm);CHKERRQ(ierr); 452 if (!*mcnt) break; 453 } 454 PetscFunctionReturn(0); 455 } 456