namespace ParaMEDMEM
{
- OverlapElementLocator::OverlapElementLocator(const ParaFIELD *sourceField, const ParaFIELD *targetField, const ProcessorGroup& group)
+ const int OverlapElementLocator::START_TAG_MESH_XCH = 1140;
+
+ OverlapElementLocator::OverlapElementLocator(const ParaFIELD *sourceField, const ParaFIELD *targetField,
+ const ProcessorGroup& group, double epsAbs)
: _local_source_field(sourceField),
_local_target_field(targetField),
_local_source_mesh(0),
_local_target_mesh(0),
_domain_bounding_boxes(0),
- _group(group)
+ _group(group),
+ _epsAbs(epsAbs)
{
if(_local_source_field)
_local_source_mesh=_local_source_field->getSupport()->getCellMesh();
if(_local_target_field)
_local_target_mesh=_local_target_field->getSupport()->getCellMesh();
_comm=getCommunicator();
- computeBoundingBoxes();
+ computeBoundingBoxesAndTodoList();
}
OverlapElementLocator::~OverlapElementLocator()
return group->getComm();
}
- void OverlapElementLocator::computeBoundingBoxes()
+ void OverlapElementLocator::computeBoundingBoxesAndTodoList()
{
CommInterface comm_interface=_group.getCommInterface();
const MPIProcessorGroup* group=static_cast<const MPIProcessorGroup*> (&_group);
for(int j=0;j<_group.size();j++)
{
if(intersectsBoundingBox(i,j))
+ {
_proc_pairs[i].push_back(j);
+// std::cout << "(" << _group.myRank() << ") PROC pair: " << i << "," << j << std::endl;
+ }
}
-
// OK now let's assigning as balanced as possible, job to each proc of group
- std::vector< std::vector< std::pair<int,int> > > pairsToBeDonePerProc(_group.size());
+ std::vector< std::vector< ProcCouple > > pairsToBeDonePerProc(_group.size());
int i=0;
for(std::vector< std::vector< int > >::const_iterator it1=_proc_pairs.begin();it1!=_proc_pairs.end();it1++,i++)
for(std::vector< int >::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
{
if(pairsToBeDonePerProc[i].size()<=pairsToBeDonePerProc[*it2].size())//it includes the fact that i==*it2
- pairsToBeDonePerProc[i].push_back(std::pair<int,int>(i,*it2));
+ pairsToBeDonePerProc[i].push_back(ProcCouple(i,*it2));
else
- pairsToBeDonePerProc[*it2].push_back(std::pair<int,int>(i,*it2));
+ pairsToBeDonePerProc[*it2].push_back(ProcCouple(i,*it2));
}
//Keeping todo list of current proc. _to_do_list contains a set of pair where at least _group.myRank() appears once.
//This proc will be in charge to perform interpolation of any of element of '_to_do_list'
int myProcId=_group.myRank();
_to_do_list=pairsToBeDonePerProc[myProcId];
- //Feeding now '_procs_to_send'. A same id can appears twice. The second parameter in pair means what to send true=source, false=target
- _procs_to_send.clear();
+// std::stringstream scout;
+// scout << "(" << myProcId << ") my TODO list is: ";
+// for (std::vector< ProcCouple >::const_iterator itdbg=_to_do_list.begin(); itdbg!=_to_do_list.end(); itdbg++)
+// scout << "(" << (*itdbg).first << "," << (*itdbg).second << ")";
+// std::cout << scout.str() << "\n";
+
+ // Feeding now '_procs_to_send*'. A same id can appears twice. The second parameter in pair means what
+ // to send true=source, false=target
+ _procs_to_send_mesh.clear();
+ _procs_to_send_field.clear();
for(int i=_group.size()-1;i>=0;i--)
- if(i!=myProcId)
- {
- const std::vector< std::pair<int,int> >& anRemoteProcToDoList=pairsToBeDonePerProc[i];
- for(std::vector< std::pair<int,int> >::const_iterator it=anRemoteProcToDoList.begin();it!=anRemoteProcToDoList.end();it++)
- {
- if((*it).first==myProcId)
- _procs_to_send.push_back(std::pair<int,bool>(i,true));
- if((*it).second==myProcId)
- _procs_to_send.push_back(std::pair<int,bool>(i,false));
- }
- }
+ {
+ const std::vector< ProcCouple >& anRemoteProcToDoList=pairsToBeDonePerProc[i];
+ for(std::vector< ProcCouple >::const_iterator it=anRemoteProcToDoList.begin();it!=anRemoteProcToDoList.end();it++)
+ {
+ if((*it).first==myProcId)
+ {
+ if(i!=myProcId)
+ _procs_to_send_mesh.push_back(Proc_SrcOrTgt(i,true));
+ _procs_to_send_field.push_back((*it).second);
+ }
+ if((*it).second==myProcId)
+ if(i!=myProcId)
+ _procs_to_send_mesh.push_back(Proc_SrcOrTgt(i,false));
+ }
+ }
}
/*!
{
int myProcId=_group.myRank();
//starting to receive every procs whose id is lower than myProcId.
- std::vector< std::pair<int,int> > toDoListForFetchRemaining;
- for(std::vector< std::pair<int,int> >::const_iterator it=_to_do_list.begin();it!=_to_do_list.end();it++)
+ std::vector< ProcCouple > toDoListForFetchRemaining;
+ for(std::vector< ProcCouple >::const_iterator it=_to_do_list.begin();it!=_to_do_list.end();it++)
{
- if((*it).first!=(*it).second)
+ int first = (*it).first, second = (*it).second;
+ if(first!=second)
{
- if((*it).first==myProcId)
+ if(first==myProcId)
{
- if((*it).second<myProcId)
- receiveRemoteMesh((*it).second,false);
+ if(second<myProcId)
+ receiveRemoteMeshFrom(second,false);
else
- toDoListForFetchRemaining.push_back(std::pair<int,int>((*it).first,(*it).second));
+ toDoListForFetchRemaining.push_back(ProcCouple(first,second));
}
else
{//(*it).second==myProcId
- if((*it).first<myProcId)
- receiveRemoteMesh((*it).first,true);
+ if(first<myProcId)
+ receiveRemoteMeshFrom(first,true);
else
- toDoListForFetchRemaining.push_back(std::pair<int,int>((*it).first,(*it).second));
+ toDoListForFetchRemaining.push_back(ProcCouple(first,second));
}
}
}
//sending source or target mesh to remote procs
- for(std::vector< std::pair<int,bool> >::const_iterator it2=_procs_to_send.begin();it2!=_procs_to_send.end();it2++)
+ for(std::vector< Proc_SrcOrTgt >::const_iterator it2=_procs_to_send_mesh.begin();it2!=_procs_to_send_mesh.end();it2++)
sendLocalMeshTo((*it2).first,(*it2).second,matrix);
//fetching remaining meshes
- for(std::vector< std::pair<int,int> >::const_iterator it=toDoListForFetchRemaining.begin();it!=toDoListForFetchRemaining.end();it++)
+ for(std::vector< ProcCouple >::const_iterator it=toDoListForFetchRemaining.begin();it!=toDoListForFetchRemaining.end();it++)
{
if((*it).first!=(*it).second)
{
if((*it).first==myProcId)
- receiveRemoteMesh((*it).second,false);
+ receiveRemoteMeshFrom((*it).second,false);
else//(*it).second==myProcId
- receiveRemoteMesh((*it).first,true);
+ receiveRemoteMeshFrom((*it).first,true);
}
}
}
int myProcId=_group.myRank();
if(myProcId==procId)
return _local_source_mesh;
- std::pair<int,bool> p(procId,true);
- std::map<std::pair<int,bool>, MEDCouplingAutoRefCountObjectPtr< MEDCouplingPointSet > >::const_iterator it=_remote_meshes.find(p);
+ Proc_SrcOrTgt p(procId,true);
+ std::map<Proc_SrcOrTgt, AutoMCPointSet >::const_iterator it=_remote_meshes.find(p);
return (*it).second;
}
int myProcId=_group.myRank();
if(myProcId==procId)
return 0;
- std::pair<int,bool> p(procId,true);
- std::map<std::pair<int,bool>, MEDCouplingAutoRefCountObjectPtr< DataArrayInt > >::const_iterator it=_remote_elems.find(p);
+ Proc_SrcOrTgt p(procId,true);
+ std::map<Proc_SrcOrTgt, AutoDAInt >::const_iterator it=_remote_elems.find(p);
return (*it).second;
}
int myProcId=_group.myRank();
if(myProcId==procId)
return _local_target_mesh;
- std::pair<int,bool> p(procId,false);
- std::map<std::pair<int,bool>, MEDCouplingAutoRefCountObjectPtr< MEDCouplingPointSet > >::const_iterator it=_remote_meshes.find(p);
+ Proc_SrcOrTgt p(procId,false);
+ std::map<Proc_SrcOrTgt, AutoMCPointSet >::const_iterator it=_remote_meshes.find(p);
return (*it).second;
}
int myProcId=_group.myRank();
if(myProcId==procId)
return 0;
- std::pair<int,bool> p(procId,false);
- std::map<std::pair<int,bool>, MEDCouplingAutoRefCountObjectPtr< DataArrayInt > >::const_iterator it=_remote_elems.find(p);
+ Proc_SrcOrTgt p(procId,false);
+ std::map<Proc_SrcOrTgt, AutoDAInt >::const_iterator it=_remote_elems.find(p);
return (*it).second;
}
+
bool OverlapElementLocator::intersectsBoundingBox(int isource, int itarget) const
{
const double *source_bb=_domain_bounding_boxes+isource*2*2*_local_space_dim;
for (int idim=0; idim < _local_space_dim; idim++)
{
- const double eps = -1e-12;//tony to change
- bool intersects = (target_bb[idim*2]<source_bb[idim*2+1]+eps)
- && (source_bb[idim*2]<target_bb[idim*2+1]+eps);
+ bool intersects = (target_bb[idim*2]<source_bb[idim*2+1]+_epsAbs)
+ && (source_bb[idim*2]<target_bb[idim*2+1]+_epsAbs);
if (!intersects)
return false;
}
}
/*!
- * This methods sends local source if 'sourceOrTarget'==True to proc 'procId'.
- * This methods sends local target if 'sourceOrTarget'==False to proc 'procId'.
+ * This methods sends (part of) local source if 'sourceOrTarget'==True to proc 'procId'.
+ * This methods sends (part of) local target if 'sourceOrTarget'==False to proc 'procId'.
*
* This method prepares the matrix too, for matrix assembling and future matrix-vector computation.
*/
const double *distant_bb=0;
MEDCouplingPointSet *local_mesh=0;
const ParaFIELD *field=0;
- if(sourceOrTarget)//source for local but target for distant
+ if(sourceOrTarget)//source for local mesh but target for distant mesh
{
distant_bb=_domain_bounding_boxes+procId*2*2*_local_space_dim+2*_local_space_dim;
local_mesh=_local_source_mesh;
local_mesh=_local_target_mesh;
field=_local_target_field;
}
- MEDCouplingAutoRefCountObjectPtr<DataArrayInt> elems=local_mesh->getCellsInBoundingBox(distant_bb,getBoundingBoxAdjustment());
- DataArrayInt *idsToSend;
- MEDCouplingPointSet *send_mesh=static_cast<MEDCouplingPointSet *>(field->getField()->buildSubMeshData(elems->begin(),elems->end(),idsToSend));
+ AutoDAInt elems=local_mesh->getCellsInBoundingBox(distant_bb,getBoundingBoxAdjustment());
+ DataArrayInt *old2new_map;
+ MEDCouplingPointSet *send_mesh=static_cast<MEDCouplingPointSet *>(field->getField()->buildSubMeshData(elems->begin(),elems->end(),old2new_map));
if(sourceOrTarget)
- matrix.keepTracksOfSourceIds(procId,idsToSend);//Case#1 in Step2 of main algorithm.
+ matrix.keepTracksOfSourceIds(procId,old2new_map);
else
- matrix.keepTracksOfTargetIds(procId,idsToSend);//Case#0 in Step2 of main algorithm.
- sendMesh(procId,send_mesh,idsToSend);
+ matrix.keepTracksOfTargetIds(procId,old2new_map);
+ sendMesh(procId,send_mesh,old2new_map);
send_mesh->decrRef();
- idsToSend->decrRef();
+ old2new_map->decrRef();
}
/*!
* This method recieves source remote mesh on proc 'procId' if sourceOrTarget==True
* This method recieves target remote mesh on proc 'procId' if sourceOrTarget==False
*/
- void OverlapElementLocator::receiveRemoteMesh(int procId, bool sourceOrTarget)
+ void OverlapElementLocator::receiveRemoteMeshFrom(int procId, bool sourceOrTarget)
{
- DataArrayInt *da=0;
+ DataArrayInt *old2new_map=0;
MEDCouplingPointSet *m=0;
- receiveMesh(procId,m,da);
- std::pair<int,bool> p(procId,sourceOrTarget);
+ receiveMesh(procId,m,old2new_map);
+ Proc_SrcOrTgt p(procId,sourceOrTarget);
_remote_meshes[p]=m;
- _remote_elems[p]=da;
+ _remote_elems[p]=old2new_map;
}
void OverlapElementLocator::sendMesh(int procId, const MEDCouplingPointSet *mesh, const DataArrayInt *idsToSend) const
{
CommInterface comInterface=_group.getCommInterface();
+
// First stage : exchanging sizes
vector<double> tinyInfoLocalD;//tinyInfoLocalD not used for the moment
vector<int> tinyInfoLocal;
int lgth[2];
lgth[0]=tinyInfoLocal.size();
lgth[1]=idsToSend->getNbOfElems();
- comInterface.send(&lgth,2,MPI_INT,procId,1140,*_comm);
- comInterface.send(&tinyInfoLocal[0],tinyInfoLocal.size(),MPI_INT,procId,1141,*comm);
+ comInterface.send(&lgth,2,MPI_INT,procId,START_TAG_MESH_XCH,*_comm);
+ comInterface.send(&tinyInfoLocal[0],tinyInfoLocal.size(),MPI_INT,procId,START_TAG_MESH_XCH+1,*comm);
//
DataArrayInt *v1Local=0;
DataArrayDouble *v2Local=0;
mesh->serialize(v1Local,v2Local);
- comInterface.send(v1Local->getPointer(),v1Local->getNbOfElems(),MPI_INT,procId,1142,*comm);
- comInterface.send(v2Local->getPointer(),v2Local->getNbOfElems(),MPI_DOUBLE,procId,1143,*comm);
+ comInterface.send(v1Local->getPointer(),v1Local->getNbOfElems(),MPI_INT,procId,START_TAG_MESH_XCH+2,*comm);
+ comInterface.send(v2Local->getPointer(),v2Local->getNbOfElems(),MPI_DOUBLE,procId,START_TAG_MESH_XCH+3,*comm);
//finished for mesh, ids now
- comInterface.send(const_cast<int *>(idsToSend->getConstPointer()),lgth[1],MPI_INT,procId,1144,*comm);
+ comInterface.send(const_cast<int *>(idsToSend->getConstPointer()),lgth[1],MPI_INT,procId,START_TAG_MESH_XCH+4,*comm);
//
v1Local->decrRef();
v2Local->decrRef();
MPI_Status status;
const MPI_Comm *comm=getCommunicator();
CommInterface comInterface=_group.getCommInterface();
- comInterface.recv(lgth,2,MPI_INT,procId,1140,*_comm,&status);
+ comInterface.recv(lgth,2,MPI_INT,procId,START_TAG_MESH_XCH,*_comm,&status);
std::vector<int> tinyInfoDistant(lgth[0]);
ids=DataArrayInt::New();
ids->alloc(lgth[1],1);
- comInterface.recv(&tinyInfoDistant[0],lgth[0],MPI_INT,procId,1141,*comm,&status);
+ comInterface.recv(&tinyInfoDistant[0],lgth[0],MPI_INT,procId,START_TAG_MESH_XCH+1,*comm,&status);
mesh=MEDCouplingPointSet::BuildInstanceFromMeshType((MEDCouplingMeshType)tinyInfoDistant[0]);
std::vector<std::string> unusedTinyDistantSts;
vector<double> tinyInfoDistantD(1);//tinyInfoDistantD not used for the moment
DataArrayInt *v1Distant=DataArrayInt::New();
DataArrayDouble *v2Distant=DataArrayDouble::New();
mesh->resizeForUnserialization(tinyInfoDistant,v1Distant,v2Distant,unusedTinyDistantSts);
- comInterface.recv(v1Distant->getPointer(),v1Distant->getNbOfElems(),MPI_INT,procId,1142,*comm,&status);
- comInterface.recv(v2Distant->getPointer(),v2Distant->getNbOfElems(),MPI_DOUBLE,procId,1143,*comm,&status);
+ comInterface.recv(v1Distant->getPointer(),v1Distant->getNbOfElems(),MPI_INT,procId,START_TAG_MESH_XCH+2,*comm,&status);
+ comInterface.recv(v2Distant->getPointer(),v2Distant->getNbOfElems(),MPI_DOUBLE,procId,START_TAG_MESH_XCH+3,*comm,&status);
mesh->unserialization(tinyInfoDistantD,tinyInfoDistant,v1Distant,v2Distant,unusedTinyDistantSts);
//finished for mesh, ids now
comInterface.recv(ids->getPointer(),lgth[1],MPI_INT,procId,1144,*comm,&status);