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