1 #include "TestUtil.hpp"
2 #include "moab/Core.hpp"
3 #include "moab/ReadUtilIface.hpp"
4 #include "MBTagConventions.hpp"
5 
6 using namespace moab;
7 
8 std::string example = TestDir + "/io/mpasx1.642.t.2.nc";
9 
10 #ifdef MOAB_HAVE_MPI
11 #include "moab_mpi.h"
12 #include "moab/ParallelComm.hpp"
13 #endif
14 
15 void test_read_all();
16 void test_read_onevar();
17 void test_read_onetimestep();
18 void test_read_nomesh();
19 void test_read_novars();
20 void test_read_no_mixed_elements(); // Test read option NO_MIXED_ELEMENTS
21 void test_read_no_edges(); // Test read option NO_EDGES
22 void test_gather_onevar(); // Test gather set with one variable
23 
24 void get_options(std::string& opts);
25 
26 const double eps = 1e-20;
27 
main(int argc,char * argv[])28 int main(int argc, char* argv[])
29 {
30   int result = 0;
31 
32 #ifdef MOAB_HAVE_MPI
33   int fail = MPI_Init(&argc, &argv);
34   if (fail)
35     return 1;
36 #else
37   argv[0] = argv[argc - argc]; // To remove the warnings in serial mode about unused variables
38 #endif
39 
40   result += RUN_TEST(test_read_all);
41   result += RUN_TEST(test_read_onevar);
42   result += RUN_TEST(test_read_onetimestep);
43   result += RUN_TEST(test_read_nomesh);
44   result += RUN_TEST(test_read_novars);
45   result += RUN_TEST(test_read_no_mixed_elements);
46   result += RUN_TEST(test_read_no_edges);
47   result += RUN_TEST(test_gather_onevar);
48 
49 #ifdef MOAB_HAVE_MPI
50   fail = MPI_Finalize();
51   if (fail)
52     return 1;
53 #endif
54 
55   return result;
56 }
57 
test_read_all()58 void test_read_all()
59 {
60   Core moab;
61   Interface& mb = moab;
62 
63   std::string opts;
64   get_options(opts);
65 
66   // Read mesh and read all variables at all timesteps
67   ErrorCode rval = mb.load_file(example.c_str(), NULL, opts.c_str());
68   CHECK_ERR(rval);
69 
70 #ifdef MOAB_HAVE_MPI
71   ParallelComm* pcomm = ParallelComm::get_pcomm(&mb, 0);
72   int procs = pcomm->proc_config().proc_size();
73 #else
74   int procs = 1;
75 #endif
76 
77   // Make check runs this test on one processor
78   if (1 == procs) {
79     // For each tag, check two values
80     double val[2];
81 
82     // Check tags for vertex variable vorticity
83     Tag vorticity_tag0, vorticity_tag1;
84     rval = mb.tag_get_handle("vorticity0", 1, MB_TYPE_DOUBLE, vorticity_tag0);
85     CHECK_ERR(rval);
86     rval = mb.tag_get_handle("vorticity1", 1, MB_TYPE_DOUBLE, vorticity_tag1);
87     CHECK_ERR(rval);
88 
89     // Get vertices (1280 edges)
90     Range verts;
91     rval = mb.get_entities_by_type(0, MBVERTEX, verts);
92     CHECK_ERR(rval);
93     CHECK_EQUAL((size_t)1280, verts.size());
94     CHECK_EQUAL((size_t)1, verts.psize());
95 
96     // Check vorticity tag values on first two vertices
97     EntityHandle vert_ents[] = {verts[0], verts[1]};
98     rval = mb.tag_get_data(vorticity_tag0, vert_ents, 2, val);
99     CHECK_ERR(rval);
100     CHECK_REAL_EQUAL(1.1, val[0], eps);
101     CHECK_REAL_EQUAL(1.2, val[1], eps);
102     rval = mb.tag_get_data(vorticity_tag1, vert_ents, 2, val);
103     CHECK_ERR(rval);
104     CHECK_REAL_EQUAL(2.1, val[0], eps);
105     CHECK_REAL_EQUAL(2.2, val[1], eps);
106 
107     // Check tags for edge variable u
108     Tag u_tag0, u_tag1;
109     rval = mb.tag_get_handle("u0", 1, MB_TYPE_DOUBLE, u_tag0);
110     CHECK_ERR(rval);
111     rval = mb.tag_get_handle("u1", 1, MB_TYPE_DOUBLE, u_tag1);
112     CHECK_ERR(rval);
113 
114     // Get edges (1920 edges)
115     Range edges;
116     rval = mb.get_entities_by_type(0, MBEDGE, edges);
117     CHECK_ERR(rval);
118     CHECK_EQUAL((size_t)1920, edges.size());
119     CHECK_EQUAL((size_t)1, edges.psize());
120 
121     // Check u tag values on two specified edges
122     EntityHandle edge_ents[] = {edges[5], edges[6]};
123     rval = mb.tag_get_data(u_tag0, edge_ents, 2, val);
124     CHECK_ERR(rval);
125     CHECK_REAL_EQUAL(1.113138721544778, val[0], eps);
126     CHECK_REAL_EQUAL(-1.113138721930009, val[1], eps);
127     rval = mb.tag_get_data(u_tag1, edge_ents, 2, val);
128     CHECK_ERR(rval);
129     CHECK_REAL_EQUAL(2.113138721544778, val[0], eps);
130     CHECK_REAL_EQUAL(-2.113138721930009, val[1], eps);
131 
132     // Check tags for cell variable ke
133     Tag ke_tag0, ke_tag1;
134     rval = mb.tag_get_handle("ke0", 1, MB_TYPE_DOUBLE, ke_tag0);
135     CHECK_ERR(rval);
136     rval = mb.tag_get_handle("ke1", 1, MB_TYPE_DOUBLE, ke_tag1);
137     CHECK_ERR(rval);
138 
139     // Get cells (12 pentagons and 630 hexagons)
140     Range cells;
141     rval = mb.get_entities_by_type(0, MBPOLYGON, cells);
142     CHECK_ERR(rval);
143     CHECK_EQUAL((size_t)642, cells.size());
144     CHECK_EQUAL((size_t)1, cells.psize());
145 
146     // Check ke tag values on first pentagon and first hexagon
147     EntityHandle cell_ents[] = {cells[0], cells[12]};
148     rval = mb.tag_get_data(ke_tag0, cell_ents, 2, val);
149     CHECK_ERR(rval);
150     CHECK_REAL_EQUAL(15.001, val[0], eps);
151     CHECK_REAL_EQUAL(16.013, val[1], eps);
152     rval = mb.tag_get_data(ke_tag1, cell_ents, 2, val);
153     CHECK_ERR(rval);
154     CHECK_REAL_EQUAL(25.001, val[0], eps);
155     CHECK_REAL_EQUAL(26.013, val[1], eps);
156   }
157 }
158 
test_read_onevar()159 void test_read_onevar()
160 {
161   Core moab;
162   Interface& mb = moab;
163 
164   std::string opts;
165   get_options(opts);
166 
167   // Read mesh and read cell variable ke at all timesteps
168   opts += ";VARIABLE=ke";
169   ErrorCode rval = mb.load_file(example.c_str(), NULL, opts.c_str());
170   CHECK_ERR(rval);
171 
172 #ifdef MOAB_HAVE_MPI
173   ParallelComm* pcomm = ParallelComm::get_pcomm(&mb, 0);
174   int procs = pcomm->proc_config().proc_size();
175 #else
176   int procs = 1;
177 #endif
178 
179   // Make check runs this test on one processor
180   if (1 == procs) {
181     // Check ke tags
182     Tag ke_tag0, ke_tag1;
183     rval = mb.tag_get_handle("ke0", 1, MB_TYPE_DOUBLE, ke_tag0);
184     CHECK_ERR(rval);
185     rval = mb.tag_get_handle("ke1", 1, MB_TYPE_DOUBLE, ke_tag1);
186     CHECK_ERR(rval);
187 
188     // Get cells (12 pentagons and 630 hexagons)
189     Range cells;
190     rval = mb.get_entities_by_type(0, MBPOLYGON, cells);
191     CHECK_ERR(rval);
192     CHECK_EQUAL((size_t)642, cells.size());
193     CHECK_EQUAL((size_t)1, cells.psize());
194 
195     // Check ke tag values on 4 cells: first pentagon, last pentagon,
196     // first hexagon, and last hexagon
197     EntityHandle cell_ents[] = {cells[0], cells[11], cells[12], cells[641]};
198     double ke0_val[4];
199     rval = mb.tag_get_data(ke_tag0, cell_ents, 4, ke0_val);
200     CHECK_ERR(rval);
201     CHECK_REAL_EQUAL(15.001, ke0_val[0], eps);
202     CHECK_REAL_EQUAL(15.012, ke0_val[1], eps);
203     CHECK_REAL_EQUAL(16.013, ke0_val[2], eps);
204     CHECK_REAL_EQUAL(16.642, ke0_val[3], eps);
205     double ke1_val[4];
206     rval = mb.tag_get_data(ke_tag1, cell_ents, 4, ke1_val);
207     CHECK_ERR(rval);
208     CHECK_REAL_EQUAL(25.001, ke1_val[0], eps);
209     CHECK_REAL_EQUAL(25.012, ke1_val[1], eps);
210     CHECK_REAL_EQUAL(26.013, ke1_val[2], eps);
211     CHECK_REAL_EQUAL(26.642, ke1_val[3], eps);
212   }
213 }
214 
test_read_onetimestep()215 void test_read_onetimestep()
216 {
217   Core moab;
218   Interface& mb = moab;
219 
220   std::string opts;
221   get_options(opts);
222 
223   // Read mesh and read all variables at 2nd timestep
224   opts += ";TIMESTEP=1";
225   ErrorCode rval = mb.load_file(example.c_str(), NULL, opts.c_str());
226   CHECK_ERR(rval);
227 
228   // Check vorticity tags
229   Tag vorticity_tag0, vorticity_tag1;
230   rval = mb.tag_get_handle("vorticity0", 1, MB_TYPE_DOUBLE, vorticity_tag0);
231   // Tag vorticity0 should not exist
232   CHECK_EQUAL(rval, MB_TAG_NOT_FOUND);
233   rval = mb.tag_get_handle("vorticity1", 1, MB_TYPE_DOUBLE, vorticity_tag1);
234   CHECK_ERR(rval);
235 }
236 
test_read_nomesh()237 void test_read_nomesh()
238 {
239   Core moab;
240   Interface& mb = moab;
241 
242   // Need a file set for nomesh to work right
243   EntityHandle file_set;
244   ErrorCode rval = mb.create_meshset(MESHSET_SET, file_set);
245   CHECK_ERR(rval);
246 
247   std::string orig, opts;
248   get_options(orig);
249 
250   // Read mesh and read all variables at 1st timestep
251   opts = orig + ";TIMESTEP=0";
252   rval = mb.load_file(example.c_str(), &file_set, opts.c_str());
253   CHECK_ERR(rval);
254 
255   // Check u tags
256   Tag u_tag0, u_tag1;
257   rval = mb.tag_get_handle("u0", 1, MB_TYPE_DOUBLE, u_tag0);
258   CHECK_ERR(rval);
259   // Tag u1 should not exist
260   rval = mb.tag_get_handle("u1", 1, MB_TYPE_DOUBLE, u_tag1);
261   CHECK_EQUAL(rval, MB_TAG_NOT_FOUND);
262 
263   // Read all variables at 2nd timestep 0, no need to read mesh
264   opts = orig + ";TIMESTEP=1;NOMESH";
265   rval = mb.load_file(example.c_str(), &file_set, opts.c_str());
266   CHECK_ERR(rval);
267 
268   // Check tag u1 again
269   rval = mb.tag_get_handle("u1", 1, MB_TYPE_DOUBLE, u_tag1);
270   // Tag u1 should exist at this time
271   CHECK_ERR(rval);
272 }
273 
test_read_novars()274 void test_read_novars()
275 {
276   Core moab;
277   Interface& mb = moab;
278 
279   // Need a file set for nomesh to work right
280   EntityHandle file_set;
281   ErrorCode rval = mb.create_meshset(MESHSET_SET, file_set);
282   CHECK_ERR(rval);
283 
284   std::string orig, opts;
285   get_options(orig);
286   CHECK_ERR(rval);
287 
288   // Read header info only, no mesh, no variables
289   opts = orig + ";NOMESH;VARIABLE=";
290   rval = mb.load_file(example.c_str(), &file_set, opts.c_str());
291   CHECK_ERR(rval);
292 
293   // Read mesh, but still no variables
294   opts = orig + ";VARIABLE=;TIMESTEP=0";
295   rval = mb.load_file(example.c_str(), &file_set, opts.c_str());
296   CHECK_ERR(rval);
297 
298   // Check ke tags
299   Tag ke_tag0, ke_tag1;
300   rval = mb.tag_get_handle("ke0", 1, MB_TYPE_DOUBLE, ke_tag0);
301   // Tag ke0 should not exist
302   CHECK_EQUAL(rval, MB_TAG_NOT_FOUND);
303   rval = mb.tag_get_handle("ke1", 1, MB_TYPE_DOUBLE, ke_tag1);
304   // Tag ke1 should not exist
305   CHECK_EQUAL(rval, MB_TAG_NOT_FOUND);
306 
307   // Read ke at 1st timestep, no need to read mesh
308   opts = orig + ";VARIABLE=ke;TIMESTEP=0;NOMESH";
309   rval = mb.load_file(example.c_str(), &file_set, opts.c_str());
310   CHECK_ERR(rval);
311 
312   // Check ke tags again
313   rval = mb.tag_get_handle("ke0", 1, MB_TYPE_DOUBLE, ke_tag0);
314   // Tag ke0 should exist at this time
315   CHECK_ERR(rval);
316   // Tag ke1 should still not exist
317   rval = mb.tag_get_handle("ke1", 1, MB_TYPE_DOUBLE, ke_tag1);
318   CHECK_EQUAL(rval, MB_TAG_NOT_FOUND);
319 
320   // Read ke at 2nd timestep, no need to read mesh
321   opts = orig + ";VARIABLE=ke;TIMESTEP=1;NOMESH";
322   rval = mb.load_file(example.c_str(), &file_set, opts.c_str());
323   CHECK_ERR(rval);
324 
325   // Check tag ke1 again
326   rval = mb.tag_get_handle("ke1", 1, MB_TYPE_DOUBLE, ke_tag1);
327   // Tag ke1 should exist at this time
328   CHECK_ERR(rval);
329 
330 #ifdef MOAB_HAVE_MPI
331   ParallelComm* pcomm = ParallelComm::get_pcomm(&mb, 0);
332   int procs = pcomm->proc_config().proc_size();
333 #else
334   int procs = 1;
335 #endif
336 
337   // Make check runs this test on one processor
338   if (1 == procs) {
339     // Get cells (12 pentagons and 630 hexagons)
340     Range cells;
341     rval = mb.get_entities_by_type(file_set, MBPOLYGON, cells);
342     CHECK_ERR(rval);
343     CHECK_EQUAL((size_t)642, cells.size());
344     CHECK_EQUAL((size_t)1, cells.psize());
345 
346     // Check ke tag values on 4 cells: first pentagon, last pentagon,
347     // first hexagon, and last hexagon
348     EntityHandle cell_ents[] = {cells[0], cells[11], cells[12], cells[641]};
349     double ke0_val[4];
350     rval = mb.tag_get_data(ke_tag0, cell_ents, 4, ke0_val);
351     CHECK_ERR(rval);
352     CHECK_REAL_EQUAL(15.001, ke0_val[0], eps);
353     CHECK_REAL_EQUAL(15.012, ke0_val[1], eps);
354     CHECK_REAL_EQUAL(16.013, ke0_val[2], eps);
355     CHECK_REAL_EQUAL(16.642, ke0_val[3], eps);
356     double ke1_val[4];
357     rval = mb.tag_get_data(ke_tag1, cell_ents, 4, ke1_val);
358     CHECK_ERR(rval);
359     CHECK_REAL_EQUAL(25.001, ke1_val[0], eps);
360     CHECK_REAL_EQUAL(25.012, ke1_val[1], eps);
361     CHECK_REAL_EQUAL(26.013, ke1_val[2], eps);
362     CHECK_REAL_EQUAL(26.642, ke1_val[3], eps);
363   }
364 }
365 
test_read_no_mixed_elements()366 void test_read_no_mixed_elements()
367 {
368   Core moab;
369   Interface& mb = moab;
370 
371   std::string opts;
372   get_options(opts);
373 
374   // Read mesh with no mixed elements and read all variables at all timesteps
375   opts += ";NO_MIXED_ELEMENTS";
376   ErrorCode rval = mb.load_file(example.c_str(), NULL, opts.c_str());
377   CHECK_ERR(rval);
378 
379 #ifdef MOAB_HAVE_MPI
380   ParallelComm* pcomm = ParallelComm::get_pcomm(&mb, 0);
381   int procs = pcomm->proc_config().proc_size();
382 #else
383   int procs = 1;
384 #endif
385 
386   // Make check runs this test on one processor
387   if (1 == procs) {
388     // Check ke tags
389     Tag ke_tag0, ke_tag1;
390     rval = mb.tag_get_handle("ke0", 1, MB_TYPE_DOUBLE, ke_tag0);
391     CHECK_ERR(rval);
392     rval = mb.tag_get_handle("ke1", 1, MB_TYPE_DOUBLE, ke_tag1);
393     CHECK_ERR(rval);
394 
395     // Get cells (12 pentagons and 630 hexagons)
396     Range cells;
397     rval = mb.get_entities_by_type(0, MBPOLYGON, cells);
398     CHECK_ERR(rval);
399     CHECK_EQUAL((size_t)642, cells.size());
400     // Only one group of cells (pentagons are padded to hexagons,
401     // e.g. connectivity [1 2 3 4 5] => [1 2 3 4 5 5])
402     CHECK_EQUAL((size_t)1, cells.psize());
403 
404     // Check ke tag values on 4 cells: first pentagon, last pentagon,
405     // first hexagon, and last hexagon
406     EntityHandle cell_ents[] = {cells[0], cells[11], cells[12], cells[641]};
407     double ke0_val[4];
408     rval = mb.tag_get_data(ke_tag0, cell_ents, 4, ke0_val);
409     CHECK_ERR(rval);
410     CHECK_REAL_EQUAL(15.001, ke0_val[0], eps);
411     CHECK_REAL_EQUAL(15.012, ke0_val[1], eps);
412     CHECK_REAL_EQUAL(16.013, ke0_val[2], eps);
413     CHECK_REAL_EQUAL(16.642, ke0_val[3], eps);
414     double ke1_val[4];
415     rval = mb.tag_get_data(ke_tag1, cell_ents, 4, ke1_val);
416     CHECK_ERR(rval);
417     CHECK_REAL_EQUAL(25.001, ke1_val[0], eps);
418     CHECK_REAL_EQUAL(25.012, ke1_val[1], eps);
419     CHECK_REAL_EQUAL(26.013, ke1_val[2], eps);
420     CHECK_REAL_EQUAL(26.642, ke1_val[3], eps);
421   }
422 }
423 
test_read_no_edges()424 void test_read_no_edges()
425 {
426   Core moab;
427   Interface& mb = moab;
428 
429   std::string opts;
430   get_options(opts);
431 
432   opts += ";NO_EDGES;VARIABLE=";
433   ErrorCode rval = mb.load_file(example.c_str(), NULL, opts.c_str());
434   CHECK_ERR(rval);
435 
436   // Get edges
437   Range edges;
438   rval = mb.get_entities_by_type(0, MBEDGE, edges);
439   CHECK_ERR(rval);
440   CHECK_EQUAL((size_t)0, edges.size());
441 }
442 
test_gather_onevar()443 void test_gather_onevar()
444 {
445   Core moab;
446   Interface& mb = moab;
447 
448   EntityHandle file_set;
449   ErrorCode rval = mb.create_meshset(MESHSET_SET, file_set);
450   CHECK_ERR(rval);
451 
452   std::string opts;
453   get_options(opts);
454 
455   // Read cell variable ke and create gather set on processor 0
456   opts += ";VARIABLE=ke;GATHER_SET=0";
457   rval = mb.load_file(example.c_str(), &file_set, opts.c_str());
458   CHECK_ERR(rval);
459 
460 #ifdef MOAB_HAVE_MPI
461   ParallelComm* pcomm = ParallelComm::get_pcomm(&mb, 0);
462   int rank = pcomm->proc_config().proc_rank();
463 
464   Range cells, cells_owned;
465   rval = mb.get_entities_by_type(file_set, MBPOLYGON, cells);
466   CHECK_ERR(rval);
467 
468   // Get local owned cells
469   rval = pcomm->filter_pstatus(cells, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1, &cells_owned);
470   CHECK_ERR(rval);
471 
472   EntityHandle gather_set = 0;
473   if (0 == rank) {
474     // Get gather set
475     ReadUtilIface* readUtilIface;
476     mb.query_interface(readUtilIface);
477     rval = readUtilIface->get_gather_set(gather_set);
478     CHECK_ERR(rval);
479     assert(gather_set != 0);
480   }
481 
482   Tag ke_tag0, gid_tag;
483   rval = mb.tag_get_handle("ke0", 1, MB_TYPE_DOUBLE, ke_tag0, MB_TAG_DENSE);
484   CHECK_ERR(rval);
485 
486   rval = mb.tag_get_handle(GLOBAL_ID_TAG_NAME, 1, MB_TYPE_INTEGER, gid_tag, MB_TAG_DENSE);
487   CHECK_ERR(rval);
488 
489   pcomm->gather_data(cells_owned, ke_tag0, gid_tag, gather_set, 0);
490 
491   if (0 == rank) {
492     // Get gather set cells
493     Range gather_set_cells;
494     rval = mb.get_entities_by_type(gather_set, MBPOLYGON, gather_set_cells);
495     CHECK_ERR(rval);
496     CHECK_EQUAL((size_t)642, gather_set_cells.size());
497     CHECK_EQUAL((size_t)1, gather_set_cells.psize());
498 
499     // Check ke0 tag values on 4 gather set cells: first pentagon, last pentagon,
500     // first hexagon, and last hexagon
501     double ke0_val[4];
502     EntityHandle cell_ents[] = {gather_set_cells[0], gather_set_cells[11],
503                                 gather_set_cells[12], gather_set_cells[641]};
504     rval = mb.tag_get_data(ke_tag0, cell_ents, 4, ke0_val);
505     CHECK_ERR(rval);
506     CHECK_REAL_EQUAL(15.001, ke0_val[0], eps);
507     CHECK_REAL_EQUAL(15.012, ke0_val[1], eps);
508     CHECK_REAL_EQUAL(16.013, ke0_val[2], eps);
509     CHECK_REAL_EQUAL(16.642, ke0_val[3], eps);
510   }
511 #endif
512 }
513 
get_options(std::string & opts)514 void get_options(std::string& opts)
515 {
516 #ifdef MOAB_HAVE_MPI
517   // Use parallel options
518   opts = std::string(";;PARALLEL=READ_PART;PARTITION_METHOD=TRIVIAL");
519 #else
520   opts = std::string(";;");
521 #endif
522 }
523