From 8a9d2aff81a724a5ee2043a90e3e23a85784bd4c Mon Sep 17 00:00:00 2001 From: eap Date: Fri, 8 Jun 2012 10:53:38 +0000 Subject: [PATCH] Make DirectedBoundingBox available at runtime via InterpolationOptions --- src/ParaMEDMEM/ElementLocator.cxx | 150 +++++++++++++++++------------- src/ParaMEDMEM/ElementLocator.hxx | 1 + 2 files changed, 86 insertions(+), 65 deletions(-) diff --git a/src/ParaMEDMEM/ElementLocator.cxx b/src/ParaMEDMEM/ElementLocator.cxx index 8af351d76..13639261a 100644 --- a/src/ParaMEDMEM/ElementLocator.cxx +++ b/src/ParaMEDMEM/ElementLocator.cxx @@ -35,8 +35,6 @@ using namespace std; -//#define USE_DIRECTED_BB - namespace ParaMEDMEM { ElementLocator::ElementLocator(const ParaFIELD& sourceField, @@ -45,11 +43,12 @@ namespace ParaMEDMEM : _local_para_field(sourceField), _local_cell_mesh(sourceField.getSupport()->getCellMesh()), _local_face_mesh(sourceField.getSupport()->getFaceMesh()), + _domain_bounding_boxes(0), _distant_group(distant_group), _local_group(local_group) { _union_group = _local_group.fuse(distant_group); - _computeBoundingBoxes(); + _computeSpaceDim(); //_computeBoundingBoxes(); wait for transfering options _comm=getCommunicator(); } @@ -84,25 +83,32 @@ namespace ParaMEDMEM { int rank = _union_group->translateRank(&_distant_group,idistantrank); + if ( !_domain_bounding_boxes ) + _computeBoundingBoxes(); + if (find(_distant_proc_ids.begin(), _distant_proc_ids.end(),rank)==_distant_proc_ids.end()) return; - + vector elems; -#ifdef USE_DIRECTED_BB - INTERP_KERNEL::DirectedBoundingBox dbb; - double* distant_bb = _domain_bounding_boxes+rank*dbb.dataSize(_local_cell_mesh_space_dim); - dbb.setData(distant_bb); - _local_cell_mesh->getCellsInBoundingBox(dbb,getBoundingBoxAdjustment(),elems); -#else - double* distant_bb = _domain_bounding_boxes+rank*2*_local_cell_mesh_space_dim; - _local_cell_mesh->getCellsInBoundingBox(distant_bb,getBoundingBoxAdjustment(),elems); -#endif - + if ( getUseDirectedBoundingBox() ) + { + INTERP_KERNEL::DirectedBoundingBox dbb; + double* distant_bb = _domain_bounding_boxes+rank*dbb.dataSize(_local_cell_mesh_space_dim); + dbb.setData(distant_bb); + _local_cell_mesh->getCellsInBoundingBox(dbb,getBoundingBoxAdjustment(),elems); + } + else + { + double* distant_bb = _domain_bounding_boxes+rank*2*_local_cell_mesh_space_dim; + _local_cell_mesh->getCellsInBoundingBox(distant_bb,getBoundingBoxAdjustment(),elems); + } + //cout << _local_group.myRank() << "->" << rank << ": Send " << elems.size() << " elems " << endl; + DataArrayInt *distant_ids_send; MEDCouplingPointSet *send_mesh = (MEDCouplingPointSet *)_local_para_field.getField()->buildSubMeshData(&elems[0],&elems[elems.size()],distant_ids_send); _exchangeMesh(send_mesh, distant_mesh, idistantrank, distant_ids_send, distant_ids); distant_ids_send->decrRef(); - + if(send_mesh) send_mesh->decrRef(); } @@ -125,12 +131,7 @@ namespace ParaMEDMEM delete [] recv_buffer; } - - // ====================== - // Compute bounding boxes - // ====================== - - void ElementLocator::_computeBoundingBoxes() + void ElementLocator::_computeSpaceDim() { CommInterface comm_interface =_union_group->getCommInterface(); MPIProcessorGroup* group=static_cast (_union_group); @@ -148,35 +149,53 @@ namespace ParaMEDMEM if(spaceDimForAll[i]!=_local_cell_mesh_space_dim && spaceDimForAll[i]!=-1) throw INTERP_KERNEL::Exception("Spacedim not matches !"); delete [] spaceDimForAll; -#ifdef USE_DIRECTED_BB - INTERP_KERNEL::DirectedBoundingBox dbb; - int bbSize = dbb.dataSize(_local_cell_mesh_space_dim); - _domain_bounding_boxes = new double[bbSize*_union_group->size()]; - if(_local_cell_mesh->getMeshDimension() != -1) - dbb = INTERP_KERNEL::DirectedBoundingBox(_local_cell_mesh->getCoords()->getPointer(), - _local_cell_mesh->getNumberOfNodes(), - _local_cell_mesh_space_dim); - std::vector dbbData = dbb.getData(); - if ( dbbData.size() < bbSize ) dbbData.resize(bbSize,0); - double * minmax= &dbbData[0]; -#else - int bbSize = 2*_local_cell_mesh_space_dim; - _domain_bounding_boxes = new double[bbSize*_union_group->size()]; - double * minmax=new double [bbSize]; - if(_local_cell_mesh->getMeshDimension() != -1) - _local_cell_mesh->getBoundingBox(minmax); + } + + // ====================== + // Compute bounding boxes + // ====================== + + void ElementLocator::_computeBoundingBoxes() + { + double * minmax = 0; + int bbSize; + if ( getUseDirectedBoundingBox() ) + { + INTERP_KERNEL::DirectedBoundingBox dbb; + bbSize = dbb.dataSize(_local_cell_mesh_space_dim); + _domain_bounding_boxes = new double[bbSize*_union_group->size()]; + if(_local_cell_mesh->getMeshDimension() != -1) + dbb = INTERP_KERNEL::DirectedBoundingBox(_local_cell_mesh->getCoords()->getPointer(), + _local_cell_mesh->getNumberOfNodes(), + _local_cell_mesh_space_dim); + std::vector dbbData = dbb.getData(); + if ( dbbData.size() < bbSize ) dbbData.resize(bbSize,0); + minmax=new double [bbSize]; + memcpy( minmax, &dbbData[0], bbSize*sizeof(double)); + } else - for(int i=0;i<_local_cell_mesh_space_dim;i++) - { - minmax[i*2]=-std::numeric_limits::max(); - minmax[i*2+1]=std::numeric_limits::max(); - } -#endif + { + bbSize = 2*_local_cell_mesh_space_dim; + _domain_bounding_boxes = new double[bbSize*_union_group->size()]; + minmax=new double [bbSize]; + if(_local_cell_mesh->getMeshDimension() != -1) + _local_cell_mesh->getBoundingBox(minmax); + else + for(int i=0;i<_local_cell_mesh_space_dim;i++) + { + minmax[i*2]=-std::numeric_limits::max(); + minmax[i*2+1]=std::numeric_limits::max(); + } + } + + CommInterface comm_interface =_union_group->getCommInterface(); + MPIProcessorGroup* group=static_cast (_union_group); + const MPI_Comm* comm = group->getComm(); comm_interface.allGather(minmax, bbSize, MPI_DOUBLE, _domain_bounding_boxes,bbSize, MPI_DOUBLE, *comm); - + for (int i=0; i< _distant_group.size(); i++) { int rank=_union_group->translateRank(&_distant_group,i); @@ -186,10 +205,8 @@ namespace ParaMEDMEM _distant_proc_ids.push_back(rank); } } -#ifdef USE_DIRECTED_BB -#else + delete [] minmax; -#endif } @@ -198,25 +215,28 @@ namespace ParaMEDMEM // ============================================= bool ElementLocator::_intersectsBoundingBox(int irank) { -#ifdef USE_DIRECTED_BB - INTERP_KERNEL::DirectedBoundingBox local_dbb, distant_dbb; - local_dbb.setData( _domain_bounding_boxes+_union_group->myRank()*local_dbb.dataSize( _local_cell_mesh_space_dim )); - distant_dbb.setData( _domain_bounding_boxes+irank*distant_dbb.dataSize( _local_cell_mesh_space_dim )); - return !local_dbb.isDisjointWith( distant_dbb ); -#else - double* local_bb = _domain_bounding_boxes+_union_group->myRank()*2*_local_cell_mesh_space_dim; - double* distant_bb = _domain_bounding_boxes+irank*2*_local_cell_mesh_space_dim; - - for (int idim=0; idim < _local_cell_mesh_space_dim; idim++) + if ( getUseDirectedBoundingBox() ) { - const double eps = 1e-12; - bool intersects = (distant_bb[idim*2]myRank()*local_dbb.dataSize( _local_cell_mesh_space_dim )); + distant_dbb.setData( _domain_bounding_boxes+irank*distant_dbb.dataSize( _local_cell_mesh_space_dim )); + return !local_dbb.isDisjointWith( distant_dbb ); } - return true; -#endif - } + else + { + double* local_bb = _domain_bounding_boxes+_union_group->myRank()*2*_local_cell_mesh_space_dim; + double* distant_bb = _domain_bounding_boxes+irank*2*_local_cell_mesh_space_dim; + + for (int idim=0; idim < _local_cell_mesh_space_dim; idim++) + { + const double eps = 1e-12; + bool intersects = (distant_bb[idim*2]