/[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

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

Legend:
Removed from v.2140  
changed lines
  Added in v.2141

  ViewVC Help
Powered by ViewVC 1.1.26