MOAB: Mesh Oriented datABase  (version 5.5.0)
test_geom_gqt.cpp File Reference
#include "MBTagConventions.hpp"
#include "moab/Interface.hpp"
#include "moab/Core.hpp"
#include "moab/Range.hpp"
#include "moab/CartVect.hpp"
#include "moab/GeomQueryTool.hpp"
#include "moab/GeomTopoTool.hpp"
#include <vector>
#include <iostream>
#include <cmath>
#include <limits>
#include <algorithm>
#include <cstdio>
+ Include dependency graph for test_geom_gqt.cpp:

Go to the source code of this file.

Classes

struct  ray_fire
 
struct  PointInVol
 

Macros

#define CHKERR    if( MB_SUCCESS != rval ) return rval
 
#define RUN_TEST(A)
 

Functions

ErrorCode write_geometry (const char *output_file_name)
 
ErrorCode test_ray_fire (GeomQueryTool *)
 
ErrorCode test_point_in_volume (GeomQueryTool *)
 
ErrorCode test_closest_to_location (GeomQueryTool *)
 
ErrorCode test_measure_volume (GeomQueryTool *)
 
ErrorCode test_measure_area (GeomQueryTool *)
 
ErrorCode test_surface_sense (GeomQueryTool *)
 
ErrorCode overlap_write_geometry (const char *output_file_name)
 
ErrorCode overlap_test_ray_fire (GeomQueryTool *)
 
ErrorCode overlap_test_point_in_volume (GeomQueryTool *)
 
ErrorCode overlap_test_measure_volume (GeomQueryTool *)
 
ErrorCode overlap_test_measure_area (GeomQueryTool *)
 
ErrorCode overlap_test_surface_sense (GeomQueryTool *)
 
ErrorCode overlap_test_tracking (GeomQueryTool *)
 
int run_regular_tests (GeomQueryTool *gqt)
 
int run_overlap_tests (GeomQueryTool *gqt)
 
int main (int argc, char *argv[])
 

Variables

const double ROOT2 = 1.4142135623730951
 

Macro Definition Documentation

◆ CHKERR

#define CHKERR    if( MB_SUCCESS != rval ) return rval

Definition at line 21 of file test_geom_gqt.cpp.

◆ RUN_TEST

#define RUN_TEST (   A)
Value:
do \
{ \
std::cout << #A << "... " << std::endl; \
if( MB_SUCCESS != A( gqt ) ) \
{ \
++errors; \
} \
} while( false )

Definition at line 224 of file test_geom_gqt.cpp.

Function Documentation

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 234 of file test_geom_gqt.cpp.

235 {
236  ErrorCode rval;
237  const char* filename = "test_geom.h5m";
238 
239 #ifdef MOAB_HAVE_MPI
240  int fail = MPI_Init( &argc, &argv );
241  if( fail ) return fail;
242 #endif
243 
244  rval = write_geometry( filename );MB_CHK_SET_ERR( rval, "Failed to create input file: " << filename );
245 
246  Interface* MBI = new Core();
247 
248  int errors = 0;
249  rval = MBI->load_file( filename );
250  remove( filename );MB_CHK_SET_ERR( rval, "Failed to load file" );
251 
252  GeomTopoTool* gtt = new GeomTopoTool( MBI );
253  GeomQueryTool* gqt = new GeomQueryTool( gtt );
254 
255  errors += run_regular_tests( gqt );
256 
257  // clear out moab instance
258  rval = MBI->delete_mesh();MB_CHK_SET_ERR( rval, "Failed to delete mesh" );
259 
260  delete gtt;
261  delete gqt;
262 
263  // Now load a different geometry: two cubes that slightly overlap
264  rval = overlap_write_geometry( filename );MB_CHK_SET_ERR( rval, "Failed to create input file: " << filename );
265 
266  rval = MBI->load_file( filename );
267  remove( filename );MB_CHK_SET_ERR( rval, "Failed to load file with overlaps" );
268 
269  gtt = new GeomTopoTool( MBI );
270  gqt = new GeomQueryTool( gtt );
271 
272  errors += run_overlap_tests( gqt );
273 
274  // clear moab instance
275  rval = MBI->delete_mesh();MB_CHK_SET_ERR( rval, "Failed to delete mesh" );
276 
277  delete gtt;
278  delete gqt;
279 
280  // Re-run all tests with the alternate constructor
281  std::cout << "-------------------------------------" << std::endl;
282  std::cout << "Re-running tests with MBI constructor" << std::endl;
283  std::cout << "-------------------------------------" << std::endl;
284 
285  rval = write_geometry( filename );MB_CHK_SET_ERR( rval, "Failed to create input file" );
286 
287  rval = MBI->load_file( filename );
288  remove( filename );MB_CHK_SET_ERR( rval, "Failed to load file" );
289 
290  gqt = new GeomQueryTool( MBI );
291 
292  errors += run_regular_tests( gqt );
293 
294  // clear moab and dagmc instance
295  rval = MBI->delete_mesh();MB_CHK_SET_ERR( rval, "Failed to delete mesh" );
296 
297  delete gqt;
298 
299  // Now load a different geometry: two cubes that slightly overlap
300  rval = overlap_write_geometry( filename );MB_CHK_SET_ERR( rval, "Failed to create input file: " );
301 
302  rval = MBI->load_file( filename );
303  remove( filename );MB_CHK_SET_ERR( rval, "Failed to load file with overlaps." );
304 
305  gqt = new GeomQueryTool( MBI );
306 
307  errors += run_overlap_tests( gqt );
308 
309  // final cleanup
310  delete gqt;
311  delete MBI;
312 
313 #ifdef MOAB_HAVE_MPI
314  fail = MPI_Finalize();
315  if( fail ) return fail;
316 #endif
317 
318  return errors;
319 }

References ErrorCode, moab::fail(), filename, MB_CHK_SET_ERR, MBI, overlap_write_geometry(), run_overlap_tests(), run_regular_tests(), and write_geometry().

◆ overlap_test_measure_area()

ErrorCode overlap_test_measure_area ( GeomQueryTool gqt)

Definition at line 541 of file test_geom_gqt.cpp.

542 {
543  ErrorCode rval;
544  Interface* moab = gqt->moab_instance();
545 
546  Tag dim_tag = gqt->gttool()->get_geom_tag();
547  Range surfs;
548  const int two = 2;
549  const void* ptr = &two;
550  rval = moab->get_entities_by_type_and_tag( 0, MBENTITYSET, &dim_tag, &ptr, 1, surfs );CHKERR;
551 
552  const unsigned num_surfs = 12;
553  if( surfs.size() != num_surfs )
554  {
555  std::cerr << "ERROR: Expected " << num_surfs << " surfaces in input, found " << surfs.size() << std::endl;
556  return MB_FAILURE;
557  }
558 
559  int ids[num_surfs];
560  rval = moab->tag_get_data( gqt->gttool()->get_gid_tag(), surfs, ids );CHKERR;
561 
562  const double x_area = 2 * 2;
563  const double yz_area0 = 2 * 1;
564  const double yz_area1 = 2 * 1.01;
565  Range::iterator iter = surfs.begin();
566  for( unsigned i = 0; i < num_surfs; ++i, ++iter )
567  {
568  double expected, result;
569  if( 0 == i || 2 == i || 4 == i || 5 == i )
570  expected = yz_area0;
571  else if( 1 == i || 3 == i || 7 == i || 9 == i )
572  expected = x_area;
573  else if( 6 == i || 8 == i || 10 == i || 11 == i )
574  expected = yz_area1;
575 
576  rval = gqt->measure_area( *iter, result );CHKERR;
577  if( fabs( result - expected ) > std::numeric_limits< double >::epsilon() )
578  {
579  std::cerr << "ERROR: Expected area of surface " << ids[i] << " to be " << expected << ". Got " << result
580  << std::endl;
581  return MB_FAILURE;
582  }
583  }
584 
585  return MB_SUCCESS;
586 }

References moab::Range::begin(), CHKERR, dim_tag, ErrorCode, moab::GeomTopoTool::get_geom_tag(), moab::GeomTopoTool::get_gid_tag(), moab::GeomQueryTool::gttool(), MB_SUCCESS, MBENTITYSET, moab::GeomQueryTool::measure_area(), moab::GeomQueryTool::moab_instance(), and moab::Range::size().

Referenced by run_overlap_tests().

◆ overlap_test_measure_volume()

ErrorCode overlap_test_measure_volume ( GeomQueryTool gqt)

Definition at line 468 of file test_geom_gqt.cpp.

469 {
470  ErrorCode rval;
471  Interface* moab = gqt->moab_instance();
472 
473  Tag dim_tag = gqt->gttool()->get_geom_tag();
474  Range vols;
475  const int three = 3;
476  const void* ptr = &three;
477  rval = moab->get_entities_by_type_and_tag( 0, MBENTITYSET, &dim_tag, &ptr, 1, vols );CHKERR;
478 
479  if( vols.size() != 2 )
480  {
481  std::cerr << "ERROR: Expected 2 volumes in input, found " << vols.size() << std::endl;
482  return MB_FAILURE;
483  }
484 
485  // The volume has two regions that overlap.
486  double result;
487  const double vol = ( 1 + 1.01 ) * 2 * 2;
488 
489  rval = gqt->measure_volume( vols.front(), result );CHKERR;
490  if( fabs( result - vol ) > 2 * std::numeric_limits< double >::epsilon() )
491  {
492  std::cerr << "ERROR: Expected " << vol << " as measure of volume, got " << result << std::endl;
493  return MB_FAILURE;
494  }
495 
496  return MB_SUCCESS;
497 }

References CHKERR, dim_tag, ErrorCode, moab::Range::front(), moab::GeomTopoTool::get_geom_tag(), moab::GeomQueryTool::gttool(), MB_SUCCESS, MBENTITYSET, moab::GeomQueryTool::measure_volume(), moab::GeomQueryTool::moab_instance(), and moab::Range::size().

Referenced by run_overlap_tests().

◆ overlap_test_point_in_volume()

ErrorCode overlap_test_point_in_volume ( GeomQueryTool gqt)

Definition at line 952 of file test_geom_gqt.cpp.

953 {
954  const char* const NAME_ARR[] = { "Boundary", "Outside", "Inside" };
955  const char* const* names = NAME_ARR + 1;
956  const int INSIDE = 1, OUTSIDE = 0, BOUNDARY = -1;
957  const struct PointInVol tests[] = { { { 0.5, 0.0, 0.5 }, INSIDE, { 0.0, 0.0, 0.0 } },
958  { { 0.5, 0.0, -0.5 }, INSIDE, { 0.0, 0.0, 0.0 } },
959  { { 0.5, 0.0, 0.0 }, INSIDE, { 0.0, 0.0, 0.0 } },
960  { { -0.5, 0.0, 0.0 }, INSIDE, { 0.0, 0.0, 0.0 } },
961  { { 0.5, 0.5, 0.0 }, INSIDE, { 0.0, 0.0, 0.0 } },
962  { { 0.5, -0.5, 0.0 }, INSIDE, { 0.0, 0.0, 0.0 } },
963  { { 1.1, 1.1, 1.1 }, OUTSIDE, { 0.0, 0.0, 0.0 } },
964  { { -1.1, 1.1, 1.1 }, OUTSIDE, { 0.0, 0.0, 0.0 } },
965  { { -1.1, -1.1, 1.1 }, OUTSIDE, { 0.0, 0.0, 0.0 } },
966  { { 1.1, -1.1, 1.1 }, OUTSIDE, { 0.0, 0.0, 0.0 } },
967  { { 1.1, 1.1, -1.1 }, OUTSIDE, { 0.0, 0.0, 0.0 } },
968  { { -1.1, 1.1, -1.1 }, OUTSIDE, { 0.0, 0.0, 0.0 } },
969  { { -1.1, -1.1, -1.1 }, OUTSIDE, { 0.0, 0.0, 0.0 } },
970  { { 1.1, -1.1, -1.1 }, OUTSIDE, { 0.0, 0.0, 0.0 } },
971  // Add some directions to test special cases of edge/node intersection
972  { { 0.5, 0.0, 0.0 }, INSIDE, { -1.0, 0.0, 0.0 } },
973  { { 0.5, 0.0, 0.0 }, INSIDE, { 1.0, 0.0, 0.0 } },
974  { { 0.0, 0.0, 2.0 }, OUTSIDE, { 0.0, 0.0, -1.0 } },
975  { { 0.5, 0.0, -0.5 }, INSIDE, { -1.0, 0.0, 0.0 } },
976  { { 0.5, -0.5, -2.0 }, OUTSIDE, { 0.0, 0.0, 1.0 } },
977  // Test some points in the overlap
978  { { 0.005, 0.0, 0.0 }, INSIDE, { -1.0, 0.0, 0.0 } },
979  { { 0.005, 0.0, 0.0 }, INSIDE, { 1.0, 0.0, 0.0 } },
980  { { 0.005, 0.0, 2.0 }, OUTSIDE, { 0.0, 0.0, -1.0 } },
981  { { 0.005, 0.0, -0.5 }, INSIDE, { -1.0, 0.0, 0.0 } },
982  { { 0.005, -0.5, -2.0 }, OUTSIDE, { 0.0, 0.0, 1.0 } } };
983 
984  const int num_test = sizeof( tests ) / sizeof( tests[0] );
985 
986  ErrorCode rval;
987  Interface* moab = gqt->moab_instance();
988 
989  Tag dim_tag = gqt->gttool()->get_geom_tag();
990  Range vols;
991  const int three = 3;
992  const void* ptr = &three;
993  rval = moab->get_entities_by_type_and_tag( 0, MBENTITYSET, &dim_tag, &ptr, 1, vols );CHKERR;
994  if( vols.size() != 2 )
995  {
996  std::cerr << "ERROR: Expected 2 volumes in input, found " << vols.size() << std::endl;
997  return MB_FAILURE;
998  }
999  const EntityHandle vol = vols.front();
1000  for( int i = 0; i < num_test; ++i )
1001  {
1002  int result;
1003  rval = gqt->point_in_volume( vol, tests[i].coords, result, tests[i].dir );CHKERR;
1004  if( result != tests[i].result )
1005  {
1006  std::cerr << "ERROR testing point_in_volume[" << i << "]:" << std::endl
1007  << "\tExpected " << names[tests[i].result] << " for (" << tests[i].coords[0] << ", "
1008  << tests[i].coords[1] << ", " << tests[i].coords[2] << "). Got " << names[result] << std::endl;
1009  return MB_FAILURE;
1010  }
1011 
1012  // point_in_volume_slow doesn't to boundary.
1013  if( tests[i].result == BOUNDARY ) continue;
1014 
1015  rval = gqt->point_in_volume_slow( vol, tests[i].coords, result );CHKERR;
1016 
1017  if( result != tests[i].result )
1018  {
1019  std::cerr << "ERROR testing point_in_volume_slow[" << i << "]:" << std::endl
1020  << "\tExpected " << names[tests[i].result] << " for (" << tests[i].coords[0] << ", "
1021  << tests[i].coords[1] << ", " << tests[i].coords[2] << "). Got " << names[result] << std::endl;
1022  return MB_FAILURE;
1023  }
1024  }
1025 
1026  return MB_SUCCESS;
1027 }

References CHKERR, PointInVol::coords, dim_tag, PointInVol::dir, ErrorCode, moab::Range::front(), moab::GeomTopoTool::get_geom_tag(), moab::GeomQueryTool::gttool(), MB_SUCCESS, MBENTITYSET, moab::GeomQueryTool::moab_instance(), moab::GeomQueryTool::point_in_volume(), moab::GeomQueryTool::point_in_volume_slow(), PointInVol::result, and moab::Range::size().

Referenced by run_overlap_tests().

◆ overlap_test_ray_fire()

ErrorCode overlap_test_ray_fire ( GeomQueryTool gqt)

Definition at line 723 of file test_geom_gqt.cpp.

724 {
725  // Glancing ray-triangle intersections are not valid exit intersections.
726  // Piercing ray-triangle intersections are valid exit intersections.
727  // "0" destination surface implies that it is ambiguous.
728  const struct ray_fire tests[] = { /* ____________________
729  | |
730  -x <--- | region1 | overlap | region0 | ---> +x
731  | |
732  ---------------------
733  -x <--- -1.0 0.0 0.01 1.0 ---> +x
734  surf_id: 10 4 8 2
735 
736  The zero-distance advance would occur in the implicit volume between
737  these two regions---not in this volume.
738 
739  src_srf origin direction dest dist */
740  // numerical location on surface 1 of region0
741  { 4, { 1.0, 0.0, 0.0 }, { 1.0, 0.0, 0.0 }, 2, 0.0 },
742  { 2, { 1.0, 0.0, 0.0 }, { -1.0, 0.0, 0.0 }, 4, 1.0 },
743  // numerical location inside region0
744  { 4, { 0.5, 0.0, 0.0 }, { 1.0, 0.0, 0.0 }, 2, 0.5 },
745  { 2, { 0.5, 0.0, 0.0 }, { -1.0, 0.0, 0.0 }, 4, 0.5 },
746  // numerical location on surface 7 of region1
747  { 4, { 0.01, 0.0, 0.0 }, { 1.0, 0.0, 0.0 }, 8, 0.0 },
748  { 2, { 0.01, 0.0, 0.0 }, { -1.0, 0.0, 0.0 }, 4, 0.01 },
749  // numerical location inside overlap
750  { 10, { 0.005, 0.0, 0.0 }, { 1.0, 0.0, 0.0 }, 8, 0.005 },
751  { 2, { 0.005, 0.0, 0.0 }, { -1.0, 0.0, 0.0 }, 4, 0.005 },
752  // numerical location on surface 3 of region0
753  { 10, { 0.0, 0.0, 0.0 }, { 1.0, 0.0, 0.0 }, 8, 0.01 },
754  { 8, { 0.0, 0.0, 0.0 }, { -1.0, 0.0, 0.0 }, 4, 0.0 },
755  // numerical location inside region1
756  { 10, { -0.5, 0.0, 0.0 }, { 1.0, 0.0, 0.0 }, 8, 0.51 },
757  { 8, { -0.5, 0.0, 0.0 }, { -1.0, 0.0, 0.0 }, 10, 0.5 },
758  // numerical location on surface 9 of region1
759  { 10, { -1.0, 0.0, 0.0 }, { 1.0, 0.0, 0.0 }, 8, 1.01 },
760  { 8, { -1.0, 0.0, 0.0 }, { -1.0, 0.0, 0.0 }, 10, 0.0 } };
761 
762  ErrorCode rval;
763  Interface* moab = gqt->moab_instance();
764 
765  Tag dim_tag = gqt->gttool()->get_geom_tag();
766  Range surfs, vols;
767  const int two = 2, three = 3;
768  const void* ptrs[] = { &two, &three };
769  rval = moab->get_entities_by_type_and_tag( 0, MBENTITYSET, &dim_tag, ptrs, 1, surfs );CHKERR;
770  rval = moab->get_entities_by_type_and_tag( 0, MBENTITYSET, &dim_tag, ptrs + 1, 1, vols );CHKERR;
771 
772  if( vols.size() != 2 )
773  {
774  std::cerr << "ERROR: Expected 2 volumes in input, found " << vols.size() << std::endl;
775  return MB_FAILURE;
776  }
777  const unsigned num_surf = 12;
778  if( surfs.size() != num_surf )
779  {
780  std::cerr << "ERROR: Expected " << num_surf << " surfaces in input, found " << surfs.size() << std::endl;
781  return MB_FAILURE;
782  }
783 
784  int ids[num_surf];
785  rval = moab->tag_get_data( gqt->gttool()->get_gid_tag(), surfs, ids );CHKERR;
786  EntityHandle surf[num_surf];
787  std::copy( surfs.begin(), surfs.end(), surf );
788 
789  const int num_test = sizeof( tests ) / sizeof( tests[0] );
790  for( int i = 0; i < num_test; ++i )
791  {
792  int* ptr = std::find( ids, ids + num_surf, tests[i].prev_surf );
793  unsigned idx = ptr - ids;
794  if( idx >= num_surf )
795  {
796  std::cerr << "Surface " << tests[i].prev_surf << " not found." << std::endl;
797  return MB_FAILURE;
798  }
799  // const EntityHandle src_surf = surf[idx];
800 
801  ptr = std::find( ids, ids + num_surf, tests[i].hit_surf );
802  idx = ptr - ids;
803  if( idx >= num_surf )
804  {
805  std::cerr << "Surface " << tests[i].hit_surf << " not found." << std::endl;
806  return MB_FAILURE;
807  }
808  const EntityHandle hit_surf = surf[idx];
809 
810  double dist;
811  EntityHandle result;
812  rval = gqt->ray_fire( vols.front(), tests[i].origin, tests[i].direction, result, dist );
813 
814  if( result != hit_surf || fabs( dist - tests[i].distance ) > 1e-6 )
815  {
816  EntityHandle* p = std::find( surf, surf + 6, result );
817  idx = p - surf;
818  int id = idx > num_surf - 1 ? 0 : ids[idx];
819 
820  std::cerr << "Rayfire test failed for " << std::endl
821  << "\t ray from (" << tests[i].origin[0] << ", " << tests[i].origin[1] << ", "
822  << tests[i].origin[2] << ") going [" << tests[i].direction[0] << ", " << tests[i].direction[1]
823  << ", " << tests[i].direction[2] << "]" << std::endl
824  << "\t Beginning on surface " << tests[i].prev_surf << std::endl
825  << "\t Expected to hit surface " << tests[i].hit_surf << " after " << tests[i].distance
826  << " units." << std::endl
827  << "\t Actually hit surface " << id << " after " << dist << " units." << std::endl;
828  return MB_FAILURE;
829  }
830  }
831 
832  return MB_SUCCESS;
833 }

References moab::Range::begin(), CHKERR, dim_tag, ray_fire::direction, ray_fire::distance, moab::Range::end(), ErrorCode, moab::Range::front(), moab::GeomTopoTool::get_geom_tag(), moab::GeomTopoTool::get_gid_tag(), moab::GeomQueryTool::gttool(), ray_fire::hit_surf, MB_SUCCESS, MBENTITYSET, moab::GeomQueryTool::moab_instance(), ray_fire::origin, ray_fire::prev_surf, moab::GeomQueryTool::ray_fire(), and moab::Range::size().

Referenced by run_overlap_tests().

◆ overlap_test_surface_sense()

ErrorCode overlap_test_surface_sense ( GeomQueryTool gqt)

Definition at line 401 of file test_geom_gqt.cpp.

402 {
403  ErrorCode rval;
404  Interface* moab = gqt->moab_instance();
405 
406  Tag dim_tag = gqt->gttool()->get_geom_tag();
407  Range surfs, vols;
408  const int two = 2, three = 3;
409  const void* ptrs[] = { &two, &three };
410  rval = moab->get_entities_by_type_and_tag( 0, MBENTITYSET, &dim_tag, ptrs, 1, surfs );CHKERR;
411  rval = moab->get_entities_by_type_and_tag( 0, MBENTITYSET, &dim_tag, ptrs + 1, 1, vols );CHKERR;
412 
413  if( vols.size() != 2 )
414  {
415  std::cerr << "ERROR: Expected 2 volumes in input, found " << vols.size() << std::endl;
416  return MB_FAILURE;
417  }
418  if( surfs.size() != 12 )
419  {
420  std::cerr << "ERROR: Expected 12 surfaces in input, found " << surfs.size() << std::endl;
421  return MB_FAILURE;
422  }
423 
424  for( Range::iterator i = surfs.begin(); i != surfs.end(); ++i )
425  {
426  int sense = 0;
427  rval = gqt->gttool()->get_sense( *i, vols.front(), sense );
428  if( MB_SUCCESS != rval || sense != 1 )
429  {
430  std::cerr << "ERROR: Expected 1 for surface sense, got " << sense << std::endl;
431  return MB_FAILURE;
432  }
433  }
434 
435  return MB_SUCCESS;
436 }

References moab::Range::begin(), CHKERR, dim_tag, moab::Range::end(), ErrorCode, moab::Range::front(), moab::GeomTopoTool::get_geom_tag(), moab::GeomTopoTool::get_sense(), moab::GeomQueryTool::gttool(), MB_SUCCESS, MBENTITYSET, moab::GeomQueryTool::moab_instance(), and moab::Range::size().

Referenced by run_overlap_tests().

◆ overlap_test_tracking()

ErrorCode overlap_test_tracking ( GeomQueryTool gqt)

Definition at line 1029 of file test_geom_gqt.cpp.

1030 {
1031  /* Track a particle from left (-x) to right (+x) through an overlap.
1032  ____________________
1033  | |
1034  -x <--- | region1 | overlap | region0 | ---> +x
1035  | |
1036  ---------------------
1037  -x <--- -1.0 0.0 0.01 1.0 ---> +x
1038  surf_id: 10 4 8 2 */
1039 
1040  // get the surfaces and volumes
1041  Tag dim_tag = gqt->gttool()->get_geom_tag();
1042  Range surfs, explicit_vols;
1043  const int two = 2, three = 3;
1044  const void* ptrs[] = { &two, &three };
1045  ErrorCode rval;
1046  Interface* moab = gqt->moab_instance();
1047  rval = moab->get_entities_by_type_and_tag( 0, MBENTITYSET, &dim_tag, ptrs, 1, surfs );CHKERR;
1048  rval = moab->get_entities_by_type_and_tag( 0, MBENTITYSET, &dim_tag, ptrs + 1, 1, explicit_vols );CHKERR;
1049 
1050  if( explicit_vols.size() != 2 )
1051  {
1052  std::cerr << "ERROR: Expected 2 explicit volumes in input, found " << explicit_vols.size() << std::endl;
1053  return MB_FAILURE;
1054  }
1055  const unsigned num_surf = 12;
1056  if( surfs.size() != num_surf )
1057  {
1058  std::cerr << "ERROR: Expected " << num_surf << " surfaces in input, found " << surfs.size() << std::endl;
1059  return MB_FAILURE;
1060  }
1061  const EntityHandle explicit_vol = explicit_vols.front();
1062 
1063  // start particle
1064  double point[] = { -0.9, 0, 0 };
1065  const double dir[] = { 1, 0, 0 };
1066  EntityHandle vol = explicit_vol;
1067  int result;
1068  const int INSIDE = 1; // OUTSIDE = 0, BOUNDARY = -1;
1069  rval = gqt->point_in_volume( explicit_vol, point, result, dir );CHKERR;
1070  if( result != INSIDE )
1071  {
1072  std::cerr << "ERROR: particle not inside explicit volume" << std::endl;
1073  return MB_FAILURE;
1074  }
1075 
1076  // get next surface
1077  double dist;
1078  EntityHandle next_surf;
1079  GeomQueryTool::RayHistory history;
1080  rval = gqt->ray_fire( vol, point, dir, next_surf, dist, &history );CHKERR;
1081  if( next_surf != surfs[7] || fabs( dist - 0.91 ) > 1e-6 )
1082  {
1083  std::cerr << "ERROR: failed on advance 1" << std::endl;
1084  return MB_FAILURE;
1085  }
1086  for( unsigned i = 0; i < 3; i++ )
1087  point[i] += dist * dir[i];
1088 
1089  // get the next volume (implicit complement)
1090  EntityHandle next_vol;
1091  rval = gqt->gttool()->next_vol( next_surf, vol, next_vol );CHKERR;
1092 
1093  // get the next surface (behind numerical location)
1094  vol = next_vol;
1095  rval = gqt->ray_fire( vol, point, dir, next_surf, dist, &history );CHKERR;
1096  if( next_surf != surfs[3] || fabs( dist - 0.0 ) > 1e-6 )
1097  {
1098  std::cerr << "ERROR: failed on advance 2" << std::endl;
1099  return MB_FAILURE;
1100  }
1101  for( unsigned i = 0; i < 3; i++ )
1102  point[i] += dist * dir[i];
1103 
1104  // get the next volume (the explicit volume)
1105  rval = gqt->gttool()->next_vol( next_surf, vol, next_vol );CHKERR;
1106 
1107  // get the next surface
1108  vol = next_vol;
1109  rval = gqt->ray_fire( vol, point, dir, next_surf, dist, &history );CHKERR;
1110  if( next_surf != surfs[1] || fabs( dist - 0.99 ) > 1e-6 )
1111  {
1112  std::cerr << "ERROR: failed on advance 3" << std::endl;
1113  return MB_FAILURE;
1114  }
1115  for( unsigned i = 0; i < 3; i++ )
1116  point[i] += dist * dir[i];
1117 
1118  return MB_SUCCESS;
1119 }

References CHKERR, dim_tag, PointInVol::dir, ErrorCode, moab::Range::front(), moab::GeomTopoTool::get_geom_tag(), moab::GeomQueryTool::gttool(), MB_SUCCESS, MBENTITYSET, moab::GeomQueryTool::moab_instance(), moab::GeomTopoTool::next_vol(), moab::GeomQueryTool::point_in_volume(), moab::GeomQueryTool::ray_fire(), PointInVol::result, and moab::Range::size().

Referenced by run_overlap_tests().

◆ overlap_write_geometry()

ErrorCode overlap_write_geometry ( const char *  output_file_name)

Definition at line 136 of file test_geom_gqt.cpp.

137 {
138  ErrorCode rval;
139  Interface* moab = new Core();
140 
141  // Define two 1x2x2 cubes that overlap from 0 <= x <= 0.01
142  // cube 0 centered at (0.5,0,0)
143  const double coords[] = { 1, -1, -1, 1, 1, -1, 0, 1, -1, 0, -1, -1, 1, -1, 1, 1, 1, 1, 0, 1, 1, 0, -1, 1,
144  // cube 1 centered near (-0.5,0,0)
145  0.01, -1, -1, 0.01, 1, -1, -1, 1, -1, -1, -1, -1, 0.01, -1, 1, 0.01, 1, 1, -1, 1, 1, -1,
146  -1, 1 };
147  const int connectivity[] = { 0, 3, 1, 3, 2, 1, // -Z
148  0, 1, 4, 5, 4, 1, // +X
149  1, 2, 6, 6, 5, 1, // +Y
150  6, 2, 3, 7, 6, 3, // -X
151  0, 4, 3, 7, 3, 4, // -Y
152  4, 5, 6, 6, 7, 4 }; // +Z
153 
154  // Create the geometry
155  const unsigned tris_per_surf = 2;
156  const unsigned num_cubes = 2;
157  const unsigned num_verts = sizeof( coords ) / ( 3 * sizeof( double ) );
158  const unsigned num_tris = num_cubes * sizeof( connectivity ) / ( 3 * sizeof( int ) );
159  const unsigned num_surfs = num_tris / tris_per_surf;
160  EntityHandle verts[num_verts], tris[num_tris], surfs[num_surfs];
161 
162  for( unsigned i = 0; i < num_verts; ++i )
163  {
164  rval = moab->create_vertex( coords + 3 * i, verts[i] );CHKERR;
165  }
166  // cube0
167  for( unsigned i = 0; i < num_tris / 2; ++i )
168  {
169  const EntityHandle conn[] = { verts[connectivity[3 * i]], verts[connectivity[3 * i + 1]],
170  verts[connectivity[3 * i + 2]] };
171  rval = moab->create_element( MBTRI, conn, 3, tris[i] );CHKERR;
172  }
173  // cube1
174  for( unsigned i = 0; i < num_tris / 2; ++i )
175  {
176  const EntityHandle conn[] = { verts[8 + connectivity[3 * i]], verts[8 + connectivity[3 * i + 1]],
177  verts[8 + connectivity[3 * i + 2]] };
178  rval = moab->create_element( MBTRI, conn, 3, tris[num_tris / 2 + i] );CHKERR;
179  }
180 
181  // create CAD topology
182  EntityHandle* tri_iter = tris;
183  for( unsigned i = 0; i < num_surfs; ++i )
184  {
185  rval = moab->create_meshset( MESHSET_SET, surfs[i] );CHKERR;
186  rval = moab->add_entities( surfs[i], tri_iter, tris_per_surf );CHKERR;
187  tri_iter += tris_per_surf;
188  }
189 
190  Tag dim_tag, id_tag, sense_tag;
192  id_tag = moab->globalId_tag();
193  rval = moab->tag_get_handle( "GEOM_SENSE_2", 2, MB_TYPE_HANDLE, sense_tag, MB_TAG_SPARSE | MB_TAG_CREAT );CHKERR;
194 
195  std::vector< int > dims( num_surfs, 2 );
196  rval = moab->tag_set_data( dim_tag, surfs, num_surfs, &dims[0] );CHKERR;
197  std::vector< int > ids( num_surfs );
198  for( size_t i = 0; i < ids.size(); ++i )
199  ids[i] = i + 1;
200  rval = moab->tag_set_data( id_tag, surfs, num_surfs, &ids[0] );CHKERR;
201 
202  EntityHandle volume;
203  rval = moab->create_meshset( MESHSET_SET, volume );CHKERR;
204  for( unsigned i = 0; i < num_surfs; ++i )
205  {
206  rval = moab->add_parent_child( volume, surfs[i] );CHKERR;
207  }
208 
209  std::vector< EntityHandle > senses( 2 * num_surfs, 0 );
210  for( size_t i = 0; i < senses.size(); i += 2 )
211  senses[i] = volume;
212  rval = moab->tag_set_data( sense_tag, surfs, num_surfs, &senses[0] );CHKERR;
213 
214  const int three = 3;
215  const int one = 1;
216  rval = moab->tag_set_data( dim_tag, &volume, 1, &three );CHKERR;
217  rval = moab->tag_set_data( id_tag, &volume, 1, &one );CHKERR;
218 
219  rval = moab->write_mesh( output_file_name );CHKERR;
220  delete moab;
221  return MB_SUCCESS;
222 }

References CHKERR, dim_tag, ErrorCode, GEOM_DIMENSION_TAG_NAME, id_tag, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_SPARSE, MB_TYPE_HANDLE, MB_TYPE_INTEGER, MBTRI, and MESHSET_SET.

Referenced by main().

◆ run_overlap_tests()

int run_overlap_tests ( GeomQueryTool gqt)

Definition at line 344 of file test_geom_gqt.cpp.

345 {
346  int errors = 0;
347  ErrorCode rval;
348 
349  rval = gqt->initialize();MB_CHK_SET_ERR_CONT( rval, "Failed to initialize the GeomQueryTool" );
350 
351  // change settings to use overlap-tolerant mode (with a large enough thickness)
352  double overlap_thickness = 3.0;
353  gqt->set_overlap_thickness( overlap_thickness );
360 
361  return errors;
362 }

References ErrorCode, moab::GeomQueryTool::initialize(), MB_CHK_SET_ERR_CONT, overlap_test_measure_area(), overlap_test_measure_volume(), overlap_test_point_in_volume(), overlap_test_ray_fire(), overlap_test_surface_sense(), overlap_test_tracking(), RUN_TEST, and moab::GeomQueryTool::set_overlap_thickness().

Referenced by main().

◆ run_regular_tests()

int run_regular_tests ( GeomQueryTool gqt)

Definition at line 321 of file test_geom_gqt.cpp.

322 {
323  int errors = 0;
324  ErrorCode rval;
325 
326  rval = gqt->initialize();MB_CHK_SET_ERR_CONT( rval, "Failed to initialize the GeomQueryTool" );
327 
334 
335  // change settings to use overlap-tolerant mode (arbitrary thickness)
336  double overlap_thickness = 0.1;
337  gqt->set_overlap_thickness( overlap_thickness );
340 
341  return errors;
342 }

References ErrorCode, moab::GeomQueryTool::initialize(), MB_CHK_SET_ERR_CONT, RUN_TEST, moab::GeomQueryTool::set_overlap_thickness(), test_closest_to_location(), test_measure_area(), test_measure_volume(), test_point_in_volume(), test_ray_fire(), and test_surface_sense().

Referenced by main().

◆ test_closest_to_location()

ErrorCode test_closest_to_location ( GeomQueryTool gqt)

Definition at line 921 of file test_geom_gqt.cpp.

922 {
923  ErrorCode rval;
924  Interface* moab = gqt->moab_instance();
925 
926  Range vols;
927  const int three = 3;
928  const void* ptr = &three;
929  Tag dim_tag = gqt->gttool()->get_geom_tag();
930  rval = moab->get_entities_by_type_and_tag( 0, MBENTITYSET, &dim_tag, &ptr, 1, vols );CHKERR;
931  if( vols.size() != 2 )
932  {
933  std::cerr << "ERROR: Expected 2 volumes in input, found " << vols.size() << std::endl;
934  return MB_FAILURE;
935  }
936  const EntityHandle vol = vols.front();
937 
938  CartVect position( 10, 0, 0 );
939  double result = 0.0;
940  rval = gqt->closest_to_location( vol, position.array(), result );
941  if( result != 9.0 ) return MB_FAILURE;
942 
943  EntityHandle surface = 1;
944  rval = gqt->closest_to_location( vol, position.array(), result, &surface );
945 
946  if( result != 9.0 ) return MB_FAILURE;
947  if( surface == 1 ) return MB_FAILURE;
948 
949  return MB_SUCCESS;
950 }

References moab::CartVect::array(), CHKERR, moab::GeomQueryTool::closest_to_location(), dim_tag, ErrorCode, moab::Range::front(), moab::GeomTopoTool::get_geom_tag(), moab::GeomQueryTool::gttool(), MB_SUCCESS, MBENTITYSET, moab::GeomQueryTool::moab_instance(), PointInVol::result, and moab::Range::size().

Referenced by run_regular_tests().

◆ test_measure_area()

ErrorCode test_measure_area ( GeomQueryTool gqt)

Definition at line 499 of file test_geom_gqt.cpp.

500 {
501  ErrorCode rval;
502  Interface* moab = gqt->moab_instance();
503 
504  Tag dim_tag = gqt->gttool()->get_geom_tag();
505  Range surfs;
506  const int two = 2;
507  const void* ptr = &two;
508  rval = moab->get_entities_by_type_and_tag( 0, MBENTITYSET, &dim_tag, &ptr, 1, surfs );CHKERR;
509 
510  if( surfs.size() != 6 )
511  {
512  std::cerr << "ERROR: Expected 6 surfaces in input, found " << surfs.size() << std::endl;
513  return MB_FAILURE;
514  }
515 
516  int ids[6];
517  rval = moab->tag_get_data( gqt->gttool()->get_gid_tag(), surfs, ids );CHKERR;
518 
519  // expect area of 4 for all faces except face 6.
520  // face 6 should have area == 4*sqrt(2)
521  Range::iterator iter = surfs.begin();
522  for( unsigned i = 0; i < 6; ++i, ++iter )
523  {
524  double expected = 4.0;
525  if( ids[i] == 6 ) expected *= ROOT2;
526 
527  double result;
528 
529  rval = gqt->measure_area( *iter, result );CHKERR;
530  if( fabs( result - expected ) > std::numeric_limits< double >::epsilon() )
531  {
532  std::cerr << "ERROR: Expected area of surface " << ids[i] << " to be " << expected << ". Got " << result
533  << std::endl;
534  return MB_FAILURE;
535  }
536  }
537 
538  return MB_SUCCESS;
539 }

References moab::Range::begin(), CHKERR, dim_tag, ErrorCode, moab::GeomTopoTool::get_geom_tag(), moab::GeomTopoTool::get_gid_tag(), moab::GeomQueryTool::gttool(), MB_SUCCESS, MBENTITYSET, moab::GeomQueryTool::measure_area(), moab::GeomQueryTool::moab_instance(), ROOT2, and moab::Range::size().

Referenced by run_regular_tests().

◆ test_measure_volume()

ErrorCode test_measure_volume ( GeomQueryTool gqt)

Definition at line 437 of file test_geom_gqt.cpp.

438 {
439  ErrorCode rval;
440  Interface* moab = gqt->moab_instance();
441 
442  Tag dim_tag = gqt->gttool()->get_geom_tag();
443  Range vols;
444  const int three = 3;
445  const void* ptr = &three;
446  rval = moab->get_entities_by_type_and_tag( 0, MBENTITYSET, &dim_tag, &ptr, 1, vols );CHKERR;
447 
448  if( vols.size() != 2 )
449  {
450  std::cerr << "ERROR: Expected 2 volumes in input, found " << vols.size() << std::endl;
451  return MB_FAILURE;
452  }
453 
454  // input file is 2x2x2 cube with convexity in +Z face that touches the origin.
455  // expected volume is 8 (2x2x2) less the volume of the pyrimid concavity
456  double result;
457  const double vol = 2 * 2 * 2 - 1 * 4. / 3;
458 
459  rval = gqt->measure_volume( vols.front(), result );CHKERR;
460  if( fabs( result - vol ) > 10 * std::numeric_limits< double >::epsilon() )
461  {
462  std::cerr << "ERROR: Expected " << vol << " as measure of volume, got " << result << std::endl;
463  return MB_FAILURE;
464  }
465 
466  return MB_SUCCESS;
467 }

References CHKERR, dim_tag, ErrorCode, moab::Range::front(), moab::GeomTopoTool::get_geom_tag(), moab::GeomQueryTool::gttool(), MB_SUCCESS, MBENTITYSET, moab::GeomQueryTool::measure_volume(), moab::GeomQueryTool::moab_instance(), and moab::Range::size().

Referenced by run_regular_tests().

◆ test_point_in_volume()

ErrorCode test_point_in_volume ( GeomQueryTool gqt)

Definition at line 842 of file test_geom_gqt.cpp.

843 {
844  const char* const NAME_ARR[] = { "Boundary", "Outside", "Inside" };
845  const char* const* names = NAME_ARR + 1;
846  const int INSIDE = 1, OUTSIDE = 0, BOUNDARY = -1;
847  const struct PointInVol tests[] = { { { 0.0, 0.0, 0.5 }, OUTSIDE, { 0.0, 0.0, 0.0 } },
848  { { 0.0, 0.0, -0.5 }, INSIDE, { 0.0, 0.0, 0.0 } },
849  { { 0.7, 0.0, 0.0 }, INSIDE, { 0.0, 0.0, 0.0 } },
850  { { -0.7, 0.0, 0.0 }, INSIDE, { 0.0, 0.0, 0.0 } },
851  { { 0.0, -0.7, 0.0 }, INSIDE, { 0.0, 0.0, 0.0 } },
852  { { 0.0, -0.7, 0.0 }, INSIDE, { 0.0, 0.0, 0.0 } },
853  { { 1.1, 1.1, 1.1 }, OUTSIDE, { 0.0, 0.0, 0.0 } },
854  { { -1.1, 1.1, 1.1 }, OUTSIDE, { 0.0, 0.0, 0.0 } },
855  { { -1.1, -1.1, 1.1 }, OUTSIDE, { 0.0, 0.0, 0.0 } },
856  { { 1.1, -1.1, 1.1 }, OUTSIDE, { 0.0, 0.0, 0.0 } },
857  { { 1.1, 1.1, -1.1 }, OUTSIDE, { 0.0, 0.0, 0.0 } },
858  { { -1.1, 1.1, -1.1 }, OUTSIDE, { 0.0, 0.0, 0.0 } },
859  { { -1.1, -1.1, -1.1 }, OUTSIDE, { 0.0, 0.0, 0.0 } },
860  { { 1.1, -1.1, -1.1 }, OUTSIDE, { 0.0, 0.0, 0.0 } },
861  // Add some directions to test special cases of edge/node intersection
862  { { 0.5, 0.0, 0.0 }, INSIDE, { -1.0, 0.0, 0.0 } },
863  { { 0.5, 0.0, 0.0 }, INSIDE, { 1.0, 0.0, 0.0 } },
864  { { 0.0, 0.0, 2.0 }, OUTSIDE, { 0.0, 0.0, -1.0 } },
865  { { 0.5, 0.0, -0.5 }, INSIDE, { -1.0, 0.0, 0.0 } },
866  { { 0.5, -0.5, -2.0 }, OUTSIDE, { 0.0, 0.0, 1.0 } } };
867 
868  // { { 1.0, 0.0, 0.0 }, BOUNDARY}, MCNP doesn't return on boundary
869  //{ {-1.0, 0.0, 0.0 }, BOUNDARY},
870  //{ { 0.0, 1.0, 0.0 }, BOUNDARY},
871  //{ { 0.0,-1.0, 0.0 }, BOUNDARY},
872  //{ { 0.0, 0.0, 0.0 }, BOUNDARY},
873  //{ { 0.0, 0.0,-1.0 }, BOUNDARY} };
874  const int num_test = sizeof( tests ) / sizeof( tests[0] );
875 
876  ErrorCode rval;
877  Interface* moab = gqt->moab_instance();
878 
879  Tag dim_tag = gqt->gttool()->get_geom_tag();
880 
881  Range vols;
882  const int three = 3;
883  const void* ptr = &three;
884  rval = moab->get_entities_by_type_and_tag( 0, MBENTITYSET, &dim_tag, &ptr, 1, vols );CHKERR;
885  if( vols.size() != 2 )
886  {
887  std::cerr << "ERROR: Expected 2 volumes in input, found " << vols.size() << std::endl;
888  return MB_FAILURE;
889  }
890  const EntityHandle vol = vols.front();
891 
892  for( int i = 0; i < num_test; ++i )
893  {
894  int result;
895  rval = gqt->point_in_volume( vol, tests[i].coords, result, tests[i].dir );CHKERR;
896  if( result != tests[i].result )
897  {
898  std::cerr << "ERROR testing point_in_volume[" << i << "]:" << std::endl
899  << "\tExpected " << names[tests[i].result] << " for (" << tests[i].coords[0] << ", "
900  << tests[i].coords[1] << ", " << tests[i].coords[2] << "). Got " << names[result] << std::endl;
901  return MB_FAILURE;
902  }
903 
904  // point_in_volume_slow doesn't to boundary.
905  if( tests[i].result == BOUNDARY ) continue;
906 
907  rval = gqt->point_in_volume_slow( vol, tests[i].coords, result );CHKERR;
908 
909  if( result != tests[i].result )
910  {
911  std::cerr << "ERROR testing point_in_volume_slow[" << i << "]:" << std::endl
912  << "\tExpected " << names[tests[i].result] << " for (" << tests[i].coords[0] << ", "
913  << tests[i].coords[1] << ", " << tests[i].coords[2] << "). Got " << names[result] << std::endl;
914  return MB_FAILURE;
915  }
916  }
917 
918  return MB_SUCCESS;
919 }

References CHKERR, PointInVol::coords, dim_tag, PointInVol::dir, ErrorCode, moab::Range::front(), moab::GeomTopoTool::get_geom_tag(), moab::GeomQueryTool::gttool(), MB_SUCCESS, MBENTITYSET, moab::GeomQueryTool::moab_instance(), moab::GeomQueryTool::point_in_volume(), moab::GeomQueryTool::point_in_volume_slow(), PointInVol::result, and moab::Range::size().

Referenced by run_regular_tests().

◆ test_ray_fire()

ErrorCode test_ray_fire ( GeomQueryTool gqt)

Definition at line 596 of file test_geom_gqt.cpp.

597 {
598  // Glancing ray-triangle intersections are not valid exit intersections.
599  // Piercing ray-triangle intersections are valid exit intersections.
600  // "0" destination surface implies that it is ambiguous.
601  const struct ray_fire tests[] = { /* src_srf origin direction dest dist */
602  // piercing edge
603  { 1, { 0.0, 0.0, -1. }, { -1.0 / ROOT2, 0.0, 1.0 / ROOT2 }, 4, ROOT2 },
604  // piercing edge
605  { 1, { 0.0, 0.0, -1. }, { 1.0 / ROOT2, 0.0, 1.0 / ROOT2 }, 2, ROOT2 },
606  // piercing edge
607  { 1, { 0.0, 0.0, -1. }, { 0.0, 1.0 / ROOT2, 1.0 / ROOT2 }, 3, ROOT2 },
608  // piercing edge
609  { 1, { 0.5, 0.5, -1. }, { 0.0, 0.0, 1.0 }, 6, 1.5 },
610  // interior
611  { 2, { 1.0, 0.0, 0.5 }, { -1.0, 0.0, 0.0 }, 6, 0.5 },
612  // glancing node then piercing edge
613  { 2, { 1.0, 0.0, 0.0 }, { -1.0, 0.0, 0.0 }, 4, 2.0 },
614  // piercing node
615  { 1, { 0.0, 0.0, -1. }, { 0.0, 0.0, 1.0 }, 6, 1.0 },
616  // glancing edge then interior
617  { 2, { 1.0, 0.0, 0.5 }, { -1.0 / ROOT2, 1.0 / ROOT2, 0.0 }, 3, ROOT2 } };
618 
619  ErrorCode rval;
620  Interface* moab = gqt->moab_instance();
621 
622  Tag dim_tag = gqt->gttool()->get_geom_tag();
623  Range surfs, vols;
624  const int two = 2, three = 3;
625  const void* ptrs[] = { &two, &three };
626  rval = moab->get_entities_by_type_and_tag( 0, MBENTITYSET, &dim_tag, ptrs, 1, surfs );CHKERR;
627  rval = moab->get_entities_by_type_and_tag( 0, MBENTITYSET, &dim_tag, ptrs + 1, 1, vols );CHKERR;
628 
629  if( vols.size() != 2 )
630  {
631  std::cerr << "ERROR: Expected 2 volumes in input, found " << vols.size() << std::endl;
632  return MB_FAILURE;
633  }
634  if( surfs.size() != 6 )
635  {
636  std::cerr << "ERROR: Expected 6 surfaces in input, found " << surfs.size() << std::endl;
637  return MB_FAILURE;
638  }
639 
640  int ids[6];
641  rval = moab->tag_get_data( gqt->gttool()->get_gid_tag(), surfs, ids );CHKERR;
642  EntityHandle surf[6];
643  std::copy( surfs.begin(), surfs.end(), surf );
644 
645  const int num_test = sizeof( tests ) / sizeof( tests[0] );
646  for( int i = 0; i < num_test; ++i )
647  {
648  int* ptr = std::find( ids, ids + 6, tests[i].prev_surf );
649  int idx = ptr - ids;
650  if( idx >= 6 )
651  {
652  std::cerr << "Surface " << tests[i].prev_surf << " not found." << std::endl;
653  return MB_FAILURE;
654  }
655  // const EntityHandle src_surf = surf[idx];
656 
657  ptr = std::find( ids, ids + 6, tests[i].hit_surf );
658  idx = ptr - ids;
659  if( idx >= 6 )
660  {
661  std::cerr << "Surface " << tests[i].hit_surf << " not found." << std::endl;
662  return MB_FAILURE;
663  }
664  const EntityHandle hit_surf = surf[idx];
665 
666  double dist;
667  EntityHandle result;
669  rval = gqt->ray_fire( vols.front(), tests[i].origin, tests[i].direction, result, dist, &history );
670 
671  if( result != hit_surf || fabs( dist - tests[i].distance ) > 1e-6 )
672  {
673  EntityHandle* p = std::find( surf, surf + 6, result );
674  idx = p - surf;
675  int id = idx > 5 ? 0 : ids[idx];
676 
677  std::cerr << "Rayfire test failed for " << std::endl
678  << "\t ray from (" << tests[i].origin[0] << ", " << tests[i].origin[1] << ", "
679  << tests[i].origin[2] << ") going [" << tests[i].direction[0] << ", " << tests[i].direction[1]
680  << ", " << tests[i].direction[2] << "]" << std::endl
681  << "\t Beginning on surface " << tests[i].prev_surf << std::endl
682  << "\t Expected to hit surface " << tests[i].hit_surf << " after " << tests[i].distance
683  << " units." << std::endl
684  << "\t Actually hit surface " << id << " after " << dist << " units." << std::endl;
685  return MB_FAILURE;
686  }
687 
688  CartVect loc = CartVect( tests[i].origin ) + ( dist * CartVect( tests[i].direction ) );
689 
690  std::vector< std::pair< int, GeomQueryTool::RayHistory* > > boundary_tests;
691  boundary_tests.push_back( std::make_pair( 1, &history ) );
692  boundary_tests.push_back( std::make_pair( 0, &history ) );
693  boundary_tests.push_back( std::make_pair( 1, (GeomQueryTool::RayHistory*)NULL ) );
694  boundary_tests.push_back( std::make_pair( 0, (GeomQueryTool::RayHistory*)NULL ) );
695 
696  for( unsigned int bt = 0; bt < boundary_tests.size(); ++bt )
697  {
698 
699  int expected = boundary_tests[bt].first;
700  GeomQueryTool::RayHistory* h = boundary_tests[bt].second;
701 
702  // pick the direction based on expected result of test. Either reuse the ray_fire
703  // vector, or reverse it to check for a vector that enters the cell
704  CartVect uvw( tests[i].direction );
705  if( expected == 1 ) uvw = -uvw;
706 
707  int boundary_result = -1;
708 
709  rval = gqt->test_volume_boundary( vols.front(), result, loc.array(), uvw.array(), boundary_result, h );
710 
711  if( boundary_result != expected )
712  {
713  std::cerr << "DagMC::test_volume_boundary failed (" << ( ( expected == 0 ) ? "+" : "-" ) << " dir,"
714  << ( ( h ) ? "+" : "-" ) << " history, i=" << i << ")" << std::endl;
715  return MB_FAILURE;
716  }
717  }
718  }
719 
720  return MB_SUCCESS;
721 }

References moab::CartVect::array(), moab::Range::begin(), CHKERR, dim_tag, ray_fire::direction, ray_fire::distance, moab::Range::end(), ErrorCode, moab::Range::front(), moab::GeomTopoTool::get_geom_tag(), moab::GeomTopoTool::get_gid_tag(), moab::GeomQueryTool::gttool(), ray_fire::hit_surf, MB_SUCCESS, MBENTITYSET, moab::GeomQueryTool::moab_instance(), origin, ray_fire::origin, ray_fire::prev_surf, moab::GeomQueryTool::ray_fire(), ROOT2, moab::Range::size(), and moab::GeomQueryTool::test_volume_boundary().

Referenced by run_regular_tests().

◆ test_surface_sense()

ErrorCode test_surface_sense ( GeomQueryTool gqt)

Definition at line 364 of file test_geom_gqt.cpp.

365 {
366  ErrorCode rval;
367  Interface* moab = gqt->moab_instance();
368 
369  Tag dim_tag = gqt->gttool()->get_geom_tag();
370  Range surfs, vols;
371  const int two = 2, three = 3;
372  const void* ptrs[] = { &two, &three };
373  rval = moab->get_entities_by_type_and_tag( 0, MBENTITYSET, &dim_tag, ptrs, 1, surfs );CHKERR;
374  rval = moab->get_entities_by_type_and_tag( 0, MBENTITYSET, &dim_tag, ptrs + 1, 1, vols );CHKERR;
375 
376  if( vols.size() != 2 )
377  {
378  std::cerr << "ERROR: Expected 2 volumes in input, found " << vols.size() << std::endl;
379  return MB_FAILURE;
380  }
381  if( surfs.size() != 6 )
382  {
383  std::cerr << "ERROR: Expected 6 surfaces in input, found " << surfs.size() << std::endl;
384  return MB_FAILURE;
385  }
386 
387  for( Range::iterator i = surfs.begin(); i != surfs.end(); ++i )
388  {
389  int sense = 0;
390  rval = gqt->gttool()->get_sense( *i, vols.front(), sense );
391  if( MB_SUCCESS != rval || sense != 1 )
392  {
393  std::cerr << "ERROR: Expected 1 for surface sense, got " << sense << std::endl;
394  return MB_FAILURE;
395  }
396  }
397 
398  return MB_SUCCESS;
399 }

References moab::Range::begin(), CHKERR, dim_tag, moab::Range::end(), ErrorCode, moab::Range::front(), moab::GeomTopoTool::get_geom_tag(), moab::GeomTopoTool::get_sense(), moab::GeomQueryTool::gttool(), MB_SUCCESS, MBENTITYSET, moab::GeomQueryTool::moab_instance(), and moab::Range::size().

Referenced by run_regular_tests().

◆ write_geometry()

ErrorCode write_geometry ( const char *  output_file_name)

Definition at line 56 of file test_geom_gqt.cpp.

57 {
58  ErrorCode rval;
59 
60  Interface* moab = new Core();
61 
62  // Define a 2x2x2 cube centered at orgin
63  // with concavity in +Z face.
64  const double coords[] = { 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1,
65  1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 0, 0, 0 };
66  const int connectivity[] = {
67  0, 3, 1, 3, 2, 1, // -Z
68  0, 1, 4, 5, 4, 1, // +X
69  1, 2, 6, 6, 5, 1, // +Y
70  6, 2, 3, 7, 6, 3, // -X
71  0, 4, 3, 7, 3, 4, // -Y
72  4, 5, 8, 5, 6, 8, // +Z
73  6, 7, 8, 7, 4, 8 // +Z
74  };
75  const unsigned tris_per_surf[] = { 2, 2, 2, 2, 2, 4 };
76 
77  // Create the geometry
78  const unsigned num_verts = sizeof( coords ) / ( 3 * sizeof( double ) );
79  const unsigned num_tris = sizeof( connectivity ) / ( 3 * sizeof( int ) );
80  const unsigned num_surfs = sizeof( tris_per_surf ) / sizeof( unsigned );
81  EntityHandle verts[num_verts], tris[num_tris], surfs[num_surfs];
82  for( unsigned i = 0; i < num_verts; ++i )
83  {
84  rval = moab->create_vertex( coords + 3 * i, verts[i] );CHKERR;
85  }
86  for( unsigned i = 0; i < num_tris; ++i )
87  {
88  const EntityHandle conn[] = { verts[connectivity[3 * i]], verts[connectivity[3 * i + 1]],
89  verts[connectivity[3 * i + 2]] };
90  rval = moab->create_element( MBTRI, conn, 3, tris[i] );CHKERR;
91  }
92 
93  // create CAD topology
94  EntityHandle* tri_iter = tris;
95  for( unsigned i = 0; i < num_surfs; ++i )
96  {
97  rval = moab->create_meshset( MESHSET_SET, surfs[i] );CHKERR;
98  rval = moab->add_entities( surfs[i], tri_iter, tris_per_surf[i] );CHKERR;
99  tri_iter += tris_per_surf[i];
100  }
101 
102  Tag dim_tag, id_tag, sense_tag;
104  id_tag = moab->globalId_tag();
105  rval = moab->tag_get_handle( "GEOM_SENSE_2", 2, MB_TYPE_HANDLE, sense_tag, MB_TAG_SPARSE | MB_TAG_CREAT );CHKERR;
106 
107  std::vector< int > dims( num_surfs, 2 );
108  rval = moab->tag_set_data( dim_tag, surfs, num_surfs, &dims[0] );CHKERR;
109  std::vector< int > ids( num_surfs );
110  for( size_t i = 0; i < ids.size(); ++i )
111  ids[i] = i + 1;
112  rval = moab->tag_set_data( id_tag, surfs, num_surfs, &ids[0] );CHKERR;
113 
114  EntityHandle volume;
115  rval = moab->create_meshset( MESHSET_SET, volume );CHKERR;
116  for( unsigned i = 0; i < num_surfs; ++i )
117  {
118  rval = moab->add_parent_child( volume, surfs[i] );CHKERR;
119  }
120 
121  std::vector< EntityHandle > senses( 2 * num_surfs, 0 );
122  for( size_t i = 0; i < senses.size(); i += 2 )
123  senses[i] = volume;
124  rval = moab->tag_set_data( sense_tag, surfs, num_surfs, &senses[0] );CHKERR;
125 
126  const int three = 3;
127  const int one = 1;
128  rval = moab->tag_set_data( dim_tag, &volume, 1, &three );CHKERR;
129  rval = moab->tag_set_data( id_tag, &volume, 1, &one );CHKERR;
130 
131  rval = moab->write_mesh( output_file_name );CHKERR;
132  delete moab;
133  return MB_SUCCESS;
134 }

References CHKERR, dim_tag, ErrorCode, GEOM_DIMENSION_TAG_NAME, id_tag, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_SPARSE, MB_TYPE_HANDLE, MB_TYPE_INTEGER, MBTRI, and MESHSET_SET.

Referenced by main().

Variable Documentation

◆ ROOT2

const double ROOT2 = 1.4142135623730951

Definition at line 24 of file test_geom_gqt.cpp.

Referenced by test_measure_area(), and test_ray_fire().