Changeset 1637 for XIOS/trunk/src/node


Ignore:
Timestamp:
01/14/19 13:33:48 (5 years ago)
Author:
oabramkina
Message:

Merging dev to trunk. Major changes:

(1) Grid mask is applied in the source filter of clients: unmasked values are replaced by NaN. It is not reconstructed any more by servers.

(2) Domain/axis mask has been incorporated into data index, with only data index sent to servers.

Location:
XIOS/trunk/src/node
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • XIOS/trunk/src/node/axis.cpp

    r1622 r1637  
    274274   TRY 
    275275   { 
    276       if (this->n_glo.isEmpty()) 
     276     CContext* context=CContext::getCurrent(); 
     277 
     278     if (this->n_glo.isEmpty()) 
    277279        ERROR("CAxis::checkAttributes(void)", 
    278280              << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] " 
     
    314316      } 
    315317 
    316       // Remove this check because it doesn't make sense in case of a hole or overlapping axes 
    317318      if (!this->value.isEmpty()) 
    318319      { 
    319 //        StdSize true_size = value.numElements(); 
    320 //        if (this->n.getValue() != true_size) 
    321 //          ERROR("CAxis::checkAttributes(void)", 
    322 //                << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] " 
    323 //                << "The axis is wrongly defined, attribute 'value' has a different size (" << true_size << ") than the one defined by the \'size\' attribute (" << n.getValue() << ")."); 
     320        // Avoid this check at writing because it fails in case of a hole 
     321        if (context->hasClient) 
     322        { 
     323          StdSize true_size = value.numElements(); 
     324          if (this->n.getValue() != true_size) 
     325            ERROR("CAxis::checkAttributes(void)", 
     326                << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] " 
     327                << "The axis is wrongly defined, attribute 'value' has a different size (" << true_size 
     328                << ") than the one defined by the \'size\' attribute (" << n.getValue() << ")."); 
     329        } 
    324330        this->hasValue = true; 
    325331      } 
     
    327333      this->checkBounds(); 
    328334 
    329       CContext* context=CContext::getCurrent(); 
    330335      if (context->hasClient) 
    331336      { 
     337        this->checkMask(); 
    332338        this->checkData(); 
    333         this->checkMask(); 
    334339        this->checkLabel(); 
    335340      } 
     
    338343 
    339344   /*! 
    340       Check the validity of data and fill in values if any. 
     345      Check the validity of data, fill in values if any, and apply mask. 
    341346   */ 
    342347   void CAxis::checkData() 
     
    359364      { 
    360365        data_index.resize(data_n); 
    361         for (int i = 0; i < data_n; ++i) data_index(i) = i; 
    362       } 
     366        for (int i = 0; i < data_n; ++i) 
     367        { 
     368          if ((i+data_begin) >= 0 && (i+data_begin<n)) 
     369          { 
     370            if (mask(i+data_begin)) 
     371              data_index(i) = i+data_begin; 
     372            else 
     373              data_index(i) = -1; 
     374          } 
     375          else 
     376            data_index(i) = -1; 
     377        } 
     378      } 
     379      else 
     380      { 
     381        if (data_index.numElements() != data_n) 
     382        { 
     383          ERROR("CAxis::checkData(void)", 
     384                << "[ id = " << this->getId() << " , context = '" << CObjectFactory::GetCurrentContextId() << " ] " 
     385                << "The size of data_index = "<< data_index.numElements() << "is not equal to the data size data_n = " << data_n.getValue() << ")."); 
     386        } 
     387        for (int i = 0; i < data_n; ++i) 
     388        { 
     389          if ((i+data_begin) >= 0 && (i+data_begin<n) && !mask(i+data_begin)) 
     390            data_index(i) = -1; 
     391        } 
     392      } 
     393 
    363394   } 
    364395   CATCH_DUMP_ATTR 
     
    377408      if (!mask.isEmpty()) 
    378409      { 
    379          if (mask.extent(0) != n) 
    380            ERROR("CAxis::checkMask(void)", 
    381                  << "[ id = " << this->getId() << " , context = '" << CObjectFactory::GetCurrentContextId() << " ] " 
    382                  << "The mask does not have the same size as the local domain." << std::endl 
    383                  << "Local size is " << n.getValue() << "." << std::endl 
    384                  << "Mask size is " << mask.extent(0) << "."); 
    385       } 
    386       else // (mask.isEmpty()) 
    387       { // If no mask was defined, we create a default one without any masked point. 
    388          mask.resize(n); 
    389          for (int i = 0; i < n; ++i) 
    390          { 
    391            mask(i) = true; 
    392          } 
     410        if (mask.extent(0) != n) 
     411        { 
     412          ERROR("CAxis::checkMask(void)", 
     413              << "[ id = " << this->getId() << " , context = '" << CObjectFactory::GetCurrentContextId() << " ] " 
     414              << "The mask does not have the same size as the local domain." << std::endl 
     415              << "Local size is " << n.getValue() << "." << std::endl 
     416              << "Mask size is " << mask.extent(0) << "."); 
     417        } 
     418      } 
     419      else 
     420      { 
     421        mask.resize(n); 
     422        mask = true; 
    393423      } 
    394424   } 
     
    598628 
    599629        // Calculate the compressed index if any 
    600         std::set<int> writtenInd; 
    601         if (isCompressible_) 
    602         { 
    603           for (int idx = 0; idx < data_index.numElements(); ++idx) 
    604           { 
    605             int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, ni); 
    606  
    607             if (ind >= 0 && ind < ni && mask(ind)) 
    608             { 
    609               ind += ibegin; 
    610               writtenInd.insert(ind); 
    611             } 
    612           } 
    613         } 
     630//        std::set<int> writtenInd; 
     631//        if (isCompressible_) 
     632//        { 
     633//          for (int idx = 0; idx < data_index.numElements(); ++idx) 
     634//          { 
     635//            int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, ni); 
     636// 
     637//            if (ind >= 0 && ind < ni && mask(ind)) 
     638//            { 
     639//              ind += ibegin; 
     640//              writtenInd.insert(ind); 
     641//            } 
     642//          } 
     643//        } 
    614644 
    615645        // Compute the global index of the current client (process) hold 
     
    680710          connectedServerRank_[nbServer].push_back(client->clientRank % client->serverSize); 
    681711 
    682          nbSenders[nbServer] = CClientServerMapping::computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_[nbServer]); 
     712        nbSenders[nbServer] = CClientServerMapping::computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_[nbServer]); 
    683713 
    684714        delete clientServerMap; 
     
    718748    CArray<size_t,1>::const_iterator itSrvb = writtenGlobalIndex.begin(), 
    719749                                     itSrve = writtenGlobalIndex.end(), itSrv;   
     750 
     751    localIndexToWriteOnServer.resize(writtenGlobalIndex.numElements()); 
     752    nbWritten = 0; 
    720753    for (itSrv = itSrvb; itSrv != itSrve; ++itSrv) 
    721754    { 
     
    723756      if (ite != globalLocalIndexMap_.find(indGlo)) 
    724757      { 
    725         ++nbWritten; 
    726       } 
    727     } 
    728  
    729     localIndexToWriteOnServer.resize(writtenGlobalIndex.numElements()); 
    730 //      localIndexToWriteOnServer.resize(nbWritten); 
    731  
    732     nbWritten = 0; 
    733     for (itSrv = itSrvb; itSrv != itSrve; ++itSrv) 
    734     { 
    735       indGlo = *itSrv; 
    736       if (ite != globalLocalIndexMap_.find(indGlo)) 
    737       { 
    738758        localIndexToWriteOnServer(nbWritten) = globalLocalIndexMap_[indGlo]; 
    739         ++nbWritten; 
    740       } 
    741     } 
     759      } 
     760      else 
     761      { 
     762        localIndexToWriteOnServer(nbWritten) = -1; 
     763      } 
     764      ++nbWritten; 
     765    } 
     766 
    742767  } 
    743768  CATCH_DUMP_ATTR 
     
    780805        }                  
    781806      } 
     807// 
     808//      nbWritten = 0; 
     809//      for (int idx = 0; idx < data_index.numElements(); ++idx) 
     810//      { 
     811//        if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_index(idx))) 
     812//        { 
     813//          ++nbWritten; 
     814//        } 
     815//      } 
     816// 
     817//      compressedIndexToWriteOnServer[writtenCommSize].resize(nbWritten); 
     818//      nbWritten = 0; 
     819//      for (int idx = 0; idx < data_index.numElements(); ++idx) 
     820//      { 
     821//        if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_index(idx))) 
     822//        { 
     823//          compressedIndexToWriteOnServer[writtenCommSize](nbWritten) = localGlobalIndexMap[data_index(idx)]; 
     824//          ++nbWritten; 
     825//        } 
     826//      } 
    782827 
    783828      nbWritten = 0; 
     
    10271072 
    10281073  /* 
    1029     Send attributes of axis from a group of client to other group of clients/servers  
    1030     on supposing that these attributes are distributed among the clients of the sending group 
    1031     In the future, if new attributes are added, they should also be processed in this function 
     1074    Send axis attributes from a group of clients to another group of clients/servers 
     1075    supposing that these attributes are distributed among the clients of the sending group 
     1076    In future, if new attributes are added, they should also be processed in this function 
    10321077  */ 
    10331078  void CAxis::sendDistributedAttributes(void) 
    10341079  TRY 
    10351080  { 
    1036     int ns, n, i, j, ind, nv, idx; 
     1081    int ind, idx; 
    10371082    std::list<CContextClient*>::iterator it; 
    10381083 
     
    10461091      list<CMessage> listData; 
    10471092      list<CArray<int,1> > list_indi, list_dataInd; 
    1048       list<CArray<bool,1> > list_mask; 
    10491093      list<CArray<double,1> > list_val; 
    10501094      list<CArray<double,2> > list_bounds; 
    10511095      list<CArray<string,1> > list_label; 
    10521096 
     1097      // Cut off the ghost points 
    10531098      int nbIndex = index.numElements(); 
    10541099      CArray<int,1> dataIndex(nbIndex); 
     
    10571102      { 
    10581103        if (0 <= data_index(idx) && data_index(idx) < nbIndex) 
    1059           dataIndex(idx) = 1; 
     1104          dataIndex(data_index(idx)) = 1; 
    10601105      } 
    10611106 
     
    10641109      for (int k = 0; k < connectedServerRank_[nbServer].size(); ++k) 
    10651110      { 
    1066         int nbData = 0; 
     1111        int nbData = 0, nbDataCount = 0; 
    10671112        int rank = connectedServerRank_[nbServer][k]; 
    10681113        it = indSrv_[nbServer].find(rank); 
     
    10711116 
    10721117        list_indi.push_back(CArray<int,1>(nbData)); 
    1073         list_dataInd.push_back(CArray<int,1>(nbData));         
    1074         list_mask.push_back(CArray<bool,1>(nbData)); 
     1118        list_dataInd.push_back(CArray<int,1>(nbData)); 
    10751119 
    10761120        if (hasValue) 
     
    10841128 
    10851129        CArray<int,1>& indi = list_indi.back(); 
    1086         CArray<int,1>& dataIndi = list_dataInd.back();         
    1087         CArray<bool,1>& maskIndi = list_mask.back(); 
    1088  
    1089         for (n = 0; n < nbData; ++n) 
     1130        CArray<int,1>& dataIndi = list_dataInd.back(); 
     1131        dataIndi = -1; 
     1132 
     1133        for (int n = 0; n < nbData; ++n) 
    10901134        { 
    10911135          idx = static_cast<int>(it->second[n]); 
     
    10941138          ind = globalLocalIndexMap_[idx]; 
    10951139          dataIndi(n) = dataIndex(ind); 
    1096           maskIndi(n) = mask(ind); 
    10971140 
    10981141          if (hasValue) 
     
    11181161        listData.push_back(CMessage()); 
    11191162        listData.back() << this->getId() 
    1120                         << list_indi.back() << list_dataInd.back() << list_mask.back(); 
     1163                        << list_indi.back() << list_dataInd.back(); 
    11211164 
    11221165        listData.back() << hasValue; 
     
    11731216    int nbReceived = ranks.size(), idx, ind, gloInd, locInd; 
    11741217    vector<CArray<int,1> > vec_indi(nbReceived), vec_dataInd(nbReceived); 
    1175     vector<CArray<bool,1> > vec_mask(nbReceived); 
    11761218    vector<CArray<double,1> > vec_val(nbReceived); 
    11771219    vector<CArray<double,2> > vec_bounds(nbReceived); 
     
    11831225      buffer >> vec_indi[idx]; 
    11841226      buffer >> vec_dataInd[idx];       
    1185       buffer >> vec_mask[idx]; 
    11861227 
    11871228      buffer >> hasValue; 
     
    12201261         if (0 == globalLocalIndexMap_.count(gloInd)) 
    12211262         { 
    1222            index(nbIndLoc) = gloInd % n_glo; 
    1223            globalLocalIndexMap_[gloInd] = nbIndLoc; 
     1263           index(nbIndexGlob) = gloInd % n_glo; 
     1264           globalLocalIndexMap_[gloInd] = nbIndexGlob; 
    12241265           ++nbIndexGlob; 
    12251266         }  
     
    12341275    CArray<int,1> nonCompressedData(nbData); 
    12351276    nonCompressedData = -1;    
    1236     mask.resize(nbData); 
     1277    // Mask is incorporated into data_index and is not sent/received anymore 
     1278    mask.resize(0); 
    12371279    if (hasValue) 
    12381280      value.resize(nbData); 
     
    12471289      CArray<int,1>& indi = vec_indi[idx]; 
    12481290      CArray<int,1>& dataIndi = vec_dataInd[idx]; 
    1249       CArray<bool,1>& maskIndi = vec_mask[idx]; 
    12501291      int nb = indi.numElements(); 
    12511292      for (int n = 0; n < nb; ++n) 
     
    12551296        nonCompressedData(locInd) = (-1 == nonCompressedData(locInd)) ? dataIndi(n) : nonCompressedData(locInd); 
    12561297 
    1257         if (!mask(locInd)) // Only rewrite mask if it's not true 
    1258           mask(locInd) = maskIndi(n); 
    1259          
    12601298        if (hasValue) 
    12611299          value(locInd) = vec_val[idx](n); 
     
    12721310    } 
    12731311     
    1274     int nbCompressedData = 0;  
     1312    int nbCompressedData = 0; 
    12751313    for (idx = 0; idx < nonCompressedData.numElements(); ++idx) 
    12761314    { 
    12771315      if (0 <= nonCompressedData(idx)) 
    1278         ++nbCompressedData;         
     1316        ++nbCompressedData; 
    12791317    } 
    12801318 
     
    12861324      { 
    12871325        data_index(nbCompressedData) = idx % n; 
    1288         ++nbCompressedData;         
     1326        ++nbCompressedData; 
    12891327      } 
    12901328    } 
    12911329 
    12921330    data_begin.setValue(0); 
     1331    data_n.setValue(data_index.numElements()); 
    12931332  } 
    12941333  CATCH_DUMP_ATTR 
  • XIOS/trunk/src/node/axis.hpp

    r1562 r1637  
    126126        bool hasLabel; 
    127127 
    128         CArray<size_t,1> localIndexToWriteOnServer;         
     128        CArray<int,1> localIndexToWriteOnServer; 
    129129 
    130130      private: 
  • XIOS/trunk/src/node/domain.cpp

    r1622 r1637  
    179179       // size estimation for sendIndex (and sendArea which is always smaller or equal) 
    180180       size_t sizeIndexEvent = 2 * sizeof(size_t) + 2 * CArray<int,1>::size(idxCount); 
    181        // if (isCompressible_) 
    182        // { 
    183        //   std::map<int, std::vector<int> >::const_iterator itWritten = indWrittenSrv_.find(rank); 
    184        //   size_t writtenIdxCount = (itWritten != itWrittenIndexEnd) ? itWritten->second.size() : 0; 
    185        //   sizeIndexEvent += CArray<int,1>::size(writtenIdxCount); 
    186        // } 
    187181 
    188182       // size estimation for sendLonLat 
     
    11391133   TRY 
    11401134   { 
     1135     int i,j,ind; 
    11411136      if (!data_i_index.isEmpty()) 
    11421137      { 
     
    11591154                   << "'data_j_index' must be defined when 'data_i_index' is set and 'data_dim' is 2."); 
    11601155          } 
     1156          for (int k=0; k<data_i_index.numElements(); ++k) 
     1157          { 
     1158            i = data_i_index(k)+data_ibegin ; 
     1159            j = data_j_index(k)+data_jbegin ; 
     1160            if (i>=0 && i<ni && j>=0 && j<nj) 
     1161            { 
     1162              ind=j*ni+i ; 
     1163              if (!domainMask(ind)) 
     1164              { 
     1165                data_i_index(k) = -1; 
     1166                data_j_index(k) = -1; 
     1167              } 
     1168            } 
     1169            else 
     1170            { 
     1171              data_i_index(k) = -1; 
     1172              data_j_index(k) = -1; 
     1173            } 
     1174          } 
    11611175        } 
    11621176        else // (1 == data_dim) 
     
    11651179          { 
    11661180            data_j_index.resize(data_ni); 
    1167             for (int j = 0; j < data_ni; ++j) data_j_index(j) = 0; 
     1181            data_j_index = 0; 
     1182          } 
     1183          for (int k=0; k<data_i_index.numElements(); ++k) 
     1184          { 
     1185            i=data_i_index(k)+data_ibegin ; 
     1186            if (i>=0 && i < domainMask.size()) 
     1187            { 
     1188              if (!domainMask(i)) data_i_index(k) = -1; 
     1189            } 
     1190            else 
     1191              data_i_index(k) = -1; 
     1192 
     1193            if (!domainMask(i)) data_i_index(k) = -1; 
    11681194          } 
    11691195        } 
     
    11801206          data_i_index.resize(data_ni); 
    11811207          data_j_index.resize(data_ni); 
    1182  
    1183           for (int i = 0; i < data_ni; ++i) 
     1208          data_j_index = 0; 
     1209 
     1210          for (int k = 0; k < data_ni; ++k) 
    11841211          { 
    1185             data_i_index(i) = i; 
    1186             data_j_index(i) = 0; 
     1212            i=k+data_ibegin ; 
     1213            if (i>=0 && i < domainMask.size()) 
     1214            { 
     1215              if (domainMask(i)) 
     1216                data_i_index(k) = k; 
     1217              else 
     1218                data_i_index(k) = -1; 
     1219            } 
     1220            else 
     1221              data_i_index(k) = -1; 
    11871222          } 
    11881223        } 
     
    11931228          data_j_index.resize(dsize); 
    11941229 
    1195           for(int count = 0, j = 0; j < data_nj; ++j) 
     1230          for(int count = 0, kj = 0; kj < data_nj; ++kj) 
    11961231          { 
    1197             for(int i = 0; i < data_ni; ++i, ++count) 
     1232            for(int ki = 0; ki < data_ni; ++ki, ++count) 
    11981233            { 
    1199               data_i_index(count) = i; 
    1200               data_j_index(count) = j; 
     1234              i = ki + data_ibegin; 
     1235              j = kj + data_jbegin; 
     1236              ind=j*ni+i ; 
     1237              if (i>=0 && i<ni && j>=0 && j<nj) 
     1238              { 
     1239                if (domainMask(ind)) 
     1240                { 
     1241                  data_i_index(count) = ki; 
     1242                  data_j_index(count) = kj; 
     1243                } 
     1244                else 
     1245                { 
     1246                  data_i_index(count) = -1; 
     1247                  data_j_index(count) = -1; 
     1248                } 
     1249              } 
     1250              else 
     1251              { 
     1252                data_i_index(count) = -1; 
     1253                data_j_index(count) = -1; 
     1254              } 
    12011255            } 
    12021256          } 
     
    18721926            connectedServerRank_[nbServer].push_back(client->clientRank % client->serverSize); 
    18731927 
     1928          // Now check if all servers have data to receive. If not, master client will send empty data. 
     1929          // This ensures that all servers will participate in collective calls upon receiving even if they have no date to receive. 
     1930          std::vector<int> counts (clientSize); 
     1931          std::vector<int> displs (clientSize); 
     1932          displs[0] = 0; 
     1933          int localCount = connectedServerRank_[nbServer].size() ; 
     1934          MPI_Gather(&localCount, 1, MPI_INT, &counts[0], 1, MPI_INT, 0, client->intraComm) ; 
     1935          for (int i = 0; i < clientSize-1; ++i) 
     1936          { 
     1937            displs[i+1] = displs[i] + counts[i]; 
     1938          } 
     1939          std::vector<int> allConnectedServers(displs[clientSize-1]+counts[clientSize-1]); 
     1940          MPI_Gatherv(&(connectedServerRank_[nbServer])[0], localCount, MPI_INT, &allConnectedServers[0], &counts[0], &displs[0], MPI_INT, 0, client->intraComm); 
     1941 
     1942          if ((allConnectedServers.size() != nbServer) && (rank == 0)) 
     1943          { 
     1944            std::vector<bool> isSrvConnected (nbServer, false); 
     1945            for (int i = 0; i < allConnectedServers.size(); ++i) isSrvConnected[allConnectedServers[i]] = true; 
     1946            for (int i = 0; i < nbServer; ++i) 
     1947            { 
     1948              if (!isSrvConnected[i]) connectedServerRank_[nbServer].push_back(i); 
     1949            } 
     1950          } 
    18741951          nbSenders[nbServer] = clientServerMap->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_[nbServer]); 
    18751952          delete clientServerMap; 
     
    19081985                                       itSrve = writtenGlobalIndex.end(), itSrv; 
    19091986 
    1910 //      for (itSrv = itSrvb; itSrv != itSrve; ++itSrv) 
    1911 //      { 
    1912 //        indGlo = *itSrv; 
    1913 //        if (ite != globalLocalIndexMap_.find(indGlo)) 
    1914 //        { 
    1915 //          ++nbWritten; 
    1916 //        } 
    1917 //      } 
    1918  
    1919 //      localIndexToWriteOnServer.resize(nbWritten); 
    19201987      localIndexToWriteOnServer.resize(writtenGlobalIndex.numElements()); 
    1921  
    19221988      nbWritten = 0; 
    19231989      for (itSrv = itSrvb; itSrv != itSrve; ++itSrv) 
     
    19271993        { 
    19281994          localIndexToWriteOnServer(nbWritten) = globalLocalIndexMap_[indGlo]; 
    1929           ++nbWritten; 
    19301995        } 
    19311996        else 
    19321997        { 
    1933           localIndexToWriteOnServer(nbWritten) = 0; 
    1934           ++nbWritten; 
    1935         } 
    1936       } 
    1937        
    1938       // if (isCompressible()) 
    1939       // { 
    1940       //   nbWritten = 0; 
    1941       //   std::unordered_map<size_t,size_t> localGlobalIndexMap; 
    1942       //   for (itSrv = itSrvb; itSrv != itSrve; ++itSrv) 
    1943       //   { 
    1944       //     indGlo = *itSrv; 
    1945       //     if (ite != globalLocalIndexMap_.find(indGlo)) 
    1946       //     { 
    1947       //       localGlobalIndexMap[localIndexToWriteOnServer(nbWritten)] = indGlo; 
    1948       //       ++nbWritten; 
    1949       //     }                  
    1950       //   } 
    1951  
    1952       //   nbWritten = 0; 
    1953       //   for (int idx = 0; idx < data_i_index.numElements(); ++idx) 
    1954       //   { 
    1955       //     if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_i_index(idx))) 
    1956       //     { 
    1957       //       ++nbWritten; 
    1958       //     } 
    1959       //   } 
    1960  
    1961       //   compressedIndexToWriteOnServer.resize(nbWritten); 
    1962       //   nbWritten = 0; 
    1963       //   for (int idx = 0; idx < data_i_index.numElements(); ++idx) 
    1964       //   { 
    1965       //     if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_i_index(idx))) 
    1966       //     { 
    1967       //       compressedIndexToWriteOnServer(nbWritten) = localGlobalIndexMap[data_i_index(idx)]; 
    1968       //       ++nbWritten; 
    1969       //     } 
    1970       //   } 
    1971  
    1972       //   numberWrittenIndexes_ = nbWritten; 
    1973       //   if (isDistributed()) 
    1974       //   {             
    1975       //     MPI_Allreduce(&numberWrittenIndexes_, &totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 
    1976       //     MPI_Scan(&numberWrittenIndexes_, &offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 
    1977       //     offsetWrittenIndexes_ -= numberWrittenIndexes_; 
    1978       //   } 
    1979       //   else 
    1980       //     totalNumberWrittenIndexes_ = numberWrittenIndexes_; 
    1981       // }       
     1998          localIndexToWriteOnServer(nbWritten) = -1; 
     1999        } 
     2000        ++nbWritten; 
     2001      } 
    19822002   } 
    19832003   CATCH_DUMP_ATTR 
     
    20632083    sendDistributionAttributes(); 
    20642084    sendIndex();        
    2065     sendMask(); 
    20662085    sendLonLat(); 
    20672086    sendArea();     
     
    21742193 
    21752194  /*! 
    2176     Send mask index from client to connected(s) clients     
    2177   */ 
    2178   void CDomain::sendMask() 
    2179   TRY 
    2180   { 
    2181     int ns, n, i, j, ind, nv, idx; 
    2182     std::list<CContextClient*>::iterator it; 
    2183     for (it=clients.begin(); it!=clients.end(); ++it) 
    2184     { 
    2185       CContextClient* client = *it; 
    2186       int serverSize = client->serverSize; 
    2187  
    2188       // send area for each connected server 
    2189       CEventClient eventMask(getType(), EVENT_ID_MASK); 
    2190  
    2191       list<CMessage> list_msgsMask; 
    2192       list<CArray<bool,1> > list_mask; 
    2193  
    2194       std::unordered_map<int, vector<size_t> >::const_iterator it, iteMap; 
    2195       iteMap = indSrv_[serverSize].end(); 
    2196       for (int k = 0; k < connectedServerRank_[serverSize].size(); ++k) 
    2197       { 
    2198         int nbData = 0; 
    2199         int rank = connectedServerRank_[serverSize][k]; 
    2200         it = indSrv_[serverSize].find(rank); 
    2201         if (iteMap != it) 
    2202           nbData = it->second.size(); 
    2203         list_mask.push_back(CArray<bool,1>(nbData)); 
    2204  
    2205         const std::vector<size_t>& temp = it->second; 
    2206         for (n = 0; n < nbData; ++n) 
    2207         { 
    2208           idx = static_cast<int>(it->second[n]); 
    2209           list_mask.back()(n) = domainMask(globalLocalIndexMap_[idx]); 
    2210         } 
    2211  
    2212         list_msgsMask.push_back(CMessage()); 
    2213         list_msgsMask.back() << this->getId() << list_mask.back(); 
    2214         eventMask.push(rank, nbSenders[serverSize][rank], list_msgsMask.back()); 
    2215       } 
    2216       client->sendEvent(eventMask); 
    2217     } 
    2218   } 
    2219   CATCH_DUMP_ATTR 
    2220  
    2221   /*! 
    22222195    Send area from client to connected client(s) 
    22232196  */ 
     
    24582431        case EVENT_ID_INDEX: 
    24592432          recvIndex(event); 
    2460           return true; 
    2461           break; 
    2462         case EVENT_ID_MASK: 
    2463           recvMask(event); 
    24642433          return true; 
    24652434          break; 
     
    25552524           jIndex = (jIndex < 0) ? 0 : jIndex; 
    25562525           nbIndLoc = iIndex + ni * jIndex; 
    2557            if (nbIndLoc < nbIndexGlobMax) 
    2558            { 
    2559              i_index(nbIndLoc) = index % ni_glo; 
    2560              j_index(nbIndLoc) = index / ni_glo; 
    2561              globalLocalIndexMap_[index] = nbIndLoc;   
    2562              ++nbIndGlob; 
    2563            } 
    2564            // i_index(nbIndGlob) = index % ni_glo; 
    2565            // j_index(nbIndGlob) = index / ni_glo; 
    2566            // globalLocalIndexMap_[index] = nbIndGlob;   
    2567            // ++nbIndGlob; 
     2526           i_index(nbIndGlob) = index % ni_glo; 
     2527           j_index(nbIndGlob) = index / ni_glo; 
     2528           globalLocalIndexMap_[index] = nbIndGlob; 
     2529           ++nbIndGlob; 
    25682530         }  
    25692531      }  
     
    25802542      j_index.resizeAndPreserve(nbIndGlob); 
    25812543    } 
     2544 
     2545    domainMask.resize(0); // Mask is not defined anymore on servers 
    25822546  } 
    25832547  CATCH 
     
    26192583 
    26202584  } 
    2621   CATCH_DUMP_ATTR 
    2622  
    2623   /*! 
    2624     Receive area event from clients(s) 
    2625     \param[in] event event contain info about rank and associated area 
    2626   */ 
    2627   void CDomain::recvMask(CEventServer& event) 
    2628   TRY 
    2629   { 
    2630     string domainId; 
    2631     std::map<int, CBufferIn*> rankBuffers; 
    2632  
    2633     list<CEventServer::SSubEvent>::iterator it; 
    2634     for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) 
    2635     {       
    2636       CBufferIn* buffer = it->buffer; 
    2637       *buffer >> domainId; 
    2638       rankBuffers[it->rank] = buffer;      
    2639     } 
    2640     get(domainId)->recvMask(rankBuffers); 
    2641   } 
    2642   CATCH 
    2643  
    2644   /*! 
    2645     Receive mask information from client(s) 
    2646     \param[in] rankBuffers rank of sending client and the corresponding receive buffer   
    2647   */ 
    2648   void CDomain::recvMask(std::map<int, CBufferIn*>& rankBuffers) 
    2649   TRY 
    2650   { 
    2651     int nbReceived = rankBuffers.size(), i, ind, index, lInd; 
    2652     if (nbReceived != recvClientRanks_.size()) 
    2653       ERROR("void CDomain::recvMask(std::map<int, CBufferIn*>& rankBuffers)", 
    2654            << "The number of sending clients is not correct." 
    2655            << "Expected number: " << recvClientRanks_.size() << " but received " << nbReceived); 
    2656  
    2657     vector<CArray<bool,1> > recvMaskValue(nbReceived);       
    2658     for (i = 0; i < recvClientRanks_.size(); ++i) 
    2659     { 
    2660       int rank = recvClientRanks_[i]; 
    2661       CBufferIn& buffer = *(rankBuffers[rank]);       
    2662       buffer >> recvMaskValue[i]; 
    2663     } 
    2664  
    2665     int nbMaskInd = 0; 
    2666     for (i = 0; i < nbReceived; ++i) 
    2667     { 
    2668       nbMaskInd += recvMaskValue[i].numElements(); 
    2669     } 
    2670    
    2671     if (nbMaskInd != globalLocalIndexMap_.size()) 
    2672       info (0) << "If domain " << this->getDomainOutputName() <<" does not have overlapped regions between processes " 
    2673                << "something must be wrong with mask index "<< std::endl; 
    2674  
    2675     nbMaskInd = globalLocalIndexMap_.size(); 
    2676     mask_1d.resize(nbMaskInd); 
    2677     domainMask.resize(nbMaskInd); 
    2678     mask_1d = false; 
    2679      
    2680     for (i = 0; i < nbReceived; ++i) 
    2681     { 
    2682       CArray<int,1>& tmpInd = indGlob_[recvClientRanks_[i]]; 
    2683       CArray<bool,1>& tmp = recvMaskValue[i]; 
    2684       for (ind = 0; ind < tmp.numElements(); ++ind) 
    2685       { 
    2686         lInd = globalLocalIndexMap_[size_t(tmpInd(ind))]; 
    2687         if (!mask_1d(lInd)) // Only rewrite mask_1d if it's not true 
    2688           mask_1d(lInd) = tmp(ind); 
    2689       } 
    2690     } 
    2691     domainMask=mask_1d ; 
    2692   } 
    2693   CATCH_DUMP_ATTR 
    2694  
     2585 CATCH_DUMP_ATTR 
    26952586  /*! 
    26962587    Receive longitude event from clients(s) 
     
    30462937         dataIIndex(lInd) = (-1 == dataIIndex(lInd)) ? tmpI(ind) : dataIIndex(lInd); // Only fill in dataIndex if there is no data 
    30472938         dataJIndex(lInd) = (-1 == dataJIndex(lInd)) ? tmpJ(ind) : dataJIndex(lInd);   
    3048  
    3049          if (!domainMask(lInd))   // Include mask info into data index on the RECEIVE getServerDimensionSizes 
    3050          { 
    3051            dataIIndex(lInd) = dataJIndex(lInd) = -1; 
    3052          } 
    30532939      }  
    30542940    } 
  • XIOS/trunk/src/node/domain.hpp

    r1578 r1637  
    4949         { 
    5050           EVENT_ID_INDEX, EVENT_ID_LON, EVENT_ID_LAT,  
    51            EVENT_ID_AREA, EVENT_ID_MASK, 
     51           EVENT_ID_AREA, 
    5252           EVENT_ID_DATA_INDEX, EVENT_ID_SERVER_ATTRIBUT 
    5353         } ; 
     
    142142         CArray<double, 1> areavalue; 
    143143 
    144          CArray<size_t,1> localIndexToWriteOnServer;          
     144         CArray<int,1> localIndexToWriteOnServer; 
    145145 
    146146         CArray<bool, 1> domainMask; // mask_1d, mask_2d -> domainMask 
     
    175175         void sendIndex(); 
    176176         void sendDistributionAttributes(); 
    177          void sendMask(); 
    178177         void sendArea(); 
    179178         void sendLonLat();          
     
    186185         static void recvDistributionAttributes(CEventServer& event); 
    187186         static void recvIndex(CEventServer& event); 
    188          static void recvMask(CEventServer& event);          
    189187         static void recvLon(CEventServer& event); 
    190188         static void recvLat(CEventServer& event); 
     
    193191         void recvDistributionAttributes(CBufferIn& buffer);                   
    194192         void recvIndex(std::map<int, CBufferIn*>& rankBuffers);          
    195          void recvMask(std::map<int, CBufferIn*>& rankBuffers); 
    196193         void recvLon(std::map<int, CBufferIn*>& rankBuffers); 
    197194         void recvLat(std::map<int, CBufferIn*>& rankBuffers); 
  • XIOS/trunk/src/node/field.cpp

    r1622 r1637  
    11221122     { 
    11231123        if (!instantDataFilter) 
    1124           instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid,true)); 
     1124          instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, false)); 
    11251125 
    11261126 
     
    11381138     { 
    11391139       if (!instantDataFilter) 
    1140          instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true)); 
     1140         instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, false, false)); 
    11411141 
    11421142             // If the field data is to be read by the client or/and written to a file 
     
    11841184         { 
    11851185           checkTimeAttributes(); 
    1186            instantDataFilter = serverSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, freq_offset, true, 
     1186           instantDataFilter = serverSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, false, freq_offset, true, 
    11871187                                                                                                       detectMissingValues, defaultValue)); 
    11881188         } 
     
    11901190         { 
    11911191            if (check_if_active.isEmpty()) check_if_active = false;  
    1192             instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, false, NoneDu, false, 
     1192            instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, false, true, NoneDu, false, 
    11931193                                                                                                        detectMissingValues, defaultValue)); 
    11941194         } 
     
    12751275         { 
    12761276           checkTimeAttributes(); 
    1277            serverSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, freq_offset, true, 
     1277           serverSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, false, freq_offset, true, 
    12781278                                                                                   detectMissingValues, defaultValue)); 
    12791279         } 
     
    12921292         { 
    12931293           if (check_if_active.isEmpty()) check_if_active = false; 
    1294            clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, NoneDu, false, 
     1294           clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, true, NoneDu, false, 
    12951295                                                                                   detectMissingValues, defaultValue)); 
    12961296         } 
     
    18871887   CATCH 
    18881888 
     1889   bool CField::hasGridMask(void) const 
     1890   TRY 
     1891   { 
     1892     return (this->grid->hasMask()); 
     1893   } 
     1894   CATCH 
     1895 
    18891896   DEFINE_REF_FUNC(Field,field) 
    18901897} // namespace xios 
  • XIOS/trunk/src/node/field.hpp

    r1542 r1637  
    209209        bool hasExpression(void) const; 
    210210 
     211        bool hasGridMask(void) const; 
     212 
    211213      public: 
    212214         /// Propriétés privées /// 
  • XIOS/trunk/src/node/grid.cpp

    r1622 r1637  
    364364   } 
    365365   CATCH_DUMP_ATTR 
     366   bool CGrid::hasMask() const 
     367   TRY 
     368   { 
     369     return (!mask_1d.isEmpty() || !mask_2d.isEmpty() || !mask_3d.isEmpty() || 
     370             !mask_4d.isEmpty() || !mask_5d.isEmpty() || !mask_6d.isEmpty() || !mask_7d.isEmpty()); 
     371   } 
     372   CATCH 
    366373 
    367374   /* 
     
    453460   CATCH_DUMP_ATTR 
    454461 
    455 /*! 
    456   A grid can have multiple dimension, so can its mask in the form of multi-dimension array. 
    457 It's not a good idea to store all multi-dimension arrays corresponding to each mask. 
    458 One of the ways is to convert this array into 1-dimension one and every process is taken place on it. 
    459   \param [in] multi-dimension array grid mask 
    460 */ 
    461  
    462   void CGrid::getLocalMask(CArray<bool,1>& localMask) 
    463   TRY 
    464   { 
    465       std::vector<CDomain*> domainP = this->getDomains(); 
    466       std::vector<CAxis*> axisP = this->getAxis(); 
    467       int dim = domainP.size() * 2 + axisP.size(); 
    468  
    469       switch (dim) 
    470       { 
    471         case 0: 
    472           getLocalMask(mask_0d, localMask); 
    473           break; 
    474         case 1: 
    475           getLocalMask(mask_1d, localMask); 
    476           break; 
    477         case 2: 
    478           getLocalMask(mask_2d, localMask); 
    479           break; 
    480         case 3: 
    481           getLocalMask(mask_3d, localMask); 
    482           break; 
    483         case 4: 
    484           getLocalMask(mask_4d, localMask); 
    485           break; 
    486         case 5: 
    487           getLocalMask(mask_5d, localMask); 
    488           break; 
    489         case 6: 
    490           getLocalMask(mask_6d, localMask); 
    491           break; 
    492         case 7: 
    493           getLocalMask(mask_7d, localMask); 
    494           break; 
    495         default: 
    496           break; 
    497       } 
    498   } 
    499   CATCH_DUMP_ATTR 
    500        
    501462   /* 
    502463     Modify value of mask in a certain index 
     
    736697     CContext* context = CContext::getCurrent(); 
    737698 
    738      CContextClient* client = context->client;  // Here it's not important which contextClient to recuperate 
     699     CContextClient* client = context->client; 
    739700     int rank = client->clientRank; 
    740701 
    741702     clientDistribution_ = new CDistributionClient(rank, this); 
    742703     // Get local data index on client 
    743      storeIndex_client.resize(clientDistribution_->getLocalDataIndexOnClient().size()); 
    744      int nbStoreIndex = storeIndex_client.numElements(); 
     704     int nbStoreIndex = clientDistribution_->getLocalDataIndexOnClient().size(); 
     705     int nbStoreGridMask = clientDistribution_->getLocalMaskIndexOnClient().size(); 
     706     // nbStoreGridMask = nbStoreIndex if grid mask is defined, and 0 otherwise 
     707     storeIndex_client.resize(nbStoreIndex); 
     708     storeMask_client.resize(nbStoreGridMask); 
    745709     for (int idx = 0; idx < nbStoreIndex; ++idx) storeIndex_client(idx) = (clientDistribution_->getLocalDataIndexOnClient())[idx]; 
     710     for (int idx = 0; idx < nbStoreGridMask; ++idx) storeMask_client(idx) = (clientDistribution_->getLocalMaskIndexOnClient())[idx]; 
    746711 
    747712     if (0 == serverDistribution_) isDataDistributed_= clientDistribution_->isDataDistributed(); 
     
    884849         if (connectedServerRank_[receiverSize].empty()) 
    885850          connectedServerRank_[receiverSize].push_back(client->clientRank % client->serverSize); 
     851 
     852         // Now check if all servers have data to receive. If not, master client will send empty data. 
     853         // This ensures that all servers will participate in collective calls upon receiving even if they have no date to receive. 
     854         std::vector<int> counts (client->clientSize); 
     855         std::vector<int> displs (client->clientSize); 
     856         displs[0] = 0; 
     857         int localCount = connectedServerRank_[receiverSize].size() ; 
     858         MPI_Gather(&localCount, 1, MPI_INT, &counts[0], 1, MPI_INT, 0, client->intraComm) ; 
     859         for (int i = 0; i < client->clientSize-1; ++i) 
     860         { 
     861           displs[i+1] = displs[i] + counts[i]; 
     862         } 
     863         std::vector<int> allConnectedServers(displs[client->clientSize-1]+counts[client->clientSize-1]); 
     864         MPI_Gatherv(&(connectedServerRank_[receiverSize])[0], localCount, MPI_INT, &allConnectedServers[0], &counts[0], &displs[0], MPI_INT, 0, client->intraComm); 
     865 
     866         if ((allConnectedServers.size() != receiverSize) && (client->clientRank == 0)) 
     867         { 
     868           std::vector<bool> isSrvConnected (receiverSize, false); 
     869           for (int i = 0; i < allConnectedServers.size(); ++i) isSrvConnected[allConnectedServers[i]] = true; 
     870           for (int i = 0; i < receiverSize; ++i) 
     871           { 
     872             if (!isSrvConnected[i]) connectedServerRank_[receiverSize].push_back(i); 
     873           } 
     874         } 
    886875 
    887876         nbSenders[receiverSize] = clientServerMap_->computeConnectedClients(receiverSize, client->clientSize, client->intraComm, connectedServerRank_[receiverSize]); 
     
    13691358   CATCH 
    13701359 
     1360   void CGrid::maskField_arr(const double* const data, CArray<double, 1>& stored) const 
     1361   { 
     1362      const StdSize size = storeIndex_client.numElements(); 
     1363      stored.resize(size); 
     1364      const double nanValue = std::numeric_limits<double>::quiet_NaN(); 
     1365 
     1366      if (storeMask_client.numElements() != 0) 
     1367        for(StdSize i = 0; i < size; i++) stored(i) = (storeMask_client(i)) ? data[storeIndex_client(i)] : nanValue; 
     1368      else 
     1369        for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client(i)]; 
     1370   } 
     1371 
    13711372   void CGrid::uncompressField_arr(const double* const data, CArray<double, 1>& out) const 
    13721373   TRY 
     
    18361837          nGlob.push_back(1);   
    18371838        } 
    1838  
    1839         modifyMaskSize(nSize, false); 
    1840  
    1841         // These below codes are reserved for future 
    1842         CDistributionServer srvDist(server->intraCommRank, nBegin, nSize, nBeginGlobal, nGlob);  
    1843         map<int, CArray<size_t, 1> >::iterator itb = outGlobalIndexFromClient.begin(), 
    1844                                                ite = outGlobalIndexFromClient.end(), it;   
    1845         const CDistributionServer::GlobalLocalMap&  globalLocalMask = srvDist.getGlobalLocalIndex(); 
    1846         CDistributionServer::GlobalLocalMap::const_iterator itSrv; 
    1847         size_t nb = 0; 
    1848         for (it = itb; it != ite; ++it) 
    1849         { 
    1850           CArray<size_t,1>& globalInd = it->second; 
    1851           for (size_t idx = 0; idx < globalInd.numElements(); ++idx) 
    1852           { 
    1853             if (globalLocalMask.end() != globalLocalMask.find(globalInd(idx))) ++nb; 
    1854           } 
    1855         } 
    1856          
    1857         CArray<int,1> indexToModify(nb); 
    1858         nb = 0;     
    1859         for (it = itb; it != ite; ++it) 
    1860         { 
    1861           CArray<size_t,1>& globalInd = it->second; 
    1862           for (size_t idx = 0; idx < globalInd.numElements(); ++idx) 
    1863           { 
    1864             itSrv = globalLocalMask.find(globalInd(idx)); 
    1865             if (globalLocalMask.end() != itSrv)  
    1866             { 
    1867               indexToModify(nb) = itSrv->second; 
    1868               ++nb; 
    1869             } 
    1870           } 
    1871         } 
    1872  
    1873         modifyMask(indexToModify, true); 
    18741839      } 
    18751840 
  • XIOS/trunk/src/node/grid.hpp

    r1622 r1637  
    9494         template <int n> 
    9595         void inputField(const CArray<double,n>& field, CArray<double,1>& stored) const; 
     96         template <int n> 
     97         void maskField(const CArray<double,n>& field, CArray<double,1>& stored) const; 
    9698         template <int n> 
    9799         void outputField(const CArray<double,1>& stored, CArray<double,n>& field) const;   
     
    203205         bool hasTransform(); 
    204206         size_t getGlobalWrittenSize(void) ; 
    205          void getLocalMask(CArray<bool,1>& localMask) ; 
    206          template<int N> 
    207          void getLocalMask(const CArray<bool,N>& gridMask, CArray<bool,1>& localMask) ; 
    208207      public: 
    209208         CArray<int, 1> storeIndex_client; 
     209         CArray<bool, 1> storeMask_client; 
    210210 
    211211/** Map containing indexes that will be sent in sendIndex(). */ 
     
    247247         CArray<size_t,1> indexFromClients; 
    248248 
     249         bool hasMask(void) const; 
    249250         void checkMask(void); 
    250251         void createMask(void); 
     
    273274        void restoreField_arr(const CArray<double, 1>& stored, double* const data) const; 
    274275        void uncompressField_arr(const double* const data, CArray<double, 1>& outData) const; 
     276        void maskField_arr(const double* const data, CArray<double, 1>& stored) const; 
    275277 
    276278        void setVirtualDomainGroup(CDomainGroup* newVDomainGroup); 
     
    387389 
    388390   template <int n> 
     391   void CGrid::maskField(const CArray<double,n>& field, CArray<double,1>& stored) const 
     392   { 
     393//#ifdef __XIOS_DEBUG 
     394      if (this->getDataSize() != field.numElements()) 
     395         ERROR("void CGrid::inputField(const  CArray<double,n>& field, CArray<double,1>& stored) const", 
     396                << "[ Awaiting data of size = " << this->getDataSize() << ", " 
     397                << "Received data size = "      << field.numElements() << " ] " 
     398                << "The data array does not have the right size! " 
     399                << "Grid = " << this->getId()) 
     400//#endif 
     401      this->maskField_arr(field.dataFirst(), stored); 
     402   } 
     403 
     404   template <int n> 
    389405   void CGrid::outputField(const CArray<double,1>& stored, CArray<double,n>& field) const 
    390406   TRY 
     
    424440   TRY 
    425441   { 
    426      if (!gridMask.isEmpty() || createMask) 
    427      { 
    428        int idx = 0; 
    429        int numElement = axisDomainOrder.numElements(); 
    430        int dim = domainMasks.size() * 2 + axisMasks.size(); 
    431        std::vector<CDomain*> domainP = this->getDomains(); 
    432        std::vector<CAxis*> axisP = this->getAxis(); 
    433  
    434        std::vector<int> idxLoop(dim,0), indexMap(numElement), eachDimSize(dim); 
    435        std::vector<int> currentIndex(dim); 
    436        int idxDomain = 0, idxAxis = 0; 
     442     int idx = 0; 
     443     int numElement = axisDomainOrder.numElements(); 
     444     int dim = domainMasks.size() * 2 + axisMasks.size(); 
     445     std::vector<CDomain*> domainP = this->getDomains(); 
     446     std::vector<CAxis*> axisP = this->getAxis(); 
     447 
     448     std::vector<int> idxLoop(dim,0), indexMap(numElement), eachDimSize(dim); 
     449     std::vector<int> currentIndex(dim); 
     450     int idxDomain = 0, idxAxis = 0; 
     451    for (int i = 0; i < numElement; ++i) 
     452    { 
     453      indexMap[i] = idx; 
     454      if (2 == axisDomainOrder(i)) { 
     455          eachDimSize[indexMap[i]]   = domainP[idxDomain]->ni; 
     456          eachDimSize[indexMap[i]+1] = domainP[idxDomain]->nj; 
     457          idx += 2; ++idxDomain; 
     458      } 
     459      else if (1 == axisDomainOrder(i)) { 
     460//        eachDimSize[indexMap[i]] = axisMasks[idxAxis]->numElements(); 
     461        eachDimSize[indexMap[i]] = axisP[idxAxis]->n; 
     462        ++idx; ++idxAxis; 
     463      } 
     464      else {}; 
     465    } 
     466 
     467    if (!gridMask.isEmpty() && !createMask) 
     468    { 
     469      for (int i = 0; i < dim; ++i) 
     470      { 
     471        if (gridMask.extent(i) != eachDimSize[i]) 
     472          ERROR("CGrid::checkMask(void)", 
     473                << "The mask has one dimension whose size is different from the one of the local grid." << std::endl 
     474                << "Local size of dimension " << i << " is " << eachDimSize[i] << "." << std::endl 
     475                << "Mask size for dimension " << i << " is " << gridMask.extent(i) << "." << std::endl 
     476                << "Grid = " << this->getId()) 
     477      } 
     478    } 
     479    else { 
     480        CArrayBoolTraits<CArray<bool,N> >::resizeArray(gridMask,eachDimSize); 
     481        gridMask = true; 
     482    } 
     483 
     484    int ssize = gridMask.numElements(); 
     485    idx = 0; 
     486    while (idx < ssize) 
     487    { 
     488      for (int i = 0; i < dim-1; ++i) 
     489      { 
     490        if (idxLoop[i] == eachDimSize[i]) 
     491        { 
     492          idxLoop[i] = 0; 
     493          ++idxLoop[i+1]; 
     494        } 
     495      } 
     496 
     497      // Find out outer index 
     498      idxDomain = idxAxis = 0; 
     499      bool maskValue = true; 
    437500      for (int i = 0; i < numElement; ++i) 
    438501      { 
    439         indexMap[i] = idx; 
    440         if (2 == axisDomainOrder(i)) { 
    441             eachDimSize[indexMap[i]]   = domainP[idxDomain]->ni; 
    442             eachDimSize[indexMap[i]+1] = domainP[idxDomain]->nj; 
    443             idx += 2; ++idxDomain; 
     502        if (2 == axisDomainOrder(i)) 
     503        { 
     504          int idxTmp = idxLoop[indexMap[i]] + idxLoop[indexMap[i]+1] * eachDimSize[indexMap[i]]; 
     505          if (idxTmp < (*domainMasks[idxDomain]).numElements()) 
     506            maskValue = maskValue && (*domainMasks[idxDomain])(idxTmp); 
     507          else 
     508            maskValue = false; 
     509          ++idxDomain; 
    444510        } 
    445         else if (1 == axisDomainOrder(i)) { 
    446   //        eachDimSize[indexMap[i]] = axisMasks[idxAxis]->numElements(); 
    447           eachDimSize[indexMap[i]] = axisP[idxAxis]->n; 
    448           ++idx; ++idxAxis; 
     511        else if (1 == axisDomainOrder(i)) 
     512        { 
     513          int idxTmp = idxLoop[indexMap[i]]; 
     514          if (idxTmp < (*axisMasks[idxAxis]).numElements()) 
     515            maskValue = maskValue && (*axisMasks[idxAxis])(idxTmp); 
     516          else 
     517            maskValue = false; 
     518 
     519          ++idxAxis; 
    449520        } 
    450         else {}; 
    451       } 
    452  
    453 //      if (!gridMask.isEmpty() && !createMask) 
    454       if (!createMask) 
     521      } 
     522 
     523      int maskIndex = idxLoop[0]; 
     524      int mulDim = 1; 
     525      for (int k = 1; k < dim; ++k) 
    455526      { 
    456         for (int i = 0; i < dim; ++i) 
    457         { 
    458           if (gridMask.extent(i) != eachDimSize[i]) 
    459             ERROR("CGrid::checkMask(void)", 
    460                   << "The mask has one dimension whose size is different from the one of the local grid." << std::endl 
    461                   << "Local size of dimension " << i << " is " << eachDimSize[i] << "." << std::endl 
    462                   << "Mask size for dimension " << i << " is " << gridMask.extent(i) << "." << std::endl 
    463                   << "Grid = " << this->getId()) 
    464         } 
    465       } 
    466       else { 
    467           CArrayBoolTraits<CArray<bool,N> >::resizeArray(gridMask,eachDimSize); 
    468           gridMask = true; 
    469       } 
    470  
    471       int ssize = gridMask.numElements(); 
    472       idx = 0; 
    473       while (idx < ssize) 
    474       { 
    475         for (int i = 0; i < dim-1; ++i) 
    476         { 
    477           if (idxLoop[i] == eachDimSize[i]) 
    478           { 
    479             idxLoop[i] = 0; 
    480             ++idxLoop[i+1]; 
    481           } 
    482         } 
    483  
    484         // Find out outer index 
    485         idxDomain = idxAxis = 0; 
    486         bool maskValue = true; 
    487         for (int i = 0; i < numElement; ++i) 
    488         { 
    489           if (2 == axisDomainOrder(i)) 
    490           { 
    491             int idxTmp = idxLoop[indexMap[i]] + idxLoop[indexMap[i]+1] * eachDimSize[indexMap[i]]; 
    492             if (idxTmp < (*domainMasks[idxDomain]).numElements()) 
    493               maskValue = maskValue && (*domainMasks[idxDomain])(idxTmp); 
    494             else 
    495               maskValue = false; 
    496             ++idxDomain; 
    497           } 
    498           else if (1 == axisDomainOrder(i)) 
    499           { 
    500             int idxTmp = idxLoop[indexMap[i]]; 
    501             if (idxTmp < (*axisMasks[idxAxis]).numElements()) 
    502               maskValue = maskValue && (*axisMasks[idxAxis])(idxTmp); 
    503             else 
    504               maskValue = false; 
    505  
    506             ++idxAxis; 
    507           } 
    508         } 
    509  
    510         int maskIndex = idxLoop[0]; 
    511         int mulDim = 1; 
    512         for (int k = 1; k < dim; ++k) 
    513         { 
    514           mulDim *= eachDimSize[k-1]; 
    515           maskIndex += idxLoop[k]*mulDim; 
    516         } 
    517         *(gridMask.dataFirst()+maskIndex) &= maskValue; 
    518  
    519         ++idxLoop[0]; 
    520         ++idx; 
    521       } 
    522      } 
     527        mulDim *= eachDimSize[k-1]; 
     528        maskIndex += idxLoop[k]*mulDim; 
     529      } 
     530      *(gridMask.dataFirst()+maskIndex) &= maskValue; 
     531 
     532      ++idxLoop[0]; 
     533      ++idx; 
     534    } 
    523535   } 
    524536   CATCH_DUMP_ATTR 
     
    565577   ///-------------------------------------------------------------- 
    566578 
    567   /*! 
    568     A grid can have multiple dimension, so can its mask in the form of multi-dimension array. 
    569   It's not a good idea to store all multi-dimension arrays corresponding to each mask. 
    570   One of the ways is to convert this array into 1-dimension one and every process is taken place on it. 
    571     \param [in] multi-dimension array grid mask 
    572   */ 
    573   template<int N> 
    574   void CGrid::getLocalMask(const CArray<bool,N>& gridMask, CArray<bool,1>& localMask) 
    575   TRY 
    576   { 
    577     if (gridMask.isEmpty()) return ; 
    578     int dim = gridMask.dimensions(); 
    579     std::vector<int> dimensionSizes(dim); 
    580     for (int i = 0; i < dim; ++i) dimensionSizes[i] = gridMask.extent(i); 
    581  
    582     std::vector<int> idxLoop(dim,0); 
    583     int ssize = gridMask.numElements(), idx = 0; 
    584     localMask.resize(ssize); 
    585     while (idx < ssize) 
    586     { 
    587       for (int i = 0; i < dim-1; ++i) 
    588       { 
    589         if (idxLoop[i] == dimensionSizes[i]) 
    590         { 
    591           idxLoop[i] = 0; 
    592           ++idxLoop[i+1]; 
    593         } 
    594       } 
    595  
    596       int maskIndex = idxLoop[0]; 
    597       int mulDim = 1; 
    598       for (int k = 1; k < dim; ++k) 
    599       { 
    600         mulDim *= dimensionSizes[k-1]; 
    601         maskIndex += idxLoop[k]*mulDim; 
    602       } 
    603       localMask(maskIndex) = *(gridMask.dataFirst()+maskIndex); 
    604  
    605       ++idxLoop[0]; 
    606       ++idx; 
    607     } 
    608   } 
    609    CATCH_DUMP_ATTR 
     579 
    610580 
    611581   // Declare/Define CGridGroup and CGridDefinition 
Note: See TracChangeset for help on using the changeset viewer.