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

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

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

revision 2059 by gross, Mon Nov 17 22:57:50 2008 UTC revision 2856 by gross, Mon Jan 18 04:14:37 2010 UTC
# Line 1  Line 1 
1    
2  /*******************************************************  /*******************************************************
3  *  *
4  * Copyright (c) 2003-2008 by University of Queensland  * Copyright (c) 2003-2009 by University of Queensland
5  * Earth Systems Science Computational Center (ESSCC)  * Earth Systems Science Computational Center (ESSCC)
6  * http://www.uq.edu.au/esscc  * http://www.uq.edu.au/esscc
7  *  *
# Line 23  Line 23 
23    
24  #define FSCANF_CHECK(scan_ret, reason) { if (scan_ret == EOF) { perror(reason); Finley_setError(IO_ERROR,"scan error while reading finley file"); return NULL;} }  #define FSCANF_CHECK(scan_ret, reason) { if (scan_ret == EOF) { perror(reason); Finley_setError(IO_ERROR,"scan error while reading finley file"); return NULL;} }
25    
 /**************************************************************/  
   
 /*  reads a mesh from a Finley file of name fname */  
   
 Finley_Mesh* Finley_Mesh_read(char* fname,index_t order, index_t reduced_order,  bool_t optimize)  
26    
27    Finley_Mesh* Finley_Mesh_read(char* fname,index_t order, index_t reduced_order,  bool_t optimize)
28  {  {
29        Paso_MPIInfo *mpi_info = NULL;
30    Paso_MPIInfo *mpi_info = Paso_MPIInfo_alloc( MPI_COMM_WORLD );      dim_t numNodes, numDim, numEle, i0, i1;
31    dim_t numNodes, numDim, numEle, i0, i1;      Finley_Mesh *mesh_p=NULL;
32    index_t tag_key;      Finley_ReferenceElementSet *refPoints=NULL, *refContactElements=NULL, *refFaceElements=NULL, *refElements=NULL;
33    Finley_Mesh *mesh_p=NULL;      char name[LenString_MAX],element_type[LenString_MAX],frm[20];
34    char name[LenString_MAX],element_type[LenString_MAX],frm[20];      char error_msg[LenErrorMsg_MAX];
35    char error_msg[LenErrorMsg_MAX];      FILE *fileHandle_p = NULL;
36    #ifdef Finley_TRACE      ElementTypeId typeID=NoRef;
37    double time0=Finley_timer();      int scan_ret;
38    #endif  
39    FILE *fileHandle_p = NULL;      Finley_resetError();
40    ElementTypeId typeID=NoType, faceTypeID=NoType, contactTypeID=NoType, pointTypeID=NoType;      mpi_info = Paso_MPIInfo_alloc( MPI_COMM_WORLD );
41    int scan_ret;  
42          if (mpi_info->rank == 0) {
43    Finley_resetError();          /* get file handle */
44            fileHandle_p = fopen(fname, "r");
45    if (mpi_info->size > 1) {          if (fileHandle_p==NULL) {
46       Finley_setError(SYSTEM_ERROR,"Finley_Mesh_read: MPI is not suporrted yet.");              sprintf(error_msg,"Finley_Mesh_read: Opening file %s for reading failed.",fname);
47    } else {              Finley_setError(IO_ERROR,error_msg);
48       /* get file handle */              Paso_MPIInfo_free( mpi_info );
49       fileHandle_p = fopen(fname, "r");              return NULL;
      if (fileHandle_p==NULL) {  
        sprintf(error_msg,"Finley_Mesh_read: Opening file %s for reading failed.",fname);  
        Finley_setError(IO_ERROR,error_msg);  
        Paso_MPIInfo_free( mpi_info );  
        return NULL;  
      }  
     
      /* read header */  
      sprintf(frm,"%%%d[^\n]",LenString_MAX-1);  
      scan_ret = fscanf(fileHandle_p, frm, name);  
      FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
   
     
      /* get the nodes */  
     
      scan_ret = fscanf(fileHandle_p, "%1d%*s %d\n", &numDim,&numNodes);  
      FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
      /* allocate mesh */  
      mesh_p = Finley_Mesh_alloc(name,numDim,order,reduced_order,mpi_info);  
      if (Finley_noError()) {  
     
         /* read nodes */  
         Finley_NodeFile_allocTable(mesh_p->Nodes, numNodes);  
         if (Finley_noError()) {  
            if (1 == numDim) {  
                for (i0 = 0; i0 < numNodes; i0++) {  
                 scan_ret = fscanf(fileHandle_p, "%d %d %d %le\n", &mesh_p->Nodes->Id[i0],  
                        &mesh_p->Nodes->globalDegreesOfFreedom[i0], &mesh_p->Nodes->Tag[i0],  
                        &mesh_p->Nodes->Coordinates[INDEX2(0,i0,numDim)]);  
             FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
            }  
            } else if (2 == numDim) {  
                     for (i0 = 0; i0 < numNodes; i0++) {  
                           scan_ret = fscanf(fileHandle_p, "%d %d %d %le %le\n", &mesh_p->Nodes->Id[i0],  
                                  &mesh_p->Nodes->globalDegreesOfFreedom[i0], &mesh_p->Nodes->Tag[i0],  
                                  &mesh_p->Nodes->Coordinates[INDEX2(0,i0,numDim)],  
                                  &mesh_p->Nodes->Coordinates[INDEX2(1,i0,numDim)]);  
                   FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
                 }  
            } else if (3 == numDim) {  
                     for (i0 = 0; i0 < numNodes; i0++) {  
                           scan_ret = fscanf(fileHandle_p, "%d %d %d %le %le %le\n", &mesh_p->Nodes->Id[i0],  
                                  &mesh_p->Nodes->globalDegreesOfFreedom[i0], &mesh_p->Nodes->Tag[i0],  
                                  &mesh_p->Nodes->Coordinates[INDEX2(0,i0,numDim)],  
                                  &mesh_p->Nodes->Coordinates[INDEX2(1,i0,numDim)],  
                                  &mesh_p->Nodes->Coordinates[INDEX2(2,i0,numDim)]);  
                   FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
                 }  
            } /* if else else */  
         }  
         /* read elements */  
         if (Finley_noError()) {  
     
            scan_ret = fscanf(fileHandle_p, "%s %d\n", element_type, &numEle);  
        FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
            typeID=Finley_RefElement_getTypeId(element_type);  
            if (typeID==NoType) {  
              sprintf(error_msg,"Finley_Mesh_read :Unidentified element type %s",element_type);  
              Finley_setError(VALUE_ERROR,error_msg);  
            } else {  
              /* read the elements */  
              mesh_p->Elements=Finley_ElementFile_alloc(typeID,mesh_p->order, mesh_p->reduced_order, mpi_info);  
              if (Finley_noError()) {  
                  Finley_ElementFile_allocTable(mesh_p->Elements, numEle);  
                  mesh_p->Elements->minColor=0;  
                  mesh_p->Elements->maxColor=numEle-1;  
                  if (Finley_noError()) {  
                     for (i0 = 0; i0 < numEle; i0++) {  
                       scan_ret = fscanf(fileHandle_p, "%d %d", &mesh_p->Elements->Id[i0], &mesh_p->Elements->Tag[i0]);  
               FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
                       mesh_p->Elements->Color[i0]=i0;  
                       mesh_p->Elements->Owner[i0]=0;  
                       for (i1 = 0; i1 < mesh_p->Elements->ReferenceElement->Type->numNodes; i1++) {  
                            scan_ret = fscanf(fileHandle_p, " %d",  
                               &mesh_p->Elements->Nodes[INDEX2(i1, i0, mesh_p->Elements->ReferenceElement->Type->numNodes)]);  
                FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
                       } /* for i1 */  
                       scan_ret = fscanf(fileHandle_p, "\n");  
               FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
                     } /* for i0 */  
                  }  
              }  
           }  
         }  
         /* get the face elements */  
         if (Finley_noError()) {  
              scan_ret = fscanf(fileHandle_p, "%s %d\n", element_type, &numEle);  
          FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
              faceTypeID=Finley_RefElement_getTypeId(element_type);  
              if (faceTypeID==NoType) {  
                sprintf(error_msg,"Finley_Mesh_read :Unidentified element type %s for face elements",element_type);  
                Finley_setError(VALUE_ERROR,error_msg);  
              } else {  
                 mesh_p->FaceElements=Finley_ElementFile_alloc(faceTypeID,mesh_p->order, mesh_p->reduced_order, mpi_info);  
                 if (Finley_noError()) {  
                    Finley_ElementFile_allocTable(mesh_p->FaceElements, numEle);  
                    if (Finley_noError()) {  
                       mesh_p->FaceElements->minColor=0;  
                       mesh_p->FaceElements->maxColor=numEle-1;  
                       for (i0 = 0; i0 < numEle; i0++) {  
                         scan_ret = fscanf(fileHandle_p, "%d %d", &mesh_p->FaceElements->Id[i0], &mesh_p->FaceElements->Tag[i0]);  
             FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
                         mesh_p->FaceElements->Color[i0]=i0;  
                         mesh_p->FaceElements->Owner[i0]=0;  
                         for (i1 = 0; i1 < mesh_p->FaceElements->ReferenceElement->Type->numNodes; i1++) {  
                              scan_ret = fscanf(fileHandle_p, " %d",  
                                 &mesh_p->FaceElements->Nodes[INDEX2(i1, i0, mesh_p->FaceElements->ReferenceElement->Type->numNodes)]);  
                  FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
                         }   /* for i1 */  
                         scan_ret = fscanf(fileHandle_p, "\n");  
             FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
                       } /* for i0 */  
                    }  
                 }  
              }  
         }  
         /* get the Contact face element */  
         if (Finley_noError()) {  
              scan_ret = fscanf(fileHandle_p, "%s %d\n", element_type, &numEle);  
          FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
              contactTypeID=Finley_RefElement_getTypeId(element_type);  
              if (contactTypeID==NoType) {  
                sprintf(error_msg,"Finley_Mesh_read: Unidentified element type %s for contact elements",element_type);  
                Finley_setError(VALUE_ERROR,error_msg);  
              } else {  
                mesh_p->ContactElements=Finley_ElementFile_alloc(contactTypeID,mesh_p->order, mesh_p->reduced_order, mpi_info);  
                if (Finley_noError()) {  
                    Finley_ElementFile_allocTable(mesh_p->ContactElements, numEle);  
                    if (Finley_noError()) {  
                       mesh_p->ContactElements->minColor=0;  
                       mesh_p->ContactElements->maxColor=numEle-1;  
                       for (i0 = 0; i0 < numEle; i0++) {  
                         scan_ret = fscanf(fileHandle_p, "%d %d", &mesh_p->ContactElements->Id[i0], &mesh_p->ContactElements->Tag[i0]);  
             FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
                         mesh_p->ContactElements->Color[i0]=i0;  
                         mesh_p->ContactElements->Owner[i0]=0;  
                         for (i1 = 0; i1 < mesh_p->ContactElements->ReferenceElement->Type->numNodes; i1++) {  
                             scan_ret = fscanf(fileHandle_p, " %d",  
                                &mesh_p->ContactElements->Nodes[INDEX2(i1, i0, mesh_p->ContactElements->ReferenceElement->Type->numNodes)]);  
                 FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
                         }   /* for i1 */  
                         scan_ret = fscanf(fileHandle_p, "\n");  
             FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
                       } /* for i0 */  
                   }  
                }  
              }  
         }    
         /* get the nodal element */  
         if (Finley_noError()) {  
              scan_ret = fscanf(fileHandle_p, "%s %d\n", element_type, &numEle);  
          FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
              pointTypeID=Finley_RefElement_getTypeId(element_type);  
              if (pointTypeID==NoType) {  
                sprintf(error_msg,"Finley_Mesh_read: Unidentified element type %s for points",element_type);  
                Finley_setError(VALUE_ERROR,error_msg);  
              }  
              mesh_p->Points=Finley_ElementFile_alloc(pointTypeID,mesh_p->order, mesh_p->reduced_order, mpi_info);  
              if (Finley_noError()) {  
                 Finley_ElementFile_allocTable(mesh_p->Points, numEle);  
                 if (Finley_noError()) {  
                    mesh_p->Points->minColor=0;  
                    mesh_p->Points->maxColor=numEle-1;  
                    for (i0 = 0; i0 < numEle; i0++) {  
                      scan_ret = fscanf(fileHandle_p, "%d %d", &mesh_p->Points->Id[i0], &mesh_p->Points->Tag[i0]);  
              FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
                      mesh_p->Points->Color[i0]=i0;  
                      mesh_p->Points->Owner[i0]=0;  
                      for (i1 = 0; i1 < mesh_p->Points->ReferenceElement->Type->numNodes; i1++) {  
                          scan_ret = fscanf(fileHandle_p, " %d",  
                             &mesh_p->Points->Nodes[INDEX2(i1, i0, mesh_p->Points->ReferenceElement->Type->numNodes)]);  
              FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
                      }  /* for i1 */  
                      scan_ret = fscanf(fileHandle_p, "\n");  
              FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
                    } /* for i0 */  
                 }  
              }  
         }  
         /* get the name tags */  
         if (Finley_noError()) {  
            if (feof(fileHandle_p) == 0) {  
               scan_ret = fscanf(fileHandle_p, "%s\n", name);  
           FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
               while (feof(fileHandle_p) == 0) {  
                    scan_ret = fscanf(fileHandle_p, "%s %d\n", name, &tag_key);  
            FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
                    Finley_Mesh_addTagMap(mesh_p,name,tag_key);  
               }  
            }  
50          }          }
      }  
      /* close file */  
      fclose(fileHandle_p);  
     
      /*   resolve id's : */  
      /* rearrange elements: */  
     
      if (Finley_noError()) Finley_Mesh_resolveNodeIds(mesh_p);  
      if (Finley_noError()) Finley_Mesh_prepare(mesh_p, optimize);  
     
      /* that's it */  
      #ifdef Finley_TRACE  
      printf("timing: reading mesh: %.4e sec\n",Finley_timer()-time0);  
      #endif  
   }  
   
   /* that's it */  
   if (! Finley_noError()) {  
        Finley_Mesh_free(mesh_p);  
   }  
   Paso_MPIInfo_free( mpi_info );  
   return mesh_p;  
 }  
   
 Finley_Mesh* Finley_Mesh_read_MPI(char* fname,index_t order, index_t reduced_order,  bool_t optimize)  
51    
52  {          /* read header */
53            sprintf(frm,"%%%d[^\n]",LenString_MAX-1);
54    Paso_MPIInfo *mpi_info = Paso_MPIInfo_alloc( MPI_COMM_WORLD );          scan_ret = fscanf(fileHandle_p, frm, name);
55    dim_t numNodes, numDim, numEle, i0, i1;          FSCANF_CHECK(scan_ret, "Finley_Mesh_read")
56    Finley_Mesh *mesh_p=NULL;  
57    char name[LenString_MAX],element_type[LenString_MAX],frm[20];          /* get the number of nodes */
58    char error_msg[LenErrorMsg_MAX];          scan_ret = fscanf(fileHandle_p, "%1d%*s %d\n", &numDim,&numNodes);
59    #ifdef Finley_TRACE          FSCANF_CHECK(scan_ret, "Finley_Mesh_read")
   double time0=Finley_timer();  
   #endif  
   FILE *fileHandle_p = NULL;  
   ElementTypeId typeID=NoType;  
   int scan_ret;  
   
   Finley_resetError();  
   
   if (mpi_info->rank == 0) {  
      /* get file handle */  
      fileHandle_p = fopen(fname, "r");  
      if (fileHandle_p==NULL) {  
        sprintf(error_msg,"Finley_Mesh_read: Opening file %s for reading failed.",fname);  
        Finley_setError(IO_ERROR,error_msg);  
        Paso_MPIInfo_free( mpi_info );  
        return NULL;  
      }  
   
      /* read header */  
      sprintf(frm,"%%%d[^\n]",LenString_MAX-1);  
      scan_ret = fscanf(fileHandle_p, frm, name);  
      FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
   
      /* get the number of nodes */  
      scan_ret = fscanf(fileHandle_p, "%1d%*s %d\n", &numDim,&numNodes);  
      FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
   }  
   
 #ifdef PASO_MPI  
   /* MPI Broadcast numDim, numNodes, name if there are multiple MPI procs*/  
   if (mpi_info->size > 1) {  
     int temp1[3], error_code;  
     temp1[0] = numDim;  
     temp1[1] = numNodes;  
     temp1[2] = strlen(name) + 1;  
     error_code = MPI_Bcast (temp1, 3, MPI_INT,  0, mpi_info->comm);  
     if (error_code != MPI_SUCCESS) {  
       Finley_setError(PASO_MPI_ERROR, "Finley_Mesh_read: broadcast of temp1 failed");  
       return NULL;  
     }  
     numDim = temp1[0];  
     numNodes = temp1[1];  
     error_code = MPI_Bcast (name, temp1[2], MPI_CHAR, 0, mpi_info->comm);  
     if (error_code != MPI_SUCCESS) {  
       Finley_setError(PASO_MPI_ERROR, "Finley_Mesh_read: broadcast of name failed");  
       return NULL;  
60      }      }
   }  
 #endif  
61    
62       /* allocate mesh */      #ifdef PASO_MPI
63       mesh_p = Finley_Mesh_alloc(name,numDim,order,reduced_order,mpi_info);          /* MPI Broadcast numDim, numNodes, name if there are multiple MPI procs*/
64       if (Finley_noError()) {          if (mpi_info->size > 1) {
65      /* Each CPU will get at most chunkSize nodes so the message has to be sufficiently large */              int temp1[3];
66      int chunkSize = numNodes / mpi_info->size + 1, totalNodes=0, chunkNodes=0, chunkEle=0, nextCPU=1;              if (mpi_info->rank == 0) {
67      int *tempInts = TMPMEMALLOC(chunkSize*3+1, index_t);        /* Stores the integer message data */                  temp1[0] = numDim;
68      double *tempCoords = TMPMEMALLOC(chunkSize*numDim, double); /* Stores the double message data */                  temp1[1] = numNodes;
69                    temp1[2] = strlen(name) + 1;
70      /*              } else {
71        Read chunkSize nodes, send it in a chunk to worker CPU which copies chunk into its local mesh_p                  temp1[0] = 0;
72        It doesn't matter that a CPU has the wrong nodes for its elements, this is sorted out later                  temp1[1] = 0;
73        First chunk sent to CPU 1, second to CPU 2, ...                  temp1[2] = 1;
74        Last chunk stays on CPU 0 (the master)              }
75        The three columns of integers (Id, gDOF, Tag) are gathered into a single array tempInts and sent together in a single MPI message              MPI_Bcast (temp1, 3, MPI_INT,  0, mpi_info->comm);
76      */              numDim = temp1[0];
77                numNodes = temp1[1];
78      if (mpi_info->rank == 0) {  /* Master */              MPI_Bcast (name, temp1[2], MPI_CHAR, 0, mpi_info->comm);
79        for (;;) {            /* Infinite loop */          }
80          for (i0=0; i0<chunkSize*3+1; i0++) tempInts[i0] = -1;      #endif
81          for (i0=0; i0<chunkSize*numDim; i0++) tempCoords[i0] = -1.0;  
82          chunkNodes = 0;      /* allocate mesh */
83          for (i1=0; i1<chunkSize; i1++) {      mesh_p = Finley_Mesh_alloc(name,numDim,mpi_info);
84            if (totalNodes >= numNodes) break;    /* End of inner loop */      
85                if (1 == numDim) {      if (Finley_noError()) {
86          scan_ret = fscanf(fileHandle_p, "%d %d %d %le\n",          /* Each CPU will get at most chunkSize nodes so the message has to be sufficiently large */
87            &tempInts[0+i1], &tempInts[chunkSize+i1], &tempInts[chunkSize*2+i1],          int chunkSize = numNodes / mpi_info->size + 1, totalNodes=0, chunkNodes=0,  nextCPU=1;
88            &tempCoords[i1*numDim+0]);          int *tempInts = TMPMEMALLOC(chunkSize*3+1, index_t);        /* Stores the integer message data */
89          FSCANF_CHECK(scan_ret, "Finley_Mesh_read")          double *tempCoords = TMPMEMALLOC(chunkSize*numDim, double); /* Stores the double message data */
90            }  
91                if (2 == numDim) {          /*
92          scan_ret = fscanf(fileHandle_p, "%d %d %d %le %le\n",          Read chunkSize nodes, send it in a chunk to worker CPU which copies chunk into its local mesh_p
93            &tempInts[0+i1], &tempInts[chunkSize+i1], &tempInts[chunkSize*2+i1],          It doesn't matter that a CPU has the wrong nodes for its elements, this is sorted out later
94            &tempCoords[i1*numDim+0], &tempCoords[i1*numDim+1]);          First chunk sent to CPU 1, second to CPU 2, ...
95          FSCANF_CHECK(scan_ret, "Finley_Mesh_read")          Last chunk stays on CPU 0 (the master)
96            }          The three columns of integers (Id, gDOF, Tag) are gathered into a single array tempInts and sent together in a single MPI message
97                if (3 == numDim) {          */
98          scan_ret = fscanf(fileHandle_p, "%d %d %d %le %le %le\n",  
99            &tempInts[0+i1], &tempInts[chunkSize+i1], &tempInts[chunkSize*2+i1],          if (mpi_info->rank == 0) {  /* Master */
100            &tempCoords[i1*numDim+0], &tempCoords[i1*numDim+1], &tempCoords[i1*numDim+2]);              for (;;) {            /* Infinite loop */
101          FSCANF_CHECK(scan_ret, "Finley_Mesh_read")                  #pragma omp parallel for private (i0) schedule(static)
102            }                  for (i0=0; i0<chunkSize*3+1; i0++) tempInts[i0] = -1;
103            totalNodes++; /* When do we quit the infinite loop? */                  
104            chunkNodes++; /* How many nodes do we actually have in this chunk? It may be smaller than chunkSize. */                  #pragma omp parallel for private (i0) schedule(static)
105          }                  for (i0=0; i0<chunkSize*numDim; i0++) tempCoords[i0] = -1.0;
106          if (chunkNodes > chunkSize) {                  
107                Finley_setError(PASO_MPI_ERROR, "Finley_Mesh_read: error reading chunks of mesh, data too large for message size");                  chunkNodes = 0;
108                return NULL;                  for (i1=0; i1<chunkSize; i1++) {
109          }                      if (totalNodes >= numNodes) break;    /* End of inner loop */
110  #ifdef PASO_MPI                      if (1 == numDim) {
111          /* Eventually we'll send chunkSize nodes to each CPU numbered 1 ... mpi_info->size-1, here goes one of them */                          scan_ret = fscanf(fileHandle_p, "%d %d %d %le\n",
112          if (nextCPU < mpi_info->size) {                                              &tempInts[0+i1], &tempInts[chunkSize+i1], &tempInts[chunkSize*2+i1],
113                int mpi_error;                                              &tempCoords[i1*numDim+0]);
114            tempInts[chunkSize*3] = chunkNodes;   /* The message has one more int to send chunkNodes */                          FSCANF_CHECK(scan_ret, "Finley_Mesh_read")
115            mpi_error = MPI_Send(tempInts, chunkSize*3+1, MPI_INT, nextCPU, 81720, mpi_info->comm);                      }
116            if ( mpi_error != MPI_SUCCESS ) {                      if (2 == numDim) {
117                  Finley_setError(PASO_MPI_ERROR, "Finley_Mesh_read: send of tempInts failed");                          scan_ret = fscanf(fileHandle_p, "%d %d %d %le %le\n",
118                  return NULL;                                              &tempInts[0+i1], &tempInts[chunkSize+i1], &tempInts[chunkSize*2+i1],
119            }                                              &tempCoords[i1*numDim+0], &tempCoords[i1*numDim+1]);
120            mpi_error = MPI_Send(tempCoords, chunkSize*numDim, MPI_DOUBLE, nextCPU, 81721, mpi_info->comm);                          FSCANF_CHECK(scan_ret, "Finley_Mesh_read")
121            if ( mpi_error != MPI_SUCCESS ) {                      }
122                  Finley_setError(PASO_MPI_ERROR, "Finley_Mesh_read: send of tempCoords failed");                      if (3 == numDim) {
123                  return NULL;                          scan_ret = fscanf(fileHandle_p, "%d %d %d %le %le %le\n",
124            }                                              &tempInts[0+i1], &tempInts[chunkSize+i1], &tempInts[chunkSize*2+i1],
125          }                                              &tempCoords[i1*numDim+0], &tempCoords[i1*numDim+1], &tempCoords[i1*numDim+2]);
126  #endif                          FSCANF_CHECK(scan_ret, "Finley_Mesh_read")
127          nextCPU++;                      }
128          /* Infinite loop ends when I've read a chunk for each of the worker nodes plus one more chunk for the master */                      totalNodes++; /* When do we quit the infinite loop? */
129          if (nextCPU > mpi_info->size) break; /* End infinite loop */                      chunkNodes++; /* How many nodes do we actually have in this chunk? It may be smaller than chunkSize. */
130        } /* Infinite loop */                  }
131      }   /* End master */                  if (chunkNodes > chunkSize) {
132      else {  /* Worker */                      Finley_setError(PASO_MPI_ERROR, "Finley_Mesh_read: error reading chunks of mesh, data too large for message size");
133  #ifdef PASO_MPI                      return NULL;
134        /* Each worker receives two messages */                  }
135        MPI_Status status;                  #ifdef PASO_MPI
136            int mpi_error;                      /* Eventually we'll send chunkSize nodes to each CPU numbered 1 ... mpi_info->size-1, here goes one of them */
137        mpi_error = MPI_Recv(tempInts, chunkSize*3+1, MPI_INT, 0, 81720, mpi_info->comm, &status);                      if (nextCPU < mpi_info->size) {
138        if ( mpi_error != MPI_SUCCESS ) {                          tempInts[chunkSize*3] = chunkNodes;   /* The message has one more int to send chunkNodes */
139              Finley_setError(PASO_MPI_ERROR, "Finley_Mesh_read: receive of tempInts failed");                          MPI_Send(tempInts, chunkSize*3+1, MPI_INT, nextCPU, 81720, mpi_info->comm);
140              return NULL;                          MPI_Send(tempCoords, chunkSize*numDim, MPI_DOUBLE, nextCPU, 81721, mpi_info->comm);
141        }                      }
142        mpi_error = MPI_Recv(tempCoords, chunkSize*numDim, MPI_DOUBLE, 0, 81721, mpi_info->comm, &status);                  #endif
143        if ( mpi_error != MPI_SUCCESS ) {                  nextCPU++;
144              Finley_setError(PASO_MPI_ERROR, "Finley_Mesh_read: receive of tempCoords failed");                  /* Infinite loop ends when I've read a chunk for each of the worker nodes plus one more chunk for the master */
145              return NULL;                  if (nextCPU > mpi_info->size) break; /* End infinite loop */
146        }              } /* Infinite loop */
147        chunkNodes = tempInts[chunkSize*3];   /* How many nodes are in this workers chunk? */          }   /* End master */
148  #endif          else {  /* Worker */
149      }   /* Worker */              #ifdef PASO_MPI
150                    /* Each worker receives two messages */
151                    MPI_Status status;
152                    MPI_Recv(tempInts, chunkSize*3+1, MPI_INT, 0, 81720, mpi_info->comm, &status);
153                    MPI_Recv(tempCoords, chunkSize*numDim, MPI_DOUBLE, 0, 81721, mpi_info->comm, &status);
154                    chunkNodes = tempInts[chunkSize*3];   /* How many nodes are in this workers chunk? */
155                #endif
156            }   /* Worker */
157    
158      /* Copy node data from tempMem to mesh_p */          /* Copy node data from tempMem to mesh_p */
159          Finley_NodeFile_allocTable(mesh_p->Nodes, chunkNodes);          Finley_NodeFile_allocTable(mesh_p->Nodes, chunkNodes);
160          if (Finley_noError()) {          
161        for (i0=0; i0<chunkNodes; i0++) {          if (Finley_noError()) {
162          mesh_p->Nodes->Id[i0]               = tempInts[0+i0];              #pragma omp parallel for private (i0, i1) schedule(static)
163          mesh_p->Nodes->globalDegreesOfFreedom[i0]       = tempInts[chunkSize+i0];              for (i0=0; i0<chunkNodes; i0++) {
164          mesh_p->Nodes->Tag[i0]              = tempInts[chunkSize*2+i0];                  mesh_p->Nodes->Id[i0]               = tempInts[0+i0];
165          for (i1=0; i1<numDim; i1++) {                  mesh_p->Nodes->globalDegreesOfFreedom[i0]       = tempInts[chunkSize+i0];
166            mesh_p->Nodes->Coordinates[INDEX2(i1,i0,numDim)]  = tempCoords[i0*numDim+i1];                  mesh_p->Nodes->Tag[i0]              = tempInts[chunkSize*2+i0];
167          }                  for (i1=0; i1<numDim; i1++) {
168            }                      mesh_p->Nodes->Coordinates[INDEX2(i1,i0,numDim)]  = tempCoords[i0*numDim+i1];
169                    }
170                }
171          }          }
172            TMPMEMFREE(tempInts);
173      TMPMEMFREE(tempInts);          TMPMEMFREE(tempCoords);
     TMPMEMFREE(tempCoords);  
   
         /* read elements */  
   
     /* Read the element typeID */  
         if (Finley_noError()) {  
       if (mpi_info->rank == 0) {  
             scan_ret = fscanf(fileHandle_p, "%s %d\n", element_type, &numEle);  
         FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
             typeID=Finley_RefElement_getTypeId(element_type);  
       }  
 #ifdef PASO_MPI  
       if (mpi_info->size > 1) {  
         int temp1[2], mpi_error;  
         temp1[0] = (int) typeID;  
         temp1[1] = numEle;  
         mpi_error = MPI_Bcast (temp1, 2, MPI_INT,  0, mpi_info->comm);  
         if (mpi_error != MPI_SUCCESS) {  
           Finley_setError(PASO_MPI_ERROR, "Finley_Mesh_read: broadcast of Element typeID failed");  
           return NULL;  
         }  
         typeID = (ElementTypeId) temp1[0];  
         numEle = temp1[1];  
       }  
 #endif  
           if (typeID==NoType) {  
             sprintf(error_msg, "Finley_Mesh_read: Unidentified element type %s", element_type);  
             Finley_setError(VALUE_ERROR, error_msg);  
           }  
174      }      }
175    
176        /* Allocate the ElementFile */      /* ***********************************  read elements ******************************************************************/
177        mesh_p->Elements=Finley_ElementFile_alloc(typeID,mesh_p->order, mesh_p->reduced_order, mpi_info);      if (Finley_noError()) {
       numNodes = mesh_p->Elements->ReferenceElement->Type->numNodes; /* New meaning for numNodes: num nodes per element */  
   
       /* Read the element data */  
       if (Finley_noError()) {  
     int chunkSize = numEle / mpi_info->size + 1, totalEle=0, nextCPU=1;  
     int *tempInts = TMPMEMALLOC(chunkSize*(2+numNodes)+1, index_t); /* Store Id + Tag + node list (+ one int at end for chunkEle) */  
     /* Elements are specified as a list of integers...only need one message instead of two as with the nodes */  
     if (mpi_info->rank == 0) {  /* Master */  
       for (;;) {            /* Infinite loop */  
         for (i0=0; i0<chunkSize*(2+numNodes)+1; i0++) tempInts[i0] = -1;  
         chunkEle = 0;  
         for (i0=0; i0<chunkSize; i0++) {  
           if (totalEle >= numEle) break; /* End inner loop */  
           scan_ret = fscanf(fileHandle_p, "%d %d", &tempInts[i0*(2+numNodes)+0], &tempInts[i0*(2+numNodes)+1]);  
           FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
           for (i1 = 0; i1 < numNodes; i1++) {  
         scan_ret = fscanf(fileHandle_p, " %d", &tempInts[i0*(2+numNodes)+2+i1]);  
             FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
           }  
           scan_ret = fscanf(fileHandle_p, "\n");  
           FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
           totalEle++;  
           chunkEle++;  
         }  
 #ifdef PASO_MPI  
         /* Eventually we'll send chunk of elements to each CPU except 0 itself, here goes one of them */  
         if (nextCPU < mpi_info->size) {  
               int mpi_error;  
           tempInts[chunkSize*(2+numNodes)] = chunkEle;  
           mpi_error = MPI_Send(tempInts, chunkSize*(2+numNodes)+1, MPI_INT, nextCPU, 81722, mpi_info->comm);  
           if ( mpi_error != MPI_SUCCESS ) {  
                 Finley_setError(PASO_MPI_ERROR, "Finley_Mesh_read: send of tempInts for Elements failed");  
                 return NULL;  
           }  
         }  
 #endif  
         nextCPU++;  
         /* Infinite loop ends when I've read a chunk for each of the worker nodes plus one more chunk for the master */  
         if (nextCPU > mpi_info->size) break; /* End infinite loop */  
       } /* Infinite loop */  
     }   /* End master */  
     else {  /* Worker */  
 #ifdef PASO_MPI  
       /* Each worker receives one message */  
       MPI_Status status;  
       int mpi_error;  
       mpi_error = MPI_Recv(tempInts, chunkSize*(2+numNodes)+1, MPI_INT, 0, 81722, mpi_info->comm, &status);  
       if ( mpi_error != MPI_SUCCESS ) {  
             Finley_setError(PASO_MPI_ERROR, "Finley_Mesh_read: receive of tempInts for Elements failed");  
             return NULL;  
       }  
       chunkEle = tempInts[chunkSize*(2+numNodes)];  
 #endif  
     }   /* Worker */  
   
     /* Copy Element data from tempInts to mesh_p */  
     Finley_ElementFile_allocTable(mesh_p->Elements, chunkEle);  
         mesh_p->Elements->minColor=0;  
         mesh_p->Elements->maxColor=chunkEle-1;  
         if (Finley_noError()) {  
           #pragma omp parallel for private (i0, i1)  
       for (i0=0; i0<chunkEle; i0++) {  
         mesh_p->Elements->Id[i0]    = tempInts[i0*(2+numNodes)+0];  
         mesh_p->Elements->Tag[i0]   = tempInts[i0*(2+numNodes)+1];  
             mesh_p->Elements->Owner[i0]  =mpi_info->rank;  
             mesh_p->Elements->Color[i0] = i0;  
         for (i1 = 0; i1 < numNodes; i1++) {  
           mesh_p->Elements->Nodes[INDEX2(i1, i0, numNodes)] = tempInts[i0*(2+numNodes)+2+i1];  
         }  
           }  
         }  
   
     TMPMEMFREE(tempInts);  
       } /* end of Read the element data */  
   
         /* read face elements */  
178    
179      /* Read the element typeID */          /* Read the element typeID */
180          if (Finley_noError()) {          if (mpi_info->rank == 0) {
181        if (mpi_info->rank == 0) {              scan_ret = fscanf(fileHandle_p, "%s %d\n", element_type, &numEle);
182              scan_ret = fscanf(fileHandle_p, "%s %d\n", element_type, &numEle);              FSCANF_CHECK(scan_ret, "Finley_Mesh_read")
183          FSCANF_CHECK(scan_ret, "Finley_Mesh_read")              typeID=Finley_ReferenceElement_getTypeId(element_type);
184              typeID=Finley_RefElement_getTypeId(element_type);          }
185        }          #ifdef PASO_MPI
186  #ifdef PASO_MPI              if (mpi_info->size > 1) {
187        if (mpi_info->size > 1) {                  int temp1[2], mpi_error;
188          int temp1[2], mpi_error;                  temp1[0] = (int) typeID;
189          temp1[0] = (int) typeID;                  temp1[1] = numEle;
190          temp1[1] = numEle;                  mpi_error = MPI_Bcast (temp1, 2, MPI_INT,  0, mpi_info->comm);
191          mpi_error = MPI_Bcast (temp1, 2, MPI_INT,  0, mpi_info->comm);                  if (mpi_error != MPI_SUCCESS) {
192          if (mpi_error != MPI_SUCCESS) {                      Finley_setError(PASO_MPI_ERROR, "Finley_Mesh_read: broadcast of Element typeID failed");
193            Finley_setError(PASO_MPI_ERROR, "Finley_Mesh_read: broadcast of Element typeID failed");                      return NULL;
194            return NULL;                  }
195          }                  typeID = (ElementTypeId) temp1[0];
196          typeID = (ElementTypeId) temp1[0];                  numEle = temp1[1];
197          numEle = temp1[1];              }
198        }          #endif
199  #endif          if (typeID==NoRef) {
           if (typeID==NoType) {  
200              sprintf(error_msg, "Finley_Mesh_read: Unidentified element type %s", element_type);              sprintf(error_msg, "Finley_Mesh_read: Unidentified element type %s", element_type);
201              Finley_setError(VALUE_ERROR, error_msg);              Finley_setError(VALUE_ERROR, error_msg);
202            }            }
203      }      }
204    
205        /* Allocate the ElementFile */      /* Allocate the ElementFile */
206        mesh_p->FaceElements=Finley_ElementFile_alloc(typeID,mesh_p->order, mesh_p->reduced_order, mpi_info);      if (Finley_noError()) {
207        numNodes = mesh_p->FaceElements->ReferenceElement->Type->numNodes; /* New meaning for numNodes: num nodes per element */          refElements= Finley_ReferenceElementSet_alloc(typeID,order, reduced_order);
208            mesh_p->Elements=Finley_ElementFile_alloc(refElements, mpi_info);
209        /* Read the face element data */          numNodes = mesh_p->Elements->referenceElementSet->numNodes; /* New meaning for numNodes: num nodes per element */
210        if (Finley_noError()) {      }
     int chunkSize = numEle / mpi_info->size + 1, totalEle=0, nextCPU=1;  
     int *tempInts = TMPMEMALLOC(chunkSize*(2+numNodes)+1, index_t); /* Store Id + Tag + node list (+ one int at end for chunkEle) */  
     /* Elements are specified as a list of integers...only need one message instead of two as with the nodes */  
     if (mpi_info->rank == 0) {  /* Master */  
       for (;;) {            /* Infinite loop */  
         for (i0=0; i0<chunkSize*(2+numNodes)+1; i0++) tempInts[i0] = -1;  
         chunkEle = 0;  
         for (i0=0; i0<chunkSize; i0++) {  
           if (totalEle >= numEle) break; /* End inner loop */  
           scan_ret = fscanf(fileHandle_p, "%d %d", &tempInts[i0*(2+numNodes)+0], &tempInts[i0*(2+numNodes)+1]);  
           FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
           for (i1 = 0; i1 < numNodes; i1++) {  
         scan_ret = fscanf(fileHandle_p, " %d", &tempInts[i0*(2+numNodes)+2+i1]);  
             FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
           }  
           scan_ret = fscanf(fileHandle_p, "\n");  
           FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
           totalEle++;  
           chunkEle++;  
         }  
 #ifdef PASO_MPI  
         /* Eventually we'll send chunk of elements to each CPU except 0 itself, here goes one of them */  
         if (nextCPU < mpi_info->size) {  
               int mpi_error;  
           tempInts[chunkSize*(2+numNodes)] = chunkEle;  
           mpi_error = MPI_Send(tempInts, chunkSize*(2+numNodes)+1, MPI_INT, nextCPU, 81723, mpi_info->comm);  
           if ( mpi_error != MPI_SUCCESS ) {  
                 Finley_setError(PASO_MPI_ERROR, "Finley_Mesh_read: send of tempInts for FaceElements failed");  
                 return NULL;  
           }  
         }  
 #endif  
         nextCPU++;  
         /* Infinite loop ends when I've read a chunk for each of the worker nodes plus one more chunk for the master */  
         if (nextCPU > mpi_info->size) break; /* End infinite loop */  
       } /* Infinite loop */  
     }   /* End master */  
     else {  /* Worker */  
 #ifdef PASO_MPI  
       /* Each worker receives one message */  
       MPI_Status status;  
       int mpi_error;  
       mpi_error = MPI_Recv(tempInts, chunkSize*(2+numNodes)+1, MPI_INT, 0, 81723, mpi_info->comm, &status);  
       if ( mpi_error != MPI_SUCCESS ) {  
             Finley_setError(PASO_MPI_ERROR, "Finley_Mesh_read: receive of tempInts for FaceElements failed");  
             return NULL;  
       }  
       chunkEle = tempInts[chunkSize*(2+numNodes)];  
 #endif  
     }   /* Worker */  
   
     /* Copy Element data from tempInts to mesh_p */  
     Finley_ElementFile_allocTable(mesh_p->FaceElements, chunkEle);  
         mesh_p->FaceElements->minColor=0;  
         mesh_p->FaceElements->maxColor=chunkEle-1;  
         if (Finley_noError()) {  
           #pragma omp parallel for private (i0, i1)  
       for (i0=0; i0<chunkEle; i0++) {  
         mesh_p->FaceElements->Id[i0]    = tempInts[i0*(2+numNodes)+0];  
         mesh_p->FaceElements->Tag[i0]   = tempInts[i0*(2+numNodes)+1];  
             mesh_p->FaceElements->Owner[i0]  =mpi_info->rank;  
             mesh_p->FaceElements->Color[i0] = i0;  
         for (i1 = 0; i1 < numNodes; i1++) {  
           mesh_p->FaceElements->Nodes[INDEX2(i1, i0, numNodes)] = tempInts[i0*(2+numNodes)+2+i1];  
         }  
           }  
         }  
211    
212      TMPMEMFREE(tempInts);      /* *************************** Read the element data *******************************************************************/
213        } /* end of Read the face element data */      if (Finley_noError()) {
214    
215          /* read contact elements */          int chunkSize = numEle / mpi_info->size + 1, totalEle=0, nextCPU=1, chunkEle=0;
216            int *tempInts = TMPMEMALLOC(chunkSize*(2+numNodes)+1, index_t); /* Store Id + Tag + node list (+ one int at end for chunkEle) */
217            /* Elements are specified as a list of integers...only need one message instead of two as with the nodes */
218            if (mpi_info->rank == 0) {  /* Master */
219                for (;;) {            /* Infinite loop */
220                    #pragma omp parallel for private (i0) schedule(static)
221                    for (i0=0; i0<chunkSize*(2+numNodes)+1; i0++) tempInts[i0] = -1;
222            
223                    chunkEle = 0;
224                    for (i0=0; i0<chunkSize; i0++) {
225                        if (totalEle >= numEle) break; /* End inner loop */
226                        scan_ret = fscanf(fileHandle_p, "%d %d", &tempInts[i0*(2+numNodes)+0], &tempInts[i0*(2+numNodes)+1]);
227                        FSCANF_CHECK(scan_ret, "Finley_Mesh_read")
228                        for (i1 = 0; i1 < numNodes; i1++) {
229                            scan_ret = fscanf(fileHandle_p, " %d", &tempInts[i0*(2+numNodes)+2+i1]);
230                            FSCANF_CHECK(scan_ret, "Finley_Mesh_read")
231                        }
232                        scan_ret = fscanf(fileHandle_p, "\n");
233                        FSCANF_CHECK(scan_ret, "Finley_Mesh_read")
234                        totalEle++;
235                        chunkEle++;
236                    }
237                    #ifdef PASO_MPI
238                        /* Eventually we'll send chunk of elements to each CPU except 0 itself, here goes one of them */
239                        if (nextCPU < mpi_info->size) {
240                            tempInts[chunkSize*(2+numNodes)] = chunkEle;
241                            MPI_Send(tempInts, chunkSize*(2+numNodes)+1, MPI_INT, nextCPU, 81722, mpi_info->comm);
242                        }
243                    #endif
244                    nextCPU++;
245                    /* Infinite loop ends when I've read a chunk for each of the worker nodes plus one more chunk for the master */
246                    if (nextCPU > mpi_info->size) break; /* End infinite loop */
247                } /* Infinite loop */
248            }   /* End master */
249            else {  /* Worker */
250                #ifdef PASO_MPI
251                    /* Each worker receives one message */
252                    MPI_Status status;
253                    MPI_Recv(tempInts, chunkSize*(2+numNodes)+1, MPI_INT, 0, 81722, mpi_info->comm, &status);
254                    chunkEle = tempInts[chunkSize*(2+numNodes)];
255                #endif
256            }   /* Worker */
257    
258            
259            Finley_ElementFile_allocTable(mesh_p->Elements, chunkEle);
260    
261        
262            /* Copy Element data from tempInts to mesh_p */
263            if (Finley_noError()) {
264    
265                mesh_p->Elements->minColor=0;
266                mesh_p->Elements->maxColor=chunkEle-1;
267                #pragma omp parallel for private (i0, i1) schedule(static)
268                for (i0=0; i0<chunkEle; i0++) {
269                    mesh_p->Elements->Id[i0]    = tempInts[i0*(2+numNodes)+0];
270                    mesh_p->Elements->Tag[i0]   = tempInts[i0*(2+numNodes)+1];
271                    mesh_p->Elements->Owner[i0]  =mpi_info->rank;
272                    mesh_p->Elements->Color[i0] = i0;
273                    for (i1 = 0; i1 < numNodes; i1++) {
274                        mesh_p->Elements->Nodes[INDEX2(i1, i0, numNodes)] = tempInts[i0*(2+numNodes)+2+i1];
275                    }
276                }
277            }
278    
279            TMPMEMFREE(tempInts);
280        }
281        /* ******************** end of Read the element data ******************************************************/
282    
283        /* ********************* read face elements ***************************************************************/
284        if (Finley_noError()) {
285            /* Read the element typeID */
286    
287      /* Read the element typeID */          if (mpi_info->rank == 0) {
288          if (Finley_noError()) {               scan_ret = fscanf(fileHandle_p, "%s %d\n", element_type, &numEle);
289        if (mpi_info->rank == 0) {               FSCANF_CHECK(scan_ret, "Finley_Mesh_read")
290              scan_ret = fscanf(fileHandle_p, "%s %d\n", element_type, &numEle);               typeID=Finley_ReferenceElement_getTypeId(element_type);
291          FSCANF_CHECK(scan_ret, "Finley_Mesh_read")          }
292              typeID=Finley_RefElement_getTypeId(element_type);          #ifdef PASO_MPI
293        }              if (mpi_info->size > 1) {
294  #ifdef PASO_MPI                  int temp1[2];
295        if (mpi_info->size > 1) {                  temp1[0] = (int) typeID;
296          int temp1[2], mpi_error;                  temp1[1] = numEle;
297          temp1[0] = (int) typeID;                  MPI_Bcast (temp1, 2, MPI_INT,  0, mpi_info->comm);
298          temp1[1] = numEle;                  typeID = (ElementTypeId) temp1[0];
299          mpi_error = MPI_Bcast (temp1, 2, MPI_INT,  0, mpi_info->comm);                  numEle = temp1[1];
300          if (mpi_error != MPI_SUCCESS) {              }
301            Finley_setError(PASO_MPI_ERROR, "Finley_Mesh_read: broadcast of Element typeID failed");          #endif
302            return NULL;          if (typeID==NoRef) {
         }  
         typeID = (ElementTypeId) temp1[0];  
         numEle = temp1[1];  
       }  
 #endif  
           if (typeID==NoType) {  
303              sprintf(error_msg, "Finley_Mesh_read: Unidentified element type %s", element_type);              sprintf(error_msg, "Finley_Mesh_read: Unidentified element type %s", element_type);
304              Finley_setError(VALUE_ERROR, error_msg);              Finley_setError(VALUE_ERROR, error_msg);
           }  
     }  
   
       /* Allocate the ElementFile */  
       mesh_p->ContactElements=Finley_ElementFile_alloc(typeID,mesh_p->order, mesh_p->reduced_order, mpi_info);  
       numNodes = mesh_p->ContactElements->ReferenceElement->Type->numNodes; /* New meaning for numNodes: num nodes per element */  
   
       /* Read the contact element data */  
       if (Finley_noError()) {  
     int chunkSize = numEle / mpi_info->size + 1, totalEle=0, nextCPU=1;  
     int *tempInts = TMPMEMALLOC(chunkSize*(2+numNodes)+1, index_t); /* Store Id + Tag + node list (+ one int at end for chunkEle) */  
     /* Elements are specified as a list of integers...only need one message instead of two as with the nodes */  
     if (mpi_info->rank == 0) {  /* Master */  
       for (;;) {            /* Infinite loop */  
         for (i0=0; i0<chunkSize*(2+numNodes)+1; i0++) tempInts[i0] = -1;  
         chunkEle = 0;  
         for (i0=0; i0<chunkSize; i0++) {  
           if (totalEle >= numEle) break; /* End inner loop */  
           scan_ret = fscanf(fileHandle_p, "%d %d", &tempInts[i0*(2+numNodes)+0], &tempInts[i0*(2+numNodes)+1]);  
           FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
           for (i1 = 0; i1 < numNodes; i1++) {  
         scan_ret = fscanf(fileHandle_p, " %d", &tempInts[i0*(2+numNodes)+2+i1]);  
             FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
           }  
           scan_ret = fscanf(fileHandle_p, "\n");  
           FSCANF_CHECK(scan_ret, "Finley_Mesh_read")  
           totalEle++;  
           chunkEle++;  
         }  
 #ifdef PASO_MPI  
         /* Eventually we'll send chunk of elements to each CPU except 0 itself, here goes one of them */  
         if (nextCPU < mpi_info->size) {  
               int mpi_error;  
           tempInts[chunkSize*(2+numNodes)] = chunkEle;  
           mpi_error = MPI_Send(tempInts, chunkSize*(2+numNodes)+1, MPI_INT, nextCPU, 81724, mpi_info->comm);  
           if ( mpi_error != MPI_SUCCESS ) {  
                 Finley_setError(PASO_MPI_ERROR, "Finley_Mesh_read: send of tempInts for ContactElements failed");  
                 return NULL;  
           }  
         }  
 #endif  
         nextCPU++;  
         /* Infinite loop ends when I've read a chunk for each of the worker nodes plus one more chunk for the master */  
         if (nextCPU > mpi_info->size) break; /* End infinite loop */  
       } /* Infinite loop */  
     }   /* End master */  
     else {  /* Worker */  
 #ifdef PASO_MPI  
       /* Each worker receives one message */  
       MPI_Status status;  
       int mpi_error;  
       mpi_error = MPI_Recv(tempInts, chunkSize*(2+numNodes)+1, MPI_INT, 0, 81724, mpi_info->comm, &status);  
       if ( mpi_error != MPI_SUCCESS ) {  
             Finley_setError(PASO_MPI_ERROR, "Finley_Mesh_read: receive of tempInts for ContactElements failed");  
             return NULL;  
       }  
       chunkEle = tempInts[chunkSize*(2+numNodes)];  
 #endif  
     }   /* Worker */  
   
     /* Copy Element data from tempInts to mesh_p */  
     Finley_ElementFile_allocTable(mesh_p->ContactElements, chunkEle);  
         mesh_p->ContactElements->minColor=0;  
         mesh_p->ContactElements->maxColor=chunkEle-1;  
         if (Finley_noError()) {  
           #pragma omp parallel for private (i0, i1)  
       for (i0=0; i0<chunkEle; i0++) {  
         mesh_p->ContactElements->Id[i0] = tempInts[i0*(2+numNodes)+0];  
         mesh_p->ContactElements->Tag[i0]    = tempInts[i0*(2+numNodes)+1];  
             mesh_p->ContactElements->Owner[i0]  =mpi_info->rank;  
             mesh_p->ContactElements->Color[i0] = i0;  
         for (i1 = 0; i1 < numNodes; i1++) {  
           mesh_p->ContactElements->Nodes[INDEX2(i1, i0, numNodes)] = tempInts[i0*(2+numNodes)+2+i1];  
         }  
           }  
305          }          }
306            if (Finley_noError()) {
307                /* Allocate the ElementFile */
308                refFaceElements= Finley_ReferenceElementSet_alloc(typeID,order, reduced_order);
309                mesh_p->FaceElements=Finley_ElementFile_alloc(refFaceElements, mpi_info);
310                numNodes = mesh_p->FaceElements->referenceElementSet->numNodes; /* New meaning for numNodes: num nodes per element */
311            }
312    
313      TMPMEMFREE(tempInts);      }
       } /* end of Read the contact element data */  
314    
315          /* read nodal elements */      /* ********************** Read the face element data ********************************************************* */
316    
317      /* Read the element typeID */      if (Finley_noError()) {
318          if (Finley_noError()) {          int chunkSize = numEle / mpi_info->size + 1, totalEle=0, nextCPU=1, chunkEle=0;
319        if (mpi_info->rank == 0) {          int *tempInts = TMPMEMALLOC(chunkSize*(2+numNodes)+1, index_t); /* Store Id + Tag + node list (+ one int at end for chunkEle) */
320              scan_ret = fscanf(fileHandle_p, "%s %d\n", element_type, &numEle);          /* Elements are specified as a list of integers...only need one message instead of two as with the nodes */
321          FSCANF_CHECK(scan_ret, "Finley_Mesh_read")          if (mpi_info->rank == 0) {  /* Master */
322              typeID=Finley_RefElement_getTypeId(element_type);              for (;;) {            /* Infinite loop */
323        }                  #pragma omp parallel for private (i0) schedule(static)
324  #ifdef PASO_MPI                  for (i0=0; i0<chunkSize*(2+numNodes)+1; i0++) tempInts[i0] = -1;
325        if (mpi_info->size > 1) {          
326          int temp1[2], mpi_error;                  chunkEle = 0;
327          temp1[0] = (int) typeID;                  for (i0=0; i0<chunkSize; i0++) {
328          temp1[1] = numEle;                      if (totalEle >= numEle) break; /* End inner loop */
329          mpi_error = MPI_Bcast (temp1, 2, MPI_INT,  0, mpi_info->comm);                      scan_ret = fscanf(fileHandle_p, "%d %d", &tempInts[i0*(2+numNodes)+0], &tempInts[i0*(2+numNodes)+1]);
330          if (mpi_error != MPI_SUCCESS) {                      FSCANF_CHECK(scan_ret, "Finley_Mesh_read")
331            Finley_setError(PASO_MPI_ERROR, "Finley_Mesh_read: broadcast of Element typeID failed");                      for (i1 = 0; i1 < numNodes; i1++) {
332            return NULL;                          scan_ret = fscanf(fileHandle_p, " %d", &tempInts[i0*(2+numNodes)+2+i1]);
333          }                          FSCANF_CHECK(scan_ret, "Finley_Mesh_read")
334          typeID = (ElementTypeId) temp1[0];                      }
335          numEle = temp1[1];                      scan_ret = fscanf(fileHandle_p, "\n");
336        }                      FSCANF_CHECK(scan_ret, "Finley_Mesh_read")
337  #endif                      totalEle++;
338            if (typeID==NoType) {                      chunkEle++;
339              sprintf(error_msg, "Finley_Mesh_read: Unidentified element type %s", element_type);                  }
340                    #ifdef PASO_MPI
341                        /* Eventually we'll send chunk of elements to each CPU except 0 itself, here goes one of them */
342                        if (nextCPU < mpi_info->size) {
343                            tempInts[chunkSize*(2+numNodes)] = chunkEle;
344                            MPI_Send(tempInts, chunkSize*(2+numNodes)+1, MPI_INT, nextCPU, 81723, mpi_info->comm);
345                        }
346                    #endif
347                    nextCPU++;
348                    /* Infinite loop ends when I've read a chunk for each of the worker nodes plus one more chunk for the master */
349                    if (nextCPU > mpi_info->size) break; /* End infinite loop */
350                } /* Infinite loop */
351            }   /* End master */
352            else {  /* Worker */
353                #ifdef PASO_MPI
354                    /* Each worker receives one message */
355                    MPI_Status status;
356                    MPI_Recv(tempInts, chunkSize*(2+numNodes)+1, MPI_INT, 0, 81723, mpi_info->comm, &status);
357                    chunkEle = tempInts[chunkSize*(2+numNodes)];
358                    #endif
359            }   /* Worker */
360            
361            Finley_ElementFile_allocTable(mesh_p->FaceElements, chunkEle);
362            
363            if (Finley_noError()) {
364                /* Copy Element data from tempInts to mesh_p */
365                
366                mesh_p->FaceElements->minColor=0;
367                mesh_p->FaceElements->maxColor=chunkEle-1;
368                #pragma omp parallel for private (i0, i1)
369                for (i0=0; i0<chunkEle; i0++) {
370                    mesh_p->FaceElements->Id[i0]    = tempInts[i0*(2+numNodes)+0];
371                    mesh_p->FaceElements->Tag[i0]   = tempInts[i0*(2+numNodes)+1];
372                    mesh_p->FaceElements->Owner[i0]  =mpi_info->rank;
373                    mesh_p->FaceElements->Color[i0] = i0;
374                    for (i1 = 0; i1 < numNodes; i1++) {
375                        mesh_p->FaceElements->Nodes[INDEX2(i1, i0, numNodes)] = tempInts[i0*(2+numNodes)+2+i1];
376                    }
377                }
378            }
379    
380            TMPMEMFREE(tempInts);
381        }
382        /* ************************************* end of Read the face element data *************************************** */
383    
384    
385        /* ************************************* read contact elements ************************************************** */
386    
387        /* Read the element typeID */
388        if (Finley_noError()) {
389            if (mpi_info->rank == 0) {
390                scan_ret = fscanf(fileHandle_p, "%s %d\n", element_type, &numEle);
391                FSCANF_CHECK(scan_ret, "Finley_Mesh_read")
392                typeID=Finley_ReferenceElement_getTypeId(element_type);
393            }
394            #ifdef PASO_MPI
395                if (mpi_info->size > 1) {
396                    int temp1[2];
397                    temp1[0] = (int) typeID;
398                    temp1[1] = numEle;
399                    MPI_Bcast (temp1, 2, MPI_INT,  0, mpi_info->comm);
400                    typeID = (ElementTypeId) temp1[0];
401                    numEle = temp1[1];
402                }
403            #endif
404            if (typeID==NoRef) {
405                sprintf(error_msg, "Finley_Mesh_read: Unidentified element type %s", element_type);
406              Finley_setError(VALUE_ERROR, error_msg);              Finley_setError(VALUE_ERROR, error_msg);
407            }           }
408      }      }
409    
410        /* Allocate the ElementFile */      if (Finley_noError()) {
411        mesh_p->Points=Finley_ElementFile_alloc(typeID,mesh_p->order, mesh_p->reduced_order, mpi_info);          /* Allocate the ElementFile */
412        numNodes = mesh_p->Points->ReferenceElement->Type->numNodes; /* New meaning for numNodes: num nodes per element */          refContactElements= Finley_ReferenceElementSet_alloc(typeID,order, reduced_order);
413            mesh_p->ContactElements=Finley_ElementFile_alloc(refContactElements, mpi_info);
414        /* Read the nodal element data */          numNodes = mesh_p->ContactElements->referenceElementSet->numNodes; /* New meaning for numNodes: num nodes per element */
415        if (Finley_noError()) {      }
416      int chunkSize = numEle / mpi_info->size + 1, totalEle=0, nextCPU=1;      /* *************************** Read the contact element data ************************************************* */
417      int *tempInts = TMPMEMALLOC(chunkSize*(2+numNodes)+1, index_t); /* Store Id + Tag + node list (+ one int at end for chunkEle) */      if (Finley_noError()) {
418      /* Elements are specified as a list of integers...only need one message instead of two as with the nodes */          int chunkSize = numEle / mpi_info->size + 1, totalEle=0, nextCPU=1, chunkEle=0;
419      if (mpi_info->rank == 0) {  /* Master */          int *tempInts = TMPMEMALLOC(chunkSize*(2+numNodes)+1, index_t); /* Store Id + Tag + node list (+ one int at end for chunkEle) */
420        for (;;) {            /* Infinite loop */          /* Elements are specified as a list of integers...only need one message instead of two as with the nodes */
421          for (i0=0; i0<chunkSize*(2+numNodes)+1; i0++) tempInts[i0] = -1;          if (mpi_info->rank == 0) {  /* Master */
422          chunkEle = 0;              for (;;) {            /* Infinite loop */
423          for (i0=0; i0<chunkSize; i0++) {                  #pragma omp parallel for private (i0) schedule(static)
424            if (totalEle >= numEle) break; /* End inner loop */                  for (i0=0; i0<chunkSize*(2+numNodes)+1; i0++) tempInts[i0] = -1;
425            scan_ret = fscanf(fileHandle_p, "%d %d", &tempInts[i0*(2+numNodes)+0], &tempInts[i0*(2+numNodes)+1]);        
426            FSCANF_CHECK(scan_ret, "Finley_Mesh_read")                  chunkEle = 0;
427            for (i1 = 0; i1 < numNodes; i1++) {                  for (i0=0; i0<chunkSize; i0++) {
428          scan_ret = fscanf(fileHandle_p, " %d", &tempInts[i0*(2+numNodes)+2+i1]);                      if (totalEle >= numEle) break; /* End inner loop */
429              FSCANF_CHECK(scan_ret, "Finley_Mesh_read")                      scan_ret = fscanf(fileHandle_p, "%d %d", &tempInts[i0*(2+numNodes)+0], &tempInts[i0*(2+numNodes)+1]);
430            }                      FSCANF_CHECK(scan_ret, "Finley_Mesh_read")
431            scan_ret = fscanf(fileHandle_p, "\n");                      for (i1 = 0; i1 < numNodes; i1++) {
432            FSCANF_CHECK(scan_ret, "Finley_Mesh_read")                          scan_ret = fscanf(fileHandle_p, " %d", &tempInts[i0*(2+numNodes)+2+i1]);
433            totalEle++;                          FSCANF_CHECK(scan_ret, "Finley_Mesh_read")
434            chunkEle++;                      }
435          }                      scan_ret = fscanf(fileHandle_p, "\n");
436  #ifdef PASO_MPI                      FSCANF_CHECK(scan_ret, "Finley_Mesh_read")
437          /* Eventually we'll send chunk of elements to each CPU except 0 itself, here goes one of them */                      totalEle++;
438          if (nextCPU < mpi_info->size) {                      chunkEle++;
439                int mpi_error;                  }
440            tempInts[chunkSize*(2+numNodes)] = chunkEle;                  #ifdef PASO_MPI
441            mpi_error = MPI_Send(tempInts, chunkSize*(2+numNodes)+1, MPI_INT, nextCPU, 81725, mpi_info->comm);                      /* Eventually we'll send chunk of elements to each CPU except 0 itself, here goes one of them */
442            if ( mpi_error != MPI_SUCCESS ) {                      if (nextCPU < mpi_info->size) {
443                  Finley_setError(PASO_MPI_ERROR, "Finley_Mesh_read: send of tempInts for Points failed");                          tempInts[chunkSize*(2+numNodes)] = chunkEle;
444                  return NULL;                          MPI_Send(tempInts, chunkSize*(2+numNodes)+1, MPI_INT, nextCPU, 81724, mpi_info->comm);
445            }                      }
446          }                  #endif
447  #endif                  nextCPU++;
448          nextCPU++;                  /* Infinite loop ends when I've read a chunk for each of the worker nodes plus one more chunk for the master */
449          /* Infinite loop ends when I've read a chunk for each of the worker nodes plus one more chunk for the master */                  if (nextCPU > mpi_info->size) break; /* End infinite loop */
450          if (nextCPU > mpi_info->size) break; /* End infinite loop */              } /* Infinite loop */
451        } /* Infinite loop */          }   /* End master */
452      }   /* End master */          else {  /* Worker */
453      else {  /* Worker */              #ifdef PASO_MPI
454  #ifdef PASO_MPI                  /* Each worker receives one message */
455        /* Each worker receives one message */                  MPI_Status status;
456        MPI_Status status;                  MPI_Recv(tempInts, chunkSize*(2+numNodes)+1, MPI_INT, 0, 81724, mpi_info->comm, &status);
457        int mpi_error;                  chunkEle = tempInts[chunkSize*(2+numNodes)] ;
458        mpi_error = MPI_Recv(tempInts, chunkSize*(2+numNodes)+1, MPI_INT, 0, 81725, mpi_info->comm, &status);              #endif
459        if ( mpi_error != MPI_SUCCESS ) {          }   /* Worker */
460              Finley_setError(PASO_MPI_ERROR, "Finley_Mesh_read: receive of tempInts for Points failed");  
461              return NULL;          /* Copy Element data from tempInts to mesh_p */
462        }           Finley_ElementFile_allocTable(mesh_p->ContactElements, chunkEle);
463        chunkEle = tempInts[chunkSize*(2+numNodes)];          
464  #endif           if (Finley_noError()) {        
465      }   /* Worker */               mesh_p->ContactElements->minColor=0;
466                 mesh_p->ContactElements->maxColor=chunkEle-1;
467      /* Copy Element data from tempInts to mesh_p */               #pragma omp parallel for private (i0, i1)
468      Finley_ElementFile_allocTable(mesh_p->Points, chunkEle);               for (i0=0; i0<chunkEle; i0++) {
469          mesh_p->Points->minColor=0;                   mesh_p->ContactElements->Id[i0] = tempInts[i0*(2+numNodes)+0];
470          mesh_p->Points->maxColor=chunkEle-1;                   mesh_p->ContactElements->Tag[i0]    = tempInts[i0*(2+numNodes)+1];
471          if (Finley_noError()) {                   mesh_p->ContactElements->Owner[i0]  =mpi_info->rank;
472            #pragma omp parallel for private (i0, i1)                   mesh_p->ContactElements->Color[i0] = i0;
473        for (i0=0; i0<chunkEle; i0++) {                   for (i1 = 0; i1 < numNodes; i1++) {
474          mesh_p->Points->Id[i0]  = tempInts[i0*(2+numNodes)+0];                       mesh_p->ContactElements->Nodes[INDEX2(i1, i0, numNodes)] = tempInts[i0*(2+numNodes)+2+i1];
475          mesh_p->Points->Tag[i0] = tempInts[i0*(2+numNodes)+1];                   }
476              mesh_p->Points->Owner[i0]  =mpi_info->rank;               }
477              mesh_p->Points->Color[i0] = i0;          }
478          for (i1 = 0; i1 < numNodes; i1++) {          TMPMEMFREE(tempInts);
479            mesh_p->Points->Nodes[INDEX2(i1, i0, numNodes)] = tempInts[i0*(2+numNodes)+2+i1];      } /* end of Read the contact element data */
480          }  
481            }      /* ********************************* read nodal elements ****************************************************** */
482          }  
483        /* *******************************  Read the element typeID */
484    
485        if (Finley_noError()) {
486            if (mpi_info->rank == 0) {
487                scan_ret = fscanf(fileHandle_p, "%s %d\n", element_type, &numEle);
488                FSCANF_CHECK(scan_ret, "Finley_Mesh_read")
489                typeID=Finley_ReferenceElement_getTypeId(element_type);
490            }
491            #ifdef PASO_MPI
492                if (mpi_info->size > 1) {
493                    int temp1[2];
494                    temp1[0] = (int) typeID;
495                    temp1[1] = numEle;
496                    MPI_Bcast (temp1, 2, MPI_INT,  0, mpi_info->comm);
497                    typeID = (ElementTypeId) temp1[0];
498                    numEle = temp1[1];
499                }
500            #endif
501            if (typeID==NoRef) {
502                sprintf(error_msg, "Finley_Mesh_read: Unidentified element type %s", element_type);
503                Finley_setError(VALUE_ERROR, error_msg);
504             }
505        }
506    
507      TMPMEMFREE(tempInts);      if (Finley_noError()) {
508        } /* end of Read the nodal element data */          /* Allocate the ElementFile */
509            refPoints= Finley_ReferenceElementSet_alloc(typeID,order, reduced_order);
510            mesh_p->Points=Finley_ElementFile_alloc(refPoints, mpi_info);
511            numNodes = mesh_p->Points->referenceElementSet->numNodes; /* New meaning for numNodes: num nodes per element */
512        }
513    
514        /* get the name tags */      /**********************************  Read the nodal element data **************************************************/
515        if (Finley_noError()) {      if (Finley_noError()) {
516            int chunkSize = numEle / mpi_info->size + 1, totalEle=0, nextCPU=1, chunkEle=0;
517            int *tempInts = TMPMEMALLOC(chunkSize*(2+numNodes)+1, index_t); /* Store Id + Tag + node list (+ one int at end for chunkEle) */
518            /* Elements are specified as a list of integers...only need one message instead of two as with the nodes */
519            if (mpi_info->rank == 0) {  /* Master */
520                for (;;) {            /* Infinite loop */
521                    #pragma omp parallel for private (i0) schedule(static)
522                    for (i0=0; i0<chunkSize*(2+numNodes)+1; i0++) tempInts[i0] = -1;
523            
524                    chunkEle = 0;
525                    for (i0=0; i0<chunkSize; i0++) {
526                        if (totalEle >= numEle) break; /* End inner loop */
527                        scan_ret = fscanf(fileHandle_p, "%d %d", &tempInts[i0*(2+numNodes)+0], &tempInts[i0*(2+numNodes)+1]);
528                        FSCANF_CHECK(scan_ret, "Finley_Mesh_read")
529                        for (i1 = 0; i1 < numNodes; i1++) {
530                            scan_ret = fscanf(fileHandle_p, " %d", &tempInts[i0*(2+numNodes)+2+i1]);
531                            FSCANF_CHECK(scan_ret, "Finley_Mesh_read")
532                        }
533                        scan_ret = fscanf(fileHandle_p, "\n");
534                        FSCANF_CHECK(scan_ret, "Finley_Mesh_read")
535                        totalEle++;
536                        chunkEle++;
537                    }
538                    #ifdef PASO_MPI
539                        /* Eventually we'll send chunk of elements to each CPU except 0 itself, here goes one of them */
540                        if (nextCPU < mpi_info->size) {
541                            tempInts[chunkSize*(2+numNodes)] = chunkEle;
542                            MPI_Send(tempInts, chunkSize*(2+numNodes)+1, MPI_INT, nextCPU, 81725, mpi_info->comm);
543                        }
544                    #endif
545                    nextCPU++;
546                    /* Infinite loop ends when I've read a chunk for each of the worker nodes plus one more chunk for the master */
547                    if (nextCPU > mpi_info->size) break; /* End infinite loop */
548                } /* Infinite loop */
549            }   /* End master */
550            else {  /* Worker */
551                #ifdef PASO_MPI
552                    /* Each worker receives one message */
553                    MPI_Status status;
554                    MPI_Recv(tempInts, chunkSize*(2+numNodes)+1, MPI_INT, 0, 81725, mpi_info->comm, &status);
555                    chunkEle = tempInts[chunkSize*(2+numNodes)];
556                #endif
557            }   /* Worker */
558    
559            /* Copy Element data from tempInts to mesh_p */
560            Finley_ElementFile_allocTable(mesh_p->Points, chunkEle);
561            
562            if (Finley_noError()) {
563                mesh_p->Points->minColor=0;
564                mesh_p->Points->maxColor=chunkEle-1;
565                #pragma omp parallel for private (i0, i1) schedule(static)
566                for (i0=0; i0<chunkEle; i0++) {
567                    mesh_p->Points->Id[i0]  = tempInts[i0*(2+numNodes)+0];
568                    mesh_p->Points->Tag[i0] = tempInts[i0*(2+numNodes)+1];
569                    mesh_p->Points->Owner[i0]  =mpi_info->rank;
570                    mesh_p->Points->Color[i0] = i0;
571                    for (i1 = 0; i1 < numNodes; i1++) {
572                        mesh_p->Points->Nodes[INDEX2(i1, i0, numNodes)] = tempInts[i0*(2+numNodes)+2+i1];
573                    }
574                }
575            }
576    
577            TMPMEMFREE(tempInts);
578        } /* ******************************** end of Read the nodal element data ************************************************************* */
579    
580        
581        /******************  get the name tags *****************************************/
582        if (Finley_noError()) {
583          char *remainder=0, *ptr;          char *remainder=0, *ptr;
584          size_t len;          size_t len=0;
585            #ifdef PASO_MPI
586                int len_i;
587            #endif
588          int tag_key;          int tag_key;
589            if (mpi_info->rank == 0) {  /* Master */
590                /* Read the word 'Tag' */
591                if (! feof(fileHandle_p)) {
592          if (mpi_info->rank == 0) {  /* Master */                  scan_ret = fscanf(fileHandle_p, "%s\n", name);
593        /* Read the word 'Tag' */                  FSCANF_CHECK(scan_ret, "Finley_Mesh_read")
594        if (! feof(fileHandle_p)) {              }
595          scan_ret = fscanf(fileHandle_p, "%s\n", name);  
596          FSCANF_CHECK(scan_ret, "Finley_Mesh_read")              #if defined(_WIN32)  /* windows ftell lies on unix formatted text files */
597        }                  remainder = NULL;
598                    len=0;
599  #if defined(_WIN32)  /* windows ftell lies on unix formatted text files */                  while (1)
600                    {
601        remainder = NULL;                      size_t malloc_chunk = 1024;
602            len=0;                      size_t buff_size = 0;
603        while (1)                      int ch;
604            {  
605               size_t malloc_chunk = 1024;                      ch = fgetc(fileHandle_p);
606               size_t buff_size = 0;                      if( ch == '\r' )
607               int ch;                      {
608                            continue;
609               ch = fgetc(fileHandle_p);                      }
610               if( ch == '\r' )                      if( len+1 > buff_size )
611               {                      {
612                  continue;                          TMPMEMREALLOC(remainder,remainder,buff_size+malloc_chunk,char);
613               }                      }
614               if( len+1 > buff_size )                      if( ch == EOF )
615               {                      {
616                  TMPMEMREALLOC(remainder,remainder,buff_size+malloc_chunk,char);                          /* hit EOF */
617               }                          remainder[len] = (char)0;
618               if( ch == EOF )                          break;
619               {                      }
620                  /* hit EOF */                      remainder[len] = (char)ch;
621                  remainder[len] = (char)0;                      len++;
622                  break;                  }
623               }              #else
624               remainder[len] = (char)ch;                  /* Read rest of file in one chunk, after using seek to find length */
625               len++;                  {
626            }                      long cur_pos, end_pos;
627  #else  
628        /* Read rest of file in one chunk, after using seek to find length */                      cur_pos = ftell(fileHandle_p);
629            {                      fseek(fileHandle_p, 0L, SEEK_END);
630               long cur_pos, end_pos;                      end_pos = ftell(fileHandle_p);
631                        fseek(fileHandle_p, (long)cur_pos, SEEK_SET);
632               cur_pos = ftell(fileHandle_p);                      remainder = TMPMEMALLOC(end_pos-cur_pos+1, char);
633               fseek(fileHandle_p, 0L, SEEK_END);                      if (! feof(fileHandle_p))
634               end_pos = ftell(fileHandle_p);                      {
635               fseek(fileHandle_p, (long)cur_pos, SEEK_SET);                          scan_ret = fread(remainder, (size_t) end_pos-cur_pos,
636               remainder = TMPMEMALLOC(end_pos-cur_pos+1, char);                                               sizeof(char), fileHandle_p);
637               if (! feof(fileHandle_p))  
638               {                          FSCANF_CHECK(scan_ret, "Finley_Mesh_read")
639                  scan_ret = fread(remainder, (size_t) end_pos-cur_pos,                          remainder[end_pos-cur_pos] = 0;
640                                   sizeof(char), fileHandle_p);                      }
641                    }
642                  FSCANF_CHECK(scan_ret, "Finley_Mesh_read")              #endif
643                  remainder[end_pos-cur_pos] = 0;              len = strlen(remainder);
644              }              while ((len>1) && isspace(remainder[--len])) {remainder[len]=0;}
645            }              len = strlen(remainder);
646  #endif              TMPMEMREALLOC(remainder,remainder,len+1,char);
647        len = strlen(remainder);          } /* Master */
648        while ((--len)>0 && isspace(remainder[len])) remainder[len]=0;          #ifdef PASO_MPI
649        len = strlen(remainder);  
650            TMPMEMREALLOC(remainder,remainder,len+1,char);              len_i=(int) len;
651          }              MPI_Bcast (&len_i, 1, MPI_INT,  0, mpi_info->comm);
652  #ifdef PASO_MPI              len=(size_t) len_i;
653                if (mpi_info->rank != 0) {
654          if (MPI_Bcast (&len, 1, MPI_INT,  0, mpi_info->comm) != MPI_SUCCESS)                  remainder = TMPMEMALLOC(len+1, char);
655          {                  remainder[0] = 0;
656             Finley_setError(PASO_MPI_ERROR,              }
657                             "Finley_Mesh_read: broadcast of tag len failed");              if (MPI_Bcast (remainder, len+1, MPI_CHAR,  0, mpi_info->comm) !=
658             return NULL;                      MPI_SUCCESS)
659          }                  Finley_setError(PASO_MPI_ERROR, "Finley_Mesh_read: broadcast of remainder failed");
660      if (mpi_info->rank != 0) {          #endif
661        remainder = TMPMEMALLOC(len+1, char);  
662        remainder[0] = 0;          if (remainder[0]) {
663                ptr = remainder;
664                do {
665                    sscanf(ptr, "%s %d\n", name, &tag_key);
666                    if (*name) Finley_Mesh_addTagMap(mesh_p,name,tag_key);
667                    ptr++;
668                } while(NULL != (ptr = strchr(ptr, '\n')) && *ptr);
669            }
670            if (remainder)
671                TMPMEMFREE(remainder);
672      }      }
673    
674          if (MPI_Bcast (remainder, len+1, MPI_CHAR,  0, mpi_info->comm) !=      /* close file */
675              MPI_SUCCESS)      if (mpi_info->rank == 0) fclose(fileHandle_p);
         {  
            Finley_setError(PASO_MPI_ERROR,  
                            "Finley_Mesh_read: broadcast of tags failed");  
            return NULL;  
         }  
 #endif  
     if (remainder[0]) {  
           ptr = remainder;  
           do {  
             sscanf(ptr, "%s %d\n", name, &tag_key);  
             if (*name) Finley_Mesh_addTagMap(mesh_p,name,tag_key);  
             ptr++;  
           } while(NULL != (ptr = strchr(ptr, '\n')) && *ptr);  
           TMPMEMFREE(remainder);  
     }  
       }  
676    
677       }      /*   resolve id's : */
678        /* rearrange elements: */
679       /* close file */      if (Finley_noError()) Finley_Mesh_resolveNodeIds(mesh_p);
680       if (mpi_info->rank == 0) fclose(fileHandle_p);      if (Finley_noError()) Finley_Mesh_prepare(mesh_p, optimize);
681    
682       /*   resolve id's : */      /* that's it */
683       /* rearrange elements: */      if (! Finley_noError()) {
684            Finley_Mesh_free(mesh_p);
685       if (Finley_noError()) Finley_Mesh_resolveNodeIds(mesh_p);      }
686       if (Finley_noError()) Finley_Mesh_prepare(mesh_p, optimize);      /* free up memory */
687        Finley_ReferenceElementSet_dealloc(refPoints);
688       /* that's it */      Finley_ReferenceElementSet_dealloc(refContactElements);
689       #ifdef Finley_TRACE      Finley_ReferenceElementSet_dealloc(refFaceElements);
690       printf("timing: reading mesh: %.4e sec\n",Finley_timer()-time0);      Finley_ReferenceElementSet_dealloc(refElements);
691       #endif      Paso_MPIInfo_free( mpi_info );
692        return mesh_p;
   /* that's it */  
   if (! Finley_noError()) {  
        Finley_Mesh_free(mesh_p);  
   }  
   Paso_MPIInfo_free( mpi_info );  
   return mesh_p;  
693  }  }
694    

Legend:
Removed from v.2059  
changed lines
  Added in v.2856

  ViewVC Help
Powered by ViewVC 1.1.26