1 #include <stdio.h>
2 #include <stdlib.h>
3 
4 #include "pcgnslib.h"
5 #include "mpi.h"
6 
7 #define NODES_PER_SIDE 5
8 
9 #ifdef DEBUG_MPI
10 # define DEBUG_PRINT(A) printf A;fflush(stdout);
11 #else
12 # define DEBUG_PRINT(A)
13 #endif
14 
main(int argc,char * argv[])15 int main(int argc, char *argv[])
16 {
17     int comm_size, comm_rank;
18     int tot_nnodes, tot_nelems, nnodes, nelems;
19     int F, B, Z, E, S, Fs, A, Cx, Cy, Cz;
20     int i, j, k, n, nn, ne;
21     float *x, *y, *z, *d;
22     cgsize_t sizes[3], *e, start, end, ncells;
23     static char *outfile = "cexample.cgns";
24 
25     /* initialize MPI */
26     MPI_Init(&argc,&argv);
27     MPI_Comm_size(MPI_COMM_WORLD, &comm_size);
28     MPI_Comm_rank(MPI_COMM_WORLD, &comm_rank);
29 
30     /* total number of nodes and hex elements */
31     tot_nnodes = NODES_PER_SIDE * NODES_PER_SIDE * NODES_PER_SIDE;
32     tot_nelems = (NODES_PER_SIDE-1) * (NODES_PER_SIDE-1) * (NODES_PER_SIDE-1);
33 
34     /* open the file and create base and zone */
35     sizes[0] = tot_nnodes;
36     sizes[1] = tot_nelems;
37     sizes[2] = 0;
38 
39     /* print info */
40     if (comm_rank == 0) {
41         printf("writing %d coordinates and %d hex elements to %s\n",
42             tot_nnodes, tot_nelems, outfile);
43 #ifdef DEBUG_MPI
44         fflush(stdout);
45 #endif
46     }
47 
48     DEBUG_PRINT(("[%d]cgp_open\n",comm_rank))
49     if (cgp_open(outfile, CG_MODE_WRITE, &F)) cgp_error_exit();
50     DEBUG_PRINT(("[%d]cg_base_write\n",comm_rank))
51     if (cg_base_write(F, "Base", 3, 3, &B)) cgp_error_exit();
52     DEBUG_PRINT(("[%d]cg_zone_write\n",comm_rank))
53     if (cg_zone_write(F, B, "Zone", sizes, CGNS_ENUMV(Unstructured), &Z))
54         cgp_error_exit();
55 
56     /* create data nodes for coordinates */
57     DEBUG_PRINT(("[%d]cgp_coord_write\n",comm_rank))
58     if (cgp_coord_write(F, B, Z, CGNS_ENUMV(RealSingle), "CoordinateX", &Cx) ||
59         cgp_coord_write(F, B, Z, CGNS_ENUMV(RealSingle), "CoordinateY", &Cy) ||
60         cgp_coord_write(F, B, Z, CGNS_ENUMV(RealSingle), "CoordinateZ", &Cz))
61         cgp_error_exit();
62 
63     /* number of nodes and range this process will write */
64     nnodes = (tot_nnodes + comm_size - 1) / comm_size;
65     start  = nnodes * comm_rank + 1;
66     end    = nnodes * (comm_rank + 1);
67     if (end > tot_nnodes) end = tot_nnodes;
68 
69     /* create the coordinate data for this process */
70     x = (float *)malloc(nnodes * sizeof(float));
71     y = (float *)malloc(nnodes * sizeof(float));
72     z = (float *)malloc(nnodes * sizeof(float));
73     nn = 0;
74     for (n = 1, k = 0; k < NODES_PER_SIDE; k++) {
75         for (j = 0; j < NODES_PER_SIDE; j++) {
76             for (i = 0; i < NODES_PER_SIDE; i++, n++) {
77                 if (n >= start && n <= end) {
78                     x[nn] = (float)i;
79                     y[nn] = (float)j;
80                     z[nn] = (float)k;
81                     nn++;
82                 }
83             }
84         }
85     }
86 
87     DEBUG_PRINT(("[%d]cgp_coord_write_data\n",comm_rank))
88     if (cgp_coord_write_data(F, B, Z, Cx, &start, &end, x) ||
89         cgp_coord_write_data(F, B, Z, Cy, &start, &end, y) ||
90         cgp_coord_write_data(F, B, Z, Cz, &start, &end, z))
91         cgp_error_exit();
92 
93     /* create data node for elements */
94     DEBUG_PRINT(("[%d]cgp_section_write\n",comm_rank))
95     if (cgp_section_write(F, B, Z, "Hex", CGNS_ENUMV(HEXA_8), 1, tot_nelems, 0, &E))
96         cgp_error_exit();
97 
98     /* number of elements and range this process will write */
99     nelems = (tot_nelems + comm_size - 1) / comm_size;
100     start  = nelems * comm_rank + 1;
101     end    = nelems * (comm_rank + 1);
102     if (end > tot_nelems) end = tot_nelems;
103 
104     /* create the hex element data for this process */
105     e = (cgsize_t *)malloc(8 * nelems * sizeof(cgsize_t));
106     nn = 0;
107     for (n = 1, k = 1; k < NODES_PER_SIDE; k++) {
108         for (j = 1; j < NODES_PER_SIDE; j++) {
109             for (i = 1; i < NODES_PER_SIDE; i++, n++) {
110                 if (n >= start && n <= end) {
111                     ne = i + NODES_PER_SIDE*((j-1)+NODES_PER_SIDE*(k-1));
112                     e[nn++] = ne;
113                     e[nn++] = ne + 1;
114                     e[nn++] = ne + 1 + NODES_PER_SIDE;
115                     e[nn++] = ne + NODES_PER_SIDE;
116                     ne += NODES_PER_SIDE * NODES_PER_SIDE;
117                     e[nn++] = ne;
118                     e[nn++] = ne + 1;
119                     e[nn++] = ne + 1 + NODES_PER_SIDE;
120                     e[nn++] = ne + NODES_PER_SIDE;
121                 }
122             }
123         }
124     }
125 
126     /* write the element connectivity in parallel */
127     DEBUG_PRINT(("[%d]cgp_elements_write_data\n",comm_rank))
128     if (cgp_elements_write_data(F, B, Z, E, start, end, e))
129         cgp_error_exit();
130 
131     /* create a centered solution */
132     DEBUG_PRINT(("[%d]cg_sol_write\n",comm_rank))
133     if (cg_sol_write(F, B, Z, "Solution", CGNS_ENUMV(CellCenter), &S))
134         cgp_error_exit();
135     DEBUG_PRINT(("[%d]cgp_field_write\n",comm_rank))
136     if (cgp_field_write(F, B, Z, S, CGNS_ENUMV(RealSingle), "CellIndex", &Fs))
137         cgp_error_exit();
138 
139     /* create the field data for this process */
140     d = (float *)malloc(nelems * sizeof(float));
141     nn = 0;
142     for (n = 1; n <= tot_nelems; n++) {
143         if (n >= start && n <= end) {
144             d[nn] = (float)n;
145             nn++;
146         }
147     }
148 
149     /* write the solution field data in parallel */
150     DEBUG_PRINT(("[%d]cgp_field_write_data\n",comm_rank))
151     if (cgp_field_write_data(F, B, Z, S, Fs, &start, &end, d))
152         cgp_error_exit();
153 
154     /* create user data under the zone and duplicate solution data */
155     ncells = tot_nelems;
156     DEBUG_PRINT(("[%d]cg_goto\n",comm_rank))
157     if (cg_goto(F, B, "Zone_t", 1, NULL)) cgp_error_exit();
158     DEBUG_PRINT(("[%d]cg_user_data_write\n",comm_rank))
159     if (cg_user_data_write("User Data")) cgp_error_exit();
160     DEBUG_PRINT(("[%d]cg_gorel\n",comm_rank))
161     if (cg_gorel(F, "User Data", 0, NULL)) cgp_error_exit();
162     DEBUG_PRINT(("[%d]cgp_array_write\n",comm_rank))
163     if (cgp_array_write("CellIndex", CGNS_ENUMV(RealSingle), 1, &ncells, &A))
164         cgp_error_exit();
165 
166     /* write the array data in parallel */
167     DEBUG_PRINT(("[%d]cgp_array_write_data\n",comm_rank))
168     if (cgp_array_write_data(A, &start, &end, d))
169         cgp_error_exit();
170 
171     /* close the file and terminate MPI */
172     DEBUG_PRINT(("[%d]cgp_close\n",comm_rank))
173     cgp_close(F);
174     MPI_Finalize();
175     return 0;
176 }
177 
178