Date: 2022-03-31T04:45:58+00:00

Actual source code: viewreg.c

      2: #include <petsc/private/viewerimpl.h>
      3: #include <petsc/private/hashtable.h>
      4: #if defined(PETSC_HAVE_SAWS)
      5: #include <petscviewersaws.h>
      6: #endif

      8: PetscFunctionList PetscViewerList = NULL;

     10: PetscOptionsHelpPrinted PetscOptionsHelpPrintedSingleton = NULL;
     11: KHASH_SET_INIT_STR(HTPrinted)
     12: struct  _n_PetscOptionsHelpPrinted{
     13:   khash_t(HTPrinted) *printed;
     14:   PetscSegBuffer     strings;
     15: };

     17: PetscErrorCode PetscOptionsHelpPrintedDestroy(PetscOptionsHelpPrinted *hp)
     18: {
     19:   if (!*hp) return 0;
     20:   kh_destroy(HTPrinted,(*hp)->printed);
     21:   PetscSegBufferDestroy(&(*hp)->strings);
     22:   PetscFree(*hp);
     23:   return 0;
     24: }

     26: /*@C
     27:       PetscOptionsHelpPrintedCreate - Creates an object used to manage tracking which help messages have
     28:          been printed so they will not be printed again.

     30:      Not collective

     32:     Level: developer

     34: .seealso: PetscOptionsHelpPrintedCheck(), PetscOptionsHelpPrintChecked()
     35: @*/
     36: PetscErrorCode PetscOptionsHelpPrintedCreate(PetscOptionsHelpPrinted *hp)
     37: {
     38:   PetscNew(hp);
     39:   (*hp)->printed = kh_init(HTPrinted);
     40:   PetscSegBufferCreate(sizeof(char),10000,&(*hp)->strings);
     41:   return 0;
     42: }

     44: /*@C
     45:       PetscOptionsHelpPrintedCheck - Checks if a particular pre, name pair has previous been entered (meaning the help message was printed)

     47:      Not collective

     49:     Input Parameters:
     50: +     hp - the object used to manage tracking what help messages have been printed
     51: .     pre - the prefix part of the string, many be NULL
     52: -     name - the string to look for (cannot be NULL)

     54:     Output Parameter:
     55: .     found - PETSC_TRUE if the string was already set

     57:     Level: intermediate

     59: .seealso: PetscOptionsHelpPrintedCreate()
     60: @*/
     61: PetscErrorCode PetscOptionsHelpPrintedCheck(PetscOptionsHelpPrinted hp,const char *pre,const char* name,PetscBool *found)
     62: {
     63:   size_t          l1,l2;
     64: #if !defined(PETSC_HAVE_THREADSAFETY)
     65:   char            *both;
     66:   int             newitem;
     67: #endif

     69:   PetscStrlen(pre,&l1);
     70:   PetscStrlen(name,&l2);
     71:   if (l1+l2 == 0) {
     72:     *found = PETSC_FALSE;
     73:     return 0;
     74:   }
     75: #if !defined(PETSC_HAVE_THREADSAFETY)
     76:   PetscSegBufferGet(hp->strings,l1+l2+1,&both);
     77:   PetscStrcpy(both,pre);
     78:   PetscStrcat(both,name);
     79:   kh_put(HTPrinted,hp->printed,both,&newitem);
     80:   if (!newitem) {
     81:     PetscSegBufferUnuse(hp->strings,l1+l2+1);
     82:   }
     83:   *found = newitem ? PETSC_FALSE : PETSC_TRUE;
     84: #else
     85:   *found = PETSC_FALSE;
     86: #endif
     87:   return 0;
     88: }

     90: static PetscBool noviewer = PETSC_FALSE;
     91: static PetscBool noviewers[PETSCVIEWERGETVIEWEROFFPUSHESMAX];
     92: static PetscInt  inoviewers = 0;

     94: /*@
     95:   PetscOptionsPushGetViewerOff - control whether PetscOptionsGetViewer returns a viewer.

     97:   Logically Collective

     99:   Input Parameter:
    100: . flg - PETSC_TRUE to turn off viewer creation, PETSC_FALSE to turn it on.

    102:   Level: developer

    104:   Notes:
    105:     Calling XXXViewFromOptions in an inner loop can be very expensive.  This can appear, for example, when using
    106:    many small subsolves.  Call this function to control viewer creation in PetscOptionsGetViewer, thus removing the expensive XXXViewFromOptions calls.

    108: .seealso: PetscOptionsGetViewer(), PetscOptionsPopGetViewerOff()
    109: @*/
    110: PetscErrorCode  PetscOptionsPushGetViewerOff(PetscBool flg)
    111: {

    114:   noviewers[inoviewers++] = noviewer;
    115:   noviewer = flg;
    116:   return 0;
    117: }

    119: /*@
    120:   PetscOptionsPopGetViewerOff - reset whether PetscOptionsGetViewer returns a viewer.

    122:   Logically Collective

    124:   Level: developer

    126:   Notes:
    127:     Calling XXXViewFromOptions in an inner loop can be very expensive.  This can appear, for example, when using
    128:    many small subsolves.  Call this function to control viewer creation in PetscOptionsGetViewer, thus removing the expensive XXXViewFromOptions calls.

    130: .seealso: PetscOptionsGetViewer(), PetscOptionsPushGetViewerOff()
    131: @*/
    132: PetscErrorCode  PetscOptionsPopGetViewerOff(void)
    133: {
    135:   noviewer = noviewers[--inoviewers];
    136:   return 0;
    137: }

    139: /*@
    140:   PetscOptionsGetViewerOff - does PetscOptionsGetViewer return a viewer?

    142:   Logically Collective

    144:   Output Parameter:
    145: . flg - whether viewers are returned.

    147:   Level: developer

    149:   Notes:
    150:     Calling XXXViewFromOptions in an inner loop can be very expensive.  This can appear, for example, when using
    151:    many small subsolves.

    153: .seealso: PetscOptionsGetViewer(), PetscOptionsPushGetViewerOff(), PetscOptionsPopGetViewerOff()
    154: @*/
    155: PetscErrorCode  PetscOptionsGetViewerOff(PetscBool *flg)
    156: {
    158:   *flg = noviewer;
    159:   return 0;
    160: }

    162: /*@C
    163:    PetscOptionsGetViewer - Gets a viewer appropriate for the type indicated by the user

    165:    Collective

    167:    Input Parameters:
    168: +  comm - the communicator to own the viewer
    169: .  options - options database, use NULL for default global database
    170: .  pre - the string to prepend to the name or NULL
    171: -  name - the option one is seeking

    173:    Output Parameters:
    174: +  viewer - the viewer, pass NULL if not needed
    175: .  format - the PetscViewerFormat requested by the user, pass NULL if not needed
    176: -  set - PETSC_TRUE if found, else PETSC_FALSE

    178:    Level: intermediate

    180:    Notes:
    181:     If no value is provided ascii:stdout is used
    182: $       ascii[:[filename][:[format][:append]]]    defaults to stdout - format can be one of ascii_info, ascii_info_detail, or ascii_matlab,
    183:                                                   for example ascii::ascii_info prints just the information about the object not all details
    184:                                                   unless :append is given filename opens in write mode, overwriting what was already there
    185: $       binary[:[filename][:[format][:append]]]   defaults to the file binaryoutput
    186: $       draw[:drawtype[:filename]]                for example, draw:tikz, draw:tikz:figure.tex  or draw:x
    187: $       socket[:port]                             defaults to the standard output port
    188: $       saws[:communicatorname]                    publishes object to the Scientific Application Webserver (SAWs)

    190:    Use PetscViewerDestroy() after using the viewer, otherwise a memory leak will occur

    192:    You can control whether calls to this function create a viewer (or return early with *set of PETSC_FALSE) with
    193:    PetscOptionsPushGetViewerOff.  This is useful if calling many small subsolves, in which case XXXViewFromOptions can take
    194:    an appreciable fraction of the runtime.

    196:    If PETSc is configured with --with-viewfromoptions=0 this function always returns with *set of PETSC_FALSE

    198: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
    199:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
    200:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
    201:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    202:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    203:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    204:           PetscOptionsFList(), PetscOptionsEList(), PetscOptionsPushGetViewerOff(), PetscOptionsPopGetViewerOff(),
    205:           PetscOptionsGetViewerOff()
    206: @*/
    207: PetscErrorCode  PetscOptionsGetViewer(MPI_Comm comm,PetscOptions options,const char pre[],const char name[],PetscViewer *viewer,PetscViewerFormat *format,PetscBool  *set)
    208: {
    209:   const char                     *value;
    210:   PetscBool                      flag,hashelp;

    214:   if (viewer) *viewer = NULL;
    215:   if (format) *format = PETSC_VIEWER_DEFAULT;
    216:   if (set)    *set    = PETSC_FALSE;
    217:   PetscOptionsGetViewerOff(&flag);
    218:   if (flag) return 0;

    220:   PetscOptionsHasHelp(NULL,&hashelp);
    221:   if (hashelp) {
    222:     PetscBool found;

    224:     if (!PetscOptionsHelpPrintedSingleton) {
    225:       PetscOptionsHelpPrintedCreate(&PetscOptionsHelpPrintedSingleton);
    226:     }
    227:     PetscOptionsHelpPrintedCheck(PetscOptionsHelpPrintedSingleton,pre,name,&found);
    228:     if (!found && viewer) {
    229:       (*PetscHelpPrintf)(comm,"----------------------------------------\nViewer (-%s%s) options:\n",pre ? pre : "",name+1);
    230:       (*PetscHelpPrintf)(comm,"  -%s%s ascii[:[filename][:[format][:append]]]: %s (%s)\n",pre ? pre : "",name+1,"Prints object to stdout or ASCII file","PetscOptionsGetViewer");
    231:       (*PetscHelpPrintf)(comm,"  -%s%s binary[:[filename][:[format][:append]]]: %s (%s)\n",pre ? pre : "",name+1,"Saves object to a binary file","PetscOptionsGetViewer");
    232:       (*PetscHelpPrintf)(comm,"  -%s%s draw[:[drawtype][:filename|format]] %s (%s)\n",pre ? pre : "",name+1,"Draws object","PetscOptionsGetViewer");
    233:       (*PetscHelpPrintf)(comm,"  -%s%s socket[:port]: %s (%s)\n",pre ? pre : "",name+1,"Pushes object to a Unix socket","PetscOptionsGetViewer");
    234:       (*PetscHelpPrintf)(comm,"  -%s%s saws[:communicatorname]: %s (%s)\n",pre ? pre : "",name+1,"Publishes object to SAWs","PetscOptionsGetViewer");
    235:     }
    236:   }

    238:   if (format) *format = PETSC_VIEWER_DEFAULT;
    239:   PetscOptionsFindPair(options,pre,name,&value,&flag);
    240:   if (flag) {
    241:     if (set) *set = PETSC_TRUE;
    242:     if (!value) {
    243:       if (viewer) {
    244:         PetscViewerASCIIGetStdout(comm,viewer);
    245:         PetscObjectReference((PetscObject)*viewer);
    246:       }
    247:     } else {
    248:       char       *loc0_vtype,*loc1_fname,*loc2_fmt = NULL,*loc3_fmode = NULL;
    249:       PetscInt   cnt;
    250:       const char *viewers[] = {PETSCVIEWERASCII,PETSCVIEWERBINARY,PETSCVIEWERDRAW,PETSCVIEWERSOCKET,PETSCVIEWERMATLAB,PETSCVIEWERSAWS,PETSCVIEWERVTK,PETSCVIEWERHDF5,PETSCVIEWERGLVIS,PETSCVIEWEREXODUSII,NULL};

    252:       PetscStrallocpy(value,&loc0_vtype);
    253:       PetscStrchr(loc0_vtype,':',&loc1_fname);
    254:       if (loc1_fname) {
    255:         *loc1_fname++ = 0;
    256:         PetscStrchr(loc1_fname,':',&loc2_fmt);
    257:       }
    258:       if (loc2_fmt) {
    259:         *loc2_fmt++ = 0;
    260:         PetscStrchr(loc2_fmt,':',&loc3_fmode);
    261:       }
    262:       if (loc3_fmode) *loc3_fmode++ = 0;
    263:       PetscStrendswithwhich(*loc0_vtype ? loc0_vtype : "ascii",viewers,&cnt);
    265:       if (viewer) {
    266:         if (!loc1_fname) {
    267:           switch (cnt) {
    268:           case 0:
    269:             PetscViewerASCIIGetStdout(comm,viewer);
    270:             break;
    271:           case 1:
    272:             if (!(*viewer = PETSC_VIEWER_BINARY_(comm))) PETSC_ERR_PLIB;
    273:             break;
    274:           case 2:
    275:             if (!(*viewer = PETSC_VIEWER_DRAW_(comm))) PETSC_ERR_PLIB;
    276:             break;
    277: #if defined(PETSC_USE_SOCKET_VIEWER)
    278:           case 3:
    279:             if (!(*viewer = PETSC_VIEWER_SOCKET_(comm))) PETSC_ERR_PLIB;
    280:             break;
    281: #endif
    282: #if defined(PETSC_HAVE_MATLAB_ENGINE)
    283:           case 4:
    284:             if (!(*viewer = PETSC_VIEWER_MATLAB_(comm))) PETSC_ERR_PLIB;
    285:             break;
    286: #endif
    287: #if defined(PETSC_HAVE_SAWS)
    288:           case 5:
    289:             if (!(*viewer = PETSC_VIEWER_SAWS_(comm))) PETSC_ERR_PLIB;
    290:             break;
    291: #endif
    292: #if defined(PETSC_HAVE_HDF5)
    293:           case 7:
    294:             if (!(*viewer = PETSC_VIEWER_HDF5_(comm))) PETSC_ERR_PLIB;
    295:             break;
    296: #endif
    297:           case 8:
    298:             if (!(*viewer = PETSC_VIEWER_GLVIS_(comm))) PETSC_ERR_PLIB;
    299:             break;
    300: #if defined(PETSC_HAVE_EXODUSII)
    301:           case 9:
    302:             if (!(*viewer = PETSC_VIEWER_EXODUSII_(comm))) PETSC_ERR_PLIB;
    303:             break;
    304: #endif
    305:           default: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported viewer %s",loc0_vtype);
    306:           }
    307:           PetscObjectReference((PetscObject)*viewer);
    308:         } else {
    309:           if (loc2_fmt && !*loc1_fname && (cnt == 0)) { /* ASCII format without file name */
    310:             PetscViewerASCIIGetStdout(comm,viewer);
    311:             PetscObjectReference((PetscObject)*viewer);
    312:           } else {
    313:             PetscFileMode fmode;
    314:             PetscViewerCreate(comm,viewer);
    315:             PetscViewerSetType(*viewer,*loc0_vtype ? loc0_vtype : "ascii");
    316:             fmode = FILE_MODE_WRITE;
    317:             if (loc3_fmode && *loc3_fmode) { /* Has non-empty file mode ("write" or "append") */
    318:               PetscEnumFind(PetscFileModes,loc3_fmode,(PetscEnum*)&fmode,&flag);
    320:             }
    321:             if (loc2_fmt) {
    322:               PetscBool tk,im;
    323:               PetscStrcmp(loc1_fname,"tikz",&tk);
    324:               PetscStrcmp(loc1_fname,"image",&im);
    325:               if (tk || im) {
    326:                 PetscViewerDrawSetInfo(*viewer,NULL,loc2_fmt,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE);
    327:                 *loc2_fmt = 0;
    328:               }
    329:             }
    330:             PetscViewerFileSetMode(*viewer,flag?fmode:FILE_MODE_WRITE);
    331:             PetscViewerFileSetName(*viewer,loc1_fname);
    332:             if (*loc1_fname) {
    333:               PetscViewerDrawSetDrawType(*viewer,loc1_fname);
    334:             }
    335:             PetscViewerSetFromOptions(*viewer);
    336:           }
    337:         }
    338:       }
    339:       if (viewer) {
    340:         PetscViewerSetUp(*viewer);
    341:       }
    342:       if (loc2_fmt && *loc2_fmt) {
    343:         PetscViewerFormat tfmt;

    345:         PetscEnumFind(PetscViewerFormats,loc2_fmt,(PetscEnum*)&tfmt,&flag);
    346:         if (format) *format = tfmt;
    348:       } else if (viewer && (cnt == 6) && format) { /* Get format from VTK viewer */
    349:         PetscViewerGetFormat(*viewer,format);
    350:       }
    351:       PetscFree(loc0_vtype);
    352:     }
    353:   }
    354:   return 0;
    355: }

    357: /*@
    358:    PetscViewerCreate - Creates a viewing context

    360:    Collective

    362:    Input Parameter:
    363: .  comm - MPI communicator

    365:    Output Parameter:
    366: .  inviewer - location to put the PetscViewer context

    368:    Level: advanced

    370: .seealso: PetscViewerDestroy(), PetscViewerSetType(), PetscViewerType

    372: @*/
    373: PetscErrorCode  PetscViewerCreate(MPI_Comm comm,PetscViewer *inviewer)
    374: {
    375:   PetscViewer    viewer;

    377:   *inviewer = NULL;
    378:   PetscViewerInitializePackage();
    379:   PetscHeaderCreate(viewer,PETSC_VIEWER_CLASSID,"PetscViewer","PetscViewer","Viewer",comm,PetscViewerDestroy,PetscViewerView);
    380:   *inviewer    = viewer;
    381:   viewer->data = NULL;
    382:   return 0;
    383: }

    385: /*@C
    386:    PetscViewerSetType - Builds PetscViewer for a particular implementation.

    388:    Collective on PetscViewer

    390:    Input Parameters:
    391: +  viewer      - the PetscViewer context
    392: -  type        - for example, PETSCVIEWERASCII

    394:    Options Database Command:
    395: .  -viewer_type  <type> - Sets the type; use -help for a list
    396:     of available methods (for instance, ascii)

    398:    Level: advanced

    400:    Notes:
    401:    See "include/petscviewer.h" for available methods (for instance,
    402:    PETSCVIEWERSOCKET)

    404: .seealso: PetscViewerCreate(), PetscViewerGetType(), PetscViewerType, PetscViewerPushFormat()
    405: @*/
    406: PetscErrorCode  PetscViewerSetType(PetscViewer viewer,PetscViewerType type)
    407: {
    408:   PetscBool      match;
    409:   PetscErrorCode (*r)(PetscViewer);

    413:   PetscObjectTypeCompare((PetscObject)viewer,type,&match);
    414:   if (match) return 0;

    416:   /* cleanup any old type that may be there */
    417:   if (viewer->data) {
    418:     (*viewer->ops->destroy)(viewer);

    420:     viewer->ops->destroy = NULL;
    421:     viewer->data         = NULL;
    422:   }
    423:   PetscMemzero(viewer->ops,sizeof(struct _PetscViewerOps));

    425:   PetscFunctionListFind(PetscViewerList,type,&r);

    428:   PetscObjectChangeTypeName((PetscObject)viewer,type);
    429:   (*r)(viewer);
    430:   return 0;
    431: }

    433: /*@C
    434:    PetscViewerRegister - Adds a viewer

    436:    Not Collective

    438:    Input Parameters:
    439: +  name_solver - name of a new user-defined viewer
    440: -  routine_create - routine to create method context

    442:    Level: developer
    443:    Notes:
    444:    PetscViewerRegister() may be called multiple times to add several user-defined viewers.

    446:    Sample usage:
    447: .vb
    448:    PetscViewerRegister("my_viewer_type",MyViewerCreate);
    449: .ve

    451:    Then, your solver can be chosen with the procedural interface via
    452: $     PetscViewerSetType(viewer,"my_viewer_type")
    453:    or at runtime via the option
    454: $     -viewer_type my_viewer_type

    456: .seealso: PetscViewerRegisterAll()
    457:  @*/
    458: PetscErrorCode  PetscViewerRegister(const char *sname,PetscErrorCode (*function)(PetscViewer))
    459: {
    460:   PetscViewerInitializePackage();
    461:   PetscFunctionListAdd(&PetscViewerList,sname,function);
    462:   return 0;
    463: }

    465: /*@C
    466:    PetscViewerSetFromOptions - Sets the graphics type from the options database.
    467:       Defaults to a PETSc X windows graphics.

    469:    Collective on PetscViewer

    471:    Input Parameter:
    472: .     PetscViewer - the graphics context

    474:    Level: intermediate

    476:    Notes:
    477:     Must be called after PetscViewerCreate() before the PetscViewer is used.

    479: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerType

    481: @*/
    482: PetscErrorCode  PetscViewerSetFromOptions(PetscViewer viewer)
    483: {
    484:   PetscErrorCode    ierr;
    485:   char              vtype[256];
    486:   PetscBool         flg;

    490:   if (!PetscViewerList) {
    491:     PetscViewerRegisterAll();
    492:   }
    493:   PetscObjectOptionsBegin((PetscObject)viewer);
    494:   PetscOptionsFList("-viewer_type","Type of PetscViewer","None",PetscViewerList,(char*)(((PetscObject)viewer)->type_name ? ((PetscObject)viewer)->type_name : PETSCVIEWERASCII),vtype,256,&flg);
    495:   if (flg) {
    496:     PetscViewerSetType(viewer,vtype);
    497:   }
    498:   /* type has not been set? */
    499:   if (!((PetscObject)viewer)->type_name) {
    500:     PetscViewerSetType(viewer,PETSCVIEWERASCII);
    501:   }
    502:   if (viewer->ops->setfromoptions) {
    503:     (*viewer->ops->setfromoptions)(PetscOptionsObject,viewer);
    504:   }

    506:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
    507:   PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)viewer);
    508:   PetscViewerViewFromOptions(viewer,NULL,"-viewer_view");
    509:   PetscOptionsEnd();
    510:   return 0;
    511: }

    513: PetscErrorCode PetscViewerFlowControlStart(PetscViewer viewer,PetscInt *mcnt,PetscInt *cnt)
    514: {
    515:   PetscViewerBinaryGetFlowControl(viewer,mcnt);
    516:   PetscViewerBinaryGetFlowControl(viewer,cnt);
    517:   return 0;
    518: }

    520: PetscErrorCode PetscViewerFlowControlStepMain(PetscViewer viewer,PetscInt i,PetscInt *mcnt,PetscInt cnt)
    521: {
    522:   MPI_Comm       comm;

    524:   PetscObjectGetComm((PetscObject)viewer,&comm);
    525:   if (i >= *mcnt) {
    526:     *mcnt += cnt;
    527:     MPI_Bcast(mcnt,1,MPIU_INT,0,comm);
    528:   }
    529:   return 0;
    530: }

    532: PetscErrorCode PetscViewerFlowControlEndMain(PetscViewer viewer,PetscInt *mcnt)
    533: {
    534:   MPI_Comm       comm;
    535:   PetscObjectGetComm((PetscObject)viewer,&comm);
    536:   *mcnt = 0;
    537:   MPI_Bcast(mcnt,1,MPIU_INT,0,comm);
    538:   return 0;
    539: }

    541: PetscErrorCode PetscViewerFlowControlStepWorker(PetscViewer viewer,PetscMPIInt rank,PetscInt *mcnt)
    542: {
    543:   MPI_Comm       comm;
    544:   PetscObjectGetComm((PetscObject)viewer,&comm);
    545:   while (PETSC_TRUE) {
    546:     if (rank < *mcnt) break;
    547:     MPI_Bcast(mcnt,1,MPIU_INT,0,comm);
    548:   }
    549:   return 0;
    550: }

    552: PetscErrorCode PetscViewerFlowControlEndWorker(PetscViewer viewer,PetscInt *mcnt)
    553: {
    554:   MPI_Comm       comm;
    555:   PetscObjectGetComm((PetscObject)viewer,&comm);
    556:   while (PETSC_TRUE) {
    557:     MPI_Bcast(mcnt,1,MPIU_INT,0,comm);
    558:     if (!*mcnt) break;
    559:   }
    560:   return 0;
    561: }