1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
 void
 GetAddDelSequence(
    const char *inFileName,      /* [IN] name of input file or NULL if no input file specified */
    int *numDims,                /* [OUT] the number of spatial and topological dimensions of the mesh */
    int *numSteps,               /* [OUT] the number of addition/deletion steps */
    int **theOps,                /* [OUT] array of length numSteps indicating the operation (add=+1,delete=-1) */
    ElemSlab_t **theSlabs        /* [OUT] array of element slabs, one for each step */
 )
 {
    int rank = 0;

 #ifdef HAVE_PARALLEL
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
 #endif

    /* only processor 0 reads the file */
    if (rank == 0)
    {
       if (inFileName[0] == '\0')
       {
          int n = 0;

          /* generate and return the default data */
          *numDims = 2;
          *numSteps = 4;
          *theSlabs = (ElemSlab_t *) malloc((*numSteps) * sizeof(ElemSlab_t));
          *theOps = (int *) malloc((*numSteps) * sizeof(int));

          /* first step (add) */
          (*theOps)[n] = 1; (*theSlabs)[n].idx[0] = 2; (*theSlabs)[n].idx[1] = 3; n += 1;

          /* second step (add) */
          (*theOps)[n] = 1; (*theSlabs)[n].idx[0] = 2; (*theSlabs)[n].idx[1] = 0; n += 1;

          /* third step (delete) */
          (*theOps)[n] = -1; (*theSlabs)[n].idx[0] = 0; (*theSlabs)[n].idx[1] = -1; n += 1;

          /* fourth step (delete) */
          (*theOps)[n] = -1; (*theSlabs)[n].idx[0] = -1; (*theSlabs)[n].idx[1] = 0; n += 1;

       }
       else
       {
          int count;
          char line[128];
          const char *fmtStr[3] = {"step %c %c%d\n","step %c %c%d, %c%d\n","step %c %c%d, %c%d, %c%d\n"};
          FILE *f;

          /* open and read the input file */
          if ((f = fopen(inFileName, "r")) == NULL)
             AbortThisMess("unable to open input file");

          /* get the number of dimensions */
          if (fscanf(f,"ndims=%d\n", numDims) != 1)
             AbortThisMess("cannot read \"ndims\" line");

          if (*numDims < 1 || *numDims > 3)
             AbortThisMess("ndims out of range [1,3]");

          /* count number of "step" lines */
          count = 0;
          while (fgets(line, sizeof(line), f) != NULL)
             count++;
          *numSteps = count;

          if (*numSteps < 1)
             AbortThisMess("must have at least one step in the birth/death sequence");

          /* allocate the steps output array */
          *theOps = (int *) malloc(count * sizeof(int));
          *theSlabs = (ElemSlab_t *) calloc((size_t)count,sizeof(ElemSlab_t));

          /* rewind back to beginning and skip past first line */
          rewind(f);
          fgets(line, sizeof(line), f);

          /* now, read the step lines into the steps array */
          {
             char op, s1, s2, s3; int n1, n2, n3;
             int reCount = 0;
             int *thisOp = *theOps;
             ElemSlab_t *thisSlab = *theSlabs;

             switch (*numDims)
             {
                case 1:
                   while (fscanf(f, fmtStr[0], &op, &s1, &n1) == 3)
                   {
                      *thisOp++ = (op == '+' ? 1 : -1);
                      (*thisSlab++).idx[0] = (s1 == '+' ? n1 : -n1);
                      reCount++;
                   }
                   break;
                case 2:
                   while (fscanf(f, fmtStr[1], &op, &s1, &n1, &s2, &n2) == 5)
                   {
                      *thisOp++ = (op == '+' ? 1 : -1);
                      (*thisSlab  ).idx[0] = (s1 == '+' ? n1 : -n1);
                      (*thisSlab++).idx[1] = (s2 == '+' ? n2 : -n2);
                      reCount++;
                   }
                   break;
                case 3:
                   while (fscanf(f, fmtStr[2], &op, &s1, &n1, &s2, &n2, &s3, &n3) == 7)
                   {
                      *thisOp++ = (op == '+' ? 1 : -1);
                      (*thisSlab  ).idx[0] = (s1 == '+' ? n1 : -n1);
                      (*thisSlab  ).idx[1] = (s2 == '+' ? n2 : -n2);
                      (*thisSlab++).idx[2] = (s3 == '+' ? n3 : -n3);
                      reCount++;
                   }
                   break;
                default:
                   break;
             }

             if (reCount != count)
             {
                char tmpMsg[1024];
                sprintf(tmpMsg, "input file error, perhaps on line %d", reCount+1);
                AbortThisMess(tmpMsg);
             }
          }

          /* close the file */
          fclose(f);

       }
    }

 #ifdef HAVE_PARALLEL
    MPI_Bcast(numDims, 1, MPI_INT, 0, MPI_COMM_WORLD);
    MPI_Bcast(numSteps, 1, MPI_INT, 0, MPI_COMM_WORLD);
    if (rank != 0)
    {
       *theOps = (int *) malloc(*numSteps * sizeof(int));
       *theSlabs = (ElemSlab_t *) malloc(*numSteps * sizeof(ElemSlab_t));
    }
    MPI_Bcast(*theOps, *numSteps, MPI_INT, 0, MPI_COMM_WORLD);
    MPI_Bcast(*theSlabs, *numSteps * MAX_DIMS, MPI_INT, 0, MPI_COMM_WORLD);
 #endif

 }