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