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