Logo Search packages:      
Sourcecode: madlib version File versions  Download package

void MAd::F_createInfoInterface ( pMesh  mesh,
pMeshDataId  tagFace 
)

Establish face to face correspondance and assure coherent orientation.

Fill the attached pointer containing the distant proc numbers and the distant face pointers.

Definition at line 1422 of file MeshDataBaseParallelInterface.cc.

References MAd::EN_attachDataPtr(), MAd::EN_deleteData(), MAd::EN_getDataPtr(), MAd::EN_id(), MAd::F_corresponds(), MAd::F_exist(), MAd::F_isPotentialInterface(), MAd::F_numVertices(), MAd::F_vertex(), and MAd::M_faceIter().

Referenced by MAd::M_load().

  {
    
    int nproc  = 1;
    int myrank = 0;
    size_t nbConnections = 0;
    
#ifdef PARALLEL
    MPI_Comm_size(MPI_COMM_WORLD, &nproc);
    MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
#endif

    // --- delete previous information ---

    FIter fit = M_faceIter(mesh);
    while ( pFace pf = FIter_next(fit) ) {
      void * tmp_ptr;
      if( EN_getDataPtr((pEntity) pf, tagFace, &tmp_ptr) ) {
        EN_deleteData((pEntity) pf, tagFace);
      }
    }
    FIter_delete(fit);

    // --- first establish local communication and coherent orientation ---
    //     * coherent reorientation on other partitions assumes coherent orientation here 
    //     * all periodic faces have same connections across partititions
    //       hence subsequent reorientation should remain coherent
    
    
    fit = M_faceIter(mesh);
    while ( pFace pf = FIter_next(fit) ) {
      int distProc = -1;

      std::vector<pVertex> distVt;
      std::vector<face_comm> rd;
      
      if ( F_isPotentialInterface(mesh, pf, rd) ) {
        
        std::vector<face_comm>::iterator rIter = rd.begin();

        std::vector<int> lNodeID;
        for (int i=0;i<F_numVertices(pf);i++) lNodeID.push_back(EN_id((pEntity) F_vertex(pf,i)));
        
        
        for (;rIter!=rd.end();++rIter) {
          
          distProc = rIter->distProc;
          
          if (distProc == myrank) {
            
            face_comm& comm = *rIter;
            
            pVertex p1recv,p2recv,p3recv,p4recv;
            int nbNodes = (comm.p4 == NULL) ? 3:4;

            if (nbNodes != F_numVertices(pf)) {
              std::cout << "Non-coherent number of vertices " << nbNodes << " vs " << F_numVertices(pf) << std::endl;
            }
            
            p1recv = comm.p1;
            p2recv = comm.p2;
            p3recv = comm.p3;
            p4recv = comm.p4;
            
            assert(p1recv);assert(p2recv);assert(p3recv);
            // p4recv = nbNodes == 4 ? comm.p4 : NULL;
            
            pFace remoteFace = F_exist(p1recv,p2recv,p3recv,p4recv);
            
            if (remoteFace) {
            
              // compare ordered lists of nodes 
              
              std::vector<int> rNodeID;
              rNodeID.push_back(EN_id((pEntity) p1recv));
              rNodeID.push_back(EN_id((pEntity) p2recv));
              rNodeID.push_back(EN_id((pEntity) p3recv));
              if (nbNodes == 4) rNodeID.push_back(EN_id((pEntity) p4recv));
              
              // this is ok : only 1 periodic connection possible per face 

              if (rNodeID > lNodeID) {
                lNodeID = rNodeID; 
                F_align(remoteFace,p1recv,p2recv,p3recv,p4recv);
              }
              
              void* tmpptr;
              std::multimap<int,pFace>* list = NULL;
              
              if(EN_getDataPtr((pEntity) pf , tagFace,&tmpptr)){
                list = (std::multimap<int,pFace>*) (tmpptr);
              } else {
                list = new std::multimap<int,pFace>;
                EN_attachDataPtr((pEntity) pf, tagFace, list);
              }
              list->insert(std::make_pair(myrank,remoteFace));
              nbConnections++;
            }
          }
        }
      }
    }
    
#ifdef PARALLEL

    int *sendcounts = new int[nproc];
    for(int i=0;i<nproc;i++)sendcounts[i]=0;

    // --- send faces ---     

    fit = M_faceIter(mesh);
    while ( pFace pf = FIter_next(fit) ) {
      int distProc = -1;
      std::vector<pVertex> distVt;
      
      std::vector<face_comm> rd;
      
      if ( F_isPotentialInterface(mesh, pf, rd) ) {
        
        std::vector<face_comm>::iterator rIter = rd.begin();
        
        for (;rIter!=rd.end();++rIter) {
          
          distProc = rIter->distProc;
          
          if (distProc != myrank) {
            
            void *buf = AP_alloc(distProc,444,sizeof(face_comm));
            face_comm *castbuf = (face_comm *) buf;
            memcpy(buf,&(*rIter),sizeof(face_comm));
            castbuf->distProc = myrank;
            
            AP_send(buf);
            sendcounts[distProc]++;
          }
        }
      }
    }
    FIter_delete(fit);

    // --- synchronise sends --- 

    AP_check_sends(AP_NOFLAGS);
    AP_reduce_nsends(sendcounts);
    //AP_flush();
  
    // --- Receive face info ---
    int message=0, count;
    while (!AP_recv_count(&count) || message<count) {
      void *msg;
      int from;
      int tag;
      int size;
      int rc;
      rc=AP_recv(MPI_ANY_SOURCE,444, AP_BLOCKING|AP_DROPOUT,
                 &msg, &size, &from, &tag);
      if (rc) {
        message++;
        
        face_comm * castbuf = (face_comm*) msg;
        
        pVertex p1recv = castbuf -> p1;
        pVertex p2recv = castbuf -> p2;
        pVertex p3recv = castbuf -> p3;
        pVertex p4recv = castbuf -> p4;

        int id1recv = castbuf->id1;
        int id2recv = castbuf->id2;
        int id3recv = castbuf->id3;
        int id4recv = castbuf->id4;
      
        assert(p1recv);assert(p2recv);assert(p3recv);
        // p4recv = nbNodes == 4 ? castbuf -> p4 : NULL;
      
        int nprocrecv = castbuf->distProc;
        assert(nprocrecv==from);
      
        pFace pface = F_exist(p1recv,p2recv,p3recv,p4recv);
        
        if (pface) {

          if (F_corresponds(pface,id1recv,id2recv,id3recv,id4recv)) {

            // lowest ranking processor is master
            
            void* tmpptr;
            std::multimap<int,pFace>* list = NULL;
            
            if( EN_getDataPtr((pEntity) pface , tagFace,&tmpptr)){
              list = (std::multimap<int,pFace>*) (tmpptr);
              if (from < myrank && from < list->begin()->first) {
                F_align(pface,p1recv,p2recv,p3recv,p4recv);
              }
            } 
            else {
              if (from < myrank) F_align(pface,p1recv,p2recv,p3recv,p4recv);
              list = new std::multimap<int,pFace>;
              EN_attachDataPtr((pEntity) pface, tagFace, list);
            }
            list->insert(std::make_pair(nprocrecv,castbuf->pf));
          }
        }
        AP_free(msg);
      }
    }

    // --- synchronise receives --- 

    AP_check_sends(AP_WAITALL);
    MPI_Barrier(MPI_COMM_WORLD);

    // --- clean ship --- 

    delete [] sendcounts;

#endif
    
    // --- verify !! --- 

    MDB_CommCheck cc;
    exchangeDataOnFaces(mesh,cc);
  }


Generated by  Doxygen 1.6.0   Back to index