xref: /petsc/src/sys/classes/viewer/impls/vtk/vtkv.c (revision 5a4671aecb2b1c6017089db16b143293c51b8cb0)
1 #include "../src/sys/classes/viewer/impls/vtk/vtkvimpl.h" /*I "petscviewer.h" I*/
2 
3 #undef __FUNCT__
4 #define __FUNCT__ "PetscViewerVTKAddField"
5 /*@C
6    PetscViewerVTKAddField - Add a field to the viewer
7 
8    Collective
9 
10    Input Arguments:
11 + viewer - VTK viewer
12 . dm - DM on which Vec lives
13 . func - function to write this Vec
14 . fieldtype - Either PETSC_VTK_POINT_FIELD or PETSC_VTK_CELL_FIELD
15 - vec - Vec to write
16 
17    Level: developer
18 
19    Note:
20    This routine keeps exclusive ownership of the Vec. The caller should not use or destroy the Vec after adding it.
21 
22 .seealso: PetscViewerVTKOpen(), DMDAVTKWriteAll()
23 @*/
24 PetscErrorCode PetscViewerVTKAddField(PetscViewer viewer,PetscObject dm,PetscViewerVTKWriteFunction func,PetscViewerVTKFieldType fieldtype,PetscObject vec)
25 {
26   PetscErrorCode ierr;
27 
28   PetscFunctionBegin;
29   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
30   PetscValidHeader(dm,2);
31   PetscValidHeader(vec,4);
32   ierr = PetscUseMethod(viewer,"PetscViewerVTKAddField_C",(PetscViewer,PetscObject,PetscViewerVTKWriteFunction,PetscViewerVTKFieldType,PetscObject),(viewer,dm,func,fieldtype,vec));CHKERRQ(ierr);
33   PetscFunctionReturn(0);
34 }
35 
36 #undef __FUNCT__
37 #define __FUNCT__ "PetscViewerDestroy_VTK"
38 static PetscErrorCode PetscViewerDestroy_VTK(PetscViewer viewer)
39 {
40  PetscViewer_VTK *vtk = (PetscViewer_VTK*)viewer->data;
41  PetscErrorCode  ierr;
42 
43  PetscFunctionBegin;
44  ierr = PetscFree(vtk->filename);CHKERRQ(ierr);
45  ierr = PetscFree(vtk);CHKERRQ(ierr);
46  ierr = PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","",PETSC_NULL);CHKERRQ(ierr);
47  ierr = PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetMode_C","",PETSC_NULL);CHKERRQ(ierr);
48  ierr = PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerVTKAddField_C","",PETSC_NULL);CHKERRQ(ierr);
49  PetscFunctionReturn(0);
50 }
51 
52 #undef __FUNCT__
53 #define __FUNCT__ "PetscViewerFlush_VTK"
54 static PetscErrorCode PetscViewerFlush_VTK(PetscViewer viewer)
55 {
56   PetscViewer_VTK *vtk = (PetscViewer_VTK*)viewer->data;
57   PetscErrorCode ierr;
58   PetscViewerVTKObjectLink   link,next;
59 
60   PetscFunctionBegin;
61   if (vtk->link && (!vtk->dm || !vtk->dmwriteall)) SETERRQ(((PetscObject)viewer)->comm,PETSC_ERR_ARG_WRONGSTATE,"No fields or no grid");
62   if (vtk->dmwriteall) {ierr = (*vtk->dmwriteall)(vtk->dm,viewer);CHKERRQ(ierr);}
63   for (link=vtk->link; link; link=next) {
64     next = link->next;
65     ierr = PetscObjectDestroy(&link->vec);CHKERRQ(ierr);
66     ierr = PetscFree(link);CHKERRQ(ierr);
67   }
68   ierr = PetscObjectDestroy(&vtk->dm);CHKERRQ(ierr);
69   vtk->dmwriteall = PETSC_NULL;
70   PetscFunctionReturn(0);
71 }
72 
73 EXTERN_C_BEGIN
74 #undef __FUNCT__
75 #define __FUNCT__ "PetscViewerFileSetName_VTK"
76 PetscErrorCode  PetscViewerFileSetName_VTK(PetscViewer viewer,const char name[])
77 {
78   PetscViewer_VTK *vtk = (PetscViewer_VTK*)viewer->data;
79   PetscErrorCode  ierr;
80   PetscBool       isvtk,isvts,isvtu;
81   size_t          len;
82 
83   PetscFunctionBegin;
84   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
85   ierr = PetscFree(vtk->filename);CHKERRQ(ierr);
86   ierr = PetscStrlen(name,&len);CHKERRQ(ierr);
87   ierr = PetscStrcasecmp(name+len-4,".vtk",&isvtk);CHKERRQ(ierr);
88   ierr = PetscStrcasecmp(name+len-4,".vts",&isvts);CHKERRQ(ierr);
89   ierr = PetscStrcasecmp(name+len-4,".vtu",&isvtu);CHKERRQ(ierr);
90   if (isvtk) {
91     if (viewer->format == PETSC_VIEWER_DEFAULT) {ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_VTK);CHKERRQ(ierr);}
92     if (viewer->format != PETSC_VIEWER_ASCII_VTK) SETERRQ2(((PetscObject)viewer)->comm,PETSC_ERR_ARG_INCOMP,"Cannot use file '%s' with format %s, should have '.vtk' extension",name,PetscViewerFormats[viewer->format]);
93   } else if (isvts) {
94     if (viewer->format == PETSC_VIEWER_DEFAULT) {ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_VTK_VTS);CHKERRQ(ierr);}
95     if (viewer->format != PETSC_VIEWER_VTK_VTS) SETERRQ2(((PetscObject)viewer)->comm,PETSC_ERR_ARG_INCOMP,"Cannot use file '%s' with format %s, should have '.vts' extension",name,PetscViewerFormats[viewer->format]);
96   } else if (isvtu) {
97     if (viewer->format == PETSC_VIEWER_DEFAULT) {ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_VTK_VTU);CHKERRQ(ierr);}
98     if (viewer->format != PETSC_VIEWER_VTK_VTU) SETERRQ2(((PetscObject)viewer)->comm,PETSC_ERR_ARG_INCOMP,"Cannot use file '%s' with format %s, should have '.vts' extension",name,PetscViewerFormats[viewer->format]);
99   } else SETERRQ1(((PetscObject)viewer)->comm,PETSC_ERR_ARG_UNKNOWN_TYPE,"File '%s' has unrecognized extension",name);
100   ierr = PetscStrallocpy(name,&vtk->filename);CHKERRQ(ierr);
101   PetscFunctionReturn(0);
102 }
103 EXTERN_C_END
104 
105 EXTERN_C_BEGIN
106 #undef __FUNCT__
107 #define __FUNCT__ "PetscViewerFileSetMode_VTK"
108 PetscErrorCode  PetscViewerFileSetMode_VTK(PetscViewer viewer,PetscFileMode type)
109 {
110   PetscViewer_VTK *vtk = (PetscViewer_VTK*)viewer->data;
111 
112   PetscFunctionBegin;
113   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
114   vtk->btype = type;
115   PetscFunctionReturn(0);
116 }
117 EXTERN_C_END
118 
119 EXTERN_C_BEGIN
120 #undef __FUNCT__
121 #define __FUNCT__ "PetscViewerVTKAddField_VTK"
122 PetscErrorCode  PetscViewerVTKAddField_VTK(PetscViewer viewer,PetscObject dm,PetscViewerVTKWriteFunction dmwriteall,PetscViewerVTKFieldType fieldtype,PetscObject vec)
123 {
124   PetscViewer_VTK *vtk = (PetscViewer_VTK*)viewer->data;
125   PetscViewerVTKObjectLink link, tail = vtk->link;
126   PetscErrorCode ierr;
127 
128   PetscFunctionBegin;
129   if (vtk->dm) {
130     if (dm != vtk->dm) SETERRQ(((PetscObject)viewer)->comm,PETSC_ERR_ARG_INCOMP,"Cannot write a field from more than one grid to the same VTK file");
131   }
132   vtk->dm = dm;
133   vtk->dmwriteall = dmwriteall;
134   ierr = PetscMalloc(sizeof(struct _n_PetscViewerVTKObjectLink),&link);CHKERRQ(ierr);
135   link->ft = fieldtype;
136   link->vec = vec;
137   link->next = PETSC_NULL;
138   /* Append to list */
139   if (tail) {
140     while(tail->next) tail = tail->next;
141     tail->next = link;
142   } else {
143     vtk->link = link;
144   }
145   PetscFunctionReturn(0);
146 }
147 EXTERN_C_END
148 
149 EXTERN_C_BEGIN
150 #undef __FUNCT__
151 #define __FUNCT__ "PetscViewerCreate_VTK"
152 PetscErrorCode  PetscViewerCreate_VTK(PetscViewer v)
153 {
154   PetscViewer_VTK *vtk;
155   PetscErrorCode  ierr;
156 
157   PetscFunctionBegin;
158   ierr = PetscNewLog(v,PetscViewer_VTK,&vtk);CHKERRQ(ierr);
159 
160   v->data         = (void*)vtk;
161   v->ops->destroy = PetscViewerDestroy_VTK;
162   v->ops->flush   = PetscViewerFlush_VTK;
163   v->iformat      = 0;
164   vtk->btype     = (PetscFileMode) -1;
165   vtk->filename  = 0;
166 
167   ierr = PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileSetName_C","PetscViewerFileSetName_VTK",
168                                            PetscViewerFileSetName_VTK);CHKERRQ(ierr);
169   ierr = PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileSetMode_C","PetscViewerFileSetMode_VTK",
170                                            PetscViewerFileSetMode_VTK);CHKERRQ(ierr);
171   ierr = PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerVTKAddField_C","PetscViewerVTKAddField_VTK",
172                                            PetscViewerVTKAddField_VTK);CHKERRQ(ierr);
173   PetscFunctionReturn(0);
174 }
175 EXTERN_C_END
176 
177 #undef __FUNCT__
178 #define __FUNCT__ "PetscViewerVTKOpen"
179 /*@C
180    PetscViewerVTKOpen - Opens a file for VTK output.
181 
182    Collective on MPI_Comm
183 
184    Input Parameters:
185 +  comm - MPI communicator
186 .  name - name of file
187 -  type - type of file
188 $    FILE_MODE_WRITE - create new file for binary output
189 $    FILE_MODE_READ - open existing file for binary input (not currently supported)
190 $    FILE_MODE_APPEND - open existing file for binary output (not currently supported)
191 
192    Output Parameter:
193 .  vtk - PetscViewer for VTK input/output to use with the specified file
194 
195    Level: beginner
196 
197    Note:
198    This PetscViewer should be destroyed with PetscViewerDestroy().
199 
200    Concepts: VTK files
201    Concepts: PetscViewer^creating
202 
203 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
204           VecView(), MatView(), VecLoad(), MatLoad(),
205           PetscFileMode, PetscViewer
206 @*/
207 PetscErrorCode PetscViewerVTKOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *vtk)
208 {
209   PetscErrorCode ierr;
210 
211   PetscFunctionBegin;
212   ierr = PetscViewerCreate(comm,vtk);CHKERRQ(ierr);
213   ierr = PetscViewerSetType(*vtk,PETSCVIEWERVTK);CHKERRQ(ierr);
214   ierr = PetscViewerFileSetMode(*vtk,type);CHKERRQ(ierr);
215   ierr = PetscViewerFileSetName(*vtk,name);CHKERRQ(ierr);
216   PetscFunctionReturn(0);
217 }
218 
219 #undef __FUNCT__
220 #define __FUNCT__ "PetscViewerVTKFWrite"
221 /*@C
222    PetscViewerVTKFWrite - write binary data preceded by 32-bit int length (in bytes), does not do byte swapping.
223 
224    Logically collective on PetscViewer
225 
226    Input Parameters:
227 +  viewer - logically collective viewer, data written from rank 0
228 .  fp - file pointer valid on rank 0
229 .  data - data pointer valid on rank 0
230 .  n - number of data items
231 -  dtype - data type
232 
233    Level: developer
234 
235    Concepts: VTK files
236    Concepts: PetscViewer^creating
237 
238 .seealso: DMDAVTKWriteAll(), DMComplexVTKWriteAll(), PetscViewerSetFormat(), PetscViewerVTKOpen(), PetscBinaryWrite()
239 @*/
240 PetscErrorCode PetscViewerVTKFWrite(PetscViewer viewer,FILE *fp,const void *data,PetscInt n,PetscDataType dtype)
241 {
242   PetscErrorCode ierr;
243   PetscMPIInt rank;
244 
245   PetscFunctionBegin;
246   if (n < 0) SETERRQ1(((PetscObject)viewer)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Trying to write a negative amount of data %D",n);
247   if (!n) PetscFunctionReturn(0);
248   ierr = MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);CHKERRQ(ierr);
249   if (!rank) {
250     size_t count;
251     PetscInt size;
252     PetscVTKInt bytes;
253     switch (dtype) {
254     case PETSC_DOUBLE:
255       size = sizeof(double);
256       break;
257     case PETSC_FLOAT:
258       size = sizeof(float);
259       break;
260     case PETSC_INT:
261       size = sizeof(PetscInt);
262       break;
263     case PETSC_ENUM:
264       size = sizeof(PetscEnum);
265       break;
266     case PETSC_CHAR:
267       size = sizeof(char);
268       break;
269     default: SETERRQ(((PetscObject)viewer)->comm,PETSC_ERR_SUP,"Data type not supported");
270     }
271     bytes = PetscVTKIntCast(size*n);
272 
273     count = fwrite(&bytes,sizeof(int),1,fp);
274     if (count != 1) {
275       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_WRITE,"Error writing byte count");
276     }
277     count = fwrite(data,size,(size_t)n,fp);
278     if ((PetscInt)count != n) {
279       SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FILE_WRITE,"Wrote %D/%D array members of size %D",(PetscInt)count,n,(PetscInt)size);
280     }
281   }
282   PetscFunctionReturn(0);
283 }
284