Actual source code: drawreg.c


  2: /*
  3:        Provides the registration process for PETSc PetscDraw routines
  4: */
  5: #include <petsc/private/drawimpl.h>
  6: #include <petscviewer.h>
  7: #if defined(PETSC_HAVE_SAWS)
  8: #include <petscviewersaws.h>
  9: #endif

 11: /*
 12:    Contains the list of registered PetscDraw routines
 13: */
 14: PetscFunctionList PetscDrawList = NULL;

 16: /*@C
 17:    PetscDrawView - Prints the `PetscDraw` data structure.

 19:    Collective

 21:    Input Parameters:
 22: +  indraw - the `PetscDraw` context
 23: -  viewer - visualization context

 25:    See PetscDrawSetFromOptions() for options database keys

 27:    Note:
 28:    The available visualization contexts include
 29: +     `PETSC_VIEWER_STDOUT_SELF` - standard output (default)
 30: -     `PETSC_VIEWER_STDOUT_WORLD` - synchronized standard
 31:          output where only the first processor opens
 32:          the file.  All other processors send their
 33:          data to the first processor to print.

 35:    The user can open an alternative visualization context with
 36:    `PetscViewerASCIIOpen()` - output to a specified file.

 38:    Level: beginner

 40: .seealso: `PetscDraw`, `PetscViewerASCIIOpen()`, `PetscViewer`
 41: @*/
 42: PetscErrorCode PetscDrawView(PetscDraw indraw, PetscViewer viewer)
 43: {
 44:   PetscBool isdraw;
 45: #if defined(PETSC_HAVE_SAWS)
 46:   PetscBool issaws;
 47: #endif

 50:   if (!viewer) PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)indraw), &viewer);

 54:   PetscObjectPrintClassNamePrefixType((PetscObject)indraw, viewer);
 55:   PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw);
 56: #if defined(PETSC_HAVE_SAWS)
 57:   PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSAWS, &issaws);
 58: #endif
 59:   if (isdraw) {
 60:     PetscDraw draw;
 61:     char      str[36];
 62:     PetscReal x, y, bottom, h;

 64:     PetscViewerDrawGetDraw(viewer, 0, &draw);
 65:     PetscDrawGetCurrentPoint(draw, &x, &y);
 66:     PetscStrncpy(str, "PetscDraw: ", sizeof(str));
 67:     PetscStrlcat(str, ((PetscObject)indraw)->type_name, sizeof(str));
 68:     PetscDrawStringBoxed(draw, x, y, PETSC_DRAW_RED, PETSC_DRAW_BLACK, str, NULL, &h);
 69:     bottom = y - h;
 70:     PetscDrawPushCurrentPoint(draw, x, bottom);
 71: #if defined(PETSC_HAVE_SAWS)
 72:   } else if (issaws) {
 73:     PetscMPIInt rank;

 75:     PetscObjectName((PetscObject)indraw);
 76:     MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
 77:     if (!((PetscObject)indraw)->amsmem && rank == 0) PetscObjectViewSAWs((PetscObject)indraw, viewer);
 78: #endif
 79:   } else PetscTryTypeMethod(indraw, view, viewer);
 80:   return 0;
 81: }

 83: /*@C
 84:    PetscDrawViewFromOptions - View a `PetscDraw` from the option database

 86:    Collective

 88:    Input Parameters:
 89: +  A - the `PetscDraw` context
 90: .  obj - Optional object
 91: -  name - command line option

 93:    Level: intermediate
 94: .seealso: `PetscDraw`, `PetscDrawView`, `PetscObjectViewFromOptions()`, `PetscDrawCreate()`
 95: @*/
 96: PetscErrorCode PetscDrawViewFromOptions(PetscDraw A, PetscObject obj, const char name[])
 97: {
 99:   PetscObjectViewFromOptions((PetscObject)A, obj, name);
100:   return 0;
101: }

103: /*@C
104:    PetscDrawCreate - Creates a graphics context.

106:    Collective

108:    Input Parameters:
109: +  comm - MPI communicator
110: .  display - X display when using X Windows
111: .  title - optional title added to top of window
112: .  x,y - coordinates of lower left corner of window or `PETSC_DECIDE`
113: -  w, h - width and height of window or `PETSC_DECIDE` or `PETSC_DRAW_HALF_SIZE`, `PETSC_DRAW_FULL_SIZE`,
114:           or `PETSC_DRAW_THIRD_SIZE` or `PETSC_DRAW_QUARTER_SIZE`

116:    Output Parameter:
117: .  draw - location to put the `PetscDraw` context

119:    Level: beginner

121: .seealso: `PetscDrawSetType()`, `PetscDrawSetFromOptions()`, `PetscDrawDestroy()`, `PetscDrawSetType()`, `PetscDrawLGCreate()`, `PetscDrawSPCreate()`,
122:           `PetscDrawViewPortsCreate()`, `PetscDrawViewPortsSet()`, `PetscDrawAxisCreate()`, `PetscDrawHGCreate()`, `PetscDrawBarCreate()`,
123:           `PetscViewerDrawGetDraw()`, `PetscDrawSetFromOptions()`, `PetscDrawSetSave()`, `PetscDrawSetSaveMovie()`, `PetscDrawSetSaveFinalImage()`,
124:           `PetscDrawOpenX()`, `PetscDrawOpenImage()`, `PetscDrawIsNull()`, `PetscDrawGetPopup()`, `PetscDrawCheckResizedWindow()`, `PetscDrawResizeWindow()`,
125:           `PetscDrawGetWindowSize()`, `PetscDrawLine()`, `PetscDrawArrow()`, `PetscDrawLineSetWidth()`, `PetscDrawLineGetWidth()`, `PetscDrawMarker()`,
126:           `PetscDrawPoint()`, `PetscDrawRectangle()`, `PetscDrawTriangle()`, `PetscDrawEllipse()`, `PetscDrawString()`, `PetscDrawStringCentered()`,
127:           `PetscDrawStringBoxed()`, `PetscDrawStringVertical()`, `PetscDrawSetViewPort()`, `PetscDrawGetViewPort()`,
128:           `PetscDrawSplitViewPort()`, `PetscDrawSetTitle()`, `PetscDrawAppendTitle()`, `PetscDrawGetTitle()`, `PetscDrawSetPause()`, `PetscDrawGetPause()`,
129:           `PetscDrawPause()`, `PetscDrawSetDoubleBuffer()`, `PetscDrawClear()`, `PetscDrawFlush()`, `PetscDrawGetSingleton()`, `PetscDrawGetMouseButton()`,
130:           `PetscDrawZoom()`, `PetscDrawGetBoundingBox()`
131: @*/
132: PetscErrorCode PetscDrawCreate(MPI_Comm comm, const char display[], const char title[], int x, int y, int w, int h, PetscDraw *indraw)
133: {
134:   PetscDraw draw;
135:   PetscReal dpause = 0.0;
136:   PetscBool flag;

138:   PetscDrawInitializePackage();
139:   *indraw = NULL;
140:   PetscHeaderCreate(draw, PETSC_DRAW_CLASSID, "Draw", "Graphics", "Draw", comm, PetscDrawDestroy, PetscDrawView);

142:   draw->data = NULL;
143:   PetscStrallocpy(display, &draw->display);
144:   PetscStrallocpy(title, &draw->title);
145:   draw->x       = x;
146:   draw->y       = y;
147:   draw->w       = w;
148:   draw->h       = h;
149:   draw->pause   = 0.0;
150:   draw->coor_xl = 0.0;
151:   draw->coor_xr = 1.0;
152:   draw->coor_yl = 0.0;
153:   draw->coor_yr = 1.0;
154:   draw->port_xl = 0.0;
155:   draw->port_xr = 1.0;
156:   draw->port_yl = 0.0;
157:   draw->port_yr = 1.0;
158:   draw->popup   = NULL;

160:   PetscOptionsGetReal(NULL, NULL, "-draw_pause", &dpause, &flag);
161:   if (flag) draw->pause = dpause;

163:   draw->savefilename   = NULL;
164:   draw->saveimageext   = NULL;
165:   draw->savemovieext   = NULL;
166:   draw->savefilecount  = 0;
167:   draw->savesinglefile = PETSC_FALSE;
168:   draw->savemoviefps   = PETSC_DECIDE;

170:   PetscDrawSetCurrentPoint(draw, .5, .9);

172:   draw->boundbox_xl = .5;
173:   draw->boundbox_xr = .5;
174:   draw->boundbox_yl = .9;
175:   draw->boundbox_yr = .9;

177:   *indraw = draw;
178:   return 0;
179: }

181: /*@C
182:    PetscDrawSetType - Builds graphics object for a particular implementation

184:    Collective

186:    Input Parameters:
187: +  draw      - the graphics context
188: -  type      - for example, `PETSC_DRAW_X`

190:    Options Database Key:
191: .  -draw_type  <type> - Sets the type; use -help for a list of available methods (for instance, x)

193:    Level: intermediate

195:    Note:
196:    See `PetscDrawSetFromOptions()` for additional options database keys

198:    See "petsc/include/petscdraw.h" for available methods (for instance,
199:    `PETSC_DRAW_X`, `PETSC_DRAW_TIKZ` or `PETSC_DRAW_IMAGE`)

201: .seealso: `PetscDraw`, `PETSC_DRAW_X`, `PETSC_DRAW_TIKZ`, `PETSC_DRAW_IMAGE`, `PetscDrawSetFromOptions()`, `PetscDrawCreate()`, `PetscDrawDestroy()`, `PetscDrawType`
202: @*/
203: PetscErrorCode PetscDrawSetType(PetscDraw draw, PetscDrawType type)
204: {
205:   PetscBool match;
206:   PetscBool flg = PETSC_FALSE;
207:   PetscErrorCode (*r)(PetscDraw);


212:   PetscObjectTypeCompare((PetscObject)draw, type, &match);
213:   if (match) return 0;

215:   /*  User requests no graphics */
216:   PetscOptionsHasName(((PetscObject)draw)->options, NULL, "-nox", &flg);

218:   /*
219:      This is not ideal, but it allows codes to continue to run if X graphics
220:    was requested but is not installed on this machine. Mostly this is for
221:    testing.
222:    */
223: #if !defined(PETSC_HAVE_X)
224:   if (!flg) {
225:     PetscStrcmp(type, PETSC_DRAW_X, &match);
226:     if (match) {
227:       PetscBool dontwarn = PETSC_TRUE;
228:       flg                = PETSC_TRUE;
229:       PetscOptionsHasName(NULL, NULL, "-nox_warning", &dontwarn);
230:       if (!dontwarn) (*PetscErrorPrintf)("PETSc installed without X Windows on this machine\nproceeding without graphics\n");
231:     }
232:   }
233: #endif
234:   if (flg) {
235:     PetscStrcmp(type, "tikz", &flg);
236:     if (!flg) type = PETSC_DRAW_NULL;
237:   }

239:   PetscStrcmp(type, PETSC_DRAW_NULL, &match);
240:   if (match) {
241:     PetscOptionsHasName(NULL, NULL, "-draw_double_buffer", NULL);
242:     PetscOptionsHasName(NULL, NULL, "-draw_virtual", NULL);
243:     PetscOptionsHasName(NULL, NULL, "-draw_fast", NULL);
244:     PetscOptionsHasName(NULL, NULL, "-draw_ports", NULL);
245:     PetscOptionsHasName(NULL, NULL, "-draw_coordinates", NULL);
246:   }

248:   PetscFunctionListFind(PetscDrawList, type, &r);
250:   PetscTryTypeMethod(draw, destroy);
251:   PetscMemzero(draw->ops, sizeof(struct _PetscDrawOps));
252:   PetscObjectChangeTypeName((PetscObject)draw, type);
253:   (*r)(draw);
254:   return 0;
255: }

257: /*@C
258:    PetscDrawGetType - Gets the `PetscDraw` type as a string from the `PetscDraw` object.

260:    Not Collective

262:    Input Parameter:
263: .  draw - Krylov context

265:    Output Parameters:
266: .  name - name of PetscDraw method

268:    Level: advanced

270: .seealso: `PetscDraw`, `PetscDrawType`, `PetscDrawSetType()`, `PetscDrawCreate()
271: @*/
272: PetscErrorCode PetscDrawGetType(PetscDraw draw, PetscDrawType *type)
273: {
276:   *type = ((PetscObject)draw)->type_name;
277:   return 0;
278: }

280: /*@C
281:    PetscDrawRegister - Adds a method to the graphics package.

283:    Not Collective

285:    Input Parameters:
286: +  name_solver - name of a new user-defined graphics class
287: -  routine_create - routine to create method context

289:    Level: developer

291:    Note:
292:    `PetscDrawRegister()` may be called multiple times to add several user-defined graphics classes

294:    Sample usage:
295: .vb
296:    PetscDrawRegister("my_draw_type", MyDrawCreate);
297: .ve

299:    Then, your specific graphics package can be chosen with the procedural interface via
300: $     PetscDrawSetType(ksp,"my_draw_type")
301:    or at runtime via the option
302: $     -draw_type my_draw_type

304: .seealso: `PetscDraw`, `PetscDrawRegisterAll()`, `PetscDrawRegisterDestroy()`, `PetscDrawType`, `PetscDrawSetType()`
305: @*/
306: PetscErrorCode PetscDrawRegister(const char *sname, PetscErrorCode (*function)(PetscDraw))
307: {
308:   PetscDrawInitializePackage();
309:   PetscFunctionListAdd(&PetscDrawList, sname, function);
310:   return 0;
311: }

313: /*@C
314:    PetscDrawSetOptionsPrefix - Sets the prefix used for searching for all
315:    `PetscDraw` options in the database.

317:    Logically Collective

319:    Input Parameters:
320: +  draw - the draw context
321: -  prefix - the prefix to prepend to all option names

323:    Level: advanced

325: .seealso: `PetscDraw`, `PetscDrawSetFromOptions()`, `PetscDrawCreate()`
326: @*/
327: PetscErrorCode PetscDrawSetOptionsPrefix(PetscDraw draw, const char prefix[])
328: {
330:   PetscObjectSetOptionsPrefix((PetscObject)draw, prefix);
331:   return 0;
332: }

334: /*@
335:    PetscDrawSetFromOptions - Sets the graphics type from the options database.
336:       Defaults to a PETSc X Windows graphics.

338:    Collective

340:    Input Parameter:
341: .     draw - the graphics context

343:    Options Database Keys:
344: +   -nox - do not use X graphics (ignore graphics calls, but run program correctly)
345: .   -nox_warning - when X Windows support is not installed this prevents the warning message from being printed
346: .   -draw_pause <pause amount> -- -1 indicates wait for mouse input, -2 indicates pause when window is to be destroyed
347: .   -draw_marker_type - <x,point>
348: .   -draw_save [optional filename] - (X Windows only) saves each image before it is cleared to a file
349: .   -draw_save_final_image [optional filename] - (X Windows only) saves the final image displayed in a window
350: .   -draw_save_movie - converts image files to a movie  at the end of the run. See PetscDrawSetSave()
351: .   -draw_save_single_file - saves each new image in the same file, normally each new image is saved in a new file with 'filename/filename_%d.ext'
352: .   -draw_save_on_clear - saves an image on each clear, mainly for debugging
353: -   -draw_save_on_flush - saves an image on each flush, mainly for debugging

355:    Level: intermediate

357:    Note:
358:     Must be called after `PetscDrawCreate()` before the `PetscDraw` is used.

360: .seealso: `PetscDraw`, `PetscDrawCreate()`, `PetscDrawSetType()`, `PetscDrawSetSave()`, `PetscDrawSetSaveFinalImage()`, `PetscDrawPause()`, `PetscDrawSetPause()`
361: @*/
362: PetscErrorCode PetscDrawSetFromOptions(PetscDraw draw)
363: {
364:   PetscBool   flg, nox;
365:   char        vtype[256];
366:   const char *def;
367: #if !defined(PETSC_USE_WINDOWS_GRAPHICS) && !defined(PETSC_HAVE_X)
368:   PetscBool warn;
369: #endif


373:   PetscDrawRegisterAll();

375:   if (((PetscObject)draw)->type_name) def = ((PetscObject)draw)->type_name;
376:   else {
377:     PetscOptionsHasName(((PetscObject)draw)->options, NULL, "-nox", &nox);
378:     def = PETSC_DRAW_NULL;
379: #if defined(PETSC_USE_WINDOWS_GRAPHICS)
380:     if (!nox) def = PETSC_DRAW_WIN32;
381: #elif defined(PETSC_HAVE_X)
382:     if (!nox) def = PETSC_DRAW_X;
383: #else
384:     PetscOptionsHasName(NULL, NULL, "-nox_warning", &warn);
385:     if (!nox && !warn) (*PetscErrorPrintf)("PETSc installed without X Windows or Microsoft Graphics on this machine\nproceeding without graphics\n");
386: #endif
387:   }
388:   PetscObjectOptionsBegin((PetscObject)draw);
389:   PetscOptionsFList("-draw_type", "Type of graphical output", "PetscDrawSetType", PetscDrawList, def, vtype, 256, &flg);
390:   if (flg) {
391:     PetscDrawSetType(draw, vtype);
392:   } else if (!((PetscObject)draw)->type_name) {
393:     PetscDrawSetType(draw, def);
394:   }
395:   PetscOptionsName("-nox", "Run without graphics", "None", &nox);
396:   {
397:     char      filename[PETSC_MAX_PATH_LEN];
398:     char      movieext[32];
399:     PetscBool image, movie;
400:     PetscSNPrintf(filename, sizeof(filename), "%s%s", draw->savefilename ? draw->savefilename : "", draw->saveimageext ? draw->saveimageext : "");
401:     PetscSNPrintf(movieext, sizeof(movieext), "%s", draw->savemovieext ? draw->savemovieext : "");
402:     PetscOptionsString("-draw_save", "Save graphics to image file", "PetscDrawSetSave", filename, filename, sizeof(filename), &image);
403:     PetscOptionsString("-draw_save_movie", "Make a movie from saved images", "PetscDrawSetSaveMovie", movieext, movieext, sizeof(movieext), &movie);
404:     PetscOptionsInt("-draw_save_movie_fps", "Set frames per second in saved movie", PETSC_FUNCTION_NAME, draw->savemoviefps, &draw->savemoviefps, NULL);
405:     PetscOptionsBool("-draw_save_single_file", "Each new image replaces previous image in file", PETSC_FUNCTION_NAME, draw->savesinglefile, &draw->savesinglefile, NULL);
406:     if (image) PetscDrawSetSave(draw, filename);
407:     if (movie) PetscDrawSetSaveMovie(draw, movieext);
408:     PetscOptionsString("-draw_save_final_image", "Save final graphics to image file", "PetscDrawSetSaveFinalImage", filename, filename, sizeof(filename), &image);
409:     if (image) PetscDrawSetSaveFinalImage(draw, filename);
410:     PetscOptionsBool("-draw_save_on_clear", "Save graphics to file on each clear", PETSC_FUNCTION_NAME, draw->saveonclear, &draw->saveonclear, NULL);
411:     PetscOptionsBool("-draw_save_on_flush", "Save graphics to file on each flush", PETSC_FUNCTION_NAME, draw->saveonflush, &draw->saveonflush, NULL);
412:   }
413:   PetscOptionsReal("-draw_pause", "Amount of time that program pauses after plots", "PetscDrawSetPause", draw->pause, &draw->pause, NULL);
414:   PetscOptionsEnum("-draw_marker_type", "Type of marker to use on plots", "PetscDrawSetMarkerType", PetscDrawMarkerTypes, (PetscEnum)draw->markertype, (PetscEnum *)&draw->markertype, NULL);

416:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
417:   PetscObjectProcessOptionsHandlers((PetscObject)draw, PetscOptionsObject);

419:   PetscDrawViewFromOptions(draw, NULL, "-draw_view");
420:   PetscOptionsEnd();
421:   return 0;
422: }