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 Arguments: 25 + viewer - VTK viewer 26 . dm - DM on which Vec lives 27 . PetscViewerVTKWriteFunction - function to write this Vec 28 . fieldtype - Either PETSC_VTK_POINT_FIELD or PETSC_VTK_CELL_FIELD 29 - vec - Vec to write 30 31 Level: developer 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 .seealso: PetscViewerVTKOpen(), DMDAVTKWriteAll(), PetscViewerVTKWriteFunction 37 @*/ 38 PetscErrorCode PetscViewerVTKAddField(PetscViewer viewer,PetscObject dm,PetscErrorCode (*PetscViewerVTKWriteFunction)(PetscObject,PetscViewer),PetscViewerVTKFieldType fieldtype,PetscObject vec) 39 { 40 PetscErrorCode ierr; 41 42 PetscFunctionBegin; 43 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 44 PetscValidHeader(dm,2); 45 PetscValidHeader(vec,4); 46 ierr = PetscUseMethod(viewer,"PetscViewerVTKAddField_C",(PetscViewer,PetscObject,PetscErrorCode (*)(PetscObject,PetscViewer),PetscViewerVTKFieldType,PetscObject),(viewer,dm,PetscViewerVTKWriteFunction,fieldtype,vec));CHKERRQ(ierr); 47 PetscFunctionReturn(0); 48 } 49 50 static PetscErrorCode PetscViewerDestroy_VTK(PetscViewer viewer) 51 { 52 PetscViewer_VTK *vtk = (PetscViewer_VTK*)viewer->data; 53 PetscErrorCode ierr; 54 55 PetscFunctionBegin; 56 ierr = PetscFree(vtk->filename);CHKERRQ(ierr); 57 ierr = PetscFree(vtk);CHKERRQ(ierr); 58 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",NULL);CHKERRQ(ierr); 59 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",NULL);CHKERRQ(ierr); 60 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerVTKAddField_C",NULL);CHKERRQ(ierr); 61 PetscFunctionReturn(0); 62 } 63 64 static PetscErrorCode PetscViewerFlush_VTK(PetscViewer viewer) 65 { 66 PetscViewer_VTK *vtk = (PetscViewer_VTK*)viewer->data; 67 PetscErrorCode ierr; 68 PetscViewerVTKObjectLink link,next; 69 70 PetscFunctionBegin; 71 if (vtk->link && (!vtk->dm || !vtk->write)) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"No fields or no grid"); 72 if (vtk->write) {ierr = (*vtk->write)(vtk->dm,viewer);CHKERRQ(ierr);} 73 for (link=vtk->link; link; link=next) { 74 next = link->next; 75 ierr = PetscObjectDestroy(&link->vec);CHKERRQ(ierr); 76 ierr = PetscFree(link);CHKERRQ(ierr); 77 } 78 ierr = PetscObjectDestroy(&vtk->dm);CHKERRQ(ierr); 79 vtk->write = NULL; 80 PetscFunctionReturn(0); 81 } 82 83 PetscErrorCode PetscViewerFileSetName_VTK(PetscViewer viewer,const char name[]) 84 { 85 PetscViewer_VTK *vtk = (PetscViewer_VTK*)viewer->data; 86 PetscErrorCode ierr; 87 PetscBool isvtk,isvts,isvtu,isvtr; 88 size_t len; 89 90 PetscFunctionBegin; 91 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 92 ierr = PetscFree(vtk->filename);CHKERRQ(ierr); 93 ierr = PetscStrlen(name,&len);CHKERRQ(ierr); 94 ierr = PetscStrcasecmp(name+len-4,".vtk",&isvtk);CHKERRQ(ierr); 95 ierr = PetscStrcasecmp(name+len-4,".vts",&isvts);CHKERRQ(ierr); 96 ierr = PetscStrcasecmp(name+len-4,".vtu",&isvtu);CHKERRQ(ierr); 97 ierr = PetscStrcasecmp(name+len-4,".vtr",&isvtr);CHKERRQ(ierr); 98 if (isvtk) { 99 if (viewer->format == PETSC_VIEWER_DEFAULT) {ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_VTK);CHKERRQ(ierr);} 100 if (viewer->format != PETSC_VIEWER_ASCII_VTK) SETERRQ2(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_INCOMP,"Cannot use file '%s' with format %s, should have '.vtk' extension",name,PetscViewerFormats[viewer->format]); 101 } else if (isvts) { 102 if (viewer->format == PETSC_VIEWER_DEFAULT) {ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_VTK_VTS);CHKERRQ(ierr);} 103 if (viewer->format != PETSC_VIEWER_VTK_VTS) SETERRQ2(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_INCOMP,"Cannot use file '%s' with format %s, should have '.vts' extension",name,PetscViewerFormats[viewer->format]); 104 } else if (isvtu) { 105 if (viewer->format == PETSC_VIEWER_DEFAULT) {ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_VTK_VTU);CHKERRQ(ierr);} 106 if (viewer->format != PETSC_VIEWER_VTK_VTU) SETERRQ2(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_INCOMP,"Cannot use file '%s' with format %s, should have '.vtu' extension",name,PetscViewerFormats[viewer->format]); 107 } else if (isvtr) { 108 if (viewer->format == PETSC_VIEWER_DEFAULT) {ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_VTK_VTR);CHKERRQ(ierr);} 109 if (viewer->format != PETSC_VIEWER_VTK_VTR) SETERRQ2(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_INCOMP,"Cannot use file '%s' with format %s, should have '.vtr' extension",name,PetscViewerFormats[viewer->format]); 110 } else SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_UNKNOWN_TYPE,"File '%s' has unrecognized extension",name); 111 ierr = PetscStrallocpy(name,&vtk->filename);CHKERRQ(ierr); 112 PetscFunctionReturn(0); 113 } 114 115 PetscErrorCode PetscViewerFileSetMode_VTK(PetscViewer viewer,PetscFileMode type) 116 { 117 PetscViewer_VTK *vtk = (PetscViewer_VTK*)viewer->data; 118 119 PetscFunctionBegin; 120 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 121 vtk->btype = type; 122 PetscFunctionReturn(0); 123 } 124 125 PetscErrorCode PetscViewerVTKAddField_VTK(PetscViewer viewer,PetscObject dm,PetscErrorCode (*PetscViewerVTKWriteFunction)(PetscObject,PetscViewer),PetscViewerVTKFieldType fieldtype,PetscObject vec) 126 { 127 PetscViewer_VTK *vtk = (PetscViewer_VTK*)viewer->data; 128 PetscViewerVTKObjectLink link, tail = vtk->link; 129 PetscErrorCode ierr; 130 131 PetscFunctionBegin; 132 if (vtk->dm) { 133 if (dm != vtk->dm) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_INCOMP,"Cannot write a field from more than one grid to the same VTK file"); 134 } else { 135 ierr = PetscObjectReference(dm);CHKERRQ(ierr); 136 vtk->dm = dm; 137 } 138 vtk->write = PetscViewerVTKWriteFunction; 139 ierr = PetscNew(&link);CHKERRQ(ierr); 140 link->ft = fieldtype; 141 link->vec = vec; 142 link->next = NULL; 143 /* Append to list */ 144 if (tail) { 145 while (tail->next) tail = tail->next; 146 tail->next = link; 147 } else vtk->link = link; 148 PetscFunctionReturn(0); 149 } 150 151 /*MC 152 PETSCVIEWERVTK - A viewer that writes to an VTK file 153 154 155 .seealso: PetscViewerVTKOpen(), PetscViewerHDF5Open(), PetscViewerStringSPrintf(), PetscViewerSocketOpen(), PetscViewerDrawOpen(), PETSCVIEWERSOCKET, 156 PetscViewerCreate(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PETSCVIEWERBINARY, PETSCVIEWERDRAW, PETSCVIEWERSTRING, 157 PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB, 158 PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType() 159 160 Level: beginner 161 M*/ 162 163 PETSC_EXTERN PetscErrorCode PetscViewerCreate_VTK(PetscViewer v) 164 { 165 PetscViewer_VTK *vtk; 166 PetscErrorCode ierr; 167 168 PetscFunctionBegin; 169 ierr = PetscNewLog(v,&vtk);CHKERRQ(ierr); 170 171 v->data = (void*)vtk; 172 v->ops->destroy = PetscViewerDestroy_VTK; 173 v->ops->flush = PetscViewerFlush_VTK; 174 vtk->btype = (PetscFileMode) -1; 175 vtk->filename = 0; 176 177 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_VTK);CHKERRQ(ierr); 178 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_VTK);CHKERRQ(ierr); 179 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerVTKAddField_C",PetscViewerVTKAddField_VTK);CHKERRQ(ierr); 180 PetscFunctionReturn(0); 181 } 182 183 /*@C 184 PetscViewerVTKOpen - Opens a file for VTK output. 185 186 Collective on MPI_Comm 187 188 Input Parameters: 189 + comm - MPI communicator 190 . name - name of file 191 - type - type of file 192 $ FILE_MODE_WRITE - create new file for binary output 193 $ FILE_MODE_READ - open existing file for binary input (not currently supported) 194 $ FILE_MODE_APPEND - open existing file for binary output (not currently supported) 195 196 Output Parameter: 197 . vtk - PetscViewer for VTK input/output to use with the specified file 198 199 Level: beginner 200 201 Note: 202 This PetscViewer should be destroyed with PetscViewerDestroy(). 203 204 Concepts: VTK files 205 Concepts: PetscViewer^creating 206 207 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), 208 VecView(), MatView(), VecLoad(), MatLoad(), 209 PetscFileMode, PetscViewer 210 @*/ 211 PetscErrorCode PetscViewerVTKOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *vtk) 212 { 213 PetscErrorCode ierr; 214 215 PetscFunctionBegin; 216 ierr = PetscViewerCreate(comm,vtk);CHKERRQ(ierr); 217 ierr = PetscViewerSetType(*vtk,PETSCVIEWERVTK);CHKERRQ(ierr); 218 ierr = PetscViewerFileSetMode(*vtk,type);CHKERRQ(ierr); 219 ierr = PetscViewerFileSetName(*vtk,name);CHKERRQ(ierr); 220 PetscFunctionReturn(0); 221 } 222 223 /*@C 224 PetscViewerVTKFWrite - write binary data preceded by 32-bit int length (in bytes), does not do byte swapping. 225 226 Logically collective on PetscViewer 227 228 Input Parameters: 229 + viewer - logically collective viewer, data written from rank 0 230 . fp - file pointer valid on rank 0 231 . data - data pointer valid on rank 0 232 . n - number of data items 233 - dtype - data type 234 235 Level: developer 236 237 Notes: If PetscScalar is __float128 then the binary files are written in double precision 238 239 Concepts: VTK files 240 Concepts: PetscViewer^creating 241 242 .seealso: DMDAVTKWriteAll(), DMComplexVTKWriteAll(), PetscViewerPushFormat(), PetscViewerVTKOpen(), PetscBinaryWrite() 243 @*/ 244 PetscErrorCode PetscViewerVTKFWrite(PetscViewer viewer,FILE *fp,const void *data,PetscInt n,MPI_Datatype dtype) 245 { 246 PetscErrorCode ierr; 247 PetscMPIInt rank; 248 MPI_Datatype vdtype=dtype; 249 #if defined(PETSC_USE_REAL___FLOAT128) 250 double *tmp; 251 PetscInt i; 252 PetscReal *ttmp = (PetscReal*)data; 253 #endif 254 255 PetscFunctionBegin; 256 if (n < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_OUTOFRANGE,"Trying to write a negative amount of data %D",n); 257 if (!n) PetscFunctionReturn(0); 258 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 259 if (!rank) { 260 size_t count; 261 PetscMPIInt dsize; 262 PetscVTKInt bytes; 263 264 #if defined(PETSC_USE_REAL___FLOAT128) 265 if (dtype == MPIU___FLOAT128) { 266 ierr = PetscMalloc1(n,&tmp);CHKERRQ(ierr); 267 for (i=0; i<n; i++) tmp[i] = ttmp[i]; 268 data = (void*) tmp; 269 vdtype = MPI_DOUBLE; 270 } 271 #endif 272 ierr = MPI_Type_size(vdtype,&dsize);CHKERRQ(ierr); 273 bytes = PetscVTKIntCast(dsize*n); 274 275 count = fwrite(&bytes,sizeof(int),1,fp); 276 if (count != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_WRITE,"Error writing byte count"); 277 count = fwrite(data,dsize,(size_t)n,fp); 278 if ((PetscInt)count != n) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FILE_WRITE,"Wrote %D/%D array members of size %d",(PetscInt)count,n,dsize); 279 #if defined(PETSC_USE_REAL___FLOAT128) 280 if (dtype == MPIU___FLOAT128) { 281 ierr = PetscFree(tmp);CHKERRQ(ierr); 282 } 283 #endif 284 } 285 PetscFunctionReturn(0); 286 } 287