/******************************************************** Class for sorting clusters. Written by k-fleak *********************************************************/ #pragma warning(disable:4786) #include #include #include #include #include #include #include #include "../combination.cpp" #include "../atom.cpp" #ifndef __CLUSTERSORT_CPP #define __CLUSTERSORT_CPP typedef std::map, std::vector > sortPointData; typedef std::map, std::vector >, std::deque > sortPairData; typedef std::vector, std::vector >, std::deque > > sortTriData; typedef std::vector, std::vector >, std::vector > > sortTetraData; class ClusterSort{ private: sortPointData sortPoint; sortPairData sortPair; sortTriData sortTri; sortTetraData sortTetra; int pairIndex; int flagPair; int flagTri; std::vector atomArray; double edigit; void setAtomArray(std::vector &atomArrayIn); void setPairIndex(); void setTriIndex(); std::vector getPairIndexSet(std::vector > &pairAtomIndex); std::vector getTriIndexSet(std::vector > &triAtomIndex); public: ClusterSort(std::vector &atomArrayIn, const double &tol, int MaxBody); ~ClusterSort(); void addCluster(const std::set &cluster, int &clusterIndex); void printSortCluster(); }; ClusterSort::ClusterSort(std::vector &atomArrayIn, const double &tol, int MaxBody){ pairIndex = 0; flagPair = 0; flagTri = 0; edigit = 1.0 / tol; setAtomArray(atomArrayIn); sortTri.resize(1); sortTetra.resize(1); } ClusterSort::~ClusterSort(){} void ClusterSort::setAtomArray(std::vector &atomArrayIn){ for ( int i = 0; i < atomArrayIn.size(); ++i){ atomArray.push_back(atomArrayIn[i]); } } void ClusterSort::addCluster(const std::set &cluster, int &clusterIndex){ std::set::iterator it; std::vector sublattice; std::vector dist; std::vector base; if ( cluster.size() == 1){ dist.push_back(0); it = cluster.begin(); while ( it != cluster.end()){ sublattice.push_back(atomArray[*it].getSublatticeNumber()); ++it; } sortPoint[sublattice].push_back(clusterIndex); }else if ( cluster.size() == 2){ it = cluster.begin(); while ( it != cluster.end()){ sublattice.push_back(atomArray[*it].getSublatticeNumber()); base.push_back(*it); ++it; } double tmpDist = atomArray[base[0]].minimumDistance(atomArray[base[1]].getPosition()); dist.push_back(static_cast ( tmpDist * edigit) ); sort(sublattice.begin(), sublattice.end()); std::pair, std::vector > ptmp(dist, sublattice); sortPair[ptmp].push_back(clusterIndex); }else if ( cluster.size() == 3 ){ std::vector > pairAtom; if ( flagPair == 0){ setPairIndex(); flagPair = 1; } it = cluster.begin(); while ( it != cluster.end()){ sublattice.push_back(atomArray[*it].getSublatticeNumber()); base.push_back(*it); ++it; } sort(sublattice.begin(), sublattice.end()); Combination pair(&base); pairAtom = pair.getCombination(2); std::vector pairIndexSet; pairIndexSet = getPairIndexSet(pairAtom); std::pair, std::vector > ptmp2(pairIndexSet, sublattice); (sortTri[cluster.size() - 3])[ptmp2].push_back(clusterIndex); } else if ( cluster.size() == 4 ){ std::vector > triAtom; if ( flagTri == 0){ setTriIndex(); flagTri = 1; } it = cluster.begin(); while ( it != cluster.end()){ sublattice.push_back(atomArray[*it].getSublatticeNumber()); base.push_back(*it); ++it; } sort(sublattice.begin(), sublattice.end()); Combination tri(&base); triAtom = tri.getCombination(3); std::vector triIndexSet; triIndexSet = getTriIndexSet(triAtom); std::pair, std::vector > ptmp3(triIndexSet, sublattice); (sortTetra[cluster.size() - 4])[ptmp3].push_back(clusterIndex); } } void ClusterSort::setPairIndex(){ sortPairData::iterator it; int index = 0; it = sortPair.begin(); while ( it != sortPair.end()){ (*it).second.push_front(index); ++index; ++it; } } void ClusterSort::setTriIndex(){ std::map, std::vector >, std::deque >::iterator it; int index = 0; it = sortTri[0].begin(); while ( it != sortTri[0].end()){ (*it).second.push_front(index); ++index; ++it; } } std::vector ClusterSort::getPairIndexSet(std::vector > &pairAtomIndex){ std::vector pairIndexSet; for ( int i = 0; i < pairAtomIndex.size(); ++i){ std::vector latticeSet; std::vector distSet; double distTmp = atomArray[pairAtomIndex[i][0]].minimumDistance(atomArray[pairAtomIndex[i][1]].getPosition()); distSet.push_back(static_cast ( distTmp * edigit )); latticeSet.push_back(atomArray[pairAtomIndex[i][0]].getSublatticeNumber()); latticeSet.push_back(atomArray[pairAtomIndex[i][1]].getSublatticeNumber()); sort(latticeSet.begin(), latticeSet.end()); std::pair, std::vector > ptmp(distSet, latticeSet); int pairIndexTmp = sortPair[ptmp][0]; pairIndexSet.push_back(pairIndexTmp); } sort(pairIndexSet.begin(), pairIndexSet.end()); return pairIndexSet; } std::vector ClusterSort::getTriIndexSet(std::vector > &triAtomIndex){ std::vector triIndexSet; for ( int i = 0; i < triAtomIndex.size(); ++i){ std::vector latticeSet; std::vector > pairAtomSet; std::vector pairIndexSet; Combination tri(&triAtomIndex[i]); pairAtomSet = tri.getCombination(2); pairIndexSet = getPairIndexSet(pairAtomSet); latticeSet.push_back(atomArray[triAtomIndex[i][0]].getSublatticeNumber()); latticeSet.push_back(atomArray[triAtomIndex[i][1]].getSublatticeNumber()); latticeSet.push_back(atomArray[triAtomIndex[i][2]].getSublatticeNumber()); sort(latticeSet.begin(), latticeSet.end()); std::pair, std::vector > ptmp(pairIndexSet, latticeSet); int triIndexTmp = sortTri[0][ptmp][0]; triIndexSet.push_back(triIndexTmp); } sort(triIndexSet.begin(), triIndexSet.end()); return triIndexSet; } void ClusterSort::printSortCluster(){ std::ofstream sortClusterOut; std::ofstream sortIndexOut; sortClusterOut.open("cluster.out.sort", std::ios::out); sortIndexOut.open("sortIndex.out", std::ios::out); sortClusterOut << std::endl; sortClusterOut << " ----------Empty Cluster----------" << std::endl; sortClusterOut << std::endl; sortClusterOut << "index" << std::endl << std::endl; sortClusterOut << "0 " << std::endl; sortIndexOut << "0 " << std::endl; sortClusterOut << std::endl; sortClusterOut << " ----------Point Cluster----------" << std::endl; sortClusterOut << std::endl; sortClusterOut << "sublattice : index" << std::endl << std::endl; sortPointData::iterator it; std::vector::iterator it2; it = sortPoint.begin(); while ( it != sortPoint.end()){ sortClusterOut << std::setw(6) << std::left << ((*it).first)[0] << " : "; it2 = (*it).second.begin(); while ( it2 != (*it).second.end()){ sortClusterOut << *it2 << " "; sortIndexOut << *it2 << " "; ++it2; } sortClusterOut << std::endl; sortIndexOut << std::endl; ++it; } sortClusterOut << std::endl; sortClusterOut << " ----------2 body Cluster----------" << std::endl; sortClusterOut << std::endl; sortClusterOut << "distance : sublattice : pair-index : index " << std::endl << std::endl; sortPairData::iterator itPair; std::vector::const_iterator itDist; std::vector::const_iterator itLattice; std::deque::iterator itIndex; itPair = sortPair.begin(); while ( itPair != sortPair.end()){ itDist = (*itPair).first.first.begin(); itLattice = (*itPair).first.second.begin(); itIndex = (*itPair).second.begin(); while ( itDist != (*itPair).first.first.end()){ sortClusterOut << std::setw(11) << std::left << *itDist << " "; ++itDist; } sortClusterOut << " : "; while ( itLattice != (*itPair).first.second.end()){ sortClusterOut << std::setw(4) << std::left << *itLattice << " "; ++itLattice; } sortClusterOut << " : "; while ( itIndex != (*itPair).second.end()){ if ( itIndex == (*itPair).second.begin() ){ sortClusterOut << std::setw(5) << std::left << *itIndex << " : "; }else{ sortClusterOut << *itIndex << " "; sortIndexOut << *itIndex << " "; } ++itIndex; } sortClusterOut << std::endl; sortIndexOut << std::endl; ++itPair; } std::map, std::vector >, std::deque >::iterator itTri; std::vector::const_iterator itPair2; std::vector::const_iterator itLattice2; std::deque::const_iterator itIndex2; for ( int j = 0; j < sortTri.size(); ++j){ sortClusterOut << std::endl; sortClusterOut << " ----------3 body Cluster----------" << std::endl; sortClusterOut << std::endl; sortClusterOut << "pair-index : sublattice : tri-index : index " << std::endl << std::endl; itTri = sortTri[j].begin(); while ( itTri != sortTri[j].end()){ itPair2 = (*itTri).first.first.begin(); itLattice2 = (*itTri).first.second.begin(); itIndex2 = (*itTri).second.begin(); while ( itPair2 != (*itTri).first.first.end()){ sortClusterOut << std::setw(4) << std::left << *itPair2 << " "; ++itPair2; } sortClusterOut << " : "; while ( itLattice2 != (*itTri).first.second.end()){ sortClusterOut << std::setw(4) << std::left << *itLattice2 << " "; ++itLattice2; } sortClusterOut << " : "; while ( itIndex2 != (*itTri).second.end()){ if ( itIndex2 == (*itTri).second.begin()){ sortClusterOut << std::setw(5) << std::left << *itIndex2 << " : "; }else{ sortClusterOut << *itIndex2 << " "; sortIndexOut << *itIndex2 << " "; } ++itIndex2; } sortClusterOut << std::endl; sortIndexOut << std::endl; ++itTri; } } std::map, std::vector >, std::vector >::iterator itTetra; std::vector::const_iterator itPair3; std::vector::const_iterator itLattice3; std::vector::const_iterator itIndex3; for ( int j = 0; j < sortTetra.size(); ++j){ sortClusterOut << std::endl; sortClusterOut << " ----------4 body Cluster----------" << std::endl; sortClusterOut << std::endl; sortClusterOut << "tri-index : sublattice : index " << std::endl << std::endl; itTetra = sortTetra[j].begin(); while ( itTetra != sortTetra[j].end()){ itPair3 = (*itTetra).first.first.begin(); itLattice3 = (*itTetra).first.second.begin(); itIndex3 = (*itTetra).second.begin(); while ( itPair3 != (*itTetra).first.first.end()){ sortClusterOut << std::setw(4) << std::left << *itPair3 << " "; ++itPair3; } sortClusterOut << " : "; while ( itLattice3 != (*itTetra).first.second.end()){ sortClusterOut << std::setw(4) << std::left << *itLattice3 << " "; ++itLattice3; } sortClusterOut << " : "; while ( itIndex3 != (*itTetra).second.end()){ sortClusterOut << *itIndex3 << " "; sortIndexOut << *itIndex3 << " "; ++itIndex3; } sortClusterOut << std::endl; sortIndexOut << std::endl; ++itTetra; } } sortClusterOut.close(); sortIndexOut.close(); } #endif