Loading [MathJax]/extensions/tex2jax.js
Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ElemEvaluator.hpp
Go to the documentation of this file.
1 #ifndef ELEM_EVALUATOR_HPP 2 #define ELEM_EVALUATOR_HPP 3  4 #include "moab/Interface.hpp" 5 #include "moab/CartVect.hpp" 6 #include "moab/Matrix3.hpp" 7 #include "moab/CN.hpp" 8  9 #include <vector> 10  11 namespace moab 12 { 13  14 typedef ErrorCode ( *EvalFcn )( const double* params, 15  const double* field, 16  const int ndim, 17  const int num_tuples, 18  double* work, 19  double* result ); 20  21 typedef ErrorCode ( *JacobianFcn )( const double* params, 22  const double* verts, 23  const int nverts, 24  const int ndim, 25  double* work, 26  double* result ); 27  28 typedef ErrorCode ( *IntegrateFcn )( const double* field, 29  const double* verts, 30  const int nverts, 31  const int ndim, 32  const int num_tuples, 33  double* work, 34  double* result ); 35  36 typedef ErrorCode ( *InitFcn )( const double* verts, const int nverts, double*& work ); 37  38 typedef int ( *InsideFcn )( const double* verts, const int ndims, const double tol ); 39  40 typedef ErrorCode ( *ReverseEvalFcn )( EvalFcn eval, 41  JacobianFcn jacob, 42  InsideFcn ins, 43  const double* posn, 44  const double* verts, 45  const int nverts, 46  const int ndim, 47  const double iter_tol, 48  const double inside_tol, 49  double* work, 50  double* params, 51  int* is_inside ); 52  53 typedef ErrorCode ( 54  *NormalFcn )( const int ientDim, const int facet, const int nverts, const double* verts, double normal[3] ); 55  56 class EvalSet 57 { 58  public: 59  /** \brief Forward-evaluation of field at parametric coordinates */ 60  EvalFcn evalFcn; 61  62  /** \brief Reverse-evaluation of parametric coordinates at physical space position */ 63  ReverseEvalFcn reverseEvalFcn; 64  65  /** \brief Evaluate the normal at a local facet (edge/face for 2D/3D) */ 66  NormalFcn normalFcn; 67  68  /** \brief Evaluate the jacobian at a specified parametric position */ 69  JacobianFcn jacobianFcn; 70  71  /** \brief Forward-evaluation of field at parametric coordinates */ 72  IntegrateFcn integrateFcn; 73  74  /** \brief Initialization function for an element */ 75  InitFcn initFcn; 76  77  /** \brief Function that returns whether or not the parameters are inside the natural space of 78  * the element */ 79  InsideFcn insideFcn; 80  81  /** \brief Bare constructor */ 82  EvalSet() 83  : evalFcn( NULL ), reverseEvalFcn( NULL ), normalFcn( NULL ), jacobianFcn( NULL ), integrateFcn( NULL ), 84  initFcn( NULL ), insideFcn( NULL ) 85  { 86  } 87  88  /** \brief Constructor */ 89  EvalSet( EvalFcn eval, 90  ReverseEvalFcn rev, 91  NormalFcn normal, 92  JacobianFcn jacob, 93  IntegrateFcn integ, 94  InitFcn initf, 95  InsideFcn insidef ) 96  : evalFcn( eval ), reverseEvalFcn( rev ), normalFcn( normal ), jacobianFcn( jacob ), integrateFcn( integ ), 97  initFcn( initf ), insideFcn( insidef ) 98  { 99  } 100  101  /** \brief Copy constructor */ 102  EvalSet( EvalSet const& eval ) 103  : evalFcn( eval.evalFcn ), reverseEvalFcn( eval.reverseEvalFcn ), normalFcn( eval.normalFcn ), 104  jacobianFcn( eval.jacobianFcn ), integrateFcn( eval.integrateFcn ), initFcn( eval.initFcn ), 105  insideFcn( eval.insideFcn ) 106  { 107  } 108  109  /** \brief Given an entity handle, get an appropriate eval set, based on type & #vertices */ 110  static ErrorCode get_eval_set( Interface* mb, EntityHandle eh, EvalSet& eval_set ); 111  112  /** \brief Given type & #vertices, get an appropriate eval set */ 113  static ErrorCode get_eval_set( EntityType tp, unsigned int num_vertices, EvalSet& eval_set ); 114  115  /** \brief Operator= */ 116  EvalSet& operator=( const EvalSet& eval ) 117  { 118  evalFcn = eval.evalFcn; 119  reverseEvalFcn = eval.reverseEvalFcn; 120  normalFcn = eval.normalFcn; 121  jacobianFcn = eval.jacobianFcn; 122  integrateFcn = eval.integrateFcn; 123  initFcn = eval.initFcn; 124  insideFcn = eval.insideFcn; 125  return *this; 126  } 127  128  /** \brief Common function to do reverse evaluation based on evaluation and jacobian functions 129  */ 130  static ErrorCode evaluate_reverse( EvalFcn eval, 131  JacobianFcn jacob, 132  InsideFcn inside_f, 133  const double* posn, 134  const double* verts, 135  const int nverts, 136  const int ndim, 137  const double iter_tol, 138  const double inside_tol, 139  double* work, 140  double* params, 141  int* inside ); 142  /** \brief Common function that returns true if params is in [-1,1]^ndims */ 143  static int inside_function( const double* params, const int ndims, const double tol ); 144 }; 145  146 /** \brief Given an entity handle, get an appropriate eval set, based on type & #vertices */ 147 inline ErrorCode EvalSet::get_eval_set( Interface* mb, EntityHandle eh, EvalSet& eval_set ) 148 { 149  int nv; 150  EntityType tp = mb->type_from_handle( eh ); 151  const EntityHandle* connect; 152  std::vector< EntityHandle > dum_vec; 153  ErrorCode rval = mb->get_connectivity( eh, connect, nv, false, &dum_vec ); 154  if( MB_SUCCESS != rval ) return rval; 155  156  return get_eval_set( tp, nv, eval_set ); 157 } 158  159 /**\brief Class facilitating local discretization-related functions 160  * \class ElemEvaluator 161  * This class implements discretization-related functionality operating 162  * on data in MOAB. A member of this class caches certain data about the element 163  * it's currently operating on, but is not meant to be instantiated one-per-element, 164  * but rather one-per-search (or other operation on a collection of elements). 165  * 166  * Actual discretization functionality is accessed through function pointers, 167  * allowing applications to specialize the implementation of specific functions 168  * while still using this class. 169  * 170  * This class depends on MOAB functionality for gathering entity-based data; the functions 171  * it calls through function pointers depend only on POD (plain old data, or intrinsic data types). 172  * This allows the use of other packages for serving these functions, without having to modify 173  * them to get data through MOAB. This should also promote efficiency, since in many cases they 174  * will be able to read data from its native storage locations. 175  */ 176  177 class ElemEvaluator 178 { 179  public: 180  /** \brief Constructor 181  * \param impl MOAB instance 182  * \param ent Entity handle to cache on the evaluator; if non-zero, calls set_ent_handle, which 183  * does some other stuff. \param tag Tag to cache on the evaluator; if non-zero, calls 184  * set_tag_handle, which does some other stuff too. \param tagged_ent_dim Dimension of entities 185  * to be tagged to cache on the evaluator 186  */ 187  ElemEvaluator( Interface* impl, EntityHandle ent = 0, Tag tag = 0, int tagged_ent_dim = -1 ); 188  ~ElemEvaluator(); 189  190  /** \brief Evaluate cached tag at a given parametric location within the cached entity 191  * If evaluating coordinates, call set_tag(0, 0), which indicates coords instead of a tag. 192  * \param params Parameters at which to evaluate field 193  * \param result Result of evaluation 194  * \param num_tuples Size of evaluated field, in number of values 195  */ 196  ErrorCode eval( const double* params, double* result, int num_tuples = -1 ) const; 197  198  /** \brief Reverse-evaluate the cached entity at a given physical position 199  * \param posn Position at which to evaluate parameters 200  * \param iter_tol Tolerance of reverse evaluation non-linear iteration, usually 10^-10 or so 201  * \param inside_tol Tolerance of is_inside evaluation, usually 10^-6 or so 202  * \param params Result of evaluation 203  * \param is_inside If non-NULL, returns true of resulting parameters place the point inside the 204  * element (in most cases, within [-1]*(dim) 205  */ 206  ErrorCode reverse_eval( const double* posn, 207  double iter_tol, 208  double inside_tol, 209  double* params, 210  int* is_inside = NULL ) const; 211  212  /** 213  * \brief Evaluate the normal to a facet of an entity 214  * \param ientDim Dimension of the facet. Should be (d-1) for d-dimensional entities 215  * \param facet Local id of the facet w.r.t the entity 216  * \param normal Returns the normal. 217  */ 218  ErrorCode get_normal( const int ientDim, const int facet, double normal[3] ) const; 219  220  /** \brief Evaluate the jacobian of the cached entity at a given parametric location 221  * \param params Parameters at which to evaluate jacobian 222  * \param result Result of evaluation, in the form of a 3x3 matrix, stored in column-major order 223  */ 224  ErrorCode jacobian( const double* params, double* result ) const; 225  226  /** \brief Integrate the cached tag over the cached entity 227  * \param result Result of the integration 228  */ 229  ErrorCode integrate( double* result ) const; 230  231  /** \brief Return whether a physical position is inside the cached entity to within a tolerance 232  * \param params Parameters at which to query the element 233  * \param tol Tolerance, usually 10^-6 or so 234  */ 235  int inside( const double* params, const double tol ) const; 236  237  /** \brief Given a list of entities, return the entity the point is in, or none 238  * This function reverse-evaluates the entities, returning the first entity containing the 239  * point. If no entity contains the point, containing_ent is returned as 0 and params are 240  * unchanged. This function returns something other than MB_SUCCESS only when queries go wrong 241  * for some reason. num_evals, if non-NULL, is always incremented for each call to reverse_eval. 242  * This function calls set_ent_handle for each entity before calling reverse_eval, so the 243  * ElemEvaluator object is changed. \param entities Entities tested \param point Point tested, 244  * must have 3 dimensions, even for edge and face entities \param iter_tol Tolerance for 245  * non-linear reverse evaluation \param inside_tol Tolerance for is_inside test \param 246  * containing_ent Entity containing the point, returned 0 if no entity \param params Parameters 247  * of point in containing entity, unchanged if no containing entity \param num_evals If 248  * non-NULL, incremented each time reverse_eval is called \return Returns non-success only if 249  * evaulation failed for some reason (point not in element is NOT a reason for failure) 250  */ 251  ErrorCode find_containing_entity( Range& entities, 252  const double* point, 253  const double iter_tol, 254  const double inside_tol, 255  EntityHandle& containing_ent, 256  double* params, 257  unsigned int* num_evals = NULL ); 258  259  /** \brief Given an entity set, return the contained entity the point is in, or none 260  * This function reverse-evaluates the entities, returning the first entity containing the 261  * point. If no entity contains the point, containing_ent is returned as 0 and params are 262  * unchanged. This function returns something other than MB_SUCCESS only when queries go wrong 263  * for some reason. num_evals, if non-NULL, is always incremented for each call to reverse_eval. 264  * This function calls set_ent_handle for each entity before calling reverse_eval, so the 265  * ElemEvaluator object is changed. \param ent_set Entity set containing the entities to be 266  * tested \param point Point tested, must have 3 dimensions, even for edge and face entities 267  * \param iter_tol Tolerance for non-linear reverse evaluation 268  * \param inside_tol Tolerance for is_inside test 269  * \param containing_ent Entity containing the point, returned 0 if no entity 270  * \param params Parameters of point in containing entity, unchanged if no containing entity 271  * \param num_evals If non-NULL, incremented each time reverse_eval is called 272  * \return Returns non-success only if evaulation failed for some reason (point not in element 273  * is NOT a reason for failure) 274  */ 275  ErrorCode find_containing_entity( EntityHandle ent_set, 276  const double* point, 277  const double iter_tol, 278  const double inside_tol, 279  EntityHandle& containing_ent, 280  double* params, 281  unsigned int* num_evals = NULL ); 282  283  /** \brief Set the eval set for a given type entity 284  * \param tp Entity type for which to set the eval set 285  * \param eval_set Eval set object to use 286  */ 287  ErrorCode set_eval_set( EntityType tp, const EvalSet& eval_set ); 288  289  /** \brief Set the eval set using a given entity handle 290  * This function queries the entity type and number of vertices on the entity to decide which 291  * type of shape function to use. NOTE: this function should only be called after setting a 292  * valid MOAB instance on the evaluator \param eh Entity handle whose type and #vertices are 293  * queried 294  */ 295  ErrorCode set_eval_set( const EntityHandle eh ); 296  297  /** \brief Get the eval set for a given type entity */ 298  inline EvalSet get_eval_set( EntityType tp ) 299  { 300  return evalSets[tp]; 301  } 302  303  /** \brief Set entity handle & cache connectivty & vertex positions */ 304  inline ErrorCode set_ent_handle( EntityHandle ent ); 305  306  /** \brief Get entity handle for this ElemEval */ 307  inline EntityHandle get_ent_handle() const 308  { 309  return entHandle; 310  } 311  312  /* \brief Get vertex positions cached on this EE 313  */ 314  inline double* get_vert_pos() 315  { 316  return vertPos[0].array(); 317  } 318  319  /* \brief Get the vertex handles cached here */ 320  inline const EntityHandle* get_vert_handles() const 321  { 322  return vertHandles; 323  } 324  325  /* \brief Get the number of vertices for the cached entity */ 326  inline int get_num_verts() const 327  { 328  return numVerts; 329  } 330  331  /* \brief Get the tag handle cached on this entity */ 332  inline Tag get_tag_handle() const 333  { 334  return tagHandle; 335  }; 336  337  /* \brief Set the tag handle to cache on this evaluator 338  * To designate that vertex coordinates are the desired tag, pass in a tag handle of 0 339  * and a tag dimension of 0. 340  * \param tag Tag handle to cache, or 0 to cache vertex positions 341  * \param tagged_ent_dim Dimension of entities tagged with this tag 342  */ 343  inline ErrorCode set_tag_handle( Tag tag, int tagged_ent_dim = -1 ); 344  345  /* \brief Set the name of the tag to cache on this evaluator 346  * To designate that vertex coordinates are the desired tag, pass in "COORDS" as the name 347  * and a tag dimension of 0. 348  * \param tag_name Tag handle to cache, or 0 to cache vertex positions 349  * \param tagged_ent_dim Dimension of entities tagged with this tag 350  */ 351  inline ErrorCode set_tag( const char* tag_name, int tagged_ent_dim = -1 ); 352  353  /* \brief Get the dimension of the entities on which tag is set */ 354  inline int get_tagged_ent_dim() const 355  { 356  return taggedEntDim; 357  }; 358  359  /* \brief Set the dimension of entities having the tag */ 360  inline ErrorCode set_tagged_ent_dim( int dim ); 361  362  /* \brief Get work space, sometimes this is useful for evaluating data you don't want to set as 363  * tags on entities Can't be const because most of the functions (evaluate, integrate, etc.) 364  * take non-const work space *'s 365  */ 366  inline double* get_work_space() 367  { 368  return workSpace; 369  } 370  371  /* \brief MOAB interface cached on this evaluator */ 372  inline Interface* get_moab() 373  { 374  return mbImpl; 375  } 376  377  private: 378  /** \brief Interface */ 379  Interface* mbImpl; 380  381  /** \brief Entity handle being evaluated */ 382  EntityHandle entHandle; 383  384  /** \brief Entity type */ 385  EntityType entType; 386  387  /** \brief Entity dimension */ 388  int entDim; 389  390  /** \brief Number of vertices cached here */ 391  int numVerts; 392  393  /** \brief Cached copy of vertex handle ptr */ 394  const EntityHandle* vertHandles; 395  396  /** \brief Cached copy of vertex positions */ 397  CartVect vertPos[CN::MAX_NODES_PER_ELEMENT]; 398  399  /** \brief Tag being evaluated */ 400  Tag tagHandle; 401  402  /** \brief Whether tag is coordinates or something else */ 403  bool tagCoords; 404  405  /** \brief Number of values in this tag */ 406  int numTuples; 407  408  /** \brief Dimension of entities from which to grab tag */ 409  int taggedEntDim; 410  411  /** \brief Tag space */ 412  std::vector< unsigned char > tagSpace; 413  414  /** \brief Evaluation methods for elements of various topologies */ 415  EvalSet evalSets[MBMAXTYPE]; 416  417  /** \brief Work space for element-specific data */ 418  double* workSpace; 419  420 }; // class ElemEvaluator 421  422 inline ElemEvaluator::ElemEvaluator( Interface* impl, EntityHandle ent, Tag tag, int tagged_ent_dim ) 423  : mbImpl( impl ), entHandle( 0 ), entType( MBMAXTYPE ), entDim( -1 ), numVerts( 0 ), vertHandles( NULL ), 424  tagHandle( 0 ), tagCoords( false ), numTuples( 0 ), taggedEntDim( 0 ), workSpace( NULL ) 425 { 426  if( ent ) set_ent_handle( ent ); 427  if( tag ) set_tag_handle( tag, tagged_ent_dim ); 428 } 429  430 inline ElemEvaluator::~ElemEvaluator() 431 { 432  if( workSpace ) delete[] workSpace; 433 } 434  435 inline ErrorCode ElemEvaluator::set_ent_handle( EntityHandle ent ) 436 { 437  entHandle = ent; 438  if( workSpace ) 439  { 440  delete[] workSpace; 441  workSpace = NULL; 442  } 443  444  entType = mbImpl->type_from_handle( ent ); 445  entDim = mbImpl->dimension_from_handle( ent ); 446  447  std::vector< EntityHandle > dum_vec; 448  ErrorCode rval = mbImpl->get_connectivity( ent, vertHandles, numVerts, false, &dum_vec ); 449  if( MB_SUCCESS != rval ) return rval; 450  451  if( !evalSets[entType].evalFcn ) EvalSet::get_eval_set( entType, numVerts, evalSets[entType] ); 452  453  rval = mbImpl->get_coords( vertHandles, numVerts, vertPos[0].array() ); 454  if( MB_SUCCESS != rval ) return rval; 455  456  if( tagHandle ) 457  { 458  rval = set_tag_handle( tagHandle ); 459  if( MB_SUCCESS != rval ) return rval; 460  } 461  if( evalSets[entType].initFcn ) return ( *evalSets[entType].initFcn )( vertPos[0].array(), numVerts, workSpace ); 462  return MB_SUCCESS; 463 } 464  465 inline ErrorCode ElemEvaluator::set_tag_handle( Tag tag, int tagged_ent_dim ) 466 { 467  ErrorCode rval = MB_SUCCESS; 468  if( !tag && !tagged_ent_dim ) 469  { 470  tagCoords = true; 471  numTuples = 3; 472  taggedEntDim = 0; 473  tagHandle = 0; 474  return rval; 475  } 476  else if( tagHandle != tag ) 477  { 478  tagHandle = tag; 479  rval = mbImpl->tag_get_length( tagHandle, numTuples ); 480  if( MB_SUCCESS != rval ) return rval; 481  int sz; 482  rval = mbImpl->tag_get_bytes( tag, sz ); 483  if( MB_SUCCESS != rval ) return rval; 484  tagSpace.resize( CN::MAX_NODES_PER_ELEMENT * sz ); 485  tagCoords = false; 486  } 487  488  taggedEntDim = ( -1 == tagged_ent_dim ? 0 : tagged_ent_dim ); 489  490  if( entHandle ) 491  { 492  if( 0 == taggedEntDim ) 493  { 494  rval = mbImpl->tag_get_data( tagHandle, vertHandles, numVerts, &tagSpace[0] ); 495  if( MB_SUCCESS != rval ) return rval; 496  } 497  else if( taggedEntDim == entDim ) 498  { 499  rval = mbImpl->tag_get_data( tagHandle, &entHandle, 1, &tagSpace[0] ); 500  if( MB_SUCCESS != rval ) return rval; 501  } 502  } 503  504  return rval; 505 } 506  507 inline ErrorCode ElemEvaluator::set_tag( const char* tag_name, int tagged_ent_dim ) 508 { 509  ErrorCode rval = MB_SUCCESS; 510  if( !tag_name || strlen( tag_name ) == 0 ) return MB_FAILURE; 511  Tag tag; 512  if( !strcmp( tag_name, "COORDS" ) ) 513  { 514  tagCoords = true; 515  taggedEntDim = 0; 516  numTuples = 3; 517  tagHandle = 0; 518  // can return here, because vertex coords already cached when entity handle set 519  return rval; 520  } 521  else 522  { 523  rval = mbImpl->tag_get_handle( tag_name, tag ); 524  if( MB_SUCCESS != rval ) return rval; 525  526  if( tagHandle != tag ) 527  { 528  tagHandle = tag; 529  rval = mbImpl->tag_get_length( tagHandle, numTuples ); 530  if( MB_SUCCESS != rval ) return rval; 531  int sz; 532  rval = mbImpl->tag_get_bytes( tag, sz ); 533  if( MB_SUCCESS != rval ) return rval; 534  tagSpace.reserve( CN::MAX_NODES_PER_ELEMENT * sz ); 535  tagCoords = false; 536  } 537  538  taggedEntDim = ( -1 == tagged_ent_dim ? entDim : tagged_ent_dim ); 539  } 540  541  if( entHandle ) 542  { 543  if( 0 == taggedEntDim ) 544  { 545  rval = mbImpl->tag_get_data( tagHandle, vertHandles, numVerts, &tagSpace[0] ); 546  if( MB_SUCCESS != rval ) return rval; 547  } 548  else if( taggedEntDim == entDim ) 549  { 550  rval = mbImpl->tag_get_data( tagHandle, &entHandle, 1, &tagSpace[0] ); 551  if( MB_SUCCESS != rval ) return rval; 552  } 553  } 554  555  return rval; 556 } 557  558 inline ErrorCode ElemEvaluator::set_eval_set( EntityType tp, const EvalSet& eval_set ) 559 { 560  evalSets[tp] = eval_set; 561  if( entHandle && evalSets[entType].initFcn ) 562  { 563  ErrorCode rval = ( *evalSets[entType].initFcn )( vertPos[0].array(), numVerts, workSpace ); 564  if( MB_SUCCESS != rval ) return rval; 565  } 566  return MB_SUCCESS; 567 } 568  569 inline ErrorCode ElemEvaluator::eval( const double* params, double* result, int num_tuples ) const 570 { 571  assert( entHandle && MBMAXTYPE != entType ); 572  return ( *evalSets[entType].evalFcn )( 573  params, ( tagCoords ? (const double*)vertPos[0].array() : (const double*)&tagSpace[0] ), entDim, 574  ( -1 == num_tuples ? numTuples : num_tuples ), workSpace, result ); 575 } 576  577 inline ErrorCode ElemEvaluator::reverse_eval( const double* posn, 578  const double iter_tol, 579  const double inside_tol, 580  double* params, 581  int* ins ) const 582 { 583  assert( entHandle && MBMAXTYPE != entType ); 584  return ( *evalSets[entType].reverseEvalFcn )( evalSets[entType].evalFcn, evalSets[entType].jacobianFcn, 585  evalSets[entType].insideFcn, posn, vertPos[0].array(), numVerts, 586  entDim, iter_tol, inside_tol, workSpace, params, ins ); 587 } 588  589 /** \brief Evaluate the normal of the cached entity at a given facet */ 590 inline ErrorCode ElemEvaluator::get_normal( const int ientDim, const int facet, double normal[3] ) const 591 { 592  assert( entHandle && MBMAXTYPE != entType ); 593  return ( *evalSets[entType].normalFcn )( ientDim, facet, numVerts, vertPos[0].array(), normal ); 594 } 595  596 /** \brief Evaluate the jacobian of the cached entity at a given parametric location */ 597 inline ErrorCode ElemEvaluator::jacobian( const double* params, double* result ) const 598 { 599  assert( entHandle && MBMAXTYPE != entType ); 600  return ( *evalSets[entType].jacobianFcn )( params, vertPos[0].array(), numVerts, entDim, workSpace, result ); 601 } 602  603 /** \brief Integrate the cached tag over the cached entity */ 604 inline ErrorCode ElemEvaluator::integrate( double* result ) const 605 { 606  assert( entHandle && MBMAXTYPE != entType && ( tagCoords || tagHandle ) ); 607  ErrorCode rval = MB_SUCCESS; 608  if( !tagCoords ) 609  { 610  if( 0 == taggedEntDim ) 611  rval = mbImpl->tag_get_data( tagHandle, vertHandles, numVerts, (void*)&tagSpace[0] ); 612  else 613  rval = mbImpl->tag_get_data( tagHandle, &entHandle, 1, (void*)&tagSpace[0] ); 614  if( MB_SUCCESS != rval ) return rval; 615  } 616  return ( *evalSets[entType].integrateFcn )( ( tagCoords ? vertPos[0].array() : (const double*)&tagSpace[0] ), 617  vertPos[0].array(), numVerts, entDim, numTuples, workSpace, result ); 618 } 619  620 inline ErrorCode ElemEvaluator::find_containing_entity( EntityHandle ent_set, 621  const double* point, 622  const double iter_tol, 623  const double inside_tol, 624  EntityHandle& containing_ent, 625  double* params, 626  unsigned int* num_evals ) 627 { 628  assert( mbImpl->type_from_handle( ent_set ) == MBENTITYSET ); 629  Range entities; 630  ErrorCode rval = mbImpl->get_entities_by_handle( ent_set, entities ); 631  if( MB_SUCCESS != rval ) 632  return rval; 633  else 634  return find_containing_entity( entities, point, iter_tol, inside_tol, containing_ent, params, num_evals ); 635 } 636  637 inline int ElemEvaluator::inside( const double* params, const double tol ) const 638 { 639  return ( *evalSets[entType].insideFcn )( params, entDim, tol ); 640 } 641  642 inline ErrorCode ElemEvaluator::set_eval_set( const EntityHandle eh ) 643 { 644  EvalSet eset; 645  ErrorCode rval = EvalSet::get_eval_set( mbImpl, eh, evalSets[mbImpl->type_from_handle( eh )] ); 646  return rval; 647 } 648  649 } // namespace moab 650  651 #endif /*MOAB_ELEM_EVALUATOR_HPP*/