1 /**
2 * MOAB, a Mesh-Oriented datABase, is a software component for creating,
3 * storing and accessing finite element mesh data.
4 *
5 * Copyright 2004 Sandia Corporation. Under the terms of Contract
6 * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
7 * retains certain rights in this software.
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 */
15
16
17 /*!
18 MBTest.cpp
19 Test Harness for MB mesh database system
20 */
21
22 #ifdef WIN32
23 #ifdef _DEBUG
24 // turn off warnings that say they debugging identifier has been truncated
25 // this warning comes up when using some STL containers
26 #pragma warning(disable : 4786)
27 #endif
28 #endif
29
30 #include <iostream>
31 #include <fstream>
32 #include <algorithm>
33 #include <cstdio>
34 #include <time.h>
35 #include <assert.h>
36 #include <math.h>
37 #include <stdio.h>
38 #include "moab/Interface.hpp"
39 #include "MBTagConventions.hpp"
40 #include "moab/Range.hpp"
41 #include "moab/Skinner.hpp"
42 #include "moab/MeshTopoUtil.hpp"
43 #include "moab/CN.hpp"
44 #include "moab/OrientedBox.hpp"
45 #include "moab/CartVect.hpp"
46 #include "moab/WriteUtilIface.hpp"
47
48 #ifdef MOAB_HAVE_MPI
49 #include "moab_mpi.h"
50 #endif
51
52 #ifndef IS_BUILDING_MB
53 #define IS_BUILDING_MB
54 #endif
55 #include "Internals.hpp"
56 #include "moab/Core.hpp"
57 #include "SequenceManager.hpp"
58 #include "EntitySequence.hpp"
59 #include "RangeSeqIntersectIter.hpp"
60 #include "moab/Error.hpp"
61 #include "moab/ScdInterface.hpp"
62
63 /* Use the following define to specify that our tests
64 return an error code and not the default void */
65 #define TEST_USES_ERR_CODES
66 #include "TestUtil.hpp"
67
68 using namespace std;
69 using namespace moab;
70
71 #define CHKERR(A) do { if (MB_SUCCESS != (A)) { \
72 std::cerr << "Failure (error code " << (A) << ") at " __FILE__ ":" \
73 << __LINE__ << std::endl; \
74 return A; } } while(false)
75
76
77 #ifdef MOAB_HAVE_NETCDF
load_file_one(Interface * iface)78 ErrorCode load_file_one( Interface* iface )
79 {
80 std::string file_name = TestDir + "/mbtest1.g";
81 ErrorCode error = iface->load_mesh( file_name.c_str() );
82 if (MB_SUCCESS != error) {
83 std::cout << "Failed to load input file: " << file_name << std::endl;
84 std::string error_reason;
85 iface->get_last_error(error_reason);
86 cout << error_reason << std::endl;
87 }
88 return error;
89 }
90 #endif
91
92 /* Create a regular 2x2x2 hex mesh */
93 ErrorCode create_some_mesh( Interface* iface );
94
95 ErrorCode check_valid_connectivity( Interface* iface );
96
97
98 /*!
99 @test
100 Vertex Coordinates
101 @li Get coordinates of vertex 1 correctly
102 @li Get coordinates of vertex 8 correctly
103 @li Get coordinates of vertex 6 correctly
104 */
mb_vertex_coordinate_test()105 ErrorCode mb_vertex_coordinate_test()
106 {
107 Core moab;
108 Interface* MB = &moab;
109 ErrorCode error = create_some_mesh( MB );
110 MB_CHK_ERR(error);
111
112 Range vertices;
113 error = MB->get_entities_by_type(0, MBVERTEX, vertices);
114 MB_CHK_ERR(error);
115
116 std::vector<double> all_coords(3*vertices.size());
117 double* coord_iter = &all_coords[0];
118 for ( Range::iterator iter = vertices.begin();
119 iter != vertices.end(); ++iter)
120 {
121 error = MB->get_coords(&(*iter), 1, coord_iter );
122 MB_CHK_ERR(error);
123 coord_iter += 3;
124 }
125
126 // check blocked coordinates
127 const size_t N = vertices.size()+1;
128 std::vector<double> x(N), y(N), z(N);
129 // set last value so we can check later that nothing wrote past the
130 // intended end of an array
131 x[vertices.size()] = y[vertices.size()] = z[vertices.size()] = -3.14159;
132 error = MB->get_coords( vertices, &x[0], &y[0], &z[0] );
133 for (size_t i = 0; i < vertices.size(); ++i) {
134 CHECK_REAL_EQUAL( all_coords[3*i ], x[i], 1E-12 );
135 CHECK_REAL_EQUAL( all_coords[3*i+1], y[i], 1E-12 );
136 CHECK_REAL_EQUAL( all_coords[3*i+2], z[i], 1E-12 );
137 }
138 // checkthat get_coords did not write past intended end of arrays
139 CHECK_REAL_EQUAL( -3.14159, x[vertices.size()], 1E-12 );
140 CHECK_REAL_EQUAL( -3.14159, y[vertices.size()], 1E-12 );
141 CHECK_REAL_EQUAL( -3.14159, z[vertices.size()], 1E-12 );
142
143 // add invalid handle to end of range and try query again
144 vertices.insert( vertices.back() + 1 );
145 error = MB->get_coords( vertices, &x[0], &y[0], &z[0] );
146 CHECK_EQUAL( MB_ENTITY_NOT_FOUND, error );
147
148 // Try getting coordinates for a hex (should fail)
149 Range hexes;
150 error = MB->get_entities_by_type( 0, MBHEX, hexes );MB_CHK_ERR(error);
151 EntityHandle handle = hexes.front();
152 error = MB->get_coords(&handle, 1, &x[0]);MB_CHK_ERR(error);
153 CHECK_REAL_EQUAL(0.5, x[0], 1E-12);
154 CHECK_REAL_EQUAL(0.5, x[1], 1E-12);
155 CHECK_REAL_EQUAL(0.5, x[2], 1E-12);
156
157 return MB_SUCCESS;
158 }
159
160 /*!
161 @test
162 MB Vertex Tag Test
163 @li Add, Set and correctly get an int tag
164 @li Add, Set and correctly get a boolean tag
165 @li Add, Set and correctly get a double tag
166 @li Add, Set and correctly get a struct tag
167 */
mb_vertex_tag_test()168 ErrorCode mb_vertex_tag_test()
169 {
170 Core moab;
171 Interface* MB = &moab;
172 ErrorCode error = create_some_mesh( MB );
173 if (MB_SUCCESS != error)
174 return error;
175
176 // Add an int Vertex Tag to the database
177
178 Tag tag_id;
179
180 // Create a dense tag for all vertices
181 error = MB->tag_get_handle("int_tag", 1, MB_TYPE_INTEGER, tag_id, MB_TAG_SPARSE|MB_TAG_EXCL);
182 if (error != MB_SUCCESS)
183 return error;
184
185 // put a value in vertex 1 and retrieve
186 std::vector<EntityHandle> verts;
187 error = MB->get_entities_by_type( 0, MBVERTEX, verts );
188 if (MB_SUCCESS != error) return error;
189 EntityHandle handle = verts[0];
190 int input_value = 11;
191 error = MB->tag_set_data(tag_id, &handle, 1, &input_value);
192 if (MB_SUCCESS != error) return error;
193
194 int output_value;
195 error = MB->tag_get_data(tag_id, &handle, 1, &output_value);
196 if(MB_SUCCESS != error) return error;
197 else if (output_value != input_value)
198 return MB_FAILURE;
199
200 // put a value in vertex 5 and retrieve
201
202 handle = verts[5];
203 input_value = 11;
204 error = MB->tag_set_data(tag_id, &handle, 1, &input_value);
205 if (MB_SUCCESS != error) return error;
206 error = MB->tag_get_data(tag_id, &handle, 1, &output_value);
207 if (MB_SUCCESS != error) return error;
208 else if(output_value != input_value)
209 return MB_FAILURE;
210
211 // put a value in vertex 98088234 which doesn't exist
212 handle = *std::max_element( verts.begin(), verts.end() ) + 1;
213 input_value = 11;
214
215 error = MB->tag_set_data(tag_id, &handle, 1, &input_value);
216 if (error == MB_SUCCESS)
217 return error;
218
219 error = MB->tag_get_data(tag_id, &handle, 1, &output_value);
220 if (error == MB_SUCCESS)
221 return error;
222
223 if(output_value != input_value)
224 return MB_FAILURE;
225
226 // Add a bool Vertex Tag to the database
227
228 error = MB->tag_get_handle("bool_tag", sizeof(bool), MB_TYPE_OPAQUE, tag_id, MB_TAG_SPARSE|MB_TAG_EXCL);
229 if (error != MB_SUCCESS)
230 return error;
231
232 // put a value in vertex 5 and retrieve
233
234 handle = verts[5];
235 bool bool_input_value = true;
236 bool bool_output_value = false;
237 error = MB->tag_set_data(tag_id, &handle, 1, &bool_input_value);
238 if (error != MB_SUCCESS) return error;
239 error = MB->tag_get_data(tag_id, &handle, 1, &bool_output_value);
240 if (error != MB_SUCCESS) return error;
241 else if(bool_output_value != bool_input_value)
242 return MB_FAILURE;
243
244 // Add a double Vertex Tag to the database
245
246 error = MB->tag_get_handle("double_tag", 1, MB_TYPE_DOUBLE, tag_id, MB_TAG_SPARSE|MB_TAG_EXCL);
247 if (error != MB_SUCCESS)
248 return error;
249
250 // put a value in vertex 8: and retrieve
251
252 handle = verts[8];
253 double double_input_value = 1.0;
254 double double_output_value = 0.0;
255 error = MB->tag_set_data(tag_id, &handle, 1, &double_input_value);
256 if (error != MB_SUCCESS) return error;
257
258 error = MB->tag_get_data(tag_id, &handle, 1, &double_output_value);
259 if (error != MB_SUCCESS) return error;
260 else if(double_output_value != double_input_value)
261 return MB_FAILURE;
262
263 // Add a struct Vertex Tag to the database
264
265 struct TagStruct {
266 int test_int;
267 double test_double;
268 };
269 error = MB->tag_get_handle("struct_tag", sizeof(TagStruct), MB_TYPE_OPAQUE, tag_id, MB_TAG_SPARSE|MB_TAG_EXCL);
270 if (error != MB_SUCCESS)
271 return error;
272
273 // put a value in vertex 7 and retrieve
274
275 handle = verts[7];
276 TagStruct input_tag_struct;
277 input_tag_struct.test_int = 55;
278 input_tag_struct.test_double = -1.2345;
279 TagStruct output_tag_struct;
280 error = MB->tag_set_data(tag_id, &handle, 1, &input_tag_struct);
281 if (error != MB_SUCCESS) return error;
282 error = MB->tag_get_data(tag_id, &handle, 1, &output_tag_struct);
283 if (error != MB_SUCCESS) return error;
284 else if(output_tag_struct.test_int != input_tag_struct.test_int ||
285 output_tag_struct.test_double != input_tag_struct.test_double)
286 return MB_FAILURE;
287
288
289 // Create sparse tags for 10 random entities including some outside the
290 // range of allowable entities.
291
292 error = MB->tag_get_handle("sparse_int_tag", 1, MB_TYPE_INTEGER, tag_id, MB_TAG_SPARSE|MB_TAG_EXCL);
293
294 if (error != MB_SUCCESS )
295 return error;
296
297 //print_yes = true;
298 int i;
299 for (i=0; i<10; i++)
300 {
301 // use invalid handles for odd values
302
303 if (i % 2)
304 handle = verts[i] + *std::max_element( verts.begin(), verts.end() );
305 else
306 handle = verts[i];
307
308 input_value = 11;
309 error = MB->tag_set_data(tag_id, &handle, 1, &input_value);
310
311 // should fail on odd values of i
312 if ( !(i % 2) )
313 {
314 if (error != MB_SUCCESS ) // even case and if failed
315 return error;
316 }
317 else
318 {
319 if ( error == MB_SUCCESS) // odd case and it says it worked!
320 return MB_FAILURE;
321 }
322
323
324 error = MB->tag_get_data(tag_id, &handle, 1, &output_value);
325 if ( (i % 2) && error != MB_FAILURE && error != MB_TAG_NOT_FOUND)
326 return error;
327
328 if( (i % 2) && output_value != input_value)
329 return MB_FAILURE;
330 }
331
332 // get the tag_name of the last tag created above
333 std::string int_tag_name;
334 error = MB->tag_get_name (tag_id, int_tag_name);
335 if (error != MB_SUCCESS)
336 return error;
337
338 if (int_tag_name != "sparse_int_tag")
339 return MB_FAILURE;
340
341 // get the tag handle of the last tag created above
342 Tag int_tag_handle;
343 error = MB->tag_get_handle (int_tag_name.c_str(), 1, MB_TYPE_INTEGER, int_tag_handle);
344 if (MB_SUCCESS != error) return error;
345
346 if (int_tag_handle != tag_id)
347 return MB_FAILURE;
348
349 // test tag_get_tags_on_entity and tag_delete_data
350 std::vector<Tag> all_tags;
351 handle = verts[0];
352 error = MB->tag_get_tags_on_entity(handle, all_tags);
353 if (MB_SUCCESS != error)
354 return error;
355
356 if (!all_tags.empty()) {
357 error = MB->tag_delete_data(all_tags[0], &handle, 1);
358 if (MB_SUCCESS != error)
359 return error;
360
361 error = MB->tag_delete(all_tags[0]);
362 if (MB_SUCCESS != error)
363 return error;
364 }
365 // delete tags test
366
367 // delete 2 of the sparse tags that were created above.
368 handle = verts[2];
369 error = MB->tag_delete_data(tag_id, &handle, 1);
370 if (error != MB_SUCCESS )
371 return error;
372
373 handle = verts[6];
374 error = MB->tag_delete_data(tag_id, &handle, 1);
375 if (error != MB_SUCCESS )
376 return error;
377
378 // delete all the rest of the sparse tags.
379
380 error = MB->tag_delete(tag_id);
381 if (error != MB_SUCCESS )
382 return error;
383
384 // delete the dense tag named bool_tag
385 Tag bool_tag_handle;
386 error = MB->tag_get_handle ("bool_tag", sizeof(bool), MB_TYPE_OPAQUE, bool_tag_handle);
387 if (error != MB_SUCCESS) return error;
388
389 error = MB->tag_delete(bool_tag_handle);
390 if (error != MB_SUCCESS )
391 return error;
392
393 return error;
394 }
395
396
mb_temporary_test()397 ErrorCode mb_temporary_test()
398 {
399 Core moab;
400 Interface* gMB = &moab;
401
402 double array[3] = {0.0, 0.0, 0.0};
403 EntityHandle h_node1;
404 ErrorCode result = gMB->create_vertex(array, h_node1);
405 if (MB_SUCCESS != result)
406 return result;
407
408 EntityHandle ordered_meshset1;
409 result = gMB->create_meshset(MESHSET_ORDERED | MESHSET_TRACK_OWNER, ordered_meshset1);
410 if (MB_SUCCESS != result)
411 return result;
412
413 EntityHandle ordered_meshset2;
414 result = gMB->create_meshset(MESHSET_ORDERED | MESHSET_TRACK_OWNER, ordered_meshset2);
415 if (MB_SUCCESS != result)
416 return result;
417
418 result = gMB->add_entities(ordered_meshset1, &h_node1, 1);
419 if (MB_SUCCESS != result)
420 return result;
421
422 result = gMB->remove_entities(ordered_meshset1, &h_node1, 1);
423 if (MB_SUCCESS != result)
424 return result;
425
426 result = gMB->add_entities(ordered_meshset2, &h_node1, 1);
427 if (MB_SUCCESS != result)
428 return result;
429
430 bool create_if_missing = false;
431 std::vector<EntityHandle> meshsets;
432 result = gMB->get_adjacencies(&h_node1, 1, 4, create_if_missing, meshsets);
433 if (MB_SUCCESS != result)
434 return result;
435
436 if (1u != meshsets.size())
437 return MB_FAILURE;
438
439 return MB_SUCCESS;
440 }
441
mb_adjacent_vertex_test()442 ErrorCode mb_adjacent_vertex_test()
443 {
444 Core moab;
445 Interface* mb = &moab;
446 ErrorCode rval = create_some_mesh( mb );
447 if (MB_SUCCESS != rval)
448 return rval;
449
450 Range hexes, expt_vert, got_vert, some_hexes;
451 Range::const_iterator i, j;
452 int n;
453
454 // get all hexes
455 rval = mb->get_entities_by_type( 0, MBHEX, hexes );
456 if (rval != MB_SUCCESS)
457 return rval;
458 if (hexes.empty()) // can't do test if no elements
459 return MB_FAILURE;
460
461 // get every third hex and its vertices
462 n = 0;
463 for (i = hexes.begin(); i != hexes.end(); ++i) {
464 if (++n % 3)
465 continue;
466 some_hexes.insert( *i );
467 const EntityHandle* conn;
468 int len;
469 rval = mb->get_connectivity( *i, conn, len );
470 if (MB_SUCCESS != rval)
471 return rval;
472 for (int k = 0; k < len; ++k)
473 expt_vert.insert( conn[k] );
474 }
475
476 // use get_adjacencies to get vertices
477 rval = mb->get_adjacencies( some_hexes, 0, false, got_vert, Interface::UNION );
478 if (MB_SUCCESS != rval) {
479 std::cout << "get_adjacencies failed with error code " << rval << std::endl;
480 return rval;
481 }
482
483 i = expt_vert.begin();
484 j = got_vert.begin();
485 while (i != expt_vert.end() && j != got_vert.end()) {
486 if (*i < *j) {
487 std::cout << "Result missing vertex: " << *i << std::endl;
488 return MB_FAILURE;
489 }
490 else if (*j < *i) {
491 std::cout << "Result contains extra vertex: " << *j << std::endl;
492 return MB_FAILURE;
493 }
494 ++i;
495 ++j;
496 }
497
498 if (i != expt_vert.end()) {
499 std::cout << "Result missing vertex: " << *i << std::endl;
500 return MB_FAILURE;
501 }
502 else if (j != got_vert.end()) {
503 std::cout << "Result contains extra vertex: " << *j << std::endl;
504 return MB_FAILURE;
505 }
506
507 return MB_SUCCESS;
508 }
509 #ifdef MOAB_HAVE_NETCDF
mb_adjacencies_test()510 ErrorCode mb_adjacencies_test()
511 {
512 Core moab;
513 Interface* mb = &moab;
514 ErrorCode result = load_file_one( mb );
515 if (MB_SUCCESS != result)
516 return result;
517
518 // this test does the following:
519 // 1. For each element, creates vertex-element adjacencies (only for
520 // lowest-id vertex)
521 // 2. Creates all lower-order ancillary entities
522 // 3. Checks for proper number of same
523 //
524 // assume mesh has already been read
525
526 EntityType seq_type;
527 Range handle_range;
528
529 // lets create a skin of the hexes
530 // this may be far from being the most efficient, but
531 // it certainly does exercise the adjacency routines
532
533 Range::iterator iter;
534 Range::reverse_iterator riter;
535
536 // first get the hexes
537 Range hexes;
538 result = mb->get_entities_by_type(0, MBHEX, hexes);
539 if (MB_SUCCESS != result)
540 return result;
541
542
543 unsigned int num_hexes = hexes.size();
544
545 // make sure we got hexes
546 for(riter = hexes.rbegin(); riter != hexes.rend(); ++riter)
547 {
548 if( TYPE_FROM_HANDLE(*riter) != MBHEX)
549 return MB_FAILURE;
550 }
551
552
553
554 // get all the nodes that these hexes are connected to
555 Range nodes;
556 result = mb->get_adjacencies(hexes, 0, false, nodes, Interface::UNION);
557 if (MB_SUCCESS != result)
558 return result;
559
560 // make sure we got nodes
561 for(iter = nodes.begin(); iter != nodes.end(); ++iter)
562 {
563 if( TYPE_FROM_HANDLE(*iter) != MBVERTEX)
564 return MB_FAILURE;
565 }
566
567 // find the interior nodes; assume a structured mesh
568 Range interior_nodes;
569 std::vector<EntityHandle> attached_hexes;
570 for( iter = nodes.begin(); iter != nodes.end();)
571 {
572 attached_hexes.clear();
573 result = mb->get_adjacencies(&(*iter), 1, 3, false, attached_hexes);
574 if (MB_SUCCESS != result)
575 return result;
576 attached_hexes.erase(std::remove_if(attached_hexes.begin(),
577 attached_hexes.end(),
578 type_not_equals(mb, MBHEX)),
579 attached_hexes.end());
580
581
582
583 // if this node has less than 8 hexes attached to it, it is not
584 // an interior node
585 if (attached_hexes.size() == 8)
586 {
587 // add to the interior nodes list and remove from the nodes list
588 interior_nodes.insert(*iter);
589 iter = nodes.erase(iter);
590 }
591 else
592 ++iter;
593
594 }
595
596 // get interior quads from interior nodes
597 Range interior_quads;
598 result = mb->get_adjacencies(interior_nodes, 2, true, interior_quads, Interface::UNION);
599 if (MB_SUCCESS != result)
600 return result;
601
602 // get a list of quads generated adjacent to the exterior nodes
603 Range temp_quads, exterior_quads;
604 result = mb->get_adjacencies(nodes, 2, true, temp_quads, Interface::UNION);
605 if (MB_SUCCESS != result)
606 return result;
607
608 // now remove any interior quads from the previous quads list
609 // and we should be left with exterior quads
610 std::set_difference(temp_quads.begin(), temp_quads.end(),
611 interior_quads.begin(), interior_quads.end(),
612 range_inserter(exterior_quads));
613
614 // check to make sure we have the right number of quads; for hexes, should be
615 // .5(6*num_hexes - num_exterior_quads)
616 unsigned int num_expected_int_quads = (6*num_hexes - exterior_quads.size())/2;
617 if (num_expected_int_quads != interior_quads.size())
618 return MB_FAILURE;
619
620 // delete the interior quads
621 result = mb->delete_entities(interior_quads);
622 if (MB_SUCCESS != result)
623 return result;
624
625 Range remaining_quads;
626 result = mb->get_entities_by_type(0, MBQUAD, remaining_quads);
627 if (MB_SUCCESS != result)
628 return result;
629
630 if(remaining_quads.size() != exterior_quads.size())
631 return MB_FAILURE;
632
633
634 // 3. Checks for proper number of same
635 // re-retrieve and store the handle ranges for all element types
636
637 int num_ents;
638
639 for (seq_type = MBEDGE; seq_type != MBENTITYSET; seq_type++)
640 {
641 handle_range.clear();
642
643 result = mb->get_entities_by_type(0, seq_type, handle_range);
644 if (MB_SUCCESS != result)
645 return result;
646
647 result = mb->get_number_entities_by_type(0, seq_type, num_ents);
648 if (MB_SUCCESS != result)
649 return result;
650
651 if(handle_range.size() != (unsigned int) num_ents)
652 return MB_FAILURE;
653 }
654
655 return result;
656
657 }
658
659 #endif
660
mb_adjacencies_create_delete_test()661 ErrorCode mb_adjacencies_create_delete_test()
662 {
663 Core moab;
664 Interface* mb = &moab;
665 ErrorCode rval;
666
667 double coords[] = { 0, 0, 0, 2, 0, 0, 1, 2, 0 };
668 Range verts;
669 rval = mb->create_vertices( coords, 3, verts );
670 if (MB_SUCCESS != rval)
671 return rval;
672 if (verts.size() != 3)
673 return MB_FAILURE;
674 EntityHandle vert_arr[3];
675
676 EntityHandle tri;
677 std::copy( verts.begin(), verts.end(), vert_arr );
678 rval = mb->create_element( MBTRI, vert_arr, 3, tri );
679 if (MB_SUCCESS != rval)
680 return rval;
681
682 vert_arr[2] = vert_arr[0];
683 EntityHandle forward_edge, reverse_edge;
684 rval = mb->create_element( MBEDGE, vert_arr, 2, forward_edge );
685 if (MB_SUCCESS != rval)
686 return rval;
687
688 std::vector<EntityHandle> results;
689 rval = mb->get_adjacencies( &forward_edge, 1, 2, false, results );
690 if (results.size() != 1 || results.front() != tri) {
691 std::cerr << "Adjacency query from forward edge to tri failed at "
692 << __FILE__ << ":" << __LINE__ << std::endl;
693 return MB_FAILURE;
694 }
695 results.clear();
696 rval = mb->get_adjacencies( &tri, 1, 1, false, results );
697 if (results.size() != 1 || results.front() != forward_edge) {
698 std::cerr << "Adjacency query from tri to forward edge failed at "
699 << __FILE__ << ":" << __LINE__ << std::endl;
700 return MB_FAILURE;
701 }
702
703 rval = mb->delete_entities( &forward_edge, 1 );
704 if (MB_SUCCESS != rval)
705 return rval;
706
707 results.clear();
708 rval = mb->get_adjacencies( &tri, 1, 1, false, results );
709 if (!results.empty()) {
710 std::cerr << "Adjacency query from tri returned non-existent edge at "
711 << __FILE__ << ":" << __LINE__ << std::endl;
712 return MB_FAILURE;
713 }
714
715 rval = mb->create_element( MBEDGE, vert_arr+1, 2, reverse_edge );
716 if (MB_SUCCESS != rval)
717 return rval;
718
719 results.clear();
720 rval = mb->get_adjacencies( &reverse_edge, 1, 2, false, results );
721 if (results.size() != 1 || results.front() != tri) {
722 std::cerr << "Adjacency query from reverse edge to tri failed at "
723 << __FILE__ << ":" << __LINE__ << std::endl;
724 return MB_FAILURE;
725 }
726 results.clear();
727 rval = mb->get_adjacencies( &tri, 1, 1, false, results );
728 if (results.size() != 1 || results.front() != reverse_edge) {
729 std::cerr << "Adjacency query from tri to reverse edge failed at "
730 << __FILE__ << ":" << __LINE__ << std::endl;
731 return MB_FAILURE;
732 }
733
734 return MB_SUCCESS;
735 }
736
create_two_hex_full_mesh(Interface * mb,EntityHandle vertices[12],EntityHandle hexes[2],EntityHandle hex1_faces[6],EntityHandle hex2_faces[6],EntityHandle hex1_edges[12],EntityHandle hex2_edges[12])737 static ErrorCode create_two_hex_full_mesh( Interface* mb,
738 EntityHandle vertices[12],
739 EntityHandle hexes[2],
740 EntityHandle hex1_faces[6],
741 EntityHandle hex2_faces[6],
742 EntityHandle hex1_edges[12],
743 EntityHandle hex2_edges[12] )
744 {
745 ErrorCode rval;
746 // create a simple mesh containing 2 hexes
747 const double coords[] = { 0, 0, 0,
748 1, 0, 0,
749 2, 0, 0,
750 0, 1, 0,
751 1, 1, 0,
752 2, 1, 0,
753 0, 0, 1,
754 1, 0, 1,
755 2, 0, 1,
756 0, 1, 1,
757 1, 1, 1,
758 2, 1, 1 };
759 for (int i = 0; i < 12; ++i)
760 if (MB_SUCCESS != mb->create_vertex( coords + 3*i, vertices[i] ))
761 return MB_FAILURE;
762 EntityHandle hex1_conn[] = { vertices[6], vertices[7], vertices[1], vertices[0],
763 vertices[9], vertices[10],vertices[4], vertices[3] };
764 EntityHandle hex2_conn[] = { vertices[7], vertices[8], vertices[2], vertices[1],
765 vertices[10],vertices[11],vertices[5], vertices[4] };
766 EntityHandle shared_quad_conn[] = { vertices[7], vertices[1], vertices[4], vertices[10] };
767 EntityHandle hex1_face_conn[][4] = {
768 { vertices[6], vertices[7], vertices[10],vertices[9] },
769 { vertices[7], vertices[6], vertices[0], vertices[1] },
770 { vertices[1], vertices[0], vertices[3], vertices[4] },
771 { vertices[9], vertices[10],vertices[4], vertices[3] },
772 { vertices[3], vertices[0], vertices[6], vertices[9] } };
773 EntityHandle hex2_face_conn[][4] = {
774 { vertices[7], vertices[8], vertices[11],vertices[10] },
775 { vertices[8], vertices[7], vertices[1], vertices[2] },
776 { vertices[2], vertices[1], vertices[4], vertices[5] },
777 { vertices[10],vertices[11],vertices[5], vertices[4] },
778 { vertices[5], vertices[2], vertices[8], vertices[11] } };
779 EntityHandle shared_edge_conn[][2] = { { vertices[1], vertices[7] },
780 { vertices[7], vertices[10]},
781 { vertices[10],vertices[4] },
782 { vertices[4], vertices[1] } };
783 EntityHandle hex1_edge_conn[][2] = { { vertices[6], vertices[7] },
784 { vertices[9], vertices[10] },
785 { vertices[3], vertices[4] },
786 { vertices[0], vertices[1] },
787 { vertices[6], vertices[9] },
788 { vertices[9], vertices[3] },
789 { vertices[3], vertices[0] },
790 { vertices[0], vertices[6] } };
791 EntityHandle hex2_edge_conn[][2] = { { vertices[7], vertices[8] },
792 { vertices[10], vertices[11] },
793 { vertices[4], vertices[5] },
794 { vertices[1], vertices[2] },
795 { vertices[8], vertices[11] },
796 { vertices[11], vertices[5] },
797 { vertices[5], vertices[2] },
798 { vertices[2], vertices[8] } };
799 rval = mb->create_element( MBHEX, hex1_conn, 8, hexes[0] );
800 if (MB_SUCCESS != rval)
801 return rval;
802 rval = mb->create_element( MBHEX, hex2_conn, 8, hexes[1] );
803 if (MB_SUCCESS != rval)
804 return rval;
805 rval = mb->create_element( MBQUAD, shared_quad_conn, 4, hex1_faces[0] );
806 if (MB_SUCCESS != rval)
807 return rval;
808 hex2_faces[0] = hex1_faces[0];
809 for (int i = 0; i < 5; ++i) {
810 rval = mb->create_element( MBQUAD, hex1_face_conn[i], 4, hex1_faces[i+1] );
811 if (MB_SUCCESS != rval)
812 return rval;
813 rval = mb->create_element( MBQUAD, hex2_face_conn[i], 4, hex2_faces[i+1] );
814 if (MB_SUCCESS != rval)
815 return rval;
816 }
817 for (int i = 0; i < 4; ++i) {
818 rval = mb->create_element( MBEDGE, shared_edge_conn[i], 2, hex1_edges[i] );
819 if (MB_SUCCESS != rval)
820 return rval;
821 hex2_edges[i] = hex1_edges[i];
822 }
823 for (int i = 0; i < 8; ++i) {
824 rval = mb->create_element( MBEDGE, hex1_edge_conn[i], 2, hex1_edges[i+4] );
825 if (MB_SUCCESS != rval)
826 return rval;
827 rval = mb->create_element( MBEDGE, hex2_edge_conn[i], 2, hex2_edges[i+4] );
828 if (MB_SUCCESS != rval)
829 return rval;
830 }
831 return MB_SUCCESS;
832 }
833
mb_upward_adjacencies_test()834 ErrorCode mb_upward_adjacencies_test()
835 {
836 ErrorCode rval;
837 Core moab;
838 Interface* mb = &moab;
839
840 // create a simple mesh containing 2 hexes
841 EntityHandle vertices[12], hexes[2], hex1_faces[6], hex2_faces[6], hex1_edges[12], hex2_edges[12];
842 rval = create_two_hex_full_mesh( mb, vertices, hexes, hex1_faces, hex2_faces, hex1_edges, hex2_edges );
843 MB_CHK_ERR(rval);
844
845 // test adjacences from dim to 3
846 for (int dim = 0; dim < 3; ++dim) {
847 std::vector<EntityHandle> hex1_ent, hex2_ent, shared;
848 const EntityHandle *list1, *list2;
849 int n;
850 switch (dim) {
851 case 0:
852 rval = mb->get_connectivity( hexes[0], list1, n );
853 MB_CHK_ERR(rval);
854 rval = mb->get_connectivity( hexes[1], list2, n );
855 MB_CHK_ERR(rval);
856 break;
857 case 1:
858 list1 = hex1_edges;
859 list2 = hex2_edges;
860 n = 12;
861 break;
862 case 2:
863 list1 = hex1_faces;
864 list2 = hex2_faces;
865 n = 6;
866 break;
867 }
868 // split entities into those uniquely in hex1, those uniquely in hex2
869 // and those shared between the two
870 for (int i = 0; i < n; ++i) {
871 if (std::find(list2, list2+n, list1[i]) - list2 == n)
872 hex1_ent.push_back(list1[i]);
873 else
874 shared.push_back(list1[i]);
875 if (std::find(list1, list1+n, list2[i]) - list1 == n)
876 hex2_ent.push_back(list2[i]);
877 }
878 // for each shared entity check that get_adjacencies returns both hexes
879 for (size_t j = 0; j < shared.size(); ++j) {
880 std::vector<EntityHandle> adj;
881 rval = mb->get_adjacencies( &shared[j], 1, 3, false, adj );
882 MB_CHK_ERR(rval);
883 if (adj.size() != 2) {
884 std::cout << "Expected 2 hexes adjacent to " << dim << "D entity " << j
885 << ". Got " << adj.size() << " hexes." << std::endl;
886 return MB_FAILURE;
887 }
888 if (!(adj[0] == hexes[0] && adj[1] == hexes[1]) &&
889 !(adj[0] == hexes[1] && adj[1] == hexes[0])) {
890 std::cout << "Got incorrect hexes adjacent to " << dim << "D entity " << j << std::endl;
891 return MB_FAILURE;
892 }
893 }
894
895 for (size_t j = 0; j < hex1_ent.size(); ++j) {
896 std::vector<EntityHandle> adj;
897 rval = mb->get_adjacencies( &hex1_ent[j], 1, 3, false, adj );
898 MB_CHK_ERR(rval);
899 CHECK(adj.size() == 1 && adj[0] == hexes[0]);
900 }
901
902 for (size_t j = 0; j < hex2_ent.size(); ++j) {
903 std::vector<EntityHandle> adj;
904 rval = mb->get_adjacencies( &hex2_ent[j], 1, 3, false, adj );
905 MB_CHK_ERR(rval);
906 CHECK(adj.size() == 1 && adj[0] == hexes[1]);
907 }
908 }
909
910 // For each edge, get adjacent faces, and for each face
911 // get adjacent hexes. Result should be the same as
912 // direct query from edges to hexes
913 std::vector<EntityHandle> all_edges(24);
914 std::copy( hex1_edges, hex1_edges+12, all_edges.begin() );
915 std::copy( hex2_edges, hex2_edges+12, all_edges.begin()+12 );
916 std::sort( all_edges.begin(), all_edges.end() );
917 all_edges.erase( std::unique(all_edges.begin(), all_edges.end()), all_edges.end() );
918 for (size_t j = 0; j < all_edges.size(); ++j) {
919 std::vector<EntityHandle> edge_hexes, edge_faces, face_hexes;
920 rval = mb->get_adjacencies( &all_edges[j], 1, 3, false, edge_hexes );
921 MB_CHK_ERR(rval);
922 rval = mb->get_adjacencies( &all_edges[j], 1, 2, false, edge_faces );
923 MB_CHK_ERR(rval);
924 rval = mb->get_adjacencies( &edge_faces[0], edge_faces.size(), 3,
925 false, face_hexes, Interface::UNION );
926 MB_CHK_ERR(rval);
927 if (edge_hexes.size() != face_hexes.size()) {
928 std::cout << "Inconsistent adjacency data for edge " << j
929 << ". edge->face->hex resulted in " << face_hexes.size()
930 << "hexes while edge->hex resulted in " << edge_hexes.size()
931 << std::endl;
932 return MB_FAILURE;
933 }
934 switch (edge_hexes.size()) {
935 case 1:
936 CHECK(edge_hexes[0] == face_hexes[0]);
937 break;
938 case 2:
939 CHECK((edge_hexes[0] == face_hexes[0] && edge_hexes[1] == face_hexes[1]) ||
940 (edge_hexes[0] == face_hexes[1] && edge_hexes[1] == face_hexes[0]));
941 break;
942 default:
943 std::cout << "Got " << edge_hexes.size() << " hexes adjacent to edge " << j << std::endl;
944 return MB_FAILURE;
945 }
946 }
947 return MB_SUCCESS;
948 }
949
mb_adjacent_create_test()950 ErrorCode mb_adjacent_create_test()
951 {
952 Core moab;
953 Interface& mb = moab;
954 ErrorCode rval;
955
956 // create vertices
957 const double coords[][3] =
958 { {-0.5, -0.5, 0.5 },
959 {-0.5, -0.5, -0.5 },
960 {-0.5, 0.5, -0.5 },
961 {-0.5, 0.5, 0.5 },
962 { 0.5, -0.5, 0.5 },
963 { 0.5, -0.5, -0.5 },
964 { 0.5, 0.5, -0.5 },
965 { 0.5, 0.5, 0.5 } };
966 EntityHandle verts[8] = {0};
967 for (int i = 0; i < 8; ++i) {
968 rval = mb.create_vertex( coords[i], verts[i] );
969 MB_CHK_ERR(rval);
970 }
971 // create a single hex
972 const EntityHandle hconn[8] = { verts[0], verts[1], verts[2], verts[3],
973 verts[4], verts[5], verts[6], verts[7] };
974 EntityHandle hex;
975 rval = mb.create_element( MBHEX, hconn, 8, hex );
976 MB_CHK_ERR(rval);
977 // create hex faces
978 std::vector<EntityHandle> quads;
979 rval = mb.get_adjacencies( &hex, 1, 2, true, quads, Interface::UNION );
980 MB_CHK_ERR(rval);
981 CHECK_EQUAL( (size_t)6, quads.size() );
982 // check that we got each of the 6 expected faces, with outwards
983 // normals assuming CCW order and correct connectivity
984 const EntityHandle faces[6][4] = {
985 { verts[0], verts[1], verts[5], verts[4] },
986 { verts[1], verts[2], verts[6], verts[5] },
987 { verts[2], verts[3], verts[7], verts[6] },
988 { verts[3], verts[0], verts[4], verts[7] },
989 { verts[3], verts[2], verts[1], verts[0] },
990 { verts[4], verts[5], verts[6], verts[7] } };
991 for (int i = 0; i < 6; ++i) { // for each expected face
992 // get sorted list of verts first for easy comparison
993 std::vector<EntityHandle> exp_sorted(4);
994 std::copy( faces[i], faces[i]+4, exp_sorted.begin() );
995 std::sort( exp_sorted.begin(), exp_sorted.end() );
996 // search for matching face in output
997 int j = 0;
998 std::vector<EntityHandle> conn;
999 for (; j < 6; ++j) {
1000 conn.clear();
1001 rval = mb.get_connectivity( &quads[j], 1, conn );
1002 MB_CHK_ERR(rval);
1003 CHECK_EQUAL( (size_t)4, conn.size() );
1004 std::vector<EntityHandle> sorted(conn);
1005 std::sort( sorted.begin(), sorted.end() );
1006 if (sorted == exp_sorted)
1007 break;
1008 }
1009 if (j == 6) {
1010 std::cerr << "No adjacent face matching hex face " << i << std::endl;
1011 CHECK(j<6);
1012 }
1013 // check order
1014 int k = std::find( conn.begin(), conn.end(), faces[i][0] ) - conn.begin();
1015 for (j = 1; j < 4; ++j)
1016 if (faces[i][j] != conn[(j+k)%4])
1017 break;
1018 if (j != 4) {
1019 std::cerr << "Incorrect vertex order for hex face " << i << std::endl;
1020 std::cerr << "Expected: " << faces[i][0] << ", " << faces[i][1] << ", "
1021 << faces[i][2] << ", " << faces[i][3] << std::endl;
1022 std::cerr << "Actual: " << conn[0] << ", " << conn[1] << ", "
1023 << conn[2] << ", " << conn[3] << std::endl;
1024 CHECK(false);
1025 }
1026 }
1027 return MB_SUCCESS;
1028 }
1029
nothing_but_type(Range & range,EntityType type)1030 ErrorCode nothing_but_type( Range& range, EntityType type )
1031 {
1032
1033 //make sure there's nothing but hexes in hex_ms
1034 Range::iterator iter, end_iter;
1035 iter = range.begin();
1036 end_iter = range.end();
1037
1038 for(; iter != end_iter; ++iter)
1039 {
1040 if( TYPE_FROM_HANDLE(*iter) != type )
1041 {
1042 return MB_FAILURE;
1043 }
1044 }
1045 return MB_SUCCESS;
1046 }
1047
check_esets(Interface * MB,const int num_sets)1048 ErrorCode check_esets(Interface * MB, const int num_sets)
1049 {
1050 int entity_sets_size;
1051 ErrorCode result = MB->get_number_entities_by_type(0, MBENTITYSET, entity_sets_size);
1052 if (MB_SUCCESS != result ||
1053 entity_sets_size != num_sets) return MB_FAILURE;
1054
1055 return MB_SUCCESS;
1056 }
1057
mb_mesh_sets_test(int flags)1058 ErrorCode mb_mesh_sets_test(int flags)
1059 {
1060 Core moab;
1061 Interface* MB = &moab;
1062 ErrorCode result = create_some_mesh( MB );
1063 if (MB_SUCCESS != result)
1064 return result;
1065
1066 Range temp_range;
1067 std::vector<EntityHandle> temp_vector;
1068 EntityType ent_type;
1069
1070 EntityHandle ms_array[MBENTITYSET] = {0};
1071 unsigned int number_array[MBENTITYSET] = {0};
1072 unsigned int num_dim_array[4] = { 0, 0, 0, 0 };
1073 int count, start_num_sets;
1074
1075 result = MB->get_number_entities_by_type(0, MBENTITYSET, start_num_sets);
1076 if (MB_SUCCESS != result) return result;
1077
1078 //add entities to meshsets
1079 for (ent_type = MBEDGE; ent_type != MBENTITYSET; ent_type++)
1080 {
1081 result = MB->create_meshset( flags, ms_array[ent_type] );
1082 if( result != MB_SUCCESS )
1083 return result;
1084
1085 temp_range.clear();
1086 result = MB->get_entities_by_type(0, ent_type, temp_range );
1087 if( result != MB_SUCCESS )
1088 return result;
1089 result = MB->get_number_entities_by_type(0, ent_type, count);
1090 if (result != MB_SUCCESS)
1091 return result;
1092 if ((unsigned)count != temp_range.size())
1093 return MB_FAILURE;
1094 result = MB->add_entities( ms_array[ent_type], temp_range);
1095 if( result != MB_SUCCESS )
1096 return result;
1097
1098 number_array[ent_type] = temp_range.size(); //KGM
1099 num_dim_array[CN::Dimension(ent_type)] += count;
1100
1101 //Check to make sure mesh set really has correct number of entities in it
1102 temp_range.clear();
1103 temp_vector.clear();
1104 result = MB->get_entities_by_handle(ms_array[ent_type], temp_range);
1105 if(result != MB_SUCCESS)
1106 return result;
1107 if(number_array[ent_type] != temp_range.size())
1108 {
1109 cout<<"Number of entities in meshset test is not correct"<<endl;
1110 return MB_FAILURE;
1111 }
1112 if (!temp_range.all_of_type( ent_type ))
1113 return MB_FAILURE;
1114
1115 result = MB->get_entities_by_handle(ms_array[ent_type], temp_vector);
1116 if(result != MB_SUCCESS)
1117 return result;
1118 if(number_array[ent_type] != temp_vector.size())
1119 {
1120 cout<<"Number of entities in meshset test is not correct"<<endl;
1121 return MB_FAILURE;
1122 }
1123
1124 temp_range.clear();
1125 result = MB->get_entities_by_type( ms_array[ent_type], ent_type, temp_range);
1126 if(result != MB_SUCCESS)
1127 return result;
1128 if(number_array[ent_type] != temp_range.size())
1129 {
1130 cout<<"Number of entities by type in meshset test is not correct"<<endl;
1131 return MB_FAILURE;
1132 }
1133 if (!temp_range.all_of_type( ent_type ))
1134 return MB_FAILURE;
1135
1136 temp_range.clear();
1137 result = MB->get_entities_by_type( ms_array[ent_type], MBVERTEX, temp_range);
1138 if(result != MB_SUCCESS)
1139 return result;
1140 if(0 != temp_range.size())
1141 return MB_FAILURE;
1142
1143 temp_range.clear();
1144 result = MB->get_entities_by_dimension( ms_array[ent_type], CN::Dimension(ent_type), temp_range);
1145 if(result != MB_SUCCESS)
1146 return result;
1147 if(number_array[ent_type] != temp_range.size())
1148 {
1149 cout<<"Number of entities by dimension in meshset test is not correct"<<endl;
1150 return MB_FAILURE;
1151 }
1152 if (!temp_range.all_of_type( ent_type ))
1153 return MB_FAILURE;
1154
1155 temp_range.clear();
1156 result = MB->get_entities_by_dimension( ms_array[ent_type], 0, temp_range);
1157 if(result != MB_SUCCESS)
1158 return result;
1159 if(0 != temp_range.size())
1160 {
1161 cout<<"Number of entities by dimension in meshset test is not correct"<<endl;
1162 return MB_FAILURE;
1163 }
1164
1165 result = MB->get_number_entities_by_handle( ms_array[ent_type], count );
1166 if (result != MB_SUCCESS)
1167 return result;
1168 if ((unsigned)count != number_array[ent_type])
1169 return MB_FAILURE;
1170
1171 result = MB->get_number_entities_by_type( ms_array[ent_type], ent_type, count );
1172 if (result != MB_SUCCESS)
1173 return result;
1174 if ((unsigned)count != number_array[ent_type])
1175 return MB_FAILURE;
1176
1177 result = MB->get_number_entities_by_type( ms_array[ent_type], MBVERTEX, count );
1178 if (result != MB_SUCCESS)
1179 return result;
1180 if (count != 0)
1181 return MB_FAILURE;
1182
1183 result = MB->get_number_entities_by_dimension( ms_array[ent_type], CN::Dimension(ent_type), count );
1184 if (result != MB_SUCCESS)
1185 return result;
1186 if ((unsigned)count != number_array[ent_type])
1187 return MB_FAILURE;
1188
1189 result = MB->get_number_entities_by_dimension( ms_array[ent_type], 0, count );
1190 if (result != MB_SUCCESS)
1191 return result;
1192 if (count != 0)
1193 return MB_FAILURE;
1194 }
1195
1196 result = check_esets(MB, start_num_sets + MBENTITYSET - MBEDGE);
1197 if (MB_SUCCESS != result) return result;
1198
1199 for (int dim = 1; dim < 4; ++dim) {
1200 result = MB->get_number_entities_by_dimension( 0, dim, count );
1201 if (MB_SUCCESS != result)
1202 return MB_FAILURE;
1203 if ((unsigned)count != num_dim_array[dim])
1204 return MB_FAILURE;
1205 }
1206
1207 //----------TEST RECURSIVE OPERATIONS----------------//
1208 EntityHandle recursive1, recursive2;
1209 result = MB->create_meshset( MESHSET_SET, recursive1 );
1210 if( result != MB_SUCCESS )
1211 return result;
1212 result = MB->create_meshset( 0, recursive2 );
1213 if( result != MB_SUCCESS )
1214 return result;
1215 unsigned num_sets = MBENTITYSET-MBEDGE;
1216 result = MB->add_entities( recursive2, ms_array+MBEDGE, num_sets );
1217 if (MB_SUCCESS != result)
1218 return result;
1219 result = MB->add_entities( recursive1, &recursive2, 1 );
1220 if (MB_SUCCESS != result)
1221 return result;
1222
1223 temp_range.clear();
1224 result = MB->get_entities_by_type( recursive1, MBENTITYSET, temp_range );
1225 if (MB_SUCCESS != result)
1226 return result;
1227 if (temp_range.size() != 1 || *(temp_range.begin()) != recursive2)
1228 return MB_FAILURE;
1229
1230 temp_range.clear();
1231 result = MB->get_entities_by_type( recursive2, MBENTITYSET, temp_range );
1232 if (MB_SUCCESS != result)
1233 return result;
1234 if (temp_range.size() != num_sets || !temp_range.all_of_type(MBENTITYSET))
1235 return MB_FAILURE;
1236
1237 temp_range.clear();
1238 result = MB->get_entities_by_handle( recursive1, temp_range );
1239 if (MB_SUCCESS != result)
1240 return result;
1241 if (temp_range.size() != 1 || *(temp_range.begin()) != recursive2)
1242 return MB_FAILURE;
1243
1244 temp_range.clear();
1245 result = MB->get_entities_by_handle( recursive2, temp_range );
1246 if (MB_SUCCESS != result)
1247 return result;
1248 if (temp_range.size() != num_sets || !temp_range.all_of_type(MBENTITYSET))
1249 return MB_FAILURE;
1250
1251
1252 unsigned total = 0;
1253 for (ent_type = MBEDGE; ent_type != MBENTITYSET; ent_type++)
1254 {
1255 total += number_array[ent_type];
1256 temp_range.clear();
1257 result = MB->get_entities_by_type( recursive1, ent_type, temp_range, true );
1258 if(result != MB_SUCCESS)
1259 return result;
1260 if(number_array[ent_type] != temp_range.size())
1261 {
1262 cout<<"Recursive number of entities by type in meshset test is not correct"<<endl;
1263 return MB_FAILURE;
1264 }
1265 if (!temp_range.all_of_type( ent_type ))
1266 return MB_FAILURE;
1267 result = MB->get_number_entities_by_type( recursive1, ent_type, count, true );
1268 if(result != MB_SUCCESS)
1269 return result;
1270 if(number_array[ent_type] != (unsigned)count)
1271 {
1272 cout<<"Recursive number of entities by type in meshset test is not correct"<<endl;
1273 return MB_FAILURE;
1274 }
1275 if (!temp_range.all_of_type( ent_type ))
1276 return MB_FAILURE;
1277 }
1278 if (0 == total) {
1279 cout << "Invalid test input. No entities!" << endl;
1280 return MB_FAILURE;
1281 }
1282
1283 for (int dim = 1; dim < 4; ++dim) {
1284 temp_range.clear();
1285 result = MB->get_entities_by_dimension( recursive1, dim, temp_range, true );
1286 if (MB_SUCCESS != result)
1287 return MB_FAILURE;
1288 if (temp_range.size() != num_dim_array[dim])
1289 return MB_FAILURE;
1290 if (!temp_range.all_of_dimension(dim))
1291 return MB_FAILURE;
1292 result = MB->get_number_entities_by_dimension( recursive1, dim, count, true );
1293 if (MB_SUCCESS != result)
1294 return MB_FAILURE;
1295 if ((unsigned)count != num_dim_array[dim])
1296 return MB_FAILURE;
1297 }
1298
1299 temp_range.clear();
1300 result = MB->get_entities_by_handle( recursive1, temp_range, true );
1301 if(result != MB_SUCCESS)
1302 return result;
1303 if(total != temp_range.size())
1304 {
1305 cout<<"Recursive number of entities in meshset test is not correct"<<endl;
1306 return MB_FAILURE;
1307 }
1308
1309 // try circular relation
1310 result = MB->add_entities( recursive2, &recursive1, 1 );
1311 if (MB_SUCCESS != result) {
1312 std::cout << "Failed to create circular set containment" << std::endl;
1313 return result;
1314 }
1315 temp_range.clear();
1316 result = MB->get_entities_by_handle( recursive1, temp_range, true );
1317 if(result != MB_SUCCESS)
1318 return result;
1319 if(total != temp_range.size())
1320 {
1321 cout<<"Recursive number of entities in meshset test is not correct"<<endl;
1322 return MB_FAILURE;
1323 }
1324
1325 result = check_esets(MB, start_num_sets + MBENTITYSET - MBEDGE + 2);
1326 if (MB_SUCCESS != result) return result;
1327
1328 //----------TEST BOOLEAN OPERATIONS----------------//
1329
1330 EntityHandle temp_ms1, temp_ms2;
1331 result = MB->create_meshset(flags, temp_ms1);
1332 if(result != MB_SUCCESS )
1333 return result;
1334 result = MB->create_meshset(flags, temp_ms2);
1335 if(result != MB_SUCCESS )
1336 return result;
1337
1338 //Subtract
1339 //add all edges and hexes of ms_array[MBHEX] and ms_array[MBEDGE] to temp_ms1
1340 //get all Edge entities
1341 temp_range.clear();
1342 result = MB->get_entities_by_handle(ms_array[MBEDGE], temp_range );
1343 if(result != MB_SUCCESS )
1344 return result;
1345
1346 //add Edges to ms1
1347 result = MB->add_entities( temp_ms1, temp_range );
1348 if(result != MB_SUCCESS )
1349 return result;
1350
1351 temp_range.clear();
1352 result = MB->get_entities_by_handle(ms_array[MBHEX], temp_range );
1353 if(result != MB_SUCCESS )
1354 return result;
1355
1356 //add Hexes to ms1
1357 result = MB->add_entities( temp_ms1, temp_range );
1358 if(result != MB_SUCCESS )
1359 return result;
1360
1361
1362 //subtract bars meshset out of hex meshset
1363 result = MB->subtract_meshset( temp_ms1, ms_array[MBEDGE]);
1364 if(result != MB_SUCCESS )
1365 return result;
1366
1367 //Perform the check
1368 temp_range.clear();
1369 result = MB->get_entities_by_handle(temp_ms1, temp_range );
1370 if(result != MB_SUCCESS )
1371 return result;
1372
1373 if(number_array[MBHEX] != temp_range.size())
1374 {
1375 cout<<"MBset subtraction is bad"<<endl;
1376 return MB_FAILURE;
1377 }
1378 //make sure there's nothing but hexes in hex_ms
1379 if( nothing_but_type( temp_range, MBHEX ) != MB_SUCCESS )
1380 return MB_FAILURE;
1381
1382 result = check_esets(MB, start_num_sets + MBENTITYSET - MBEDGE + 4);
1383 if (MB_SUCCESS != result) return result;
1384
1385 //------------Intersect------------
1386 //
1387 //clean out the temp_ms1
1388 MB->clear_meshset(&temp_ms1, 1);
1389
1390 temp_range.clear();
1391 //get all quad entities
1392 temp_range.clear();
1393 result = MB->get_entities_by_handle(ms_array[MBQUAD], temp_range );
1394 if(result != MB_SUCCESS )
1395 return result;
1396
1397
1398 //add tets them to ms1
1399 result = MB->add_entities( temp_ms1, temp_range ) ;
1400 if(result != MB_SUCCESS )
1401 return result;
1402
1403 //get all tet entities
1404 temp_range.clear();
1405 result = MB->get_entities_by_handle(ms_array[MBTET], temp_range );
1406 if(result != MB_SUCCESS )
1407 return result;
1408
1409
1410 //add tets them to ms1
1411 result = MB->add_entities( temp_ms1, temp_range ) ;
1412 if(result != MB_SUCCESS )
1413 return result;
1414
1415 //intersect temp_ms1 (which contains all quads and tets) with tet meshset
1416 //temp_ms1 meshset is altered
1417 result = MB->intersect_meshset(temp_ms1, ms_array[MBTET]) ;
1418 if(result != MB_SUCCESS )
1419 return result;
1420
1421 //Perform the check, only tets should be in temp_ms1
1422 temp_range.clear();
1423 result = MB->get_entities_by_handle(temp_ms1, temp_range );
1424 if(result != MB_SUCCESS )
1425 return result;
1426 if(number_array[MBTET] != temp_range.size())
1427 {
1428 cout<<"MBset intersection is bad"<<endl;
1429 return MB_FAILURE;
1430 }
1431
1432 //make sure there's nothing but tet in range
1433 if( nothing_but_type( temp_range, MBTET ) != MB_SUCCESS )
1434 return MB_FAILURE;
1435
1436 result = check_esets(MB, start_num_sets + MBENTITYSET - MBEDGE + 4);
1437 if (MB_SUCCESS != result) return result;
1438
1439 //-------------Unite--------------
1440 //fill temp_ms1 with tets and tris
1441 //get all tris
1442 temp_range.clear();
1443 result = MB->get_entities_by_handle(ms_array[MBTRI], temp_range );
1444 if(result != MB_SUCCESS )
1445 return result;
1446
1447 //add tets them to ms1
1448 result = MB->add_entities( temp_ms1, temp_range ) ;
1449 if(result != MB_SUCCESS )
1450 return result;
1451
1452 temp_range.clear();
1453 result = MB->get_entities_by_handle(ms_array[MBTET], temp_range );
1454 if(result != MB_SUCCESS )
1455 return result;
1456
1457 //add tets them to ms1
1458 result = MB->add_entities( temp_ms1, temp_range ) ;
1459 if(result != MB_SUCCESS )
1460 return result;
1461
1462
1463 //fill temp_ms2 with tris and hexes
1464 temp_range.clear();
1465 result = MB->get_entities_by_handle(ms_array[MBTRI], temp_range );
1466 if(result != MB_SUCCESS )
1467 return result;
1468
1469 //add tets them to ms1
1470 result = MB->add_entities( temp_ms2, temp_range ) ;
1471 if(result != MB_SUCCESS )
1472 return result;
1473
1474 temp_range.clear();
1475 result = MB->get_entities_by_handle(ms_array[MBQUAD], temp_range );
1476 if(result != MB_SUCCESS )
1477 return result;
1478
1479 //add tets them to ms1
1480 result = MB->add_entities( temp_ms2, temp_range ) ;
1481 if(result != MB_SUCCESS )
1482 return result;
1483
1484
1485 //temp_ms1 is now filled with tets and tris
1486 //temp_ms2 is now filled with quads and tris
1487 int size1 = 0, size2 = 0;
1488 result = MB->get_number_entities_by_handle(ms_array[MBTRI], size1 ) ;
1489 if(result != MB_SUCCESS )
1490 return result;
1491
1492 result = MB->intersect_meshset(temp_ms1, temp_ms2 ) ;
1493 if(result != MB_SUCCESS )
1494 return result;
1495 result = MB->get_number_entities_by_handle(temp_ms1, size2 ) ;
1496 if(result != MB_SUCCESS )
1497 return result;
1498
1499 if(size1 != size2)
1500 {
1501 return MB_FAILURE;
1502 }
1503
1504 temp_range.clear();
1505 result = MB->get_entities_by_handle(temp_ms1, temp_range );
1506 if(result != MB_SUCCESS )
1507 return result;
1508
1509 //make sure there's nothing but tris in temp_range
1510 if( nothing_but_type( temp_range, MBTRI ) != MB_SUCCESS)
1511 return MB_FAILURE;
1512
1513
1514 result = check_esets(MB, start_num_sets + MBENTITYSET - MBEDGE + 4);
1515 if (MB_SUCCESS != result) return result;
1516
1517 //-------------Misc tests--------------
1518 EntityHandle temp_ms3;
1519 result = MB->create_meshset(flags, temp_ms3);
1520 if(result != MB_SUCCESS )
1521 return result;
1522
1523 EntityHandle handle_array[] = {1, 2, 3, 4, 5, 7, 8, 9, 10};
1524 const int num_handle = sizeof(handle_array)/sizeof(handle_array[0]);
1525 //add ents to set
1526 result = MB->add_entities( temp_ms3, handle_array, num_handle );
1527 if(result != MB_SUCCESS )
1528 return result;
1529
1530 // try adding again
1531 result = MB->add_entities( temp_ms3, handle_array, num_handle );
1532 if(result != MB_SUCCESS )
1533 return result;
1534
1535 int num_ents;
1536 result = MB->get_number_entities_by_handle(temp_ms3, num_ents);
1537 if(result != MB_SUCCESS )
1538 return result;
1539
1540 int num_expected = (flags & MESHSET_SET) ? num_handle : 2*num_handle;
1541 if (num_ents != num_expected)
1542 return MB_FAILURE;
1543
1544 return MB_SUCCESS;
1545 }
1546
compare_lists(std::vector<EntityHandle> vect,const EntityHandle * array,int count,bool ordered=true)1547 static bool compare_lists( std::vector<EntityHandle> vect,
1548 const EntityHandle* array,
1549 int count,
1550 bool ordered = true )
1551 {
1552 if (vect.size() != (size_t)count)
1553 return false;
1554 for (int i = 0; i < count; ++i) {
1555 if (ordered) {
1556 if (vect[i] != array[i])
1557 return false;
1558 }
1559 else if (std::find(vect.begin(),vect.end(),array[i]) == vect.end())
1560 return false;
1561 }
1562 return true;
1563 }
1564
1565 //Test parent/child stuff in meshsets
mb_mesh_set_parent_child_test()1566 ErrorCode mb_mesh_set_parent_child_test()
1567 {
1568 Core moab;
1569 Interface *MB = &moab;
1570
1571 ErrorCode rval;
1572 std::vector<EntityHandle> list;
1573 Range range;
1574 Range::iterator iter;
1575 int count;
1576
1577 // create a few mesh sets
1578 const int num_sets = 10;
1579 EntityHandle sets[num_sets];
1580 for (int i = 0; i < num_sets; ++i) {
1581 rval = MB->create_meshset( i % 2 ? MESHSET_SET : 0, sets[i] );
1582 if (MB_SUCCESS != rval)
1583 return rval;
1584 }
1585
1586 // test adding child meshsets
1587
1588 // add first child
1589 rval = MB->add_child_meshset( sets[0], sets[1] );
1590 if (MB_SUCCESS != rval) return rval;
1591 list.clear();
1592 rval = MB->get_child_meshsets( sets[0], list );
1593 if (MB_SUCCESS != rval) return rval;
1594 if (!compare_lists( list, sets+1, 1 ))
1595 return MB_FAILURE;
1596 // try to add child again
1597 rval = MB->add_child_meshset( sets[0], sets[1] );
1598 if (MB_SUCCESS != rval) return rval;
1599 list.clear();
1600 rval = MB->get_child_meshsets( sets[0], list );
1601 if (MB_SUCCESS != rval) return rval;
1602 if (!compare_lists( list, sets+1, 1 ))
1603 return MB_FAILURE;
1604
1605 // add second child
1606 rval = MB->add_child_meshset( sets[0], sets[2] );
1607 if (MB_SUCCESS != rval) return rval;
1608 list.clear();
1609 rval = MB->get_child_meshsets( sets[0], list );
1610 if (MB_SUCCESS != rval) return rval;
1611 if (!compare_lists( list, sets+1, 2 ))
1612 return MB_FAILURE;
1613 // try adding child again
1614 rval = MB->add_child_meshset( sets[0], sets[1] );
1615 if (MB_SUCCESS != rval) return rval;
1616 list.clear();
1617 rval = MB->get_child_meshsets( sets[0], list );
1618 if (MB_SUCCESS != rval) return rval;
1619 if (!compare_lists( list, sets+1, 2 ))
1620 return MB_FAILURE;
1621
1622 // add third child
1623 rval = MB->add_child_meshset( sets[0], sets[3] );
1624 if (MB_SUCCESS != rval) return rval;
1625 list.clear();
1626 rval = MB->get_child_meshsets( sets[0], list );
1627 if (MB_SUCCESS != rval) return rval;
1628 if (!compare_lists( list, sets+1, 3 ))
1629 return MB_FAILURE;
1630 // try adding child again
1631 rval = MB->add_child_meshset( sets[0], sets[1] );
1632 if (MB_SUCCESS != rval) return rval;
1633 list.clear();
1634 rval = MB->get_child_meshsets( sets[0], list );
1635 if (MB_SUCCESS != rval) return rval;
1636 if (!compare_lists( list, sets+1, 3 ))
1637 return MB_FAILURE;
1638
1639 // add fourth child
1640 rval = MB->add_child_meshset( sets[0], sets[4] );
1641 if (MB_SUCCESS != rval) return rval;
1642 list.clear();
1643 rval = MB->get_child_meshsets( sets[0], list );
1644 if (MB_SUCCESS != rval) return rval;
1645 if (!compare_lists( list, sets+1, 4 ))
1646 return MB_FAILURE;
1647
1648 // make sure range query returns same result
1649 std::sort( list.begin(), list.end() );
1650 rval = MB->get_child_meshsets( sets[0], range );
1651 iter = range.begin();
1652 for (unsigned i = 0; i < 4; ++i, ++iter)
1653 if (*iter != list[i])
1654 return MB_FAILURE;
1655
1656 // remove first child
1657 rval = MB->remove_child_meshset( sets[0], sets[1] );
1658 if (MB_SUCCESS != rval) return rval;
1659 list.clear();
1660 rval = MB->get_child_meshsets( sets[0], list );
1661 if (MB_SUCCESS != rval) return rval;
1662 if (!compare_lists( list, sets+2, 3 ))
1663 return MB_FAILURE;
1664 // try removing child again
1665 rval = MB->remove_child_meshset( sets[0], sets[1] );
1666 if (MB_SUCCESS != rval) return rval;
1667
1668 // remove second child
1669 rval = MB->remove_child_meshset( sets[0], sets[2] );
1670 if (MB_SUCCESS != rval) return rval;
1671 list.clear();
1672 rval = MB->get_child_meshsets( sets[0], list );
1673 if (!compare_lists( list, sets+3, 2 ))
1674 return MB_FAILURE;
1675 // try removing child again
1676 rval = MB->remove_child_meshset( sets[0], sets[2] );
1677 if (MB_SUCCESS != rval) return rval;
1678
1679 // remove third child
1680 rval = MB->remove_child_meshset( sets[0], sets[3] );
1681 if (MB_SUCCESS != rval) return rval;
1682 list.clear();
1683 rval = MB->get_child_meshsets( sets[0], list );
1684 if (list.size() != 1 || list[0] != sets[4])
1685 return MB_FAILURE;
1686
1687 // remove fourth child
1688 rval = MB->remove_child_meshset( sets[0], sets[4] );
1689 if (MB_SUCCESS != rval) return rval;
1690 list.clear();
1691 rval = MB->get_child_meshsets( sets[0], list );
1692 if (!list.empty())
1693 return MB_FAILURE;
1694
1695
1696 // test adding parent meshsets
1697
1698 // add first parent
1699 rval = MB->add_parent_meshset( sets[0], sets[1] );
1700 if (MB_SUCCESS != rval) return rval;
1701 list.clear();
1702 rval = MB->get_parent_meshsets( sets[0], list );
1703 if (MB_SUCCESS != rval) return rval;
1704 if (!compare_lists( list, sets+1, 1 ))
1705 return MB_FAILURE;
1706 // try to add parent again
1707 rval = MB->add_parent_meshset( sets[0], sets[1] );
1708 if (MB_SUCCESS != rval) return rval;
1709 list.clear();
1710 rval = MB->get_parent_meshsets( sets[0], list );
1711 if (MB_SUCCESS != rval) return rval;
1712 if (!compare_lists( list, sets+1, 1 ))
1713 return MB_FAILURE;
1714
1715 // add second parent
1716 rval = MB->add_parent_meshset( sets[0], sets[2] );
1717 if (MB_SUCCESS != rval) return rval;
1718 list.clear();
1719 rval = MB->get_parent_meshsets( sets[0], list );
1720 if (MB_SUCCESS != rval) return rval;
1721 if (!compare_lists( list, sets+1, 2 ))
1722 return MB_FAILURE;
1723 // try adding parent again
1724 rval = MB->add_parent_meshset( sets[0], sets[1] );
1725 if (MB_SUCCESS != rval) return rval;
1726 list.clear();
1727 rval = MB->get_parent_meshsets( sets[0], list );
1728 if (MB_SUCCESS != rval) return rval;
1729 if (!compare_lists( list, sets+1, 2 ))
1730 return MB_FAILURE;
1731
1732 // add third parent
1733 rval = MB->add_parent_meshset( sets[0], sets[3] );
1734 if (MB_SUCCESS != rval) return rval;
1735 list.clear();
1736 rval = MB->get_parent_meshsets( sets[0], list );
1737 if (MB_SUCCESS != rval) return rval;
1738 if (!compare_lists( list, sets+1, 3 ))
1739 return MB_FAILURE;
1740 // try adding parent again
1741 rval = MB->add_parent_meshset( sets[0], sets[1] );
1742 if (MB_SUCCESS != rval) return rval;
1743 list.clear();
1744 rval = MB->get_parent_meshsets( sets[0], list );
1745 if (MB_SUCCESS != rval) return rval;
1746 if (!compare_lists( list, sets+1, 3 ))
1747 return MB_FAILURE;
1748
1749 // add fourth parent
1750 rval = MB->add_parent_meshset( sets[0], sets[4] );
1751 if (MB_SUCCESS != rval) return rval;
1752 list.clear();
1753 rval = MB->get_parent_meshsets( sets[0], list );
1754 if (MB_SUCCESS != rval) return rval;
1755 if (!compare_lists( list, sets+1, 4 ))
1756 return MB_FAILURE;
1757
1758 // make sure range query returns same result
1759 std::sort( list.begin(), list.end() );
1760 rval = MB->get_parent_meshsets( sets[0], range );
1761 iter = range.begin();
1762 for (unsigned i = 0; i < 4; ++i, ++iter)
1763 if (*iter != list[i])
1764 return MB_FAILURE;
1765
1766 // remove first parent
1767 rval = MB->remove_parent_meshset( sets[0], sets[1] );
1768 if (MB_SUCCESS != rval) return rval;
1769 list.clear();
1770 rval = MB->get_parent_meshsets( sets[0], list );
1771 if (MB_SUCCESS != rval) return rval;
1772 if (!compare_lists( list, sets+2, 3 ))
1773 return MB_FAILURE;
1774 // try removing parent again
1775 rval = MB->remove_parent_meshset( sets[0], sets[1] );
1776 if (MB_SUCCESS != rval) return rval;
1777
1778 // remove second parent
1779 rval = MB->remove_parent_meshset( sets[0], sets[2] );
1780 if (MB_SUCCESS != rval) return rval;
1781 list.clear();
1782 rval = MB->get_parent_meshsets( sets[0], list );
1783 if (!compare_lists( list, sets+3, 2 ))
1784 return MB_FAILURE;
1785 // try removing parent again
1786 rval = MB->remove_parent_meshset( sets[0], sets[2] );
1787 if (MB_SUCCESS != rval) return rval;
1788
1789 // remove third parent
1790 rval = MB->remove_parent_meshset( sets[0], sets[3] );
1791 if (MB_SUCCESS != rval) return rval;
1792 list.clear();
1793 rval = MB->get_parent_meshsets( sets[0], list );
1794 if (list.size() != 1 || list[0] != sets[4])
1795 return MB_FAILURE;
1796
1797 // remove fourth parent
1798 rval = MB->remove_parent_meshset( sets[0], sets[4] );
1799 if (MB_SUCCESS != rval) return rval;
1800 list.clear();
1801 rval = MB->get_parent_meshsets( sets[0], list );
1802 if (!list.empty())
1803 return MB_FAILURE;
1804
1805
1806 // setup tests of recursive child query
1807 // 0
1808 // / \ .
1809 // 1 2
1810 // / \ / \ .
1811 // 3 4 5
1812 // \ / \ /
1813 // 6 7
1814 rval = MB->add_child_meshset( sets[0], sets[1] );
1815 if (MB_SUCCESS != rval) return rval;
1816 rval = MB->add_child_meshset( sets[0], sets[2] );
1817 if (MB_SUCCESS != rval) return rval;
1818 rval = MB->add_child_meshset( sets[1], sets[3] );
1819 if (MB_SUCCESS != rval) return rval;
1820 rval = MB->add_child_meshset( sets[1], sets[4] );
1821 if (MB_SUCCESS != rval) return rval;
1822 rval = MB->add_child_meshset( sets[2], sets[4] );
1823 if (MB_SUCCESS != rval) return rval;
1824 rval = MB->add_child_meshset( sets[2], sets[5] );
1825 if (MB_SUCCESS != rval) return rval;
1826 rval = MB->add_child_meshset( sets[3], sets[6] );
1827 if (MB_SUCCESS != rval) return rval;
1828 rval = MB->add_child_meshset( sets[4], sets[6] );
1829 if (MB_SUCCESS != rval) return rval;
1830 rval = MB->add_child_meshset( sets[4], sets[7] );
1831 if (MB_SUCCESS != rval) return rval;
1832 rval = MB->add_child_meshset( sets[5], sets[7] );
1833 if (MB_SUCCESS != rval) return rval;
1834
1835 // test query at depth of 1
1836 list.clear();
1837 rval = MB->get_child_meshsets( sets[0], list, 1 );
1838 if (MB_SUCCESS != rval) return rval;
1839 if (list.size() != 2 || list[0] != sets[1] || list[1] != sets[2])
1840 return MB_FAILURE;
1841 rval = MB->num_child_meshsets( sets[0], &count, 1 );
1842 if (MB_SUCCESS != rval) return rval;
1843 if (count != 2)
1844 return MB_FAILURE;
1845
1846 // test query at depth of 2
1847 list.clear();
1848 rval = MB->get_child_meshsets( sets[0], list, 2 );
1849 if (MB_SUCCESS != rval) return rval;
1850 if (!compare_lists( list, sets+1, 5, false ))
1851 return MB_FAILURE;
1852 rval = MB->num_child_meshsets( sets[0], &count, 2 );
1853 if (MB_SUCCESS != rval) return rval;
1854 if (count != 5)
1855 return MB_FAILURE;
1856
1857 // test query at depth of 3
1858 list.clear();
1859 rval = MB->get_child_meshsets( sets[0], list, 3 );
1860 if (MB_SUCCESS != rval) return rval;
1861 if (!compare_lists( list, sets+1, 7, false ))
1862 return MB_FAILURE;
1863 rval = MB->num_child_meshsets( sets[0], &count, 3 );
1864 if (MB_SUCCESS != rval) return rval;
1865 if (count != 7)
1866 return MB_FAILURE;
1867
1868 // test query at depth of 4
1869 list.clear();
1870 rval = MB->get_child_meshsets( sets[0], list, 4 );
1871 if (MB_SUCCESS != rval) return rval;
1872 if (!compare_lists( list, sets+1, 7, false ))
1873 return MB_FAILURE;
1874 rval = MB->num_child_meshsets( sets[0], &count, 4 );
1875 if (MB_SUCCESS != rval) return rval;
1876 if (count != 7)
1877 return MB_FAILURE;
1878
1879 // test query at all
1880 list.clear();
1881 rval = MB->get_child_meshsets( sets[0], list, 0 );
1882 if (MB_SUCCESS != rval) return rval;
1883 if (!compare_lists( list, sets+1, 7, false ))
1884 return MB_FAILURE;
1885 rval = MB->num_child_meshsets( sets[0], &count, 0 );
1886 if (MB_SUCCESS != rval) return rval;
1887 if (count != 7)
1888 return MB_FAILURE;
1889
1890 // clean up child links
1891 rval = MB->remove_child_meshset( sets[0], sets[1] );
1892 if (MB_SUCCESS != rval) return rval;
1893 rval = MB->remove_child_meshset( sets[0], sets[2] );
1894 if (MB_SUCCESS != rval) return rval;
1895 rval = MB->remove_child_meshset( sets[1], sets[3] );
1896 if (MB_SUCCESS != rval) return rval;
1897 rval = MB->remove_child_meshset( sets[1], sets[4] );
1898 if (MB_SUCCESS != rval) return rval;
1899 rval = MB->remove_child_meshset( sets[2], sets[4] );
1900 if (MB_SUCCESS != rval) return rval;
1901 rval = MB->remove_child_meshset( sets[2], sets[5] );
1902 if (MB_SUCCESS != rval) return rval;
1903 rval = MB->remove_child_meshset( sets[3], sets[6] );
1904 if (MB_SUCCESS != rval) return rval;
1905 rval = MB->remove_child_meshset( sets[4], sets[6] );
1906 if (MB_SUCCESS != rval) return rval;
1907 rval = MB->remove_child_meshset( sets[4], sets[7] );
1908 if (MB_SUCCESS != rval) return rval;
1909 rval = MB->remove_child_meshset( sets[5], sets[7] );
1910 if (MB_SUCCESS != rval) return rval;
1911 for (int i = 0; i < 5; ++i)
1912 if (MB_SUCCESS != MB->num_child_meshsets(sets[i], &count) || count)
1913 return MB_FAILURE;
1914
1915 // setup tests of recursive parent query
1916 // 6 7
1917 // / \ / \ .
1918 // 3 4 5
1919 // \ / \ /
1920 // 1 2
1921 // \ /
1922 // 0
1923 rval = MB->add_parent_meshset( sets[0], sets[1] );
1924 if (MB_SUCCESS != rval) return rval;
1925 rval = MB->add_parent_meshset( sets[0], sets[2] );
1926 if (MB_SUCCESS != rval) return rval;
1927 rval = MB->add_parent_meshset( sets[1], sets[3] );
1928 if (MB_SUCCESS != rval) return rval;
1929 rval = MB->add_parent_meshset( sets[1], sets[4] );
1930 if (MB_SUCCESS != rval) return rval;
1931 rval = MB->add_parent_meshset( sets[2], sets[4] );
1932 if (MB_SUCCESS != rval) return rval;
1933 rval = MB->add_parent_meshset( sets[2], sets[5] );
1934 if (MB_SUCCESS != rval) return rval;
1935 rval = MB->add_parent_meshset( sets[3], sets[6] );
1936 if (MB_SUCCESS != rval) return rval;
1937 rval = MB->add_parent_meshset( sets[4], sets[6] );
1938 if (MB_SUCCESS != rval) return rval;
1939 rval = MB->add_parent_meshset( sets[4], sets[7] );
1940 if (MB_SUCCESS != rval) return rval;
1941 rval = MB->add_parent_meshset( sets[5], sets[7] );
1942 if (MB_SUCCESS != rval) return rval;
1943
1944 // test query at depth of 1
1945 list.clear();
1946 rval = MB->get_parent_meshsets( sets[0], list, 1 );
1947 if (MB_SUCCESS != rval) return rval;
1948 if (list.size() != 2 || list[0] != sets[1] || list[1] != sets[2])
1949 return MB_FAILURE;
1950 rval = MB->num_parent_meshsets( sets[0], &count, 1 );
1951 if (MB_SUCCESS != rval) return rval;
1952 if (count != 2)
1953 return MB_FAILURE;
1954
1955 // test query at depth of 2
1956 list.clear();
1957 rval = MB->get_parent_meshsets( sets[0], list, 2 );
1958 if (MB_SUCCESS != rval) return rval;
1959 if (!compare_lists( list, sets+1, 5, false ))
1960 return MB_FAILURE;
1961 rval = MB->num_parent_meshsets( sets[0], &count, 2 );
1962 if (MB_SUCCESS != rval) return rval;
1963 if (count != 5)
1964 return MB_FAILURE;
1965
1966 // test query at depth of 3
1967 list.clear();
1968 rval = MB->get_parent_meshsets( sets[0], list, 3 );
1969 if (MB_SUCCESS != rval) return rval;
1970 if (!compare_lists( list, sets+1, 7, false ))
1971 return MB_FAILURE;
1972 rval = MB->num_parent_meshsets( sets[0], &count, 3 );
1973 if (MB_SUCCESS != rval) return rval;
1974 if (count != 7)
1975 return MB_FAILURE;
1976
1977 // test query at depth of 4
1978 list.clear();
1979 rval = MB->get_parent_meshsets( sets[0], list, 4 );
1980 if (MB_SUCCESS != rval) return rval;
1981 if (!compare_lists( list, sets+1, 7, false ))
1982 return MB_FAILURE;
1983 rval = MB->num_parent_meshsets( sets[0], &count, 4 );
1984 if (MB_SUCCESS != rval) return rval;
1985 if (count != 7)
1986 return MB_FAILURE;
1987
1988 // test query at all
1989 list.clear();
1990 rval = MB->get_parent_meshsets( sets[0], list, 0 );
1991 if (MB_SUCCESS != rval) return rval;
1992 if (!compare_lists( list, sets+1, 7, false ))
1993 return MB_FAILURE;
1994 rval = MB->num_parent_meshsets( sets[0], &count, 0 );
1995 if (MB_SUCCESS != rval) return rval;
1996 if (count != 7)
1997 return MB_FAILURE;
1998
1999 // clean up parent links
2000 rval = MB->remove_parent_meshset( sets[0], sets[1] );
2001 if (MB_SUCCESS != rval) return rval;
2002 rval = MB->remove_parent_meshset( sets[0], sets[2] );
2003 if (MB_SUCCESS != rval) return rval;
2004 rval = MB->remove_parent_meshset( sets[1], sets[3] );
2005 if (MB_SUCCESS != rval) return rval;
2006 rval = MB->remove_parent_meshset( sets[1], sets[4] );
2007 if (MB_SUCCESS != rval) return rval;
2008 rval = MB->remove_parent_meshset( sets[2], sets[4] );
2009 if (MB_SUCCESS != rval) return rval;
2010 rval = MB->remove_parent_meshset( sets[2], sets[5] );
2011 if (MB_SUCCESS != rval) return rval;
2012 rval = MB->remove_parent_meshset( sets[3], sets[6] );
2013 if (MB_SUCCESS != rval) return rval;
2014 rval = MB->remove_parent_meshset( sets[4], sets[6] );
2015 if (MB_SUCCESS != rval) return rval;
2016 rval = MB->remove_parent_meshset( sets[4], sets[7] );
2017 if (MB_SUCCESS != rval) return rval;
2018 rval = MB->remove_parent_meshset( sets[5], sets[7] );
2019 if (MB_SUCCESS != rval) return rval;
2020 for (int i = 0; i < 5; ++i)
2021 if (MB_SUCCESS != MB->num_parent_meshsets(sets[i], &count) || count)
2022 return MB_FAILURE;
2023
2024
2025 // test combined parent/child links
2026
2027 // test creation
2028 rval = MB->add_parent_child( sets[9], sets[8] );
2029 if (MB_SUCCESS != rval) return rval;
2030 list.clear();
2031 rval = MB->get_child_meshsets( sets[9], list );
2032 if (MB_SUCCESS != rval) return rval;
2033 if (list.size() != 1 || list[0] != sets[8])
2034 return MB_FAILURE;
2035 list.clear();
2036 rval = MB->get_parent_meshsets( sets[8], list );
2037 if (MB_SUCCESS != rval) return rval;
2038 if (list.size() != 1 || list[0] != sets[9])
2039 return MB_FAILURE;
2040
2041 // test deletion of parent/child
2042 rval = MB->add_parent_child( sets[7], sets[9] );
2043 if (MB_SUCCESS != rval) return rval;
2044 rval = MB->delete_entities( &sets[9], 1 );
2045 if (MB_SUCCESS != rval) return rval;
2046 list.clear();
2047 rval = MB->get_parent_meshsets( sets[8], list );
2048 if (!list.empty())
2049 return MB_FAILURE;
2050 list.clear();
2051 rval = MB->get_child_meshsets( sets[7], list );
2052 if (!list.empty())
2053 return MB_FAILURE;
2054
2055 // clean up remaining sets
2056 return MB->delete_entities( sets, 9 );
2057 }
2058
mb_mesh_sets_set_test()2059 ErrorCode mb_mesh_sets_set_test()
2060 {
2061 return mb_mesh_sets_test( MESHSET_SET );
2062 }
2063
mb_mesh_sets_list_test()2064 ErrorCode mb_mesh_sets_list_test()
2065 {
2066 return mb_mesh_sets_test( MESHSET_ORDERED );
2067 }
2068
2069 // Verify that all query functions *append* to output Range
mb_mesh_set_appends(int flags)2070 ErrorCode mb_mesh_set_appends( int flags )
2071 {
2072 Core moab;
2073 Interface* mb = &moab;
2074 ErrorCode rval = create_some_mesh( mb );
2075 if (MB_SUCCESS != rval)
2076 return rval;
2077
2078 // get all handles and subdivide into vertex and non-vertex ents
2079 Range all_ents, verts, elems, results;
2080 rval = mb->get_entities_by_handle( 0, all_ents );
2081 if (MB_SUCCESS != rval)
2082 return rval;
2083 Range::iterator ve = all_ents.upper_bound( MBVERTEX );
2084 verts.merge( all_ents.begin(), ve );
2085 elems.merge( ve, all_ents.end() );
2086
2087 // If we're not testing queries from the root set,
2088 // create a set containing all the vertices
2089 EntityHandle set = 0;
2090 if (flags != -1) {
2091 rval = mb->create_meshset( flags, set );
2092 if (MB_SUCCESS != rval)
2093 return rval;
2094 rval = mb->add_entities( set, verts );
2095 if (MB_SUCCESS != rval)
2096 return rval;
2097 }
2098
2099 // Test get_entities_by_handle. This one doesn't make
2100 // much sense if we're testing the root set, but it doesn't
2101 // hurt to test it anyway.
2102 results = elems;
2103 rval = mb->get_entities_by_handle( set, results );
2104 if (MB_SUCCESS != rval)
2105 return rval;
2106 if (results != all_ents)
2107 return MB_FAILURE;
2108
2109 // Test get_entities_by_dimension
2110 results = elems;
2111 rval = mb->get_entities_by_dimension( set, 0, results );
2112 if (MB_SUCCESS != rval)
2113 return rval;
2114 if (results != all_ents)
2115 return MB_FAILURE;
2116
2117 // Test get_entities_by_type
2118 results = elems;
2119 rval = mb->get_entities_by_type( set, MBVERTEX, results );
2120 if (MB_SUCCESS != rval)
2121 return rval;
2122 if (results != all_ents)
2123 return MB_FAILURE;
2124
2125 // choose a single entity for testing tag queries
2126 EntityHandle entity = verts.front();
2127 Range expected( elems );
2128 expected.insert( entity );
2129
2130 Tag sparse, dense;
2131 const int zero = 0, one = 1;
2132 const void* vals[] = {&one};
2133
2134 // Test get_entities_by_type_and_tag w/ sparse tag and no value
2135 rval = mb->tag_get_handle( "mb_mesh_set_appends_sparse",
2136 1, MB_TYPE_INTEGER, sparse, MB_TAG_SPARSE|MB_TAG_EXCL );
2137 if (MB_SUCCESS != rval)
2138 return rval;
2139 rval = mb->tag_set_data( sparse, &entity, 1, &one );
2140 if (MB_SUCCESS != rval)
2141 return rval;
2142 results = elems;
2143 rval = mb->get_entities_by_type_and_tag( set,
2144 TYPE_FROM_HANDLE(entity),
2145 &sparse, 0, 1,
2146 results, Interface::UNION );
2147 if (MB_SUCCESS != rval)
2148 return rval;
2149 if (results != expected)
2150 return MB_FAILURE;
2151 // Test again, but specify tag value
2152 results = elems;
2153 rval = mb->get_entities_by_type_and_tag( set,
2154 TYPE_FROM_HANDLE(entity),
2155 &sparse, vals, 1,
2156 results, Interface::UNION );
2157 if (MB_SUCCESS != rval)
2158 return rval;
2159 if (results != expected)
2160 return MB_FAILURE;
2161
2162 // Test get_entities_by_type_and_tag w/ dense tag
2163 rval = mb->tag_get_handle( "mb_mesh_set_appends_dense",
2164 1, MB_TYPE_INTEGER, dense,
2165 MB_TAG_DENSE|MB_TAG_EXCL, &zero );
2166 if (MB_SUCCESS != rval)
2167 return rval;
2168 rval = mb->tag_set_data( dense, &entity, 1, &one );
2169 if (MB_SUCCESS != rval)
2170 return rval;
2171 results = elems;
2172 rval = mb->get_entities_by_type_and_tag( set,
2173 TYPE_FROM_HANDLE(entity),
2174 &dense, vals, 1,
2175 results, Interface::UNION );
2176 if (MB_SUCCESS != rval)
2177 return rval;
2178 if (results != expected)
2179 return MB_FAILURE;
2180
2181 return MB_SUCCESS;
2182 }
2183
mb_mesh_set_set_appends()2184 ErrorCode mb_mesh_set_set_appends()
2185 {
2186 return mb_mesh_set_appends( MESHSET_SET );
2187 }
2188
mb_mesh_set_list_appends()2189 ErrorCode mb_mesh_set_list_appends()
2190 {
2191 return mb_mesh_set_appends( MESHSET_ORDERED );
2192 }
2193
mb_mesh_set_root_appends()2194 ErrorCode mb_mesh_set_root_appends()
2195 {
2196 return mb_mesh_set_appends( -1 );
2197 }
2198
mb_mesh_set_set_replace_test()2199 ErrorCode mb_mesh_set_set_replace_test()
2200 {
2201 Core moab;
2202 Interface* mb = &moab;
2203 ErrorCode rval;
2204 Range r;
2205 // create 10 vertices to put in set
2206 std::vector<double> coords(30);
2207 rval = mb->create_vertices( &coords[0], 10, r );
2208 MB_CHK_ERR(rval);
2209 std::vector<EntityHandle> verts(r.size());
2210 std::copy( r.begin(), r.end(), verts.begin() );
2211 r.clear();
2212 // create a set
2213 EntityHandle set;
2214 rval = mb->create_meshset( MESHSET_SET, set );
2215 MB_CHK_ERR(rval);
2216 // put every other vertex in set
2217 for (size_t i = 0; i < 10; i += 2)
2218 r.insert( verts[i] );
2219 rval = mb->add_entities( set, r );
2220 MB_CHK_ERR(rval);
2221 r.clear();
2222 // swap 3 of the vertices
2223 EntityHandle old_ents[3] = { verts[2], verts[4], verts[6] };
2224 EntityHandle new_ents[3] = { verts[1], verts[9], verts[5] };
2225 rval = mb->replace_entities( set, old_ents, new_ents, 3 );
2226 MB_CHK_ERR(rval);
2227 // check new set contents
2228 rval = mb->get_entities_by_handle( set, r );
2229 MB_CHK_ERR(rval);
2230 Range r2;
2231 r2.insert( verts[0] );
2232 r2.insert( verts[1] );
2233 r2.insert( verts[9] );
2234 r2.insert( verts[5] );
2235 r2.insert( verts[8] );
2236 if (r != r2) {
2237 std::cerr << "Range does not contain expected values." << std::endl
2238 << " Expected: " << r2 << std::endl
2239 << " Actual : " << r << std::endl;
2240 return MB_FAILURE;
2241 }
2242
2243 return MB_SUCCESS;
2244 }
2245
mb_mesh_set_list_replace_test()2246 ErrorCode mb_mesh_set_list_replace_test()
2247 {
2248 Core moab;
2249 Interface* mb = &moab;
2250 ErrorCode rval;
2251 // create 10 vertices to put in set
2252 Range r;
2253 std::vector<double> coords(30);
2254 rval = mb->create_vertices( &coords[0], 10, r );
2255 MB_CHK_ERR(rval);
2256 std::vector<EntityHandle> verts(r.size());
2257 std::copy( r.begin(), r.end(), verts.begin() );
2258 r.clear();
2259 // create a set
2260 EntityHandle set;
2261 rval = mb->create_meshset( MESHSET_ORDERED, set );
2262 MB_CHK_ERR(rval);
2263 // put all vertices in set, but add the first one a second time
2264 std::vector<EntityHandle> list( verts );
2265 list.push_back( verts.front() );
2266 rval = mb->add_entities( set, &list[0], list.size() );MB_CHK_ERR(rval);
2267 // swap 3 of the vertices
2268 EntityHandle old_ents[3] = { verts[2], verts[4], verts[6] };
2269 EntityHandle new_ents[3] = { verts[1], verts[9], verts[5] };
2270 rval = mb->replace_entities( set, old_ents, new_ents, 3 );MB_CHK_ERR(rval);
2271 // check new set contents
2272 std::vector<EntityHandle> list2;
2273 rval = mb->get_entities_by_handle( set, list2 );
2274 MB_CHK_ERR(rval);
2275 list[2] = verts[1];
2276 list[4] = verts[9];
2277 list[6] = verts[5];
2278 if (list != list2) {
2279 std::cerr << "Range does not contain expected values." << std::endl;
2280 std::cerr << " Expected: ";
2281 std::copy( list.begin(), list.end(), std::ostream_iterator<EntityHandle>(std::cerr, " ") );
2282 std::cerr << std::endl << " Actual : ";
2283 std::copy( list2.begin(), list2.end(), std::ostream_iterator<EntityHandle>(std::cerr, " ") );
2284 std::cerr << std::endl;
2285 return MB_FAILURE;
2286 }
2287 // now try replacing a repeated value
2288 rval = mb->replace_entities( set, &verts[0], &verts[3], 1 );
2289 MB_CHK_ERR(rval);
2290 list[0] = list[10] = verts[3];
2291 list2.clear();
2292 rval = mb->get_entities_by_handle( set, list2 );
2293 MB_CHK_ERR(rval);
2294 if (list != list2) {
2295 std::cerr << "Range does not contain expected values." << std::endl;
2296 std::cerr << " Expected: ";
2297 std::copy( list.begin(), list.end(), std::ostream_iterator<EntityHandle>(std::cerr, " ") );
2298 std::cerr << std::endl << " Actual : ";
2299 std::copy( list2.begin(), list2.end(), std::ostream_iterator<EntityHandle>(std::cerr, " ") );
2300 std::cerr << std::endl;
2301 return MB_FAILURE;
2302 }
2303
2304 return MB_SUCCESS;
2305 }
2306
2307 /* Test the following changes to a meshset:
2308 set MB-> tracking
2309 tracking MB-> set
2310 unordered MB-> ordered
2311 ordered MB-> unordered
2312 */
mb_mesh_set_flag_test()2313 ErrorCode mb_mesh_set_flag_test()
2314 {
2315 Core moab;
2316 Interface* mb = &moab;
2317
2318 ErrorCode rval;
2319 // create 10 vertices to put in set
2320 Range verts;
2321 std::vector<double> coords(30);
2322 rval = mb->create_vertices( &coords[0], 10, verts );
2323 MB_CHK_ERR(rval);
2324
2325 // CHECK SET->TRACKING
2326 // create a set and add the verts
2327 EntityHandle set;
2328 rval = mb->create_meshset( MESHSET_SET, set );
2329 MB_CHK_ERR(rval);
2330 rval = mb->add_entities( set, verts);
2331 MB_CHK_ERR(rval);
2332 // the verts should not be tracking adjacencies
2333 Range adj_sets;
2334 rval = mb->get_adjacencies( verts, 4, false, adj_sets);
2335 MB_CHK_ERR(rval);
2336 if(!adj_sets.empty()) {
2337 std::cerr << "range should be empty but contains:" << std::endl;
2338 rval = mb->list_entities( adj_sets );
2339 return MB_FAILURE;
2340 }
2341 // check to make sure the flags on MESHSET_SET
2342 unsigned int flags;
2343 rval = mb->get_meshset_options( set, flags );MB_CHK_ERR(rval);
2344 if(!(MESHSET_SET&flags) || (MESHSET_TRACK_OWNER&flags) || (MESHSET_ORDERED&flags) ){
2345 std::cerr << "set should be MESHSET_SET only, flags=" << flags << std::endl;
2346 return MB_FAILURE;
2347 }
2348 // change to a tracking set and check flags
2349 rval = mb->set_meshset_options( set, MESHSET_TRACK_OWNER);MB_CHK_ERR(rval);
2350 rval = mb->get_meshset_options( set, flags );MB_CHK_ERR(rval);
2351 if( (MESHSET_SET&flags) || !(MESHSET_TRACK_OWNER&flags) || (MESHSET_ORDERED&flags) ){
2352 std::cerr << "set should be MESHSET_TRACK_OWNER only, flags=" << flags
2353 << std::endl;
2354 return MB_FAILURE;
2355 }
2356 // check adjacencies
2357 rval = mb->get_adjacencies( verts, 4, false, adj_sets);
2358 MB_CHK_ERR(rval);
2359 if(1 != adj_sets.size()) {
2360 std::cerr << "range should contain a set, adj_sets.size()="
2361 << adj_sets.size() << std::endl;
2362 rval = mb->list_entities( adj_sets );
2363 return MB_FAILURE;
2364 }
2365
2366 // CHECK TRACKING->SET
2367 // change to a standard set and check flags
2368 rval = mb->set_meshset_options( set, MESHSET_SET);MB_CHK_ERR(rval);
2369 rval = mb->get_meshset_options( set, flags );MB_CHK_ERR(rval);
2370 if(!(MESHSET_SET&flags) || (MESHSET_TRACK_OWNER&flags) || (MESHSET_ORDERED&flags) ){
2371 std::cerr << "set should be MESHSET_SET only, flags=" << flags
2372 << std::endl;
2373 return MB_FAILURE;
2374 }
2375 // the set should no longer be adjacent to the vertices
2376 adj_sets.clear();
2377 rval = mb->get_adjacencies( verts, 4, false, adj_sets);
2378 MB_CHK_ERR(rval);
2379 if(!adj_sets.empty()) {
2380 std::cerr << "range should be empty but contains:" << std::endl;
2381 rval = mb->list_entities( adj_sets );
2382 return MB_FAILURE;
2383 }
2384 // CHECK UNORDERED->ORDERED
2385 // add a duplicate vert
2386 rval = mb->add_entities( set, &verts.front(), 1);
2387 MB_CHK_ERR(rval);
2388 // unordered sets cannot hold duplicates so size shouldn't change
2389 std::vector<EntityHandle> entities;
2390 rval = mb->get_entities_by_handle( set, entities );
2391 if(10 != entities.size()) {
2392 std::cerr << "set should not hold duplicate entities" << std::endl;
2393 return MB_FAILURE;
2394 }
2395 // change to an ordered set and check flags
2396 rval = mb->set_meshset_options( set, MESHSET_ORDERED);
2397 MB_CHK_ERR(rval);
2398 rval = mb->get_meshset_options( set, flags );MB_CHK_ERR(rval);
2399 if( (MESHSET_SET&flags) || (MESHSET_TRACK_OWNER&flags) || !(MESHSET_ORDERED&flags) ){
2400 std::cerr << "set should be MESHSET_ORDERED only, flags=" << flags
2401 << std::endl;
2402 return MB_FAILURE;
2403 }
2404 // swap the order with some entities to that the handles aren't ordered
2405 rval = mb->clear_meshset( &set, 1 );
2406 MB_CHK_ERR(rval);
2407 entities.clear();
2408 entities.resize(2);
2409 entities[0] = verts[1];
2410 entities[1] = verts[0];
2411 rval = mb->add_entities( set, &entities[0], 2);
2412 MB_CHK_ERR(rval);
2413 // check to ensure the entities keep their order
2414 entities.clear();
2415 rval = mb->get_entities_by_handle( set, entities );
2416 if(verts[0]!=entities[1] || verts[1]!=entities[0]) {
2417 std::cerr << "ordered set did not keep its order" << std::endl;
2418 return MB_FAILURE;
2419 }
2420
2421 // CHECK ORDERED->UNORDERED
2422 // change to an unordered set and check flags
2423 rval = mb->set_meshset_options( set, MESHSET_SET);
2424 MB_CHK_ERR(rval);
2425 rval = mb->get_meshset_options( set, flags );MB_CHK_ERR(rval);
2426 if(!(MESHSET_SET&flags) || (MESHSET_TRACK_OWNER&flags) || MESHSET_ORDERED&flags){
2427 std::cerr << "set should be MESHSET_SET only, flags=" << flags
2428 << std::endl;
2429 return MB_FAILURE;
2430 }
2431 // the entities in the set should now be ordered by handle
2432 entities.clear();
2433 rval = mb->get_entities_by_handle( set, entities );
2434 if(verts[0]!=entities[0] || verts[1]!=entities[1]) {
2435 std::cerr << "unordered set is still ordered" << std::endl;
2436 return MB_FAILURE;
2437 }
2438 return MB_SUCCESS;
2439 }
2440
2441 #ifdef MOAB_HAVE_NETCDF
2442 // number of entities of type MBVERTEX, MBEDGE, MBDTri, MBQUAD, MBTET, and MBHEX
2443 // in mbtest1.g (all other values are 0.
2444 static const EntityType types[] = { MBVERTEX, MBEDGE, MBTRI, MBQUAD, MBTET, MBHEX };
2445 const int num_types = sizeof(types)/sizeof(types[0]);
2446 static const unsigned int num_entities[num_types+1] = {47,12,18,8,22,8,0};
2447
mb_delete_mesh_test()2448 ErrorCode mb_delete_mesh_test()
2449 {
2450 Core moab;
2451 Interface* gMB = &moab;
2452 ErrorCode error = load_file_one( gMB );
2453 if (MB_SUCCESS != error)
2454 return error;
2455
2456 // Lets also test the global MB pointer (gMB) here.
2457 error = gMB->delete_mesh();
2458 if (error != MB_SUCCESS)
2459 return error;
2460
2461 // load the mesh again
2462 error = load_file_one( gMB );
2463 if (error != MB_SUCCESS)
2464 return error;
2465
2466
2467 // step through each element type
2468 for (EntityType type = MBVERTEX; type != MBENTITYSET; type++)
2469 {
2470 // There should be entities
2471 Range entities;
2472 error = gMB->get_entities_by_type(0, type, entities);
2473 if (error != MB_SUCCESS)
2474 return error;
2475
2476 size_t idx = std::find( types, types+num_types, type ) - types;
2477 if ( entities.size() != num_entities[idx] )
2478 return MB_FAILURE;
2479 }
2480
2481 return MB_SUCCESS;
2482 }
2483
mb_mesh_set_tracking_test()2484 ErrorCode mb_mesh_set_tracking_test()
2485 {
2486 Core moab;
2487 Interface* MB = &moab;
2488
2489 //read in a file so you have some data in the database
2490
2491 ErrorCode error = load_file_one( MB );
2492 if (error != MB_SUCCESS)
2493 return error;
2494
2495 EntityHandle ms1, ms2, ms3;
2496
2497 //create meshsets
2498 ErrorCode result = MB->create_meshset( MESHSET_TRACK_OWNER | MESHSET_ORDERED, ms1 ) ;
2499 if(result != MB_SUCCESS )
2500 return result;
2501 result = MB->create_meshset( MESHSET_SET | MESHSET_TRACK_OWNER, ms2 ) ;
2502 if(result != MB_SUCCESS )
2503 return result;
2504 result = MB->create_meshset( MESHSET_SET | MESHSET_TRACK_OWNER, ms3 ) ;
2505 if(result != MB_SUCCESS )
2506 return result;
2507
2508 // get all hexes
2509 Range hexes;
2510 result = MB->get_entities_by_type(0, MBHEX, hexes);
2511 if(result != MB_SUCCESS )
2512 return result;
2513
2514 // get all tris
2515 Range tris;
2516 result = MB->get_entities_by_type(0, MBTRI, tris );
2517 if(result != MB_SUCCESS )
2518 return result;
2519
2520 // get all tets
2521 Range temp_range;
2522 result = MB->get_entities_by_type(0, MBTET, temp_range);
2523 if(result != MB_SUCCESS )
2524 return result;
2525
2526 //copy all the tets from the range into a vector 'tets'
2527 std::vector<EntityHandle> tets( temp_range.size() );
2528 std::copy(temp_range.begin(), temp_range.end(), tets.begin() );
2529
2530 //Quick check on 'get_entities_by_dimension()'
2531 Range dim_3_range;
2532 result = MB->get_entities_by_dimension(0, 3, dim_3_range) ;
2533 if(result != MB_SUCCESS )
2534 return result;
2535
2536 //hexes and tets should be only dimension 3 entities
2537 if( hexes.size() + tets.size() != dim_3_range.size() )
2538 return MB_FAILURE;
2539
2540 //put all hexes in ms1, ms2, ms3
2541 result = MB->add_entities(ms1, hexes); //add ents in a range
2542 if(result != MB_SUCCESS )
2543 return result;
2544 // to ordered meshset
2545
2546 result = MB->add_entities(ms2, hexes); //add ents in a range
2547 if(result != MB_SUCCESS )
2548 return result;
2549 //to unordered meshset
2550
2551 result = MB->add_entities(ms3, hexes);
2552 if(result != MB_SUCCESS )
2553 return result;
2554
2555 //put all tets in ms1, ms2
2556 if(MB->add_entities(ms1, &tets[0], tets.size()) != MB_SUCCESS ) //add ents in a vector
2557 return MB_FAILURE; //to ordered meshset
2558
2559 if(MB->add_entities(ms2, &tets[0], tets.size()) != MB_SUCCESS ) //add ents in a vector
2560 return MB_FAILURE; //to unordered meshset
2561
2562 //put all tris in ms1
2563 result = MB->add_entities(ms1, tris) ;
2564 if(result != MB_SUCCESS )
2565 return result;
2566
2567 Range::iterator iter;
2568 iter = tris.begin();
2569
2570 std::vector< EntityHandle > temp_vec;
2571
2572 //ask a tri which meshsets it is in
2573 result = MB->get_adjacencies( &(*iter), 1, 4, false, temp_vec ) ;
2574 if(result != MB_SUCCESS )
2575 return result;
2576
2577 //cout<<"tris temp_vec.size() = "<<temp_vec.size()<<endl;
2578 if( temp_vec.size() != 2 )
2579 return MB_FAILURE;
2580
2581 //ask a tet which meshsets it is in
2582 temp_vec.clear();
2583 std::vector<EntityHandle>::iterator vec_iter = tets.begin();
2584 result = MB->get_adjacencies( &(*vec_iter), 1, 4, false, temp_vec ) ;
2585 if(result != MB_SUCCESS )
2586 return result;
2587
2588 //cout<<"tet temp_vec.size() = "<<temp_vec.size()<<endl;
2589 if( temp_vec.size() != 3 )
2590 return MB_FAILURE;
2591
2592 //ask a hex which meshsets it is in
2593 temp_vec.clear();
2594 iter = hexes.begin();
2595 result = MB->get_adjacencies( &(*iter), 1, 4, false, temp_vec ) ;
2596 if(result != MB_SUCCESS )
2597 return result;
2598
2599 //should be in 4 temp_vec
2600 if( temp_vec.size() != 4 )
2601 return MB_FAILURE;
2602
2603 //take this hex out of the ms1, ms2, ms3
2604 if(MB->remove_entities(ms1, &(*iter), 1) != MB_SUCCESS ) //remove ents in a vector
2605 return MB_FAILURE; //from ordered meshset
2606
2607 if(MB->remove_entities(ms2, &(*iter), 1) != MB_SUCCESS ) //remove ents in a vector
2608 return MB_FAILURE; //from unordered meshset
2609
2610 temp_range.clear();
2611 temp_range.insert(*iter);
2612 if(MB->remove_entities(ms3, temp_range) != MB_SUCCESS ) //remove ents in a range
2613 return MB_FAILURE; //from unordered meshset
2614
2615
2616 //ask the hex how many meshsets it is in
2617 temp_vec.clear();
2618 result = MB->get_adjacencies( &(*iter), 1, 4, false, temp_vec ) ;
2619 if(result != MB_SUCCESS )
2620 return result;
2621 if( temp_vec.size() != 1 )
2622 return MB_FAILURE;
2623
2624 //add the hex back into ms1
2625 result = MB->add_entities(ms1, temp_range) ;
2626 if(result != MB_SUCCESS )
2627 return result;
2628
2629 //ask the hex how many meshsets it is in
2630 temp_vec.clear();
2631 result = MB->get_adjacencies( &(*iter), 1, 4, false, temp_vec ) ;
2632 if(result != MB_SUCCESS )
2633 return result;
2634 if( temp_vec.size() != 2 )
2635 return MB_FAILURE;
2636
2637 temp_range.clear();
2638 temp_range.insert(*iter);
2639 if(MB->remove_entities(ms1, temp_range) != MB_SUCCESS ) //remove ents in a range
2640 return MB_FAILURE; //from an ordered meshset
2641
2642 //ask the hex how many meshsets it is in
2643 temp_vec.clear();
2644 result = MB->get_adjacencies( &(*iter), 1, 4, false, temp_vec ) ;
2645 if(result != MB_SUCCESS )
2646 return result;
2647 if( temp_vec.size() != 1 )
2648 return MB_FAILURE;
2649
2650
2651 //Deleting a meshset
2652
2653 iter = tris.begin();
2654 temp_vec.clear();
2655 //ask a tri which meshsets it is in
2656 result = MB->get_adjacencies( &(*iter), 1, 4, false, temp_vec ) ;
2657 if(result != MB_SUCCESS )
2658 return result;
2659
2660 if( temp_vec.size() != 2 )
2661 return MB_FAILURE;
2662
2663 //Try deleting a meshset
2664 result = MB->delete_entities(&ms1, 1);
2665 if(result != MB_SUCCESS )
2666 return result;
2667
2668 temp_vec.clear();
2669 //Query tri again for meshsets it's in
2670 result = MB->get_adjacencies( &(*iter), 1, 4, false, temp_vec ) ;
2671 if(result != MB_SUCCESS )
2672 return result;
2673
2674 if( temp_vec.size() != 1 )
2675 return MB_FAILURE;
2676
2677 //Delete an entitiy from ms2....make sure it's removed out of ms2
2678 int num_before = 0;
2679 MB->get_number_entities_by_handle(ms2, num_before);
2680 vec_iter = tets.begin();
2681 result = MB->delete_entities( &(*vec_iter), 1);
2682 if(result != MB_SUCCESS )
2683 return result;
2684
2685 int num_after = 0;
2686 MB->get_number_entities_by_handle(ms2, num_after);
2687 if( num_before != num_after + 1)
2688 return MB_FAILURE;
2689
2690
2691 return MB_SUCCESS;
2692
2693 }
2694 #endif
2695
2696 // Compare internal representation of contents for a list (MESHSET_ORDERED)
2697 // set to expected contents. Assumes expected contents are correctly
2698 // ordered.
check_list_meshset_internal(const EntityHandle * expected,int num_expected,const EntityHandle * contents,int length)2699 static ErrorCode check_list_meshset_internal(
2700 const EntityHandle* expected,
2701 int num_expected,
2702 const EntityHandle* contents,
2703 int length )
2704 {
2705 bool okay = true;
2706 for (int i = 0; i < std::min(num_expected, length); ++i) {
2707 if (expected[i] != contents[i]) {
2708 std::cerr << "List set contents differ at index " << i
2709 << ": expected " << expected[i] << " but got "
2710 << contents[i] << std::endl;
2711 okay = false;
2712 }
2713 }
2714 if (num_expected > length) {
2715 std::cerr << "List set is missing " << num_expected - length <<
2716 "handles" << std::endl;
2717 okay = false;
2718 }
2719 else if (length > num_expected) {
2720 std::cerr << "List set has " << num_expected - length <<
2721 " extra handles" << std::endl;
2722 okay = false;
2723 }
2724
2725 if (okay)
2726 return MB_SUCCESS;
2727
2728 std::cerr << "Expected contents: ";
2729 if (!num_expected)
2730 std::cerr << "(empty)";
2731 else
2732 std::cerr << expected[0];
2733 for (int i = 1; i < num_expected; ++i)
2734 std::cerr << ", " << expected[i];
2735 std::cerr << std::endl;
2736
2737 std::cerr << "Actual contents: ";
2738 if (!length)
2739 std::cerr << "(empty)";
2740 else
2741 std::cerr << contents[0];
2742 for (int i = 1; i < length; ++i)
2743 std::cerr << ", " << contents[i];
2744 std::cerr << std::endl;
2745
2746 return MB_FAILURE;
2747 }
2748
2749
2750 // Compare internal representation of contents for a ranged (MESHSET_SET)
2751 // set to expected contents. Assumes expected contents are correctly
2752 // ordered.
check_ranged_meshset_internal(const EntityHandle * expected,int num_expected,const EntityHandle * contents,int length)2753 static ErrorCode check_ranged_meshset_internal(
2754 const EntityHandle* expected,
2755 int num_expected,
2756 const EntityHandle* contents,
2757 int length )
2758 {
2759 if (length % 2) {
2760 std::cerr << "Range set is corrupt. Odd number of handles in content list" << std::endl;
2761 std::cerr << "Actual contents: " << contents[0];
2762 for (int i = 1; i < length; ++i)
2763 std::cerr << ", " << contents[i];
2764 std::cerr << std::endl;
2765 return MB_FAILURE;
2766 }
2767 bool okay = true;
2768 // check that all range pairs are valid (first handle less than or
2769 // equal to second)
2770 for (int i = 0; i < length; i += 2) {
2771 if (contents[i] > contents[i+1]) {
2772 std::cerr << "Range set has invalid range pair at index " << i
2773 << ": [" << contents[i] << ',' << contents[i+1]
2774 << ']' << std::endl;
2775 okay = false;
2776 }
2777 }
2778 // check that all range pairs are sorted and non-overlapping
2779 // (start of a range must be greater than end of previous range)
2780 for (int i = 2; i < length; i += 2) {
2781 if (contents[i] < contents[i-1]) {
2782 std::cerr << "Range set has incorrectly ordered ranges at index " << i
2783 << ": [...," << contents[i-1] << "], [" << contents[i]
2784 << ",...]" << std::endl;
2785 okay = false;
2786 }
2787 if (contents[i] == contents[i-1]+1) {
2788 std::cerr << "Range set has pairs that should have been merged at index " << i
2789 << ": [...," << contents[i-1] << "], [" << contents[i]
2790 << ",...]" << std::endl;
2791 okay = false;
2792 }
2793 }
2794 if (!okay) {
2795 std::cerr << "Actual contents: ";
2796 if (!length)
2797 std::cerr << "(empty)";
2798 else
2799 std::cerr << '[' << contents[0] << ',' << contents[1] << ']';
2800 for (int i = 2; i < length; i += 2)
2801 std::cerr << ", [" << contents[i] << ',' << contents[i+1] << ']';
2802 std::cerr << std::endl;
2803 return MB_FAILURE;
2804 }
2805
2806 int j = 0;
2807 for (int i = 0; i < length; i += 2) {
2808 for (; j < num_expected && expected[j] < contents[i]; ++j) {
2809 std::cerr << "Range set missing expected handle: " << expected[j] << std::endl;
2810 okay = false;
2811 }
2812 int k = j;
2813 while (k < num_expected && expected[k] <= contents[i+1])
2814 ++k;
2815 if ((EntityHandle)(k-j) <= (contents[i+1]-contents[i])) {
2816 std::cerr << "Handle range [" << contents[i] << ',' << contents[i+1]
2817 << "] contains unexpected handles. Expected handles: ";
2818 if (k == j)
2819 std::cerr << "(none)" << std::endl;
2820 else {
2821 std::cerr << expected[j];
2822 for (++j; j < k; ++j)
2823 std::cerr << ", " << expected[j];
2824 std::cerr << std::endl;
2825 }
2826 okay = false;
2827 }
2828 j = k;
2829 }
2830
2831 if (okay)
2832 return MB_SUCCESS;
2833
2834 std::cerr << "Expected contents: ";
2835 if (!num_expected)
2836 std::cerr << "(empty)";
2837 else
2838 std::cerr << expected[0];
2839 for (int i = 1; i < num_expected; ++i)
2840 std::cerr << ", " << expected[i];
2841 std::cerr << std::endl;
2842
2843 std::cerr << "Actual contents: ";
2844 if (!length)
2845 std::cerr << "(empty)";
2846 else
2847 std::cerr << '[' << contents[0] << ',' << contents[1] << ']';
2848 for (int i = 2; i < length; i += 2)
2849 std::cerr << ", [" << contents[i] << ',' << contents[i+1] << ']';
2850 std::cerr << std::endl;
2851
2852 return MB_FAILURE;
2853 }
2854
2855 // Check the internal representation of a meshset
2856 // to verify that it is correct.
check_meshset_internal(Interface & mb,EntityHandle set,const EntityHandle * expected,int num_expected)2857 static ErrorCode check_meshset_internal( Interface& mb,
2858 EntityHandle set,
2859 const EntityHandle* expected,
2860 int num_expected )
2861 {
2862 ErrorCode rval;
2863 WriteUtilIface* tool = 0;
2864 rval = mb.query_interface( tool );
2865 MB_CHK_ERR(rval);
2866
2867 const EntityHandle* contents;
2868 int length;
2869 unsigned char flags;
2870 rval = tool->get_entity_list_pointers( &set, 1, &contents,
2871 WriteUtilIface::CONTENTS, &length, &flags );MB_CHK_ERR(rval);
2872 ErrorCode rval1 = mb.release_interface( tool );MB_CHK_ERR(rval1);
2873
2874 if (flags & MESHSET_ORDERED)
2875 rval = check_list_meshset_internal( expected, num_expected, contents, length );
2876 else
2877 rval = check_ranged_meshset_internal( expected, num_expected, contents, length );
2878 MB_CHK_ERR(rval);
2879 return MB_SUCCESS;
2880 }
2881
mb_mesh_set_set_add_remove_test()2882 ErrorCode mb_mesh_set_set_add_remove_test()
2883 {
2884 Core core;
2885 Interface& mb = core;
2886 EntityHandle set;
2887 ErrorCode rval = mb.create_meshset( MESHSET_SET, set );
2888 MB_CHK_ERR(rval);
2889
2890 EntityHandle list1[] = {10, 16, 18, 20, 24, 27};
2891 size_t len1 = sizeof(list1)/sizeof(list1[0]);
2892 EntityHandle list2[] = {10, 16, 17, 18, 19, 20, 24, 27};
2893 size_t len2 = sizeof(list2)/sizeof(list2[0]);
2894 rval = mb.add_entities( set, list1, len1 );
2895 MB_CHK_ERR(rval);
2896 rval = check_meshset_internal( mb, set, list1, len1 );
2897 MB_CHK_ERR(rval);
2898 rval = mb.add_entities( set, list2, len2 );
2899 MB_CHK_ERR(rval);
2900 EntityHandle exp12[] = {10, 16, 17, 18, 19, 20, 24, 27};
2901 size_t len12 = sizeof(exp12)/sizeof(exp12[0]);
2902 rval = check_meshset_internal( mb, set, exp12, len12 );
2903 MB_CHK_ERR(rval);
2904
2905 EntityHandle list3[] = { 15, 16, 18, 20, 21, 24, 28 };
2906 size_t len3 = sizeof(list3)/sizeof(list3[0]);
2907 rval = mb.remove_entities( set, list3, len3 );
2908 MB_CHK_ERR(rval);
2909 EntityHandle exp123[] = { 10, 17, 19, 27 };
2910 size_t len123 = sizeof(exp123)/sizeof(exp123[0]);
2911 rval = check_meshset_internal( mb, set, exp123, len123 );
2912 MB_CHK_ERR(rval);
2913
2914 EntityHandle list4[] = { 18, 10, 11, 12, 13, 14, 15, 16 };
2915 size_t len4 = sizeof(list4)/sizeof(list4[0]);
2916 rval = mb.add_entities( set, list4, len4 );
2917 MB_CHK_ERR(rval);
2918 EntityHandle exp14[] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 27};
2919 size_t len14 = sizeof(exp14)/sizeof(exp14[0]);
2920 rval = check_meshset_internal( mb, set, exp14, len14 );
2921 MB_CHK_ERR(rval);
2922
2923 EntityHandle list5[] = { 9, 10, 12, 13, 14, 15, 19, 20 };
2924 rval = mb.remove_entities( set, list5, sizeof(list5)/sizeof(list5[0]) );
2925 MB_CHK_ERR(rval);
2926 EntityHandle exp5[] = { 11, 16, 17, 18, 27 };
2927 rval = check_meshset_internal( mb, set, exp5, sizeof(exp5)/sizeof(exp5[0]) );
2928 MB_CHK_ERR(rval);
2929
2930 EntityHandle list6[] = { 9, 10, 15, 16, 18, 19, 28 };
2931 rval = mb.add_entities( set, list6, sizeof(list6)/sizeof(list6[0]) );
2932 MB_CHK_ERR(rval);
2933 EntityHandle exp6[] = { 9, 10, 11, 15, 16, 17, 18, 19, 27, 28 };
2934 rval = check_meshset_internal( mb, set, exp6, sizeof(exp6)/sizeof(exp6[0]) );
2935 MB_CHK_ERR(rval);
2936
2937 EntityHandle list7[] = { 13, 19, 27, 28 };
2938 rval = mb.add_entities( set, list7, sizeof(list7)/sizeof(list7[0]) );
2939 MB_CHK_ERR(rval);
2940 EntityHandle exp7[] = { 9, 10, 11, 13, 15, 16, 17, 18, 19, 27, 28 };
2941 rval = check_meshset_internal( mb, set, exp7, sizeof(exp7)/sizeof(exp7[0]) );
2942 MB_CHK_ERR(rval);
2943
2944 EntityHandle list8[] = { 12, 14, 33 };
2945 rval = mb.add_entities( set, list8, sizeof(list8)/sizeof(list8[0]) );
2946 MB_CHK_ERR(rval);
2947 EntityHandle exp8[] = { 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 27, 28, 33 };
2948 rval = check_meshset_internal( mb, set, exp8, sizeof(exp8)/sizeof(exp8[0]) );
2949 MB_CHK_ERR(rval);
2950
2951 EntityHandle list9[] = { 29, 30, 31, 32, 34 };
2952 rval = mb.remove_entities( set, list9, sizeof(list9)/sizeof(list9[0]) );
2953 MB_CHK_ERR(rval);
2954 rval = check_meshset_internal( mb, set, exp8, sizeof(exp8)/sizeof(exp8[0]) );
2955 MB_CHK_ERR(rval);
2956
2957 EntityHandle list10[] = { 9, 11, 13, 17, 18, 19, 28, 33, 100 };
2958 rval = mb.remove_entities( set, list10, sizeof(list10)/sizeof(list10[0]) );
2959 MB_CHK_ERR(rval);
2960 EntityHandle exp10[] = { 10, 12, 14, 15, 16, 27 };
2961 rval = check_meshset_internal( mb, set, exp10, sizeof(exp10)/sizeof(exp10[0]) );
2962 MB_CHK_ERR(rval);
2963
2964 EntityHandle list11[] = { 11, 12, 13, 14, 27, 28 };
2965 rval = mb.remove_entities( set, list11, sizeof(list11)/sizeof(list11[0]) );
2966 MB_CHK_ERR(rval);
2967 EntityHandle exp11[] = { 10, 15, 16 };
2968 rval = check_meshset_internal( mb, set, exp11, sizeof(exp11)/sizeof(exp11[0]) );
2969 MB_CHK_ERR(rval);
2970
2971 EntityHandle list12[] = { 1, 10, 15, 16 };
2972 rval = mb.remove_entities( set, list12, sizeof(list12)/sizeof(list12[0]) );
2973 MB_CHK_ERR(rval);
2974 rval = check_meshset_internal( mb, set, 0, 0 );
2975 MB_CHK_ERR(rval);
2976
2977 return MB_SUCCESS;
2978 }
2979
2980
mb_higher_order_test()2981 ErrorCode mb_higher_order_test()
2982 {
2983 Core moab;
2984 Interface *MB = &moab;
2985
2986 double nodes_array [7][3];
2987
2988 nodes_array[0][0] = 0;
2989 nodes_array[0][1] = 0;
2990 nodes_array[0][2] = 0;
2991 nodes_array[1][0] = 2;
2992 nodes_array[1][1] = 0;
2993 nodes_array[1][2] = 0;
2994 nodes_array[2][0] = 1;
2995 nodes_array[2][1] = 2;
2996 nodes_array[2][2] = 1;
2997 nodes_array[3][0] = 1;
2998 nodes_array[3][1] = 0;
2999 nodes_array[3][2] = 0;
3000 nodes_array[4][0] = 1.5;
3001 nodes_array[4][1] = 0.5;
3002 nodes_array[4][2] = 0.5;
3003 nodes_array[5][0] = 0.5;
3004 nodes_array[5][1] = 0.5;
3005 nodes_array[5][2] = 0.5;
3006 nodes_array[6][0] = 1;
3007 nodes_array[6][1] = 1;
3008 nodes_array[6][2] = 0.5;
3009
3010
3011 //create the nodes
3012 std::vector<EntityHandle> connectivity(8);
3013 EntityHandle node_handle;
3014 int i;
3015 for( i=0; i<7; i++)
3016 {
3017 if(MB->create_vertex( nodes_array[i], node_handle ) != MB_SUCCESS )
3018 return MB_FAILURE;
3019 connectivity[i] = node_handle;
3020 }
3021
3022 //create the higher order tri
3023 EntityHandle tri_handle;
3024 ErrorCode result = MB->create_element(MBTRI, &connectivity[0], 6, tri_handle);
3025 if(result != MB_SUCCESS)
3026 return result;
3027
3028 //create the higher order tri
3029 std::vector<EntityHandle> other_conn(3);
3030
3031 double other_nodes[3][3];
3032 other_nodes[0][0] = 1.999;
3033 other_nodes[0][1] = 1.999;
3034 other_nodes[0][2] = 1.999;
3035 other_nodes[1][0] = 2.999;
3036 other_nodes[1][1] = 2.999;
3037 other_nodes[1][2] = 2.999;
3038 other_nodes[2][0] = 3.999;
3039 other_nodes[2][1] = 3.999;
3040 other_nodes[2][2] = 3.999;
3041
3042 for( i=0; i<3; i++)
3043 {
3044 if(MB->create_vertex( other_nodes[i], node_handle ) != MB_SUCCESS )
3045 return MB_FAILURE;
3046 other_conn[i] = node_handle;
3047 }
3048
3049 EntityHandle other_tri_handle;
3050 result = MB->create_element(MBTRI, &other_conn[0], 3, other_tri_handle);
3051 if(result != MB_SUCCESS)
3052 return result;
3053
3054 //get the connectivity now
3055 std::vector<EntityHandle> retrieved_conn;
3056
3057 result = MB->get_connectivity(&tri_handle, 1, retrieved_conn) ;
3058 if(result != MB_SUCCESS)
3059 return result;
3060
3061 unsigned int k;
3062 for( k=0; k< retrieved_conn.size(); k++)
3063 if( connectivity[k] != retrieved_conn[k] )
3064 return MB_FAILURE;
3065
3066 result = MB->get_connectivity(&other_tri_handle, 1, retrieved_conn) ;
3067 if(result != MB_SUCCESS)
3068 return result;
3069
3070 for( k=0; k< other_conn.size(); k++)
3071 if( other_conn[k] != retrieved_conn[k] )
3072 return MB_FAILURE;
3073
3074 // now let's just try getting the topological connectivity (the 3 corner vertices)
3075 std::vector<EntityHandle> topo_conn;
3076 result = MB->get_connectivity(&other_tri_handle, 1, topo_conn, true) ;
3077 if(result != MB_SUCCESS)
3078 return result;
3079
3080 if (topo_conn.size() != 3)
3081 return MB_FAILURE;
3082
3083 for ( k=0; k<3; k++)
3084 if (topo_conn[k] != retrieved_conn[k] )
3085 return MB_FAILURE;
3086
3087 // short check to make sure that Core::handle_from_id() works
3088 unsigned long handle_id = MB->id_from_handle( node_handle);
3089
3090 EntityHandle test_handle;
3091 result = MB->handle_from_id( MBVERTEX, handle_id, test_handle );
3092 if(result != MB_SUCCESS)
3093 return result;
3094
3095 if( test_handle != node_handle )
3096 return MB_FAILURE;
3097
3098
3099 handle_id = MB->id_from_handle( tri_handle);
3100
3101 result = MB->handle_from_id( MBTRI, handle_id, test_handle );
3102 if(result != MB_SUCCESS)
3103 return result;
3104
3105 if( test_handle != tri_handle )
3106 return MB_FAILURE;
3107
3108
3109 //make up some bogus id
3110 handle_id = 2140824;
3111
3112 result = MB->handle_from_id( MBTRI, handle_id, test_handle );
3113 if (result != MB_ENTITY_NOT_FOUND )
3114 return MB_FAILURE;
3115
3116 result = MB->handle_from_id( MBVERTEX, handle_id, test_handle );
3117 if (result != MB_ENTITY_NOT_FOUND )
3118 return MB_FAILURE;
3119
3120
3121 return MB_SUCCESS;
3122
3123 }
3124
mb_bit_tags_test()3125 ErrorCode mb_bit_tags_test()
3126 {
3127 Core moab;
3128 Interface* MB = &moab;
3129 ErrorCode success = create_some_mesh( MB );
3130 if (MB_SUCCESS != success)
3131 return success;
3132
3133 Tag bit_tag;
3134 Range entities;
3135 MB->get_entities_by_type(0, MBVERTEX, entities);
3136
3137 if(MB->tag_get_handle("bit on vertex", 3, MB_TYPE_BIT, bit_tag, MB_TAG_CREAT) != MB_SUCCESS)
3138 {
3139 cout << "couldn't create bit tag" << endl;
3140 return MB_FAILURE;
3141 }
3142
3143 Range::iterator iter;
3144 unsigned char bits;
3145 for(iter = entities.begin();
3146 iter != entities.end(); ++iter)
3147 {
3148 // tag each vertex with the low 3 bits of the entity handle
3149 bits = ((*iter) & 0x7);
3150 success = MB->tag_set_data(bit_tag, &(*iter), 1, &bits);
3151 if(success != MB_SUCCESS)
3152 return MB_FAILURE;
3153 }
3154
3155 bits = 0;
3156 for(iter = entities.begin();
3157 iter != entities.end(); ++iter)
3158 {
3159 // tag each vertex with the low 3 bits of the entity handle
3160 success = MB->tag_get_data(bit_tag, &(*iter), 1, &bits);
3161 if(success != MB_SUCCESS)
3162 return MB_FAILURE;
3163
3164 if(bits != ((*iter) & 0x7))
3165 return MB_FAILURE;
3166 }
3167
3168 // test range-based query for all vertices
3169 std::vector<unsigned char> data(entities.size());
3170 success = MB->tag_get_data( bit_tag, entities, &data[0] );
3171 if (MB_SUCCESS != success) return success;
3172 std::vector<unsigned char>::iterator i = data.begin();
3173 for (iter = entities.begin(); iter != entities.end(); ++iter, ++i)
3174 if (*i != ((*iter) & 0x7))
3175 return MB_FAILURE;
3176
3177 // test vector-based query for all vertices
3178 std::vector<EntityHandle> verts(entities.begin(), entities.end());
3179 success = MB->tag_get_data( bit_tag, &verts[0], verts.size(), &data[0] );
3180 if (MB_SUCCESS != success) return success;
3181 i = data.begin();
3182 for (iter = entities.begin(); iter != entities.end(); ++iter, ++i)
3183 if (*i != ((*iter) & 0x7))
3184 return MB_FAILURE;
3185
3186 // test default value
3187 const unsigned char default_bits = '\005'; // 0000 0101
3188 Tag tag2;
3189 success = MB->tag_get_handle( "bit with default", 4, MB_TYPE_BIT, tag2, MB_TAG_CREAT, &default_bits );
3190 if (MB_SUCCESS != success) {
3191 cout << "Failed to create bit tag with default value" << std::endl;
3192 return success;
3193 }
3194
3195 // set value to zero on a single vertex
3196 bits = 0;
3197 EntityHandle zh = verts[verts.size()/2];
3198 success = MB->tag_set_data( tag2, &zh, 1, &bits );
3199 if (MB_SUCCESS != success)
3200 return success;
3201
3202 // get tag values for all entities
3203 data.clear();
3204 data.resize( verts.size(), 0x7A ); // initialize with 0111 1010
3205 success = MB->tag_get_data( tag2, entities, &data[0] );
3206 if (MB_SUCCESS != success)
3207 return success;
3208
3209 // check values
3210 i = data.begin();
3211 for (iter = entities.begin(); iter != entities.end(); ++iter, ++i)
3212 if (*iter == zh && *i) // the one we set to zero
3213 return MB_FAILURE;
3214 else if (*iter != zh && *i != default_bits)
3215 return MB_FAILURE;
3216
3217 return MB_SUCCESS;
3218 }
3219
3220 #ifdef MOAB_HAVE_NETCDF
mb_tags_test()3221 ErrorCode mb_tags_test()
3222 {
3223 Core moab;
3224 Interface* MB = &moab;
3225 ErrorCode result = load_file_one( MB );
3226 if (MB_SUCCESS != result)
3227 return result;
3228
3229 Tag stale_bits, stale_dense, stale_sparse;
3230 result = MB->tag_get_handle("stale data", 5, MB_TYPE_BIT, stale_bits, MB_TAG_CREAT);
3231 if (MB_SUCCESS != result)
3232 return result;
3233
3234 int def_data = 9;
3235 result = MB->tag_get_handle("dense stale_data", 1, MB_TYPE_INTEGER, stale_dense, MB_TAG_DENSE|MB_TAG_EXCL, &def_data);
3236 if (MB_SUCCESS != result)
3237 return result;
3238 result = MB->tag_get_handle("sparse stale data", 1, MB_TYPE_INTEGER, stale_sparse, MB_TAG_SPARSE|MB_TAG_EXCL);
3239 if (MB_SUCCESS != result)
3240 return result;
3241
3242 double coords[3] = { 0,0,0 };
3243 EntityHandle stale_handle1, stale_handle2;
3244 result = MB->create_vertex( coords, stale_handle1 );
3245 if (MB_SUCCESS != result)
3246 return result;
3247
3248 unsigned char bits = 0x5;
3249 result = MB->tag_set_data(stale_bits, &stale_handle1, 1, &bits);
3250 if (MB_SUCCESS != result)
3251 return result;
3252 bits = 0;
3253 result = MB->tag_get_data(stale_bits, &stale_handle1, 1, &bits);
3254 if (MB_SUCCESS != result)
3255 return result;
3256 if (bits != 0x5)
3257 return MB_FAILURE;
3258
3259 def_data = 1;
3260 result = MB->tag_set_data(stale_dense, &stale_handle1, 1, &def_data);
3261 if (MB_SUCCESS != result)
3262 return result;
3263 def_data = 0;
3264 result = MB->tag_get_data(stale_dense, &stale_handle1, 1, &def_data);
3265 if (MB_SUCCESS != result)
3266 return result;
3267 if (def_data != 1)
3268 return MB_FAILURE;
3269
3270 def_data = 100;
3271 result = MB->tag_set_data(stale_sparse, &stale_handle1, 1, &def_data);
3272 if (MB_SUCCESS != result)
3273 return result;
3274 def_data = 0;
3275 result = MB->tag_get_data(stale_sparse, &stale_handle1, 1, &def_data);
3276 if (MB_SUCCESS != result)
3277 return result;
3278 if (def_data != 100)
3279 return MB_FAILURE;
3280
3281 result = MB->delete_entities(&stale_handle1, 1);
3282 if (MB_SUCCESS != result)
3283 return result;
3284 result = MB->create_vertex(coords, stale_handle2);
3285 if (MB_SUCCESS != result)
3286 return result;
3287
3288 if(stale_handle1 != stale_handle2)
3289 cout<< "Tag test could test stale data" << endl;
3290 else
3291 {
3292 bits=0;
3293 result = MB->tag_get_data(stale_bits, &stale_handle2, 1, &bits);
3294 if (MB_SUCCESS != result)
3295 return result;
3296 if(bits != 0)
3297 return MB_FAILURE;
3298
3299 def_data = 3;
3300 result = MB->tag_get_data(stale_dense, &stale_handle2, 1, &def_data);
3301 if (MB_SUCCESS != result)
3302 return result;
3303 if(def_data != 9)
3304 return MB_FAILURE;
3305
3306 def_data = 3;
3307 ErrorCode stale_result = MB->tag_get_data(stale_sparse, &stale_handle2, 1, &def_data);
3308 // we are supposed to fail here
3309 if(stale_result != MB_TAG_NOT_FOUND)
3310 return MB_FAILURE;
3311 }
3312
3313 result = MB->tag_delete(stale_dense);
3314 if (MB_SUCCESS != result)
3315 return result;
3316
3317 result = MB->delete_entities(&stale_handle2, 1);
3318 if (MB_SUCCESS != result)
3319 return result;
3320
3321
3322 //get all blocks with material tag and with tag_value of 1 (should only be 1)
3323 Range entities;
3324 int value = 1;
3325 const void *dum_ptr = &value;
3326 Tag material_tag;
3327 result = MB->tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, material_tag);
3328 if (MB_SUCCESS != result)
3329 return result;
3330 if(MB->get_entities_by_type_and_tag( 0, MBENTITYSET, &material_tag,
3331 &dum_ptr,
3332 1, entities) != MB_SUCCESS)
3333 return MB_FAILURE;
3334
3335 if( entities.size() != 1)
3336 return MB_FAILURE;
3337
3338 //add a dense tag to hexes
3339 Tag junk_tag;
3340 if(MB->tag_get_handle( "junk_tag", 1, MB_TYPE_INTEGER, junk_tag, MB_TAG_DENSE|MB_TAG_EXCL)
3341 != MB_SUCCESS)
3342 return MB_FAILURE;
3343
3344 //Set the dense tag on 5 hexes to 3489
3345 Range test_range;
3346 result = MB->get_entities_by_type(0, MBHEX, test_range ) ;
3347 if(result != MB_SUCCESS)
3348 return result;
3349
3350 Range::iterator iter, end_iter;
3351 iter = test_range.begin();
3352 end_iter = test_range.end();
3353
3354 int data = 3489;
3355 const void *ptr_data = &data;
3356
3357 //mark approxiamtely the first 20% of the hex entities; also put a bit tag on them
3358 unsigned int times = test_range.size()/5;
3359 bits = 0x5;
3360 const void *ptr_bits = &bits;
3361
3362 for(unsigned int i=0; i<times; i++)
3363 {
3364 if(MB->tag_set_data( junk_tag, &(*iter), 1, &data ) != MB_SUCCESS )
3365 return MB_FAILURE;
3366 if(MB->tag_set_data( stale_bits, &(*iter), 1, &bits ) != MB_SUCCESS )
3367 return MB_FAILURE;
3368 ++iter;
3369 }
3370
3371 entities.clear();
3372 //fetch the hex entities of type--MBHEX, tag-"junk_tag", and tag value -- 3489
3373 if(MB->get_entities_by_type_and_tag(0, MBHEX, &junk_tag,
3374 &ptr_data,
3375 1, entities ) != MB_SUCCESS)
3376 return MB_FAILURE;
3377
3378 if( entities.size() != times) //should get as many hexes as you perviously marked
3379 return MB_FAILURE;
3380
3381 //fetch the hex entities of type--MBHEX, tag-"junk_tag", and tag value -- 3489
3382 entities.clear();
3383 if(MB->get_entities_by_type_and_tag(0, MBHEX, &stale_bits,
3384 &ptr_bits, 1, entities ) != MB_SUCCESS)
3385 return MB_FAILURE;
3386
3387 if( entities.size() != times) //should get as many hexes as you perviously marked
3388 return MB_FAILURE;
3389
3390 // test fetch by tag value again, this time limiting the results
3391 // to the contents of an entity set
3392 EntityHandle meshset;
3393 result = MB->create_meshset( MESHSET_SET, meshset );
3394 if (MB_SUCCESS != result)
3395 return result;
3396 result = MB->add_entities( meshset, test_range );
3397 if (MB_SUCCESS != result)
3398 return result;
3399
3400
3401 //fetch the hex entities of type--MBHEX, tag-"junk_tag", and tag value -- 3489
3402 entities.clear();
3403 result = MB->get_entities_by_type_and_tag(meshset, MBHEX, &junk_tag,
3404 &ptr_data, 1, entities );
3405 if (MB_SUCCESS != result)
3406 return result;
3407
3408 if( entities.size() != times) //should get as many hexes as you perviously marked
3409 return MB_FAILURE;
3410
3411 //fetch the hex entities of type--MBHEX, tag-"stale_bits", and tag value -- 0x5
3412 entities.clear();
3413 result = MB->get_entities_by_type_and_tag(meshset, MBHEX, &stale_bits,
3414 &ptr_bits, 1, entities );
3415 if (MB_SUCCESS != result)
3416 return result;
3417
3418 if( entities.size() != times) //should get as many hexes as you perviously marked
3419 return MB_FAILURE;
3420
3421
3422 // now try the query with an empty meshset, expecting to get back
3423 // an empty Range
3424
3425 result = MB->create_meshset( MESHSET_SET, meshset );
3426 if (MB_SUCCESS != result)
3427 return result;
3428
3429 entities.clear();
3430 result = MB->get_entities_by_type_and_tag(meshset, MBHEX, &junk_tag,
3431 &ptr_data, 1, entities );
3432 if (MB_SUCCESS != result)
3433 return result;
3434
3435 if(!entities.empty())
3436 return MB_FAILURE;
3437
3438
3439
3440 result = MB->tag_delete(stale_bits);
3441 if (MB_SUCCESS != result)
3442 return result;
3443
3444 return MB_SUCCESS;
3445 }
3446 #endif
mb_common_tag_test(TagType storage)3447 ErrorCode mb_common_tag_test( TagType storage )
3448 {
3449 Core moab;
3450 Interface* mb = &moab;
3451 ErrorCode result = create_some_mesh( mb );
3452 if (MB_SUCCESS != result)
3453 return result;
3454
3455 char tagname[64];
3456 sprintf( tagname, "t%d", rand() );
3457
3458 Tag tag;
3459 const EntityHandle def_val = ~(EntityHandle)0;
3460 ErrorCode rval = mb->tag_get_handle( tagname,
3461 1, MB_TYPE_HANDLE,
3462 tag, storage|MB_TAG_EXCL,
3463 &def_val );
3464 if (MB_SUCCESS != rval)
3465 return rval;
3466
3467
3468 Range entities;
3469 mb->get_entities_by_handle( 0, entities );
3470 if (entities.empty())
3471 return MB_FAILURE;
3472
3473 // set tag on every other entity to be the entities handle
3474 Range::const_iterator i;
3475 bool odd = true;
3476 for (i = entities.begin(); i != entities.end(); ++i, odd = !odd) {
3477 if (odd) {
3478 const EntityHandle h = *i;
3479 rval = mb->tag_set_data( tag, &h, 1, &h );
3480 if (MB_SUCCESS != rval)
3481 return rval;
3482 }
3483 }
3484
3485 // check values on every entity -- expect default for every other entity
3486 odd = true;
3487 for (i = entities.begin(); i != entities.end(); ++i, odd = !odd) {
3488 EntityHandle val = 0;
3489 rval = mb->tag_get_data( tag, &*i, 1, &val );
3490 if (MB_SUCCESS != rval)
3491 return rval;
3492
3493 if (odd) {
3494 if (val != *i)
3495 return MB_FAILURE;
3496 }
3497 else {
3498 if (val != def_val)
3499 return MB_FAILURE;
3500 }
3501 }
3502
3503 // set tag values on all entities
3504 std::vector<EntityHandle> values( entities.size() );
3505 std::copy( entities.begin(), entities.end(), values.begin() );
3506 rval = mb->tag_set_data( tag, entities, &values[0] );
3507 if (MB_SUCCESS != rval)
3508 return rval;
3509
3510 // check values on every entity -- expect default for every other entity
3511 for (i = entities.begin(); i != entities.end(); ++i) {
3512 EntityHandle val = 0;
3513 rval = mb->tag_get_data( tag, &*i, 1, &val );
3514 if (MB_SUCCESS != rval)
3515 return rval;
3516 if (val != *i)
3517 return MB_FAILURE;
3518 }
3519
3520 // find each entity by tag value
3521 for (i = entities.begin(); i != entities.end(); ++i) {
3522 const EntityHandle h = *i;
3523 const EntityType type = mb->type_from_handle( h );
3524 const void* const tag_vals[] = { &h };
3525 Range range;
3526 rval = mb->get_entities_by_type_and_tag( 0, type, &tag, tag_vals, 1, range );
3527 if (MB_SUCCESS != rval)
3528 return rval;
3529 if (range.size() != 1)
3530 return MB_FAILURE;
3531 if (range.front() != h)
3532 return MB_FAILURE;
3533 }
3534
3535 return MB_SUCCESS;
3536 }
3537
3538
mb_dense_tag_test()3539 ErrorCode mb_dense_tag_test()
3540 {
3541 return mb_common_tag_test( MB_TAG_DENSE );
3542 }
3543
mb_sparse_tag_test()3544 ErrorCode mb_sparse_tag_test()
3545 {
3546 return mb_common_tag_test( MB_TAG_SPARSE );
3547 }
3548
3549 // class to offset hex center nodes
3550 class OffsetHexCenterNodes : public Interface::HONodeAddedRemoved
3551 {
3552 public:
OffsetHexCenterNodes(Interface * mb,double x,double y,double z)3553 OffsetHexCenterNodes(Interface* mb, double x, double y, double z)
3554 : gMB(mb)
3555 {
3556 mCoords[0] = 0.0; mCoords[1] = 0.0; mCoords[2] = 0.0;
3557 mOffset[0] = x; mOffset[1] = y; mOffset[2] = z;
3558 }
3559
~OffsetHexCenterNodes()3560 ~OffsetHexCenterNodes(){}
3561
node_added(EntityHandle node,EntityHandle)3562 void node_added(EntityHandle node, EntityHandle)
3563 {
3564 gMB->get_coords(&node, 1, mCoords);
3565 mCoords[0] += mOffset[0];
3566 mCoords[1] += mOffset[1];
3567 mCoords[2] += mOffset[2];
3568 gMB->set_coords(&node, 1, mCoords);
3569 }
3570
3571 //do nothing
node_removed(EntityHandle)3572 void node_removed( EntityHandle /*node*/) {}
3573
3574 private:
3575 Interface* gMB;
3576 double mCoords[3];
3577 double mOffset[3];
3578 };
3579 #ifdef MOAB_HAVE_NETCDF
mb_entity_conversion_test()3580 ErrorCode mb_entity_conversion_test()
3581 {
3582 ErrorCode error;
3583 Core moab;
3584 Interface* MB = &moab;
3585
3586 //read in a file so you have some data in the database
3587 std::string file_name = TestDir + "/mbtest3.g";
3588 error = MB->load_mesh(file_name.c_str(), NULL, 0);
3589 if (error != MB_SUCCESS)
3590 return error;
3591
3592 Range entities;
3593 EntityHandle meshset;
3594 MB->create_meshset(MESHSET_SET, meshset);
3595
3596 MB->get_entities_by_type(0, MBHEX, entities);
3597 MB->add_entities(meshset, entities);
3598
3599
3600 OffsetHexCenterNodes function_object(MB,0.07, 0.15, 0);
3601
3602 MB->convert_entities(meshset, false, false, true, &function_object);
3603 if (MB_SUCCESS != check_valid_connectivity( MB ))
3604 return MB_FAILURE;
3605
3606 file_name = "hex_mid_volume_nodes.g";
3607 error = MB->write_mesh(file_name.c_str());
3608 if (error != MB_SUCCESS)
3609 return error;
3610
3611 error = MB->delete_mesh();
3612 if (error != MB_SUCCESS)
3613 return error;
3614
3615 error = MB->load_mesh(file_name.c_str(), NULL, 0);
3616 if (error != MB_SUCCESS)
3617 return error;
3618
3619 error = MB->delete_mesh();
3620 if (error != MB_SUCCESS)
3621 return error;
3622
3623
3624
3625
3626
3627 file_name = TestDir + "/mbtest3.g";
3628 error = MB->load_mesh(file_name.c_str(), NULL, 0);
3629 if (error != MB_SUCCESS)
3630 return error;
3631
3632 entities.clear();
3633 MB->get_entities_by_type(0, MBHEX, entities);
3634
3635 MB->create_meshset(MESHSET_SET, meshset);
3636 MB->add_entities(meshset, entities);
3637 MB->convert_entities(meshset, true, true, true);
3638 if (MB_SUCCESS != check_valid_connectivity( MB ))
3639 return MB_FAILURE;
3640
3641 file_name = "hex_mid_edge_face_vol_nodes.g";
3642 error = MB->write_mesh(file_name.c_str());
3643 if (error != MB_SUCCESS)
3644 return error;
3645
3646 error = MB->delete_mesh();
3647 if (error != MB_SUCCESS)
3648 return error;
3649
3650 error = MB->load_mesh(file_name.c_str(), NULL, 0);
3651 if (error != MB_SUCCESS)
3652 return error;
3653
3654 error = MB->delete_mesh();
3655 if (error != MB_SUCCESS)
3656 return error;
3657
3658
3659
3660
3661
3662 file_name = TestDir + "/mbtest3.g";
3663 error = MB->load_mesh(file_name.c_str(), NULL, 0);
3664 if (error != MB_SUCCESS)
3665 return error;
3666
3667 entities.clear();
3668 MB->get_entities_by_type(0, MBVERTEX, entities);
3669 unsigned int original_num_nodes = entities.size();
3670 entities.clear();
3671 MB->get_entities_by_type(0, MBHEX, entities);
3672
3673 MB->create_meshset(MESHSET_SET, meshset);
3674 MB->add_entities(meshset, entities);
3675 MB->convert_entities(meshset, true, false, false);
3676 if (MB_SUCCESS != check_valid_connectivity( MB ))
3677 return MB_FAILURE;
3678
3679 file_name = "hex_mid_edge_nodes.g";
3680 error = MB->write_mesh(file_name.c_str());
3681 if (error != MB_SUCCESS)
3682 return error;
3683
3684 // convert them back to hex8's
3685 MB->convert_entities(meshset, false, false, false);
3686 if (MB_SUCCESS != check_valid_connectivity( MB ))
3687 return MB_FAILURE;
3688
3689 entities.clear();
3690 MB->get_entities_by_type(0, MBVERTEX, entities);
3691 // make sure the higher order nodes really were deleted
3692 if(entities.size() != original_num_nodes)
3693 return MB_FAILURE;
3694
3695 error = MB->delete_mesh();
3696 if (error != MB_SUCCESS)
3697 return error;
3698
3699 error = MB->load_mesh(file_name.c_str(), NULL, 0);
3700 if (error != MB_SUCCESS)
3701 return error;
3702
3703 error = MB->delete_mesh();
3704 if (error != MB_SUCCESS)
3705 return error;
3706
3707
3708
3709
3710 file_name = TestDir + "/mbtest1.g";
3711 error = MB->load_mesh(file_name.c_str(), NULL, 0);
3712 if (error != MB_SUCCESS)
3713 return error;
3714
3715 entities.clear();
3716 MB->get_entities_by_type(0, MBTET, entities);
3717
3718 MB->create_meshset(MESHSET_SET, meshset);
3719 MB->add_entities(meshset, entities);
3720 MB->convert_entities(meshset, true, false, false);
3721 if (MB_SUCCESS != check_valid_connectivity( MB ))
3722 return MB_FAILURE;
3723
3724 file_name = "tet_mid_edge_nodes.g";
3725 error = MB->write_mesh(file_name.c_str());
3726 if (error != MB_SUCCESS)
3727 return error;
3728
3729 error = MB->delete_mesh();
3730 if (error != MB_SUCCESS)
3731 return error;
3732
3733 error = MB->load_mesh(file_name.c_str(), NULL, 0);
3734 if (error != MB_SUCCESS)
3735 return error;
3736
3737 error = MB->delete_mesh();
3738 if (error != MB_SUCCESS)
3739 return error;
3740
3741
3742
3743 file_name = TestDir + "/mbtest1.g";
3744 error = MB->load_mesh(file_name.c_str(), NULL, 0);
3745 if (error != MB_SUCCESS)
3746 return error;
3747
3748 entities.clear();
3749 MB->get_entities_by_type(0, MBTET, entities);
3750
3751 MB->create_meshset(MESHSET_SET, meshset);
3752 MB->add_entities(meshset, entities);
3753 MB->convert_entities(meshset, false, true, false);
3754 if (MB_SUCCESS != check_valid_connectivity( MB ))
3755 return MB_FAILURE;
3756
3757 file_name = "tet_mid_face_nodes.g";
3758 error = MB->write_mesh(file_name.c_str());
3759 if (error != MB_SUCCESS)
3760 return error;
3761
3762 error = MB->delete_mesh();
3763 if (error != MB_SUCCESS)
3764 return error;
3765
3766 error = MB->load_mesh(file_name.c_str(), NULL, 0);
3767 if (error != MB_SUCCESS)
3768 return error;
3769
3770 error = MB->delete_mesh();
3771 if (error != MB_SUCCESS)
3772 return error;
3773
3774
3775
3776
3777
3778
3779
3780 file_name = TestDir + "/mbtest1.g";
3781 error = MB->load_mesh(file_name.c_str(), NULL, 0);
3782 if (error != MB_SUCCESS)
3783 return error;
3784
3785 entities.clear();
3786 MB->get_entities_by_type(0, MBTET, entities);
3787
3788 MB->create_meshset(MESHSET_SET, meshset);
3789 MB->add_entities(meshset, entities);
3790 MB->convert_entities(meshset, true, true, false);
3791 if (MB_SUCCESS != check_valid_connectivity( MB ))
3792 return MB_FAILURE;
3793
3794 file_name = "tet_mid_edge_face_nodes.g";
3795 error = MB->write_mesh(file_name.c_str());
3796 if (error != MB_SUCCESS)
3797 return error;
3798
3799 error = MB->delete_mesh();
3800 if (error != MB_SUCCESS)
3801 return error;
3802
3803 error = MB->load_mesh(file_name.c_str(), NULL, 0);
3804 if (error != MB_SUCCESS)
3805 return error;
3806
3807 error = MB->delete_mesh();
3808 if (error != MB_SUCCESS)
3809 return error;
3810
3811
3812
3813
3814 file_name = TestDir + "/mbtest1.g";
3815 error = MB->load_mesh(file_name.c_str(), NULL, 0);
3816 if (error != MB_SUCCESS)
3817 return error;
3818
3819 // delete all MBTRI's
3820 entities.clear();
3821 error = MB->get_entities_by_type(0, MBTRI, entities);
3822 if (MB_SUCCESS != error)
3823 return error;
3824 error = MB->delete_entities(entities);
3825 if (MB_SUCCESS != error)
3826 return error;
3827
3828 entities.clear();
3829 error = MB->get_entities_by_type(0, MBTET, entities);
3830 if (MB_SUCCESS != error)
3831 return error;
3832
3833 // skin the model
3834 for(Range::iterator tet_iter = entities.begin(); tet_iter != entities.end(); ++tet_iter)
3835 {
3836 std::vector<EntityHandle> adj;
3837 error = MB->get_adjacencies(&(*tet_iter), 1, 2, true, adj);
3838 if (MB_SUCCESS != error)
3839 return error;
3840 for(std::vector<EntityHandle>::iterator tri_iter = adj.begin();
3841 tri_iter != adj.end(); ++tri_iter)
3842 {
3843 std::vector<EntityHandle> up_adj;
3844 MB->get_adjacencies(&(*tri_iter), 1, 3, false, up_adj);
3845 if(up_adj.size() > 1) {
3846 error = MB->delete_entities(&(*tri_iter), 1);
3847 if (MB_SUCCESS != error)
3848 return error;
3849 }
3850 }
3851 }
3852
3853 // create a meshset of the skin
3854 EntityHandle export_meshset;
3855 MB->create_meshset( MESHSET_SET, export_meshset);
3856 Tag material_tag;
3857 MB->tag_get_handle(MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, material_tag);
3858 int block_id = 100;
3859 MB->tag_set_data(material_tag, &export_meshset, 1, &block_id);
3860 entities.clear();
3861 MB->get_entities_by_type(0, MBTRI, entities);
3862 // remove the first few tri's for fun
3863 Range tmp_ents;
3864 tmp_ents.insert(*entities.begin());
3865 entities.erase(entities.begin());
3866 tmp_ents.insert(*entities.begin());
3867 entities.erase(entities.begin());
3868 tmp_ents.insert(*entities.begin());
3869 entities.erase(entities.begin());
3870 tmp_ents.insert(*entities.begin());
3871 entities.erase(entities.begin());
3872
3873 MB->add_entities(export_meshset, entities);
3874
3875 // convert the skin
3876 MB->convert_entities(export_meshset, true, true, false);
3877 if (MB_SUCCESS != check_valid_connectivity( MB ))
3878 return MB_FAILURE;
3879
3880 // make sure our first few tri's were untouched
3881 std::vector<EntityHandle> conn(3);
3882 for(Range::iterator kter=tmp_ents.begin(); kter != tmp_ents.end(); ++kter)
3883 {
3884 MB->get_connectivity(&(*kter), 1, conn);
3885 if(conn.size() != 3)
3886 return MB_FAILURE;
3887 }
3888
3889 // output the skin
3890 file_name = "tri_mid_edge_face_nodes.g";
3891 error = MB->write_mesh(file_name.c_str(), &export_meshset, 1);
3892 if (error != MB_SUCCESS)
3893 return error;
3894
3895 MB->delete_entities(&export_meshset, 1);
3896
3897 error = MB->delete_mesh();
3898 if (error != MB_SUCCESS)
3899 return error;
3900
3901 //read the skin back in
3902 error = MB->load_mesh(file_name.c_str(), NULL, 0);
3903 if (error != MB_SUCCESS)
3904 return error;
3905
3906 entities.clear();
3907 MB->get_entities_by_type(0, MBVERTEX, entities);
3908 // must have 101 nodes
3909 if(entities.size() != 101)
3910 return MB_FAILURE;
3911
3912 error = MB->delete_mesh();
3913 if (error != MB_SUCCESS)
3914 return error;
3915
3916
3917 return MB_SUCCESS;
3918 }
3919 #endif
3920 //! Build two Quads with two edges shared between them. The
3921 //! edges share the same nodes. We should be able to get
3922 //! adjacencies on the edges and get one (correct) quad. We
3923 //! should be able to get the edge adjacencies of the quads
3924 //! and only get 4 (not 5) edges.
3925 //!
3926
mb_forced_adjacencies_test()3927 ErrorCode mb_forced_adjacencies_test()
3928 {
3929 //! first clean up any existing mesh.
3930 ErrorCode error;
3931 Core moab;
3932 Interface* MB = &moab;
3933
3934
3935 //! create 6 nodes, 2 quads and 8 edges. Edge 4 is adjacent
3936 //! to quad 1 and edge 5 is adjacent to quad 2.
3937 //!
3938 //! 4 5 6
3939 //! o--e7---o--e8---o
3940 //! | | |
3941 //! e3 q1 e4 e5 q2 e6
3942 //! | | |
3943 //! o--e1---o--e2---o
3944 //! 1 2 3
3945 //!
3946 double node_coord1[3] = {0., 0., 0.};
3947 double node_coord2[3] = {1., 0., 0.};
3948 double node_coord3[3] = {2., 0., 0.};
3949 double node_coord4[3] = {0., 1., 0.};
3950 double node_coord5[3] = {1., 1., 0.};
3951 double node_coord6[3] = {2., 1., 0.};
3952
3953 EntityHandle node1, node2, node3, node4, node5, node6;
3954 error = MB->create_vertex(node_coord1, node1);
3955 if (error != MB_SUCCESS)
3956 return error;
3957
3958 error = MB->create_vertex(node_coord2, node2);
3959 if (error != MB_SUCCESS)
3960 return error;
3961
3962 error = MB->create_vertex(node_coord3, node3);
3963 if (error != MB_SUCCESS)
3964 return error;
3965
3966 error = MB->create_vertex(node_coord4, node4);
3967 if (error != MB_SUCCESS)
3968 return error;
3969
3970 error = MB->create_vertex(node_coord5, node5);
3971 if (error != MB_SUCCESS)
3972 return error;
3973
3974 error = MB->create_vertex(node_coord6, node6);
3975 if (error != MB_SUCCESS)
3976 return error;
3977
3978 std::vector<EntityHandle> conn(4);
3979 //! create the first quad
3980 EntityHandle quad1;
3981 conn[0] = node1;
3982 conn[1] = node2;
3983 conn[2] = node5;
3984 conn[3] = node4;
3985 error = MB->create_element(MBQUAD, &conn[0], 4, quad1);
3986 if (error != MB_SUCCESS)
3987 return error;
3988
3989 //! create the second quad
3990 EntityHandle quad2;
3991 conn[0] = node2;
3992 conn[1] = node3;
3993 conn[2] = node6;
3994 conn[3] = node5;
3995 error = MB->create_element(MBQUAD, &conn[0], 4, quad2);
3996 if (error != MB_SUCCESS)
3997 return error;
3998
3999 //! create the edges
4000 EntityHandle edge1;
4001 conn.resize(2);
4002 conn[0] = node1;
4003 conn[1] = node2;
4004 error = MB->create_element(MBEDGE, &conn[0], 2, edge1);
4005 if (error != MB_SUCCESS)
4006 return error;
4007
4008 EntityHandle edge2;
4009 conn[0] = node2;
4010 conn[1] = node3;
4011 error = MB->create_element(MBEDGE, &conn[0], 2, edge2);
4012 if (error != MB_SUCCESS)
4013 return error;
4014
4015 EntityHandle edge3;
4016 conn[0] = node1;
4017 conn[1] = node4;
4018 error = MB->create_element(MBEDGE, &conn[0], 2, edge3);
4019 if (error != MB_SUCCESS)
4020 return error;
4021
4022 EntityHandle edge4;
4023 conn[0] = node2;
4024 conn[1] = node5;
4025 error = MB->create_element(MBEDGE, &conn[0], 2, edge4);
4026 if (error != MB_SUCCESS)
4027 return error;
4028
4029 EntityHandle edge5;
4030 conn[0] = node2;
4031 conn[1] = node5;
4032 error = MB->create_element(MBEDGE, &conn[0], 2, edge5);
4033 if (error != MB_SUCCESS)
4034 return error;
4035
4036 EntityHandle edge6;
4037 conn[0] = node3;
4038 conn[1] = node6;
4039 error = MB->create_element(MBEDGE, &conn[0], 2, edge6);
4040 if (error != MB_SUCCESS)
4041 return error;
4042
4043 EntityHandle edge7;
4044 conn[0] = node4;
4045 conn[1] = node5;
4046 error = MB->create_element(MBEDGE, &conn[0], 2, edge7);
4047 if (error != MB_SUCCESS)
4048 return error;
4049
4050 EntityHandle edge8;
4051 conn[0] = node5;
4052 conn[1] = node6;
4053 error = MB->create_element(MBEDGE, &conn[0], 2, edge8);
4054 if (error != MB_SUCCESS)
4055 return error;
4056
4057
4058 //! Edge 4 and 5 share the same nodes, but should be different entities
4059 if (edge4 == edge5)
4060 return MB_FAILURE;
4061
4062 //! Now that the geometry is created start adding the adjacency information
4063 std::vector<EntityHandle> edge_adjacencies1(4);
4064 edge_adjacencies1[0] = edge1;
4065 edge_adjacencies1[1] = edge4;
4066 edge_adjacencies1[2] = edge7;
4067 edge_adjacencies1[3] = edge3;
4068
4069 //! does this (should this) say anything about order of the edges around the
4070 //! quad? Also, does this also build the edge->quad adjacency, or is that
4071 //! does with a separate call?
4072 error = MB->add_adjacencies(quad1, &edge_adjacencies1[0], edge_adjacencies1.size(), true);
4073 if (error != MB_SUCCESS)
4074 return error;
4075
4076 std::vector<EntityHandle> edge_adjacencies2(4);
4077 edge_adjacencies2[0] = edge2;
4078 edge_adjacencies2[1] = edge6;
4079 edge_adjacencies2[2] = edge8;
4080 edge_adjacencies2[3] = edge5;
4081 error = MB->add_adjacencies(quad2, &edge_adjacencies2[0], edge_adjacencies2.size(), true);
4082 if (error != MB_SUCCESS)
4083 return error;
4084
4085 //! now get the adjacencies of each quad.
4086 std::vector<EntityHandle> quad1_adjacencies;
4087 error = MB->get_adjacencies(&(quad1), 1, 1, false, quad1_adjacencies);
4088 if (error != MB_SUCCESS)
4089 return error;
4090
4091
4092 std::sort(quad1_adjacencies.begin(), quad1_adjacencies.end());
4093 std::sort(edge_adjacencies1.begin(), edge_adjacencies1.end());
4094
4095 if (quad1_adjacencies != edge_adjacencies1)
4096 return MB_FAILURE;
4097
4098 std::vector<EntityHandle> quad2_adjacencies;
4099 error = MB->get_adjacencies(&(quad2), 1, 1, false, quad2_adjacencies);
4100 if (error != MB_SUCCESS)
4101 return error;
4102
4103 std::sort(quad2_adjacencies.begin(), quad2_adjacencies.end());
4104 std::sort(edge_adjacencies2.begin(), edge_adjacencies2.end());
4105
4106 if (quad2_adjacencies != edge_adjacencies2)
4107 return MB_FAILURE;
4108
4109 //! try getting the adjacency of edge1 (should be quad1)
4110 std::vector<EntityHandle> edge1_adjacencies;
4111 error = MB->get_adjacencies(&(edge1), 1, 2, false, edge1_adjacencies);
4112 if (error != MB_SUCCESS)
4113 return error;
4114
4115 //! there should be only 1 entity adjacent to edge1
4116 if (edge1_adjacencies.size() != 1)
4117 return MB_FAILURE;
4118
4119 //! and that entity should be quad1
4120 if (edge1_adjacencies[0] != quad1)
4121 return MB_FAILURE;
4122
4123 //! try getting the adjacency of edge6 (should be one)
4124 std::vector<EntityHandle> edge6_adjacencies;
4125 error = MB->get_adjacencies(&(edge6), 1, 2, false, edge6_adjacencies);
4126 if (error != MB_SUCCESS)
4127 return error;
4128
4129 //! there should be only 1 entity adjacent to edge6
4130 if (edge6_adjacencies.size() != 1)
4131 return MB_FAILURE;
4132
4133 //! Now seal up the "gap" caused by edges 4 and 5. Remove edge5
4134 //! from the adjacencies of quad2 and add edge 4 to quad2.
4135
4136 std::vector<EntityHandle> edge5_adjacencies(1, edge5);
4137 error = MB->remove_adjacencies(quad2, &edge5_adjacencies[0], edge5_adjacencies.size());
4138 if (error != MB_SUCCESS)
4139 return error;
4140
4141
4142 std::vector<EntityHandle> edge4_adjacencies(1, edge4);
4143 error = MB->add_adjacencies(quad2, &edge4_adjacencies[0], edge4_adjacencies.size(), true);
4144 if (error != MB_SUCCESS)
4145 return error;
4146
4147 //! get the adjacencies of edge4 and it should return both quads.
4148 std::vector<EntityHandle> quad_adjacencies;
4149 error = MB->get_adjacencies(&(edge4), 1, 2, false, quad_adjacencies);
4150 if (error != MB_SUCCESS)
4151 return error;
4152
4153 //! there should be 2 entities adjacent to edge4
4154 if (quad_adjacencies.size() != 2)
4155 return MB_FAILURE;
4156
4157 //! and they should be quad1 and quad2. Note that we are not saying anything
4158 //! about order in the array.
4159 if ( (quad_adjacencies[0] != quad1 || quad_adjacencies[1] != quad2) &&
4160 (quad_adjacencies[0] != quad2 || quad_adjacencies[1] != quad1) )
4161 return MB_FAILURE;
4162
4163 //! clean up on exit
4164 error = MB->delete_mesh();
4165 if (error != MB_SUCCESS)
4166 return error;
4167
4168
4169 return MB_SUCCESS;
4170 }
4171
4172 /*bool lessnodesZ(const EntityHandle entity_handle1, const EntityHandle entity_handle2)
4173 {
4174 double coords1[3], coords2[3];
4175 gMB->get_coords(entity_handle1, coords1);
4176 gMB->get_coords(entity_handle2, coords2);
4177
4178 return coords2[2] < coords1[2];
4179 }*/
4180
4181 /*void sort_verts(Range vertices)
4182 {
4183 std::vector<EntityHandle> vert_vec(vertices.size());
4184 Range::const_iterator iter;
4185 for (iter = vertices.begin(); iter != vertices.end(); ++iter)
4186 vert_vec.push_back(*iter);
4187 vert_vec.sort(lessnodesZ);
4188 }*/
points_are_coincident(const double * first,const double * second)4189 bool points_are_coincident(const double *first, const double *second)
4190 {
4191 double diff[3];
4192 diff[2] = first[2] - second[2];
4193 // if (diff[2] > 0.001) return false;
4194
4195 diff[0] = first[0] - second[0];
4196 diff[1] = first[1] - second[1];
4197
4198 double length = diff[0]*diff[0] + diff[1]*diff[1] + diff[2]*diff[2];
4199 if(fabs(length) < .001)
4200 return true;
4201
4202 return false;
4203 }
find_coincident_nodes(Interface * gMB,Range vertices,std::vector<std::pair<EntityHandle,EntityHandle>> & coin_nodes)4204 ErrorCode find_coincident_nodes(Interface* gMB, Range vertices,
4205 std::vector< std::pair<EntityHandle,EntityHandle> > &coin_nodes)
4206 {
4207 double first_coords[3], second_coords[3];
4208 Range::const_iterator iter, jter;
4209 std::pair<EntityHandle, EntityHandle> coincident_pair;
4210 ErrorCode result;
4211
4212 for (iter = vertices.begin(); iter != vertices.end(); ++iter)
4213 {
4214 result = gMB->get_coords(&(*iter),1, first_coords);
4215 if (result != MB_SUCCESS)
4216 return result;
4217
4218 for (jter = iter; jter != vertices.end(); ++jter)
4219 {
4220 if (*iter != *jter)
4221 {
4222 result = gMB->get_coords(&(*jter), 1, second_coords);
4223 if (result != MB_SUCCESS)
4224 return result;
4225
4226 if(points_are_coincident(first_coords, second_coords))
4227 {
4228 coincident_pair.first = *iter;
4229 coincident_pair.second = *jter;
4230 coin_nodes.push_back(coincident_pair);
4231 }
4232 }
4233 }
4234 }
4235 return MB_SUCCESS;
4236 }
4237
find_coincident_elements(Interface * gMB,Range entities,int num_nodes,std::vector<std::pair<EntityHandle,EntityHandle>> & coin)4238 ErrorCode find_coincident_elements(Interface* gMB, Range entities, int num_nodes,
4239 std::vector< std::pair<EntityHandle,EntityHandle> > &coin)
4240 {
4241 double coords1[8][3], coords2[8][3];
4242 Range::iterator iter, jter;
4243 std::vector<EntityHandle> conn(8);
4244 std::pair<EntityHandle, EntityHandle> coincident_pair;
4245 int i = 0,/* j = 0,*/ ii = 0;
4246
4247 for(iter = entities.begin(); iter != entities.end(); ++iter)
4248 {
4249 // Get the coordinates for the element corners.
4250 if(gMB->get_connectivity(&(*iter), 1, conn) != MB_SUCCESS)
4251 return MB_FAILURE;
4252 for(ii=0; ii<num_nodes; ii++)
4253 {
4254 if(gMB->get_coords(&(conn[ii]), 1, coords1[ii]) != MB_SUCCESS)
4255 return MB_FAILURE;
4256 }
4257
4258 for(jter = iter; jter != entities.end(); ++jter)
4259 {
4260 if(*iter != *jter)
4261 {
4262 // Elements should be the same sense to merge.
4263 if(gMB->get_connectivity(&(*jter), 1, conn) != MB_SUCCESS)
4264 return MB_FAILURE;
4265
4266 for (int tq = 0; tq < num_nodes; tq++)
4267 if(gMB->get_coords(&(conn[tq]), 1, coords2[tq]) != MB_SUCCESS)
4268 return MB_FAILURE;
4269 // if(gMB->get_coords(&(conn[0]), 1, coords2[0]) != MB_SUCCESS)
4270 // return MB_FAILURE;
4271
4272 // Find if first node is coincident before testing the rest.
4273 bool first = false;
4274 for(i=0; i<num_nodes; i++)
4275 {
4276 if(points_are_coincident(coords1[i], coords2[0])) {
4277 /* cout <<"first("<<i<<",0) - ";
4278 cout <<" coords1["<<i<<"] = ("
4279 <<coords1[i][0]<<","
4280 <<coords1[i][1]<<","
4281 <<coords1[i][2]<<") ";
4282 cout <<" coords2["<<0<<"] = ("
4283 <<coords2[0][0]<<","
4284 <<coords2[0][1]<<","
4285 <<coords2[0][2]<<")\n";*/
4286 first = true;
4287 break;
4288 }
4289 }
4290 // TEST -- Find if second node is coincident before testing the rest.
4291 bool second = false;
4292 for(int t2=0; t2<num_nodes; t2++)
4293 {
4294 if(points_are_coincident(coords1[t2], coords2[1])) {
4295 /* cout <<"second("<<t2<<",1) - ";
4296 cout <<" coords1["<<t2<<"] = ("
4297 <<coords1[t2][0]<<","
4298 <<coords1[t2][1]<<","
4299 <<coords1[t2][2]<<") ";
4300 cout <<" coords2["<<1<<"] = ("
4301 <<coords2[1][0]<<","
4302 <<coords2[1][1]<<","
4303 <<coords2[1][2]<<")\n";*/
4304 second = true;
4305 break;
4306 }
4307 }
4308 // TEST -- Find if second node is coincident before testing the rest.
4309 bool third = false;
4310 for(int ti=0; ti<num_nodes; ti++)
4311 {
4312 if(points_are_coincident(coords1[ti], coords2[2])) {
4313 /* cout <<"third("<<ti<<",2) - ";
4314 cout <<" coords1["<<ti<<"] = ("
4315 <<coords1[ti][0]<<","
4316 <<coords1[ti][1]<<","
4317 <<coords1[ti][2]<<") ";
4318 cout <<" coords2["<<1<<"] = ("
4319 <<coords2[2][0]<<","
4320 <<coords2[2][1]<<","
4321 <<coords2[2][2]<<")\n";*/
4322 third = true;
4323 break;
4324 }
4325 }
4326 if ((first)&&(second)&&(third)) {
4327 cout <<"i = "<<i<<"\n";
4328 for (int tii = 0; tii < num_nodes; tii++) {
4329 cout <<" coords1["<<tii<<"] = ("
4330 <<coords1[tii][0]<<","
4331 <<coords1[tii][1]<<","
4332 <<coords1[tii][2]<<") ";
4333 cout <<" coords2["<<tii<<"] = ("
4334 <<coords2[tii][0]<<","
4335 <<coords2[tii][1]<<","
4336 <<coords2[tii][2]<<")\n";
4337 }
4338 }
4339
4340 if(i < num_nodes)
4341 {
4342 for(ii=1; ii<num_nodes; ii++)
4343 {
4344 if(gMB->get_coords(&(conn[ii]), 1, coords2[ii]) != MB_SUCCESS)
4345 return MB_FAILURE;
4346 }
4347 /*
4348 for(j=1; j<num_nodes; j++)
4349 {
4350
4351 if(!points_are_coincident(coords1[j], coords2[(j+i)%num_nodes]))
4352 break;
4353 }
4354 if(j == num_nodes)*/
4355 if ((first)&&(second)&&(third))
4356 {
4357 coincident_pair.first = *iter;
4358 coincident_pair.second = *jter;
4359 coin.push_back(coincident_pair);
4360 }
4361 }
4362 }
4363 }
4364 }
4365
4366 return MB_SUCCESS;
4367 }
4368
4369 #ifdef MOAB_HAVE_NETCDF
mb_merge_test()4370 ErrorCode mb_merge_test()
4371 {
4372 Core moab;
4373 Interface* MB = &moab;
4374
4375 time_t begin_time = clock();
4376 unsigned int i;
4377 ErrorCode result;
4378 Skinner Skinner_Obj(MB);
4379
4380 std::string test_files[] = {std::string("cell1.gen"),
4381 std::string("cell2.gen")};
4382 /* std::string("cell3.gen"),
4383 std::string("cell4.gen"),
4384 std::string("cell5.gen"),
4385 std::string("cell6.gen"),
4386 std::string("cell7.gen"),
4387 std::string("cell8.gen"),
4388 std::string("cell9.gen"),
4389 std::string("cell10.gen"),
4390 std::string("cell11.gen"),
4391 std::string("cell12.gen"),
4392 std::string("cell13.gen"),
4393 std::string("cell14.gen"),
4394 std::string("cell15.gen"),
4395 std::string("cell16.gen"),
4396 std::string("cell17.gen"),
4397 std::string("cell18.gen"),
4398 std::string("cell19.gen"),
4399 std::string("cell20.gen"),
4400 std::string("cell21.gen"),
4401 std::string("cell22.gen"),
4402 std::string("cell23.gen"),
4403 std::string("cell24.gen")};*/
4404
4405 /*std::vector<Range> entities(sizeof(test_files));
4406 std::vector<Range> forward_lower(sizeof(test_files));
4407 std::vector<Range> reverse_lower(sizeof(test_files));
4408 std::vector<Range> nodes(sizeof(test_files));*/
4409 Range entities;
4410 Range forward_lower;
4411 Range reverse_lower;
4412 Range faces;
4413 Range nodes;
4414
4415 cout << "---Starting Merge Tests---" << endl << endl;
4416 for(i=0; i<(sizeof(test_files)/sizeof(std::string)); i++)
4417 {
4418
4419 cout << "---Testing:\"" << test_files[i] << "\"---" << endl;
4420 result = MB->load_mesh(test_files[i].c_str(), NULL, 0);
4421 if (result == MB_SUCCESS)
4422 cout <<"Loaded "<<test_files[i]<<"\n";
4423 //get Hexes from model
4424 }
4425 result = MB->get_entities_by_type(0, MBHEX, entities);
4426 if (MB_SUCCESS != result)
4427 return result;
4428 Skinner_Obj.find_skin(0,entities,false,forward_lower,&reverse_lower);
4429 // cout <<"num hexes = "<<entities.size()<<"\n";
4430 // cout <<"fl = "<<forward_lower.size()<<" rl = "<<reverse_lower.size()<<"\n";
4431
4432 // Range::const_iterator iter;
4433 int dim = 0;
4434 // int num_ents = 1;
4435 result = MB->get_adjacencies(forward_lower, dim, true, nodes, Interface::UNION);
4436 // cout <<"nodes.size() = "<<nodes.size() <<"\n";
4437
4438 // result = MB->get_entities_by_type(0, MBQUAD, faces);
4439 // cout <<"num faces = "<<faces.size() <<"\n";
4440
4441 std::vector<std::pair<EntityHandle, EntityHandle> > coin_nodes;
4442 // cout <<"Begining sort...\n";
4443 // std::sort(nodes.begin(),nodes.end(),lessnodesZ);
4444 // cout <<"Ending sort...\n";
4445 result = find_coincident_nodes(MB,nodes, coin_nodes);
4446 cout <<"coin_nodes.size() = "<<coin_nodes.size() <<"\n";
4447 std::vector< std::pair<EntityHandle, EntityHandle> >::iterator n_iter;
4448 for (n_iter=coin_nodes.begin(); n_iter != coin_nodes.end(); ++n_iter) {
4449 result = MB->merge_entities((*n_iter).first, (*n_iter).second, false, true);
4450 if (MB_SUCCESS != result)
4451 return result;
4452 }
4453 /* std::vector<std::pair<EntityHandle, EntityHandle> > coin_faces;
4454 int nodes_per_elt = 4;
4455 result = find_coincident_elements(forward_lower, nodes_per_elt, coin_faces);
4456 if (result != MB_SUCCESS) cout <<"find_coincident_elements fail!\n";
4457 cout <<"coin_faces.size() = "<<coin_faces.size() <<"\n";
4458 std::vector< std::pair<EntityHandle, EntityHandle> >::iterator f_iter;
4459 for (f_iter=coin_faces.begin(); f_iter != coin_faces.end(); ++f_iter)
4460 MB->merge_entities((*f_iter).first, (*f_iter).second, true, true);*/
4461 /*
4462 std::vector<std::pair<EntityHandle, EntityHandle> > coin_fl;
4463 nodes_per_elt = 4;
4464 result = find_coincident_elements(entities, nodes_per_elt, coin_fl);
4465 cout <<"coin_fl.size() = "<<coin_fl.size() <<"\n";
4466 */
4467 int num_ents;
4468 if ((MB_SUCCESS == MB->get_number_entities_by_dimension(0, 3, num_ents) &&
4469 0 != num_ents) ||
4470 (MB_SUCCESS == MB->get_number_entities_by_dimension(0, 2, num_ents) &&
4471 0 != num_ents))
4472 result = MB->write_mesh("merge_test.g");
4473 ;
4474
4475
4476 double clocks_per_sec = (double) CLOCKS_PER_SEC;
4477 double real_time = difftime(time(NULL), begin_time);
4478 cout <<"TIME: "<<(real_time/clocks_per_sec)<<" seconds.\n";
4479 return result;
4480 }
4481 #endif
4482
mb_merge_update_test()4483 ErrorCode mb_merge_update_test()
4484 {
4485 Core moab;
4486 Interface* mb = &moab;
4487 ErrorCode rval;
4488
4489 // create two quads with a coincident edge pair
4490 double coords[] = { 0, 0, 0,
4491 1, 0, 0,
4492 1, 1, 0,
4493 0, 1, 0,
4494 1, 1, 0,
4495 1, 0, 0,
4496 2, 0, 0,
4497 2, 1, 0 };
4498 EntityHandle verts[8];
4499 for (int i = 0; i < 8; ++i)
4500 mb->create_vertex( coords + 3*i, verts[i] );
4501 EntityHandle quad1, quad2, edge1, edge2;
4502 mb->create_element( MBQUAD, verts, 4, quad1 );
4503 mb->create_element( MBQUAD, verts+4, 4, quad2 );
4504 mb->create_element( MBEDGE, verts+1, 2, edge1 );
4505 mb->create_element( MBEDGE, verts+4, 2, edge2 );
4506
4507 // create two tracking sets containing the vertices
4508 // and edge of each quad
4509 EntityHandle set1, set2;
4510 mb->create_meshset( MESHSET_TRACK_OWNER|MESHSET_SET, set1 );
4511 mb->create_meshset( MESHSET_TRACK_OWNER|MESHSET_ORDERED, set2 );
4512 mb->add_entities( set1, verts, 4 );
4513 mb->add_entities( set2, verts+4, 4 );
4514 mb->add_entities( set1, &edge1, 1 );
4515 mb->add_entities( set2, &edge2, 1 );
4516
4517 // now merge the coincident edges
4518 rval = mb->merge_entities( verts[1], verts[5], false, true );
4519 if (MB_SUCCESS != rval) {
4520 std::cerr << "Merge failed at " << __FILE__ << ":" << __LINE__ << std::endl;
4521 return rval;
4522 }
4523 rval = mb->merge_entities( verts[2], verts[4], false, true );
4524 if (MB_SUCCESS != rval) {
4525 std::cerr << "Merge failed at " << __FILE__ << ":" << __LINE__ << std::endl;
4526 return rval;
4527 }
4528 rval = mb->merge_entities( edge1, edge2, false, true );
4529 if (MB_SUCCESS != rval) {
4530 std::cerr << "Merge failed at " << __FILE__ << ":" << __LINE__ << std::endl;
4531 return rval;
4532 }
4533
4534 // check that there is only one edge and that it has the correct connectivity
4535 Range r;
4536 mb->get_entities_by_type( 0, MBEDGE, r );
4537 if (r.size() != 1 || r.front() != edge1) {
4538 std::cerr << "Edge merge failed at " << __FILE__ << ":" << __LINE__ << std::endl;
4539 return MB_FAILURE;
4540 }
4541 std::vector<EntityHandle> exp(verts+1, verts+3), act;
4542 mb->get_connectivity( &edge1, 1, act );
4543 if (exp != act) {
4544 std::cerr << "Incorrect conn for edge at " << __FILE__ << ":" << __LINE__ << std::endl;
4545 return MB_FAILURE;
4546 }
4547
4548 // check that quad connectivity is as expected
4549 exp = std::vector<EntityHandle>(verts, verts+4);
4550 act.clear();
4551 mb->get_connectivity( &quad1, 1, act );
4552 if (exp != act) {
4553 std::cerr << "Incorrect conn for quad at " << __FILE__ << ":" << __LINE__ << std::endl;
4554 return MB_FAILURE;
4555 }
4556 exp.resize(4);
4557 exp[0] = verts[2];
4558 exp[1] = verts[1];
4559 exp[2] = verts[6];
4560 exp[3] = verts[7];
4561 act.clear();
4562 mb->get_connectivity( &quad2, 1, act );
4563 if (exp != act) {
4564 std::cerr << "Incorrect conn for quad at " << __FILE__ << ":" << __LINE__ << std::endl;
4565 return MB_FAILURE;
4566 }
4567
4568 // check that set contents are correctly updated
4569 exp = std::vector<EntityHandle>(verts, verts+4);
4570 exp.push_back( edge1 );
4571 act.clear();
4572 mb->get_entities_by_handle( set1, act );
4573 std::sort( exp.begin(), exp.end() );
4574 std::sort( act.begin(), act.end() );
4575 if (exp != act) {
4576 std::cerr << "Incorrect set contents at " << __FILE__ << ":" << __LINE__ << std::endl;
4577 std::cerr << " Expected: ";
4578 std::copy( exp.begin(), exp.end(), std::ostream_iterator<EntityHandle>(std::cerr, " ") );
4579 std::cerr << std::endl << " Actual : ";
4580 std::copy( act.begin(), act.end(), std::ostream_iterator<EntityHandle>(std::cerr, " ") );
4581 std::cerr << std::endl;
4582 return MB_FAILURE;
4583 }
4584
4585 exp.resize(5);
4586 exp[0] = verts[2];
4587 exp[1] = verts[1];
4588 exp[2] = verts[6];
4589 exp[3] = verts[7];
4590 exp[4] = edge1;
4591 act.clear();
4592 mb->get_entities_by_handle( set2, act );
4593 if (exp != act) {
4594 std::cerr << "Incorrect set contents at " << __FILE__ << ":" << __LINE__ << std::endl;
4595 std::cerr << " Expected: ";
4596 std::copy( exp.begin(), exp.end(), std::ostream_iterator<EntityHandle>(std::cerr, " ") );
4597 std::cerr << std::endl << " Actual : ";
4598 std::copy( act.begin(), act.end(), std::ostream_iterator<EntityHandle>(std::cerr, " ") );
4599 std::cerr << std::endl;
4600 return MB_FAILURE;
4601 }
4602
4603 return MB_SUCCESS;
4604 }
4605 #ifdef MOAB_HAVE_NETCDF
mb_stress_test()4606 ErrorCode mb_stress_test()
4607 {
4608 ErrorCode error;
4609 Core moab;
4610 Interface* MB = &moab;
4611
4612 cout << " Beginning Stress Test . . ." << endl;
4613 cout << "\n Reading elements" << endl;
4614 clock_t start = clock();
4615 clock_t total_start = clock();
4616
4617 //read in a file so you have some data in the database
4618 std::string file_name = "mb_big_test.g";
4619 error = MB->load_mesh(file_name.c_str(), NULL, 0);
4620 if (error != MB_SUCCESS)
4621 return error;
4622
4623 clock_t stop = clock();
4624
4625 int num_entities_local;
4626 error = MB->get_number_entities_by_type(0, MBHEX, num_entities_local);
4627 if (error != MB_SUCCESS)
4628 return error;
4629
4630 if (num_entities_local != 256000)
4631 return error;
4632
4633 float time = static_cast<float>(stop - start)/CLOCKS_PER_SEC;
4634 float speed = num_entities_local/time;
4635 cout << " Read " << num_entities_local << " entities"
4636 << " in " << time << " seconds" << endl;
4637 cout << " at " << speed << " elements per second." << endl;
4638
4639
4640 cout << "\n Transforming and copying elements" << endl;
4641 start = clock();
4642
4643 Range hexes;
4644 error = MB->get_entities_by_type(0, MBHEX, hexes);
4645 if (error != MB_SUCCESS)
4646 return error;
4647
4648
4649 std::vector<EntityHandle> conn;
4650 Range::iterator iter;
4651 for (iter = hexes.begin(); iter != hexes.end(); ++iter)
4652 {
4653 error = MB->get_connectivity(&(*iter), 1, conn);
4654 if (error != MB_SUCCESS)
4655 return error;
4656
4657 double coords[3];
4658 int i = 0;
4659 std::vector<EntityHandle> vertex_handle(8);
4660 EntityHandle element_handle;
4661 std::vector<EntityHandle>::iterator jter;
4662
4663 for (jter = conn.begin(); jter != conn.end(); ++jter)
4664 {
4665 error = MB->get_coords(&(*jter), 1, coords);
4666 if (error != MB_SUCCESS)
4667 return error;
4668 coords[2] += 20.0;
4669 error = MB->create_vertex(coords, vertex_handle[i++]);
4670 if (error != MB_SUCCESS)
4671 return error;
4672 }
4673 error = MB->create_element(MBHEX, &vertex_handle[0], 8, element_handle);
4674 if (error != MB_SUCCESS)
4675 return error;
4676 }
4677
4678
4679 stop = clock();
4680 time = static_cast<float>(stop - start)/CLOCKS_PER_SEC;
4681
4682 cout << " Transformed and created " << num_entities_local << " entities"
4683 << " in " << time << " seconds" << endl;
4684
4685 // Create mesh set
4686 cout << "\n Creating meshset" << endl;
4687 start = clock();
4688 error = MB->get_entities_by_type(0, MBHEX, hexes);
4689 if (error != MB_SUCCESS)
4690 return error;
4691
4692 if (hexes.size() != 512000)
4693 return MB_FAILURE;
4694
4695 EntityHandle mesh_set;
4696 error = MB->create_meshset( MESHSET_SET, mesh_set );
4697 if (error != MB_SUCCESS)
4698 return error;
4699
4700 error = MB->add_entities(mesh_set, hexes);
4701 if (error != MB_SUCCESS)
4702 return error;
4703
4704 stop = clock();
4705 time = static_cast<float>(stop - start)/CLOCKS_PER_SEC;
4706
4707 cout << " Created meshset with " << hexes.size() << " entities"
4708 << " in " << time << " seconds" << endl;
4709
4710 cout << "\n Writing 512K element file . . ." << endl;
4711 start = clock();
4712
4713 // set the block tag
4714 Tag tag_handle;
4715 ErrorCode result = MB->tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, tag_handle ) ;
4716 if(result != MB_SUCCESS)
4717 return result;
4718
4719 int id = 1;
4720 result = MB->tag_set_data( tag_handle, &mesh_set, 1, &id ) ;
4721 if(result != MB_SUCCESS)
4722 return result;
4723
4724 std::vector<EntityHandle> output_list;
4725 output_list.push_back(mesh_set);
4726
4727 file_name = "mb_stress_out.g";
4728 error = MB->write_mesh(file_name.c_str(), &output_list[0], output_list.size());
4729 if (error != MB_SUCCESS)
4730 return error;
4731
4732 stop = clock();
4733 time = static_cast<float>(stop - start)/CLOCKS_PER_SEC;
4734
4735 cout << " Wrote file with " << hexes.size() << " entities"
4736 << " in " << time << " seconds" << endl;
4737
4738 clock_t total_stop = clock();
4739 time = static_cast<float>(total_stop - total_start)/CLOCKS_PER_SEC;
4740
4741 cout << " Total time: " << time << " seconds." << endl;
4742
4743 MB->delete_mesh();
4744
4745 return MB_SUCCESS;
4746 }
4747 #endif
4748
mb_canon_number_test()4749 ErrorCode mb_canon_number_test()
4750 {
4751 Core moab;
4752 Interface* MB = &moab;
4753
4754 // various tests for canonical ordering
4755
4756 // CN::AdjacentSubEntities
4757 std::vector<int> vec1, vec2;
4758 ErrorCode result;
4759
4760 EntityType this_type;
4761
4762 for (this_type = MBEDGE; this_type != MBKNIFE; this_type++) {
4763
4764 for (int i = 0; i < CN::VerticesPerEntity(this_type); i++) {
4765 // test for edges and faces
4766 for (int dim = 1; dim <= CN::Dimension(this_type); dim++) {
4767 // get the sides adjacent to this vertex
4768 vec1.clear();
4769 int temp_result = CN::AdjacentSubEntities(this_type, &i, 1, 0, dim, vec1);
4770
4771 if (0 != temp_result ||
4772 vec1.size() > (unsigned int) CN::NumSubEntities(this_type, dim)) {
4773 cout << "failed getting sides for type " << CN::EntityTypeName(this_type)
4774 << " dimension" << dim << endl;
4775 return MB_FAILURE;
4776 }
4777
4778
4779 // now get the vertices shared by these sides
4780 vec2.clear();
4781 temp_result =
4782 CN::AdjacentSubEntities(this_type, &vec1[0], vec1.size(), dim, 0,
4783 vec2);
4784
4785 // vertex side recovered should be i
4786 if (0 != temp_result ||
4787 // if dimension is same as DIMENSION(this_type), will get back all the
4788 // vertices in the entity
4789 (dim == CN::Dimension(this_type) &&
4790 vec2.size() != (unsigned int) CN::VerticesPerEntity(this_type)) ||
4791 // otherwise, we should get back only one vertex, and it should be the one
4792 // we started with
4793 (dim != CN::Dimension(this_type) &&
4794 (vec2.size() != 1 || vec2[0] != i))) {
4795 cout << "traversal from verts to sides to verts failed for " << endl
4796 << "vertex " << i << " type " << CN::EntityTypeName(this_type)
4797 << " dimension " << dim << endl;
4798 return MB_FAILURE;
4799 }
4800 }
4801 }
4802 }
4803
4804 // CN::side_number
4805
4806 // create vertices to use later
4807 double xyz[3] = {0.0, 0.0, 0.0};
4808 EntityHandle vertex_handles[8];
4809 for (int i = 0; i < 8; i++) {
4810 result = MB->create_vertex(xyz, vertex_handles[i]);
4811 assert(result == MB_SUCCESS);
4812 }
4813 int side, sense, offset;
4814
4815 EntityHandle this_entity;
4816
4817 for (this_type = MBEDGE; this_type != MBKNIFE; this_type++) {
4818
4819 // skip remainder of the loop for MBPOLYGONS and POLYHEDRA, which don't follow
4820 // the standard canonical ordering
4821 if (this_type == MBPOLYGON || this_type == MBPOLYHEDRON)
4822 continue;
4823
4824 // make an entity of this type
4825 result = MB->create_element(this_type, vertex_handles,
4826 CN::VerticesPerEntity(this_type),
4827 this_entity);
4828 if (MB_SUCCESS != result || 0 == this_entity) {
4829 cout << "failed to create entity of type "
4830 << CN::EntityTypeName(this_type) << endl;
4831 return MB_FAILURE;
4832 }
4833
4834 // now get the connectivity vector *
4835 const EntityHandle *entity_vertices;
4836 int num_verts;
4837 result = MB->get_connectivity(this_entity, entity_vertices, num_verts);
4838 if (MB_SUCCESS != result ||
4839 num_verts != CN::VerticesPerEntity(this_type)) {
4840 cout << "failed to get connectivity for entity type "
4841 << CN::EntityTypeName(this_type) << endl;
4842 return MB_FAILURE;
4843 }
4844
4845 // for each dimension
4846 for (int dim = 1; dim <= CN::Dimension(this_type); dim++) {
4847 // for each side of this dimension
4848 const CN::ConnMap &cm = CN::mConnectivityMap[this_type][dim-1];
4849 int tmp_conn[moab::MAX_SUB_ENTITY_VERTICES];
4850
4851 for (int side_no = 0; side_no < CN::NumSubEntities(this_type, dim); side_no++) {
4852
4853 for (int j = 0; j < moab::MAX_SUB_ENTITY_VERTICES; j++) tmp_conn[j] = cm.conn[side_no][j];
4854 int temp_result =
4855 CN::SideNumber(this_type,
4856 tmp_conn,
4857 CN::VerticesPerEntity(CN::SubEntityType(this_type, dim, side_no)),
4858 dim, side, sense, offset);
4859 if (0 != temp_result) {
4860 cout << "call to CN::side_number failed with non-success result"
4861 << " for type "
4862 << CN::EntityTypeName(this_type) << " dimension " << dim
4863 << " side no " << side_no << endl;
4864 return MB_FAILURE;
4865 }
4866
4867 // side number should be the same as side_no, sense should be forward, offset should
4868 // be zero
4869 if (side != side_no || sense != 1 || offset != 0) {
4870 cout << "call to CN::side_number failed for type "
4871 << CN::EntityTypeName(this_type) << " dimension " << dim << " side no "
4872 << side_no << endl
4873 << "side, sense, offset = " << side << " " << sense << " " << offset << endl;
4874 return MB_FAILURE;
4875 }
4876 }
4877 }
4878
4879 // destroy the entity of this_type
4880 result = MB->delete_entities(&this_entity, 1);
4881 if (MB_SUCCESS != result)
4882 return result;
4883 }
4884
4885 return MB_SUCCESS;
4886 }
mb_side_number_test()4887 ErrorCode mb_side_number_test()
4888 {
4889 ErrorCode rval;
4890 Core moab;
4891 Interface *mb = &moab;
4892
4893 /* Create faces of a wedge: */
4894 /*
4895 4
4896 /|\
4897 / | \
4898 / | \
4899 / 2 \
4900 3.../.\...5
4901 | / \ |
4902 | / \ |
4903 |/ \| 6 // off vertex
4904 0_________1
4905 */
4906
4907 const double coords[][3] = { { 0, 0, 0 },
4908 { 2, 0, 0 },
4909 { 1, 0, 1 },
4910 { 0, 2, 0 },
4911 { 2, 2, 0 },
4912 { 1, 2, 1 },
4913 { 3, 1, 0 },
4914 };
4915 EntityHandle verts[7];
4916 for (unsigned i = 0; i < 7; ++i)
4917 mb->create_vertex( coords[i], verts[i] );
4918
4919 EntityHandle faces[6];
4920 EntityHandle tri[] = { verts[0], verts[1], verts[2] };
4921 EntityHandle tri2[] = { verts[3], verts[4], verts[5] };
4922 EntityHandle quad1[] = { verts[0], verts[1], verts[5], verts[3] };
4923 EntityHandle quad2[] = { verts[1], verts[5], verts[4], verts[2] };
4924 EntityHandle quad3[] = { verts[2], verts[4], verts[3], verts[0] };
4925 rval = mb->create_element( MBTRI, tri, 3, faces[0] );MB_CHK_ERR(rval);
4926 rval = mb->create_element( MBQUAD, quad1, 4, faces[1] );MB_CHK_ERR(rval);
4927 rval = mb->create_element( MBQUAD, quad2, 4, faces[2] );MB_CHK_ERR(rval);
4928 rval = mb->create_element( MBQUAD, quad3, 4, faces[3] );MB_CHK_ERR(rval);
4929 rval = mb->create_element( MBTRI, tri2, 3, faces[4] );MB_CHK_ERR(rval);
4930
4931 EntityHandle prism;
4932 rval = mb->create_element( MBPRISM, verts, 6, prism);MB_CHK_ERR(rval);
4933
4934 /*
4935 * side_number(const EntityHandle parent,
4936 const EntityHandle child,
4937 int &side_number,
4938 int &sense,
4939 int &offset)
4940 */
4941 int side_n, sen, ofs;
4942 rval = mb->side_number(prism, faces[0], side_n, sen, ofs);MB_CHK_ERR(rval);
4943 CHECK_EQUAL(side_n, 3);
4944 CHECK_EQUAL(sen, -1);
4945 CHECK_EQUAL(ofs, 0);
4946
4947 // this diagonal should not be on the prism (not an edge of the prism)
4948 EntityHandle diagonal1;
4949 EntityHandle diag[] = { verts[2], verts[3] };
4950 rval = mb->create_element( MBEDGE, diag, 2, diagonal1);MB_CHK_ERR(rval);
4951 rval = mb->side_number(prism, diagonal1, side_n, sen, ofs);
4952 // expected fail
4953 if (rval != MB_FAILURE)
4954 return MB_FAILURE;
4955
4956 // create another triangle, connected to the prism, but not on the side
4957 EntityHandle tri3[] = { verts[3], verts[4], verts[6] };
4958 rval = mb->create_element( MBTRI, tri3, 3, faces[5] );MB_CHK_ERR(rval);
4959 rval = mb->side_number(prism, faces[5], side_n, sen, ofs);
4960 // expected fail
4961 if (rval != MB_FAILURE)
4962 return MB_FAILURE;
4963
4964 return MB_SUCCESS;
4965 }
4966
mb_poly_test()4967 ErrorCode mb_poly_test()
4968 {
4969 Core moab;
4970 Interface* mb = &moab;
4971
4972 // test polygon and polyhedron representation
4973 // create a couple of polygons; vertices first
4974 const double vert_pos[48] = {
4975 -1, 0, 0,
4976 1, 0, 0,
4977 2, 0, 0,
4978 2, 1, 0,
4979 1, 1, 0,
4980 0, 2, 0,
4981 -1, 1, 0,
4982 -2, 1, 0,
4983 -2, 0, 0,
4984 -2, -1, 0,
4985 -1, -1, 0,
4986 -1, -2, 0,
4987 1, -2, 0,
4988 1, -1, 0,
4989 2, -1, 0,
4990 1.5, .5, 1};
4991
4992 EntityHandle verts[16];
4993 ErrorCode result;
4994 int i;
4995 for (i = 0; i < 16; i++) {
4996 result = mb->create_vertex(&vert_pos[3*i], verts[i]);
4997 if (MB_SUCCESS != result) {
4998 std::cout << "Failed to create vertex " << i << " in mb_poly_test." << std::endl;
4999 return result;
5000 }
5001 }
5002
5003 // then polygons
5004 const int connect_idx[] =
5005 {
5006 1, 2, 5, 6, 7,
5007 2, 3, 4, 5,
5008 5, 4, 6,
5009 7, 6, 8,
5010 0, 1, 7, 8,
5011 0, 1, 2, 3, 14, 13, 12, 11, 10, 9,
5012 0, 9, 10, 11, 12, 13, 14, 3, 4, 6, 8,
5013 2, 3, 15, 5,
5014 3, 4, 5, 15
5015 };
5016
5017 int num_connect_idx[] = {5, 4, 3, 3, 4, 10, 11, 4, 4};
5018
5019 EntityHandle polygons[9], temp_connect[12];
5020 int idx = 0, nump = 0;
5021 ErrorCode tmp_result;
5022 while (nump < 9) {
5023 for (i = 0; i < num_connect_idx[nump]; i++)
5024 temp_connect[i] = verts[connect_idx[idx+i]];
5025
5026 tmp_result = mb->create_element(MBPOLYGON, temp_connect, num_connect_idx[nump],
5027 polygons[nump]);
5028 if (MB_SUCCESS != tmp_result) {
5029 std::cout << "mb_poly_test: create_element failed for polygon " << i << "." << std::endl;
5030 result = tmp_result;
5031 nump++;
5032 continue;
5033 }
5034
5035 idx += num_connect_idx[nump];
5036 nump++;
5037 }
5038
5039 if (MB_SUCCESS != result) return result;
5040
5041 // ok, made 'em; now get all the vertices and make sure they're the same
5042 const EntityHandle *connect;
5043 int num_connect;
5044 idx = 0;
5045 int j;
5046 for (i = 0; i < 9; i++) {
5047 tmp_result = mb->get_connectivity(polygons[i], connect, num_connect);
5048 if (MB_SUCCESS != tmp_result || num_connect != num_connect_idx[i]) {
5049 std::cout << "mb_poly_test: get_connectivity test failed for polygon " << i << "." << std::endl;
5050 result = (tmp_result != MB_SUCCESS ? tmp_result : MB_FAILURE);
5051 continue;
5052 }
5053
5054 for (j = 0; j < num_connect; j++) {
5055 if (connect[j] != verts[connect_idx[idx+j]]) {
5056 std::cout << "mb_poly_test: get_connectivity test returned wrong vertices for polygon "
5057 << i << "." << std::endl;
5058 result = MB_FAILURE;
5059 continue;
5060 }
5061 }
5062
5063 idx += num_connect;
5064 }
5065
5066 if (MB_SUCCESS != result) return result;
5067
5068 // check a different way, with ranges
5069 Range vert_range, poly_range;
5070 for (i = 0; i < 9; i++) poly_range.insert(polygons[i]);
5071 result = mb->get_adjacencies(poly_range, 0, false, vert_range,
5072 Interface::UNION);
5073 if (MB_SUCCESS != result) {
5074 std::cout << "mb_poly_test: get_adjacencies failed for polygon "
5075 << i << "." << std::endl;
5076 return result;
5077 }
5078
5079 else if (vert_range.size() != 16) {
5080 std::cout << "mb_poly_test: get_adjacencies returned wrong # of vertices for polygon "
5081 << i << "." << std::endl;
5082 return MB_FAILURE;
5083 }
5084
5085 // make a couple polyhedra
5086 EntityHandle polyhedra[2];
5087 result = mb->create_element(MBPOLYHEDRON, polygons, 7, polyhedra[0]);
5088 if (MB_SUCCESS != result) {
5089 std::cout << "mb_poly_test: create_element failed for polyhedron 1." << std::endl;
5090 return result;
5091 }
5092
5093 temp_connect[0] = polygons[1];
5094 temp_connect[1] = polygons[7];
5095 temp_connect[2] = polygons[8];
5096 result = mb->create_element(MBPOLYHEDRON, temp_connect, 3, polyhedra[1]);
5097 if (MB_SUCCESS != result) {
5098 std::cout << "mb_poly_test: create_element failed for polyhedron 2." << std::endl;
5099 return result;
5100 }
5101
5102 // now look for vertices common to both
5103 std::vector<EntityHandle> temp_verts;
5104 result = mb->get_adjacencies(polyhedra, 2, 0, false, temp_verts);
5105 if (MB_SUCCESS != result) {
5106 std::cout << "mb_poly_test: get_adjacencies failed for polyhedra." << std::endl;
5107 return result;
5108 }
5109
5110 if (4 != temp_verts.size()) {
5111 std::cout << "mb_poly_test: get_adjacencies for polyhedra returned " << temp_verts.size()
5112 << " vertices, should be 4." << std::endl;
5113 return MB_FAILURE;
5114 }
5115
5116 // ok, we're probably fine
5117 return MB_SUCCESS;
5118 }
5119
mb_topo_util_test()5120 ErrorCode mb_topo_util_test()
5121 {
5122 Core moab;
5123 Interface* gMB = &moab;
5124 MeshTopoUtil mtu(gMB);
5125
5126 // construct a four-hex mesh for testing purposes
5127 double grid_vert_pos[] =
5128 {
5129 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 2.0, 0.0, 0.0,
5130 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 2.0, 1.0, 0.0,
5131 0.0, 2.0, 0.0, 1.0, 2.0, 0.0, 2.0, 2.0, 0.0,
5132 //
5133 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 2.0, 0.0, 1.0,
5134 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 1.0, 1.0,
5135 0.0, 2.0, 1.0, 1.0, 2.0, 1.0, 2.0, 2.0, 1.0
5136 };
5137
5138 EntityHandle grid_verts[18], grid_elems[4];
5139 ErrorCode result;
5140 #define RR if (result != MB_SUCCESS) return result
5141 int init_edges, init_faces;
5142 result = gMB->get_number_entities_by_dimension(0, 1, init_edges); RR;
5143 result = gMB->get_number_entities_by_dimension(0, 2, init_faces); RR;
5144
5145 // make vertices
5146 for (int i = 0; i < 18; i++) {
5147 result = gMB->create_vertex(&grid_vert_pos[3*i], grid_verts[i]); RR;
5148 }
5149
5150 // make hexes
5151 int numv = 3, numv_sq = 9;
5152 #define VINDEX(i,j,k) (i + (j*numv) + (k*numv_sq))
5153 EntityHandle connect[8];
5154 for (int j = 0; j < 2; j++) {
5155 for (int i = 0; i < 2; i++) {
5156 int vijk = VINDEX(i,j,0);
5157 connect[0] = grid_verts[vijk];
5158 connect[1] = grid_verts[vijk+1];
5159 connect[2] = grid_verts[vijk+1+numv];
5160 connect[3] = grid_verts[vijk+numv];
5161 connect[4] = grid_verts[vijk+numv*numv];
5162 connect[5] = grid_verts[vijk+1+numv*numv];
5163 connect[6] = grid_verts[vijk+1+numv+numv*numv];
5164 connect[7] = grid_verts[vijk+numv+numv*numv];
5165 result = gMB->create_element(MBHEX, connect, 8, grid_elems[2*j+i]); RR;
5166 }
5167 }
5168
5169 Range vert_range;
5170 std::copy(grid_verts, grid_verts+18, range_inserter(vert_range));
5171
5172 // generate aentities
5173 result = mtu.construct_aentities(vert_range); RR;
5174
5175 int this_edges, this_faces;
5176 result = gMB->get_number_entities_by_dimension(0, 1, this_edges); RR;
5177 result = gMB->get_number_entities_by_dimension(0, 2, this_faces); RR;
5178
5179 if (this_edges != init_edges+33 || this_faces != init_faces+20) {
5180 std::cout << "Wrong number of edges or faces in mb_topo_util test." << std::endl;
5181 // return MB_FAILURE;
5182 }
5183
5184 // get average position
5185 double pos[3];
5186 for (int j = 0; j < 2; j++) {
5187 for (int i = 0; i < 2; i++) {
5188 result = mtu.get_average_position(grid_elems[2*j+i], pos);
5189 RR;
5190 if (pos[0] != .5+i || pos[1] != .5+j || pos[2] != .5) {
5191 std::cout << "Wrong position at i = " << i << ", j = " << j << std::endl;
5192 result = MB_FAILURE;
5193 }
5194 }
5195 }
5196 RR;
5197
5198 // get star faces
5199 Range all_hexes, middle_edge;
5200 std::copy(grid_elems, grid_elems+4, range_inserter(all_hexes));
5201 // get the shared edge
5202 result = gMB->get_adjacencies(all_hexes, 1, false, middle_edge);
5203 if (MB_SUCCESS != result || 1 != middle_edge.size()) {
5204 std::cout << "Bad result getting single shared edge." << std::endl;
5205 return MB_FAILURE;
5206 }
5207
5208 std::vector<EntityHandle> star_faces, star_hexes;
5209 bool bdy_edge;
5210 result = mtu.star_entities(*middle_edge.begin(), star_faces, bdy_edge, 0, &star_hexes);
5211 if (MB_SUCCESS != result || bdy_edge || star_faces.size() != 4 || star_hexes.size() != 4) {
5212 std::cout << "Bad result from star_faces for non-bdy edge." << std::endl;
5213 return MB_FAILURE;
5214 }
5215
5216 // now try for a different edge, which has to be on the bdy
5217 Range other_edges;
5218 all_hexes.clear(); all_hexes.insert(grid_elems[0]);
5219 result = gMB->get_adjacencies(all_hexes, 1, false, other_edges); RR;
5220 other_edges.erase(*middle_edge.begin());
5221 if (11 != other_edges.size()) {
5222 std::cout << "Wrong number of edges in hex." << std::endl;
5223 return MB_FAILURE;
5224 }
5225 star_faces.clear();
5226 star_hexes.clear();
5227 result = mtu.star_entities(*other_edges.begin(), star_faces, bdy_edge, 0, &star_hexes);
5228 if (MB_SUCCESS != result || !bdy_edge ||
5229 (star_faces.size() != 2 && star_faces.size() != 3) ||
5230 (star_hexes.size() != 1 && star_hexes.size() != 2)) {
5231 std::cout << "Bad result from star_faces for bdy edge." << std::endl;
5232 return MB_FAILURE;
5233 }
5234
5235 return MB_SUCCESS;
5236 }
5237
mb_split_test()5238 ErrorCode mb_split_test()
5239 {
5240 Core moab;
5241 Interface* gMB = &moab;
5242 MeshTopoUtil mtu(gMB);
5243
5244 // construct a four-hex mesh for testing purposes
5245 double grid_vert_pos[] =
5246 {
5247 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 2.0, 0.0, 0.0,
5248 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 2.0, 1.0, 0.0,
5249 0.0, 2.0, 0.0, 1.0, 2.0, 0.0, 2.0, 2.0, 0.0,
5250 //
5251 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 2.0, 0.0, 1.0,
5252 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 1.0, 1.0,
5253 0.0, 2.0, 1.0, 1.0, 2.0, 1.0, 2.0, 2.0, 1.0,
5254 //
5255 0.0, 0.0, 2.0, 1.0, 0.0, 2.0, 2.0, 0.0, 2.0,
5256 0.0, 1.0, 2.0, 1.0, 1.0, 2.0, 2.0, 1.0, 2.0,
5257 0.0, 2.0, 2.0, 1.0, 2.0, 2.0, 2.0, 2.0, 2.0
5258 };
5259
5260 EntityHandle grid_verts[27], grid_elems[8];
5261 ErrorCode result;
5262 #define RR if (result != MB_SUCCESS) return result
5263 int init_edges, init_faces, init_regions;
5264 result = gMB->get_number_entities_by_dimension(0, 1, init_edges); RR;
5265 result = gMB->get_number_entities_by_dimension(0, 2, init_faces); RR;
5266 result = gMB->get_number_entities_by_dimension(0, 3, init_regions); RR;
5267
5268 // make vertices
5269 for (int i = 0; i < 27; i++) {
5270 result = gMB->create_vertex(&grid_vert_pos[3*i], grid_verts[i]); RR;
5271 }
5272
5273 // make hexes
5274 int numv = 3, numv_sq = 9;
5275 #define VINDEX(i,j,k) (i + (j*numv) + (k*numv_sq))
5276 EntityHandle connect[8];
5277 for (int k = 0; k < 2; k++) {
5278 for (int j = 0; j < 2; j++) {
5279 for (int i = 0; i < 2; i++) {
5280 int vijk = VINDEX(i,j,k);
5281 connect[0] = grid_verts[vijk];
5282 connect[1] = grid_verts[vijk+1];
5283 connect[2] = grid_verts[vijk+1+numv];
5284 connect[3] = grid_verts[vijk+numv];
5285 connect[4] = grid_verts[vijk+numv*numv];
5286 connect[5] = grid_verts[vijk+1+numv*numv];
5287 connect[6] = grid_verts[vijk+1+numv+numv*numv];
5288 connect[7] = grid_verts[vijk+numv+numv*numv];
5289 result = gMB->create_element(MBHEX, connect, 8, grid_elems[4*k+2*j+i]); RR;
5290 }
5291 }
5292 }
5293
5294 Range vert_range;
5295 std::copy(grid_verts, grid_verts+27, range_inserter(vert_range));
5296
5297 // generate aentities
5298 result = mtu.construct_aentities(vert_range); RR;
5299
5300 int this_edges, this_faces;
5301 result = gMB->get_number_entities_by_dimension(0, 1, this_edges); RR;
5302 result = gMB->get_number_entities_by_dimension(0, 2, this_faces); RR;
5303
5304 if (this_edges != init_edges+54 || this_faces != init_faces+36) {
5305 std::cout << "Wrong number of edges or faces in mb_topo_util test." << std::endl;
5306 return MB_FAILURE;
5307 }
5308
5309 // split the faces between the 2 layers
5310 // first get the faces
5311 Range split_faces, tmp_ents, tmp_faces;
5312 for (int i = 0; i < 4; i++) {
5313 tmp_ents.clear();
5314 tmp_ents.insert(grid_elems[i]);
5315 tmp_ents.insert(grid_elems[i+4]);
5316 tmp_faces.clear();
5317 result = gMB->get_adjacencies(tmp_ents, 2, false, tmp_faces);
5318 if (MB_SUCCESS != result || tmp_faces.size() != 1) {
5319 std::cout << "mb_split_test failed to get shared quad." << std::endl;
5320 return MB_FAILURE;
5321 }
5322 split_faces.insert(*tmp_faces.begin());
5323 }
5324
5325 Range new_faces, new_regions;
5326
5327 // NOTE: passing in non-NULL pointer for new_regions requests that region between the
5328 // split entities be filled with an element; in this case, since we're splitting faces,
5329 // the new entities are polyhedra
5330 result = mtu.split_entities_manifold(split_faces, new_faces, &new_regions);
5331 if (MB_SUCCESS != result || new_faces.size() != 4 ||
5332 new_regions.size() != 4) {
5333 std::cout << "mb_split_test failed to split quads." << std::endl;
5334 return MB_FAILURE;
5335 }
5336
5337 int this_regions;
5338 result = gMB->get_number_entities_by_dimension(0, 1, this_edges); RR;
5339 result = gMB->get_number_entities_by_dimension(0, 2, this_faces); RR;
5340 result = gMB->get_number_entities_by_dimension(0, 3, this_regions); RR;
5341
5342 if (this_edges != init_edges+54 || this_faces != init_faces+40 ||
5343 this_regions != init_regions+12) {
5344 std::cout << "Wrong number of edges or faces or regions after splitting in mb_topo_util test."
5345 << std::endl;
5346 return MB_FAILURE;
5347 }
5348
5349 return MB_SUCCESS;
5350 }
5351
mb_range_seq_intersect_test()5352 ErrorCode mb_range_seq_intersect_test()
5353 {
5354 ErrorCode rval;
5355 SequenceManager sequences;
5356 RangeSeqIntersectIter iter( &sequences );
5357 Range range;
5358
5359 // create some entity sequences
5360 EntitySequence *ts1, *ts2, *ts3, *qs1;
5361 EntityHandle th1, th2, th3, qh1;
5362 const int nt1 = 100, nt2 = 10, nt3 = 1, nq1 = 20;
5363 rval = sequences.create_entity_sequence( MBTRI, nt1, 3, 5, th1, ts1, -1 );
5364 if (MB_SUCCESS != rval) return rval;
5365 rval = sequences.create_entity_sequence( MBTRI, nt2, 6, 0, th2, ts2, -1 );
5366 if (MB_SUCCESS != rval) return rval;
5367 rval = sequences.create_entity_sequence( MBTRI, nt3, 3, MB_END_ID, th3, ts3, -1 );
5368 if (MB_SUCCESS != rval) return rval;
5369 rval = sequences.create_entity_sequence( MBQUAD, nq1, 4, 0, qh1, qs1, -1 );
5370 if (MB_SUCCESS != rval) return rval;
5371
5372 // we're going to assume this below, so verify it now
5373 if (th1 > th2 || th2 > th3 || th3 > qh1)
5374 return MB_FAILURE;
5375
5376 // construct an Range containing all valid handles;
5377 range.clear();
5378 range.insert( ts1->start_handle(), ts1->end_handle() );
5379 range.insert( ts2->start_handle(), ts2->end_handle() );
5380 range.insert( ts3->start_handle(), ts3->end_handle() );
5381 range.insert( qs1->start_handle(), qs1->end_handle() );
5382
5383 // iterate over all and check results
5384
5385 rval = iter.init( range.begin(), range.end() );
5386 if (MB_SUCCESS != rval)
5387 return rval;
5388 if (ts1 != iter.get_sequence())
5389 return MB_FAILURE;
5390 if (iter.get_start_handle() != ts1->start_handle())
5391 return MB_FAILURE;
5392 if (iter.get_end_handle() != ts1->end_handle())
5393 return MB_FAILURE;
5394
5395 rval = iter.step();
5396 if (MB_SUCCESS != rval)
5397 return rval;
5398 if (ts2 != iter.get_sequence())
5399 return MB_FAILURE;
5400 if (iter.get_start_handle() != ts2->start_handle())
5401 return MB_FAILURE;
5402 if (iter.get_end_handle() != ts2->end_handle())
5403 return MB_FAILURE;
5404
5405 rval = iter.step();
5406 if (MB_SUCCESS != rval)
5407 return rval;
5408 if (ts3 != iter.get_sequence())
5409 return MB_FAILURE;
5410 if (iter.get_start_handle() != ts3->start_handle())
5411 return MB_FAILURE;
5412 if (iter.get_end_handle() != ts3->end_handle())
5413 return MB_FAILURE;
5414
5415 rval = iter.step();
5416 if (MB_SUCCESS != rval)
5417 return rval;
5418 if (qs1 != iter.get_sequence())
5419 return MB_FAILURE;
5420 if (iter.get_start_handle() != qs1->start_handle())
5421 return MB_FAILURE;
5422 if (iter.get_end_handle() != qs1->end_handle())
5423 return MB_FAILURE;
5424
5425 if (!iter.is_at_end())
5426 return MB_FAILURE;
5427 rval = iter.step();
5428 if (MB_FAILURE != rval)
5429 return MB_FAILURE;
5430
5431 // iterate over just the quads
5432
5433 rval = iter.init( range.lower_bound(MBQUAD), range.end() );
5434 if (MB_SUCCESS != rval)
5435 return rval;
5436 if (qs1 != iter.get_sequence())
5437 return MB_FAILURE;
5438 if (iter.get_start_handle() != qs1->start_handle())
5439 return MB_FAILURE;
5440 if (iter.get_end_handle() != qs1->end_handle())
5441 return MB_FAILURE;
5442
5443 if (!iter.is_at_end())
5444 return MB_FAILURE;
5445 rval = iter.step();
5446 if (MB_FAILURE != rval)
5447 return MB_FAILURE;
5448
5449 // iterate starting one past the beginning of the
5450 // triangles and stopping one before the end. The last
5451 // sequence contains only one tri, so should stop and end
5452 // of second-to-last sequence
5453
5454 rval = iter.init( ++(range.begin()), --(range.lower_bound(MBQUAD)) );
5455 if (MB_SUCCESS != rval)
5456 return rval;
5457 if (ts1 != iter.get_sequence())
5458 return MB_FAILURE;
5459 if (iter.get_start_handle() != ts1->start_handle() + 1)
5460 return MB_FAILURE;
5461 if (iter.get_end_handle() != ts1->end_handle())
5462 return MB_FAILURE;
5463
5464 rval = iter.step();
5465 if (MB_SUCCESS != rval)
5466 return rval;
5467 if (ts2 != iter.get_sequence())
5468 return MB_FAILURE;
5469 if (iter.get_start_handle() != ts2->start_handle())
5470 return MB_FAILURE;
5471 if (iter.get_end_handle() != ts2->end_handle())
5472 return MB_FAILURE;
5473
5474 if (!iter.is_at_end())
5475 return MB_FAILURE;
5476 rval = iter.step();
5477 if (MB_FAILURE != rval)
5478 return MB_FAILURE;
5479
5480 // Iterate over the quad sequence, starting two past the
5481 // beginning and stopping one before the end
5482
5483 rval = iter.init( ++(range.lower_bound(MBQUAD)), --(range.end()));
5484 if (MB_SUCCESS != rval)
5485 return rval;
5486 if (qs1 != iter.get_sequence())
5487 return MB_FAILURE;
5488 if (iter.get_start_handle() != qs1->start_handle() + 1)
5489 return MB_FAILURE;
5490 if (iter.get_end_handle() != qs1->end_handle() - 1)
5491 return MB_FAILURE;
5492
5493 if (!iter.is_at_end())
5494 return MB_FAILURE;
5495 rval = iter.step();
5496 if (MB_FAILURE != rval)
5497 return MB_FAILURE;
5498
5499 // Iterate over two subsets of the quad sequence
5500
5501 Range quads = range.subset_by_type( MBQUAD );
5502 EntityHandle removed = qs1->start_handle() + nq1/2;
5503 if (quads.erase( removed ) == quads.end())
5504 return MB_FAILURE;
5505
5506 rval = iter.init( quads.begin(), quads.end());
5507 if (MB_SUCCESS != rval)
5508 return rval;
5509 if (qs1 != iter.get_sequence())
5510 return MB_FAILURE;
5511 if (iter.get_start_handle() != qs1->start_handle())
5512 return MB_FAILURE;
5513 if (iter.get_end_handle() != removed - 1)
5514 return MB_FAILURE;
5515
5516 rval = iter.step();
5517 if (MB_SUCCESS != rval)
5518 return rval;
5519 if (qs1 != iter.get_sequence())
5520 return MB_FAILURE;
5521 if (iter.get_start_handle() != removed + 1)
5522 return MB_FAILURE;
5523 if (iter.get_end_handle() != qs1->end_handle())
5524 return MB_FAILURE;
5525
5526 if (!iter.is_at_end())
5527 return MB_FAILURE;
5528 rval = iter.step();
5529 if (MB_FAILURE != rval)
5530 return MB_FAILURE;
5531
5532 // Iterate over everything, including a bunch of
5533 // invalid handles
5534
5535 Range big;
5536 int junk;
5537 EntityHandle last = CREATE_HANDLE(MBQUAD+1, 0, junk);
5538 big.insert( ts1->start_handle() - 1, last );
5539
5540 // first some invalid handles in the beginning of the range
5541 rval = iter.init( big.begin(), big.end() );
5542 if (MB_ENTITY_NOT_FOUND != rval)
5543 return MB_FAILURE;
5544 if (NULL != iter.get_sequence())
5545 return MB_FAILURE;
5546 if (iter.get_start_handle() != *big.begin())
5547 return MB_FAILURE;
5548 if (iter.get_end_handle() != ts1->start_handle() - 1)
5549 return MB_FAILURE;
5550
5551 // next the first triangle sequence
5552 rval = iter.step();
5553 if (MB_SUCCESS != rval)
5554 return rval;
5555 if (ts1 != iter.get_sequence())
5556 return MB_FAILURE;
5557 if (iter.get_start_handle() != ts1->start_handle())
5558 return MB_FAILURE;
5559 if (iter.get_end_handle() != ts1->end_handle())
5560 return MB_FAILURE;
5561
5562 // next the the invalid handles between the first two tri sequences
5563 if (ts1->end_handle() + 1 != ts2->start_handle()) {
5564 rval = iter.step();
5565 if (MB_ENTITY_NOT_FOUND != rval)
5566 return MB_FAILURE;
5567 if (NULL != iter.get_sequence())
5568 return MB_FAILURE;
5569 if (iter.get_start_handle() != ts1->end_handle()+1)
5570 return MB_FAILURE;
5571 if (iter.get_end_handle() != ts2->start_handle()-1)
5572 return MB_FAILURE;
5573 }
5574
5575 // next the second triangle sequence
5576 rval = iter.step();
5577 if (MB_SUCCESS != rval)
5578 return rval;
5579 if (ts2 != iter.get_sequence())
5580 return MB_FAILURE;
5581 if (iter.get_start_handle() != ts2->start_handle())
5582 return MB_FAILURE;
5583 if (iter.get_end_handle() != ts2->end_handle())
5584 return MB_FAILURE;
5585
5586 // next the the invalid handles between the 2nd and 3rd tri sequences
5587 if (ts2->end_handle() + 1 != ts3->start_handle()) {
5588 rval = iter.step();
5589 if (MB_ENTITY_NOT_FOUND != rval)
5590 return MB_FAILURE;
5591 if (NULL != iter.get_sequence())
5592 return MB_FAILURE;
5593 if (iter.get_start_handle() != ts2->end_handle()+1)
5594 return MB_FAILURE;
5595 if (iter.get_end_handle() != ts3->start_handle()-1)
5596 return MB_FAILURE;
5597 }
5598
5599 // next the third triangle sequence
5600 rval = iter.step();
5601 if (MB_SUCCESS != rval)
5602 return rval;
5603 if (ts3 != iter.get_sequence())
5604 return MB_FAILURE;
5605 if (iter.get_start_handle() != ts3->start_handle())
5606 return MB_FAILURE;
5607 if (iter.get_end_handle() != ts3->end_handle())
5608 return MB_FAILURE;
5609
5610 // third tri sequence contains the MAX tri handle, so no more
5611 // invalid triangles.
5612 // next 1 invalid quad at the before MB_START_ID
5613 if (ts3->end_handle() + 1 != qs1->start_handle()) {
5614 rval = iter.step();
5615 if (MB_ENTITY_NOT_FOUND != rval)
5616 return MB_FAILURE;
5617 if (NULL != iter.get_sequence())
5618 return MB_FAILURE;
5619 if (iter.get_start_handle() != ts3->end_handle()+1)
5620 return MB_FAILURE;
5621 if (iter.get_end_handle() != qs1->start_handle()-1)
5622 return MB_FAILURE;
5623 }
5624
5625 // next the quad sequence
5626 rval = iter.step();
5627 if (MB_SUCCESS != rval)
5628 return rval;
5629 if (qs1 != iter.get_sequence())
5630 return MB_FAILURE;
5631 if (iter.get_start_handle() != qs1->start_handle())
5632 return MB_FAILURE;
5633 if (iter.get_end_handle() != qs1->end_handle())
5634 return MB_FAILURE;
5635
5636 // next remaining invalid quad handles in the range
5637 rval = iter.step();
5638 if (MB_ENTITY_NOT_FOUND != rval)
5639 return MB_FAILURE;
5640 if (0 != iter.get_sequence())
5641 return MB_FAILURE;
5642 if (iter.get_start_handle() != qs1->end_handle() + 1)
5643 return MB_FAILURE;
5644 if (iter.get_end_handle() != last - 1)
5645 return MB_FAILURE;
5646
5647 // next invalid entity after the last quad in the range
5648 rval = iter.step();
5649 if (MB_ENTITY_NOT_FOUND != rval)
5650 return MB_FAILURE;
5651 if (0 != iter.get_sequence())
5652 return MB_FAILURE;
5653 if (iter.get_start_handle() != last)
5654 return MB_FAILURE;
5655 if (iter.get_end_handle() != last)
5656 return MB_FAILURE;
5657
5658 // now at the end
5659 if (!iter.is_at_end())
5660 return MB_FAILURE;
5661 rval = iter.step();
5662 if (MB_FAILURE != rval)
5663 return MB_FAILURE;
5664
5665
5666
5667 // Create some holes
5668 Error eh;
5669 EntityHandle ts1s = ts1->start_handle();
5670 EntityHandle dead1 = ts1->start_handle() + 1;
5671 EntityHandle dead2 = ts1->start_handle() + 2;
5672 EntityHandle ts1e = ts1->end_handle();
5673 EntityHandle dead3 = ts2->start_handle();
5674 EntityHandle dead4 = ts2->end_handle();
5675 EntityHandle qs1s = qs1->start_handle();
5676 EntityHandle qs1e = qs1->end_handle();
5677 EntityHandle dead5 = qs1->start_handle() + nq1/2;
5678 EntityHandle dead6 = dead5+1;
5679 rval = sequences.delete_entity( &eh, dead1 );
5680 if (MB_SUCCESS != rval) return rval;
5681 rval = sequences.delete_entity( &eh, dead2 );
5682 if (MB_SUCCESS != rval) return rval;
5683 rval = sequences.delete_entity( &eh, dead3 );
5684 if (MB_SUCCESS != rval) return rval;
5685 rval = sequences.delete_entity( &eh, dead4 );
5686 if (MB_SUCCESS != rval) return rval;
5687 rval = sequences.delete_entity( &eh, dead5 );
5688 if (MB_SUCCESS != rval) return rval;
5689 rval = sequences.delete_entity( &eh, dead6 );
5690 if (MB_SUCCESS != rval) return rval;
5691
5692 // Iterate over sequences w/out removing deleted entities
5693 // from range.
5694
5695 // first sequence should have one valid handle at beginning
5696 rval = iter.init( range.begin(), range.end() );
5697 if (MB_SUCCESS != rval)
5698 return rval;
5699 if (0 == iter.get_sequence() ||
5700 ts1s != iter.get_sequence()->start_handle() ||
5701 dead1-1 != iter.get_sequence()->end_handle())
5702 return MB_FAILURE;
5703 if (iter.get_start_handle() != ts1->start_handle())
5704 return MB_FAILURE;
5705 if (iter.get_end_handle() != dead1 - 1)
5706 return MB_FAILURE;
5707
5708 // next two invalid handles in sequence in first sequence
5709 rval = iter.step( );
5710 if (MB_ENTITY_NOT_FOUND != rval)
5711 return MB_FAILURE;
5712 if (0 != iter.get_sequence())
5713 return MB_FAILURE;
5714 if (iter.get_start_handle() != dead1)
5715 return MB_FAILURE;
5716 if (iter.get_end_handle() != dead2)
5717 return MB_FAILURE;
5718
5719 // next the remainder of the fist sequence
5720 rval = iter.step();
5721 if (MB_SUCCESS != rval)
5722 return rval;
5723 if (0 == iter.get_sequence() ||
5724 dead2+1 != iter.get_sequence()->start_handle() ||
5725 ts1e != iter.get_sequence()->end_handle())
5726 return MB_FAILURE;
5727 if (iter.get_start_handle() != dead2+1)
5728 return MB_FAILURE;
5729 if (iter.get_end_handle() != ts1e)
5730 return MB_FAILURE;
5731
5732 // next an invalid handle at the start of the second sequence
5733 rval = iter.step();
5734 if (MB_ENTITY_NOT_FOUND != rval)
5735 return MB_FAILURE;
5736 if (0 != iter.get_sequence())
5737 return MB_FAILURE;
5738 if (iter.get_start_handle() != dead3)
5739 return MB_FAILURE;
5740 if (iter.get_end_handle() != dead3)
5741 return MB_FAILURE;
5742
5743 // next the second sequence up to the invalid handle at the end
5744 rval = iter.step();
5745 if (MB_SUCCESS != rval)
5746 return rval;
5747 if (0 == iter.get_sequence() ||
5748 dead3+1 != iter.get_sequence()->start_handle() ||
5749 dead4-1 != iter.get_sequence()->end_handle())
5750 return MB_FAILURE;
5751 if (ts2 != iter.get_sequence())
5752 return MB_FAILURE;
5753 if (iter.get_start_handle() != dead3+1)
5754 return MB_FAILURE;
5755 if (iter.get_end_handle() != dead4-1)
5756 return MB_FAILURE;
5757
5758 // next invaild handle at the end of the second sequence
5759 rval = iter.step();
5760 if (MB_ENTITY_NOT_FOUND != rval)
5761 return MB_FAILURE;
5762 if (0 != iter.get_sequence())
5763 return MB_FAILURE;
5764 if (iter.get_start_handle() != dead4)
5765 return MB_FAILURE;
5766 if (iter.get_end_handle() != dead4)
5767 return MB_FAILURE;
5768
5769 // next the third sequence
5770 rval = iter.step();
5771 if (MB_SUCCESS != rval)
5772 return rval;
5773 if (ts3 != iter.get_sequence())
5774 return MB_FAILURE;
5775 if (iter.get_start_handle() != ts3->start_handle())
5776 return MB_FAILURE;
5777 if (iter.get_end_handle() != ts3->end_handle())
5778 return MB_FAILURE;
5779
5780 // next the quad sequence up to the invalid handle in the middle
5781 rval = iter.step();
5782 if (MB_SUCCESS != rval)
5783 return rval;
5784 if (0 == iter.get_sequence() ||
5785 qs1s != iter.get_sequence()->start_handle() ||
5786 dead5-1 != iter.get_sequence()->end_handle())
5787 return MB_FAILURE;
5788 if (qs1 != iter.get_sequence())
5789 return MB_FAILURE;
5790 if (iter.get_start_handle() != qs1s)
5791 return MB_FAILURE;
5792 if (iter.get_end_handle() != dead5-1)
5793 return MB_FAILURE;
5794
5795 // next the two invalid handles in the middle
5796 rval = iter.step();
5797 if (MB_ENTITY_NOT_FOUND != rval)
5798 return MB_FAILURE;
5799 if (0 != iter.get_sequence())
5800 return MB_FAILURE;
5801 if (iter.get_start_handle() != dead5)
5802 return MB_FAILURE;
5803 if (iter.get_end_handle() != dead6)
5804 return MB_FAILURE;
5805
5806 // next the remainder of the quad sequence
5807 rval = iter.step();
5808 if (MB_SUCCESS != rval)
5809 return rval;
5810 if (0 == iter.get_sequence() ||
5811 dead6+1 != iter.get_sequence()->start_handle() ||
5812 qs1e != iter.get_sequence()->end_handle())
5813 return MB_FAILURE;
5814 if (iter.get_start_handle() != dead6+1)
5815 return MB_FAILURE;
5816 if (iter.get_end_handle() != qs1e)
5817 return MB_FAILURE;
5818
5819 // now at the end
5820 if (!iter.is_at_end())
5821 return MB_FAILURE;
5822 rval = iter.step();
5823 if (MB_FAILURE != rval)
5824 return MB_FAILURE;
5825
5826
5827 // now remove the dead entities from the range and iterate again
5828
5829 if (range.erase( dead1 ) == quads.end())
5830 return MB_FAILURE;
5831 if (range.erase( dead2 ) == quads.end())
5832 return MB_FAILURE;
5833 if (range.erase( dead3 ) == quads.end())
5834 return MB_FAILURE;
5835 if (range.erase( dead4 ) == quads.end())
5836 return MB_FAILURE;
5837 if (range.erase( dead5 ) == quads.end())
5838 return MB_FAILURE;
5839 if (range.erase( dead6 ) == quads.end())
5840 return MB_FAILURE;
5841
5842
5843 // first sequence should have one valid handle at beginning
5844 rval = iter.init( range.begin(), range.end() );
5845 if (MB_SUCCESS != rval)
5846 return rval;
5847 if (0 == iter.get_sequence() ||
5848 ts1s != iter.get_sequence()->start_handle() ||
5849 dead1-1 != iter.get_sequence()->end_handle())
5850 return MB_FAILURE;
5851 if (iter.get_start_handle() != ts1s)
5852 return MB_FAILURE;
5853 if (iter.get_end_handle() != dead1 - 1)
5854 return MB_FAILURE;
5855
5856 // next the remainder of the fist sequence after the hole
5857 rval = iter.step();
5858 if (MB_SUCCESS != rval)
5859 return rval;
5860 if (0 == iter.get_sequence() ||
5861 dead2+1 != iter.get_sequence()->start_handle() ||
5862 ts1e != iter.get_sequence()->end_handle())
5863 return MB_FAILURE;
5864 if (iter.get_start_handle() != dead2+1)
5865 return MB_FAILURE;
5866 if (iter.get_end_handle() != ts1e)
5867 return MB_FAILURE;
5868
5869 // next the second sequence between deleted start and end handles
5870 rval = iter.step();
5871 if (MB_SUCCESS != rval)
5872 return rval;
5873 if (0 == iter.get_sequence() ||
5874 dead3+1 != iter.get_sequence()->start_handle() ||
5875 dead4-1 != iter.get_sequence()->end_handle())
5876 return MB_FAILURE;
5877 if (iter.get_start_handle() != dead3+1)
5878 return MB_FAILURE;
5879 if (iter.get_end_handle() != dead4-1)
5880 return MB_FAILURE;
5881
5882 // next the third sequence
5883 rval = iter.step();
5884 if (MB_SUCCESS != rval)
5885 return rval;
5886 if (ts3 != iter.get_sequence())
5887 return MB_FAILURE;
5888 if (iter.get_start_handle() != ts3->start_handle())
5889 return MB_FAILURE;
5890 if (iter.get_end_handle() != ts3->end_handle())
5891 return MB_FAILURE;
5892
5893 // next the quad sequence up to the hole in the middle
5894 rval = iter.step();
5895 if (MB_SUCCESS != rval)
5896 return rval;
5897 if (0 == iter.get_sequence() ||
5898 qs1s != iter.get_sequence()->start_handle() ||
5899 dead5-1 != iter.get_sequence()->end_handle())
5900 return MB_FAILURE;
5901 if (iter.get_start_handle() != qs1s)
5902 return MB_FAILURE;
5903 if (iter.get_end_handle() != dead5-1)
5904 return MB_FAILURE;
5905
5906 // next the remainder of the quad sequence after the hole
5907 rval = iter.step();
5908 if (MB_SUCCESS != rval)
5909 return rval;
5910 if (0 == iter.get_sequence() ||
5911 dead6+1 != iter.get_sequence()->start_handle() ||
5912 qs1e != iter.get_sequence()->end_handle())
5913 return MB_FAILURE;
5914 if (iter.get_start_handle() != dead6+1)
5915 return MB_FAILURE;
5916 if (iter.get_end_handle() != qs1e)
5917 return MB_FAILURE;
5918
5919 // now at the end
5920 if (!iter.is_at_end())
5921 return MB_FAILURE;
5922 rval = iter.step();
5923 if (MB_FAILURE != rval)
5924 return MB_FAILURE;
5925
5926 return MB_SUCCESS;
5927 }
5928
5929 #define ASSERT_EQUAL( A, B ) \
5930 do { if (!_assert_equal( (A), (B), #A, #B, __LINE__)) \
5931 return MB_FAILURE; } while(false)
5932
5933 #define ASSERT_NOT_EQUAL( A, B ) \
5934 do { if (!_assert_not_equal( (A), (B), #A, #B, __LINE__)) \
5935 return MB_FAILURE; } while(false)
5936
5937 template <typename T1, typename T2>
_assert_equal(T1 a,T2 b,const char * as,const char * bs,int line)5938 bool _assert_equal( T1 a, T2 b, const char* as, const char* bs, int line )
5939 {
5940 if (a == b)
5941 return true;
5942
5943 std::cout << "Assertion failed at line " << line << std::endl
5944 << "\t" << as << " == " << bs << std::endl
5945 << "\t" << as << " = " << a << std::endl
5946 << "\t" << bs << " = " << b << std::endl;
5947 return false;
5948 }
5949
5950 template <typename T1, typename T2>
_assert_not_equal(T1 a,T2 b,const char * as,const char * bs,int line)5951 bool _assert_not_equal( T1 a, T2 b, const char* as, const char* bs, int line )
5952 {
5953 if (a != b)
5954 return true;
5955
5956 std::cout << "Assertion failed at line " << line << std::endl
5957 << "\t" << as << " != " << bs << std::endl
5958 << "\t" << as << " = " << a << std::endl
5959 << "\t" << bs << " = " << b << std::endl;
5960 return false;
5961 }
5962
operator <<(std::ostream & s,Range::const_iterator i)5963 std::ostream& operator<<( std::ostream& s, Range::const_iterator i ) {
5964 return s << *i;
5965 }
5966
mb_poly_adjacency_test()5967 ErrorCode mb_poly_adjacency_test()
5968 {
5969 ErrorCode rval;
5970 Core moab;
5971 Interface *mbImpl = &moab;
5972
5973 // make a couple polygons and a polyhedron
5974 double coords[3] = {0,1,2};
5975 EntityHandle verts[10], polygons[2], polyhedron;
5976
5977 for (int i = 0; i < 10; i++) {
5978 rval = mbImpl->create_vertex(coords, verts[i]);
5979 if (MB_SUCCESS != rval)
5980 return rval;
5981 }
5982
5983 for (int i = 0; i < 2; i++) {
5984 rval = mbImpl->create_element(MBPOLYGON, verts, 5, polygons[i]);
5985 if (MB_SUCCESS != rval)
5986 return rval;
5987 }
5988 rval = mbImpl->create_element(MBPOLYHEDRON, polygons, 2, polyhedron);
5989 if (MB_SUCCESS != rval)
5990 return rval;
5991
5992 // create the aentities
5993 Range dum_range;
5994 for (int dim = 0; dim < 3; dim++) {
5995 dum_range.clear();
5996 rval = mbImpl->get_adjacencies(&polyhedron, 1, dim, true, dum_range);
5997 if (MB_SUCCESS != rval)
5998 return rval;
5999 }
6000
6001 // delete the polyhedron
6002 rval = mbImpl->delete_entities(&polyhedron, 1);
6003 if (MB_SUCCESS != rval)
6004 return rval;
6005
6006 // check adjacencies
6007 return moab.check_adjacencies();
6008 }
6009
mb_poly_adjacency_test2()6010 ErrorCode mb_poly_adjacency_test2()
6011 {
6012 ErrorCode rval;
6013 Core moab;
6014 Interface *mbImpl = &moab;
6015
6016 // make a polyhedra in shape of a cube with a corner cut
6017
6018 /*
6019 *
6020 * 7 ------------- 8
6021 * . | . |
6022 * . . | initial cube had 8 vertices; box [000 - 222]
6023 * 5 ------------- 6 | cut a triangle 123 on lower corner
6024 * | | | |
6025 * | | | faces of the polyhedra (pointing outward)
6026 * | | | | (123) (24653) (4 10 8 6)
6027 * 3 | | (9 10 4 2 1) (7 8 10 9) (5687)
6028 * \ | | | (1 3 5 7 9)
6029 * 9 - - -| - 10
6030 * \ . | .
6031 * 1, | .
6032 * (000) '2 ---- 4
6033 *
6034 */
6035 double coords[] = {0, 1, 0, // vertex 1
6036 1, 0, 0, // vertex 2
6037 0, 0 ,1, // vertex 3
6038 2, 0, 0,
6039 0, 0, 2,
6040 2, 0, 2, // vertex 6
6041 0, 2, 2,
6042 2, 2, 2, // vertex 8
6043 0, 2, 0, // vertex 9
6044 2, 2, 0 // vertex 9
6045
6046 };
6047 EntityHandle verts[10], polygons[7], polyhedron;
6048
6049 for (int i = 0; i < 10; i++) {
6050 rval = mbImpl->create_vertex(&coords[3*i], verts[i]);
6051 if (MB_SUCCESS != rval)
6052 return rval;
6053 }
6054
6055 EntityHandle connect[]= {1, 2, 3, // poly 1
6056 2, 4, 6, 5, 3, // poly 2
6057 4, 10, 8, 6, // polygon 3...
6058 9, 10, 4, 2, 1,
6059 7, 8, 10, 9,
6060 5, 6, 8, 7,
6061 1, 3, 5, 7, 9 // polygon 7
6062 }; // we know the handles directly
6063
6064 int num_verts[7]={3, 5, 4, 5, 4, 4, 5};
6065 int start_indx[7];
6066 start_indx[0]= 0;
6067 for (int i=0; i<6; i++)
6068 start_indx[i+1]=start_indx[i]+num_verts[i];
6069 for (int j = 0; j < 7; j++) {
6070 rval = mbImpl->create_element(MBPOLYGON, &connect[start_indx[j]],
6071 num_verts[j], polygons[j]);
6072 if (MB_SUCCESS != rval)
6073 return rval;
6074 }
6075 rval = mbImpl->create_element(MBPOLYHEDRON, polygons, 7, polyhedron);
6076 if (MB_SUCCESS != rval)
6077 return rval;
6078
6079 // create the aentities
6080 Range dum_range;
6081 for (int dim = 0; dim < 3; dim++) {
6082 dum_range.clear();
6083 rval = mbImpl->get_adjacencies(&polyhedron, 1, dim, true, dum_range, Interface::UNION);
6084 if (MB_SUCCESS != rval)
6085 return rval;
6086 // std::cout << "\n dimension:" << dim << " " << dum_range.size() << " entities";
6087 }
6088 // std::cout << "\n";
6089 /*rval=mbImpl->write_mesh("polyhedra.vtk");
6090 if (MB_SUCCESS != rval)
6091 return rval;*/
6092 // delete the polyhedron
6093 rval = mbImpl->delete_entities(&polyhedron, 1);
6094 if (MB_SUCCESS != rval)
6095 return rval;
6096
6097 // check adjacencies
6098 return moab.check_adjacencies();
6099 }
6100
mb_memory_use_test()6101 ErrorCode mb_memory_use_test()
6102 {
6103 Core mb;
6104 unsigned long long init_total, total_with_elem, total_with_tag, total_with_tag_data;
6105 mb.estimated_memory_use(0,0,0,&init_total);
6106
6107 double coords[12] = { 1, 2, 0, 3, 4, 0, 5, 6, 0, 7, 8, 0 };
6108 EntityHandle verts[4];
6109 for (int i = 0; i < 4; ++i)
6110 if (MB_SUCCESS != mb.create_vertex( coords + 3*i, verts[i] ))
6111 return MB_FAILURE;
6112
6113 EntityHandle elem;
6114 mb.create_element( MBQUAD, verts, 4, elem );
6115
6116 mb.estimated_memory_use(0,0,0,&total_with_elem);
6117 if (total_with_elem <= init_total)
6118 return MB_FAILURE;
6119
6120 unsigned long long min, am;
6121 Range r;
6122 r.insert( elem );
6123 mb.estimated_memory_use( r, &min, &am );
6124 if (min != 4*sizeof(EntityHandle))
6125 return MB_FAILURE;
6126
6127 r.clear();
6128 r.insert( verts[0] );
6129 r.insert( verts[1] );
6130 mb.estimated_memory_use( r, &min, &am );
6131 if (min != 6*sizeof(double))
6132 return MB_FAILURE;
6133
6134 Tag tag;
6135 if (MB_SUCCESS != mb.tag_get_handle( "TMP_TAG", 1, MB_TYPE_INTEGER, tag, MB_TAG_SPARSE|MB_TAG_EXCL ))
6136 return MB_FAILURE;
6137 mb.estimated_memory_use( r, &min, &am );
6138 if (min != 6*sizeof(double))
6139 return MB_FAILURE;
6140
6141 mb.estimated_memory_use(0,0,0,&total_with_tag);
6142 if (total_with_tag <= total_with_elem)
6143 return MB_FAILURE;
6144
6145 int tag_data[] = { 0xA, 0xB };
6146 if (MB_SUCCESS != mb.tag_set_data( tag, r, &tag_data ))
6147 return MB_FAILURE;
6148 mb.estimated_memory_use( r, &min, &am );
6149 if (min <= 6*sizeof(double))
6150 return MB_FAILURE;
6151
6152 mb.estimated_memory_use(0,0,0,&total_with_tag_data);
6153 if (total_with_tag_data <= total_with_tag)
6154 return MB_FAILURE;
6155
6156 return MB_SUCCESS;
6157 }
6158
6159 ErrorCode mb_skin_curve_test_common( bool use_adj );
6160
mb_skin_curve_test()6161 ErrorCode mb_skin_curve_test()
6162 { return mb_skin_curve_test_common( false ); }
6163
mb_skin_curve_adj_test()6164 ErrorCode mb_skin_curve_adj_test()
6165 { return mb_skin_curve_test_common( true ); }
6166
6167 ErrorCode mb_skin_surface_test_common( bool use_adj );
6168
mb_skin_surface_test()6169 ErrorCode mb_skin_surface_test()
6170 { return mb_skin_surface_test_common( false ); }
6171
mb_skin_surface_adj_test()6172 ErrorCode mb_skin_surface_adj_test()
6173 { return mb_skin_surface_test_common( true ); }
6174
6175 ErrorCode mb_skin_volume_test_common( bool use_adj );
6176
mb_skin_volume_test()6177 ErrorCode mb_skin_volume_test()
6178 { return mb_skin_volume_test_common( false ); }
6179
mb_skin_volume_adj_test()6180 ErrorCode mb_skin_volume_adj_test()
6181 { return mb_skin_volume_test_common( true ); }
6182
mb_skin_curve_test_common(bool use_adj)6183 ErrorCode mb_skin_curve_test_common( bool use_adj )
6184 {
6185 ErrorCode rval;
6186 Core moab;
6187 Interface *mb = &moab;
6188
6189 std::vector<EntityHandle> verts;
6190 for (unsigned i = 0; i < 10; ++i) {
6191 double coords[] = { static_cast<double>(i), 0, 0 };
6192 EntityHandle h;
6193 mb->create_vertex( coords, h );
6194 verts.push_back(h);
6195 }
6196 Range edges;
6197 for (unsigned i = 1; i < verts.size(); ++i) {
6198 EntityHandle conn[] = { verts[i-1], verts[i] };
6199 EntityHandle h;
6200 mb->create_element( MBEDGE, conn, 2, h );
6201 edges.insert(h);
6202 }
6203
6204 Range skin;
6205 Skinner tool(mb);
6206 rval = tool.find_skin( 0, edges, 0, skin, use_adj );
6207 if (MB_SUCCESS != rval) {
6208 std::cerr << "Skinner failure at " __FILE__ ":" << __LINE__ << std::endl;
6209 return MB_FAILURE;
6210 }
6211 if (skin.size() != 2) {
6212 std::cerr << "Skinner bad result at " __FILE__ ":" << __LINE__ << std::endl;
6213 return MB_FAILURE;
6214 }
6215
6216 if (verts.front() > verts.back())
6217 std::swap( verts.front(), verts.back() );
6218 if (skin.front() != verts.front() ||
6219 skin.back() != verts.back()) {
6220 std::cerr << "Skinner bad result at " __FILE__ ":" << __LINE__ << std::endl;
6221 return MB_FAILURE;
6222 }
6223
6224
6225 // now test again with only one edge
6226 EntityHandle edge = edges.front();
6227 Range range(edge,edge);
6228 skin.clear();
6229 rval = tool.find_skin( 0, range, 0, skin, use_adj );
6230 if (MB_SUCCESS != rval) {
6231 std::cerr << "Skinner failure at " __FILE__ ":" << __LINE__ << std::endl;
6232 return MB_FAILURE;
6233 }
6234 if (skin.size() != 2) {
6235 std::cerr << "Skinner bad result at " __FILE__ ":" << __LINE__ << std::endl;
6236 return MB_FAILURE;
6237 }
6238
6239 Range verts2;
6240 mb->get_connectivity( &edge, 1, verts2 );
6241 if (skin.front() != verts2.front() ||
6242 skin.back() != verts2.back()) {
6243 std::cerr << "Skinner bad result at " __FILE__ ":" << __LINE__ << std::endl;
6244 return MB_FAILURE;
6245 }
6246
6247 return MB_SUCCESS;
6248 }
6249
mb_skin_surface_test_common(bool use_adj)6250 ErrorCode mb_skin_surface_test_common( bool use_adj )
6251 {
6252 ErrorCode rval;
6253 Core moab;
6254 Interface *mb = &moab;
6255
6256 /* Create 4 of 5 faces of a wedge: */
6257 /*
6258 4
6259 /|\
6260 / | \
6261 / | \
6262 / 2 \
6263 3.../.\...5
6264 | / \ |
6265 | / \ |
6266 |/ \|
6267 0_________1
6268 */
6269
6270 const double coords[][3] = { { 0, 0, 0 },
6271 { 2, 0, 0 },
6272 { 1, 0, 1 },
6273 { 0, 2, 0 },
6274 { 2, 2, 0 },
6275 { 1, 2, 1 } };
6276 EntityHandle verts[6];
6277 for (unsigned i = 0; i < 6; ++i)
6278 mb->create_vertex( coords[i], verts[i] );
6279
6280 EntityHandle faces[4];
6281 EntityHandle tri[] = { verts[0], verts[1], verts[2] };
6282 EntityHandle quad1[] = { verts[0], verts[1], verts[5], verts[3] };
6283 EntityHandle quad2[] = { verts[1], verts[5], verts[4], verts[2] };
6284 EntityHandle quad3[] = { verts[2], verts[4], verts[3], verts[0] };
6285 mb->create_element( MBTRI, tri, 3, faces[0] );
6286 mb->create_element( MBQUAD, quad1, 4, faces[1] );
6287 mb->create_element( MBQUAD, quad2, 4, faces[2] );
6288 mb->create_element( MBQUAD, quad3, 4, faces[3] );
6289 Range source;
6290 std::copy( faces, faces+4, range_inserter(source) );
6291
6292 // Now skin the mesh. The only missing face is the
6293 // back triangle (verts 3, 4, & 5) so the skin should
6294 // be the edges bordering that face.
6295
6296 Range skin;
6297 Skinner tool(mb);
6298 rval = tool.find_skin( 0, source, 1, skin, use_adj );
6299 if (MB_SUCCESS != rval) {
6300 std::cerr << "Skinner failure at " __FILE__ ":" << __LINE__ << std::endl;
6301 return MB_FAILURE;
6302 }
6303 if (skin.size() != 3 || !skin.all_of_type(MBEDGE)) {
6304 std::cerr << "Skinner bad result at " __FILE__ ":" << __LINE__ << std::endl;
6305 return MB_FAILURE;
6306 }
6307
6308 // Check each edge
6309 std::vector<EntityHandle> conn[3];
6310 rval = mb->get_connectivity( &skin.front(), 1, conn[0] );
6311 if (MB_SUCCESS != rval)
6312 return rval;
6313 rval = mb->get_connectivity( &*++skin.begin(), 1, conn[1] );
6314 if (MB_SUCCESS != rval)
6315 return rval;
6316 rval = mb->get_connectivity( &skin.back(), 1, conn[2] );
6317 if (MB_SUCCESS != rval)
6318 return rval;
6319 for (int i = 0; i < 3; ++i)
6320 if (conn[i][0] > conn[i][1])
6321 std::swap(conn[i][0], conn[i][1]);
6322
6323 for (int i = 0; i < 3; ++i) {
6324 EntityHandle s = verts[i+3], e = verts[(i+1)%3 + 3];
6325 if (s > e)
6326 std::swap(s,e);
6327 int j = 0;
6328 for (j = 0; j < 3; ++j)
6329 if (conn[j][0] == s && conn[j][1] == e)
6330 break;
6331
6332 if (j == 3) {
6333 std::cerr << "Skin does not contain edge [" << s << "," << e << "] at "
6334 << __FILE__ ":" << __LINE__ << std::endl;
6335 return MB_FAILURE;
6336 }
6337 }
6338
6339 return MB_SUCCESS;
6340 }
6341
mb_skin_volume_test_common(bool use_adj)6342 ErrorCode mb_skin_volume_test_common( bool use_adj )
6343 {
6344 ErrorCode rval;
6345 Core moab;
6346 Interface *mb = &moab;
6347
6348 /* A 2 adjacent hexes hexes */
6349 /*
6350 9-----10----11
6351 / / /|
6352 / / / |
6353 6-----7-----8..5
6354 | . | . | /
6355 |. |. |/
6356 0-----1-----2
6357 */
6358
6359 const double coords[][3] = { { 0, 0, 0 },
6360 { 1, 0, 0 },
6361 { 2, 0, 0 },
6362 { 0, 1, 0 },
6363 { 1, 1, 0 },
6364 { 2, 1, 0 },
6365 { 0, 0, 1 },
6366 { 1, 0, 1 },
6367 { 2, 0, 1 },
6368 { 0, 1, 1 },
6369 { 1, 1, 1 },
6370 { 2, 1, 1 } };
6371 EntityHandle verts[12];
6372 for (unsigned i = 0; i < 12; ++i)
6373 mb->create_vertex( coords[i], verts[i] );
6374
6375 EntityHandle hex1c[] = { verts[0], verts[1], verts[4], verts[3],
6376 verts[6], verts[7], verts[10], verts[9] };
6377 EntityHandle hex2c[] = { verts[1], verts[2], verts[5], verts[4],
6378 verts[7], verts[8], verts[11], verts[10] };
6379 EntityHandle hex1, hex2;
6380 mb->create_element( MBHEX, hex1c, 8, hex1 );
6381 mb->create_element( MBHEX, hex2c, 8, hex2 );
6382 Range source;
6383 source.insert( hex1 );
6384 source.insert( hex2 );
6385
6386 // get all quads and shared face
6387 Range tmp, all_faces;
6388 mb->get_adjacencies( source, 2, true, all_faces, Interface::UNION );
6389 mb->get_adjacencies( source, 2, true, tmp, Interface::INTERSECT );
6390 assert(tmp.size() == 1);
6391 Range non_shared = subtract( all_faces, tmp );
6392
6393 // Now skin the mesh.
6394
6395 Range skin;
6396 Skinner tool(mb);
6397 rval = tool.find_skin( 0, source, 2, skin, use_adj );
6398 if (MB_SUCCESS != rval) {
6399 std::cerr << "Skinner failure at " __FILE__ ":" << __LINE__ << std::endl;
6400 return MB_FAILURE;
6401 }
6402 if (skin != non_shared) {
6403 std::cerr << "Skinner bad result at " __FILE__ ":" << __LINE__ << std::endl;
6404 return MB_FAILURE;
6405 }
6406
6407 return MB_SUCCESS;
6408 }
6409
mb_skin_scd_test()6410 ErrorCode mb_skin_scd_test()
6411 {
6412 // make a 10x10x5 scd mesh
6413 Core moab;
6414 Interface *mb = &moab;
6415 ScdInterface *scdi;
6416 ErrorCode rval = mb->query_interface(scdi);
6417 if (MB_SUCCESS != rval) return rval;
6418 HomCoord low(0, 0, 0), high(10, 10, 5);
6419 ScdBox *this_box;
6420 rval = scdi->construct_box(low, high, NULL, 0, this_box);
6421 if (MB_SUCCESS != rval) return rval;
6422
6423 // now skin it with the structured and original method, and compare results
6424 Skinner tool(mb);
6425 Range ents(this_box->start_element(), this_box->start_element()+this_box->num_elements()-1),
6426 scd_skin_ents, skin_ents;
6427 rval = tool.find_skin(0, ents, false, scd_skin_ents, NULL, true, true, true);
6428 if (MB_SUCCESS != rval) return rval;
6429
6430 rval = tool.find_skin(0, ents, false, skin_ents, NULL, true, true, false);
6431 if (MB_SUCCESS != rval) return rval;
6432
6433 // should be same number of entities
6434 if (scd_skin_ents.size() != skin_ents.size()) return MB_FAILURE;
6435
6436 skin_ents.clear();
6437 scd_skin_ents.clear();
6438
6439 // now test getting faces and vertices, also with existing faces now
6440 rval = tool.find_skin(0, ents, true, scd_skin_ents, NULL, true, true, true);
6441 if (MB_SUCCESS != rval) return rval;
6442
6443 rval = tool.find_skin(0, ents, true, skin_ents, NULL, true, true, false);
6444 if (MB_SUCCESS != rval) return rval;
6445
6446 // again, should have same numbers
6447 if (skin_ents.subset_by_type(MBVERTEX).size() != scd_skin_ents.subset_by_type(MBVERTEX).size())
6448 return MB_FAILURE;
6449
6450 return MB_SUCCESS;
6451 }
6452
mb_skin_fileset_test()6453 ErrorCode mb_skin_fileset_test()
6454 {
6455 Core moab;
6456 Interface *mb = &moab;
6457 ErrorCode error;
6458 const double coords[] = {0,0,0,
6459 1,0,0,
6460 2,0,0,
6461 2,1,0,
6462 1,1,0,
6463 0,1,0,
6464 0,0,1,
6465 1,0,1,
6466 2,0,1,
6467 2,1,1,
6468 1,1,1,
6469 0,1,1,
6470 0,0,2,
6471 1,0,2,
6472 2,0,2,
6473 2,1,2,
6474 1,1,2,
6475 0,1,2 };
6476 const size_t num_vtx = sizeof(coords)/sizeof(double)/3;
6477
6478 const int conn[] = {0,1,4,5,6,7,10,11,
6479 1,2,3,4,7,8,9,10,
6480 6,7,10,11,12,13,16,17,
6481 7,8,9,10,13,14,15,16};
6482 const size_t num_elems = sizeof(conn)/sizeof(int)/8;
6483
6484 EntityHandle verts[num_vtx], cells[num_elems];
6485 for (size_t i=0; i< num_vtx; ++i)
6486 {
6487 error = mb->create_vertex(coords+3*i, verts[i]); MB_CHK_ERR(error);
6488 }
6489
6490 for (size_t i=0; i< num_elems; ++i)
6491 {
6492 EntityHandle c[8];
6493 for (int j=0; j<8; j++)
6494 c[j] = verts[conn[8*i+j]];
6495
6496 error = mb->create_element(MBHEX, c, 8, cells[i]);MB_CHK_ERR(error);
6497 }
6498
6499 EntityHandle fileset;
6500 error = mb->create_meshset(MESHSET_SET, fileset);MB_CHK_ERR(error);
6501 error = mb->add_entities(fileset, &verts[0], num_vtx);MB_CHK_ERR(error);
6502 error = mb->add_entities(fileset, &cells[0], num_elems);MB_CHK_ERR(error);
6503
6504 Range fverts, fedges, ffaces, fcells;
6505 error = mb->get_entities_by_dimension(fileset, 0, fverts);MB_CHK_ERR(error);
6506 error = mb->get_entities_by_dimension(fileset, 1, fedges);MB_CHK_ERR(error);
6507 error = mb->get_entities_by_dimension(fileset, 2, ffaces);MB_CHK_ERR(error);
6508 error = mb->get_entities_by_dimension(fileset, 3, fcells);MB_CHK_ERR(error);
6509
6510 assert(fverts.size()==18 && fedges.size()==0 && ffaces.size()==0 && fcells.size()==4);
6511
6512 Skinner sk(mb);
6513 Range skin_ents;
6514 error = sk.find_skin(fileset, fcells, 2, skin_ents, false, true);MB_CHK_ERR(error);
6515 error = mb->get_entities_by_dimension(fileset, 2, ffaces);MB_CHK_ERR(error);
6516 assert(ffaces.size() == 16);
6517 error = sk.find_skin(fileset, fcells, 1, skin_ents, false, true);MB_CHK_ERR(error);
6518 error = mb->get_entities_by_dimension(fileset, 1, fedges);MB_CHK_ERR(error);
6519 assert(fedges.size() == 32);
6520
6521 const double fcoords[] = { 0,0,3,
6522 1,0,3,
6523 2,0,3,
6524 2,1,3,
6525 1,1,3,
6526 0,1,3 };
6527 const size_t num_fvtx = sizeof(fcoords)/sizeof(double)/3;
6528
6529 const int fconn[] = {0,1,4,5,
6530 1,2,3,4};
6531 const size_t num_faces = sizeof(fconn)/sizeof(int)/4;
6532 EntityHandle nwverts[num_fvtx], faces[num_faces];
6533 for (size_t i=0; i< num_fvtx; ++i)
6534 {
6535 error = mb->create_vertex(fcoords+3*i, nwverts[i]); MB_CHK_ERR(error);
6536 }
6537
6538 for (size_t i=0; i< num_faces; ++i)
6539 {
6540 EntityHandle c[4];
6541 for (int j=0; j<4; j++)
6542 c[j] = nwverts[fconn[4*i+j]];
6543
6544 error = mb->create_element(MBQUAD, c, 4, faces[i]);MB_CHK_ERR(error);
6545 }
6546 EntityHandle fileset1;
6547 error = mb->create_meshset(MESHSET_SET, fileset1);MB_CHK_ERR(error);
6548 error = mb->add_entities(fileset1, &nwverts[0], num_fvtx);MB_CHK_ERR(error);
6549 error = mb->add_entities(fileset1, &faces[0], num_faces);MB_CHK_ERR(error);
6550
6551 Range verts1, edges1, faces1;
6552 error = mb->get_entities_by_dimension(fileset1, 0, verts1);MB_CHK_ERR(error);
6553 error = mb->get_entities_by_dimension(fileset1, 1, edges1);MB_CHK_ERR(error);
6554 error = mb->get_entities_by_dimension(fileset1, 2, faces1);MB_CHK_ERR(error);
6555
6556 assert(verts1.size()==6 && edges1.size()==0 && faces1.size()==2);
6557
6558 // error = sk.find_skin(fileset1, faces1, 1, skin_ents, false, true);MB_CHK_ERR(error);
6559 error = sk.find_skin(fileset1, faces1, false, skin_ents, NULL, true, true, false);MB_CHK_ERR(error);
6560 error = mb->get_entities_by_dimension(fileset1, 1, edges1);MB_CHK_ERR(error);
6561 assert(edges1.size() == 6);
6562
6563
6564 return MB_SUCCESS;
6565 }
6566
6567 // It is a common problem for readers to incorrectly
6568 // handle invalid/unknown file types and non-existant
6569 // files. For either case, MOAB will try all readers
6570 // (assuming it doesn't recongnize the file extension),
6571 // so we can test all the readers w/out knowing which
6572 // readers we have.
6573 const char* argv0 = 0;
mb_read_fail_test()6574 ErrorCode mb_read_fail_test()
6575 {
6576 Core moab;
6577 Interface* mb = &moab;
6578
6579 const char BAD_FILE_NAME[] = "non-existant-file.txt";
6580 ErrorCode rval;
6581
6582 FILE* fptr = fopen(BAD_FILE_NAME,"r");
6583 if (fptr) {
6584 fclose(fptr);
6585 std::cout << "Test cannot proceed while file exists: " << BAD_FILE_NAME << std::endl;
6586 return MB_FAILURE;
6587 }
6588
6589 // try reading a non-existant file
6590
6591 rval = mb->load_file( BAD_FILE_NAME );
6592 if (MB_FILE_DOES_NOT_EXIST != rval)
6593 return MB_FAILURE;
6594
6595 // try reading an invalid file
6596 if (!argv0) // not set by main, oops!
6597 return MB_FAILURE;
6598 rval = mb->load_file( argv0 );
6599 if (MB_SUCCESS == rval)
6600 return MB_FAILURE;
6601
6602 return MB_SUCCESS;
6603 }
6604
6605 #define TEST_ERROR_CODE(E) \
6606 if (mb->get_error_string(E) != #E) { \
6607 std::cerr << "Invalid error string from get_error_string for " \
6608 << #E << ": " << mb->get_error_string(E) << std::endl;\
6609 return MB_FAILURE; \
6610 }
6611
mb_enum_string_test()6612 ErrorCode mb_enum_string_test()
6613 {
6614 Core moab;
6615 Interface* mb = &moab;
6616
6617 TEST_ERROR_CODE( MB_SUCCESS );
6618 TEST_ERROR_CODE( MB_INDEX_OUT_OF_RANGE );
6619 TEST_ERROR_CODE( MB_TYPE_OUT_OF_RANGE );
6620 TEST_ERROR_CODE( MB_MEMORY_ALLOCATION_FAILED );
6621 TEST_ERROR_CODE( MB_ENTITY_NOT_FOUND );
6622 TEST_ERROR_CODE( MB_MULTIPLE_ENTITIES_FOUND );
6623 TEST_ERROR_CODE( MB_TAG_NOT_FOUND );
6624 TEST_ERROR_CODE( MB_FILE_DOES_NOT_EXIST );
6625 TEST_ERROR_CODE( MB_FILE_WRITE_ERROR );
6626 TEST_ERROR_CODE( MB_NOT_IMPLEMENTED );
6627 TEST_ERROR_CODE( MB_ALREADY_ALLOCATED );
6628 TEST_ERROR_CODE( MB_VARIABLE_DATA_LENGTH );
6629 TEST_ERROR_CODE( MB_INVALID_SIZE );
6630 TEST_ERROR_CODE( MB_UNSUPPORTED_OPERATION );
6631 TEST_ERROR_CODE( MB_UNHANDLED_OPTION );
6632 TEST_ERROR_CODE( MB_STRUCTURED_MESH );
6633 TEST_ERROR_CODE( MB_FAILURE );
6634
6635 return MB_SUCCESS;
6636 }
6637
6638 // Test basic skinning using vert-to-elem adjacencies
6639 ErrorCode mb_skin_verts_common( unsigned dim, bool skin_elems );
6640
mb_skin_surf_verts_test()6641 ErrorCode mb_skin_surf_verts_test()
6642 { return mb_skin_verts_common( 2, false ); }
6643
mb_skin_vol_verts_test()6644 ErrorCode mb_skin_vol_verts_test()
6645 { return mb_skin_verts_common( 3, false ); }
6646
mb_skin_surf_verts_elems_test()6647 ErrorCode mb_skin_surf_verts_elems_test()
6648 { return mb_skin_verts_common( 2, true ); }
6649
mb_skin_vol_verts_elems_test()6650 ErrorCode mb_skin_vol_verts_elems_test()
6651 { return mb_skin_verts_common( 3, true ); }
6652
mb_skin_verts_common(unsigned dim,bool skin_elems)6653 ErrorCode mb_skin_verts_common( unsigned dim, bool skin_elems )
6654 {
6655 const int INT = 10; // intervals+1
6656 const char* tmp_file = "structured.vtk";
6657 std::ofstream str(tmp_file);
6658 if (!str) {
6659 std::cerr << tmp_file << ": filed to create temp file" << std::endl;
6660 return MB_FAILURE;
6661 }
6662 str << "#vtk DataFile Version 2.0" << std::endl
6663 << "mb_skin_verts_common temp file" << std::endl
6664 << "ASCII" << std::endl
6665 << "DATASET STRUCTURED_POINTS" << std::endl
6666 << "DIMENSIONS " << INT << " " << (dim > 1 ? INT : 1) << " " << (dim > 2 ? INT : 1) << std::endl
6667 << "ORIGIN 0 0 0" << std::endl
6668 << "SPACING 1 1 1" << std::endl;
6669 str.close();
6670
6671 Core moab;
6672 Interface& mb = moab;
6673 ErrorCode rval;
6674
6675 rval = mb.load_file( tmp_file );
6676 remove( tmp_file );
6677 if (MB_SUCCESS != rval)
6678 return rval;
6679
6680 Range ents;
6681 rval = mb.get_entities_by_dimension( 0, dim, ents );
6682 if (MB_SUCCESS != rval)
6683 return rval;
6684 if (ents.empty())
6685 return MB_FAILURE;
6686
6687 Skinner tool( &mb );
6688
6689 // mesh is a structured quad/hex mesh, so we can
6690 // determine skin vertices from the number of
6691 // adjacent elements.
6692 unsigned interior_adj = 1;
6693 for (unsigned i = 0; i < dim; ++i)
6694 interior_adj *= 2;
6695 Range expected, verts;
6696 rval = mb.get_entities_by_dimension( 0, 0, verts );
6697 if (MB_SUCCESS != rval)
6698 return rval;
6699 Range::iterator h = expected.begin();
6700 std::vector<EntityHandle> adj;
6701 for (Range::iterator v = verts.begin(); v != verts.end(); ++v) {
6702 adj.clear();
6703 rval = mb.get_adjacencies( &*v, 1, dim, false, adj );
6704 if (MB_SUCCESS != rval)
6705 return rval;
6706 if (adj.size() < interior_adj)
6707 h = expected.insert( h, *v );
6708 }
6709
6710 // Get skin vertices using skinner
6711 Range actual;
6712 rval = tool.find_skin( 0, ents, !skin_elems, actual );
6713 if (MB_SUCCESS != rval)
6714 return rval;
6715
6716 Range extra, missing;
6717 if (!skin_elems) {
6718 // Check that we got expected result
6719 extra = subtract( actual, expected );
6720 missing = subtract( expected, actual );
6721 if (!extra.empty() || !missing.empty()) {
6722 std::cout << "Extra vertices returned: " << extra << std::endl
6723 << "Missing vertices: " << missing << std::endl;
6724 return MB_FAILURE;
6725 }
6726 return MB_SUCCESS;
6727 }
6728
6729 // test that no extra elements we're created
6730 extra.clear();
6731 rval = mb.get_entities_by_dimension( 0, dim-1, extra );
6732 if (MB_SUCCESS != rval)
6733 return rval;
6734 extra = subtract( extra, actual );
6735 if (!extra.empty()) {
6736 std::cout << "Extra/non-returned elements created: " << extra << std::endl;
6737 return MB_FAILURE;
6738 }
6739
6740 // check that each skin vertex has the correct number of adjacent quads
6741 missing.clear(); extra.clear();
6742 for (Range::iterator i = expected.begin(); i != expected.end(); ++i) {
6743 std::vector<EntityHandle> elem, side;
6744 rval = mb.get_adjacencies( &*i, 1, dim, false, elem );
6745 if (MB_SUCCESS != rval) return rval;
6746 rval = mb.get_adjacencies( &*i, 1, dim-1, false, side );
6747 if (MB_SUCCESS != rval) return rval;
6748 if (elem.size() == 1) {
6749 if (side.size() < dim)
6750 missing.insert( *i );
6751 else if(side.size() > dim)
6752 extra.insert( *i );
6753 }
6754 else if (elem.size() == interior_adj) {
6755 if (!side.empty())
6756 extra.insert( *i );
6757 }
6758 else {
6759 if (side.size() < interior_adj/2)
6760 missing.insert( *i );
6761 else if (side.size() > interior_adj/2)
6762 extra.insert( *i );
6763 }
6764 }
6765 if (!missing.empty() || !extra.empty()) {
6766 std::cout << "Skin elements missing at vertices: " << missing << std::endl
6767 << "Extra skin elements at vertices: " << extra << std::endl;
6768 return MB_FAILURE;
6769 }
6770
6771 // check that all returned elements are actually on the skin
6772 extra.clear();
6773 for (Range::iterator i = actual.begin(); i != actual.end(); ++i) {
6774 Range verts2;
6775 rval = mb.get_adjacencies( &*i, 1, 0, false, verts2 );
6776 if (MB_SUCCESS != rval)
6777 return rval;
6778 verts2 = subtract( verts2, expected );
6779 if (!verts2.empty())
6780 extra.insert( *i );
6781 }
6782 if (!extra.empty()) {
6783 std::cout << "Skinner returned elements not on skin: " << extra << std::endl;
6784 return MB_FAILURE;
6785 }
6786
6787 return MB_SUCCESS;
6788 }
6789
6790 // Test that skinning of polyhedra works
mb_skin_poly_test()6791 ErrorCode mb_skin_poly_test()
6792 {
6793 /* Create a mesh composed of 8 hexagonal prisms and
6794 two hexahedra by extruding the following cross section
6795 two steps in the Z direction.
6796
6797 0-----1
6798 / (0) \
6799 (11)/ \(1)
6800 / \
6801 11 2
6802 / \ Y / \
6803 (10)/ \(12)^(13)/ \(2)
6804 / \ | / \
6805 10 12-----13 3
6806 | | | | |
6807 (9)| | +--|-->X |(3)
6808 | | | |
6809 9 15-----14 4
6810 \ / \ /
6811 (8)\ /(15) (14)\ /(4)
6812 \ / \ /
6813 8 5
6814 \ /
6815 (7)\ /(5)
6816 \ (6) /
6817 7-----6
6818 */
6819
6820 const double coords2D[][2] = { {-1, 5}, // 0
6821 { 1, 5},
6822 { 3, 3},
6823 { 5, 1},
6824 { 5,-1},
6825 { 3,-3}, // 5
6826 { 1,-5},
6827 {-1,-5},
6828 {-3,-3},
6829 {-5,-1},
6830 {-5, 1}, // 10
6831 {-3, 3},
6832 {-1, 1},
6833 { 1, 1},
6834 { 1,-1},
6835 {-1,-1} // 15
6836 };
6837 const int polyconn[4][6] = { { 0, 1, 2, 13, 12, 11 },
6838 { 2, 3, 4, 5, 14, 13 },
6839 { 5, 6, 7, 8, 15, 14 },
6840 { 8, 9, 10, 11, 12, 15 } };
6841 const int polyside[4][6] = { { 0, 1, 13, 16, 12, 11 },
6842 { 2, 3, 4, 14, 17, 13 },
6843 { 5, 6, 7, 15, 18, 14 },
6844 { 8, 9, 10, 12, 19, 15 } };
6845
6846 ErrorCode rval;
6847 Core moab;
6848 Interface& mb = moab;
6849 Range regions, faces, interior_faces;
6850
6851 // create 48 vertices
6852 EntityHandle verts[3][16];
6853 for (int i = 0; i < 3; ++i) {
6854 for (int j = 0; j < 16; ++j) {
6855 double coords[3] = { coords2D[j][0], coords2D[j][1], static_cast<double>(2*i) };
6856 rval = mb.create_vertex( coords, verts[i][j] );
6857 if (MB_SUCCESS != rval) return rval;
6858 }
6859 }
6860
6861 // create two hexahedra
6862 EntityHandle hexes[2];
6863 for (int i = 0; i < 2; ++i) {
6864 EntityHandle conn[8] = { verts[i ][15],
6865 verts[i ][14],
6866 verts[i ][13],
6867 verts[i ][12],
6868 verts[i+1][15],
6869 verts[i+1][14],
6870 verts[i+1][13],
6871 verts[i+1][12] };
6872 rval = mb.create_element( MBHEX, conn, 8, hexes[i] );
6873 if (MB_SUCCESS != rval) return rval;
6874 regions.insert(hexes[i]);
6875 }
6876
6877 // create hexagonal faces
6878 EntityHandle hexagons[3][4];
6879 for (int i = 0; i < 3; ++i) {
6880 for (int j = 0; j < 4; ++j) {
6881 EntityHandle conn[6];
6882 for (int k = 0; k < 6; ++k)
6883 conn[k] = verts[i][polyconn[j][k]];
6884 rval = mb.create_element( MBPOLYGON, conn, 6, hexagons[i][j] );
6885 if (MB_SUCCESS != rval) return rval;
6886 faces.insert( hexagons[i][j] );
6887 if (i == 1)
6888 interior_faces.insert( hexagons[i][j] );
6889 }
6890 }
6891
6892 // create quadrilateral faces
6893 EntityHandle quads[2][20];
6894 for (int i = 0; i < 2; ++i) {
6895 for (int j = 0; j < 20; ++j) {
6896 int c1, c2;
6897 if (j < 12) {
6898 c1 = j; c2 = (j+1)%12;
6899 }
6900 else if (j < 16) {
6901 c1 = j; c2 = 2 + 3*((j-9)%4);
6902 }
6903 else {
6904 c1 = j-4; c2 = 12 + (j-15)%4;
6905 }
6906 EntityHandle conn[4] = { verts[i ][c1],
6907 verts[i ][c2],
6908 verts[i+1][c2],
6909 verts[i+1][c1] };
6910 rval = mb.create_element( MBQUAD, conn, 4, quads[i][j] );
6911 if (MB_SUCCESS != rval) return rval;
6912 faces.insert( quads[i][j] );
6913 if (j > 11)
6914 interior_faces.insert( quads[i][j] );
6915 }
6916 }
6917
6918 // create polyhedra
6919 EntityHandle poly[2][4];
6920 for (int i = 0; i < 2; ++i) {
6921 for (int j = 0; j < 4; ++j) {
6922 EntityHandle conn[8];
6923 for (int k = 0; k < 6; ++k)
6924 conn[k] = quads[i][polyside[j][k]];
6925 conn[6] = hexagons[ i][j];
6926 conn[7] = hexagons[i+1][j];
6927 rval = mb.create_element( MBPOLYHEDRON, conn, 8, poly[i][j] );
6928 if (MB_SUCCESS != rval) return rval;
6929 regions.insert( poly[i][j] );
6930 }
6931 }
6932
6933 Range interior_verts;
6934 interior_verts.insert( verts[1][12] );
6935 interior_verts.insert( verts[1][13] );
6936 interior_verts.insert( verts[1][14] );
6937 interior_verts.insert( verts[1][15] );
6938
6939 Skinner tool(&mb);
6940 Range skin;
6941 rval = tool.find_skin( 0, regions, true, skin, 0, true, false );
6942 if (MB_SUCCESS != rval) {
6943 std::cout << "Vertex skinning failed with: " << mb.get_error_string(rval) << std::endl;
6944 return rval;
6945 }
6946
6947 Range all_verts, all_faces;
6948 rval = mb.get_entities_by_dimension( 0, 0, all_verts );
6949 if (MB_SUCCESS != rval) return rval;
6950 rval = mb.get_entities_by_dimension( 0, 2, all_faces );
6951 if (MB_SUCCESS != rval) return rval;
6952
6953 Range expected = subtract( all_verts, interior_verts );
6954 if (expected != skin) {
6955 std::cout << "Skinner returned incorrect vertices." << std::endl;
6956 return MB_FAILURE;
6957 }
6958 if (all_faces != faces) {
6959 std::cout << "Skinner created/deleted faces for vertex-only skinning" << std::endl;
6960 return MB_FAILURE;
6961 }
6962
6963 skin.clear();
6964 rval = tool.find_skin( 0, regions, false, skin, 0, true, false );
6965 if (MB_SUCCESS != rval) {
6966 std::cout << "Non-create face skinning failed with: " << mb.get_error_string(rval) << std::endl;
6967 return rval;
6968 }
6969 expected = subtract( all_faces, interior_faces );
6970 if (expected != skin) {
6971 std::cout << "Skinner returned incorrect faces." << std::endl;
6972 return MB_FAILURE;
6973 }
6974 if (all_faces != faces) {
6975 std::cout << "Skinner created/deleted faces for no-create skinning" << std::endl;
6976 return MB_FAILURE;
6977 }
6978
6979 skin.clear();
6980 rval = tool.find_skin( 0, regions, false, skin, 0, true, true );
6981 if (MB_SUCCESS != rval) {
6982 std::cout << "Create face skinning failed with: " << mb.get_error_string(rval) << std::endl;
6983 return rval;
6984 }
6985 Range all_faces2;
6986 rval = mb.get_entities_by_dimension( 0, 2, all_faces2 );
6987 if (MB_SUCCESS != rval) return rval;
6988 Range difference = subtract( all_faces2, all_faces );
6989 if (difference.size() != 2) { // should have created two quads for hex top/bottom
6990 std::cout << "Skinner failed to create new quads or created to many." << std::endl;
6991 return MB_FAILURE;
6992 }
6993 expected.merge(difference);
6994 if (expected != skin) {
6995 std::cout << "Skinner returned incorrect faces." << std::endl;
6996 return MB_FAILURE;
6997 }
6998 // check that new faces are correct
6999 EntityHandle expected_conn[2][4] = {
7000 { verts[0][12],verts[0][13],verts[0][14],verts[0][15] },
7001 { verts[2][12],verts[2][13],verts[2][14],verts[2][15] } };
7002 EntityHandle nq[2] = { difference.front(), difference.back() };
7003 for (int i = 0; i < 2; ++i) {
7004 const EntityHandle* conn;
7005 int len;
7006 bool found = false;
7007 for (int j = 0; !found && j < 2; ++j) {
7008 rval = mb.get_connectivity( nq[j], conn, len );
7009 if (MB_SUCCESS != rval) return rval;
7010 int idx1 = std::find(conn,conn+len,expected_conn[i][0])-conn;
7011 if (idx1 == len) continue;
7012 found = true;
7013 for (int k = 1; k < 4; ++k)
7014 if (conn[(idx1+k)%4] != expected_conn[i][k])
7015 found = false;
7016 if (!found) {
7017 found = true;
7018 for (int k = 1; k < 4; ++k)
7019 if (conn[(idx1+4-k)%4] != expected_conn[i][k])
7020 found = false;
7021 }
7022 }
7023 if (!found) {
7024 std::cerr << "Skinner did not create & return expected quad " << i << std::endl;
7025 return MB_FAILURE;
7026 }
7027 }
7028
7029 return MB_SUCCESS;
7030 }
7031
7032 // Test that skinning of higher-order elements works
mb_skin_higher_order_faces_common(bool use_adj)7033 ErrorCode mb_skin_higher_order_faces_common( bool use_adj )
7034 {
7035 /* Create mesh:
7036
7037 0---1---2---3---4
7038 | | /
7039 | | /
7040 5 6 7 8 9
7041 | | /
7042 | | /
7043 10--11--12
7044 */
7045
7046 ErrorCode rval;
7047 Core moab;
7048 Interface& mb = moab;
7049
7050 double coords[13][3] = {
7051 {0,4,0}, {2,4,0}, {4,4,0}, {6,4,0}, {8,4,0},
7052 {0,2,0}, {2,2,0}, {4,2,0}, {5,2,0}, {6,2,0},
7053 {0,0,0}, {2,0,0}, {4,0,0} };
7054 EntityHandle verts[13];
7055 for (int i = 0; i < 13; ++i) {
7056 rval = mb.create_vertex( coords[i], verts[i] );
7057 if (MB_SUCCESS != rval) return rval;
7058 }
7059
7060 EntityHandle qconn[9] = {
7061 verts[0], verts[2], verts[12], verts[10],
7062 verts[1], verts[7], verts[11], verts[5],
7063 verts[6] };
7064 EntityHandle tconn[7] = {
7065 verts[2], verts[4], verts[12],
7066 verts[3], verts[9], verts[7],
7067 verts[8] };
7068 EntityHandle quad, tri;
7069 rval = mb.create_element( MBQUAD, qconn, 9, quad );
7070 if (MB_SUCCESS != rval) return rval;
7071 rval = mb.create_element( MBTRI, tconn, 7, tri );
7072 if (MB_SUCCESS != rval) return rval;
7073
7074 Range faces;
7075 faces.insert(quad);
7076 faces.insert(tri);
7077
7078 Range skin_verts;
7079 const int skin_vert_idx[] = { 0, 1, 2, 3, 4, 5, 9, 10, 11, 12 };
7080 for (size_t i = 0; i < sizeof(skin_vert_idx)/sizeof(skin_vert_idx[0]); ++i)
7081 skin_verts.insert( verts[skin_vert_idx[i]] );
7082
7083 Skinner tool(&mb);
7084 Range skin;
7085
7086 rval = tool.find_skin( 0, faces, true, skin, 0, use_adj, false );
7087 if (MB_SUCCESS != rval) {
7088 std::cout << "Vertex skinning failed with: " << mb.get_error_string(rval) << std::endl;
7089 return rval;
7090 }
7091 if (skin != skin_verts) {
7092 std::cout << "Skinner returned incorrect vertices." << std::endl;
7093 return MB_FAILURE;
7094 }
7095
7096 const int skin_edges[5][3] = {
7097 {0,1,2}, {2,3,4}, {4,9,12}, {12,11,10}, {10,5,0} };
7098 skin.clear();
7099 rval = tool.find_skin( 0, faces, false, skin, 0, use_adj, true );
7100 if (MB_SUCCESS != rval) {
7101 std::cout << "Edge skinning failed with: " << mb.get_error_string(rval) << std::endl;
7102 return rval;
7103 }
7104 if (skin.size() != 5u) {
7105 std::cout << "Skinner returned " << skin.size() << " vertices. Expected 5" << std::endl;
7106 return MB_FAILURE;
7107 }
7108 int num_quadratic = 0;
7109 const EntityHandle* conn;
7110 int len;
7111 for (Range::iterator i = skin.begin(); i != skin.end(); ++i) {
7112 rval = mb.get_connectivity( *i, conn, len, false );
7113 if (MB_SUCCESS != rval) return rval;
7114 if (len == 3)
7115 num_quadratic++;
7116 else if(len != 2) {
7117 std::cerr << "Skinner created edge with " << len << " vertices" << std::endl;
7118 return MB_FAILURE;
7119 }
7120 }
7121 if (num_quadratic != 5) {
7122 std::cerr << num_quadratic << " of 5 created edges were quadratic" << std::endl;
7123 return MB_FAILURE;
7124 }
7125
7126 for (int i = 0; i < 5; ++i) {
7127 bool found = false;
7128 for (Range::iterator j = skin.begin(); j != skin.end(); ++j) {
7129 mb.get_connectivity( *j, conn, len, false );
7130 if (conn[2] == verts[skin_edges[i][1]]) {
7131 found = true;
7132 break;
7133 }
7134 }
7135 if (!found) {
7136 std::cerr << "One or more skin edges is incorrect" << std::endl;
7137 return MB_FAILURE;
7138 }
7139 if ((conn[0] != verts[skin_edges[i][0]] || conn[1] != verts[skin_edges[i][2]])
7140 && (conn[0] != verts[skin_edges[i][2]] || conn[1] != verts[skin_edges[i][0]])) {
7141 std::cerr << "Invalid skin edge connectivity" << std::endl;
7142 return MB_FAILURE;
7143 }
7144 }
7145
7146 return MB_SUCCESS;
7147 }
mb_skin_higher_order_faces_test()7148 ErrorCode mb_skin_higher_order_faces_test()
7149 { return mb_skin_higher_order_faces_common( false ); }
mb_skin_adj_higher_order_faces_test()7150 ErrorCode mb_skin_adj_higher_order_faces_test()
7151 { return mb_skin_higher_order_faces_common( true ); }
7152
7153 // Test that skinning of higher-order elements works
mb_skin_higher_order_regions_common(bool use_adj)7154 ErrorCode mb_skin_higher_order_regions_common( bool use_adj )
7155 {
7156 // create mesh containing two 27-node hexes
7157 /*
7158 0,2---1,2---2,2---3,2---4,2
7159 | | |
7160 | | |
7161 0,1 1,1 2,1 3,1 4,1
7162 | | |
7163 | | |
7164 0,0---1,0---2,0---3,0---4,0
7165 */
7166
7167 ErrorCode rval;
7168 Core moab;
7169 Interface& mb = moab;
7170 Range hexes;
7171
7172
7173 EntityHandle verts[5][3][3];
7174 for (int i = 0; i < 5; ++i)
7175 for (int j = 0; j < 3; ++j)
7176 for (int k = 0; k < 3; ++k) {
7177 double coords[] = { static_cast<double>(i), static_cast<double>(j), static_cast<double>(k) };
7178 rval = mb.create_vertex( coords, verts[i][j][k] );
7179 if (MB_SUCCESS != rval) return rval;
7180 }
7181
7182 int hex_conn[][3] = { // corners
7183 {0,0,0}, {2,0,0}, {2,2,0}, {0,2,0},
7184 {0,0,2}, {2,0,2}, {2,2,2}, {0,2,2},
7185 // mid-edge
7186 {1,0,0}, {2,1,0}, {1,2,0}, {0,1,0},
7187 {0,0,1}, {2,0,1}, {2,2,1}, {0,2,1},
7188 {1,0,2}, {2,1,2}, {1,2,2}, {0,1,2},
7189 // mid-face
7190 {1,0,1}, {2,1,1}, {1,2,1}, {0,1,1},
7191 {1,1,0}, {1,1,2},
7192 // mid-volume
7193 {1,1,1} };
7194
7195 EntityHandle hexverts[2][27];
7196 for (int i = 0; i < 2; ++i) {
7197 EntityHandle h;
7198 for (int j = 0; j < 27; ++j)
7199 hexverts[i][j] = verts[ 2*i+hex_conn[j][0] ][ hex_conn[j][1] ][ hex_conn[j][2] ];
7200 rval = mb.create_element( MBHEX, hexverts[i], 27, h );
7201 if (MB_SUCCESS != rval)
7202 return rval;
7203 hexes.insert( h );
7204 }
7205
7206 Range interior_verts;
7207 interior_verts.insert( verts[1][1][1] ); // mid-node of hex 1
7208 interior_verts.insert( verts[3][1][1] ); // mid-node of hex 2
7209 interior_verts.insert( verts[2][1][1] ); // mid-node of shared face
7210
7211 Skinner tool(&mb);
7212 Range skin;
7213
7214 rval = tool.find_skin( 0, hexes, true, skin, 0, use_adj, false );
7215 if (MB_SUCCESS != rval) {
7216 std::cout << "Vertex skinning failed with: " << mb.get_error_string(rval)
7217 << std::endl;
7218 return rval;
7219 }
7220 Range extra = intersect( skin, interior_verts );
7221 if (!extra.empty()) {
7222 std::cout << "Skinner returned " << extra.size() << " interior vertices"
7223 << std::endl;
7224 std::cout << extra << std::endl;
7225 return MB_FAILURE;
7226 }
7227 int num_vtx;
7228 mb.get_number_entities_by_dimension( 0, 0, num_vtx );
7229 size_t num_skin = num_vtx - interior_verts.size();
7230 if (skin.size() != num_skin) {
7231 std::cout << "Skinner returned " << skin.size() << " of "
7232 << num_skin << " skin vertices" <<std::endl;
7233 return MB_FAILURE;
7234 }
7235
7236 skin.clear();
7237 rval = tool.find_skin( 0, hexes, false, skin, 0, use_adj, true );
7238 if (MB_SUCCESS != rval) {
7239 std::cout << "Element skinning failed with: " << mb.get_error_string(rval) << std::endl;
7240 return rval;
7241 }
7242
7243 if (skin.size() > 10u) {
7244 std::cout << "Skinner created too many faces" << std::endl;
7245 return MB_FAILURE;
7246 }
7247
7248 bool all_okay = true;
7249 bool faces[2][6] = { {0,0,0,0,0,0},{0,0,0,0,0,0} };
7250 const EntityHandle *conn;
7251 int len;
7252 for (Range::iterator it = skin.begin(); it != skin.end(); ++it) {
7253 rval = mb.get_connectivity( *it, conn, len );
7254 if (MB_SUCCESS != rval) return rval;
7255 if (len != 9) {
7256 std::cout << "Skinner created face with " << len << " nodes" << std::endl;
7257 all_okay = false;
7258 continue;
7259 }
7260
7261 int valid, side, sense, offset;
7262 for (int h = 0; h < 2; ++h) {
7263 valid = CN::SideNumber( MBHEX, hexverts[h], conn, 4, 2, side, sense, offset );
7264 if (valid != 0)
7265 continue;
7266 if (sense != 1) {
7267 std::cout << "Skinner created reversed face for hex "
7268 << h << " side " << side << std::endl;
7269 all_okay = false;
7270 continue;
7271 }
7272
7273 int idx[9], len2;
7274 EntityType sidetype;
7275 CN::SubEntityNodeIndices( MBHEX, 27, 2, side, sidetype, len2, idx );
7276 assert(sidetype == MBQUAD);
7277 assert(len2 == 9);
7278 if ( conn[ offset ] != hexverts[h][idx[0]] ||
7279 conn[ (offset+1)%4] != hexverts[h][idx[1]] ||
7280 conn[ (offset+2)%4] != hexverts[h][idx[2]] ||
7281 conn[ (offset+3)%4] != hexverts[h][idx[3]] ||
7282 conn[4+ offset ] != hexverts[h][idx[4]] ||
7283 conn[4+(offset+1)%4] != hexverts[h][idx[5]] ||
7284 conn[4+(offset+2)%4] != hexverts[h][idx[6]] ||
7285 conn[4+(offset+3)%4] != hexverts[h][idx[7]] ||
7286 conn[ 8 ] != hexverts[h][idx[8]]) {
7287 std::cout << "Side " << side << " of hex " << h
7288 << " has invalid connectivity" << std::endl;
7289 all_okay = false;
7290 }
7291
7292
7293 faces[h][side] = true;
7294 }
7295 }
7296
7297 for (int h = 0; h < 2; ++h) {
7298 for (int i = 0; i < 6; ++i) {
7299 if ((h == 0 && i == 1) || (h == 1 && i == 3)) {
7300 if (faces[h][i]) {
7301 std::cout << "Skinner created interior face for side "
7302 << i << " of hex " << h << std::endl;
7303 all_okay = false;
7304 }
7305 }
7306 else if (!faces[h][i]) {
7307 std::cout << "Skinner failed to create side "
7308 << i << " of hex " << h << std::endl;
7309 all_okay = false;
7310 }
7311 }
7312 }
7313
7314 return all_okay ? MB_SUCCESS : MB_FAILURE;
7315 }
7316
7317 // Test that skinning of higher-order elements works
mb_skin_higher_order_pyramids()7318 ErrorCode mb_skin_higher_order_pyramids( )
7319 {
7320 // create mesh containing 13-node pyramid
7321 /*
7322
7323 */
7324
7325 ErrorCode rval;
7326 Core moab;
7327 Interface& mb = moab;
7328 Range pyramids;
7329
7330
7331 // easier to create a 27 node grid, and then pick a 13-node pyramid
7332 EntityHandle verts[3][3][3];
7333 for (int i = 0; i < 3; ++i)
7334 for (int j = 0; j < 3; ++j)
7335 for (int k = 0; k < 3; ++k) {
7336 double coords[] = { static_cast<double>(i), static_cast<double>(j), static_cast<double>(k) };
7337 rval = mb.create_vertex( coords, verts[i][j][k] );
7338 if (MB_SUCCESS != rval) return rval;
7339 }
7340
7341
7342 EntityHandle piramid1[13]={19, 25, 27, 21, 1, 22, 26, 24, 20, 10, 13, 14, 11};
7343
7344 EntityHandle h;
7345
7346 rval = mb.create_element( MBPYRAMID, piramid1, 13, h );
7347 if (MB_SUCCESS != rval)
7348 return rval;
7349 pyramids.insert( h );
7350
7351 Range faces;
7352 rval = mb.get_adjacencies(pyramids,2, true, faces , Interface::UNION);
7353 // triangles should have 6 nodes, quads 8 nodes
7354
7355 if (MB_SUCCESS != rval)
7356 return rval;
7357
7358 Range tris=faces.subset_by_type(MBTRI);
7359 Range quads = faces.subset_by_type(MBQUAD);
7360
7361 for (Range::iterator tit=tris.begin(); tit!=tris.end(); tit++)
7362 {
7363 EntityHandle triangle = *tit;
7364 const EntityHandle * conn;
7365 int num_verts;
7366 rval = mb.get_connectivity(triangle, conn, num_verts);
7367 if (MB_SUCCESS != rval)
7368 return rval;
7369 if (6!=num_verts)
7370 return MB_FAILURE;
7371 }
7372 for (Range::iterator qit=quads.begin(); qit!=quads.end(); qit++)
7373 {
7374 EntityHandle quad = *qit;
7375 const EntityHandle * conn;
7376 int num_verts;
7377 rval = mb.get_connectivity(quad, conn, num_verts);
7378 if (MB_SUCCESS != rval)
7379 return rval;
7380 if (8!=num_verts)
7381 return MB_FAILURE;
7382 }
7383
7384 return MB_SUCCESS;
7385 }
mb_skin_higher_order_regions_test()7386 ErrorCode mb_skin_higher_order_regions_test()
7387 { return mb_skin_higher_order_regions_common(false); }
mb_skin_adj_higher_order_regions_test()7388 ErrorCode mb_skin_adj_higher_order_regions_test()
7389 { return mb_skin_higher_order_regions_common(true); }
7390
7391
mb_skin_reversed_common(int dim,bool use_adj)7392 ErrorCode mb_skin_reversed_common( int dim, bool use_adj )
7393 {
7394 EntityType type, subtype;
7395 switch (dim) {
7396 case 2: type = MBTRI; subtype = MBEDGE; break;
7397 case 3: type = MBTET; subtype = MBTRI; break;
7398 default: assert(false); return MB_FAILURE;
7399 }
7400
7401 /* 3
7402 /|\
7403 / | \
7404 / | \
7405 / | \
7406 0----1----2
7407 */
7408
7409 ErrorCode rval;
7410 Core moab;
7411 Interface& mb = moab;
7412 Range hexes;
7413
7414 double coords[][3] = { { 0, 0, 0 },
7415 { 1, 0, 0 },
7416 { 2, 0, 0 },
7417 { 1, 2, 0 },
7418 { 1, 2, 2 } };
7419 EntityHandle verts[5];
7420 const int nvtx = 2+dim;
7421 for (int i = 0; i < nvtx; ++i) {
7422 rval = mb.create_vertex( coords[i], verts[i] );
7423 if (MB_SUCCESS != rval) return rval;
7424 }
7425 // NOTE: order connectivity such that side 1 is shared!
7426 EntityHandle conn[2][4] = {
7427 { verts[0], verts[1], verts[3], verts[4] },
7428 { verts[2], verts[3], verts[1], verts[4] } };
7429 const int conn_len = dim+1;
7430 Range elems;
7431 for (int i = 0; i < 2; ++i) {
7432 EntityHandle h;
7433 rval = mb.create_element( type, conn[i], conn_len, h );
7434 if (MB_SUCCESS != rval) return rval;
7435 elems.insert(h);
7436 }
7437
7438 // create one reversed side
7439 EntityHandle side_conn[3];
7440 int side_indices[3] = {0,0,0};
7441 CN::SubEntityVertexIndices(type, dim-1, 0, side_indices );
7442 side_conn[0] = conn[0][side_indices[1]];
7443 side_conn[1] = conn[0][side_indices[0]];
7444 side_conn[2] = conn[0][side_indices[2]];
7445 EntityHandle side;
7446 rval = mb.create_element( subtype, side_conn, dim, side );
7447 if (MB_SUCCESS != rval) return rval;
7448
7449 Range forward, reverse;
7450 Skinner tool(&mb);
7451 rval = tool.find_skin( 0, elems, false, forward, &reverse, use_adj, true );
7452 if (MB_SUCCESS != rval) {
7453 std::cout << "Skinner failed." << std::endl;
7454 return rval;
7455 }
7456
7457 // expect all faces created by the skinner to be forward,
7458 // so the only reversed side should be the one created above.
7459 if (reverse.size() != 1 || reverse.front() != side) {
7460 std::cout << "Expected 1 reversed side, got: " << reverse.size() << std::endl;
7461 return MB_FAILURE;
7462 }
7463
7464 return MB_SUCCESS;
7465 }
mb_skin_faces_reversed_test()7466 ErrorCode mb_skin_faces_reversed_test()
7467 { return mb_skin_reversed_common( 2, false ); }
mb_skin_adj_faces_reversed_test()7468 ErrorCode mb_skin_adj_faces_reversed_test()
7469 { return mb_skin_reversed_common( 2, true ); }
mb_skin_regions_reversed_test()7470 ErrorCode mb_skin_regions_reversed_test()
7471 { return mb_skin_reversed_common( 3, false ); }
mb_skin_adj_regions_reversed_test()7472 ErrorCode mb_skin_adj_regions_reversed_test()
7473 { return mb_skin_reversed_common( 3, true ); }
7474
7475
mb_skin_subset_common(int dimension,bool use_adj)7476 ErrorCode mb_skin_subset_common( int dimension, bool use_adj )
7477 {
7478 EntityType type;
7479 switch (dimension) {
7480 case 2: type = MBTRI; break;
7481 case 3: type = MBPRISM; break;
7482 default: assert(false); return MB_FAILURE;
7483 }
7484
7485
7486 /* 0
7487 /|\
7488 / | \
7489 5 | 1
7490 |\ | /|
7491 | \|/ |
7492 | 6 |
7493 | /|\ |
7494 |/ | \|
7495 4 | 2
7496 \ | /
7497 \|/
7498 3
7499 */
7500
7501 ErrorCode rval;
7502 Core moab;
7503 Interface& mb = moab;
7504 Range expected_verts;
7505
7506 const double coords2D[7][2] = { {0,2}, {1,1}, {1,-1}, {0,-2}, {-1,-1}, {-1,1}, {0,0} };
7507 EntityHandle verts[2][7] = { {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0} };
7508 for (int d = 1; d < dimension; ++d) {
7509 for (int i = 0; i < 7; ++i) {
7510 double coords[3] = { coords2D[i][0], coords2D[i][1], static_cast<double>(d-1) };
7511 rval = mb.create_vertex( coords, verts[d-1][i] );
7512 if (MB_SUCCESS != rval) return rval;
7513 if (i != 4 && i != 5)
7514 expected_verts.insert( verts[d-1][i] );
7515 }
7516 }
7517
7518 EntityHandle elems[6];
7519 for (int i = 0; i < 6; ++i) {
7520 EntityHandle conn[6] = { verts[0][6], verts[0][(i+1)%6], verts[0][i],
7521 verts[1][6], verts[1][(i+1)%6], verts[1][i] };
7522 rval = mb.create_element( type, conn, CN::VerticesPerEntity(type), elems[i] );
7523 if (MB_SUCCESS != rval) return rval;
7524 }
7525
7526 Range input;
7527 input.insert( elems[0] );
7528 input.insert( elems[1] );
7529 input.insert( elems[2] );
7530
7531 Range skin;
7532 Skinner tool(&mb);
7533 rval = tool.find_skin( 0, input, true, skin, 0, use_adj, false );
7534 if (MB_SUCCESS != rval) {
7535 std::cout << "Skinner failed to find skin vertices" << std::endl;
7536 return MB_FAILURE;
7537 }
7538 if (skin != expected_verts) {
7539 std::cout << "Skinner returned incorrect skin vertices" << std::endl;
7540 return MB_FAILURE;
7541 }
7542 int n = 0;
7543 mb.get_number_entities_by_dimension( 0, dimension-1, n );
7544 if (n > 0) {
7545 std::cout << "Skinner created lower-dimension entities for vertex-only skinning" << std::endl;
7546 return MB_FAILURE;
7547 }
7548
7549 std::vector<EntityHandle> sv( skin.begin(), skin.end() );
7550 std::vector<int> counts( sv.size(), 0 );
7551 skin.clear();
7552 rval = tool.find_skin( 0, input, false, skin, 0, use_adj, true );
7553 if (MB_SUCCESS != rval) {
7554 std::cout << "Skinner failed to find skin elements" << std::endl;
7555 return MB_FAILURE;
7556 }
7557 for (Range::iterator i = skin.begin(); i != skin.end(); ++i) {
7558 const EntityHandle *conn;
7559 int len;
7560 rval = mb.get_connectivity( *i, conn, len );
7561 if (MB_SUCCESS != rval) return rval;
7562 for (int j = 0; j < len; ++j) {
7563 size_t idx = std::find(sv.begin(), sv.end(), conn[j]) - sv.begin();
7564 if (idx == sv.size()) {
7565 std::cout << "Skinner returned non-skin element" << std::endl;
7566 return MB_FAILURE;
7567 }
7568 counts[idx]++;
7569 }
7570 }
7571 for (size_t i = 0; i < counts.size(); ++i) {
7572 if (counts[i] < dimension) { // 2 for dim==2, {3,4,5} for dim==3
7573 std::cout << "Skinner did not return all skin elements" << std::endl;
7574 return MB_FAILURE;
7575 }
7576 }
7577 mb.get_number_entities_by_dimension( 0, dimension-1, n );
7578 if ((size_t)n != skin.size()) {
7579 std::cout << "Skinner created extra lower-dimension entities" << std::endl;
7580 return MB_FAILURE;
7581 }
7582
7583 return MB_SUCCESS;
7584 }
7585
mb_skin_faces_subset_test()7586 ErrorCode mb_skin_faces_subset_test()
7587 { return mb_skin_subset_common( 2, false ); }
mb_skin_adj_faces_subset_test()7588 ErrorCode mb_skin_adj_faces_subset_test()
7589 { return mb_skin_subset_common( 2, true ); }
mb_skin_regions_subset_test()7590 ErrorCode mb_skin_regions_subset_test()
7591 { return mb_skin_subset_common( 3, false ); }
mb_skin_adj_regions_subset_test()7592 ErrorCode mb_skin_adj_regions_subset_test()
7593 { return mb_skin_subset_common( 3, true ); }
7594
7595
7596
7597
mb_skin_full_common(int dimension,bool use_adj)7598 ErrorCode mb_skin_full_common( int dimension, bool use_adj )
7599 {
7600 EntityType type;
7601 switch (dimension) {
7602 case 2: type = MBQUAD; break;
7603 case 3: type = MBHEX; break;
7604 default: assert(false); return MB_FAILURE;
7605 }
7606
7607
7608 /*
7609 3----4----5
7610 | | |
7611 | | |
7612 0----1----2
7613 */
7614
7615 ErrorCode rval;
7616 Core moab;
7617 Interface& mb = moab;
7618
7619 // create vertices
7620 const double coords2D[6][2] = { {0,0}, {1,0}, {2,0}, {0,1}, {1,1}, {2,1} };
7621 EntityHandle v[2][6] = { {0,0,0,0,0,0}, {0,0,0,0,0,0} };
7622 for (int d = 1; d < dimension; ++d) {
7623 for (int i = 0; i < 6; ++i) {
7624 double coords[3] = { coords2D[i][0], coords2D[i][1], static_cast<double>(d-1) };
7625 rval = mb.create_vertex( coords, v[d-1][i] );
7626 if (MB_SUCCESS != rval) return rval;
7627 }
7628 }
7629
7630 // create elements
7631 Range input;
7632 EntityHandle elems[2], econn[2][8];;
7633 for (int i = 0; i < 2; ++i) {
7634 EntityHandle conn[8] = { v[0][i], v[0][i+1], v[0][i+4], v[0][i+3],
7635 v[1][i], v[1][i+1], v[1][i+4], v[1][i+3] };
7636 memcpy( econn[i], conn, sizeof(conn) );
7637 rval = mb.create_element( type, conn, CN::VerticesPerEntity(type), elems[i] );
7638 if (MB_SUCCESS != rval) return rval;
7639 input.insert( elems[i] );
7640 }
7641
7642 // create sides
7643 // NOTE: Shared side is element 0 side 1 and element 1 side 3
7644 Range expected;
7645 for (int i = 0; i < CN::NumSubEntities( type, dimension-1 ); ++i) {
7646 EntityType subtype;
7647 int len;
7648 const short* indices = CN::SubEntityVertexIndices( type, dimension-1,
7649 i, subtype, len );
7650 EntityHandle conn[4];
7651 assert((size_t)len <= sizeof(conn)/sizeof(conn[0]));
7652 for (int j = 0; j < 2; ++j) {
7653 if (j == 1 && i == 3) // don't create shared face twice
7654 continue;
7655 for (int k = 0; k < len; ++k)
7656 conn[k] = econn[j][indices[k]];
7657 EntityHandle h;
7658 rval = mb.create_element( subtype, conn, len, h );
7659 if (MB_SUCCESS != rval) return rval;
7660 if (j != 0 || i != 1) // don't insert shared face
7661 expected.insert(h);
7662 }
7663 }
7664
7665 Range skin;
7666 Skinner tool(&mb);
7667 rval = tool.find_skin( 0, input, false, skin, 0, use_adj, true );
7668 if (MB_SUCCESS != rval) {
7669 std::cout << "Skinner failed to find skin elements" << std::endl;
7670 return MB_FAILURE;
7671 }
7672 if (skin != expected) {
7673 std::cout << "Skinner returned incorrect skin elements" << std::endl;
7674 return MB_FAILURE;
7675 }
7676
7677 int n = 0;
7678 mb.get_number_entities_by_dimension( 0, dimension-1, n );
7679 if ((size_t)n != expected.size()+1) {
7680 std::cout << "Skinner created extra lower-dimension entities" << std::endl;
7681 return MB_FAILURE;
7682 }
7683
7684 return MB_SUCCESS;
7685 }
7686
mb_skin_faces_full_test()7687 ErrorCode mb_skin_faces_full_test()
7688 { return mb_skin_full_common( 2, false ); }
mb_skin_adj_faces_full_test()7689 ErrorCode mb_skin_adj_faces_full_test()
7690 { return mb_skin_full_common( 2, true ); }
mb_skin_regions_full_test()7691 ErrorCode mb_skin_regions_full_test()
7692 { return mb_skin_full_common( 3, false ); }
mb_skin_adj_regions_full_test()7693 ErrorCode mb_skin_adj_regions_full_test()
7694 { return mb_skin_full_common( 3, true ); }
7695
mb_skin_adjacent_surf_patches()7696 ErrorCode mb_skin_adjacent_surf_patches()
7697 {
7698 Core moab;
7699 Interface& mb = moab;
7700 ErrorCode rval;
7701 Skinner tool(&mb);
7702
7703 /* Mesh with vertices and quads numbered.
7704 Groups are indicated by letters {A,B,C,D}
7705
7706 0----1----2----3----4----5
7707 | (0)| (1)| (2)| (3)| (4)|
7708 | A | A | B | B | B |
7709 6----7----8----9---10---11
7710 | (5)| (6)| (7)| (8)| (9)|
7711 | A | A | A | B | B |
7712 12---13---14---15---16---17
7713 |(10)|(11)|(12)|(13)|(14)|
7714 | A | C | D | D | D |
7715 18---19---20---21---22---23
7716 |(15)|(16)|(17)|(18)|(19)|
7717 | C | C | C | D | D |
7718 24---25---26---27---28---29
7719 */
7720
7721 const int num_vtx = 30;
7722 EntityHandle vtx[num_vtx];
7723 for (int i = 0; i < 6; ++i) {
7724 for (int j = 0; j < 5; ++j) {
7725 double coords[3] = {static_cast<double>(i), static_cast<double>(j), 0};
7726 rval = mb.create_vertex( coords, vtx[6*j+i] );
7727 if (MB_SUCCESS != rval) return rval;
7728 }
7729 }
7730
7731 EntityHandle quads[20];
7732 for (int i = 0; i < 5; ++i) {
7733 for (int j = 0; j < 4; ++j) {
7734 int v = 6*j+i;
7735 EntityHandle conn[4] = { vtx[v+6], vtx[v+7], vtx[v+1], vtx[v+0] };
7736 rval = mb.create_element( MBQUAD, conn, 4, quads[5*j+i] );
7737 if (MB_SUCCESS != rval) return rval;
7738 }
7739 }
7740
7741 // Define four groups of quads (as labeled above)
7742 const int Aquads[] = { 0, 1, 5, 6, 7, 10 };
7743 const int Aquads_size = sizeof(Aquads)/sizeof(Aquads[0]);
7744 const int Bquads[] = { 2, 3, 4, 8, 9 };
7745 const int Bquads_size = sizeof(Bquads)/sizeof(Bquads[0]);
7746 const int Cquads[] = { 11, 15, 16, 17 };
7747 const int Cquads_size = sizeof(Cquads)/sizeof(Cquads[0]);
7748 const int Dquads[] = { 12, 13, 14, 18, 19 };
7749 const int Dquads_size = sizeof(Dquads)/sizeof(Dquads[0]);
7750
7751 // Define the results we expect for each group as a loop
7752 // of vertex indices
7753 const int Askin[] = { 0, 1, 2, 8, 9, 15, 14, 13, 19, 18, 12, 6 };
7754 const int Ashared[] = {-1,-1, 1, 1, 1, 3, 2, 2, 2, -1, -1,-1 };
7755 const int Askin_size = sizeof(Askin)/sizeof(Askin[0]);
7756 const int Bskin[] = { 2, 3, 4, 5, 11, 17, 16, 15, 9, 8 };
7757 const int Bshared[] = {-1,-1,-1,-1, -1, 3, 3, 0, 0, 0 };
7758 const int Bskin_size = sizeof(Bskin)/sizeof(Bskin[0]);
7759 const int Cskin[] = { 18, 19, 13, 14, 20, 21, 27, 26, 25, 24 };
7760 const int Cshared[] = { 0, 0, 0, 3, 3, 3, -1, -1, -1, -1 };
7761 const int Cskin_size = sizeof(Cskin)/sizeof(Cskin[0]);
7762 const int Dskin[] = { 14, 15, 16, 17, 23, 29, 28, 27, 21, 20 };
7763 const int Dshared[] = { 0, 1, 1, -1, -1, -1, -1, 2, 2, 2 };
7764 const int Dskin_size = sizeof(Dskin)/sizeof(Dskin[0]);
7765
7766 // Make the above stuff indexable for easier looping
7767 const int* const gquads[4] = { Aquads, Bquads, Cquads, Dquads };
7768 const int gquads_size[4] = { Aquads_size, Bquads_size, Cquads_size, Dquads_size };
7769 const int* const skin[4] = { Askin, Bskin, Cskin, Dskin };
7770 const int* const shared[4] = { Ashared, Bshared, Cshared, Dshared };
7771 const int skin_size[4] = { Askin_size, Bskin_size, Cskin_size, Dskin_size };
7772
7773 // Create an Range for each group of quads
7774 Range ranges[4];
7775 for (int grp = 0; grp < 4; ++grp)
7776 for (int i = 0; i < gquads_size[grp]; ++i)
7777 ranges[grp].insert( quads[gquads[grp][i]] );
7778
7779 // run test 4 times, one for each of:
7780 // o no adjacencies, no edges
7781 // o no adjacencies, edges
7782 // o adjacencies, edges
7783 // o adjacencies, no edges
7784 //
7785 // Be careful here: once we specify use_adj, we can't
7786 // unspecify it (the adjacencies will exist so the skinner
7787 // will use them, regardless of the passed flag.)
7788 int error_count = 0;
7789 for (int run = 0; run < 4; ++run) {
7790 const bool use_adj = run > 1;
7791 if (run == 3) {
7792 Range dead;
7793 mb.get_entities_by_type( 0, MBEDGE, dead );
7794 mb.delete_entities( dead );
7795 }
7796
7797 // test each group
7798 Range edges[4];
7799 for (int grp = 0; grp < 4; ++grp) {
7800 // get the skin edges
7801 rval = tool.find_skin( 0, ranges[grp], 1, edges[grp], use_adj );
7802 if (MB_SUCCESS != rval) {
7803 std::cout << "Skinner failed for run " << run << " group " << grp << std::endl;
7804 return rval;
7805 }
7806
7807 // check that we have the expected result
7808 std::vector<bool> seen(skin_size[grp], false);
7809 for (Range::iterator e = edges[grp].begin(); e != edges[grp].end(); ++e) {
7810 const EntityHandle* conn;
7811 int len;
7812 rval = mb.get_connectivity( *e, conn, len );
7813 if (MB_SUCCESS != rval) return rval;
7814 if (len != 2) return MB_FAILURE;
7815 const int idx1 = std::find( vtx, vtx+num_vtx, conn[0] ) - vtx;
7816 const int idx2 = std::find( vtx, vtx+num_vtx, conn[1] ) - vtx;
7817 int pos = std::find( skin[grp], skin[grp]+skin_size[grp], idx1 ) - skin[grp];
7818 if (pos == skin_size[grp]) {
7819 std::cout << "Non-skin vertex in skin for run " << run << " group " << grp << std::endl;
7820 std::cout << "idx1 = " << idx1 << ", idx2 = " << idx2 << std::endl;
7821 ++error_count;
7822 continue;
7823 }
7824
7825
7826 if (skin[grp][(pos+skin_size[grp]-1)%skin_size[grp]] == idx2)
7827 pos = (pos + skin_size[grp] - 1)%skin_size[grp];
7828 else if (skin[grp][(pos+1)%skin_size[grp]] != idx2) {
7829 std::cout << "Non-skin edge in skin for run " << run << " group " << grp << std::endl;
7830 std::cout << "idx1 = " << idx1 << ", idx2 = " << idx2 << std::endl;
7831 ++error_count;
7832 continue;
7833 }
7834
7835 if (seen[pos]) {
7836 std::cout << "Duplicate edge in skin for run " << run << " group " << grp << std::endl;
7837 std::cout << "idx1 = " << idx1 << ", idx2 = " << idx2 << std::endl;
7838 ++error_count;
7839 }
7840 seen[pos] = true;
7841
7842 int shared_with = shared[grp][pos];
7843 if (shared_with < 0) // not shared with another group
7844 continue;
7845 if (shared_with > grp) // didn't skin other group yet
7846 continue;
7847 if (edges[shared_with].find(*e) == edges[shared_with].end()) {
7848 std::cout << "Skin edge duplicated for run " << run << " group " << grp << std::endl;
7849 std::cout << "idx1 = " << idx1 << ", idx2 = " << idx2
7850 << " not in skin for group " << shared_with << std::endl;
7851 ++error_count;
7852 }
7853 }
7854
7855 int missing = std::count( seen.begin(), seen.end(), false );
7856 if (missing) {
7857 std::cout << "Missking " << missing << " skin edges for run " << run << " group " << grp << std::endl;
7858 error_count += missing;
7859 }
7860 }
7861 }
7862
7863 return error_count ? MB_FAILURE : MB_SUCCESS;
7864 }
7865
7866
get_by_all_types_and_tag(Interface * mb,EntityHandle meshset,const Tag * tag_handles,const void * const * values,int num_tags,Range & result,int condition,bool recursive)7867 static ErrorCode get_by_all_types_and_tag( Interface* mb,
7868 EntityHandle meshset,
7869 const Tag* tag_handles,
7870 const void* const* values,
7871 int num_tags,
7872 Range& result,
7873 int condition,
7874 bool recursive )
7875 {
7876 ErrorCode rval;
7877 Range tmp;
7878 const EntityType LAST = recursive ? MBENTITYSET : MBMAXTYPE;
7879 for (EntityType t = MBVERTEX; t < LAST; ++t) {
7880 tmp.clear();
7881 rval = mb->get_entities_by_type_and_tag( meshset, t, tag_handles, values, num_tags, tmp, condition, recursive );
7882 if (MB_SUCCESS != rval)
7883 return rval;
7884 result.insert( tmp.begin(), tmp.end() );
7885 }
7886 return MB_SUCCESS;
7887 }
7888
7889
7890 /** Check that functions which accept a type return the
7891 * result for all types when passed MBMAXTYPE
7892 */
mb_type_is_maxtype_test()7893 ErrorCode mb_type_is_maxtype_test()
7894 {
7895 Core moab;
7896 Interface* mb = &moab;
7897 ErrorCode rval = create_some_mesh( mb );
7898 if (MB_SUCCESS != rval)
7899 return rval;
7900
7901 Range r1, r2;
7902 rval = mb->get_entities_by_type( 0, MBMAXTYPE, r1, false ); MB_CHK_ERR(rval);
7903 rval = mb->get_entities_by_handle( 0, r2, false ); MB_CHK_ERR(rval);
7904 CHECK( r1 == r2 );
7905
7906 std::vector<EntityHandle> v1, v2;
7907 rval = mb->get_entities_by_type( 0, MBMAXTYPE, v1, false ); MB_CHK_ERR(rval);
7908 rval = mb->get_entities_by_handle( 0, v2, false ); MB_CHK_ERR(rval);
7909 CHECK( v1 == v2 );
7910
7911 int c1, c2;
7912 rval = mb->get_number_entities_by_type( 0, MBMAXTYPE, c1, false ); MB_CHK_ERR(rval);
7913 rval = mb->get_number_entities_by_handle( 0, c2, false ); MB_CHK_ERR(rval);
7914 CHECK( c1 == c2 );
7915
7916 Range h1, h2;
7917 Range::iterator it = r1.begin() + r1.size()/2;
7918 h1.insert( r1.begin(), it );
7919 if (it != r1.end())
7920 h2.insert( ++it, r1.end() );
7921
7922 EntityHandle s1, s2;
7923 rval = mb->create_meshset( MESHSET_SET, s1 ); MB_CHK_ERR(rval);
7924 rval = mb->create_meshset( MESHSET_ORDERED, s2 ); MB_CHK_ERR(rval);
7925 rval = mb->add_entities( s1, r1 ); MB_CHK_ERR(rval);
7926 rval = mb->add_entities( s2, r2 ); MB_CHK_ERR(rval);
7927 rval = mb->add_entities( s2, &s1, 1 ); MB_CHK_ERR(rval);
7928
7929 r1.clear();
7930 r2.clear();
7931 rval = mb->get_entities_by_type( s1, MBMAXTYPE, r1, false ); MB_CHK_ERR(rval);
7932 rval = mb->get_entities_by_handle( s1, r2, false ); MB_CHK_ERR(rval);
7933 CHECK( r1 == r2 );
7934
7935 r1.clear();
7936 r2.clear();
7937 rval = mb->get_entities_by_type( s2, MBMAXTYPE, r1, false ); MB_CHK_ERR(rval);
7938 rval = mb->get_entities_by_handle( s2, r2, false ); MB_CHK_ERR(rval);
7939 CHECK( r1 == r2 );
7940
7941 r1.clear();
7942 r2.clear();
7943 rval = mb->get_entities_by_type( s2, MBMAXTYPE, r1, true ); MB_CHK_ERR(rval);
7944 rval = mb->get_entities_by_handle( s2, r2, true ); MB_CHK_ERR(rval);
7945 CHECK( r1 == r2 );
7946
7947
7948 v1.clear();
7949 v2.clear();
7950 rval = mb->get_entities_by_type( s1, MBMAXTYPE, v1, false ); MB_CHK_ERR(rval);
7951 rval = mb->get_entities_by_handle( s1, v2, false ); MB_CHK_ERR(rval);
7952 CHECK( v1 == v2 );
7953
7954 v1.clear();
7955 v2.clear();
7956 rval = mb->get_entities_by_type( s2, MBMAXTYPE, v1, false ); MB_CHK_ERR(rval);
7957 rval = mb->get_entities_by_handle( s2, v2, false ); MB_CHK_ERR(rval);
7958 CHECK( v1 == v2 );
7959
7960 v1.clear();
7961 v2.clear();
7962 rval = mb->get_entities_by_type( s2, MBMAXTYPE, v1, true ); MB_CHK_ERR(rval);
7963 rval = mb->get_entities_by_handle( s2, v2, true ); MB_CHK_ERR(rval);
7964 CHECK( v1 == v2 );
7965
7966
7967 rval = mb->get_number_entities_by_type( s1, MBMAXTYPE, c1, false ); MB_CHK_ERR(rval);
7968 rval = mb->get_number_entities_by_handle( s1, c2, false ); MB_CHK_ERR(rval);
7969 CHECK( c1 == c2 );
7970
7971 rval = mb->get_number_entities_by_type( s2, MBMAXTYPE, c1, false ); MB_CHK_ERR(rval);
7972 rval = mb->get_number_entities_by_handle( s2, c2, false ); MB_CHK_ERR(rval);
7973 CHECK( c1 == c2 );
7974
7975 rval = mb->get_number_entities_by_type( s2, MBMAXTYPE, c1, true ); MB_CHK_ERR(rval);
7976 rval = mb->get_number_entities_by_handle( s2, c2, true ); MB_CHK_ERR(rval);
7977 CHECK( c1 == c2 );
7978
7979 r1.clear();
7980 rval = mb->get_entities_by_handle( s1, r1 ); MB_CHK_ERR(rval);
7981 Tag t1;
7982 rval = mb->tag_get_handle( "maxtype1", 1, MB_TYPE_INTEGER, t1, MB_TAG_SPARSE|MB_TAG_EXCL );
7983 MB_CHK_ERR(rval);
7984 std::vector<int> d1(r1.size());
7985 Range::iterator ri;
7986 std::vector<int>::iterator ii = d1.begin();
7987 for (ri = r1.begin(); ri != r1.end(); ++ri, ++ii)
7988 *ii = ((int)ID_FROM_HANDLE(*ri)) % 20;
7989 rval = mb->tag_set_data( t1, r1, &d1[0] ); MB_CHK_ERR(rval);
7990
7991 r1.clear(); r2.clear();
7992 rval = mb->get_entities_by_type_and_tag( 0, MBMAXTYPE, &t1, 0, 1, r1, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
7993 rval = mb->get_number_entities_by_type_and_tag( 0, MBMAXTYPE, &t1, 0, 1, c1, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
7994 rval = get_by_all_types_and_tag( mb, 0, &t1, 0, 1, r2, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
7995 CHECK( r1 == r2 );
7996 CHECK( (unsigned)c1 == r2.size() );
7997
7998 r1.clear(); r2.clear();
7999 rval = mb->get_entities_by_type_and_tag( s1, MBMAXTYPE, &t1, 0, 1, r1, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8000 rval = mb->get_number_entities_by_type_and_tag( s1, MBMAXTYPE, &t1, 0, 1, c1, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8001 rval = get_by_all_types_and_tag( mb, s1, &t1, 0, 1, r2, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8002 CHECK( r1 == r2 );
8003 CHECK( (unsigned)c1 == r2.size() );
8004
8005 r1.clear(); r2.clear();
8006 rval = mb->get_entities_by_type_and_tag( s2, MBMAXTYPE, &t1, 0, 1, r1, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8007 rval = mb->get_number_entities_by_type_and_tag( s2, MBMAXTYPE, &t1, 0, 1, c1, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8008 rval = get_by_all_types_and_tag( mb, s2, &t1, 0, 1, r2, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8009 CHECK( r1 == r2 );
8010 CHECK( (unsigned)c1 == r2.size() );
8011
8012 r1.clear(); r2.clear();
8013 rval = mb->get_entities_by_type_and_tag( s2, MBMAXTYPE, &t1, 0, 1, r1, Interface::INTERSECT, true ); MB_CHK_ERR(rval);
8014 rval = mb->get_number_entities_by_type_and_tag( s2, MBMAXTYPE, &t1, 0, 1, c1, Interface::INTERSECT, true ); MB_CHK_ERR(rval);
8015 rval = get_by_all_types_and_tag( mb, s2, &t1, 0, 1, r2, Interface::INTERSECT, true ); MB_CHK_ERR(rval);
8016 CHECK( r1 == r2 );
8017 CHECK( (unsigned)c1 == r2.size() );
8018
8019 int value = 3;
8020 const void* vallist[2] = { &value, 0 };
8021
8022 r1.clear(); r2.clear();
8023 rval = mb->get_entities_by_type_and_tag( 0, MBMAXTYPE, &t1, vallist, 1, r1, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8024 rval = mb->get_number_entities_by_type_and_tag( 0, MBMAXTYPE, &t1, vallist, 1, c1, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8025 rval = get_by_all_types_and_tag( mb, 0, &t1, vallist, 1, r2, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8026 CHECK( r1 == r2 );
8027 CHECK( (unsigned)c1 == r2.size() );
8028
8029 r1.clear(); r2.clear();
8030 rval = mb->get_entities_by_type_and_tag( s1, MBMAXTYPE, &t1, vallist, 1, r1, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8031 rval = mb->get_number_entities_by_type_and_tag( s1, MBMAXTYPE, &t1, vallist, 1, c1, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8032 rval = get_by_all_types_and_tag( mb, s1, &t1, vallist, 1, r2, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8033 CHECK( r1 == r2 );
8034 CHECK( (unsigned)c1 == r2.size() );
8035
8036 r1.clear(); r2.clear();
8037 rval = mb->get_entities_by_type_and_tag( s2, MBMAXTYPE, &t1, vallist, 1, r1, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8038 rval = mb->get_number_entities_by_type_and_tag( s2, MBMAXTYPE, &t1, vallist, 1, c1, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8039 rval = get_by_all_types_and_tag( mb, s2, &t1, vallist, 1, r2, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8040 CHECK( r1 == r2 );
8041 CHECK( (unsigned)c1 == r2.size() );
8042
8043 r1.clear(); r2.clear();
8044 rval = mb->get_entities_by_type_and_tag( s2, MBMAXTYPE, &t1, vallist, 1, r1, Interface::INTERSECT, true ); MB_CHK_ERR(rval);
8045 rval = mb->get_number_entities_by_type_and_tag( s2, MBMAXTYPE, &t1, vallist, 1, c1, Interface::INTERSECT, true ); MB_CHK_ERR(rval);
8046 rval = get_by_all_types_and_tag( mb, s2, &t1, vallist, 1, r2, Interface::INTERSECT, true ); MB_CHK_ERR(rval);
8047 CHECK( r1 == r2 );
8048 CHECK( (unsigned)c1 == r2.size() );
8049
8050 r1.clear(); r2.clear();
8051 rval = mb->get_entities_by_handle( s1, r1 ); MB_CHK_ERR(rval);
8052 r2.insert( r1.back() );
8053 r1.clear();
8054 rval = mb->get_entities_by_handle( s2, r1 ); MB_CHK_ERR(rval);
8055 r2.insert( r1.front() );
8056
8057 Tag t2;
8058 rval = mb->tag_get_handle( "maxtype2", 1, MB_TYPE_INTEGER, t2, MB_TAG_DENSE|MB_TAG_EXCL );
8059 MB_CHK_ERR(rval);
8060 d1.resize(r2.size());
8061 ii = d1.begin();;
8062 for (ri = r2.begin(); ri != r2.end(); ++ri, ++ii)
8063 *ii = ((int)ID_FROM_HANDLE(*ri)) % 2;
8064 rval = mb->tag_set_data( t2, r2, &d1[0] ); MB_CHK_ERR(rval);
8065
8066 Tag tags[] = { t1, t2 };
8067
8068 r1.clear(); r2.clear();
8069 rval = mb->get_entities_by_type_and_tag( 0, MBMAXTYPE, tags, 0, 2, r1, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8070 rval = mb->get_number_entities_by_type_and_tag( 0, MBMAXTYPE, tags, 0, 2, c1, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8071 rval = get_by_all_types_and_tag( mb, 0, tags, 0, 2, r2, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8072 CHECK( r1 == r2 );
8073 CHECK( (unsigned)c1 == r2.size() );
8074
8075 r1.clear(); r2.clear();
8076 rval = mb->get_entities_by_type_and_tag( s1, MBMAXTYPE, tags, 0, 2, r1, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8077 rval = mb->get_number_entities_by_type_and_tag( s1, MBMAXTYPE, tags, 0, 2, c1, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8078 rval = get_by_all_types_and_tag( mb, s1, tags, 0, 2, r2, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8079 CHECK( r1 == r2 );
8080 CHECK( (unsigned)c1 == r2.size() );
8081
8082 r1.clear(); r2.clear();
8083 rval = mb->get_entities_by_type_and_tag( s2, MBMAXTYPE, tags, 0, 2, r1, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8084 rval = mb->get_number_entities_by_type_and_tag( s2, MBMAXTYPE, tags, 0, 2, c1, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8085 rval = get_by_all_types_and_tag( mb, s2, tags, 0, 2, r2, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8086 CHECK( r1 == r2 );
8087 CHECK( (unsigned)c1 == r2.size() );
8088
8089 r1.clear(); r2.clear();
8090 rval = mb->get_entities_by_type_and_tag( s2, MBMAXTYPE, tags, 0, 2, r1, Interface::INTERSECT, true ); MB_CHK_ERR(rval);
8091 rval = mb->get_number_entities_by_type_and_tag( s2, MBMAXTYPE, tags, 0, 2, c1, Interface::INTERSECT, true ); MB_CHK_ERR(rval);
8092 rval = get_by_all_types_and_tag( mb, s2, tags, 0, 2, r2, Interface::INTERSECT, true ); MB_CHK_ERR(rval);
8093 CHECK( r1 == r2 );
8094 CHECK( (unsigned)c1 == r2.size() );
8095
8096 int val2 = 1;
8097 vallist[1] = &val2;
8098
8099 r1.clear(); r2.clear();
8100 rval = mb->get_entities_by_type_and_tag( 0, MBMAXTYPE, tags, vallist, 2, r1, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8101 rval = mb->get_number_entities_by_type_and_tag( 0, MBMAXTYPE, tags, vallist, 2, c1, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8102 rval = get_by_all_types_and_tag( mb, 0, tags, vallist, 2, r2, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8103 CHECK( r1 == r2 );
8104 CHECK( (unsigned)c1 == r2.size() );
8105
8106 r1.clear(); r2.clear();
8107 rval = mb->get_entities_by_type_and_tag( s1, MBMAXTYPE, tags, vallist, 2, r1, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8108 rval = mb->get_number_entities_by_type_and_tag( s1, MBMAXTYPE, tags, vallist, 2, c1, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8109 rval = get_by_all_types_and_tag( mb, s1, tags, vallist, 2, r2, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8110 CHECK( r1 == r2 );
8111 CHECK( (unsigned)c1 == r2.size() );
8112
8113 r1.clear(); r2.clear();
8114 rval = mb->get_entities_by_type_and_tag( s2, MBMAXTYPE, tags, vallist, 2, r1, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8115 rval = mb->get_number_entities_by_type_and_tag( s2, MBMAXTYPE, tags, vallist, 2, c1, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8116 rval = get_by_all_types_and_tag( mb, s2, tags, vallist, 2, r2, Interface::INTERSECT, false ); MB_CHK_ERR(rval);
8117 CHECK( r1 == r2 );
8118 CHECK( (unsigned)c1 == r2.size() );
8119
8120 r1.clear(); r2.clear();
8121 rval = mb->get_entities_by_type_and_tag( s2, MBMAXTYPE, tags, vallist, 2, r1, Interface::INTERSECT, true ); MB_CHK_ERR(rval);
8122 rval = mb->get_number_entities_by_type_and_tag( s2, MBMAXTYPE, tags, vallist, 2, c1, Interface::INTERSECT, true ); MB_CHK_ERR(rval);
8123 rval = get_by_all_types_and_tag( mb, s2, tags, vallist, 2, r2, Interface::INTERSECT, true ); MB_CHK_ERR(rval);
8124 CHECK( r1 == r2 );
8125 CHECK( (unsigned)c1 == r2.size() );
8126
8127 r1.clear(); r2.clear();
8128 rval = mb->get_entities_by_type_and_tag( 0, MBMAXTYPE, tags, vallist, 2, r1, Interface::UNION, false ); MB_CHK_ERR(rval);
8129 rval = mb->get_number_entities_by_type_and_tag( 0, MBMAXTYPE, tags, vallist, 2, c1, Interface::UNION, false ); MB_CHK_ERR(rval);
8130 rval = get_by_all_types_and_tag( mb, 0, tags, vallist, 2, r2, Interface::UNION, false ); MB_CHK_ERR(rval);
8131 CHECK( r1 == r2 );
8132 CHECK( (unsigned)c1 == r2.size() );
8133
8134 r1.clear(); r2.clear();
8135 rval = mb->get_entities_by_type_and_tag( s1, MBMAXTYPE, tags, vallist, 2, r1, Interface::UNION, false ); MB_CHK_ERR(rval);
8136 rval = mb->get_number_entities_by_type_and_tag( s1, MBMAXTYPE, tags, vallist, 2, c1, Interface::UNION, false ); MB_CHK_ERR(rval);
8137 rval = get_by_all_types_and_tag( mb, s1, tags, vallist, 2, r2, Interface::UNION, false ); MB_CHK_ERR(rval);
8138 CHECK( r1 == r2 );
8139 CHECK( (unsigned)c1 == r2.size() );
8140
8141 r1.clear(); r2.clear();
8142 rval = mb->get_entities_by_type_and_tag( s2, MBMAXTYPE, tags, vallist, 2, r1, Interface::UNION, false ); MB_CHK_ERR(rval);
8143 rval = mb->get_number_entities_by_type_and_tag( s2, MBMAXTYPE, tags, vallist, 2, c1, Interface::UNION, false ); MB_CHK_ERR(rval);
8144 rval = get_by_all_types_and_tag( mb, s2, tags, vallist, 2, r2, Interface::UNION, false ); MB_CHK_ERR(rval);
8145 CHECK( r1 == r2 );
8146 CHECK( (unsigned)c1 == r2.size() );
8147
8148 r1.clear(); r2.clear();
8149 rval = mb->get_entities_by_type_and_tag( s2, MBMAXTYPE, tags, vallist, 2, r1, Interface::UNION, true ); MB_CHK_ERR(rval);
8150 rval = mb->get_number_entities_by_type_and_tag( s2, MBMAXTYPE, tags, vallist, 2, c1, Interface::UNION, true ); MB_CHK_ERR(rval);
8151 rval = get_by_all_types_and_tag( mb, s2, tags, vallist, 2, r2, Interface::UNION, true ); MB_CHK_ERR(rval);
8152 CHECK( r1 == r2 );
8153 CHECK( (unsigned)c1 == r2.size() );
8154
8155 return MB_SUCCESS;
8156 }
8157
8158 /** Test behavior of various functions when passed the root set
8159 */
mb_root_set_test()8160 ErrorCode mb_root_set_test()
8161 {
8162 ErrorCode rval;
8163 Core moab;
8164 Interface* mb = &moab;
8165 EntityHandle rs = mb->get_root_set();
8166
8167 // expect root set to have zero handle
8168 CHECK(!rs);
8169
8170 // check type
8171 EntityType type = mb->type_from_handle( rs );
8172 CHECK( MBENTITYSET == type );
8173
8174 // Create a set to test with
8175 EntityHandle some_set;
8176 rval = mb->create_meshset( MESHSET_SET, some_set );
8177 MB_CHK_ERR( rval );
8178 Range sets;
8179 sets.insert( some_set );
8180
8181 int exp_dim = mb->dimension_from_handle( some_set );
8182 int dim = mb->dimension_from_handle( rs );
8183 CHECK( exp_dim == dim );
8184
8185 // test some stuff that should fail
8186 rval = mb->clear_meshset( &rs, 1 );
8187 CHECK( MB_SUCCESS != rval );
8188 rval = mb->set_meshset_options( rs, MESHSET_ORDERED );
8189 CHECK( MB_SUCCESS != rval );
8190 rval = mb->subtract_meshset( rs, some_set );
8191 CHECK( MB_SUCCESS != rval );
8192 rval = mb->intersect_meshset( rs, some_set );
8193 CHECK( MB_SUCCESS != rval );
8194 rval = mb->unite_meshset( rs, some_set );
8195 CHECK( MB_SUCCESS != rval );
8196
8197 // add/remove should fail for root set?
8198 rval = mb->add_entities( rs, &some_set, 1 );
8199 CHECK( MB_SUCCESS != rval );
8200 rval = mb->remove_entities( rs, &some_set, 1 );
8201 CHECK( MB_SUCCESS != rval );
8202 rval = mb->replace_entities( rs, &some_set, &some_set, 1 );
8203 CHECK( MB_SUCCESS != rval );
8204
8205 // check flags
8206 unsigned flags;
8207 rval = mb->get_meshset_options( rs, flags );
8208 CHECK( flags & MESHSET_SET );
8209 CHECK( !(flags & MESHSET_ORDERED) );
8210 CHECK( flags & MESHSET_TRACK_OWNER );
8211
8212 // contains tests
8213 bool c = mb->contains_entities( rs, &some_set, 1 );
8214 CHECK( c );
8215
8216 Range sets2;
8217 rval = mb->get_contained_meshsets( rs, sets2 );
8218 MB_CHK_ERR(rval);
8219 CHECK( sets == sets2 );
8220
8221 int count;
8222 rval = mb->num_contained_meshsets( rs, &count );
8223 MB_CHK_ERR(rval);
8224 CHECK( count == (int)sets.size() );
8225
8226 // The expected behavior for parent/child queries on the root set
8227 // is to return an error.
8228
8229 rval = mb->get_parent_meshsets( rs, sets2 );
8230 CHECK( MB_SUCCESS != rval );
8231 rval = mb->get_parent_meshsets( rs, sets2, 2 );
8232 CHECK( MB_SUCCESS != rval );
8233
8234 rval = mb->get_child_meshsets( rs, sets2 );
8235 CHECK( MB_SUCCESS != rval );
8236 rval = mb->get_child_meshsets( rs, sets2, 2 );
8237 CHECK( MB_SUCCESS != rval );
8238
8239 rval = mb->num_parent_meshsets( rs, &count );
8240 CHECK( MB_SUCCESS != rval );
8241 rval = mb->num_parent_meshsets( rs, &count, 2 );
8242 CHECK( MB_SUCCESS != rval );
8243
8244 rval = mb->num_child_meshsets( rs, &count );
8245 CHECK( MB_SUCCESS != rval );
8246 rval = mb->num_child_meshsets( rs, &count, 2 );
8247 CHECK( MB_SUCCESS != rval );
8248
8249 rval = mb->add_parent_meshset( rs, some_set );
8250 CHECK(MB_SUCCESS != rval);
8251 rval = mb->add_parent_meshsets( rs, &some_set, 1 );
8252 CHECK(MB_SUCCESS != rval);
8253 rval = mb->add_child_meshset( rs, some_set );
8254 CHECK(MB_SUCCESS != rval);
8255 rval = mb->add_child_meshsets( rs, &some_set, 1 );
8256 CHECK(MB_SUCCESS != rval);
8257 rval = mb->add_parent_child( rs, some_set );
8258 CHECK(MB_SUCCESS != rval);
8259 rval = mb->remove_parent_child( rs, some_set );
8260 CHECK(MB_SUCCESS != rval);
8261 rval = mb->remove_parent_meshset( rs, some_set );
8262 CHECK(MB_SUCCESS != rval);
8263 rval = mb->remove_child_meshset( rs, some_set );
8264 CHECK(MB_SUCCESS != rval);
8265
8266 return MB_SUCCESS;
8267 }
8268
8269
8270 /* Create a regular 2x2x2 hex mesh */
create_some_mesh(Interface * iface)8271 ErrorCode create_some_mesh( Interface* iface )
8272 {
8273 const double coords[] = { 0, 0, 0,
8274 1, 0, 0,
8275 2, 0, 0,
8276 0, 1, 0,
8277 1, 1, 0,
8278 2, 1, 0,
8279 0, 2, 0,
8280 1, 2, 0,
8281 2, 2, 0,
8282 0, 0, 1,
8283 1, 0, 1,
8284 2, 0, 1,
8285 0, 1, 1,
8286 1, 1, 1,
8287 2, 1, 1,
8288 0, 2, 1,
8289 1, 2, 1,
8290 2, 2, 1,
8291 0, 0, 2,
8292 1, 0, 2,
8293 2, 0, 2,
8294 0, 1, 2,
8295 1, 1, 2,
8296 2, 1, 2,
8297 0, 2, 2,
8298 1, 2, 2,
8299 2, 2, 2 };
8300 const size_t num_vtx = sizeof(coords)/sizeof(double)/3;
8301 assert(num_vtx == 27u);
8302
8303 const int conn[] = { 0, 1, 4, 3, 9, 10, 13, 12,
8304 1, 2, 5, 4, 10, 11, 14, 13,
8305 3, 4, 7, 6, 12, 13, 16, 15,
8306 4, 5, 8, 9, 13, 14, 17, 16,
8307 9, 10, 13, 12, 18, 19, 22, 21,
8308 10, 11, 14, 13, 19, 20, 23, 22,
8309 12, 13, 16, 15, 21, 22, 25, 24,
8310 13, 14, 17, 18, 22, 23, 26, 25 };
8311 const size_t num_elem = sizeof(conn)/sizeof(conn[0])/8;
8312 assert(num_elem == 8u);
8313
8314 EntityHandle verts[num_vtx], hexes[num_elem];
8315 for (size_t i = 0; i < num_vtx; ++i) {
8316 ErrorCode err = iface->create_vertex( coords + 3*i, verts[i] );
8317 if (MB_SUCCESS != err) return err;
8318 }
8319
8320 for (size_t i = 0; i < num_elem; ++i) {
8321 EntityHandle c[8];
8322 for (int j = 0; j < 8; ++j) {
8323 assert(conn[8*i+j] < (int)num_vtx);
8324 c[j] = verts[conn[8*i+j]];
8325 }
8326 ErrorCode err = iface->create_element( MBHEX, c, 8, hexes[i] );
8327 if (MB_SUCCESS != err) return err;
8328 }
8329
8330 return MB_SUCCESS;
8331 }
8332
contained(const std::vector<EntityHandle> & list,EntityHandle h)8333 inline bool contained( const std::vector<EntityHandle>& list, EntityHandle h )
8334 {
8335 std::vector<EntityHandle>::const_iterator i;
8336 i = std::lower_bound( list.begin(), list.end(), h );
8337 return i != list.end() && *i == h;
8338 }
8339
check_valid_connectivity(Interface * iface)8340 ErrorCode check_valid_connectivity( Interface* iface )
8341 {
8342 ErrorCode rval;
8343
8344 // get sorted array of vertex handles so that we can
8345 // check that all vertices in connectivity are valid
8346 // handles
8347 std::vector<EntityHandle> vertices, storage;
8348 rval = iface->get_entities_by_type( 0, MBVERTEX, vertices ); MB_CHK_ERR(rval);
8349 std::sort( vertices.begin(), vertices.end() );
8350
8351 // get all the elements
8352 Range elements, tmp;
8353 for (int d = 1; d < 4; ++d) {
8354 tmp.clear();
8355 rval = iface->get_entities_by_dimension( 0, d, tmp ); MB_CHK_ERR(rval);
8356 elements.merge(tmp);
8357 }
8358
8359 // check that all connectivity handles are valid
8360 Range::iterator it;
8361 ErrorCode result = MB_SUCCESS;
8362 for (it = elements.begin(); it != elements.end(); ++it) {
8363 const EntityHandle* conn;
8364 int len;
8365 rval = iface->get_connectivity( *it, conn, len, false, &storage ); MB_CHK_ERR(rval);
8366 for (int i = 0; i < len; ++i) {
8367 if (!contained( vertices, conn[i] )) {
8368 printf("Invalid handle (%s %d) in connectivity of %s %d\n",
8369 CN::EntityTypeName(TYPE_FROM_HANDLE(conn[i])),
8370 (int)ID_FROM_HANDLE(conn[i]),
8371 CN::EntityTypeName(TYPE_FROM_HANDLE(*it)),
8372 (int)ID_FROM_HANDLE(*it));
8373 result = MB_FAILURE;
8374 }
8375 }
8376 }
8377
8378 return result;
8379 }
8380
8381
usage(const char * exe)8382 static void usage(const char* exe) {
8383 cerr << "Usage: " << exe << " [-nostress] [-d input_file_dir]\n";
8384 exit (1);
8385 }
8386
8387
8388 int number_tests = 0;
8389 int number_tests_failed = 0;
8390 #define RUN_TEST_ERR( A ) _run_test( (A), #A )
8391
8392 typedef ErrorCode (*TestFunc)();
_run_test(TestFunc func,const char * func_str)8393 static int _run_test( TestFunc func, const char* func_str )
8394 {
8395 ++number_tests;
8396 return run_test ( func, func_str );
8397 }
8398
8399
8400 /*!
8401 main routine for test harness
8402 */
main(int argc,char * argv[])8403 int main(int argc, char* argv[])
8404 {
8405 #ifdef MOAB_HAVE_MPI
8406 int fail = MPI_Init(&argc, &argv);
8407 if (fail) return fail;
8408 #endif
8409
8410 argv0 = argv[0];
8411
8412 // Check command line arg to see if we should avoid doing the stress test
8413 #ifdef MOAB_HAVE_NETCDF
8414 bool stress_test = true;
8415 #endif
8416
8417 std::cout << "Size of mConnMap = " << sizeof(CN::mConnectivityMap)
8418 << std::endl;
8419 std::cout << "Size of mUpConnMap = " << sizeof(CN::mUpConnMap)
8420 << std::endl;
8421 std::cout << "Size of CN = " << sizeof(CN)
8422 << std::endl;
8423
8424 for (int i = 1; i < argc; ++i) {
8425
8426 if (string(argv[i]) == "-h" || string(argv[i]) == "--help")
8427 usage( argv[0] );
8428 #if MOAB_HAVE_NETCDF
8429 else if (string(argv[i]) == "-nostress")
8430 stress_test = false;
8431 #endif
8432 else {
8433 cerr << "Invalid argument: " << argv[i] << endl;
8434 usage( argv[0] );
8435 }
8436 }
8437
8438 // Print out Header information
8439
8440 cout << "\n\nMOAB Comprehensive test suite:\n\n";
8441
8442 number_tests = number_tests_failed = 0;
8443 number_tests_failed += RUN_TEST_ERR( mb_adjacent_vertex_test );
8444 number_tests_failed += RUN_TEST_ERR( mb_adjacencies_create_delete_test );
8445 number_tests_failed += RUN_TEST_ERR( mb_upward_adjacencies_test );
8446 number_tests_failed += RUN_TEST_ERR( mb_adjacent_create_test );
8447 number_tests_failed += RUN_TEST_ERR( mb_vertex_coordinate_test );
8448 number_tests_failed += RUN_TEST_ERR( mb_vertex_tag_test );
8449 number_tests_failed += RUN_TEST_ERR( mb_temporary_test );
8450 number_tests_failed += RUN_TEST_ERR( mb_mesh_sets_set_test );
8451 number_tests_failed += RUN_TEST_ERR( mb_mesh_sets_list_test );
8452 number_tests_failed += RUN_TEST_ERR( mb_mesh_set_parent_child_test );
8453 number_tests_failed += RUN_TEST_ERR( mb_mesh_set_set_appends );
8454 number_tests_failed += RUN_TEST_ERR( mb_mesh_set_list_appends );
8455 number_tests_failed += RUN_TEST_ERR( mb_mesh_set_root_appends );
8456 number_tests_failed += RUN_TEST_ERR( mb_mesh_set_set_replace_test );
8457 number_tests_failed += RUN_TEST_ERR( mb_mesh_set_list_replace_test );
8458 number_tests_failed += RUN_TEST_ERR( mb_mesh_set_flag_test );
8459 number_tests_failed += RUN_TEST_ERR( mb_mesh_set_set_add_remove_test );
8460 number_tests_failed += RUN_TEST_ERR( mb_dense_tag_test );
8461 number_tests_failed += RUN_TEST_ERR( mb_sparse_tag_test );
8462 number_tests_failed += RUN_TEST_ERR( mb_higher_order_test );
8463 number_tests_failed += RUN_TEST_ERR( mb_bit_tags_test );
8464 #if MOAB_HAVE_NETCDF
8465 number_tests_failed += RUN_TEST_ERR( mb_adjacencies_test );
8466 number_tests_failed += RUN_TEST_ERR( mb_tags_test );
8467 number_tests_failed += RUN_TEST_ERR( mb_delete_mesh_test );
8468 number_tests_failed += RUN_TEST_ERR( mb_entity_conversion_test );
8469 number_tests_failed += RUN_TEST_ERR( mb_mesh_set_tracking_test );
8470 #endif
8471 number_tests_failed += RUN_TEST_ERR( mb_forced_adjacencies_test );
8472 number_tests_failed += RUN_TEST_ERR( mb_canon_number_test );
8473 number_tests_failed += RUN_TEST_ERR(mb_side_number_test);
8474 number_tests_failed += RUN_TEST_ERR( mb_poly_test );
8475 number_tests_failed += RUN_TEST_ERR( mb_topo_util_test );
8476 number_tests_failed += RUN_TEST_ERR( mb_split_test );
8477 number_tests_failed += RUN_TEST_ERR( mb_range_seq_intersect_test );
8478 number_tests_failed += RUN_TEST_ERR( mb_poly_adjacency_test );
8479 number_tests_failed += RUN_TEST_ERR( mb_poly_adjacency_test2 );
8480 number_tests_failed += RUN_TEST_ERR( mb_memory_use_test );
8481 number_tests_failed += RUN_TEST_ERR( mb_skin_curve_test );
8482 number_tests_failed += RUN_TEST_ERR( mb_skin_curve_adj_test );
8483 number_tests_failed += RUN_TEST_ERR( mb_skin_surface_test );
8484 number_tests_failed += RUN_TEST_ERR( mb_skin_surface_adj_test );
8485 number_tests_failed += RUN_TEST_ERR( mb_skin_volume_test );
8486 number_tests_failed += RUN_TEST_ERR( mb_skin_volume_adj_test );
8487 number_tests_failed += RUN_TEST_ERR( mb_skin_surf_verts_test );
8488 number_tests_failed += RUN_TEST_ERR( mb_skin_vol_verts_test );
8489 number_tests_failed += RUN_TEST_ERR( mb_skin_surf_verts_elems_test );
8490 number_tests_failed += RUN_TEST_ERR( mb_skin_vol_verts_elems_test );
8491 number_tests_failed += RUN_TEST_ERR( mb_skin_poly_test );
8492 number_tests_failed += RUN_TEST_ERR( mb_skin_higher_order_faces_test );
8493 number_tests_failed += RUN_TEST_ERR( mb_skin_higher_order_regions_test );
8494 number_tests_failed += RUN_TEST_ERR( mb_skin_adj_higher_order_faces_test );
8495 number_tests_failed += RUN_TEST_ERR( mb_skin_adj_higher_order_regions_test );
8496 number_tests_failed += RUN_TEST_ERR( mb_skin_faces_reversed_test );
8497 number_tests_failed += RUN_TEST_ERR( mb_skin_adj_faces_reversed_test );
8498 number_tests_failed += RUN_TEST_ERR( mb_skin_regions_reversed_test );
8499 number_tests_failed += RUN_TEST_ERR( mb_skin_adj_regions_reversed_test );
8500 number_tests_failed += RUN_TEST_ERR( mb_skin_faces_subset_test );
8501 number_tests_failed += RUN_TEST_ERR( mb_skin_adj_faces_subset_test );
8502 number_tests_failed += RUN_TEST_ERR( mb_skin_regions_subset_test );
8503 number_tests_failed += RUN_TEST_ERR( mb_skin_adj_regions_subset_test );
8504 number_tests_failed += RUN_TEST_ERR( mb_skin_faces_full_test );
8505 number_tests_failed += RUN_TEST_ERR( mb_skin_adj_faces_full_test );
8506 number_tests_failed += RUN_TEST_ERR( mb_skin_regions_full_test );
8507 number_tests_failed += RUN_TEST_ERR( mb_skin_adj_regions_full_test );
8508 number_tests_failed += RUN_TEST_ERR( mb_skin_adjacent_surf_patches );
8509 number_tests_failed += RUN_TEST_ERR( mb_skin_scd_test );
8510 number_tests_failed += RUN_TEST_ERR( mb_skin_fileset_test );
8511 number_tests_failed += RUN_TEST_ERR( mb_read_fail_test );
8512 number_tests_failed += RUN_TEST_ERR( mb_enum_string_test );
8513 number_tests_failed += RUN_TEST_ERR( mb_merge_update_test );
8514 number_tests_failed += RUN_TEST_ERR( mb_type_is_maxtype_test );
8515 number_tests_failed += RUN_TEST_ERR( mb_root_set_test );
8516 #if MOAB_HAVE_NETCDF
8517 number_tests_failed += RUN_TEST_ERR( mb_merge_test );
8518 if (stress_test) number_tests_failed += RUN_TEST_ERR( mb_stress_test );
8519 #endif
8520
8521 // summary
8522
8523 cout << "\nMB TEST SUMMARY: \n"
8524 << " Number Tests: " << number_tests << "\n"
8525 << " Number Successful: " << number_tests - number_tests_failed << "\n"
8526 << " Number Failed: " << number_tests_failed
8527 << "\n\n";
8528
8529 #ifdef MOAB_HAVE_MPI
8530 fail = MPI_Finalize();
8531 if (fail) return fail;
8532 #endif
8533
8534 return number_tests_failed;
8535 }
8536