Back to index

salome-med  6.5.0
Public Member Functions | Private Member Functions | Private Attributes
ParaMEDMEM::OverlapElementLocator Class Reference

#include <OverlapElementLocator.hxx>

Collaboration diagram for ParaMEDMEM::OverlapElementLocator:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 OverlapElementLocator (const ParaFIELD *sourceField, const ParaFIELD *targetField, const ProcessorGroup &group)
virtual ~OverlapElementLocator ()
const MPI_Comm * getCommunicator () const
void exchangeMeshes (OverlapInterpolationMatrix &matrix)
 The aim of this method is to perform the communication to get data corresponding to '_to_do_list' attribute.
std::vector< std::pair< int,
int > > 
getToDoList () const
std::vector< std::vector< int > > getProcsInInteraction () const
std::string getSourceMethod () const
std::string getTargetMethod () const
const MEDCouplingPointSetgetSourceMesh (int procId) const
const DataArrayIntgetSourceIds (int procId) const
const MEDCouplingPointSetgetTargetMesh (int procId) const
const DataArrayIntgetTargetIds (int procId) const

Private Member Functions

void computeBoundingBoxes ()
bool intersectsBoundingBox (int i, int j) const
void sendLocalMeshTo (int procId, bool sourceOrTarget, OverlapInterpolationMatrix &matrix) const
 This methods sends local source if 'sourceOrTarget'==True to proc 'procId'.
void receiveRemoteMesh (int procId, bool sourceOrTarget)
 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 sendMesh (int procId, const MEDCouplingPointSet *mesh, const DataArrayInt *idsToSend) const
void receiveMesh (int procId, MEDCouplingPointSet *&mesh, DataArrayInt *&ids) const

Private Attributes

const ParaFIELD_local_source_field
const ParaFIELD_local_target_field
int _local_space_dim
MEDCouplingPointSet_local_source_mesh
MEDCouplingPointSet_local_target_mesh
std::vector
< MEDCouplingPointSet * > 
_distant_cell_meshes
std::vector
< MEDCouplingPointSet * > 
_distant_face_meshes
std::vector< std::vector< int > > _proc_pairs
 of size _group.size(). Contains for each source proc i, the ids of proc j the targets interact with. This vector is common for all procs in _group.
std::vector< std::pair< int,
int > > 
_to_do_list
 list of interpolations couple to be done
std::vector< std::pair< int,
bool > > 
_procs_to_send
std::map< std::pair< int, bool >
, MEDCouplingAutoRefCountObjectPtr
< MEDCouplingPointSet > > 
_remote_meshes
std::map< std::pair< int, bool >
, MEDCouplingAutoRefCountObjectPtr
< DataArrayInt > > 
_remote_elems
double * _domain_bounding_boxes
const ProcessorGroup_group
std::vector< int > _distant_proc_ids
const MPI_Comm * _comm

Detailed Description

Definition at line 41 of file OverlapElementLocator.hxx.


Constructor & Destructor Documentation

ParaMEDMEM::OverlapElementLocator::OverlapElementLocator ( const ParaFIELD sourceField,
const ParaFIELD targetField,
const ProcessorGroup group 
)

Definition at line 57 of file OverlapElementLocator.cxx.

  {
    delete [] _domain_bounding_boxes;
  }

Member Function Documentation

Definition at line 68 of file OverlapElementLocator.cxx.

  {
    CommInterface comm_interface=_group.getCommInterface();
    const MPIProcessorGroup* group=static_cast<const MPIProcessorGroup*> (&_group);
    _local_space_dim=0;
    if(_local_source_mesh)
      _local_space_dim=_local_source_mesh->getSpaceDimension();
    else
      _local_space_dim=_local_target_mesh->getSpaceDimension();
    //
    const MPI_Comm* comm = group->getComm();
    int bbSize=2*2*_local_space_dim;//2 (for source/target) 2 (min/max)
    _domain_bounding_boxes=new double[bbSize*_group.size()];
    INTERP_KERNEL::AutoPtr<double> minmax=new double[bbSize];
    //Format minmax : Xmin_src,Xmax_src,Ymin_src,Ymax_src,Zmin_src,Zmax_src,Xmin_trg,Xmax_trg,Ymin_trg,Ymax_trg,Zmin_trg,Zmax_trg
    if(_local_source_mesh)
      _local_source_mesh->getBoundingBox(minmax);
    else
      {
        for(int i=0;i<_local_space_dim;i++)
          {
            minmax[i*2]=std::numeric_limits<double>::max();
            minmax[i*2+1]=-std::numeric_limits<double>::max();
          }
      }
    if(_local_target_mesh)
      _local_target_mesh->getBoundingBox(minmax+2*_local_space_dim);
    else
      {
        for(int i=0;i<_local_space_dim;i++)
          {
            minmax[i*2+2*_local_space_dim]=std::numeric_limits<double>::max();
            minmax[i*2+1+2*_local_space_dim]=-std::numeric_limits<double>::max();
          }
      }
    comm_interface.allGather(minmax, bbSize, MPI_DOUBLE,
                             _domain_bounding_boxes,bbSize, MPI_DOUBLE, 
                             *comm);
  
    // Computation of all pairs needing an interpolation pairs are duplicated now !
    
    _proc_pairs.clear();//first is source second is target
    _proc_pairs.resize(_group.size());
    for(int i=0;i<_group.size();i++)
      for(int j=0;j<_group.size();j++)
        {
          if(intersectsBoundingBox(i,j))
            _proc_pairs[i].push_back(j);
        }

    // 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());
    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));
          else
            pairsToBeDonePerProc[*it2].push_back(std::pair<int,int>(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'
    //If _group.myRank()==myPair.first, current proc should fetch target mesh of myPair.second (if different from _group.myRank()).
    //If _group.myRank()==myPair.second, current proc should fetch source mesh of myPair.second.
    
    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();
    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));
            }
        }
  }

Here is the call graph for this function:

Here is the caller graph for this function:

The aim of this method is to perform the communication to get data corresponding to '_to_do_list' attribute.

The principle is the following : if proc n1 and n2 need to perform a cross sending with n1<n2, then n1 will send first and receive then.

Definition at line 157 of file OverlapElementLocator.cxx.

  {
    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++)
      {
        if((*it).first!=(*it).second)
          {
            if((*it).first==myProcId)
              {
                if((*it).second<myProcId)
                  receiveRemoteMesh((*it).second,false);
                else
                  toDoListForFetchRemaining.push_back(std::pair<int,int>((*it).first,(*it).second));
              }
            else
              {//(*it).second==myProcId
                if((*it).first<myProcId)
                  receiveRemoteMesh((*it).first,true);
                else
                  toDoListForFetchRemaining.push_back(std::pair<int,int>((*it).first,(*it).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++)
      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++)
      {
        if((*it).first!=(*it).second)
          {
            if((*it).first==myProcId)
              receiveRemoteMesh((*it).second,false);
            else//(*it).second==myProcId
              receiveRemoteMesh((*it).first,true);
          }
      }
  }

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 62 of file OverlapElementLocator.cxx.

  {
    const MPIProcessorGroup* group=static_cast<const MPIProcessorGroup*>(&_group);
    return group->getComm();
  }

Here is the call graph for this function:

Here is the caller graph for this function:

std::vector< std::vector< int > > ParaMEDMEM::OverlapElementLocator::getProcsInInteraction ( ) const [inline]

Definition at line 49 of file OverlapElementLocator.hxx.

{ return _proc_pairs; }

Here is the caller graph for this function:

Definition at line 218 of file OverlapElementLocator.cxx.

  {
    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);
    return (*it).second;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 208 of file OverlapElementLocator.cxx.

  {
    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);
    return (*it).second;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 198 of file OverlapElementLocator.cxx.

  {
    return _local_source_field->getField()->getDiscretization()->getStringRepr();
  }

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 238 of file OverlapElementLocator.cxx.

  {
    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);
    return (*it).second;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 228 of file OverlapElementLocator.cxx.

  {
    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);
    return (*it).second;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 203 of file OverlapElementLocator.cxx.

  {
    return _local_target_field->getField()->getDiscretization()->getStringRepr();
  }

Here is the call graph for this function:

Here is the caller graph for this function:

std::vector< std::pair<int,int> > ParaMEDMEM::OverlapElementLocator::getToDoList ( ) const [inline]

Definition at line 48 of file OverlapElementLocator.hxx.

{ return _to_do_list; }

Here is the caller graph for this function:

bool ParaMEDMEM::OverlapElementLocator::intersectsBoundingBox ( int  i,
int  j 
) const [private]

Definition at line 248 of file OverlapElementLocator.cxx.

  {
    const double *source_bb=_domain_bounding_boxes+isource*2*2*_local_space_dim;
    const double *target_bb=_domain_bounding_boxes+itarget*2*2*_local_space_dim+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);
        if (!intersects)
          return false; 
      }
    return true;
  }

Here is the caller graph for this function:

void ParaMEDMEM::OverlapElementLocator::receiveMesh ( int  procId,
MEDCouplingPointSet *&  mesh,
DataArrayInt *&  ids 
) const [private]

Definition at line 343 of file OverlapElementLocator.cxx.

  {
    int lgth[2];
    MPI_Status status;
    const MPI_Comm *comm=getCommunicator();
    CommInterface comInterface=_group.getCommInterface();
    comInterface.recv(lgth,2,MPI_INT,procId,1140,*_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);
    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);
    mesh->unserialization(tinyInfoDistantD,tinyInfoDistant,v1Distant,v2Distant,unusedTinyDistantSts);
    //finished for mesh, ids now
    comInterface.recv(ids->getPointer(),lgth[1],MPI_INT,procId,1144,*comm,&status);
    //
    v1Distant->decrRef();
    v2Distant->decrRef();
  }

Here is the call graph for this function:

Here is the caller graph for this function:

void ParaMEDMEM::OverlapElementLocator::receiveRemoteMesh ( int  procId,
bool  sourceOrTarget 
) [private]

This method recieves source remote mesh on proc 'procId' if sourceOrTarget==True This method recieves target remote mesh on proc 'procId' if sourceOrTarget==False.

Definition at line 305 of file OverlapElementLocator.cxx.

  {
    DataArrayInt *da=0;
    MEDCouplingPointSet *m=0;
    receiveMesh(procId,m,da);
    std::pair<int,bool> p(procId,sourceOrTarget);
    _remote_meshes[p]=m;
    _remote_elems[p]=da;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

void ParaMEDMEM::OverlapElementLocator::sendLocalMeshTo ( int  procId,
bool  sourceOrTarget,
OverlapInterpolationMatrix matrix 
) const [private]

This methods sends local source if 'sourceOrTarget'==True to proc 'procId'.

This methods sends local target if 'sourceOrTarget'==False to proc 'procId'.

This method prepares the matrix too, for matrix assembling and future matrix-vector computation.

Definition at line 270 of file OverlapElementLocator.cxx.

  {
   vector<int> elems;
   //int myProcId=_group.myRank();
   const double *distant_bb=0;
   MEDCouplingPointSet *local_mesh=0;
   const ParaFIELD *field=0;
   if(sourceOrTarget)//source for local but target for distant
     {
       distant_bb=_domain_bounding_boxes+procId*2*2*_local_space_dim+2*_local_space_dim;
       local_mesh=_local_source_mesh;
       field=_local_source_field;
     }
   else//target for local but source for distant
     {
       distant_bb=_domain_bounding_boxes+procId*2*2*_local_space_dim;
       local_mesh=_local_target_mesh;
       field=_local_target_field;
     }
   local_mesh->getCellsInBoundingBox(distant_bb,getBoundingBoxAdjustment(),elems);
   DataArrayInt *idsToSend;
   MEDCouplingPointSet *send_mesh=static_cast<MEDCouplingPointSet *>(field->getField()->buildSubMeshData(&elems[0],&elems[elems.size()],idsToSend));
   if(sourceOrTarget)
     matrix.keepTracksOfSourceIds(procId,idsToSend);//Case#1 in Step2 of main algorithm.
   else
     matrix.keepTracksOfTargetIds(procId,idsToSend);//Case#0 in Step2 of main algorithm.
   sendMesh(procId,send_mesh,idsToSend);
   send_mesh->decrRef();
   idsToSend->decrRef();
  }

Here is the call graph for this function:

Here is the caller graph for this function:

void ParaMEDMEM::OverlapElementLocator::sendMesh ( int  procId,
const MEDCouplingPointSet mesh,
const DataArrayInt idsToSend 
) const [private]

Definition at line 315 of file OverlapElementLocator.cxx.

  {
    CommInterface comInterface=_group.getCommInterface();
    // First stage : exchanging sizes
    vector<double> tinyInfoLocalD;//tinyInfoLocalD not used for the moment
    vector<int> tinyInfoLocal;
    vector<string> tinyInfoLocalS;
    mesh->getTinySerializationInformation(tinyInfoLocalD,tinyInfoLocal,tinyInfoLocalS);
    const MPI_Comm *comm=getCommunicator();
    //
    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);
    //
    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);
    //finished for mesh, ids now
    comInterface.send((int *)idsToSend->getConstPointer(),lgth[1],MPI_INT,procId,1144,*comm);
    //
    v1Local->decrRef();
    v2Local->decrRef();
  }

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

const MPI_Comm* ParaMEDMEM::OverlapElementLocator::_comm [private]

Definition at line 81 of file OverlapElementLocator.hxx.

Definition at line 69 of file OverlapElementLocator.hxx.

Definition at line 70 of file OverlapElementLocator.hxx.

Definition at line 80 of file OverlapElementLocator.hxx.

Definition at line 78 of file OverlapElementLocator.hxx.

Definition at line 79 of file OverlapElementLocator.hxx.

Definition at line 64 of file OverlapElementLocator.hxx.

Definition at line 67 of file OverlapElementLocator.hxx.

Definition at line 66 of file OverlapElementLocator.hxx.

Definition at line 65 of file OverlapElementLocator.hxx.

Definition at line 68 of file OverlapElementLocator.hxx.

std::vector< std::vector< int > > ParaMEDMEM::OverlapElementLocator::_proc_pairs [private]

of size _group.size(). Contains for each source proc i, the ids of proc j the targets interact with. This vector is common for all procs in _group.

Definition at line 72 of file OverlapElementLocator.hxx.

std::vector< std::pair<int,bool> > ParaMEDMEM::OverlapElementLocator::_procs_to_send [private]

Definition at line 75 of file OverlapElementLocator.hxx.

Definition at line 77 of file OverlapElementLocator.hxx.

Definition at line 76 of file OverlapElementLocator.hxx.

std::vector< std::pair<int,int> > ParaMEDMEM::OverlapElementLocator::_to_do_list [private]

list of interpolations couple to be done

Definition at line 74 of file OverlapElementLocator.hxx.


The documentation for this class was generated from the following files: