1 #include <../src/sys/classes/viewer/impls/vtk/vtkvimpl.h> /*I "petscviewer.h" I*/ 2 3 /*MC 4 PetscViewerVTKWriteFunction - functional form used to provide writer to the PetscViewerVTK 5 6 Synopsis: 7 #include <petscviewer.h> 8 PetscViewerVTKWriteFunction(PetscObject object,PetscViewer viewer) 9 10 Input Parameters: 11 + object - the PETSc object to be written 12 - viewer - viewer it is to be written to 13 14 Level: developer 15 16 .seealso: `PetscViewerVTKAddField()` 17 M*/ 18 19 /*@C 20 PetscViewerVTKAddField - Add a field to the viewer 21 22 Collective 23 24 Input Parameters: 25 + viewer - VTK viewer 26 . dm - DM on which Vec lives 27 . PetscViewerVTKWriteFunction - function to write this Vec 28 . fieldnum - which field of the DM to write (PETSC_DEFAULT if the whle vector should be written) 29 . fieldtype - Either PETSC_VTK_POINT_FIELD or PETSC_VTK_CELL_FIELD 30 . checkdm - whether to check for identical dm arguments as fields are added 31 - vec - Vec from which to write 32 33 Note: 34 This routine keeps exclusive ownership of the Vec. The caller should not use or destroy the Vec after adding it. 35 36 Level: developer 37 38 .seealso: `PetscViewerVTKOpen()`, `DMDAVTKWriteAll()`, `PetscViewerVTKWriteFunction`, `PetscViewerVTKGetDM()` 39 @*/ 40 PetscErrorCode PetscViewerVTKAddField(PetscViewer viewer,PetscObject dm,PetscErrorCode (*PetscViewerVTKWriteFunction)(PetscObject,PetscViewer),PetscInt fieldnum,PetscViewerVTKFieldType fieldtype,PetscBool checkdm,PetscObject vec) 41 { 42 PetscFunctionBegin; 43 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 44 PetscValidHeader(dm,2); 45 PetscValidHeader(vec,7); 46 PetscUseMethod(viewer,"PetscViewerVTKAddField_C",(PetscViewer,PetscObject,PetscErrorCode (*)(PetscObject,PetscViewer),PetscInt,PetscViewerVTKFieldType,PetscBool,PetscObject),(viewer,dm,PetscViewerVTKWriteFunction,fieldnum,fieldtype,checkdm,vec)); 47 PetscFunctionReturn(0); 48 } 49 50 /*@C 51 PetscViewerVTKGetDM - get the DM associated with the viewer 52 53 Collective 54 55 Input Parameters: 56 + viewer - VTK viewer 57 - dm - DM associated with the viewer (as PetscObject) 58 59 Level: developer 60 61 .seealso: `PetscViewerVTKOpen()`, `DMDAVTKWriteAll()`, `PetscViewerVTKWriteFunction`, `PetscViewerVTKAddField()` 62 @*/ 63 PetscErrorCode PetscViewerVTKGetDM(PetscViewer viewer,PetscObject *dm) 64 { 65 PetscFunctionBegin; 66 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 67 PetscUseMethod(viewer,"PetscViewerVTKGetDM_C",(PetscViewer,PetscObject*),(viewer,dm)); 68 PetscFunctionReturn(0); 69 } 70 71 static PetscErrorCode PetscViewerDestroy_VTK(PetscViewer viewer) 72 { 73 PetscViewer_VTK *vtk = (PetscViewer_VTK*)viewer->data; 74 75 PetscFunctionBegin; 76 PetscCall(PetscFree(vtk->filename)); 77 PetscCall(PetscFree(vtk)); 78 PetscCall(PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",NULL)); 79 PetscCall(PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",NULL)); 80 PetscCall(PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",NULL)); 81 PetscCall(PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",NULL)); 82 PetscCall(PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerVTKAddField_C",NULL)); 83 PetscCall(PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerVTKGetDM_C",NULL)); 84 PetscFunctionReturn(0); 85 } 86 87 static PetscErrorCode PetscViewerFlush_VTK(PetscViewer viewer) 88 { 89 PetscViewer_VTK *vtk = (PetscViewer_VTK*)viewer->data; 90 PetscViewerVTKObjectLink link,next; 91 92 PetscFunctionBegin; 93 PetscCheck(!vtk->link || !(!vtk->dm || !vtk->write),PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"No fields or no grid"); 94 if (vtk->write) PetscCall((*vtk->write)(vtk->dm,viewer)); 95 for (link=vtk->link; link; link=next) { 96 next = link->next; 97 PetscCall(PetscObjectDestroy(&link->vec)); 98 PetscCall(PetscFree(link)); 99 } 100 PetscCall(PetscObjectDestroy(&vtk->dm)); 101 vtk->write = NULL; 102 vtk->link = NULL; 103 PetscFunctionReturn(0); 104 } 105 106 PetscErrorCode PetscViewerFileSetName_VTK(PetscViewer viewer,const char name[]) 107 { 108 PetscViewer_VTK *vtk = (PetscViewer_VTK*)viewer->data; 109 PetscBool isvtk,isvts,isvtu,isvtr; 110 size_t len; 111 112 PetscFunctionBegin; 113 PetscCall(PetscViewerFlush(viewer)); 114 PetscCall(PetscFree(vtk->filename)); 115 PetscCall(PetscStrlen(name,&len)); 116 if (!len) { 117 isvtk = PETSC_TRUE; 118 } else { 119 PetscCall(PetscStrcasecmp(name+len-4,".vtk",&isvtk)); 120 PetscCall(PetscStrcasecmp(name+len-4,".vts",&isvts)); 121 PetscCall(PetscStrcasecmp(name+len-4,".vtu",&isvtu)); 122 PetscCall(PetscStrcasecmp(name+len-4,".vtr",&isvtr)); 123 } 124 if (isvtk) { 125 if (viewer->format == PETSC_VIEWER_DEFAULT) viewer->format = PETSC_VIEWER_ASCII_VTK_DEPRECATED; 126 PetscCheck(viewer->format == PETSC_VIEWER_ASCII_VTK_DEPRECATED,PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_INCOMP,"Cannot use file '%s' with format %s, should have '.vtk' extension",name,PetscViewerFormats[viewer->format]); 127 } else if (isvts) { 128 if (viewer->format == PETSC_VIEWER_DEFAULT) viewer->format = PETSC_VIEWER_VTK_VTS; 129 PetscCheck(viewer->format == PETSC_VIEWER_VTK_VTS,PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_INCOMP,"Cannot use file '%s' with format %s, should have '.vts' extension",name,PetscViewerFormats[viewer->format]); 130 } else if (isvtu) { 131 if (viewer->format == PETSC_VIEWER_DEFAULT) viewer->format = PETSC_VIEWER_VTK_VTU; 132 PetscCheck(viewer->format == PETSC_VIEWER_VTK_VTU,PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_INCOMP,"Cannot use file '%s' with format %s, should have '.vtu' extension",name,PetscViewerFormats[viewer->format]); 133 } else if (isvtr) { 134 if (viewer->format == PETSC_VIEWER_DEFAULT) viewer->format = PETSC_VIEWER_VTK_VTR; 135 PetscCheck(viewer->format == PETSC_VIEWER_VTK_VTR,PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_INCOMP,"Cannot use file '%s' with format %s, should have '.vtr' extension",name,PetscViewerFormats[viewer->format]); 136 } else SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_UNKNOWN_TYPE,"File '%s' has unrecognized extension",name); 137 PetscCall(PetscStrallocpy(len ? name : "stdout",&vtk->filename)); 138 PetscFunctionReturn(0); 139 } 140 141 PetscErrorCode PetscViewerFileGetName_VTK(PetscViewer viewer,const char **name) 142 { 143 PetscViewer_VTK *vtk = (PetscViewer_VTK*)viewer->data; 144 PetscFunctionBegin; 145 *name = vtk->filename; 146 PetscFunctionReturn(0); 147 } 148 149 PetscErrorCode PetscViewerFileSetMode_VTK(PetscViewer viewer,PetscFileMode type) 150 { 151 PetscViewer_VTK *vtk = (PetscViewer_VTK*)viewer->data; 152 153 PetscFunctionBegin; 154 vtk->btype = type; 155 PetscFunctionReturn(0); 156 } 157 158 PetscErrorCode PetscViewerFileGetMode_VTK(PetscViewer viewer,PetscFileMode *type) 159 { 160 PetscViewer_VTK *vtk = (PetscViewer_VTK*)viewer->data; 161 162 PetscFunctionBegin; 163 *type = vtk->btype; 164 PetscFunctionReturn(0); 165 } 166 167 PetscErrorCode PetscViewerVTKAddField_VTK(PetscViewer viewer,PetscObject dm,PetscErrorCode (*PetscViewerVTKWriteFunction)(PetscObject,PetscViewer),PetscInt fieldnum,PetscViewerVTKFieldType fieldtype,PetscBool checkdm,PetscObject vec) 168 { 169 PetscViewer_VTK *vtk = (PetscViewer_VTK*)viewer->data; 170 PetscViewerVTKObjectLink link, tail = vtk->link; 171 172 PetscFunctionBegin; 173 if (vtk->dm) { 174 PetscCheck(!checkdm || dm == vtk->dm,PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_INCOMP,"Refusing to write a field from more than one grid to the same VTK file. Set checkdm = PETSC_FALSE to skip this check."); 175 } else { 176 PetscCall(PetscObjectReference(dm)); 177 vtk->dm = dm; 178 } 179 vtk->write = PetscViewerVTKWriteFunction; 180 PetscCall(PetscNew(&link)); 181 link->ft = fieldtype; 182 link->vec = vec; 183 link->field = fieldnum; 184 link->next = NULL; 185 /* Append to list */ 186 if (tail) { 187 while (tail->next) tail = tail->next; 188 tail->next = link; 189 } else vtk->link = link; 190 PetscFunctionReturn(0); 191 } 192 193 PetscErrorCode PetscViewerVTKGetDM_VTK(PetscViewer viewer,PetscObject *dm) 194 { 195 PetscViewer_VTK *vtk = (PetscViewer_VTK*)viewer->data; 196 197 PetscFunctionBegin; 198 *dm = vtk->dm; 199 PetscFunctionReturn(0); 200 } 201 202 /*MC 203 PETSCVIEWERVTK - A viewer that writes to a VTK file 204 205 .seealso: `PetscViewerVTKOpen()`, `PetscViewerHDF5Open()`, `PetscViewerStringSPrintf()`, `PetscViewerSocketOpen()`, `PetscViewerDrawOpen()`, `PETSCVIEWERSOCKET`, 206 `PetscViewerCreate()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PETSCVIEWERBINARY`, `PETSCVIEWERDRAW`, `PETSCVIEWERSTRING`, 207 `PetscViewerMatlabOpen()`, `VecView()`, `DMView()`, `PetscViewerMatlabPutArray()`, `PETSCVIEWERASCII`, `PETSCVIEWERMATLAB`, 208 `PetscViewerFileSetName()`, `PetscViewerFileSetMode()`, `PetscViewerFormat`, `PetscViewerType`, `PetscViewerSetType()` 209 210 Level: beginner 211 M*/ 212 213 PETSC_EXTERN PetscErrorCode PetscViewerCreate_VTK(PetscViewer v) 214 { 215 PetscViewer_VTK *vtk; 216 217 PetscFunctionBegin; 218 PetscCall(PetscNewLog(v,&vtk)); 219 220 v->data = (void*)vtk; 221 v->ops->destroy = PetscViewerDestroy_VTK; 222 v->ops->flush = PetscViewerFlush_VTK; 223 vtk->btype = FILE_MODE_UNDEFINED; 224 vtk->filename = NULL; 225 226 PetscCall(PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_VTK)); 227 PetscCall(PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_VTK)); 228 PetscCall(PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_VTK)); 229 PetscCall(PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_VTK)); 230 PetscCall(PetscObjectComposeFunction((PetscObject)v,"PetscViewerVTKAddField_C",PetscViewerVTKAddField_VTK)); 231 PetscCall(PetscObjectComposeFunction((PetscObject)v,"PetscViewerVTKGetDM_C",PetscViewerVTKGetDM_VTK)); 232 PetscFunctionReturn(0); 233 } 234 235 /*@C 236 PetscViewerVTKOpen - Opens a file for VTK output. 237 238 Collective 239 240 Input Parameters: 241 + comm - MPI communicator 242 . name - name of file 243 - type - type of file 244 $ FILE_MODE_WRITE - create new file for binary output 245 $ FILE_MODE_READ - open existing file for binary input (not currently supported) 246 $ FILE_MODE_APPEND - open existing file for binary output (not currently supported) 247 248 Output Parameter: 249 . vtk - PetscViewer for VTK input/output to use with the specified file 250 251 Level: beginner 252 253 Note: 254 This PetscViewer should be destroyed with PetscViewerDestroy(). 255 256 .seealso: `PetscViewerASCIIOpen()`, `PetscViewerPushFormat()`, `PetscViewerDestroy()`, 257 `VecView()`, `MatView()`, `VecLoad()`, `MatLoad()`, 258 `PetscFileMode`, `PetscViewer` 259 @*/ 260 PetscErrorCode PetscViewerVTKOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *vtk) 261 { 262 PetscFunctionBegin; 263 PetscCall(PetscViewerCreate(comm,vtk)); 264 PetscCall(PetscViewerSetType(*vtk,PETSCVIEWERVTK)); 265 PetscCall(PetscViewerFileSetMode(*vtk,type)); 266 PetscCall(PetscViewerFileSetName(*vtk,name)); 267 PetscFunctionReturn(0); 268 } 269 270 /*@C 271 PetscViewerVTKFWrite - write binary data preceded by 32-bit int length (in bytes), does not do byte swapping. 272 273 Logically collective on PetscViewer 274 275 Input Parameters: 276 + viewer - logically collective viewer, data written from rank 0 277 . fp - file pointer valid on rank 0 278 . data - data pointer valid on rank 0 279 . n - number of data items 280 - dtype - data type 281 282 Level: developer 283 284 Notes: 285 If PetscScalar is __float128 then the binary files are written in double precision 286 287 .seealso: `DMDAVTKWriteAll()`, `DMPlexVTKWriteAll()`, `PetscViewerPushFormat()`, `PetscViewerVTKOpen()`, `PetscBinaryWrite()` 288 @*/ 289 PetscErrorCode PetscViewerVTKFWrite(PetscViewer viewer,FILE *fp,const void *data,PetscInt n,MPI_Datatype dtype) 290 { 291 PetscMPIInt rank; 292 MPI_Datatype vdtype=dtype; 293 #if defined(PETSC_USE_REAL___FLOAT128) 294 double *tmp; 295 PetscInt i; 296 PetscReal *ttmp = (PetscReal*)data; 297 #endif 298 299 PetscFunctionBegin; 300 PetscCheck(n >= 0,PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_OUTOFRANGE,"Trying to write a negative amount of data %" PetscInt_FMT,n); 301 if (!n) PetscFunctionReturn(0); 302 PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank)); 303 if (rank == 0) { 304 size_t count; 305 PetscMPIInt dsize; 306 PetscVTKInt bytes; 307 308 #if defined(PETSC_USE_REAL___FLOAT128) 309 if (dtype == MPIU___FLOAT128) { 310 PetscCall(PetscMalloc1(n,&tmp)); 311 for (i=0; i<n; i++) tmp[i] = ttmp[i]; 312 data = (void*) tmp; 313 vdtype = MPI_DOUBLE; 314 } 315 #endif 316 PetscCallMPI(MPI_Type_size(vdtype,&dsize)); 317 bytes = PetscVTKIntCast(dsize*n); 318 319 count = fwrite(&bytes,sizeof(int),1,fp); 320 PetscCheck(count == 1,PETSC_COMM_SELF,PETSC_ERR_FILE_WRITE,"Error writing byte count"); 321 count = fwrite(data,dsize,(size_t)n,fp); 322 PetscCheck((PetscInt)count == n,PETSC_COMM_SELF,PETSC_ERR_FILE_WRITE,"Wrote %" PetscInt_FMT "/%" PetscInt_FMT " array members of size %d",(PetscInt)count,n,dsize); 323 #if defined(PETSC_USE_REAL___FLOAT128) 324 if (dtype == MPIU___FLOAT128) { 325 PetscCall(PetscFree(tmp)); 326 } 327 #endif 328 } 329 PetscFunctionReturn(0); 330 } 331