1 /*
2  * Program to make hex modification operation meshes
3  *
4  */
5 
6 #include "moab/Core.hpp"
7 #include "moab/Range.hpp"
8 #include <iostream>
9 
10 using namespace moab;
11 
12 Interface *gMB = NULL;
13 
14 static ErrorCode make_atomic_pillow();
15 static ErrorCode make_face_shrink();
16 static ErrorCode make_face_open_collapse();
17 static ErrorCode make_chord_push();
18 static ErrorCode make_triple_chord_push();
19 static ErrorCode make_triple_hex_push();
20 
21 enum OperationType {ATOMIC_PILLOW = 0,
22                     FACE_OPEN_COLLAPSE,
23                     FACE_SHRINK,
24                     CHORD_PUSH,
25                     MBTRIPLE_CHORD_PUSH,
26                     MBTRIPLE_HEX_PUSH,
27                     UNDEFINED};
28 
29 const char *OperationNames[] = {"atomic_pillow",
30                                 "face_open_collapse",
31                                 "face_shrink",
32                                 "chord_push",
33                                 "triple_chord_push",
34                                 "triple_hex_push",
35                                 "undefined"};
36 
main(int argc,char ** argv)37 int main(int argc, char **argv)
38 {
39   gMB = new Core();
40   const char *extensions[] =
41     {
42       ".g",
43       ".h5m",
44       ".vtk"
45     };
46   int file_exten = 1;
47 
48   std::vector<OperationType> op_types;
49 
50   if (argc < 2) {
51     std::cout << "Usage: " << argv[0]
52               << " [-h5m] [-vtk] {-ap | -foc | -fs | -cp | -tcp | -thp}"
53               << std::endl;
54     return 1;
55   }
56 
57   int current_arg = 1;
58   while (current_arg < argc) {
59     if (!strcmp("-g", argv[current_arg])) file_exten = 0;
60     else if (!strcmp("-h5m", argv[current_arg])) file_exten = 1;
61     else if (!strcmp("-vtk", argv[current_arg])) file_exten = 2;
62     else if (!strcmp("-ap", argv[current_arg]))
63       op_types.push_back(ATOMIC_PILLOW);
64     else if (!strcmp("-foc", argv[current_arg]))
65       op_types.push_back(FACE_OPEN_COLLAPSE);
66     else if (!strcmp("-fs", argv[current_arg]))
67       op_types.push_back(FACE_SHRINK);
68     else if (!strcmp("-cp", argv[current_arg]))
69       op_types.push_back(CHORD_PUSH);
70     else if (!strcmp("-tcp", argv[current_arg]))
71       op_types.push_back(MBTRIPLE_CHORD_PUSH);
72     else if (!strcmp("-thp", argv[current_arg]))
73       op_types.push_back(MBTRIPLE_HEX_PUSH);
74     current_arg++;
75   }
76 
77   ErrorCode result = MB_SUCCESS, tmp_result = MB_FAILURE;
78 
79   for (std::vector<OperationType>::iterator vit = op_types.begin();
80        vit != op_types.end(); ++vit) {
81     if (*vit == ATOMIC_PILLOW) {
82       tmp_result = make_atomic_pillow();
83     }
84     else if (*vit == FACE_OPEN_COLLAPSE) {
85       tmp_result = make_face_open_collapse();
86     }
87     else if (*vit == CHORD_PUSH) {
88       tmp_result = make_chord_push();
89     }
90     else if (*vit == MBTRIPLE_CHORD_PUSH) {
91       tmp_result = make_triple_chord_push();
92     }
93 
94     else if (*vit == MBTRIPLE_HEX_PUSH) {
95       tmp_result = make_triple_hex_push();
96     }
97     else if (*vit == FACE_SHRINK) {
98       tmp_result = make_face_shrink();
99     }
100     else {
101       std::cout << "Operation undefined." << std::endl;
102       return 1;
103     }
104     if (MB_SUCCESS != tmp_result) result = tmp_result;
105 
106     // now write to a file
107     std::string filename(OperationNames[*vit]);
108     filename.append(extensions[file_exten]);
109     tmp_result = gMB->write_mesh(filename.c_str());
110     if (MB_SUCCESS != tmp_result) result = tmp_result;
111   }
112 
113   return (result == MB_SUCCESS ? 0 : 1);
114 }
115 
make_atomic_pillow()116 ErrorCode make_atomic_pillow()
117 {
118     // make atomic pillow configuration
119     // make all vertices
120   double vtx_coord[] =
121     {
122       1.0, 1.0, 1.0,
123       1.0, 0.0, 1.0,
124       0.0, 0.0, 1.0,
125       0.0, 1.0, 1.0,
126       .75, .75, 1.0,
127       .75, .25, 1.0,
128       .25, .25, 1.0,
129       .25, .75, 1.0
130     };
131 
132   int connect[] = {
133     0, 1, 2, 3, 4, 5, 6, 7,
134     4, 5, 6, 7, 0, 1, 2, 3
135   };
136 
137   ErrorCode result;
138   EntityHandle vtx_handles[8];
139 
140   for (int i = 0; i < 8; i++) {
141     result = gMB->create_vertex(&vtx_coord[3*i], vtx_handles[i]);
142     if (MB_SUCCESS != result) return MB_FAILURE;
143   }
144 
145   EntityHandle conn[8], elems[4];
146 
147     // make the two hexes
148   for (int i = 0; i < 8; i++)
149     conn[i] = vtx_handles[connect[i]];
150   result = gMB->create_element(MBHEX, conn, 8, elems[0]);
151   if (MB_SUCCESS != result) return MB_FAILURE;
152 
153   for (int i = 0; i < 8; i++)
154     conn[i] = vtx_handles[connect[8+i]];
155   result = gMB->create_element(MBHEX, conn, 8, elems[1]);
156   if (MB_SUCCESS != result) return MB_FAILURE;
157 
158     // make one of the end quads explicitly and bind to the first hex
159   for (int i = 0; i < 4; i++)
160     conn[i] = vtx_handles[connect[i]];
161   result = gMB->create_element(MBQUAD, conn, 4, elems[2]);
162   if (MB_SUCCESS != result) return MB_FAILURE;
163 
164   result = gMB->add_adjacencies(elems[2], elems, 1, false);
165   if (MB_SUCCESS != result) return MB_FAILURE;
166 
167     // now the other one
168   result = gMB->create_element(MBQUAD, conn, 4, elems[3]);
169   if (MB_SUCCESS != result) return MB_FAILURE;
170 
171   result = gMB->add_adjacencies(elems[3], &elems[1], 1, false);
172   if (MB_SUCCESS != result) return MB_FAILURE;
173 
174   return MB_SUCCESS;
175 }
176 
make_face_shrink()177 ErrorCode make_face_shrink()
178 {
179     // make face shrink configuration
180     // make all vertices
181   double vtx_coord[] =
182     {
183       1.0, 1.0, 0.0,
184       1.0, 0.0, 0.0,
185       0.0, 0.0, 0.0,
186       0.0, 1.0, 0.0,
187       1.0, 1.0, 1.0,
188       1.0, 0.0, 1.0,
189       0.0, 0.0, 1.0,
190       0.0, 1.0, 1.0,
191       1.0, 1.0, 2.0,
192       1.0, 0.0, 2.0,
193       0.0, 0.0, 2.0,
194       0.0, 1.0, 2.0,
195       .75, .75, 1.0,
196       .75, .25, 1.0,
197       .25, .25, 1.0,
198       .25, .75, 1.0
199     };
200 
201   int connect[] = {
202     3, 7, 11, 15, 0, 4, 8, 12,
203     0, 4, 8, 12, 1, 5, 9, 13,
204     1, 5, 9, 13, 2, 6, 10, 14,
205     2, 6, 10, 14, 3, 7, 11, 15,
206     0, 3, 2, 1, 12, 15, 14, 13,
207     12, 15, 14, 13, 8, 11, 10, 9
208   };
209 
210   ErrorCode result;
211   EntityHandle vtx_handles[16];
212 
213   for (int i = 0; i < 16; i++) {
214     result = gMB->create_vertex(&vtx_coord[3*i], vtx_handles[i]);
215     if (MB_SUCCESS != result) return MB_FAILURE;
216   }
217 
218     // make all elements at once
219   EntityHandle conn[8], elems[6];
220 
221   for (int j = 0; j < 6; j++) {
222     for (int i = 0; i < 8; i++)
223       conn[i] = vtx_handles[connect[j*8+i]];
224 
225     result = gMB->create_element(MBHEX, conn, 8, elems[j]);
226     if (MB_SUCCESS != result) return MB_FAILURE;
227   }
228 
229   return MB_SUCCESS;
230 }
231 
make_face_open_collapse()232 ErrorCode make_face_open_collapse()
233 {
234   return MB_FAILURE;
235 }
236 
make_chord_push()237 ErrorCode make_chord_push()
238 {
239     // make chord push configuration
240     // make all vertices
241   double vtx_coord[] =
242     {
243         // first layer
244       0.0, 0.0, 0.5,
245       0.0, 1.0, 0.0,
246       -1.0, 0.5, 0.0,
247       -1.0, -0.5, 0.0,
248       0.0, -1.0, 0.0,
249       1.0, -0.5, 0.0,
250       1.0, 0.5, 0.0,
251         // second layer
252       0.0, 0.0, -1.5,
253       0.0, 1.0, -1.0,
254       -1.0, 0.5, -1.0,
255       -1.0, -0.5, -1.0,
256       0.0, -1.0, -1.0,
257       1.0, -0.5, -1.0,
258       1.0, 0.5, -1.0,
259         // 2 extra vertices for chord push
260       0.0, -.333, 0.05,
261       0.0, -.667, 0.10
262     };
263 
264   int connect[] = {
265       // 3 "normal" hexes first
266       // top hex
267     0, 2, 1, 6, 7, 9, 8, 13,
268       // bottom left
269     0, 4, 3, 2, 7, 11, 10, 9,
270       // bottom right
271     6, 5, 4, 0, 13, 12, 11, 7,
272       // front chord push hex
273     2, 0, 4, 3, 14, 6, 5, 15,
274       // back chord push hex
275     2, 14, 15, 3, 0, 6, 5, 4,
276       // front/rear quads a, b
277     2, 0, 4, 3, 6, 5, 4, 0,
278       // duplicate edges from chord push
279     0, 4,
280       // face between bottom 2 normal hexes (needed for explicit
281       // adjacency)
282     0, 4, 11, 7
283   };
284 
285   ErrorCode result;
286   EntityHandle vtx_handles[16];
287 
288   for (int i = 0; i < 16; i++) {
289     result = gMB->create_vertex(&vtx_coord[3*i], vtx_handles[i]);
290     if (MB_SUCCESS != result) return MB_FAILURE;
291   }
292 
293   EntityHandle conn[8], elems[12];
294 
295     // make the five hexes
296   for (int i = 0; i < 5; i++) {
297     for (int j = 0; j < 8; j++)
298       conn[j] = vtx_handles[connect[8*i+j]];
299     result = gMB->create_element(MBHEX, conn, 8, elems[i]);
300     if (MB_SUCCESS != result) return MB_FAILURE;
301   }
302 
303     // make the frontmost pair of quads and bind to the front degen hex
304   for (int i = 0; i < 2; i++) {
305     for (int j = 0; j < 4; j++)
306       conn[j] = vtx_handles[connect[40+4*i+j]];
307     result = gMB->create_element(MBQUAD, conn, 4, elems[5+i]);
308     if (MB_SUCCESS != result) return MB_FAILURE;
309   }
310 
311     // now the back pair
312   for (int i = 0; i < 2; i++) {
313     for (int j = 0; j < 4; j++)
314       conn[j] = vtx_handles[connect[40+4*i+j]];
315     result = gMB->create_element(MBQUAD, conn, 4, elems[7+i]);
316     if (MB_SUCCESS != result) return MB_FAILURE;
317   }
318 
319     // make the duplicated edges explicitly too
320   for (int i = 0; i < 2; i++) {
321     for (int j = 0; j < 2; j++)
322       conn[j] = vtx_handles[connect[48+j]];
323     result = gMB->create_element(MBEDGE, conn, 2, elems[9+i]);
324     if (MB_SUCCESS != result) return MB_FAILURE;
325   }
326 
327     // now the quad between the lower pair of hexes
328   for (int j = 0; j < 4; j++)
329     conn[j] = vtx_handles[connect[50+j]];
330   result = gMB->create_element(MBQUAD, conn, 4, elems[11]);
331   if (MB_SUCCESS != result) return MB_FAILURE;
332 
333     // now set adjacencies explicitly
334     // front/rear duplicated edge to front/rear pair of quads
335   result = gMB->add_adjacencies(elems[9], &elems[5], 2, false);
336   if (MB_SUCCESS != result) return MB_FAILURE;
337   result = gMB->add_adjacencies(elems[10], &elems[7], 2, false);
338   if (MB_SUCCESS != result) return MB_FAILURE;
339 
340     // rear duplicated edge to quad between lower pair of normal hexes
341   result = gMB->add_adjacencies(elems[10], &elems[11], 1, false);
342   if (MB_SUCCESS != result) return MB_FAILURE;
343 
344     // front/rear duplicated edge to front/rear degen hex
345   result = gMB->add_adjacencies(elems[9], &elems[3], 1, false);
346   if (MB_SUCCESS != result) return MB_FAILURE;
347   result = gMB->add_adjacencies(elems[10], &elems[4], 1, false);
348   if (MB_SUCCESS != result) return MB_FAILURE;
349 
350     // rear duplicated edge to normal hexes behind it
351   result = gMB->add_adjacencies(elems[10], &elems[1], 2, false);
352   if (MB_SUCCESS != result) return MB_FAILURE;
353 
354     // front pair of quads to front degen hex
355   result = gMB->add_adjacencies(elems[5], &elems[3], 1, false);
356   if (MB_SUCCESS != result) return MB_FAILURE;
357   result = gMB->add_adjacencies(elems[6], &elems[3], 1, false);
358   if (MB_SUCCESS != result) return MB_FAILURE;
359 
360     // rear pair of quads to rear degen hex
361   result = gMB->add_adjacencies(elems[7], &elems[4], 1, false);
362   if (MB_SUCCESS != result) return MB_FAILURE;
363   result = gMB->add_adjacencies(elems[8], &elems[4], 1, false);
364   if (MB_SUCCESS != result) return MB_FAILURE;
365 
366     // rear pair of quads to normal hexes behind them
367   result = gMB->add_adjacencies(elems[7], &elems[1], 1, false);
368   if (MB_SUCCESS != result) return MB_FAILURE;
369   result = gMB->add_adjacencies(elems[8], &elems[2], 1, false);
370   if (MB_SUCCESS != result) return MB_FAILURE;
371 
372   return MB_SUCCESS;
373 }
374 
make_triple_chord_push()375 ErrorCode make_triple_chord_push()
376 {
377     // make chord push configuration
378     // make all vertices
379   double vtx_coord[] =
380     {
381         // first layer
382       0.0, 0.0, 0.5,
383       0.0, 1.0, 0.0,
384       -1.0, 0.5, 0.0,
385       -1.0, -0.5, 0.0,
386       0.0, -1.0, 0.0,
387       1.0, -0.5, 0.0,
388       1.0, 0.5, 0.0,
389         // second layer
390       0.0, 0.0, -1.5,
391       0.0, 1.0, -1.0,
392       -1.0, 0.5, -1.0,
393       -1.0, -0.5, -1.0,
394       0.0, -1.0, -1.0,
395       1.0, -0.5, -1.0,
396       1.0, 0.5, -1.0,
397         // 2 extra vertices in middle
398       0.0, 0.0, -0.25,
399       0.0, 0.0, 0.0
400     };
401 
402   int connect[] = {
403       // 3 "normal" hexes first
404       // top hex
405     14, 2, 1, 6, 7, 9, 8, 13,
406       // bottom left
407     14, 4, 3, 2, 7, 11, 10, 9,
408       // bottom right
409     6, 5, 4, 14, 13, 12, 11, 7,
410       // front triple chord push hex
411     0, 4, 3, 2, 6, 5, 15, 1,
412       // back triple chord push hex
413     2, 1, 15, 3, 14, 6, 5, 4
414   };
415 
416   ErrorCode result;
417   EntityHandle vtx_handles[16];
418 
419   for (int i = 0; i < 16; i++) {
420     result = gMB->create_vertex(&vtx_coord[3*i], vtx_handles[i]);
421     if (MB_SUCCESS != result) return MB_FAILURE;
422   }
423 
424   EntityHandle conn[8], elems[12];
425 
426     // make the five hexes
427   for (int i = 0; i < 5; i++) {
428     for (int j = 0; j < 8; j++)
429       conn[j] = vtx_handles[connect[8*i+j]];
430     result = gMB->create_element(MBHEX, conn, 8, elems[i]);
431     if (MB_SUCCESS != result) return MB_FAILURE;
432   }
433 
434   return MB_SUCCESS;
435 }
436 
make_triple_hex_push()437 ErrorCode make_triple_hex_push()
438 {
439   return MB_FAILURE;
440 }
441 
442