Changeset 924 for XIOS/trunk/src/node
- Timestamp:
- 09/02/16 09:41:27 (8 years ago)
- Location:
- XIOS/trunk/src/node
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
XIOS/trunk/src/node/domain.cpp
r911 r924 36 36 , isRedistributed_(false) 37 37 { 38 //mesh = new CMesh(); 39 } 38 } 40 39 41 40 CDomain::CDomain(const StdString & id) … … 47 46 , isRedistributed_(false) 48 47 { 49 //mesh = new CMesh(); 50 } 48 } 51 49 52 50 CDomain::~CDomain(void) 53 51 { 54 //delete mesh;55 52 } 56 53 57 54 ///--------------------------------------------------------------- 58 55 59 void CDomain::assignMesh(const StdString meshName )60 { 61 mesh = CMesh::getMesh(meshName );56 void CDomain::assignMesh(const StdString meshName, const int nvertex) 57 { 58 mesh = CMesh::getMesh(meshName, nvertex); 62 59 } 63 60 … … 1897 1894 1898 1895 buffer >> lon; 1896 1899 1897 if (hasBounds) buffer >> boundslon; 1900 1898 -
XIOS/trunk/src/node/domain.hpp
r893 r924 67 67 68 68 CMesh* mesh; 69 void assignMesh(const StdString );69 void assignMesh(const StdString, const int); 70 70 71 71 virtual void parse(xml::CXMLNode & node); -
XIOS/trunk/src/node/mesh.cpp
r901 r924 11 11 /// ////////////////////// Définitions ////////////////////// /// 12 12 13 CMesh::CMesh(void) : nbFaces{0}, nbNodes{0}, nbEdges{0} 14 , nvertex{0} 13 CMesh::CMesh(void) : nbNodesGlo{0}, nbEdgesGlo{0} 14 , node_start{0}, node_count{0} 15 , edge_start{0}, edge_count{0} 16 , nbFaces{0}, nbNodes{0}, nbEdges{0} 15 17 , nodesAreWritten{false}, edgesAreWritten{false}, facesAreWritten{false} 16 18 , node_lon(), node_lat() … … 18 20 , face_lon(), face_lat() 19 21 , face_nodes() 22 , pNodeGlobalIndex{NULL}, pEdgeGlobalIndex{NULL} 20 23 { 21 24 } … … 24 27 CMesh::~CMesh(void) 25 28 { 29 if (pNodeGlobalIndex != NULL) delete pNodeGlobalIndex; 30 if (pEdgeGlobalIndex != NULL) delete pEdgeGlobalIndex; 26 31 } 27 32 28 33 std::map <StdString, CMesh> CMesh::meshList = std::map <StdString, CMesh>(); 29 //CMesh* CMesh::getMesh;34 std::map <StdString, vector<int> > CMesh::domainList = std::map <StdString, vector<int> >(); 30 35 31 36 ///--------------------------------------------------------------- … … 34 39 * Returns a pointer to a mesh. If a mesh has not been created, creates it and adds its name to the list of meshes meshList. 35 40 * \param [in] meshName The name of a mesh ("name" attribute of a domain). 41 * \param [in] nvertex Number of verteces (1 for nodes, 2 for edges, 3 and up for faces). 36 42 */ 37 CMesh* CMesh::getMesh (StdString meshName )43 CMesh* CMesh::getMesh (StdString meshName, int nvertex) 38 44 { 45 CMesh::domainList[meshName].push_back(nvertex); 46 39 47 if ( CMesh::meshList.begin() != CMesh::meshList.end() ) 40 48 { … … 60 68 61 69 ///---------------------------------------------------------------- 62 int hashPair(int first, int second)70 size_t hashPair(size_t first, size_t second) 63 71 { 64 int seed = first + 0x9e3779b9 ; 65 seed ^= second + 0x9e3779b9 + (seed << 6) + (seed >> 2); 72 HashXIOS<size_t> sizetHash; 73 size_t seed = sizetHash(first) + 0x9e3779b9 ; 74 seed ^= sizetHash(second) + 0x9e3779b9 + (seed << 6) + (seed >> 2); 75 return seed ; 76 } 77 78 ///---------------------------------------------------------------- 79 size_t hashPairOrdered(size_t first, size_t second) 80 { 81 size_t seed; 82 HashXIOS<size_t> sizetHash; 83 if (first < second) 84 { 85 seed = sizetHash(first) + 0x9e3779b9 ; 86 seed ^= sizetHash(second) + 0x9e3779b9 + (seed << 6) + (seed >> 2); 87 } 88 else 89 { 90 seed = sizetHash(second) + 0x9e3779b9 ; 91 seed ^= sizetHash(first) + 0x9e3779b9 + (seed << 6) + (seed >> 2); 92 } 93 return seed ; 94 } 95 96 ///---------------------------------------------------------------- 97 /*! 98 * \fn size_t generateEdgeIndex(size_t first, size_t second, int rank) 99 * Generates an edge index. 100 * If the same edge is generated by two processes, each process will have its own edge index. 101 * \param [in] first Edge node. 102 * \param [in] second Edge node. 103 * \param [in] rank MPI process rank. 104 */ 105 size_t generateEdgeIndex(size_t first, size_t second, int rank) 106 { 107 size_t seed = rank ; 108 if (first < second) 109 { 110 seed = hashPair(seed, first); 111 seed = hashPair(seed, second); 112 } 113 else 114 { 115 seed = hashPair(seed, second); 116 seed = hashPair(seed, first); 117 } 118 119 return seed ; 120 } 121 122 ///---------------------------------------------------------------- 123 /*! 124 * \fn size_t generateNodeIndex(vector<size_t>& valList, int rank) 125 * Generates a node index. 126 * If the same node is generated by two processes, each process will have its own node index. 127 * \param [in] valList Vector storing four node hashes. 128 * \param [in] rank MPI process rank. 129 */ 130 size_t generateNodeIndex(vector<size_t>& valList, int rank) 131 { 132 // Sort is needed to avoid problems for nodes with lon = 0 generated by faces in east and west semisphere 133 vector<size_t> vec = valList; 134 sort (vec.begin(), vec.end()); 135 size_t seed = rank ; 136 int it = 0; 137 for(; it != vec.size(); ++it) 138 { 139 seed = hashPair(seed, vec[it]); 140 } 66 141 return seed ; 67 142 } … … 144 219 ///---------------------------------------------------------------- 145 220 /*! 146 * \fn CArray<size_t,1>& CMesh::createHashes ( double lon, double lat)221 * \fn CArray<size_t,1>& CMesh::createHashes (const double longitude, const double latitude) 147 222 * Creates two hash values for each dimension, longitude and latitude. 148 * \param [in] lon Node longitude in degrees.149 * \param [in] lat Node latitude in degrees ranged from 0 to 360.223 * \param [in] longitude Node longitude in degrees. 224 * \param [in] latitude Node latitude in degrees ranged from 0 to 360. 150 225 */ 151 226 152 vector<size_t> CMesh::createHashes ( double lon, double lat)227 vector<size_t> CMesh::createHashes (const double longitude, const double latitude) 153 228 { 154 229 double minBoundLon = 0. ; 155 230 double maxBoundLon = 360. ; 156 double minBoundLat = -90 ;157 double maxBoundLat = 90 ;231 double minBoundLat = -90. ; 232 double maxBoundLat = 90. ; 158 233 double prec=1e-11 ; 159 234 double precLon=prec ; 160 235 double precLat=prec ; 236 double lon = longitude; 237 double lat = latitude; 238 239 if (lon > (360.- prec)) lon = 0.; 161 240 162 241 size_t maxsize_t=numeric_limits<size_t>::max() ; … … 213 292 return std::pair<int,int>(b,a); 214 293 } 215 216 ///----------------------------------------------------------------217 //#include <random>218 // size_t randNum()219 // {220 // typedef mt19937 rng;221 // size_t max = numeric_limits<size_t>::max();222 // uniform_int_distribution<> distr(0, max);223 // return distr(rng);224 // }225 294 226 295 ///---------------------------------------------------------------- … … 237 306 const CArray<double, 2>& bounds_lon, const CArray<double, 2>& bounds_lat) 238 307 { 239 nvertex = (bounds_lon.numElements() == 0) ? 1 : bounds_lon.rows();308 int nvertex = (bounds_lon.numElements() == 0) ? 1 : bounds_lon.rows(); 240 309 241 310 if (nvertex == 1) … … 357 426 edge_lon(nbEdges) = ( abs( node_lon(face_nodes(nv1,nf)) - node_lon(face_nodes(nv2,nf))) < 180.) ? 358 427 (( node_lon(face_nodes(nv1,nf)) + node_lon(face_nodes(nv2,nf))) * 0.5) : 359 (( node_lon(face_nodes(nv1,nf)) + node_lon(face_nodes(nv2,nf))) * 0.5 -180.); ;428 (( node_lon(face_nodes(nv1,nf)) + node_lon(face_nodes(nv2,nf))) * 0.5 -180.); 360 429 edge_lat(nbEdges) = ( node_lat(face_nodes(nv1,nf)) + node_lat(face_nodes(nv2,nf)) ) * 0.5; 361 430 ++nbEdges; … … 418 487 * Creates or updates a mesh for the three types of mesh elements: nodes, edges, and faces. 419 488 * Precision check is implemented with two hash values for each dimension, longitude and latitude. 489 * \param [in] comm 420 490 * \param [in] lonvalue Array of longitudes. 421 491 * \param [in] latvalue Array of latitudes. … … 423 493 * \param [in] bounds_lat Array of boundary latitudes. Its size depends on the element type. 424 494 */ 425 void CMesh::createMeshEpsilon(const MPI_Comm& comm, const CArray<double, 1>& lonvalue, const CArray<double, 1>& latvalue, 426 const CArray<double, 2>& bounds_lon, const CArray<double, 2>& bounds_lat) 495 void CMesh::createMeshEpsilon(const MPI_Comm& comm, 496 const CArray<double, 1>& lonvalue, const CArray<double, 1>& latvalue, 497 const CArray<double, 2>& bounds_lon, const CArray<double, 2>& bounds_lat) 427 498 { 428 499 429 nvertex = (bounds_lon.numElements() == 0) ? 1 : bounds_lon.rows(); 500 int nvertex = (bounds_lon.numElements() == 0) ? 1 : bounds_lon.rows(); 501 int mpiRank, mpiSize; 502 MPI_Comm_rank(comm, &mpiRank); 503 MPI_Comm_size(comm, &mpiSize); 430 504 431 505 if (nvertex == 1) 432 506 { 433 507 nbNodes = lonvalue.numElements(); 434 435 // CClientClientDHTSizet::Index2VectorInfoTypeMap hash2Idx; // map <hash, idx>436 vector<size_t> hashValues(4); // temporary vector for storing hashes for each node437 vector<size_t> globalIndexes(nbNodes); // Probably a map ?438 CArray<size_t,1> hashList(nbNodes*4); // Do I need it?439 CArray<size_t,1> idxList(nbNodes);440 441 // Assign a unique index for each node represented by four hashes442 // The first hash will serve as the unique index443 size_t randomIdx;444 int rank, size;445 MPI_Comm_rank(comm, &rank);446 MPI_Comm_size(comm, &size);447 srand((unsigned)time(NULL)+rank*size);448 449 for (size_t nn = 0; nn < nbNodes; ++nn)450 {451 hashValues = CMesh::createHashes(lonvalue(nn), latvalue(nn));452 idxList(nn) = hashValues[nn];453 // randomIdx = rand() % numeric_limits<size_t>::max();454 // idxList(nn) = randomIdx;455 // for (size_t nh = 0; nh < 4; ++nh)456 // {457 // hash2Idx[hashValues[nh]].push_back(randomIdx);458 // hashList(nn*4 + nh) = hashValues[nh];459 // }460 }461 462 463 // CClientClientDHTSizet dhtSizet(hash2Idx, comm);464 // dhtSizet.computeIndexInfoMapping(hashList);465 // CClientClientDHTSizet::Index2VectorInfoTypeMap& hashIdxList = dhtSizet.getInfoIndexMap();466 467 // // (2.1) Create a list of indexes for each hush468 // CClientClientDHTSizet dhtSizet(hash2Idx, comm);469 // dhtSizet.computeIndexInfoMapping(hashList);470 // CClientClientDHTSizet::Index2VectorInfoTypeMap& hashIdxList = dhtSizet.getInfoIndexMap();471 //472 // // (2.2) If more than one index assigned to a hush, set the larger value to be equal to the smaller473 // int iidx = 0;474 // for (CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = hashIdxList.begin(); it != hashIdxList.end(); ++it, ++iidx)475 // {476 // vector<size_t> tmp = it->second;477 // size_t idxMinValue = it->second[0];478 // for (int i = 1; i < it->second.size(); ++i)479 // {480 // if (it->second[i] < idxMinValue )481 // idxMinValue = it->second[i];482 // }483 // if ( (iidx % 4) == 0 )484 // idxList(iidx/4) = idxMinValue;485 // }486 487 // Unique global indexing488 // CDHTAutoIndexing dhtSizetIdx = CDHTAutoIndexing(idxList, comm);489 // CClientClientDHTSizet* pDhtSizet = &dhtSizetIdx;490 // pDhtSizet->computeIndexInfoMapping(idxList);491 492 //globalIndexes = dhtSizetIdx.getGlobalIndex();493 494 508 node_lon.resize(nbNodes); 495 509 node_lat.resize(nbNodes); … … 497 511 node_lat = latvalue; 498 512 513 // Global node indexes 514 vector<size_t> hashValues(4); 515 CClientClientDHTSizet::Index2VectorInfoTypeMap nodeHash2IdxGlo; 516 for (size_t nn = 0; nn < nbNodes; ++nn) 517 { 518 hashValues = CMesh::createHashes(lonvalue(nn), latvalue(nn)); 519 for (size_t nh = 0; nh < 4; ++nh) 520 { 521 nodeHash2IdxGlo[hashValues[nh]].push_back(mpiRank*nbNodes + nn); 522 } 523 } 524 pNodeGlobalIndex = new CClientClientDHTSizet (nodeHash2IdxGlo, comm); 499 525 nodesAreWritten = true; 500 501 526 } 502 527 … … 504 529 { 505 530 nbEdges = bounds_lon.shape()[1]; 506 507 vector<size_t> hashValues(4); 508 for (int ne = 0; ne < nbEdges; ++ne) 531 edge_lon.resize(nbEdges); 532 edge_lat.resize(nbEdges); 533 edge_lon = lonvalue; 534 edge_lat = latvalue; 535 edge_nodes.resize(nvertex, nbEdges); 536 CClientClientDHTSizet::Index2VectorInfoTypeMap edgeHash2IdxGlo; 537 CClientClientDHTSizet::Index2VectorInfoTypeMap edgeHash2Idx; 538 539 // Case (1): node indexes have been generated by domain "nodes" 540 if (nodesAreWritten) 509 541 { 510 for (int nv = 0; nv < nvertex; ++nv) 511 { 512 hashValues = CMesh::createHashes(bounds_lon(nv, ne), bounds_lat(nv, ne)); 513 // for (size_t nh = 0; nh < 4; ++nh) 514 // { 515 // hash2Idx[hashValues[nh]].push_back(randomIdx); 516 // hashList(nn*4 + nh) = hashValues[nh]; 517 // } 518 519 542 vector<size_t> hashValues(4); 543 CArray<size_t,1> nodeHashList(nbEdges*nvertex*4); 544 for (int ne = 0; ne < nbEdges; ++ne) // size_t doesn't work with CArray<double, 2> 545 { 546 for (int nv = 0; nv < nvertex; ++nv) 547 { 548 hashValues = CMesh::createHashes(bounds_lon(nv, ne), bounds_lat(nv, ne)); 549 for (int nh = 0; nh < 4; ++nh) 550 { 551 nodeHashList((ne*nvertex + nv)*4 + nh) = hashValues[nh]; 552 } 553 } 554 } 555 556 // Recuperating the node global indexing and writing edge_nodes 557 // Creating map edgeHash2IdxGlo <hash, idxGlo> 558 pNodeGlobalIndex->computeIndexInfoMapping(nodeHashList); 559 CClientClientDHTSizet::Index2VectorInfoTypeMap& nodeHash2IdxGlo = pNodeGlobalIndex->getInfoIndexMap(); 560 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it; 561 vector <size_t> edgeNodes; 562 for (int ne = 0; ne < nbEdges; ++ne) 563 { 564 for (int nv = 0; nv < nvertex; ++nv) 565 { 566 int nh = 0; 567 it = nodeHash2IdxGlo.find(nodeHashList((ne*nvertex + nv)*4 + nh)); 568 // The loop below is needed in case if a hash generated by domain "edges" differs 569 // from that generated by domain "nodes" because of possible precision issues 570 while (it == nodeHash2IdxGlo.end()) 571 { 572 ++nh; 573 it = nodeHash2IdxGlo.find(nodeHashList((ne*nvertex + nv)*4 + nh)); 574 } 575 edge_nodes(nv,ne) = it->second[0]; 576 edgeNodes.push_back(it->second[0]); 577 } 578 edgeHash2IdxGlo[ hashPairOrdered(edgeNodes[0], edgeNodes[1]) ].push_back(nbEdges*mpiRank + ne); 579 } 580 } // nodesAreWritten 581 582 // Case (2): node indexes have not been generated previously 583 else 584 { 585 // (2.1) Creating a list of hashes for each node and a map nodeHash2Idx <hash, <idx,rank> > 586 vector<size_t> hashValues(4); 587 CClientClientDHTSizet::Index2VectorInfoTypeMap nodeHash2Idx; 588 CArray<size_t,1> nodeHashList(nbEdges*nvertex*4); 589 for (int ne = 0; ne < nbEdges; ++ne) 590 { 591 for (int nv = 0; nv < nvertex; ++nv) 592 { 593 hashValues = CMesh::createHashes(bounds_lon(nv, ne), bounds_lat(nv, ne)); 594 for (int nh = 0; nh < 4; ++nh) 595 { 596 if (nodeHash2Idx[hashValues[nh]].size() == 0) 597 { 598 nodeHash2Idx[hashValues[nh]].push_back(generateNodeIndex(hashValues, mpiRank)); 599 nodeHash2Idx[hashValues[nh]].push_back(mpiRank); 600 } 601 nodeHashList((ne*nvertex + nv)*4 + nh) = hashValues[nh]; 602 } 603 } 604 } 605 606 // (2.2) Generating global node indexes 607 // The ownership criterion: priority of the process holding the smaller index 608 // Maps generated in this step are: 609 // nodeHash2Info = <hash, [[idx1, rank1], [idx2, rank2], [idx3, rank3]..]> 610 // nodeIdx2IdxMin = <idx, idxMin> 611 // nodeIdx2IdxGlo = <idxMin, idxMin> 612 613 CClientClientDHTSizet::Index2VectorInfoTypeMap nodeIdx2IdxMin; 614 CClientClientDHTSizet::Index2VectorInfoTypeMap nodeIdx2IdxGlo; 615 CArray<size_t,1> nodeIdxMinList(nbEdges*nvertex); 616 617 CClientClientDHTSizet dhtNodeHash(nodeHash2Idx, comm); 618 dhtNodeHash.computeIndexInfoMapping(nodeHashList); 619 CClientClientDHTSizet::Index2VectorInfoTypeMap& nodeHash2Info = dhtNodeHash.getInfoIndexMap(); 620 size_t iIdxMin = 0; 621 622 for (CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = nodeHash2Info.begin(); it != nodeHash2Info.end(); ++it) 623 { 624 size_t idx = (it->second)[0]; 625 size_t idxMin = (it->second)[0]; 626 for (int i = 2; i < (it->second).size();) 627 { 628 if (mpiRank == (it->second)[i+1]) 629 { 630 idx = (it->second)[i]; 631 } 632 if ((it->second)[i] < idxMin) 633 { 634 idxMin = (it->second)[i]; 635 (it->second)[i] = (it->second)[i-2]; 636 } 637 i += 2; 638 } 639 (it->second)[0] = idxMin; 640 if (nodeIdx2IdxMin.count(idx) == 0) 641 { 642 nodeIdx2IdxMin[idx].push_back(idxMin); 643 if (idx == idxMin) 644 nodeIdx2IdxGlo[idxMin].push_back(idxMin); 645 nodeIdxMinList(iIdxMin) = idxMin; 646 ++iIdxMin; 647 } 648 } 649 nodeIdxMinList.resizeAndPreserve(iIdxMin); 650 CDHTAutoIndexing dhtNodeIdxGlo = CDHTAutoIndexing(nodeIdx2IdxGlo, comm); 651 CClientClientDHTSizet dhtNodeIdx(nodeIdx2IdxGlo, comm); 652 dhtNodeIdx.computeIndexInfoMapping(nodeIdxMinList); 653 CClientClientDHTSizet::Index2VectorInfoTypeMap& nodeIdxMin2IdxGlo = dhtNodeIdx.getInfoIndexMap(); 654 // nodeIdx2IdxGlo holds global indexes only for nodes owned by a process 655 // nodeIdxMin2IdxGlo holds global indexes for all nodes generated by a process 656 657 // (2.3) Saving variables: node_lon, node_lat, edge_nodes 658 // Creating map nodeHash2IdxGlo <hash, idxGlo> 659 // Creating map edgeHash2IdxGlo <hash, idxGlo> 660 nbNodesGlo = dhtNodeIdxGlo.getNbIndexesGlobal(); 661 node_count = dhtNodeIdxGlo.getIndexCount(); 662 node_start = dhtNodeIdxGlo.getIndexStart(); 663 CClientClientDHTSizet::Index2VectorInfoTypeMap nodeHash2IdxGlo; 664 node_lon.resize(node_count); 665 node_lat.resize(node_count); 666 vector <size_t> edgeNodes; 667 size_t idxGlo = 0; 668 669 for (int ne = 0; ne < nbEdges; ++ne) 670 { 671 for (int nv = 0; nv < nvertex; ++nv) 672 { 673 hashValues = CMesh::createHashes(bounds_lon(nv, ne), bounds_lat(nv, ne)); 674 size_t myIdx = generateNodeIndex(hashValues, mpiRank); 675 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx = nodeIdx2IdxMin.find(myIdx); 676 size_t ownerIdx = (itIdx->second)[0]; 677 678 if (myIdx == ownerIdx) 679 { 680 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = nodeIdx2IdxGlo.find(myIdx); 681 idxGlo = (itIdxGlo->second)[0]; 682 // node_lon(idxGlo - node_start) = (bounds_lon(nv, ne) == 360.) ? (0.) : (bounds_lon(nv, ne)); 683 node_lon(idxGlo - node_start) = bounds_lon(nv, ne); 684 node_lat(idxGlo - node_start) = bounds_lat(nv, ne); 685 } 686 else 687 { 688 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = nodeIdxMin2IdxGlo.find(ownerIdx); 689 idxGlo = (itIdxGlo->second)[0]; 690 } 691 692 edge_nodes(nv,ne) = idxGlo; 693 for (int nh = 0; nh < 4; ++nh) 694 nodeHash2IdxGlo[hashValues[nh]].push_back(idxGlo); 695 edgeNodes.push_back(idxGlo); 696 } 697 edgeHash2IdxGlo[ hashPairOrdered(edgeNodes[0], edgeNodes[1]) ].push_back(nbEdges*mpiRank + ne); 698 edgeNodes.clear(); 699 } 700 pNodeGlobalIndex = new CClientClientDHTSizet (nodeHash2IdxGlo, comm); 701 } // !nodesAreWritten 702 703 pEdgeGlobalIndex = new CClientClientDHTSizet (edgeHash2IdxGlo, comm); 704 edgesAreWritten = true; 705 } //nvertex = 2 706 707 else 708 { 709 nbFaces = bounds_lon.shape()[1]; 710 face_lon.resize(nbFaces); 711 face_lat.resize(nbFaces); 712 face_lon = lonvalue; 713 face_lat = latvalue; 714 face_nodes.resize(nvertex, nbFaces); 715 face_edges.resize(nvertex, nbFaces); 716 717 // Case (1): edges have been previously generated 718 if (edgesAreWritten) 719 { 720 // (1.1) Recuperating node global indexing and saving face_nodes 721 vector<size_t> hashValues(4); 722 CArray<size_t,1> nodeHashList(nbFaces*nvertex*4); 723 for (int nf = 0; nf < nbFaces; ++nf) 724 { 725 for (int nv = 0; nv < nvertex; ++nv) 726 { 727 hashValues = CMesh::createHashes(bounds_lon(nv, nf), bounds_lat(nv, nf)); 728 for (int nh = 0; nh < 4; ++nh) 729 nodeHashList((nf*nvertex + nv)*4 + nh) = hashValues[nh]; 730 } 731 } 732 pNodeGlobalIndex->computeIndexInfoMapping(nodeHashList); 733 CClientClientDHTSizet::Index2VectorInfoTypeMap& nodeHash2IdxGlo = pNodeGlobalIndex->getInfoIndexMap(); 734 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it1, it2; 735 CArray<size_t,1> edgeHashList(nbFaces*nvertex); 736 for (int nf = 0; nf < nbFaces; ++nf) 737 { 738 for (int nv1 = 0; nv1 < nvertex; ++nv1) 739 { 740 int nh1 = 0; 741 int nv2 = (nv1 < nvertex -1 ) ? (nv1 + 1) : (nv1 + 1 - nvertex); // cyclic rotation 742 it1 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv1)*4 + nh1)); 743 while (it1 == nodeHash2IdxGlo.end()) 744 { 745 ++nh1; 746 it1 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv1)*4 + nh1)); 747 } 748 int nh2 = 0; 749 it2 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv2)*4 + nh2)); 750 while (it2 == nodeHash2IdxGlo.end()) 751 { 752 ++nh2; 753 it2 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv1)*4 + nh2)); 754 } 755 face_nodes(nv1,nf) = it1->second[0]; 756 edgeHashList(nf*nvertex + nv1) = hashPairOrdered(it1->second[0], it2->second[0]); 757 758 } 759 } 760 761 // (1.2) Recuperating edge global indexing and saving face_edges 762 pEdgeGlobalIndex->computeIndexInfoMapping(edgeHashList); 763 CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeHash2IdxGlo = pEdgeGlobalIndex->getInfoIndexMap(); 764 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itEdgeHash; 765 CClientClientDHTSizet::Index2VectorInfoTypeMap edgeHash2Rank; 766 767 CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdxGlo2Face; 768 CArray<size_t,1> edgeIdxGloList(nbFaces*nvertex); 769 size_t iIdx = 0; 770 771 for (int nf = 0; nf < nbFaces; ++nf) 772 { 773 for (int nv1 = 0; nv1 < nvertex; ++nv1) 774 { 775 int nh1 = 0; 776 int nv2 = (nv1 < nvertex -1 ) ? (nv1 + 1) : (nv1 + 1 - nvertex); // cyclic rotation 777 it1 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv1)*4 + nh1)); 778 while (it1 == nodeHash2IdxGlo.end()) 779 { 780 ++nh1; 781 it1 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv1)*4 + nh1)); 782 } 783 int nh2 = 0; 784 it2 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv2)*4 + nh2)); 785 while (it2 == nodeHash2IdxGlo.end()) 786 { 787 ++nh2; 788 it2 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv1)*4 + nh2)); 789 } 790 size_t faceIdxGlo = mpiRank * nbFaces + nf; 791 size_t edgeHash = hashPairOrdered(it1->second[0], it2->second[0]); 792 itEdgeHash = edgeHash2IdxGlo.find(edgeHash); 793 size_t edgeIdxGlo = itEdgeHash->second[0]; 794 face_edges(nv1,nf) = edgeIdxGlo; 795 if (edgeIdxGlo2Face.count(edgeIdxGlo) == 0) 796 { 797 edgeIdxGloList(iIdx) = edgeIdxGlo; 798 ++iIdx; 799 } 800 edgeIdxGlo2Face[edgeIdxGlo].push_back(faceIdxGlo); 801 edgeHash2Rank[edgeHash].push_back(itEdgeHash->first); 802 edgeHash2Rank[edgeHash].push_back(mpiRank); 803 } 804 } 805 edgeIdxGloList.resizeAndPreserve(iIdx); 806 807 // (1.3) Saving remaining variables edge_faces and face_faces 808 809 // Establishing edge ownership 810 // The ownership criterion: priority of the process with smaller rank 811 CClientClientDHTSizet dhtEdgeHash (edgeHash2Rank, comm); 812 dhtEdgeHash.computeIndexInfoMapping(edgeHashList); 813 CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeHash2Info = dhtEdgeHash.getInfoIndexMap(); 814 CClientClientDHTSizet::Index2VectorInfoTypeMap edgeHashMin2IdxGlo; // map is needed purely for counting 815 816 // edgeHash2Info = <edgeHash, <idxGlo, rank1, idxGlo, rank2>> 817 // edgeHashMin2IdxGlo edgeHash2Info = <edgeHashMin, idxGlo> 818 for (CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = edgeHash2Info.begin(); it != edgeHash2Info.end(); ++it) 819 { 820 vector <size_t> edgeInfo = it->second; 821 if (edgeInfo.size() == 4) // two processes generate the same edge 822 if (edgeInfo[1] > edgeInfo[3]) 823 edgeInfo[1] = edgeInfo[3]; 824 if (edgeInfo[1] == mpiRank) 825 edgeHashMin2IdxGlo[it->first].push_back(edgeInfo[0]); 826 } 827 828 CDHTAutoIndexing dhtEdgeIdxGlo = CDHTAutoIndexing(edgeHashMin2IdxGlo, comm); 829 edge_count = dhtEdgeIdxGlo.getIndexCount(); 830 edge_start = dhtEdgeIdxGlo.getIndexStart(); 831 832 edge_faces.resize(2, edge_count); 833 face_faces.resize(nvertex, nbFaces); 834 835 CClientClientDHTSizet dhtEdge2Face (edgeIdxGlo2Face, comm); 836 dhtEdge2Face.computeIndexInfoMapping(edgeIdxGloList); 837 CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeIdxGlo2FaceIdx = dhtEdge2Face.getInfoIndexMap(); 838 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itFace1, itFace2; 839 840 for (int nf = 0; nf < nbFaces; ++nf) 841 { 842 for (int nv1 = 0; nv1 < nvertex; ++nv1) 843 { 844 int nh1 = 0; 845 int nv2 = (nv1 < nvertex -1 ) ? (nv1 + 1) : (nv1 + 1 - nvertex); // cyclic rotation 846 it1 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv1)*4 + nh1)); 847 while (it1 == nodeHash2IdxGlo.end()) 848 { 849 ++nh1; 850 it1 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv1)*4 + nh1)); 851 } 852 int nh2 = 0; 853 it2 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv2)*4 + nh2)); 854 while (it2 == nodeHash2IdxGlo.end()) 855 { 856 ++nh2; 857 it2 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv1)*4 + nh2)); 858 } 859 size_t faceIdxGlo = mpiRank * nbFaces + nf; 860 size_t edgeHash = hashPairOrdered(it1->second[0], it2->second[0]); 861 itEdgeHash = edgeHash2Info.find(edgeHash); 862 size_t edgeOwnerRank = itEdgeHash->second[1]; 863 int edgeIdxGlo = itEdgeHash->second[0]; 864 865 if (mpiRank == edgeOwnerRank) 866 { 867 itFace1 = edgeIdxGlo2FaceIdx.find(edgeIdxGlo); 868 int face1 = itFace1->second[0]; 869 if (itFace1->second.size() == 1) 870 { 871 edge_faces(0, edgeIdxGlo - edge_start) = face1; 872 edge_faces(1, edgeIdxGlo - edge_start) = -999; 873 face_faces(nv1, nf) = -1; 874 } 875 else 876 { 877 int face2 = itFace1->second[1]; 878 edge_faces(0, edgeIdxGlo - edge_start) = face1; 879 edge_faces(1, edgeIdxGlo - edge_start) = face2; 880 face_faces(nv1, nf) = (faceIdxGlo == face1 ? face2 : face1); 881 } 882 } 883 else 884 { 885 itFace1 = edgeIdxGlo2FaceIdx.find(edgeIdxGlo); 886 int face1 = itFace1->second[0]; 887 int face2 = itFace1->second[1]; 888 face_faces(nv1, nf) = (faceIdxGlo == face1 ? face2 : face1); 889 } 890 } 891 } 892 } // edgesAreWritten 893 894 // Case (2): nodes have been previously generated 895 else if (nodesAreWritten) 896 { 897 // (2.1) Generating nodeHashList 898 vector<size_t> hashValues(4); 899 CArray<size_t,1> nodeHashList(nbFaces*nvertex*4); 900 for (int nf = 0; nf < nbFaces; ++nf) 901 { 902 for (int nv = 0; nv < nvertex; ++nv) 903 { 904 hashValues = CMesh::createHashes(bounds_lon(nv, nf), bounds_lat(nv, nf)); 905 for (int nh = 0; nh < 4; ++nh) 906 nodeHashList((nf*nvertex + nv)*4 + nh) = hashValues[nh]; 907 } 908 } 909 910 // (2.2) Recuperating node global indexing and saving face_nodes 911 // Generating edgeHash2Info = <hash, <idx, rank>> and edgeHashList 912 pNodeGlobalIndex->computeIndexInfoMapping(nodeHashList); 913 CClientClientDHTSizet::Index2VectorInfoTypeMap& nodeHash2IdxGlo = pNodeGlobalIndex->getInfoIndexMap(); 914 CClientClientDHTSizet::Index2VectorInfoTypeMap edgeHash2Idx; 915 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it1, it2; 916 CArray<size_t,1> edgeHashList(nbFaces*nvertex); 917 for (int nf = 0; nf < nbFaces; ++nf) 918 { 919 for (int nv1 = 0; nv1 < nvertex; ++nv1) 920 { 921 int nh1 = 0; 922 int nv2 = (nv1 < nvertex -1 ) ? (nv1 + 1) : (nv1 + 1 - nvertex); // cyclic rotation 923 it1 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv1)*4 + nh1)); 924 while (it1 == nodeHash2IdxGlo.end()) 925 { 926 ++nh1; 927 it1 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv1)*4 + nh1)); 928 } 929 int nh2 = 0; 930 it2 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv2)*4 + nh2)); 931 while (it2 == nodeHash2IdxGlo.end()) 932 { 933 ++nh2; 934 it2 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv1)*4 + nh2)); 935 } 936 face_nodes(nv1,nf) = it1->second[0]; 937 size_t edgeHash = hashPairOrdered(it1->second[0], it2->second[0]); 938 edgeHash2Idx[edgeHash].push_back(generateEdgeIndex(it1->second[0], it2->second[0], mpiRank)); 939 edgeHash2Idx[edgeHash].push_back(mpiRank); 940 edgeHashList(nf*nvertex + nv1) = edgeHash; 941 } 942 } 943 944 // (2.2) Generating global edge indexes 945 // The ownership criterion: priority of the process holding the smaller index 946 // Maps generated in this step are: 947 // edgeHash2Info = <hash, [[idx1, rank1], [idx2, rank2], [idx3, rank3]..]> 948 // edgeIdx2IdxMin = = <idx, idxMin> 949 // edgeIdx2IdxGlo = <idxMin, idxGlo> 950 951 CClientClientDHTSizet dhtEdgeHash(edgeHash2Idx, comm); 952 dhtEdgeHash.computeIndexInfoMapping(edgeHashList); 953 CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeHash2Info = dhtEdgeHash.getInfoIndexMap(); 954 955 CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdx2IdxMin; 956 CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdx2IdxGlo; 957 CArray<size_t,1> edgeIdxMinList(nbFaces*nvertex); 958 size_t iIdxMin = 0; 959 960 for (CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = edgeHash2Info.begin(); it != edgeHash2Info.end(); ++it) 961 { 962 size_t idxMin = (it->second)[0]; 963 size_t idx = (it->second)[0]; 964 for (int i = 2; i < (it->second).size();) 965 { 966 if (mpiRank == (it->second)[i+1]) 967 { 968 idx = (it->second)[i]; 969 } 970 if ((it->second)[i] < idxMin) 971 { 972 idxMin = (it->second)[i]; 973 (it->second)[i] = (it->second)[i-2]; 974 } 975 i += 2; 976 } 977 (it->second)[0] = idxMin; 978 if (edgeIdx2IdxMin.count(idx) == 0) 979 { 980 edgeIdx2IdxMin[idx].push_back(idxMin); 981 if (idx == idxMin) 982 edgeIdx2IdxGlo[idxMin].push_back(idxMin); 983 edgeIdxMinList(iIdxMin) = idxMin; 984 ++iIdxMin; 985 } 986 } 987 edgeIdxMinList.resizeAndPreserve(iIdxMin); 988 CDHTAutoIndexing dhtEdgeIdxGlo = CDHTAutoIndexing(edgeIdx2IdxGlo, comm); 989 CClientClientDHTSizet dhtEdgeIdx(edgeIdx2IdxGlo, comm); 990 dhtEdgeIdx.computeIndexInfoMapping(edgeIdxMinList); 991 CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeIdxMin2IdxGlo = dhtEdgeIdx.getInfoIndexMap(); 992 // edgeIdx2IdxGlo holds global indexes only for edges owned by a process 993 // edgeIdxMin2IdxGlo holds global indexes for all edges generated by a process 994 995 // (2.3) Saving variables: edge_lon, edge_lat, face_edges 996 nbEdgesGlo = dhtEdgeIdxGlo.getNbIndexesGlobal(); 997 edge_count = dhtEdgeIdxGlo.getIndexCount(); 998 edge_start = dhtEdgeIdxGlo.getIndexStart(); 999 edge_lon.resize(edge_count); 1000 edge_lat.resize(edge_count); 1001 edge_nodes.resize(2, edge_count); 1002 face_edges.resize(nvertex, nbFaces); 1003 1004 CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdxGlo2Face; 1005 CArray<size_t,1> edgeIdxGloList(nbFaces*nvertex); 1006 size_t iIdx = 0; 1007 1008 for (int nf = 0; nf < nbFaces; ++nf) 1009 { 1010 for (int nv1 = 0; nv1 < nvertex; ++nv1) 1011 { 1012 // Getting global indexes of edge's nodes 1013 int nh1 = 0; 1014 int nv2 = (nv1 < nvertex -1 ) ? (nv1 + 1) : (nv1 + 1 - nvertex); // cyclic rotation 1015 it1 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv1)*4 + nh1)); 1016 while (it1 == nodeHash2IdxGlo.end()) 1017 { 1018 ++nh1; 1019 it1 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv1)*4 + nh1)); 1020 } 1021 int nh2 = 0; 1022 it2 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv2)*4 + nh2)); 1023 while (it2 == nodeHash2IdxGlo.end()) 1024 { 1025 ++nh2; 1026 it2 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv1)*4 + nh2)); 1027 } 1028 // Getting edge global index 1029 size_t nodeIdxGlo1 = it1->second[0]; 1030 size_t nodeIdxGlo2 = it2->second[0]; 1031 size_t myIdx = generateEdgeIndex(nodeIdxGlo1, nodeIdxGlo2, mpiRank); 1032 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx = edgeIdx2IdxMin.find(myIdx); 1033 size_t ownerIdx = (itIdx->second)[0]; 1034 int edgeIdxGlo = 0; 1035 size_t faceIdxGlo = mpiRank * nbFaces + nf; 1036 1037 if (myIdx == ownerIdx) 1038 { 1039 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdx2IdxGlo.find(myIdx); 1040 edgeIdxGlo = (itIdxGlo->second)[0]; 1041 edge_lon(edgeIdxGlo - edge_start) = ( abs( bounds_lon(nv1, nf) - bounds_lon(nv2, nf)) < 180.) ? 1042 (( bounds_lon(nv1, nf) + bounds_lon(nv2, nf)) * 0.5) : 1043 (( bounds_lon(nv1, nf) + bounds_lon(nv2, nf)) * 0.5 -180.); 1044 edge_lat(edgeIdxGlo - edge_start) = ( bounds_lat(nv1, nf) + bounds_lat(nv2, nf) ) * 0.5; 1045 edge_nodes(0, edgeIdxGlo - edge_start) = nodeIdxGlo1; 1046 edge_nodes(1, edgeIdxGlo - edge_start) = nodeIdxGlo2; 1047 } 1048 else 1049 { 1050 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdxMin2IdxGlo.find(ownerIdx); 1051 edgeIdxGlo = (itIdxGlo->second)[0]; 1052 } 1053 face_edges(nv1,nf) = edgeIdxGlo; 1054 if (edgeIdxGlo2Face.count(edgeIdxGlo) == 0) 1055 { 1056 edgeIdxGloList(iIdx) = edgeIdxGlo; 1057 ++iIdx; 1058 } 1059 edgeIdxGlo2Face[edgeIdxGlo].push_back(faceIdxGlo); 1060 } 1061 } 1062 edgeIdxGloList.resizeAndPreserve(iIdx); 1063 1064 // (2.4) Saving remaining variables edge_faces and face_faces 1065 edge_faces.resize(2, edge_count); 1066 face_faces.resize(nvertex, nbFaces); 1067 1068 CClientClientDHTSizet dhtEdge2Face (edgeIdxGlo2Face, comm); 1069 dhtEdge2Face.computeIndexInfoMapping(edgeIdxGloList); 1070 CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeIdxGlo2FaceIdx = dhtEdge2Face.getInfoIndexMap(); 1071 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itNodeIdxGlo1, itNodeIdxGlo2; 1072 1073 for (int nf = 0; nf < nbFaces; ++nf) 1074 { 1075 for (int nv1 = 0; nv1 < nvertex; ++nv1) 1076 { 1077 // Getting global indexes of edge's nodes 1078 int nh1 = 0; 1079 int nv2 = (nv1 < nvertex -1 ) ? (nv1 + 1) : (nv1 + 1 - nvertex); // cyclic rotation 1080 it1 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv1)*4 + nh1)); 1081 while (it1 == nodeHash2IdxGlo.end()) 1082 { 1083 ++nh1; 1084 it1 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv1)*4 + nh1)); 1085 } 1086 int nh2 = 0; 1087 it2 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv2)*4 + nh2)); 1088 while (it2 == nodeHash2IdxGlo.end()) 1089 { 1090 ++nh2; 1091 it2 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv1)*4 + nh2)); 1092 } 1093 size_t nodeIdxGlo1 = it1->second[0]; 1094 size_t nodeIdxGlo2 = it2->second[0]; 1095 1096 size_t myIdx = generateEdgeIndex(nodeIdxGlo1, nodeIdxGlo2, mpiRank); 1097 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx = edgeIdx2IdxMin.find(myIdx); 1098 size_t ownerIdx = (itIdx->second)[0]; 1099 size_t faceIdxGlo = mpiRank * nbFaces + nf; 1100 1101 if (myIdx == ownerIdx) 1102 { 1103 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdx2IdxGlo.find(myIdx); 1104 int edgeIdxGlo = (itIdxGlo->second)[0]; 1105 it1 = edgeIdxGlo2FaceIdx.find(edgeIdxGlo); 1106 int face1 = it1->second[0]; 1107 if (it1->second.size() == 1) 1108 { 1109 edge_faces(0, edgeIdxGlo - edge_start) = face1; 1110 edge_faces(1, edgeIdxGlo - edge_start) = -999; 1111 face_faces(nv1, nf) = -1; 1112 } 1113 else 1114 { 1115 int face2 = it1->second[1]; 1116 edge_faces(0, edgeIdxGlo - edge_start) = face1; 1117 edge_faces(1, edgeIdxGlo - edge_start) = face2; 1118 face_faces(nv1, nf) = (faceIdxGlo == face1 ? face2 : face1); 1119 } 1120 } 1121 else 1122 { 1123 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdxMin2IdxGlo.find(ownerIdx); 1124 size_t edgeIdxGlo = (itIdxGlo->second)[0]; 1125 it1 = edgeIdxGlo2FaceIdx.find(edgeIdxGlo); 1126 int face1 = it1->second[0]; 1127 int face2 = it1->second[1]; 1128 face_faces(nv1, nf) = (faceIdxGlo == face1 ? face2 : face1); 1129 } 1130 } 1131 } 1132 } // nodesAreWritten 1133 1134 // Case (3): Neither nodes nor edges have been previously generated 1135 else 1136 { 1137 // (3.1) Creating a list of hashes for each node and a map nodeHash2Idx <hash, <idx,rank> > 1138 vector<size_t> hashValues(4); 1139 CClientClientDHTSizet::Index2VectorInfoTypeMap nodeHash2Idx; 1140 CArray<size_t,1> nodeHashList(nbFaces*nvertex*4); 1141 size_t iHash = 0; 1142 for (int nf = 0; nf < nbFaces; ++nf) 1143 { 1144 for (int nv = 0; nv < nvertex; ++nv) 1145 { 1146 hashValues = CMesh::createHashes(bounds_lon(nv, nf), bounds_lat(nv, nf)); 1147 size_t nodeIndex = generateNodeIndex(hashValues, mpiRank); 1148 for (int nh = 0; nh < 4; ++nh) 1149 { 1150 if (nodeHash2Idx.count(hashValues[nh])==0) 1151 { 1152 nodeHash2Idx[hashValues[nh]].push_back(nodeIndex); 1153 nodeHash2Idx[hashValues[nh]].push_back(mpiRank); 1154 nodeHashList(iHash) = hashValues[nh]; 1155 ++iHash; 1156 } 1157 } 1158 } 1159 } 1160 nodeHashList.resizeAndPreserve(iHash); 1161 1162 // (3.2) Generating global node indexes 1163 // The ownership criterion: priority of the process holding the smaller index 1164 // Maps generated in this step are: 1165 // nodeHash2Info = <hash, [[idxMin, rankMin], [idx1, rank1], [idx3, rank3]..]> 1166 // nodeIdx2IdxMin = = <idx, idxMin> 1167 // nodeIdx2IdxGlo = <idxMin, idxGlo> 1168 1169 CClientClientDHTSizet dhtNodeHash(nodeHash2Idx, comm); 1170 dhtNodeHash.computeIndexInfoMapping(nodeHashList); 1171 CClientClientDHTSizet::Index2VectorInfoTypeMap& nodeHash2Info = dhtNodeHash.getInfoIndexMap(); 1172 1173 CClientClientDHTSizet::Index2VectorInfoTypeMap nodeIdx2IdxMin; 1174 CClientClientDHTSizet::Index2VectorInfoTypeMap nodeIdx2IdxGlo; 1175 CArray<size_t,1> nodeIdxMinList(nbFaces*nvertex*4); 1176 size_t iIdxMin = 0; 1177 1178 for (CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = nodeHash2Info.begin(); it != nodeHash2Info.end(); ++it) 1179 { 1180 size_t idxMin = (it->second)[0]; 1181 size_t idx = (it->second)[0]; 1182 for (int i = 2; i < (it->second).size();) 1183 { 1184 if (mpiRank == (it->second)[i+1]) 1185 { 1186 idx = (it->second)[i]; 1187 } 1188 if ((it->second)[i] < idxMin) 1189 { 1190 idxMin = (it->second)[i]; 1191 (it->second)[i] = (it->second)[i-2]; 1192 } 1193 i += 2; 1194 } 1195 (it->second)[0] = idxMin; 1196 if (nodeIdx2IdxMin.count(idx) == 0) 1197 { 1198 nodeIdx2IdxMin[idx].push_back(idxMin); 1199 if (idx == idxMin) 1200 nodeIdx2IdxGlo[idxMin].push_back(idxMin); 1201 nodeIdxMinList(iIdxMin) = idxMin; 1202 ++iIdxMin; 1203 } 1204 } 1205 1206 nodeIdxMinList.resizeAndPreserve(iIdxMin); 1207 CDHTAutoIndexing dhtNodeIdxGlo = CDHTAutoIndexing(nodeIdx2IdxGlo, comm); 1208 CClientClientDHTSizet dhtNodeIdx(nodeIdx2IdxGlo, comm); 1209 dhtNodeIdx.computeIndexInfoMapping(nodeIdxMinList); 1210 CClientClientDHTSizet::Index2VectorInfoTypeMap& nodeIdxMin2IdxGlo = dhtNodeIdx.getInfoIndexMap(); 1211 1212 // (3.3) Saving node data: node_lon, node_lat, and face_nodes 1213 // Generating edgeHash2Info = <hash, <idx, rank>> and edgeHashList 1214 nbNodesGlo = dhtNodeIdxGlo.getNbIndexesGlobal(); 1215 node_count = dhtNodeIdxGlo.getIndexCount(); 1216 node_start = dhtNodeIdxGlo.getIndexStart(); 1217 node_lon.resize(node_count); 1218 node_lat.resize(node_count); 1219 size_t nodeIdxGlo1 = 0; 1220 size_t nodeIdxGlo2 = 0; 1221 CClientClientDHTSizet::Index2VectorInfoTypeMap edgeHash2Idx; 1222 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itNodeIdxGlo1, itNodeIdxGlo2; 1223 CArray<size_t,1> edgeHashList(nbFaces*nvertex); 1224 1225 for (int nf = 0; nf < nbFaces; ++nf) 1226 { 1227 for (int nv1 = 0; nv1 < nvertex; ++nv1) 1228 { 1229 int nv2 = (nv1 < nvertex -1 ) ? (nv1 + 1) : (nv1 + 1 - nvertex); // cyclic rotation 1230 vector<size_t> hashValues1 = CMesh::createHashes(bounds_lon(nv1, nf), bounds_lat(nv1, nf)); 1231 vector<size_t> hashValues2 = CMesh::createHashes(bounds_lon(nv2, nf), bounds_lat(nv2, nf)); 1232 size_t myNodeIdx1 = generateNodeIndex(hashValues1, mpiRank); 1233 size_t myNodeIdx2 = generateNodeIndex(hashValues2, mpiRank); 1234 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itNodeIdx1 = nodeIdx2IdxMin.find(myNodeIdx1); 1235 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itNodeIdx2 = nodeIdx2IdxMin.find(myNodeIdx2); 1236 size_t ownerNodeIdx = (itNodeIdx1->second)[0]; 1237 1238 if (myNodeIdx1 == ownerNodeIdx) 1239 { 1240 itNodeIdxGlo1 = nodeIdx2IdxGlo.find(myNodeIdx1); 1241 nodeIdxGlo1 = (itNodeIdxGlo1->second)[0]; 1242 node_lon(nodeIdxGlo1 - node_start) = bounds_lon(nv1, nf); 1243 node_lat(nodeIdxGlo1 - node_start) = bounds_lat(nv1, nf); 1244 } 1245 else 1246 { 1247 itNodeIdxGlo1 = nodeIdxMin2IdxGlo.find(ownerNodeIdx); 1248 nodeIdxGlo1 = (itNodeIdxGlo1->second)[0]; 1249 } 1250 itNodeIdxGlo2 = nodeIdxMin2IdxGlo.find((itNodeIdx2->second)[0]); 1251 nodeIdxGlo2 = (itNodeIdxGlo2->second)[0]; 1252 size_t edgeHash = hashPairOrdered(nodeIdxGlo1, nodeIdxGlo2); 1253 edgeHash2Idx[edgeHash].push_back(generateEdgeIndex(nodeIdxGlo1, nodeIdxGlo2, mpiRank)); 1254 edgeHash2Idx[edgeHash].push_back(mpiRank); 1255 edgeHashList(nf*nvertex + nv1) = edgeHash; 1256 face_nodes(nv1,nf) = nodeIdxGlo1; 1257 } 1258 } 1259 1260 // (3.4) Generating global edge indexes 1261 // Maps generated in this step are: 1262 // edgeIdx2IdxMin = = <idx, idxMin> 1263 // edgeIdx2IdxGlo = <idxMin, idxGlo> 1264 1265 CClientClientDHTSizet dhtEdgeHash(edgeHash2Idx, comm); 1266 dhtEdgeHash.computeIndexInfoMapping(edgeHashList); 1267 CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeHash2Info = dhtEdgeHash.getInfoIndexMap(); 1268 // edgeHash2Info = <hash, [[idx1, rank1], [idx2, rank2], [idx3, rank3]..]> 1269 1270 CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdx2IdxMin; 1271 CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdx2IdxGlo; 1272 CArray<size_t,1> edgeIdxMinList(nbFaces*nvertex); 1273 iIdxMin = 0; 1274 1275 for (CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = edgeHash2Info.begin(); it != edgeHash2Info.end(); ++it) 1276 { 1277 size_t idxMin = (it->second)[0]; 1278 size_t idx = (it->second)[0]; 1279 1280 for (int i = 2; i < (it->second).size();) 1281 { 1282 if (mpiRank == (it->second)[i+1]) 1283 { 1284 idx = (it->second)[i]; 1285 } 1286 if ((it->second)[i] < idxMin) 1287 { 1288 idxMin = (it->second)[i]; 1289 (it->second)[i] = (it->second)[i-2]; 1290 } 1291 i += 2; 1292 } 1293 (it->second)[0] = idxMin; 1294 if (edgeIdx2IdxMin.count(idx) == 0) 1295 { 1296 edgeIdx2IdxMin[idx].push_back(idxMin); 1297 if (idx == idxMin) 1298 edgeIdx2IdxGlo[idxMin].push_back(idxMin); 1299 edgeIdxMinList(iIdxMin) = idxMin; 1300 ++iIdxMin; 1301 } 1302 } 1303 edgeIdxMinList.resizeAndPreserve(iIdxMin); 1304 CDHTAutoIndexing dhtEdgeIdxGlo = CDHTAutoIndexing(edgeIdx2IdxGlo, comm); 1305 CClientClientDHTSizet dhtEdgeIdx(edgeIdx2IdxGlo, comm); 1306 dhtEdgeIdx.computeIndexInfoMapping(edgeIdxMinList); 1307 CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeIdxMin2IdxGlo = dhtEdgeIdx.getInfoIndexMap(); 1308 1309 // (3.5) Saving variables: edge_lon, edge_lat, face_edges 1310 // Creating map edgeIdxGlo2Face <idxGlo, face> 1311 1312 nbEdgesGlo = dhtEdgeIdxGlo.getNbIndexesGlobal(); 1313 edge_count = dhtEdgeIdxGlo.getIndexCount(); 1314 edge_start = dhtEdgeIdxGlo.getIndexStart(); 1315 edge_lon.resize(edge_count); 1316 edge_lat.resize(edge_count); 1317 edge_nodes.resize(2, edge_count); 1318 face_edges.resize(nvertex, nbFaces); 1319 1320 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it1, it2; 1321 CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdxGlo2Face; 1322 CArray<size_t,1> edgeIdxGloList(nbFaces*nvertex); 1323 size_t iIdx = 0; 1324 1325 for (int nf = 0; nf < nbFaces; ++nf) 1326 { 1327 for (int nv1 = 0; nv1 < nvertex; ++nv1) 1328 { 1329 // Getting global indexes of edge's nodes 1330 int nv2 = (nv1 < nvertex -1 ) ? (nv1 + 1) : (nv1 + 1 - nvertex); // cyclic rotation 1331 vector<size_t> hashValues1 = CMesh::createHashes(bounds_lon(nv1, nf), bounds_lat(nv1, nf)); 1332 vector<size_t> hashValues2 = CMesh::createHashes(bounds_lon(nv2, nf), bounds_lat(nv2, nf)); 1333 1334 size_t myNodeIdx1 = generateNodeIndex(hashValues1, mpiRank); 1335 size_t myNodeIdx2 = generateNodeIndex(hashValues2, mpiRank); 1336 it1 = nodeIdx2IdxMin.find(myNodeIdx1); 1337 it2 = nodeIdx2IdxMin.find(myNodeIdx2); 1338 itNodeIdxGlo1 = nodeIdxMin2IdxGlo.find((it1->second)[0]); 1339 itNodeIdxGlo2 = nodeIdxMin2IdxGlo.find((it2->second)[0]); 1340 size_t nodeIdxGlo1 = (itNodeIdxGlo1->second)[0]; 1341 size_t nodeIdxGlo2 = (itNodeIdxGlo2->second)[0]; 1342 1343 size_t myIdx = generateEdgeIndex(nodeIdxGlo1, nodeIdxGlo2, mpiRank); 1344 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx = edgeIdx2IdxMin.find(myIdx); 1345 size_t ownerIdx = (itIdx->second)[0]; 1346 1347 int edgeIdxGlo = 0; 1348 size_t faceIdxGlo = mpiRank * nbFaces + nf; 1349 1350 if (myIdx == ownerIdx) 1351 { 1352 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdx2IdxGlo.find(myIdx); 1353 edgeIdxGlo = (itIdxGlo->second)[0]; 1354 edge_lon(edgeIdxGlo - edge_start) = ( abs( bounds_lon(nv1, nf) - bounds_lon(nv2, nf)) < 180.) ? 1355 (( bounds_lon(nv1, nf) + bounds_lon(nv2, nf)) * 0.5) : 1356 (( bounds_lon(nv1, nf) + bounds_lon(nv2, nf)) * 0.5 -180.); 1357 edge_lat(edgeIdxGlo-edge_start) = ( bounds_lat(nv1, nf) + bounds_lat(nv2, nf) ) * 0.5; 1358 edge_nodes(0, edgeIdxGlo - edge_start) = nodeIdxGlo1; 1359 edge_nodes(1, edgeIdxGlo - edge_start) = nodeIdxGlo2; 1360 } 1361 else 1362 { 1363 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdxMin2IdxGlo.find(ownerIdx); 1364 edgeIdxGlo = (itIdxGlo->second)[0]; 1365 } 1366 face_edges(nv1,nf) = edgeIdxGlo; 1367 if (edgeIdxGlo2Face.count(edgeIdxGlo) == 0) 1368 { 1369 edgeIdxGloList(iIdx) = edgeIdxGlo; 1370 ++iIdx; 1371 } 1372 edgeIdxGlo2Face[edgeIdxGlo].push_back(faceIdxGlo); 1373 } 1374 } 1375 edgeIdxGloList.resizeAndPreserve(iIdx); 1376 1377 // (3.6) Saving remaining variables edge_faces and face_faces 1378 edge_faces.resize(2, edge_count); 1379 face_faces.resize(nvertex, nbFaces); 1380 1381 CClientClientDHTSizet dhtEdge2Face (edgeIdxGlo2Face, comm); 1382 dhtEdge2Face.computeIndexInfoMapping(edgeIdxGloList); 1383 CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeIdxGlo2FaceIdx = dhtEdge2Face.getInfoIndexMap(); 1384 1385 for (int nf = 0; nf < nbFaces; ++nf) 1386 { 1387 for (int nv1 = 0; nv1 < nvertex; ++nv1) 1388 { 1389 // Getting global indexes of edge's nodes 1390 int nv2 = (nv1 < nvertex -1 ) ? (nv1 + 1) : (nv1 + 1 - nvertex); // cyclic rotation 1391 vector<size_t> hashValues1 = CMesh::createHashes(bounds_lon(nv1, nf), bounds_lat(nv1, nf)); 1392 vector<size_t> hashValues2 = CMesh::createHashes(bounds_lon(nv2, nf), bounds_lat(nv2, nf)); 1393 1394 size_t myNodeIdx1 = generateNodeIndex(hashValues1, mpiRank); 1395 size_t myNodeIdx2 = generateNodeIndex(hashValues2, mpiRank); 1396 it1 = nodeIdx2IdxMin.find(myNodeIdx1); 1397 it2 = nodeIdx2IdxMin.find(myNodeIdx2); 1398 itNodeIdxGlo1 = nodeIdxMin2IdxGlo.find((it1->second)[0]); 1399 itNodeIdxGlo2 = nodeIdxMin2IdxGlo.find((it2->second)[0]); 1400 size_t nodeIdxGlo1 = (itNodeIdxGlo1->second)[0]; 1401 size_t nodeIdxGlo2 = (itNodeIdxGlo2->second)[0]; 1402 1403 size_t myIdx = generateEdgeIndex(nodeIdxGlo1, nodeIdxGlo2, mpiRank); 1404 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx = edgeIdx2IdxMin.find(myIdx); 1405 size_t ownerIdx = (itIdx->second)[0]; 1406 size_t faceIdxGlo = mpiRank * nbFaces + nf; 1407 1408 if (myIdx == ownerIdx) 1409 { 1410 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdx2IdxGlo.find(myIdx); 1411 int edgeIdxGlo = (itIdxGlo->second)[0]; 1412 it1 = edgeIdxGlo2FaceIdx.find(edgeIdxGlo); 1413 int face1 = it1->second[0]; 1414 if (it1->second.size() == 1) 1415 { 1416 edge_faces(0, edgeIdxGlo - edge_start) = face1; 1417 edge_faces(1, edgeIdxGlo - edge_start) = -999; 1418 face_faces(nv1, nf) = -1; 1419 } 1420 else 1421 { 1422 size_t face2 = it1->second[1]; 1423 edge_faces(0, edgeIdxGlo - edge_start) = face1; 1424 edge_faces(1, edgeIdxGlo - edge_start) = face2; 1425 face_faces(nv1, nf) = (faceIdxGlo == face1 ? face2 : face1); 1426 } 1427 } 1428 else 1429 { 1430 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdxMin2IdxGlo.find(ownerIdx); 1431 size_t edgeIdxGlo = (itIdxGlo->second)[0]; 1432 it1 = edgeIdxGlo2FaceIdx.find(edgeIdxGlo); 1433 int face1 = it1->second[0]; 1434 int face2 = it1->second[1]; 1435 face_faces(nv1, nf) = (faceIdxGlo == face1 ? face2 : face1); 1436 } 1437 } 520 1438 } 521 1439 } 522 // Create nodes and edge_node connectivity 523 524 node_lon.resizeAndPreserve(nbEdges*nvertex); // Max possible number of nodes 525 node_lat.resizeAndPreserve(nbEdges*nvertex); 526 edge_nodes.resizeAndPreserve(nvertex, nbEdges); 527 528 // for (int ne = 0; ne < nbEdges; ++ne) 529 // { 530 // for (int nv = 0; nv < nvertex; ++nv) 531 // { 532 // if ( nodeIndex(bounds_lon(nv, ne), bounds_lat(nv ,ne)) == -1) 533 // { 534 // edge_nodes(nv,ne) = nbNodes ; 535 // node_lon(nbNodes) = bounds_lon(nv, ne); 536 // node_lat(nbNodes) = bounds_lat(nv, ne); 537 // ++nbNodes ; 538 // } 539 // else 540 // edge_nodes(nv,ne) = nodeIndex(bounds_lon(nv, ne), bounds_lat(nv ,ne)); 541 // } 542 // } 543 // node_lon.resizeAndPreserve(nbNodes); 544 // node_lat.resizeAndPreserve(nbNodes); 545 546 // Create edges 547 edge_lon.resizeAndPreserve(nbEdges); 548 edge_lat.resizeAndPreserve(nbEdges); 549 550 for (int ne = 0; ne < nbEdges; ++ne) 551 { 552 if (map_edges.find(make_ordered_pair (edge_nodes(0,ne), edge_nodes(1,ne))) == map_edges.end()) 553 { 554 map_edges[make_ordered_pair ( edge_nodes(0,ne), edge_nodes(1,ne) )] = ne ; 555 edge_lon(ne) = lonvalue(ne); 556 edge_lat(ne) = latvalue(ne); 557 } 558 } 559 edgesAreWritten = true; 560 } // nvertex = 2 561 else 562 { 563 nbFaces = bounds_lon.shape()[1]; 564 565 // Create nodes and face_node connectivity 566 node_lon.resizeAndPreserve(nbFaces*nvertex); // Max possible number of nodes 567 node_lat.resizeAndPreserve(nbFaces*nvertex); 568 face_nodes.resize(nvertex, nbFaces); 569 570 /*for (int nf = 0; nf < nbFaces; ++nf) 571 { 572 for (int nv = 0; nv < nvertex; ++nv) 573 { 574 if ( nodeIndex(bounds_lon(nv, nf), bounds_lat(nv ,nf)) == -1) 575 { 576 face_nodes(nv,nf) = nbNodes ; 577 node_lon(nbNodes) = bounds_lon(nv, nf); 578 node_lat(nbNodes) = bounds_lat(nv ,nf); 579 ++nbNodes ; 580 } 581 else 582 { 583 face_nodes(nv,nf) = nodeIndex(bounds_lon(nv, nf), bounds_lat(nv ,nf)); 584 } 585 } 586 } 587 node_lon.resizeAndPreserve(nbNodes); 588 node_lat.resizeAndPreserve(nbNodes);*/ 589 590 591 // Create edges and edge_nodes connectivity 592 // edge_lon.resizeAndPreserve(nbFaces*nvertex); // Max possible number of edges 593 // edge_lat.resizeAndPreserve(nbFaces*nvertex); 594 // edge_nodes.resizeAndPreserve(2, nbFaces*nvertex); 595 // for (int nf = 0; nf < nbFaces; ++nf) 596 // { 597 // for (int nv1 = 0; nv1 < nvertex; ++nv1) 598 // { 599 // int nv2 = (nv1 < nvertex -1 ) ? (nv1 + 1) : (nv1 + 1 - nvertex); // cyclic rotation 600 // if (map_edges.find(make_ordered_pair (face_nodes(nv1,nf), face_nodes(nv2,nf))) == map_edges.end()) 601 // { 602 // map_edges[make_ordered_pair (face_nodes(nv1,nf), face_nodes(nv2,nf))] = nbEdges ; 603 // edge_nodes(Range::all(),nbEdges) = face_nodes(nv1,nf), face_nodes(nv2,nf); 604 // edge_lon(nbEdges) = ( abs( node_lon(face_nodes(nv1,nf)) - node_lon(face_nodes(nv2,nf))) < 180.) ? 605 // (( node_lon(face_nodes(nv1,nf)) + node_lon(face_nodes(nv2,nf))) * 0.5) : 606 // (( node_lon(face_nodes(nv1,nf)) + node_lon(face_nodes(nv2,nf))) * 0.5 -180.);; 607 // edge_lat(nbEdges) = ( node_lat(face_nodes(nv1,nf)) + node_lat(face_nodes(nv2,nf)) ) * 0.5; 608 // ++nbEdges; 609 // } 610 // } 611 // } 612 // edge_nodes.resizeAndPreserve(2, nbEdges); 613 // edge_lon.resizeAndPreserve(nbEdges); 614 // edge_lat.resizeAndPreserve(nbEdges); 615 616 // Create faces 617 // face_lon.resize(nbFaces); 618 // face_lat.resize(nbFaces); 619 // face_lon = lonvalue; 620 // face_lat = latvalue; 621 // facesAreWritten = true; 622 1440 facesAreWritten = true; 623 1441 } // nvertex >= 3 624 1442 … … 626 1444 627 1445 } // namespace xios 628 629 // void CMesh::createMeshEpsilon(const MPI_Comm& comm, const CArray<double, 1>& lonvalue, const CArray<double, 1>& latvalue,630 // const CArray<double, 2>& bounds_lon, const CArray<double, 2>& bounds_lat)631 // {632 //633 // nvertex = (bounds_lon.numElements() == 0) ? 1 : bounds_lon.rows();634 //635 // if (nvertex == 1)636 // {637 // nbNodes = lonvalue.numElements();638 // node_lon.resizeAndPreserve(nbNodes);639 // node_lat.resizeAndPreserve(nbNodes);640 // for (int nn = 0; nn < nbNodes; ++nn)641 // {642 // if ( nodeIndex(lonvalue(nn), latvalue(nn)) == -1 )643 // {644 // node_lon(nn) = lonvalue(nn);645 // node_lat(nn) = latvalue(nn);646 // }647 // }648 //649 // nodesAreWritten = true;650 // }651 // else if (nvertex == 2)652 // {653 // nbEdges = bounds_lon.shape()[1];654 //655 // // Create nodes and edge_node connectivity656 // node_lon.resizeAndPreserve(nbEdges*nvertex); // Max possible number of nodes657 // node_lat.resizeAndPreserve(nbEdges*nvertex);658 // edge_nodes.resizeAndPreserve(nvertex, nbEdges);659 //660 // for (int ne = 0; ne < nbEdges; ++ne)661 // {662 // for (int nv = 0; nv < nvertex; ++nv)663 // {664 // if ( nodeIndex(bounds_lon(nv, ne), bounds_lat(nv ,ne)) == -1)665 // {666 // edge_nodes(nv,ne) = nbNodes ;667 // node_lon(nbNodes) = bounds_lon(nv, ne);668 // node_lat(nbNodes) = bounds_lat(nv, ne);669 // ++nbNodes ;670 // }671 // else672 // edge_nodes(nv,ne) = nodeIndex(bounds_lon(nv, ne), bounds_lat(nv ,ne));673 // }674 // }675 // node_lon.resizeAndPreserve(nbNodes);676 // node_lat.resizeAndPreserve(nbNodes);677 //678 // // Create edges679 // edge_lon.resizeAndPreserve(nbEdges);680 // edge_lat.resizeAndPreserve(nbEdges);681 //682 // for (int ne = 0; ne < nbEdges; ++ne)683 // {684 // if (map_edges.find(make_ordered_pair (edge_nodes(0,ne), edge_nodes(1,ne))) == map_edges.end())685 // {686 // map_edges[make_ordered_pair ( edge_nodes(0,ne), edge_nodes(1,ne) )] = ne ;687 // edge_lon(ne) = lonvalue(ne);688 // edge_lat(ne) = latvalue(ne);689 // }690 // }691 // edgesAreWritten = true;692 // } // nvertex = 2693 // else694 // {695 // nbFaces = bounds_lon.shape()[1];696 //697 // // Create nodes and face_node connectivity698 // node_lon.resizeAndPreserve(nbFaces*nvertex); // Max possible number of nodes699 // node_lat.resizeAndPreserve(nbFaces*nvertex);700 // face_nodes.resize(nvertex, nbFaces);701 //702 // for (int nf = 0; nf < nbFaces; ++nf)703 // {704 // for (int nv = 0; nv < nvertex; ++nv)705 // {706 // if ( nodeIndex(bounds_lon(nv, nf), bounds_lat(nv ,nf)) == -1)707 // {708 // face_nodes(nv,nf) = nbNodes ;709 // node_lon(nbNodes) = bounds_lon(nv, nf);710 // node_lat(nbNodes) = bounds_lat(nv ,nf);711 // ++nbNodes ;712 // }713 // else714 // {715 // face_nodes(nv,nf) = nodeIndex(bounds_lon(nv, nf), bounds_lat(nv ,nf));716 // }717 // }718 // }719 // node_lon.resizeAndPreserve(nbNodes);720 // node_lat.resizeAndPreserve(nbNodes);721 //722 // // Create edges and edge_nodes connectivity723 // edge_lon.resizeAndPreserve(nbFaces*nvertex); // Max possible number of edges724 // edge_lat.resizeAndPreserve(nbFaces*nvertex);725 // edge_nodes.resizeAndPreserve(2, nbFaces*nvertex);726 // for (int nf = 0; nf < nbFaces; ++nf)727 // {728 // for (int nv1 = 0; nv1 < nvertex; ++nv1)729 // {730 // int nv2 = (nv1 < nvertex -1 ) ? (nv1 + 1) : (nv1 + 1 - nvertex); // cyclic rotation731 // if (map_edges.find(make_ordered_pair (face_nodes(nv1,nf), face_nodes(nv2,nf))) == map_edges.end())732 // {733 // map_edges[make_ordered_pair (face_nodes(nv1,nf), face_nodes(nv2,nf))] = nbEdges ;734 // edge_nodes(Range::all(),nbEdges) = face_nodes(nv1,nf), face_nodes(nv2,nf);735 // edge_lon(nbEdges) = ( abs( node_lon(face_nodes(nv1,nf)) - node_lon(face_nodes(nv2,nf))) < 180.) ?736 // (( node_lon(face_nodes(nv1,nf)) + node_lon(face_nodes(nv2,nf))) * 0.5) :737 // (( node_lon(face_nodes(nv1,nf)) + node_lon(face_nodes(nv2,nf))) * 0.5 -180.);;738 // edge_lat(nbEdges) = ( node_lat(face_nodes(nv1,nf)) + node_lat(face_nodes(nv2,nf)) ) * 0.5;739 // ++nbEdges;740 // }741 // }742 // }743 // edge_nodes.resizeAndPreserve(2, nbEdges);744 // edge_lon.resizeAndPreserve(nbEdges);745 // edge_lat.resizeAndPreserve(nbEdges);746 //747 // // Create faces748 // face_lon.resize(nbFaces);749 // face_lat.resize(nbFaces);750 // face_lon = lonvalue;751 // face_lat = latvalue;752 // facesAreWritten = true;753 // } // nvertex >= 3754 //755 // } // createMeshEpsilon -
XIOS/trunk/src/node/mesh.hpp
r900 r924 9 9 10 10 #include "array_new.hpp" 11 #include "client_client_dht_template_impl.hpp"12 11 #include "dht_auto_indexing.hpp" 13 12 … … 32 31 ~CMesh(void); 33 32 34 int nbNodes; 35 int nbEdges; 36 int nbFaces; 37 int nvertex; 33 int nbNodesGlo; 34 int nbEdgesGlo; 35 36 int node_start; 37 int node_count; 38 int edge_start; 39 int edge_count; 38 40 39 41 bool nodesAreWritten; … … 56 58 57 59 void createMesh(const CArray<double, 1>&, const CArray<double, 1>&, 58 const CArray<double, 2>&, const CArray<double, 2>& );60 const CArray<double, 2>&, const CArray<double, 2>& ); 59 61 60 void createMeshEpsilon(const MPI_Comm&, const CArray<double, 1>&, const CArray<double, 1>&, 61 const CArray<double, 2>&, const CArray<double, 2>& ); 62 void createMeshEpsilon(const MPI_Comm&, 63 const CArray<double, 1>&, const CArray<double, 1>&, 64 const CArray<double, 2>&, const CArray<double, 2>& ); 62 65 63 static CMesh* getMesh(StdString );66 static CMesh* getMesh(StdString, int); 64 67 65 68 private: 66 69 70 int nbNodes; 71 int nbEdges; 72 int nbFaces; 73 67 74 static std::map <StdString, CMesh> meshList; 68 vector<size_t> createHashes (double, double); 75 static std::map <StdString, vector<int> > domainList; 76 CClientClientDHTSizet* pNodeGlobalIndex; // pointer to a map <nodeHash, nodeIdxGlo> 77 CClientClientDHTSizet* pEdgeGlobalIndex; // pointer to a map <edgeHash, edgeIdxGlo> 78 79 vector<size_t> createHashes (const double, const double); 69 80 70 81 size_t nodeIndex (double, double); // redundant in parallel version with epsilon precision
Note: See TracChangeset
for help on using the changeset viewer.