MeshKit  1.0
FreeSmoothDomain.cpp
Go to the documentation of this file.
00001 #include "meshkit/ModelEnt.hpp"
00002 #include "meshkit/MKCore.hpp"
00003 #include "moab/Interface.hpp"
00004 #include "FreeSmoothDomain.hpp"
00005 #include "MsqError.hpp"
00006 
00007 namespace MeshKit {
00008 
00009 using namespace moab;
00010 using namespace Mesquite;
00011 
00012 FreeSmoothDomain::FreeSmoothDomain( MKCore* core, const MEntVector& entities )
00013   : MsqCommonIGeom(core->igeom_instance()->instance()),
00014     haveEntGeomRelTag(false),
00015     moabIface(core->moab_instance())
00016 {
00017     // Group input entities and all child entities by dimension.
00018     // This way if a vertex is contained in all entities in which it
00019     // is used rather than just the one that owns it, it will still
00020     // get assigned correctly as long as we work from highest to lowest
00021     // dimension.
00022   MEntVector ents_by_dim[4], tmp_vec;
00023   MEntVector::const_iterator i;
00024   for (i = entities.begin(); i != entities.end(); ++i) {
00025     ModelEnt* ent = *i;
00026     int dim = ent->dimension();
00027     if (dim < 0 || dim > 3)
00028       throw Error(MK_WRONG_DIMENSION, "Entity of invalid dimension %d", dim);
00029     ents_by_dim[dim].push_back(ent);
00030     for (int d = 0; d < dim; ++d) {
00031       tmp_vec.clear();
00032       ent->get_adjacencies( d, tmp_vec );
00033       ents_by_dim[d].insert( ents_by_dim[d].end(), tmp_vec.begin(), tmp_vec.end() );
00034     }
00035   }
00036   
00037     // Create a tag to store geometry handles on mesh entities
00038   assert( sizeof(iBase_EntityHandle) == sizeof(moab::EntityHandle) );
00039   const moab::EntityHandle zero = 0;
00040   moab::ErrorCode rval = moabIface->tag_get_handle( 0, 
00041                                           1,
00042                                           MB_TYPE_HANDLE,
00043                                           entGeomRel,
00044                                           moab::MB_TAG_DENSE|moab::MB_TAG_CREAT,
00045                                           &zero );
00046   MBERRCHK( rval, moabIface );
00047   haveEntGeomRelTag = true;
00048 
00049     // NOTE: We only go up to a dimension of 2 here!
00050     //       Mesquite only cares about surface elements constrained
00051     //       to a surface and vertices constrained to lie on surfaces,
00052     //       curves, or points.
00053   for (int d = 0; d < 3; ++d) {
00054     std::sort( ents_by_dim[d].begin(), ents_by_dim[d].end() );
00055     MEntVector::iterator end = std::unique( ents_by_dim[d].begin(), ents_by_dim[d].end() );
00056     for (i = ents_by_dim[d].begin(); i != end; ++i) {
00057       EntityHandle set = (*i)->mesh_handle();
00058       iBase_EntityHandle geom = (*i)->geom_handle();
00059       if (!geom) 
00060         throw Error(MK_BAD_GEOMETRIC_EVALUATION, "Cannot do free smooth if ModelEnt doesn't have geometry" );
00061       
00062         // assign surface elements
00063       if (d == 2) { 
00064         Range elems;
00065         rval = moabIface->get_entities_by_dimension( set, 2, elems );
00066         MBERRCHK( rval, moabIface );
00067         rval = moabIface->tag_clear_data( entGeomRel, elems, &geom );
00068         MBERRCHK( rval, moabIface );
00069       }
00070       
00071         // assign vertices
00072       Range verts;
00073       rval = moabIface->get_entities_by_dimension( set, 0, verts );
00074       MBERRCHK( rval, moabIface );
00075       rval = moabIface->tag_clear_data( entGeomRel, verts, &geom );
00076       MBERRCHK( rval, moabIface );
00077     }
00078   }
00079 }
00080 
00081 FreeSmoothDomain::~FreeSmoothDomain()
00082 {
00083   if (haveEntGeomRelTag) 
00084     moabIface->tag_delete( entGeomRel );
00085 }
00086 
00087 iBase_EntityHandle FreeSmoothDomain::get_geometry( Mesh::EntityHandle mesh_ent ) const
00088 {
00089   iBase_EntityHandle result;
00090   moab::EntityHandle ent = (moab::EntityHandle)mesh_ent;
00091   moab::ErrorCode rval = moabIface->tag_get_data( entGeomRel, &ent, 1, &result );
00092   MBERRCHK( rval, moabIface );
00093   return result;
00094 }
00095 
00096 void FreeSmoothDomain::get_geometry( const Mesh::EntityHandle* mesh_ents,
00097                                      size_t num_handles,
00098                                      iBase_EntityHandle* geom_ents,
00099                                      MsqError& err ) const
00100 {
00101   const moab::EntityHandle* ents = (const moab::EntityHandle*)mesh_ents;
00102   moab::ErrorCode rval = moabIface->tag_get_data( entGeomRel, ents, num_handles, geom_ents );
00103   if (MB_SUCCESS != rval) {
00104     MSQ_SETERR(err)(MsqError::INTERNAL_ERROR,
00105                     "Error querying MOAB for geom");
00106   }                    
00107 }
00108 
00109 
00110 void FreeSmoothDomain::snap_to( Mesh::VertexHandle handle,
00111                                 Vector3D& coordinate ) const
00112 {
00113   iBase_EntityHandle geom = get_geometry( handle );
00114   if (geom) {
00115     int ierr = move_to( geom, coordinate );
00116     IBERRCHK(ierr, "iGeom evaluation error");
00117   }
00118 }
00119 
00120 void FreeSmoothDomain::vertex_normal_at( Mesh::VertexHandle handle,
00121                                          Vector3D& coordinate ) const
00122 {
00123   iBase_EntityHandle geom = get_geometry( handle );
00124   if (geom) {
00125     int ierr = normal( geom, coordinate );
00126     IBERRCHK(ierr, "iGeom evaluation error");
00127   }
00128 }
00129 
00130 void FreeSmoothDomain::element_normal_at( Mesh::ElementHandle handle,
00131                                      Vector3D& coordinate ) const
00132 {
00133   FreeSmoothDomain::vertex_normal_at( handle, coordinate );
00134 }
00135 
00136 void FreeSmoothDomain::vertex_normal_at( const Mesh::VertexHandle* handle,
00137                                          Vector3D coordinates[],
00138                                          unsigned count,
00139                                          MsqError& err ) const
00140 {
00141   tmpHandles.resize( count );
00142   get_geometry( handle, count, &tmpHandles[0], err );
00143   MSQ_ERRRTN(err);
00144   
00145   int ierr = normal( &tmpHandles[0], coordinates, count );
00146   if (iBase_SUCCESS != ierr)
00147     MSQ_SETERR(err)(MsqError::INTERNAL_ERROR,"Failure to evaluate geometry.  iBase ErrorCode %d\n", ierr);
00148 }
00149 
00150 void FreeSmoothDomain::domain_DoF( const Mesh::VertexHandle* handle_array,
00151                                    unsigned short* dof_array,
00152                                    size_t count,
00153                                    MsqError& err ) const
00154 {
00155   tmpHandles.resize( count );
00156   get_geometry( handle_array, count, &tmpHandles[0], err );
00157   MSQ_ERRRTN(err);
00158 
00159   int ierr, type;
00160   for (size_t i = 0; i < count; ++i) {
00161     if (!tmpHandles[i])
00162       dof_array[i] = 3; // don't have geom handles for volumes
00163     else if (i > 0 && tmpHandles[i-1] == tmpHandles[i])
00164       dof_array[i] = dof_array[i-1];
00165     else {
00166       iGeom_getEntType( geomIFace, tmpHandles[i], &type, &ierr );
00167       dof_array[i] = type;
00168       
00169       if (iBase_SUCCESS != ierr) {
00170         MSQ_SETERR(err)(MsqError::INTERNAL_ERROR,"Failure to evaluate geometry.  iBase ErrorCode %d\n", ierr);
00171         return;
00172       }
00173     }
00174   }
00175 }
00176 
00177 void FreeSmoothDomain::closest_point( Mesh::VertexHandle handle,
00178                                       const Vector3D& position,
00179                                       Vector3D& closest,
00180                                       Vector3D& normal,
00181                                       MsqError& err ) const
00182 {
00183   iBase_EntityHandle geom = get_geometry( handle );
00184   if (geom) {
00185     int ierr = closest_and_normal( geom, position, closest, normal );
00186     if (iBase_SUCCESS != ierr) {
00187       MSQ_SETERR(err)(MsqError::INTERNAL_ERROR,"Failure to evaluate geometry.  iBase ErrorCode %d\n", ierr);
00188     }
00189   }
00190 }
00191 
00192 
00193 } // namespace MeshKit
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines