/[escript]/trunk/finley/src/Mesh_saveVTK.c
ViewVC logotype

Diff of /trunk/finley/src/Mesh_saveVTK.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

trunk/esys2/finley/src/finleyC/Mesh_saveVTK.c revision 150 by jgs, Thu Sep 15 03:44:45 2005 UTC trunk/finley/src/Mesh_saveVTK.c revision 2548 by jfenwick, Mon Jul 20 06:20:06 2009 UTC
# Line 1  Line 1 
 /*  
  ******************************************************************************  
  *                                                                            *  
  *       COPYRIGHT  ACcESS 2003,2004,2005 -  All Rights Reserved              *  
  *                                                                            *  
  * This software is the property of ACcESS. No part of this code              *  
  * may be copied in any form or by any means without the expressed written    *  
  * consent of ACcESS.  Copying, use or modification of this software          *  
  * by any unauthorised person is illegal unless that person has a software    *  
  * license agreement with ACcESS.                                             *  
  *                                                                            *  
  ******************************************************************************  
 */  
   
   
 /**************************************************************/  
1    
2  /*   writes data and mesh in a vtk file */  /*******************************************************
3    *
4    * Copyright (c) 2003-2009 by University of Queensland
5    * Earth Systems Science Computational Center (ESSCC)
6    * http://www.uq.edu.au/esscc
7    *
8    * Primary Business: Queensland, Australia
9    * Licensed under the Open Software License version 3.0
10    * http://www.opensource.org/licenses/osl-3.0.php
11    *
12    *******************************************************/
13    
14    /***************************************************************************/
15    /*   Writes data and mesh in VTK XML format to a VTU file.                 */
16    /*   Nodal data needs to be given on FINLEY_NODES or FINLEY_REDUCED_NODES  */
17    /***************************************************************************/
18    
19  /**************************************************************/  #include "Mesh.h"
20    #include "Assemble.h"
21    #include "vtkCellType.h"  /* copied from vtk source directory */
22    #include "paso/PasoUtil.h"
23    
24    #define INT_FORMAT "%d "
25    #define LEN_INT_FORMAT (unsigned int)(9+1)
26    #define INT_NEWLINE_FORMAT "%d\n"
27    #define SCALAR_FORMAT "%12.6e\n"
28    #define VECTOR_FORMAT "%12.6e %12.6e %12.6e\n"
29    #define TENSOR_FORMAT "%12.6e %12.6e %12.6e %12.6e %12.6e %12.6e %12.6e %12.6e %12.6e\n"
30    #define LEN_TENSOR_FORMAT (unsigned int)(9*(12+1)+1)
31    #define NEWLINE "\n"
32    #define LEN_TMP_BUFFER LEN_TENSOR_FORMAT+(MAX_numNodes*LEN_INT_FORMAT+1)+2
33    #define NCOMP_MAX (unsigned int)9
34    
35    #define __STRCAT(dest, chunk, dest_in_use) \
36    do {\
37        strcpy(&dest[dest_in_use], chunk);\
38        dest_in_use += strlen(chunk);\
39    } while(0)
40    
41    #ifdef PASO_MPI
42    /* writes buffer to file catching the empty buffer case which causes problems
43     * with some MPI versions */
44    #define MPI_WRITE_ORDERED(BUF) \
45    do {\
46        int LLEN=0; \
47        LLEN=(int) strlen(BUF); \
48        if (LLEN==0) { strcpy(BUF, ""); LLEN=0; }\
49        MPI_File_write_ordered(mpi_fileHandle_p, BUF, LLEN, MPI_CHAR, &mpi_status);\
50    } while(0)
51    
52    /* writes buffer to file on master only */
53    #define MPI_RANK0_WRITE_SHARED(BUF) \
54    do {\
55        int LLEN=0; \
56        if (my_mpi_rank == 0) {\
57            LLEN=(int) strlen(BUF); \
58            if (LLEN==0) { strcpy(BUF,""); LLEN=0; }\
59            MPI_File_iwrite_shared(mpi_fileHandle_p, BUF, LLEN, MPI_CHAR, &mpi_req);\
60            MPI_Wait(&mpi_req, &mpi_status);\
61        }\
62    } while(0)
63    
64    /* For reference only. Investigation needed as to which values may improve
65     * performance */
66    #if 0
67    void create_MPIInfo(MPI_Info& info)
68    {
69        MPI_Info_create(&info);
70        MPI_Info_set(info, "access_style", "write_once, sequential");
71        MPI_Info_set(info, "collective_buffering", "true");
72        MPI_Info_set(info, "cb_block_size",        "131072");
73        MPI_Info_set(info, "cb_buffer_size",       "1048567");
74        MPI_Info_set(info, "cb_nodes",             "8");
75        MPI_Info_set(info, "striping_factor",      "16");
76        MPI_Info_set(info, "striping_unit",        "424288");
77    }
78    #endif
79    
80  /*   Author: Paul Cochrane, cochrane@esscc.uq.edu.au */  #else
 /*   Version: $Id$ */  
81    
82  /**************************************************************/  #define MPI_WRITE_ORDERED(A)
83    #define MPI_RANK0_WRITE_SHARED(A)
84    
85  #include "Mesh.h"  #endif /* PASO_MPI */
 #include "vtkCellType.h"  /* copied from vtk source directory !!! */  
86    
 /**************************************************************/  
87    
88  void Finley_Mesh_saveVTK(const char * filename_p, Finley_Mesh *mesh_p, escriptDataC* data_p) {  /* Returns one if the node given by coords and idx is within the quadrant
89    char error_msg[LenErrorMsg_MAX];   * indexed by q and if the element type is Rec9 or Hex27, zero otherwise */
90    /* if there is no mesh we just return */  int nodeInQuadrant(const double *coords, ElementTypeId type, int idx, int q)
91    if (mesh_p==NULL) return;  {
92    Finley_ElementFile* elements=NULL;  #define INSIDE_1D(_X_,_C_,_R_) ( ABS((_X_)-(_C_)) <= (_R_) )
93    char elemTypeStr[32];  #define INSIDE_2D(_X_,_Y_,_CX_,_CY_,_R_) ( INSIDE_1D(_X_,_CX_,_R_) && INSIDE_1D(_Y_,_CY_,_R_))
94    int i, j, k, numVTKNodesPerElement, isCellCentered=FALSE, nodetype=FINLEY_DEGREES_OF_FREEDOM;  #define INSIDE_3D(_X_,_Y_,_Z_,_CX_,_CY_,_CZ_,_R_) ( INSIDE_1D(_X_,_CX_,_R_) && INSIDE_1D(_Y_,_CY_,_R_) && INSIDE_1D(_Z_,_CZ_,_R_) )
95    index_t j2;  
96    double* values, rtmp;      int ret;
97    int nDim = mesh_p->Nodes->numDim;      if (type == Rec9) {
98    int numPoints=0;          if (q==0)
99                  ret = INSIDE_2D(coords[2*idx], coords[2*idx+1], 0.25, 0.25, 0.25);
100    if (nDim==1) {          else if (q==1)
101        Finley_setError(VALUE_ERROR,"saveVTK: 1-dimensional domains are not supported.");              ret = INSIDE_2D(coords[2*idx], coords[2*idx+1], 0.75, 0.25, 0.25);
102        return;          else if (q==2)
103    }              ret = INSIDE_2D(coords[2*idx], coords[2*idx+1], 0.25, 0.75, 0.25);
104    /* get a pointer to the relevant mesh component */          else if (q==3)
105    if (isEmpty(data_p)) {              ret = INSIDE_2D(coords[2*idx], coords[2*idx+1], 0.75, 0.75, 0.25);
106      numPoints = mesh_p->Nodes->numNodes;          else
107      elements=mesh_p->Elements;              ret = 0;
108    } else {      } else if (type == Hex27) {
109      switch(getFunctionSpaceType(data_p)) {          if (q==0)
110      case(FINLEY_DEGREES_OF_FREEDOM):              ret = INSIDE_3D(coords[3*idx], coords[3*idx+1], coords[3*idx+2],
111        numPoints = mesh_p->Nodes->numNodes;                      0.25, 0.25, 0.25, 0.25);
112        nodetype = FINLEY_DEGREES_OF_FREEDOM;          else if (q==1)
113        isCellCentered = FALSE;              ret = INSIDE_3D(coords[3*idx], coords[3*idx+1], coords[3*idx+2],
114        elements = mesh_p->Elements;                      0.75, 0.25, 0.25, 0.25);
115        break;          else if (q==2)
116      case(FINLEY_REDUCED_DEGREES_OF_FREEDOM):              ret = INSIDE_3D(coords[3*idx], coords[3*idx+1], coords[3*idx+2],
117        numPoints = mesh_p->Nodes->reducedNumNodes;                      0.25, 0.75, 0.25, 0.25);
118        nodetype =FINLEY_REDUCED_DEGREES_OF_FREEDOM;          else if (q==3)
119        isCellCentered = FALSE;              ret = INSIDE_3D(coords[3*idx], coords[3*idx+1], coords[3*idx+2],
120        elements = mesh_p->Elements;                      0.75, 0.75, 0.25, 0.25);
121        break;          else if (q==4)
122      case(FINLEY_NODES):              ret = INSIDE_3D(coords[3*idx], coords[3*idx+1], coords[3*idx+2],
123        numPoints = mesh_p->Nodes->numNodes;                      0.25, 0.25, 0.75, 0.25);
124        nodetype=FINLEY_NODES;          else if (q==5)
125        isCellCentered=FALSE;              ret = INSIDE_3D(coords[3*idx], coords[3*idx+1], coords[3*idx+2],
126        elements=mesh_p->Elements;                      0.75, 0.25, 0.75, 0.25);
127        break;          else if (q==6)
128      case(FINLEY_ELEMENTS):              ret = INSIDE_3D(coords[3*idx], coords[3*idx+1], coords[3*idx+2],
129        numPoints = mesh_p->Nodes->numNodes;                      0.25, 0.75, 0.75, 0.25);
130        nodetype=FINLEY_NODES;          else if (q==7)
131        isCellCentered=TRUE;              ret = INSIDE_3D(coords[3*idx], coords[3*idx+1], coords[3*idx+2],
132        elements=mesh_p->Elements;                      0.75, 0.75, 0.75, 0.25);
133        break;          else
134      case(FINLEY_FACE_ELEMENTS):              ret = 0;
135        numPoints = mesh_p->Nodes->numNodes;      } else {
136        nodetype=FINLEY_NODES;          ret = 1;
       isCellCentered=TRUE;  
       elements=mesh_p->FaceElements;  
       break;  
     case(FINLEY_POINTS):  
       numPoints = mesh_p->Nodes->numNodes;  
       nodetype=FINLEY_NODES;  
       isCellCentered=TRUE;  
       elements=mesh_p->Points;  
       break;  
     case(FINLEY_CONTACT_ELEMENTS_1):  
     case(FINLEY_CONTACT_ELEMENTS_2):  
       numPoints = mesh_p->Nodes->numNodes;  
       nodetype=FINLEY_NODES;  
       isCellCentered=TRUE;  
       elements=mesh_p->ContactElements;  
       break;  
     default:  
       sprintf(error_msg,"saveVTK: Finley does not know anything about function space type %d",getFunctionSpaceType(data_p));  
       Finley_setError(TYPE_ERROR,error_msg);  
       return;  
137      }      }
138    }      return ret;
139    }
   /* the number of points */  
140    
141    /* the number of cells */  void Finley_Mesh_saveVTK(const char *filename_p,
142    if (elements == NULL) {                           Finley_Mesh *mesh_p,
143      Finley_setError(VALUE_ERROR,"saveVTK: elements object is NULL; cannot proceed");                           const dim_t num_data,
144      return;                           char **names_p,
145    }                           escriptDataC **data_pp,
146    int numCells = elements->numElements;                             const char* metadata,
147    /* open the file and check handle */                           const char*metadata_schema)
148    FILE * fileHandle_p = fopen(filename_p, "w");  {
149    if (fileHandle_p==NULL) {  #ifdef PASO_MPI
150      sprintf(error_msg, "saveVTK: File %s could not be opened for writing.", filename_p);      MPI_File mpi_fileHandle_p;
151      Finley_setError(IO_ERROR,error_msg);      MPI_Status mpi_status;
152      return;      MPI_Request mpi_req;
153    }      MPI_Info mpi_info = MPI_INFO_NULL;
154    /* xml header */  #endif
155    fprintf(fileHandle_p, "<?xml version=\"1.0\"?>\n");      Paso_MPI_rank my_mpi_rank;
156    fprintf(fileHandle_p, "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\">\n");      FILE *fileHandle_p = NULL;
157        char errorMsg[LenErrorMsg_MAX], *txtBuffer;
158    /* finley uses an unstructured mesh, so UnstructuredGrid *should* work */      char tmpBuffer[LEN_TMP_BUFFER];
159    fprintf(fileHandle_p, "<UnstructuredGrid>\n");      size_t txtBufferSize, txtBufferInUse, maxNameLen;
160        double *quadNodes_p = NULL;
161    /* is there only one "piece" to the data?? */      dim_t dataIdx, nDim;
162    fprintf(fileHandle_p, "<Piece "      dim_t numCells=0, globalNumCells=0, numVTKNodesPerElement=0;
163            "NumberOfPoints=\"%d\" "      dim_t myNumPoints=0, globalNumPoints=0;
164            "NumberOfCells=\"%d\">\n",      dim_t shape, NN=0, numCellFactor=1, myNumCells=0;
165            numPoints, numCells);      bool_t *isCellCentered;
166    /* now for the points; equivalent to positions section in saveDX() */      bool_t writeCellData=FALSE, writePointData=FALSE, hasReducedElements=FALSE;
167    /* "The points element explicitly defines coordinates for each point      index_t myFirstNode=0, myLastNode=0, *globalNodeIndex=NULL;
168     * individually.  It contains one DataArray element describing an array      index_t myFirstCell=0, k;
169     * with three components per value, each specifying the coordinates of one      int mpi_size, i, j, l;
170     * point" - from Vtk User's Guide      int cellType=0, nodeType=FINLEY_NODES, elementType=FINLEY_UNKNOWN;
171     */      Finley_ElementFile *elements = NULL;
172    fprintf(fileHandle_p, "<Points>\n");      ElementTypeId typeId = NoType;
173    /*  
174     * the reason for this if statement is explained in the long comment below      const char *vtkHeader = \
175     */        "<?xml version=\"1.0\"?>\n" \
176    if (nDim < 3) {        "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\"%s%s>\n%s%s" \
177      fprintf(fileHandle_p, "<DataArray "        "<UnstructuredGrid>\n" \
178          "NumberOfComponents=\"3\" "        "<Piece NumberOfPoints=\"%d\" NumberOfCells=\"%d\">\n" \
179          "type=\"Float32\" "        "<Points>\n" \
180          "format=\"ascii\">\n");        "<DataArray NumberOfComponents=\"%d\" type=\"Float64\" format=\"ascii\">\n";
181    } else {      char *vtkFooter = "</Piece>\n</UnstructuredGrid>\n</VTKFile>\n";
182      fprintf(fileHandle_p, "<DataArray "      const char *tag_Float_DataArray="<DataArray Name=\"%s\" type=\"Float64\" NumberOfComponents=\"%d\" format=\"ascii\">\n";
183          "NumberOfComponents=\"%d\" "      char *tags_End_Points_and_Start_Conn = "</DataArray>\n</Points>\n<Cells>\n<DataArray Name=\"connectivity\" type=\"Int32\" format=\"ascii\">\n" ;
184          "type=\"Float32\" "      char *tags_End_Conn_and_Start_Offset = "</DataArray>\n<DataArray Name=\"offsets\" type=\"Int32\" format=\"ascii\">\n";
185          "format=\"ascii\">\n",      char *tags_End_Offset_and_Start_Type = "</DataArray>\n<DataArray Name=\"types\" type=\"UInt8\" format=\"ascii\">\n";
186          nDim);      char *tag_End_DataArray = "</DataArray>\n";
187    }  
188    /* vtk/mayavi doesn't like 2D data, it likes 3D data with a degenerate      const int VTK_HEX20_INDEX[] =
189       * third dimension to handle 2D data (like a sheet of paper).  So, if        { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 16, 17, 18, 19, 12, 13, 14, 15 };
190       * nDim is 2, we have to append zeros to the array to get this third      const int VTK_REC9_INDEX[] =
191       * dimension, and keep the visualisers happy.        { 0, 4, 8, 7,  4, 1, 5, 8,  7, 8, 6, 3,  8, 5, 2, 6 };
192       * Indeed, if nDim is less than 3, must pad all empty dimensions, so      const int VTK_HEX27_INDEX[] =
193       * that the total number of dims is 3.        {  0,  8, 20, 11, 12, 21, 26, 24,
194    */           8,  1,  9, 20, 21, 13, 22, 26,
195    if (nodetype==FINLEY_REDUCED_DEGREES_OF_FREEDOM) {          11, 20, 10,  3, 24, 26, 23, 15,
196       for (i = 0; i < mesh_p->Nodes->numNodes; i++) {          20,  9,  2, 10, 26, 22, 14, 23,
197         if (mesh_p->Nodes->toReduced[i]>=0) {          12, 21, 26, 24,  4, 16, 25, 19,
198            for (j = 0; j < nDim; j++)          21, 13, 22, 26, 16,  5, 17, 25,
199              fprintf(fileHandle_p, " %e",mesh_p->Nodes->Coordinates[INDEX2(j, i, nDim)]);          24, 26, 23, 15, 19, 25, 18,  7,
200            for (k=0; k<3-nDim; k++) fprintf(fileHandle_p, " %e",0.);          26, 22, 14, 23, 25, 17,  6, 18 };
201            fprintf(fileHandle_p, "\n");  
202         }      /* if there is no mesh we just return */
203       }      if (mesh_p==NULL) return;
204    } else {  
205       for (i = 0; i < mesh_p->Nodes->numNodes; i++) {      nDim = mesh_p->Nodes->numDim;
206         for (j = 0; j < nDim; j++)  
207           fprintf(fileHandle_p, " %e",mesh_p->Nodes->Coordinates[INDEX2(j, i, nDim)]);      if (nDim != 2 && nDim != 3) {
208         for (k=0; k<3-nDim; k++) fprintf(fileHandle_p, " %e",0.);          Finley_setError(TYPE_ERROR, "saveVTK: spatial dimension 2 or 3 is supported only.");
209         fprintf(fileHandle_p, "\n");          return;
210       }      }
211    }      my_mpi_rank = mesh_p->Nodes->MPIInfo->rank;
212    fprintf(fileHandle_p, "</DataArray>\n");      mpi_size = mesh_p->Nodes->MPIInfo->size;
   fprintf(fileHandle_p, "</Points>\n");  
   
   /* connections */  
   /* now for the cells */  
   /* "The Cells element defines cells explicitly by specifying point  
    * connectivity and cell types.  It contains three DataArray elements.  The  
    * first array specifies the point connectivity.  All cells' point lists  
    * are concatenated together.  The second array specifies th eoffset into  
    * the connectivity array for the end of each cell.  The third array  
    * specifies the type of each cell.  
    */  
   /* if no element table is present jump over the connection table */  
   if (elements!=NULL) {  
     int cellType;  
     ElementTypeId TypeId;  
213    
214      if (nodetype==FINLEY_REDUCED_DEGREES_OF_FREEDOM) {      /************************************************************************
215        TypeId = elements->LinearReferenceElement->Type->TypeId;       * open the file and check handle *
216         */
217        if (mpi_size > 1) {
218    #ifdef PASO_MPI
219            const int amode = MPI_MODE_CREATE|MPI_MODE_WRONLY|MPI_MODE_UNIQUE_OPEN;
220            int ierr;
221            if (my_mpi_rank == 0 && Paso_fileExists(filename_p)) {
222                remove(filename_p);
223            }
224            ierr = MPI_File_open(mesh_p->Nodes->MPIInfo->comm, (char*)filename_p,
225                                 amode, mpi_info, &mpi_fileHandle_p);
226            if (ierr != MPI_SUCCESS) {
227                sprintf(errorMsg, "saveVTK: File %s could not be opened for writing in parallel.", filename_p);
228                Finley_setError(IO_ERROR, errorMsg);
229            } else {
230                ierr=MPI_File_set_view(mpi_fileHandle_p,MPI_DISPLACEMENT_CURRENT,
231                        MPI_CHAR, MPI_CHAR, "native", mpi_info);
232            }
233    #endif /* PASO_MPI */
234      } else {      } else {
235        TypeId = elements->ReferenceElement->Type->TypeId;          fileHandle_p = fopen(filename_p, "w");
236            if (fileHandle_p==NULL) {
237                sprintf(errorMsg, "saveVTK: File %s could not be opened for writing.", filename_p);
238                Finley_setError(IO_ERROR, errorMsg);
239            }
240      }      }
241        if (!Paso_MPIInfo_noError(mesh_p->Nodes->MPIInfo)) return;
242    
243      switch(TypeId) {      /* General note: From this point if an error occurs Finley_setError is
244      case Point1:       * called and subsequent steps are skipped until the end of this function
245        cellType = VTK_VERTEX;       * where allocated memory is freed and the file is closed. */
246        break;  
247      case Line2:      /************************************************************************/
248        cellType = VTK_LINE;      /* find the mesh type to be written */
249        break;  
250      case Line3:      isCellCentered = TMPMEMALLOC(num_data, bool_t);
251        cellType = VTK_QUADRATIC_EDGE;      maxNameLen = 0;
252        break;      if (!Finley_checkPtr(isCellCentered)) {
253      case Tri3:          for (dataIdx=0; dataIdx<num_data; ++dataIdx) {
254        cellType = VTK_TRIANGLE;              if (! isEmpty(data_pp[dataIdx])) {
255        break;                  switch(getFunctionSpaceType(data_pp[dataIdx]) ) {
256      case Tri6:                      case FINLEY_NODES:
257        cellType = VTK_QUADRATIC_TRIANGLE;                          nodeType = (nodeType == FINLEY_REDUCED_NODES) ? FINLEY_REDUCED_NODES : FINLEY_NODES;
258        break;                          isCellCentered[dataIdx] = FALSE;
259      case Rec4:                          if (elementType==FINLEY_UNKNOWN || elementType==FINLEY_ELEMENTS) {
260        cellType = VTK_QUAD;                              elementType = FINLEY_ELEMENTS;
261        break;                          } else {
262      case Rec8:                              Finley_setError(TYPE_ERROR, "saveVTK: cannot write given data in single file.");
263        cellType = VTK_QUADRATIC_QUAD;                          }
264        break;                      break;
265      case Tet4:                      case FINLEY_REDUCED_NODES:
266        cellType = VTK_TETRA;                          nodeType = FINLEY_REDUCED_NODES;
267        break;                          isCellCentered[dataIdx] = FALSE;
268      case Tet10:                          if (elementType==FINLEY_UNKNOWN || elementType==FINLEY_ELEMENTS) {
269        cellType = VTK_QUADRATIC_TETRA;                              elementType = FINLEY_ELEMENTS;
270        break;                          } else {
271      case Hex8:                              Finley_setError(TYPE_ERROR, "saveVTK: cannot write given data in single file.");
272        cellType = VTK_HEXAHEDRON;                      }
273        break;                      break;
274      case Hex20:                      case FINLEY_REDUCED_ELEMENTS:
275        cellType = VTK_QUADRATIC_HEXAHEDRON;                          hasReducedElements = TRUE;
276        break;                      case FINLEY_ELEMENTS:
277      case Line2Face:                          isCellCentered[dataIdx] = TRUE;
278        cellType = VTK_VERTEX;                          if (elementType==FINLEY_UNKNOWN || elementType==FINLEY_ELEMENTS) {
279        break;                              elementType = FINLEY_ELEMENTS;
280      case Line3Face:                          } else {
281        cellType = VTK_VERTEX;                              Finley_setError(TYPE_ERROR, "saveVTK: cannot write given data in single file.");
282        break;                          }
283      case Tri3Face:                      break;
284        cellType = VTK_LINE;                      case FINLEY_REDUCED_FACE_ELEMENTS:
285        break;                          hasReducedElements = TRUE;
286      case Tri6Face:                      case FINLEY_FACE_ELEMENTS:
287        cellType = VTK_QUADRATIC_EDGE;                          isCellCentered[dataIdx] = TRUE;
288        break;                          if (elementType==FINLEY_UNKNOWN || elementType==FINLEY_FACE_ELEMENTS) {
289      case Rec4Face:                              elementType = FINLEY_FACE_ELEMENTS;
290        cellType = VTK_LINE;                          } else {
291        break;                              Finley_setError(TYPE_ERROR, "saveVTK: cannot write given data in single file.");
292      case Rec8Face:                          }
293        cellType = VTK_QUADRATIC_EDGE;                      break;
294        break;                      case FINLEY_POINTS:
295      case Tet4Face:                          isCellCentered[dataIdx]=TRUE;
296        cellType = VTK_TRIANGLE;                          if (elementType==FINLEY_UNKNOWN || elementType==FINLEY_POINTS) {
297        break;                              elementType = FINLEY_POINTS;
298      case Tet10Face:                          } else {
299        cellType = VTK_QUADRATIC_TRIANGLE;                              Finley_setError(TYPE_ERROR, "saveVTK: cannot write given data in single file.");
300        break;                          }
301      case Hex8Face:                      break;
302        cellType = VTK_QUAD;                      case FINLEY_REDUCED_CONTACT_ELEMENTS_1:
303        break;                          hasReducedElements = TRUE;
304      case Hex20Face:                      case FINLEY_CONTACT_ELEMENTS_1:
305        cellType = VTK_QUADRATIC_QUAD;                          isCellCentered[dataIdx] = TRUE;
306        break;                          if (elementType==FINLEY_UNKNOWN || elementType==FINLEY_CONTACT_ELEMENTS_1) {
307      case Point1_Contact:                              elementType = FINLEY_CONTACT_ELEMENTS_1;
308        cellType = VTK_VERTEX;                          } else {
309        break;                              Finley_setError(TYPE_ERROR, "saveVTK: cannot write given data in single file.");
310      case Line2_Contact:                          }
311        cellType = VTK_LINE;                      break;
312        break;                      case FINLEY_REDUCED_CONTACT_ELEMENTS_2:
313      case Line3_Contact:                          hasReducedElements = TRUE;
314        cellType = VTK_QUADRATIC_EDGE;                      case FINLEY_CONTACT_ELEMENTS_2:
315        break;                          isCellCentered[dataIdx] = TRUE;
316      case Tri3_Contact:                          if (elementType==FINLEY_UNKNOWN || elementType==FINLEY_CONTACT_ELEMENTS_1) {
317        cellType = VTK_LINE;                              elementType = FINLEY_CONTACT_ELEMENTS_1;
318        break;                          } else {
319      case Tri6_Contact:                              Finley_setError(TYPE_ERROR, "saveVTK: cannot write given data in single file.");
320        cellType = VTK_QUADRATIC_TRIANGLE;                          }
321        break;                      break;
322      case Rec4_Contact:                      default:
323        cellType = VTK_QUAD;                          sprintf(errorMsg, "saveVTK: unknown function space type %d",getFunctionSpaceType(data_pp[dataIdx]));
324        break;                          Finley_setError(TYPE_ERROR, errorMsg);
325      case Rec8_Contact:                  }
326        cellType = VTK_QUADRATIC_QUAD;                  if (isCellCentered[dataIdx]) {
327        break;                      writeCellData = TRUE;
328      case Line2Face_Contact:                  } else {
329        cellType = VTK_VERTEX;                      writePointData = TRUE;
330        break;                  }
331      case Line3Face_Contact:                  maxNameLen = MAX(maxNameLen, strlen(names_p[dataIdx]));
332        cellType = VTK_VERTEX;              }
333        break;          }
     case Tri3Face_Contact:  
       cellType = VTK_LINE;  
       break;  
     case Tri6Face_Contact:  
       cellType = VTK_QUADRATIC_EDGE;  
       break;  
     case Rec4Face_Contact:  
       cellType = VTK_LINE;  
       break;  
     case Rec8Face_Contact:  
       cellType = VTK_QUADRATIC_EDGE;  
       break;  
     case Tet4Face_Contact:  
       cellType = VTK_TRIANGLE;  
       break;  
     case Tet10Face_Contact:  
       cellType = VTK_QUADRATIC_TRIANGLE;  
       break;  
     case Hex8Face_Contact:  
       cellType = VTK_QUAD;  
       break;  
     case Hex20Face_Contact:  
       cellType = VTK_QUADRATIC_QUAD;  
       break;  
     default:  
       sprintf(error_msg, "saveVTK: Element type %s is not supported by VTK",elements->ReferenceElement->Type->Name);  
       Finley_setError(VALUE_ERROR,error_msg);  
       return;  
     }  
   
     switch(cellType) {  
     case VTK_VERTEX:  
       numVTKNodesPerElement = 1;  
       strcpy(elemTypeStr, "VTK_VERTEX");  
       break;  
     case VTK_LINE:  
       numVTKNodesPerElement = 2;  
       strcpy(elemTypeStr, "VTK_LINE");  
       break;  
     case VTK_TRIANGLE:  
       numVTKNodesPerElement = 3;  
       strcpy(elemTypeStr, "VTK_TRIANGLE");  
       break;  
     case VTK_QUAD:  
       numVTKNodesPerElement = 4;  
       strcpy(elemTypeStr, "VTK_QUAD");  
       break;  
     case VTK_TETRA:  
       numVTKNodesPerElement = 4;  
       strcpy(elemTypeStr, "VTK_TETRA");  
       break;  
     case VTK_HEXAHEDRON:  
       numVTKNodesPerElement = 8;  
       strcpy(elemTypeStr, "VTK_HEXAHEDRON");  
       break;  
     case VTK_QUADRATIC_EDGE:  
       numVTKNodesPerElement = 3;  
       strcpy(elemTypeStr, "VTK_QUADRATIC_EDGE");  
       break;  
     case VTK_QUADRATIC_TRIANGLE:  
       numVTKNodesPerElement = 6;  
       strcpy(elemTypeStr, "VTK_QUADRATIC_TRIANGLE");  
       break;  
     case VTK_QUADRATIC_QUAD:  
       numVTKNodesPerElement = 8;  
       strcpy(elemTypeStr, "VTK_QUADRATIC_QUAD");  
       break;  
     case VTK_QUADRATIC_TETRA:  
       numVTKNodesPerElement = 10;  
       strcpy(elemTypeStr, "VTK_QUADRATIC_TETRA");  
       break;  
     case VTK_QUADRATIC_HEXAHEDRON:  
       numVTKNodesPerElement = 20;  
       strcpy(elemTypeStr, "VTK_QUADRATIC_HEXAHEDRON");  
       break;  
     default:  
       sprintf(error_msg,"saveVTK: Cell type %d is not supported by VTK", cellType);  
       Finley_setError(VALUE_ERROR,error_msg);  
       return;  
334      }      }
335    
336      /* write out the DataArray element for the connectivity */      /************************************************************************/
337      int NN = elements->ReferenceElement->Type->numNodes;      /* select number of points and the mesh component */
338      fprintf(fileHandle_p, "<Cells>\n");  
339      fprintf(fileHandle_p, "<DataArray "      if (Finley_noError()) {
340          "Name=\"connectivity\" "          if (nodeType == FINLEY_REDUCED_NODES) {
341          "type=\"Int32\" "              myFirstNode = Finley_NodeFile_getFirstReducedNode(mesh_p->Nodes);
342          "format=\"ascii\">\n");              myLastNode = Finley_NodeFile_getLastReducedNode(mesh_p->Nodes);
343      if (nodetype==FINLEY_REDUCED_DEGREES_OF_FREEDOM) {              globalNumPoints = Finley_NodeFile_getGlobalNumReducedNodes(mesh_p->Nodes);
344         for (i = 0; i < numCells; i++) {              globalNodeIndex = Finley_NodeFile_borrowGlobalReducedNodesIndex(mesh_p->Nodes);
345            for (j = 0; j < numVTKNodesPerElement; j++) {          } else {
346                 j2=elements->ReferenceElement->Type->linearNodes[j];              myFirstNode = Finley_NodeFile_getFirstNode(mesh_p->Nodes);
347                 fprintf(fileHandle_p,"%d ",mesh_p->Nodes->toReduced[elements->Nodes[INDEX2(j2, i, NN)]]);              myLastNode = Finley_NodeFile_getLastNode(mesh_p->Nodes);
348            }              globalNumPoints = Finley_NodeFile_getGlobalNumNodes(mesh_p->Nodes);
349            fprintf(fileHandle_p, "\n");              globalNodeIndex = Finley_NodeFile_borrowGlobalNodesIndex(mesh_p->Nodes);
350         }          }
351      } else if (VTK_QUADRATIC_HEXAHEDRON==cellType) {          myNumPoints = myLastNode - myFirstNode;
352            for (i = 0; i < numCells; i++) {          if (elementType==FINLEY_UNKNOWN) elementType=FINLEY_ELEMENTS;
353              fprintf(fileHandle_p,"%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",          switch(elementType) {
354                                 elements->Nodes[INDEX2(0, i, NN)],              case FINLEY_ELEMENTS:
355                                 elements->Nodes[INDEX2(1, i, NN)],                  elements = mesh_p->Elements;
356                                 elements->Nodes[INDEX2(2, i, NN)],              break;
357                                 elements->Nodes[INDEX2(3, i, NN)],              case FINLEY_FACE_ELEMENTS:
358                                 elements->Nodes[INDEX2(4, i, NN)],                  elements = mesh_p->FaceElements;
359                                 elements->Nodes[INDEX2(5, i, NN)],              break;
360                                 elements->Nodes[INDEX2(6, i, NN)],              case FINLEY_POINTS:
361                                 elements->Nodes[INDEX2(7, i, NN)],                  elements = mesh_p->Points;
362                                 elements->Nodes[INDEX2(8, i, NN)],              break;
363                                 elements->Nodes[INDEX2(9, i, NN)],              case FINLEY_CONTACT_ELEMENTS_1:
364                                 elements->Nodes[INDEX2(10, i, NN)],                  elements = mesh_p->ContactElements;
365                                 elements->Nodes[INDEX2(11, i, NN)],              break;
366                                 elements->Nodes[INDEX2(16, i, NN)],          }
367                                 elements->Nodes[INDEX2(17, i, NN)],          if (elements==NULL) {
368                                 elements->Nodes[INDEX2(18, i, NN)],              Finley_setError(SYSTEM_ERROR, "saveVTK: undefined element file");
369                                 elements->Nodes[INDEX2(19, i, NN)],          } else {
370                                 elements->Nodes[INDEX2(12, i, NN)],              /* map finley element type to VTK element type */
371                                 elements->Nodes[INDEX2(13, i, NN)],              numCells = elements->numElements;
372                                 elements->Nodes[INDEX2(14, i, NN)],              globalNumCells = Finley_ElementFile_getGlobalNumElements(elements);
373                                 elements->Nodes[INDEX2(15, i, NN)]);              myNumCells = Finley_ElementFile_getMyNumElements(elements);
374            }              myFirstCell = Finley_ElementFile_getFirstElement(elements);
375       } else if (numVTKNodesPerElement!=NN) {              NN = elements->numNodes;
376            for (i = 0; i < numCells; i++) {              if (nodeType==FINLEY_REDUCED_NODES) {
377              for (j = 0; j < numVTKNodesPerElement; j++) {                  typeId = elements->LinearReferenceElement->Type->TypeId;
378                   j2=elements->ReferenceElement->Type->geoNodes[j];                  if (hasReducedElements) {
379                   fprintf(fileHandle_p,"%d ", elements->Nodes[INDEX2(j2, i, NN)]);                      quadNodes_p=elements->LinearReferenceElementReducedOrder->QuadNodes;
380                    } else {
381                        quadNodes_p=elements->LinearReferenceElement->QuadNodes;
382                    }
383                } else {
384                    typeId = elements->ReferenceElement->Type->TypeId;
385                    if (hasReducedElements)
386                        quadNodes_p=elements->ReferenceElementReducedOrder->QuadNodes;
387                    else
388                        quadNodes_p=elements->ReferenceElement->QuadNodes;
389              }              }
390              fprintf(fileHandle_p, "\n");              switch (typeId) {
391            }                  case Point1:
392       } else {                  case Line2Face:
393            for (i = 0; i < numCells; i++) {                  case Line3Face:
394              for (j = 0; j < numVTKNodesPerElement; j++) fprintf(fileHandle_p,"%d ", elements->Nodes[INDEX2(j, i, NN)]);                  case Point1_Contact:
395              fprintf(fileHandle_p, "\n");                  case Line2Face_Contact:
396            }                  case Line3Face_Contact:
397       }                      cellType = VTK_VERTEX;
398      fprintf(fileHandle_p, "</DataArray>\n");                      numVTKNodesPerElement = 1;
399                    break;
400      /* write out the DataArray element for the offsets */  
401      fprintf(fileHandle_p, "<DataArray "                  case Line2:
402          "Name=\"offsets\" "                  case Tri3Face:
403          "type=\"Int32\" "                  case Rec4Face:
404          "format=\"ascii\">\n");                  case Line2_Contact:
405      for (i=numVTKNodesPerElement; i<=numCells*numVTKNodesPerElement; i+=numVTKNodesPerElement)                  case Tri3_Contact:
406          fprintf(fileHandle_p, "%d\n", i);                  case Tri3Face_Contact:
407      fprintf(fileHandle_p, "</DataArray>\n");                  case Rec4Face_Contact:
408                        cellType = VTK_LINE;
409      /* write out the DataArray element for the types */                      numVTKNodesPerElement = 2;
410      fprintf(fileHandle_p, "<DataArray "                  break;
411          "Name=\"types\" "  
412          "type=\"UInt8\" "                  case Tri3:
413          "format=\"ascii\">\n");                  case Tet4Face:
414      for (i=0; i<numCells; i++)                  case Tet4Face_Contact:
415          fprintf(fileHandle_p, "%d\n", cellType);                      cellType = VTK_TRIANGLE;
416      fprintf(fileHandle_p, "</DataArray>\n");                      numVTKNodesPerElement = 3;
417                    break;
418      /* finish off the <Cells> element */  
419      fprintf(fileHandle_p, "</Cells>\n");                  case Rec4:
420    }                  case Hex8Face:
421                    case Rec4_Contact:
422    /* data */                  case Hex8Face_Contact:
423    if (!isEmpty(data_p)) {                      cellType = VTK_QUAD;
424      int rank = getDataPointRank(data_p);                      numVTKNodesPerElement = 4;
425      int nComp = getDataPointSize(data_p);                  break;
426      /* barf if rank is greater than two */  
427      if (rank > 2) {                  case Rec9:
428        sprintf(error_msg, "saveVTK: Vtk can't handle objects with rank greater than 2. object rank = %d\n", rank);                      numCellFactor = 4;
429        Finley_setError(VALUE_ERROR,error_msg);                      cellType = VTK_QUAD;
430        return;                      numVTKNodesPerElement = 4;
431      }                  break;
432      /* if the rank == 0:   --> scalar data  
433       * if the rank == 1:   --> vector data                  case Tet4:
434       * if the rank == 2:   --> tensor data                      cellType = VTK_TETRA;
435       */                      numVTKNodesPerElement = 4;
436      char dataNameStr[31], dataTypeStr[63];                  break;
437      int nCompReqd=1;   /* the number of components required by vtk */  
438      if (rank == 0) {                  case Hex8:
439        strcpy(dataNameStr, "scalar");                      cellType = VTK_HEXAHEDRON;
440        sprintf(dataTypeStr, "Scalars=\"%s\"", dataNameStr);                      numVTKNodesPerElement = 8;
441        nCompReqd = 1;                  break;
442    
443                    case Line3:
444                    case Tri6Face:
445                    case Rec8Face:
446                    case Line3_Contact:
447                    case Tri6Face_Contact:
448                    case Rec8Face_Contact:
449                        cellType = VTK_QUADRATIC_EDGE;
450                        numVTKNodesPerElement = 3;
451                    break;
452    
453                    case Tri6:
454                    case Tet10Face:
455                    case Tri6_Contact:
456                    case Tet10Face_Contact:
457                        cellType = VTK_QUADRATIC_TRIANGLE;
458                        numVTKNodesPerElement = 6;
459                    break;
460    
461                    case Rec8:
462                    case Hex20Face:
463                    case Rec8_Contact:
464                    case Hex20Face_Contact:
465                        cellType = VTK_QUADRATIC_QUAD;
466                        numVTKNodesPerElement = 8;
467                    break;
468    
469                    case Tet10:
470                        cellType = VTK_QUADRATIC_TETRA;
471                        numVTKNodesPerElement = 10;
472                    break;
473    
474                    case Hex20:
475                        cellType = VTK_QUADRATIC_HEXAHEDRON;
476                        numVTKNodesPerElement = 20;
477                    break;
478    
479                    case Hex27:
480                        numCellFactor = 8;
481                        cellType = VTK_HEXAHEDRON;
482                        numVTKNodesPerElement = 8;
483                    break;
484    
485                    default:
486                        sprintf(errorMsg, "saveVTK: Element type %s is not supported by VTK.", elements->ReferenceElement->Type->Name);
487                        Finley_setError(VALUE_ERROR, errorMsg);
488                }
489            }
490      }      }
491      else if (rank == 1) {  
492        strcpy(dataNameStr, "vector");      /* allocate enough memory for text buffer */
493        sprintf(dataTypeStr, "Vectors=\"%s\"", dataNameStr);  
494        nCompReqd = 3;      txtBufferSize = strlen(vtkHeader) + 3*LEN_INT_FORMAT + (30+3*maxNameLen)+strlen(metadata)+strlen(metadata_schema);
495        if (mpi_size > 1) {
496           txtBufferSize = MAX(txtBufferSize, myNumPoints * LEN_TMP_BUFFER);
497            txtBufferSize = MAX(txtBufferSize, numCellFactor * myNumCells *
498                    (LEN_INT_FORMAT * numVTKNodesPerElement + 1));
499            txtBufferSize = MAX(txtBufferSize,
500                    numCellFactor * myNumCells * LEN_TENSOR_FORMAT);
501            txtBufferSize = MAX(txtBufferSize, myNumPoints * LEN_TENSOR_FORMAT);
502      }      }
503      else if (rank == 2) {      txtBuffer = TMPMEMALLOC(txtBufferSize+1, char);
504        strcpy(dataNameStr, "tensor");  
505        sprintf(dataTypeStr, "Tensors=\"%s\"", dataNameStr);      /* sets error if memory allocation failed */
506        nCompReqd = 9;      Finley_checkPtr(txtBuffer);
507    
508        /************************************************************************/
509        /* write number of points and the mesh component */
510    
511        if (Finley_noError()) {
512            const index_t *nodeIndex;
513            if (FINLEY_REDUCED_NODES == nodeType) {
514                nodeIndex = elements->ReferenceElement->Type->linearNodes;
515            } else if (Rec9 == typeId) {
516                nodeIndex = VTK_REC9_INDEX;
517            } else if (Hex20 == typeId) {
518                nodeIndex = VTK_HEX20_INDEX;
519            } else if (Hex27 == typeId) {
520                nodeIndex = VTK_HEX27_INDEX;
521            } else if (numVTKNodesPerElement != NN) {
522                nodeIndex = elements->ReferenceElement->Type->geoNodes;
523            } else {
524                nodeIndex = NULL;
525            }
526    
527            if (strlen(metadata)>0) {
528               if (strlen(metadata_schema)>0) {
529                  sprintf(txtBuffer, vtkHeader," ",metadata_schema,metadata,"\n",globalNumPoints, numCellFactor*globalNumCells, 3);
530               } else {
531                  sprintf(txtBuffer, vtkHeader,"","",metadata,"\n",globalNumPoints, numCellFactor*globalNumCells, 3);
532               }
533            } else {
534               if (strlen(metadata_schema)>0) {
535                  sprintf(txtBuffer, vtkHeader," ",metadata_schema,"","",globalNumPoints, numCellFactor*globalNumCells, 3);
536               } else {
537                  sprintf(txtBuffer, vtkHeader,"","","","",globalNumPoints, numCellFactor*globalNumCells, 3);
538               }
539            }
540    
541            if (mpi_size > 1) {
542                /* write the nodes */
543                MPI_RANK0_WRITE_SHARED(txtBuffer);
544                txtBuffer[0] = '\0';
545                txtBufferInUse = 0;
546                if (nDim==2) {
547                    for (i = 0; i < mesh_p->Nodes->numNodes; i++) {
548                        if ( (myFirstNode <= globalNodeIndex[i]) && (globalNodeIndex[i] < myLastNode) ) {
549                            sprintf(tmpBuffer, VECTOR_FORMAT,
550                                mesh_p->Nodes->Coordinates[INDEX2(0, i, nDim)],
551                                mesh_p->Nodes->Coordinates[INDEX2(1, i, nDim)],
552                                0.);
553                            __STRCAT(txtBuffer, tmpBuffer, txtBufferInUse);
554                        }
555                    }
556                } else {
557                    for (i = 0; i < mesh_p->Nodes->numNodes; i++) {
558                        if ( (myFirstNode <= globalNodeIndex[i]) && (globalNodeIndex[i] < myLastNode) ) {
559                            sprintf(tmpBuffer, VECTOR_FORMAT,
560                                mesh_p->Nodes->Coordinates[INDEX2(0, i, nDim)],
561                                mesh_p->Nodes->Coordinates[INDEX2(1, i, nDim)],
562                                mesh_p->Nodes->Coordinates[INDEX2(2, i, nDim)]);
563                            __STRCAT(txtBuffer, tmpBuffer, txtBufferInUse);
564                        }
565                    }
566                } /* nDim */
567                MPI_WRITE_ORDERED(txtBuffer);
568    
569                /* write the cells */
570                MPI_RANK0_WRITE_SHARED(tags_End_Points_and_Start_Conn);
571                txtBuffer[0] = '\0';
572                txtBufferInUse = 0;
573                if (nodeIndex == NULL) {
574                    for (i = 0; i < numCells; i++) {
575                        if (elements->Owner[i] == my_mpi_rank) {
576                            for (j = 0; j < numVTKNodesPerElement; j++) {
577                                sprintf(tmpBuffer, INT_FORMAT, globalNodeIndex[elements->Nodes[INDEX2(j, i, NN)]]);
578                                __STRCAT(txtBuffer, tmpBuffer, txtBufferInUse);
579                            }
580                            __STRCAT(txtBuffer, NEWLINE, txtBufferInUse);
581                        }
582                    }
583                } else {
584                    for (i = 0; i < numCells; i++) {
585                        if (elements->Owner[i] == my_mpi_rank) {
586                            for (l = 0; l < numCellFactor; l++) {
587                                const int* idx=&nodeIndex[l*numVTKNodesPerElement];
588                                for (j = 0; j < numVTKNodesPerElement; j++) {
589                                    sprintf(tmpBuffer, INT_FORMAT, globalNodeIndex[elements->Nodes[INDEX2(idx[j], i, NN)]]);
590                                    __STRCAT(txtBuffer, tmpBuffer, txtBufferInUse);
591                                }
592                                __STRCAT(txtBuffer, NEWLINE, txtBufferInUse);
593                            }
594                        }
595                    }
596                } /* nodeIndex */
597                MPI_WRITE_ORDERED(txtBuffer);
598    
599                /* write the offsets */
600                MPI_RANK0_WRITE_SHARED(tags_End_Conn_and_Start_Offset);
601                txtBuffer[0] = '\0';
602                txtBufferInUse = 0;
603                for (i = numVTKNodesPerElement*(myFirstCell*numCellFactor+1);
604                        i <= (myFirstCell+myNumCells)*numVTKNodesPerElement*numCellFactor; i += numVTKNodesPerElement)
605                {
606                    sprintf(tmpBuffer, INT_NEWLINE_FORMAT, i);
607                    __STRCAT(txtBuffer, tmpBuffer, txtBufferInUse);
608                }
609                MPI_WRITE_ORDERED(txtBuffer);
610    
611                /* write element type */
612                sprintf(tmpBuffer, INT_NEWLINE_FORMAT, cellType);
613                MPI_RANK0_WRITE_SHARED(tags_End_Offset_and_Start_Type);
614                txtBuffer[0] = '\0';
615                txtBufferInUse = 0;
616                for (i = numVTKNodesPerElement*(myFirstCell*numCellFactor+1);
617                        i <= (myFirstCell+myNumCells)*numVTKNodesPerElement*numCellFactor; i += numVTKNodesPerElement)
618                {
619                    __STRCAT(txtBuffer, tmpBuffer, txtBufferInUse);
620                }
621                MPI_WRITE_ORDERED(txtBuffer);
622                /* finalize cell information */
623                strcpy(txtBuffer, "</DataArray>\n</Cells>\n");
624                MPI_RANK0_WRITE_SHARED(txtBuffer);
625    
626            } else { /***** mpi_size == 1 *****/
627    
628                /* write the nodes */
629                fputs(txtBuffer, fileHandle_p);
630                if (nDim==2) {
631                    for (i = 0; i < mesh_p->Nodes->numNodes; i++) {
632                        if ( (myFirstNode <= globalNodeIndex[i]) && (globalNodeIndex[i] < myLastNode) ) {
633                            fprintf(fileHandle_p, VECTOR_FORMAT,
634                                mesh_p->Nodes->Coordinates[INDEX2(0, i, nDim)],
635                                mesh_p->Nodes->Coordinates[INDEX2(1, i, nDim)],
636                                0.);
637                        }
638                    }
639                } else {
640                    for (i = 0; i < mesh_p->Nodes->numNodes; i++) {
641                        if ( (myFirstNode <= globalNodeIndex[i]) && (globalNodeIndex[i] < myLastNode) ) {
642                            fprintf(fileHandle_p, VECTOR_FORMAT,
643                                mesh_p->Nodes->Coordinates[INDEX2(0, i, nDim)],
644                                mesh_p->Nodes->Coordinates[INDEX2(1, i, nDim)],
645                                mesh_p->Nodes->Coordinates[INDEX2(2, i, nDim)]);
646                        }
647                    }
648                } /* nDim */
649    
650                /* write the cells */
651                fputs(tags_End_Points_and_Start_Conn, fileHandle_p);
652                if (nodeIndex == NULL) {
653                    for (i = 0; i < numCells; i++) {
654                        for (j = 0; j < numVTKNodesPerElement; j++) {
655                            fprintf(fileHandle_p, INT_FORMAT, globalNodeIndex[elements->Nodes[INDEX2(j, i, NN)]]);
656                        }
657                        fprintf(fileHandle_p, NEWLINE);
658                    }
659                } else {
660                    for (i = 0; i < numCells; i++) {
661                        for (l = 0; l < numCellFactor; l++) {
662                            const int* idx=&nodeIndex[l*numVTKNodesPerElement];
663                            for (j = 0; j < numVTKNodesPerElement; j++) {
664                                fprintf(fileHandle_p, INT_FORMAT, globalNodeIndex[elements->Nodes[INDEX2(idx[j], i, NN)]]);
665                            }
666                            fprintf(fileHandle_p, NEWLINE);
667                        }
668                    }
669                } /* nodeIndex */
670    
671                /* write the offsets */
672                fputs(tags_End_Conn_and_Start_Offset, fileHandle_p);
673                for (i = numVTKNodesPerElement; i <= numCells*numVTKNodesPerElement*numCellFactor; i += numVTKNodesPerElement) {
674                    fprintf(fileHandle_p, INT_NEWLINE_FORMAT, i);
675                }
676    
677                /* write element type */
678                sprintf(tmpBuffer, INT_NEWLINE_FORMAT, cellType);
679                fputs(tags_End_Offset_and_Start_Type, fileHandle_p);
680                for (i = 0; i < numCells*numCellFactor; i++)
681                    fputs(tmpBuffer, fileHandle_p);
682                /* finalize cell information */
683                fputs("</DataArray>\n</Cells>\n", fileHandle_p);
684            } /* mpi_size */
685    
686        } /* Finley_noError */
687    
688        /************************************************************************/
689        /* write cell data */
690    
691        if (writeCellData && Finley_noError()) {
692            bool_t set_scalar=FALSE, set_vector=FALSE, set_tensor=FALSE;
693            /* mark the active data arrays */
694            strcpy(txtBuffer, "<CellData");
695            for (dataIdx = 0; dataIdx < num_data; dataIdx++) {
696                if (!isEmpty(data_pp[dataIdx]) && isCellCentered[dataIdx]) {
697                    /* rank == 0 <--> scalar data */
698                    /* rank == 1 <--> vector data */
699                    /* rank == 2 <--> tensor data */
700                    switch (getDataPointRank(data_pp[dataIdx])) {
701                        case 0:
702                            if (!set_scalar) {
703                                strcat(txtBuffer, " Scalars=\"");
704                                strcat(txtBuffer, names_p[dataIdx]);
705                                strcat(txtBuffer, "\"");
706                                set_scalar = TRUE;
707                            }
708                        break;
709                        case 1:
710                            if (!set_vector) {
711                                strcat(txtBuffer, " Vectors=\"");
712                                strcat(txtBuffer, names_p[dataIdx]);
713                                strcat(txtBuffer, "\"");
714                                set_vector = TRUE;
715                            }
716                        break;
717                        case 2:
718                            if (!set_tensor) {
719                                strcat(txtBuffer, " Tensors=\"");
720                                strcat(txtBuffer, names_p[dataIdx]);
721                                strcat(txtBuffer, "\"");
722                                set_tensor = TRUE;
723                            }
724                        break;
725                        default:
726                            sprintf(errorMsg, "saveVTK: data %s: VTK supports data with rank <= 2 only.", names_p[dataIdx]);
727                            Finley_setError(VALUE_ERROR, errorMsg);
728                    }
729                }
730                if (!Finley_noError())
731                    break;
732            }
733      }      }
734      /* if have cell centred data then use CellData element,      /* only continue if no error occurred */
735       * if have node centred data, then use PointData element      if (writeCellData && Finley_noError()) {
736       */          strcat(txtBuffer, ">\n");
737      if (isCellCentered) {          if ( mpi_size > 1) {
738        /* now for the cell data */              MPI_RANK0_WRITE_SHARED(txtBuffer);
739        fprintf(fileHandle_p, "<CellData %s>\n", dataTypeStr);          } else {
740        fprintf(fileHandle_p,              fputs(txtBuffer, fileHandle_p);
741            "<DataArray "          }
742            "Name=\"%s\" "  
743            "type=\"Float32\" "          /* write the arrays */
744            "NumberOfComponents=\"%d\" "          for (dataIdx = 0; dataIdx < num_data; dataIdx++) {
745            "format=\"ascii\">\n",              if (!isEmpty(data_pp[dataIdx]) && isCellCentered[dataIdx]) {
746            dataNameStr, nCompReqd);                  dim_t numPointsPerSample=getNumDataPointsPerSample(data_pp[dataIdx]);
747        int numPointsPerSample = elements->ReferenceElement->numQuadNodes;                  dim_t rank = getDataPointRank(data_pp[dataIdx]);
748        if (numPointsPerSample) {                  dim_t nComp = getDataPointSize(data_pp[dataIdx]);
749      int shape = getDataPointShape(data_p, 0);                  dim_t nCompReqd = 1; /* number of components mpi_required */
750      if (shape > 3) {                  if (rank == 0) {
751          sprintf(error_msg,"saveVTK: shape should be 1, 2, or 3; I got %d\n", shape);                      nCompReqd = 1;
752              Finley_setError(VALUE_ERROR,error_msg);                      shape = 0;
753          return;                  } else if (rank == 1) {
754      }                      nCompReqd = 3;
755      for (i=0; i<numCells; i++) {                      shape = getDataPointShape(data_pp[dataIdx], 0);
756        values = getSampleData(data_p, i);                      if (shape > 3) {
757        double sampleAvg[nComp];                          Finley_setError(VALUE_ERROR, "saveVTK: rank 1 objects must have 3 components at most.");
758        for (k=0; k<nComp; k++) {                      }
759          /* averaging over the number of points in the sample */                  } else {
760          rtmp = 0.;                      nCompReqd = 9;
761          for (j=0; j<numPointsPerSample; j++)                      shape = getDataPointShape(data_pp[dataIdx], 0);
762            rtmp += values[INDEX2(k,j,nComp)];                      if (shape > 3 || shape != getDataPointShape(data_pp[dataIdx], 1)) {
763          sampleAvg[k] = rtmp/numPointsPerSample;                          Finley_setError(VALUE_ERROR, "saveVTK: rank 2 objects of shape 2x2 or 3x3 supported only.");
764        }                      }
765        /* if the number of required components is more than the number                  }
766         * of actual components, pad with zeros                  /* bail out if an error occurred */
767         */                  if (!Finley_noError())
768        /* probably only need to get shape of first element */                      break;
769        /* write the data different ways for scalar, vector and tensor */  
770        if (nCompReqd == 1) {                  sprintf(txtBuffer, tag_Float_DataArray, names_p[dataIdx], nCompReqd);
771          fprintf(fileHandle_p, " %e", sampleAvg[0]);                  if ( mpi_size > 1) {
772        } else if (nCompReqd == 3) {                      MPI_RANK0_WRITE_SHARED(txtBuffer);
773          /* write out the data */                  } else {
774          for (int m=0; m<shape; m++) {                      fputs(txtBuffer, fileHandle_p);
775            fprintf(fileHandle_p, " %e", sampleAvg[m]);                  }
776          }  
777          /* pad with zeros */                  txtBuffer[0] = '\0';
778          for (int m=0; m<nCompReqd-shape; m++)                  txtBufferInUse = 0;
779            fprintf(fileHandle_p, " %e", 0.);                  for (i=0; i<numCells; i++) {
780        } else if (nCompReqd == 9) {                      if (elements->Owner[i] == my_mpi_rank) {
781          /* tensor data, so have a 3x3 matrix to output as a row              void* sampleBuffer=allocSampleBuffer(data_pp[dataIdx]);
782           * of 9 data points */                          __const double *values = getSampleDataRO(data_pp[dataIdx], i,sampleBuffer);
783          int count = 0;                          for (l = 0; l < numCellFactor; l++) {
784          for (int m=0; m<shape; m++) {                              double sampleAvg[NCOMP_MAX];
785            for (int n=0; n<shape; n++) {                              dim_t nCompUsed = MIN(nComp, NCOMP_MAX);
786          fprintf(fileHandle_p, " %e", sampleAvg[count]);  
787          count++;                              /* average over number of points in the sample */
788            }                              if (isExpanded(data_pp[dataIdx])) {
789            for (int n=0; n<3-shape; n++)                                  dim_t hits=0, hits_old;
790              fprintf(fileHandle_p, " %e", 0.);                                  for (k=0; k<nCompUsed; k++) sampleAvg[k]=0;
791          }                                  for (j=0; j<numPointsPerSample; j++) {
792          for (int m=0; m<3-shape; m++) {                                      hits_old=hits;
793              for (int n=0; n<3; n++)                                      if (nodeInQuadrant(quadNodes_p, typeId, j, l)) {
794                 fprintf(fileHandle_p, " %e", 0.);                                          hits++;
795                                            for (k=0; k<nCompUsed; k++) {
796                                                sampleAvg[k] += values[INDEX2(k,j,nComp)];
797                                            }
798                                        }
799                                    }
800                                    for (k=0; k<nCompUsed; k++)
801                                        sampleAvg[k] /= MAX(hits, 1);
802                                } else {
803                                    for (k=0; k<nCompUsed; k++)
804                                        sampleAvg[k] = values[k];
805                                } /* isExpanded */
806    
807                                /* if the number of required components is more than
808                                 * the number of actual components, pad with zeros
809                                 */
810                                /* probably only need to get shape of first element */
811                                if (nCompReqd == 1) {
812                                    sprintf(tmpBuffer, SCALAR_FORMAT, sampleAvg[0]);
813                                } else if (nCompReqd == 3) {
814                                    if (shape==1) {
815                                        sprintf(tmpBuffer, VECTOR_FORMAT,
816                                            sampleAvg[0], 0.f, 0.f);
817                                    } else if (shape==2) {
818                                        sprintf(tmpBuffer, VECTOR_FORMAT,
819                                            sampleAvg[0], sampleAvg[1], 0.f);
820                                    } else if (shape==3) {
821                                        sprintf(tmpBuffer, VECTOR_FORMAT,
822                                            sampleAvg[0],sampleAvg[1],sampleAvg[2]);
823                                    }
824                                } else if (nCompReqd == 9) {
825                                    if (shape==1) {
826                                        sprintf(tmpBuffer, TENSOR_FORMAT,
827                                            sampleAvg[0], 0.f, 0.f,
828                                                     0.f, 0.f, 0.f,
829                                                     0.f, 0.f, 0.f);
830                                    } else if (shape==2) {
831                                        sprintf(tmpBuffer, TENSOR_FORMAT,
832                                            sampleAvg[0], sampleAvg[1], 0.f,
833                                            sampleAvg[2], sampleAvg[3], 0.f,
834                                                     0.f,          0.f, 0.f);
835                                    } else if (shape==3) {
836                                        sprintf(tmpBuffer, TENSOR_FORMAT,
837                                            sampleAvg[0],sampleAvg[1],sampleAvg[2],
838                                            sampleAvg[3],sampleAvg[4],sampleAvg[5],
839                                            sampleAvg[6],sampleAvg[7],sampleAvg[8]);
840                                    }
841                                }
842                                if ( mpi_size > 1) {
843                                    __STRCAT(txtBuffer, tmpBuffer, txtBufferInUse);
844                                } else {
845                                    fputs(tmpBuffer, fileHandle_p);
846                                }
847                            } /* for l (numCellFactor) */
848                freeSampleBuffer(sampleBuffer);
849                        } /* if I am the owner */
850                    } /* for i (numCells) */
851    
852                    if ( mpi_size > 1) {
853                        MPI_WRITE_ORDERED(txtBuffer);
854                        MPI_RANK0_WRITE_SHARED(tag_End_DataArray);
855                    } else {
856                        fputs(tag_End_DataArray, fileHandle_p);
857                    }
858                } /* !isEmpty && cellCentered */
859            } /* for dataIdx */
860    
861            strcpy(txtBuffer, "</CellData>\n");
862            if ( mpi_size > 1) {
863                MPI_RANK0_WRITE_SHARED(txtBuffer);
864            } else {
865                fputs(txtBuffer, fileHandle_p);
866            }
867        } /* if noError && writeCellData */
868    
869        /************************************************************************/
870        /* write point data */
871    
872        if (writePointData && Finley_noError()) {
873            /* mark the active data arrays */
874            bool_t set_scalar=FALSE, set_vector=FALSE, set_tensor=FALSE;
875            strcpy(txtBuffer, "<PointData");
876            for (dataIdx = 0; dataIdx<num_data; dataIdx++) {
877                if (!isEmpty(data_pp[dataIdx]) && !isCellCentered[dataIdx]) {
878                    switch (getDataPointRank(data_pp[dataIdx])) {
879                        case 0:
880                            if (!set_scalar) {
881                                strcat(txtBuffer, " Scalars=\"");
882                                strcat(txtBuffer, names_p[dataIdx]);
883                                strcat(txtBuffer, "\"");
884                                set_scalar = TRUE;
885                            }
886                        break;
887                        case 1:
888                            if (!set_vector) {
889                                strcat(txtBuffer, " Vectors=\"");
890                                strcat(txtBuffer, names_p[dataIdx]);
891                                strcat(txtBuffer, "\"");
892                                set_vector = TRUE;
893                            }
894                        break;
895                        case 2:
896                            if (!set_tensor) {
897                                strcat(txtBuffer, " Tensors=\"");
898                                strcat(txtBuffer, names_p[dataIdx]);
899                                strcat(txtBuffer, "\"");
900                                set_tensor = TRUE;
901                            }
902                        break;
903                        default:
904                            sprintf(errorMsg, "saveVTK: data %s: VTK supports data with rank <= 2 only.", names_p[dataIdx]);
905                            Finley_setError(VALUE_ERROR, errorMsg);
906                    }
907              }              }
908        }              if (!Finley_noError())
909        fprintf(fileHandle_p, "\n");                  break;
910      }          }
911        }      }
912        fprintf(fileHandle_p, "</DataArray>\n");      /* only continue if no error occurred */
913        fprintf(fileHandle_p, "</CellData>\n");      if (writePointData && Finley_noError()) {
914      } else {          strcat(txtBuffer, ">\n");
915        /* now for the point data */          if ( mpi_size > 1) {
916        fprintf(fileHandle_p, "<PointData %s>\n", dataTypeStr);              MPI_RANK0_WRITE_SHARED(txtBuffer);
917        fprintf(fileHandle_p, "<DataArray "          } else {
918            "Name=\"%s\" "              fputs(txtBuffer, fileHandle_p);
919            "type=\"Float32\" "          }
920            "NumberOfComponents=\"%d\" "  
921            "format=\"ascii\">\n",          /* write the arrays */
922            dataNameStr, nCompReqd);          for (dataIdx = 0; dataIdx < num_data; dataIdx++) {
923      /* write out the data */              if (!isEmpty(data_pp[dataIdx]) && !isCellCentered[dataIdx]) {
924      /* if the number of required components is more than the number                  Finley_NodeMapping* nodeMapping;
925       * of actual components, pad with zeros                  dim_t rank = getDataPointRank(data_pp[dataIdx]);
926         */                  dim_t nCompReqd = 1; /* number of components mpi_required */
927        bool_t do_write=TRUE;                  if (getFunctionSpaceType(data_pp[dataIdx]) == FINLEY_REDUCED_NODES) {
928        int shape = getDataPointShape(data_p, 0);                      nodeMapping = mesh_p->Nodes->reducedNodesMapping;
929        if (shape > 3) {                  } else {
930        sprintf(error_msg,"shape should be 1, 2, or 3; I got %d\n", shape);                      nodeMapping = mesh_p->Nodes->nodesMapping;
931            Finley_setError(VALUE_ERROR,error_msg);                  }
932        return;                  if (rank == 0) {
933        }                      nCompReqd = 1;
934        for (i=0; i<mesh_p->Nodes->numNodes; i++) {                      shape = 0;
935      switch (nodetype) {                  } else if (rank == 1) {
936      case(FINLEY_DEGREES_OF_FREEDOM):                      nCompReqd = 3;
937        values = getSampleData(data_p,mesh_p->Nodes->degreeOfFreedom[i]);                      shape = getDataPointShape(data_pp[dataIdx], 0);
938        break;                      if (shape > 3) {
939      case(FINLEY_REDUCED_DEGREES_OF_FREEDOM):                          Finley_setError(VALUE_ERROR, "saveVTK: rank 1 objects must have 3 components at most.");
940        if (mesh_p->Nodes->toReduced[i]>=0) {                      }
941              do_write=TRUE;                  } else {
942          values = getSampleData(data_p,mesh_p->Nodes->reducedDegreeOfFreedom[i]);                      nCompReqd = 9;
943        } else {                      shape=getDataPointShape(data_pp[dataIdx], 0);
944              do_write=FALSE;                      if (shape > 3 || shape != getDataPointShape(data_pp[dataIdx], 1)) {
945            }                          Finley_setError(VALUE_ERROR, "saveVTK: rank 2 objects of shape 2x2 or 3x3 supported only.");
946        break;                      }
947      case(FINLEY_NODES):                  }
948        values = getSampleData(data_p,i);                  /* bail out if an error occurred */
949        break;                  if (!Finley_noError())
950      }                      break;
951      /* write the data different ways for scalar, vector and tensor */  
952          if (do_write) {                  sprintf(txtBuffer, tag_Float_DataArray, names_p[dataIdx], nCompReqd);
953          if (nCompReqd == 1) {                  if ( mpi_size > 1) {
954            fprintf(fileHandle_p, " %e", values[0]);                      MPI_RANK0_WRITE_SHARED(txtBuffer);
955          }                  } else {
956          else if (nCompReqd == 3) {                      fputs(txtBuffer, fileHandle_p);
957            /* write out the data */                  }
958            for (int m=0; m<shape; m++)  
959              fprintf(fileHandle_p, " %e", values[m]);                  txtBuffer[0] = '\0';
960            /* pad with zeros */                  txtBufferInUse = 0;
961            for (int m=0; m<nCompReqd-shape; m++)                  for (i=0; i<mesh_p->Nodes->numNodes; i++) {
962                fprintf(fileHandle_p, " %e", 0.);                      k = globalNodeIndex[i];
963          }                      if ( (myFirstNode <= k) && (k < myLastNode) ) {
964          else if (nCompReqd == 9) {              void* sampleBuffer=allocSampleBuffer(data_pp[dataIdx]);
965            /* tensor data, so have a 3x3 matrix to output as a row                          __const double *values = getSampleDataRO(data_pp[dataIdx], nodeMapping->target[i], sampleBuffer);
966             * of 9 data points */                          /* if the number of mpi_required components is more than
967            int count = 0;                           * the number of actual components, pad with zeros.
968            for (int m=0; m<shape; m++) {                           * Probably only need to get shape of first element */
969              for (int n=0; n<shape; n++) {                          if (nCompReqd == 1) {
970                fprintf(fileHandle_p, " %e", values[count]);                              sprintf(tmpBuffer, SCALAR_FORMAT, values[0]);
971                count++;                          } else if (nCompReqd == 3) {
972              }                              if (shape==1) {
973              for (int n=0; n<3-shape; n++)                                  sprintf(tmpBuffer, VECTOR_FORMAT,
974                fprintf(fileHandle_p, " %e", 0.);                                          values[0], 0.f, 0.f);
975            }                              } else if (shape==2) {
976            for (int m=0; m<3-shape; m++)  {                                  sprintf(tmpBuffer, VECTOR_FORMAT,
977                for (int n=0; n<3; n++)                                          values[0], values[1], 0.f);
978                    fprintf(fileHandle_p, " %e", 0.);                              } else if (shape==3) {
979                }                                  sprintf(tmpBuffer, VECTOR_FORMAT,
980          }                                          values[0], values[1], values[2]);
981          fprintf(fileHandle_p, "\n");                              }
982           }                          } else if (nCompReqd == 9) {
983        }                              if (shape==1) {
984        fprintf(fileHandle_p, "</DataArray>\n");                                  sprintf(tmpBuffer, TENSOR_FORMAT,
985        fprintf(fileHandle_p, "</PointData>\n");                                      values[0], 0.f, 0.f,
986                                              0.f, 0.f, 0.f,
987                                              0.f, 0.f, 0.f);
988                                } else if (shape==2) {
989                                    sprintf(tmpBuffer, TENSOR_FORMAT,
990                                        values[0], values[1], 0.f,
991                                        values[2], values[3], 0.f,
992                                              0.f,       0.f, 0.f);
993                                } else if (shape==3) {
994                                    sprintf(tmpBuffer, TENSOR_FORMAT,
995                                        values[0], values[1], values[2],
996                                        values[3], values[4], values[5],
997                                        values[6], values[7], values[8]);
998                                }
999                            }
1000                            if ( mpi_size > 1) {
1001                                __STRCAT(txtBuffer, tmpBuffer, txtBufferInUse);
1002                            } else {
1003                                fputs(tmpBuffer, fileHandle_p);
1004                            }
1005                freeSampleBuffer(sampleBuffer);         /* no-one needs values anymore */
1006                        } /* if this is my node */
1007                    } /* for i (numNodes) */
1008    
1009                    if ( mpi_size > 1) {
1010                        MPI_WRITE_ORDERED(txtBuffer);
1011                        MPI_RANK0_WRITE_SHARED(tag_End_DataArray);
1012                    } else {
1013                        fputs(tag_End_DataArray, fileHandle_p);
1014                    }
1015                } /* !isEmpty && !isCellCentered */
1016            } /* for dataIdx */
1017    
1018            strcpy(txtBuffer, "</PointData>\n");
1019            if ( mpi_size > 1) {
1020                MPI_RANK0_WRITE_SHARED(txtBuffer);
1021            } else {
1022                fputs(txtBuffer, fileHandle_p);
1023            }
1024        } /* if noError && writePointData */
1025    
1026        /* Final write to VTK file */
1027        if (Finley_noError()) {
1028            if (mpi_size > 1) {
1029                MPI_RANK0_WRITE_SHARED(vtkFooter);
1030            } else {
1031                fputs(vtkFooter, fileHandle_p);
1032            }
1033      }      }
   }  
   
   /* finish off the piece */  
   fprintf(fileHandle_p, "</Piece>\n");  
1034    
1035    fprintf(fileHandle_p, "</UnstructuredGrid>\n");      if ( mpi_size > 1) {
1036    /* write the xml footer */  #ifdef PASO_MPI
1037    fprintf(fileHandle_p, "</VTKFile>\n");          MPI_File_close(&mpi_fileHandle_p);
1038    /* close the file */      MPI_Barrier(mesh_p->Nodes->MPIInfo->comm);
1039    fclose(fileHandle_p);  #endif
1040    return;      } else {
1041            fclose(fileHandle_p);
1042        }
1043        TMPMEMFREE(isCellCentered);
1044        TMPMEMFREE(txtBuffer);
1045  }  }
1046    
 /*  
  * Revision 1.6  2005/08/12 01:45:43  jgs  
  * erge of development branch dev-02 back to main trunk on 2005-08-12  
  *  
  * Revision 1.5.2.4  2005/09/09 08:15:17  gross  
  * bugs in vtk and dx writer fixed  
  *  
  * Revision 1.5.2.3  2005/09/08 08:28:39  gross  
  * some cleanup in savevtk  
  *  
  * Revision 1.5.2.2  2005/09/07 06:26:20  gross  
  * the solver from finley are put into the standalone package paso now  
  *  
  * Revision 1.5.2.1  2005/08/10 06:14:37  gross  
  * QUADRATIC HEXAHEDRON elements fixed  
  *  
  * Revision 1.5  2005/07/08 04:07:55  jgs  
  * Merge of development branch back to main trunk on 2005-07-08  
  *  
  * Revision 1.4  2005/05/06 04:26:15  jgs  
  * Merge of development branch back to main trunk on 2005-05-06  
  *  
  * Revision 1.1.2.7  2005/06/29 02:34:54  gross  
  * some changes towards 64 integers in finley  
  *  
  * Revision 1.1.2.6  2005/05/06 01:17:19  cochrane  
  * Fixed incorrect reporting of number of components in PointData arrays for  
  * vector data.  
  *  
  * Revision 1.1.2.5  2005/05/05 05:38:44  cochrane  
  * Improved formatting of VTK file output.  
  *  
  * Revision 1.1.2.4  2005/02/22 10:03:54  cochrane  
  * Implementation of writing of vtk xml files from finley.  This function will  
  * require more testing, but on the cases that I have tried (and with the help  
  * of Lutz and mayavi), it looks like it's producing the correct output.  Testing  
  * with more realistic data would be good.  I'm at least confident enough to  
  * commit my changes.  
  *  
  * Revision 1.1.2.3  2005/02/17 05:53:26  gross  
  * some bug in saveDX fixed: in fact the bug was in  
  * DataC/getDataPointShape  
  *  
  * Revision 1.1.2.2  2005/02/10 01:34:22  cochrane  
  * Quick fix to make sure that saveVTK compiles so that finley is still buildable.  Apologies to those this has affected.  
  *  
  * Revision 1.1.2.1  2005/02/09 06:53:15  cochrane  
  * Initial import to repository.  This is the file to implement saving finley/escript meshes out to vtk formatted files.  It is basically just a hack of the opendx equivalent, with a lot of the opendx stuff still in the file, so it doesn't actually work just yet, but it probably needs to be added to the cvs.  
  *  
  * Revision 1.1.1.1  2004/10/26 06:53:57  jgs  
  * initial import of project esys2  
  *  
  * Revision 1.1  2004/07/27 08:27:11  gross  
  * Finley: saveDX added: now it is possible to write data on boundary and contact elements  
  *  
  */  

Legend:
Removed from v.150  
changed lines
  Added in v.2548

  ViewVC Help
Powered by ViewVC 1.1.26