45 std::string path, std::vector<std::vector<int>> rings,
46 std::vector<std::vector<int>> nList,
50 std::vector<std::vector<int>>
53 std::vector<int> nRingList;
63 atomTypes.resize(yCloud->nop, 1);
67 for (
int ringSize = 3; ringSize <= maxDepth; ringSize++) {
74 if (ringsOneType.size() == 0) {
75 nRingList[ringSize - 3] = 0;
81 nRings = ringsOneType.size();
84 nRingList[ringSize - 3] = nRings;
135 std::string path, std::vector<std::vector<int>> rings,
136 std::vector<std::vector<int>> nList,
138 bool onlyTetrahedral) {
141 std::vector<int> listDDC;
142 std::vector<int> listHC;
145 std::vector<ring::strucType>
149 std::vector<cage::Cage> cageList;
150 std::vector<std::vector<int>>
154 std::vector<cage::iceType>
157 int numHC, numDDC, mixedRings, prismaticRings, basalRings;
160 bool doShapeMatching =
true ;
162 std::vector<double> rmsdPerAtom;
176 if (onlyTetrahedral) {
183 atomTypes.resize(yCloud->nop);
185 rmsdPerAtom.resize(yCloud->nop);
190 for (
int ringSize = initRingSize; ringSize <= maxRingSize; ringSize++) {
196 if (ringsOneType.size() == 0) {
202 ringsOneType.size());
208 listHC =
ring::findHC (ringsOneType, &ringType, nList, &cageList);
211 listDDC =
ring::findDDC (ringsOneType, &ringType, listHC, &cageList);
221 &prismaticRings, &basalRings);
225 mixedRings, basalRings, prismaticRings,
286 std::vector<ring::strucType> *ringType,
287 std::vector<int> listHC,
288 std::vector<cage::Cage> *cageList) {
289 std::vector<int> listDDC;
290 int totalRingNum = rings.size();
291 std::vector<int> peripheralRings;
292 bool cond1, cond2, cond3;
294 std::vector<int> DDCRings;
299 notEquatorial.resize(totalRingNum);
303 for (
int i = 0; i < listHC.size(); i++) {
304 int currentRingIndex = listHC[i];
306 notEquatorial[currentRingIndex] =
true ;
312 for (
int iring = 0; iring < totalRingNum; iring++) {
318 if (notEquatorial[iring]) {
324 peripheralRings.clear();
329 if (cond1 ==
false ) {
338 if (cond2 ==
false ) {
350 if (cond3 ==
false ) {
355 sort(peripheralRings.begin(), peripheralRings.end());
356 peripheralRings.erase(
357 unique(peripheralRings.begin(), peripheralRings.end()),
358 peripheralRings.end());
360 if (peripheralRings.size() != 6) {
367 listDDC.push_back(iring);
370 for (
int j = 0; j < peripheralRings.size(); j++) {
371 jring = peripheralRings[j];
374 listDDC.push_back(jring);
377 listDDC.push_back(jring);
382 listDDC.push_back(jring);
386 notEquatorial[jring] =
true ;
390 DDCRings.push_back(iring);
391 DDCRings.insert(std::end(DDCRings), std::begin(peripheralRings),
392 std::end(peripheralRings));
417 std::vector<int> *peripheralRings,
int iring) {
419 int noOfCommonRings =
424 for (
int m = 0; m < 6; m++) {
425 index = rings[iring][m];
428 for (
int jring = 0; jring < rings.size(); jring++) {
429 if (iring == jring) {
434 for (
int k = 0; k < 6; k++) {
435 jElement = rings[jring][k];
436 if (jElement == index) {
438 (*peripheralRings).push_back(jring);
449 if (noOfCommonRings < 3) {
456 std::vector<int>::iterator ip;
460 (*peripheralRings).size();
461 sort((*peripheralRings).begin(), (*peripheralRings).end());
462 ip = std::unique((*peripheralRings).begin(),
463 (*peripheralRings).begin() + numElements);
465 (*peripheralRings).resize(std::distance((*peripheralRings).begin(), ip));
489 std::vector<int> *peripheralRings,
int iring) {
490 std::vector<int> triplet;
499 for (
int k = 0; k < ringSize; k++) {
502 for (
int i = k; i < k + 3; i++) {
507 triplet.push_back(rings[iring][j]);
514 for (
int m = 0; m < (*peripheralRings).size(); m++) {
515 jring = (*peripheralRings)[m];
521 newPeripherals.push_back(jring);
534 (*peripheralRings).swap(newPeripherals);
538 if ((*peripheralRings).size() > 6) {
540 <<
"There are more than 6 peripheral rings. The code will fail. \n" ;
570 std::vector<int> *peripheralRings) {
572 std::vector<int> common;
579 rings[(*peripheralRings)[2]],
580 rings[(*peripheralRings)[4]]);
590 rings[(*peripheralRings)[3]],
591 rings[(*peripheralRings)[5]]);
603 for (
int i = 0; i <= 3; i++) {
606 iring = (*peripheralRings)[i];
607 jring = (*peripheralRings)[i + 2];
611 if (common.size() < 3) {
652 std::vector<ring::strucType> *ringType,
653 std::vector<std::vector<int>> nList,
654 std::vector<cage::Cage> *cageList) {
655 std::vector<int> listHC;
656 int totalRingNum = rings.size();
657 std::vector<int> basal1;
658 std::vector<int> basal2;
663 std::vector<int> prismaticRings;
668 isPrismatic.resize(totalRingNum);
671 for (
int iring = 0; iring < totalRingNum - 1; iring++) {
674 if (isPrismatic[iring]) {
680 basal1 = rings[iring];
682 for (
int jring = iring + 1; jring < totalRingNum; jring++) {
685 if (isPrismatic[jring]) {
689 basal2 = rings[jring];
703 if (cond2 ==
false ) {
711 listHC.push_back(iring);
714 listHC.push_back(iring);
719 listHC.push_back(jring);
722 listHC.push_back(jring);
725 prismaticRings.clear();
729 for (
int k = 0; k < prismaticRings.size(); k++) {
735 listHC.push_back(kring);
738 listHC.push_back(kring);
742 isPrismatic[kring] =
true ;
749 HCRings.push_back(iring);
750 HCRings.push_back(jring);
752 HCRings.insert(std::end(HCRings), std::begin(prismaticRings),
753 std::end(prismaticRings));
759 sort(listHC.begin(), listHC.end());
760 auto ip = std::unique(listHC.begin(), listHC.end());
762 listHC.resize(std::distance(listHC.begin(), ip));
787 std::vector<int> *basal1, std::vector<int> *basal2) {
788 int l1 = (*basal1)[0];
789 int l2 = (*basal1)[1];
795 std::vector<int> evenTriplet;
796 std::vector<int> oddTriplet;
797 int compare1, compare2;
799 bool l1_neighbour, l2_neighbour;
801 bool isNeigh, notNeigh;
806 for (
int k = 0; k < ringSize; k++) {
808 l1_neighbour =
false ;
809 l2_neighbour =
false ;
814 auto it1 = std::find(nList[l1].begin() + 1, nList[l1].end(), m_k);
816 if (it1 != nList[l1].end()) {
817 compare1 = (*basal1)[2];
818 compare2 = (*basal1)[4];
825 auto it2 = std::find(nList[l2].begin() + 1, nList[l2].end(), m_k);
827 if (it2 != nList[l2].end()) {
828 compare1 = (*basal1)[3];
829 compare2 = (*basal1)[5];
841 if (l1_neighbour ==
false && l2_neighbour ==
false ) {
848 for (
int k = 0; k <= 5; k++) {
849 currentKindex = kIndex + k;
851 if (currentKindex >= ringSize) {
852 currentKindex -= ringSize;
857 evenTriplet.push_back((*basal2)[currentKindex]);
861 oddTriplet.push_back((*basal2)[currentKindex]);
909 std::vector<int> *triplet,
int atomOne,
912 int needle1 = (*triplet)[1];
913 int needle2 = (*triplet)[2];
914 bool neighbourFound =
false ;
915 bool neighOne =
false ,
921 std::find(nList[atomOne].begin() + 1, nList[atomOne].end(), needle1);
922 if (it != nList[atomOne].end()) {
923 neighbourFound =
true ;
928 it = std::find(nList[atomTwo].begin() + 1, nList[atomTwo].end(), needle1);
929 if (it != nList[atomTwo].end()) {
930 neighbourFound =
true ;
936 if (neighbourFound ==
false ) {
945 it = std::find(nList[atomTwo].begin() + 1, nList[atomTwo].end(), needle2);
947 if (it != nList[atomTwo].end()) {
959 it = std::find(nList[atomOne].begin() + 1, nList[atomOne].end(), needle2);
961 if (it != nList[atomOne].end()) {
982 std::vector<int> *triplet,
983 std::vector<int> *
ring ) {
987 std::vector<int>::iterator it;
989 for (
int i = 0; i < (*triplet).size(); i++) {
990 iatom = (*triplet)[i];
993 for (
int j = 0; j < (*ring).size(); j++) {
997 it = std::find(nList[jatom].begin() + 1, nList[jatom].end(), iatom);
999 if (it != nList[jatom].end()) {
1022 std::vector<int> *listHC,
1023 std::vector<ring::strucType> *ringType,
int iring,
1024 int jring, std::vector<int> *prismaticRings) {
1026 int ringSize = rings[0].size();
1027 std::vector<int> iTriplet;
1028 std::vector<int> jTriplet;
1029 std::vector<int> common;
1032 for (
int i = 0; i < ringSize; i++) {
1037 for (
int m = 0; m < 3; m++) {
1039 if (iIndex >= ringSize) {
1042 iTriplet.push_back(rings[iring][iIndex]);
1048 for (
int kring = 0; kring < rings.size(); kring++) {
1050 if (kring == iring || kring == jring) {
1059 if (common.size() != 3) {
1068 for (
int j = 0; j < ringSize; j++) {
1069 int katom = rings[kring][j];
1070 auto it = std::find(iTriplet.begin(), iTriplet.end(), katom);
1073 if (it == iTriplet.end()) {
1074 jTriplet.push_back(katom);
1083 if (common.size() == 3) {
1085 (*listHC).push_back(kring);
1086 (*prismaticRings).push_back(kring);
1118 std::vector<strucType> *ringType,
1119 std::vector<int> *listDDC,
1120 std::vector<int> *listHC) {
1121 std::vector<int> listMixed;
1122 int dummyValue = -10;
1126 for (
int iring = 0; iring < (*ringType).size(); iring++) {
1130 listMixed.push_back(iring);
1134 std::sort((*listDDC).begin(), (*listDDC).end());
1135 auto iter = std::find((*listDDC).begin(), (*listDDC).end(), iring);
1136 if (iter != (*listDDC).end()) {
1142 std::sort((*listHC).begin(), (*listHC).end());
1143 auto itr = std::find((*listHC).begin(), (*listHC).end(), iring);
1144 if (itr != (*listHC).end()) {
1165 std::vector<ring::strucType> ringType,
1166 std::vector<cage::iceType> *atomTypes) {
1169 int ringSize = rings[0].size();
1172 for (
int iring = 0; iring < ringType.size(); iring++) {
1210 for (
int i = 0; i < ringSize; i++) {
1211 iatom = rings[iring][i];
1217 if (ringSize == 6) {
1221 (*atomTypes)[iatom] = iRingType;
1224 (*atomTypes)[iatom] = iRingType;
1248 std::vector<cage::Cage> cageList,
int *numHC,
1249 int *numDDC,
int *mixedRings,
int *prismaticRings,
1256 *prismaticRings = 0;
1261 for (
int icage = 0; icage < cageList.size(); icage++) {
1276 for (
int iring = 0; iring < ringType.size(); iring++) {
1287 *prismaticRings += 1;
1293 *prismaticRings += 1;
1329 std::vector<std::vector<int>> rings, std::vector<ring::strucType> *ringType,
1330 std::vector<std::vector<int>> nList,
1332 std::vector<double> *rmsdPerAtom,
double heightCutoff) {
1333 int totalRingNum = rings.size();
1334 std::vector<int> basal1;
1335 std::vector<int> basal2;
1337 int ringSize = rings[0].size();
1339 Eigen::MatrixXd refPointSet(ringSize, 3);
1346 for (
int iring = 0; iring < totalRingNum - 1; iring++) {
1349 basal1 = rings[iring];
1351 for (
int jring = iring + 1; jring < totalRingNum; jring++) {
1352 basal2 = rings[jring];
1359 if (cond1 ==
true ) {
1373 &basal1, &basal2, rmsdPerAtom);
1430 std::vector<int> *basal1,
1431 std::vector<int> *basal2) {
1432 int l1 = (*basal1)[0];
1440 std::vector<bool> isNeighbour(ringSize,
false );
1447 for (
int k = 0; k < ringSize; k++) {
1448 l1_neighbour =
false ;
1453 auto it = std::find(nList[l1].begin() + 1, nList[l1].end(), m_k);
1456 if (it != nList[l1].end()) {
1457 l1_neighbour =
true ;
1465 if (!l1_neighbour) {
1471 isNeighbour[kIndex] =
true ;
1474 for (
int i = 1; i < ringSize; i++) {
1475 lAtomID = (*basal1)[i];
1476 for (
int k = 0; k < ringSize; k++) {
1478 if (isNeighbour[k]) {
1482 kAtomID = (*basal2)[k];
1487 std::find(nList[lAtomID].begin() + 1, nList[lAtomID].end(), kAtomID);
1490 if (it1 != nList[lAtomID].end()) {
1491 isNeighbour[k] =
true ;
1499 for (
int k = 0; k < ringSize; k++) {
1501 if (!isNeighbour[k]) {
1517 std::vector<int> *basal1,
1518 std::vector<int> *basal2) {
1522 bool isNeighbour =
false ;
1529 for (
int l = 0; l < ringSize; l++) {
1533 for (
int m = 0; m < ringSize; m++) {
1536 auto it = std::find(nList[l_k].begin() + 1, nList[l_k].end(), m_k);
1539 if (it != nList[l_k].end()) {
1559 std::vector<int> basal1, std::vector<int> basal2,
double heightCutoff) {
1561 int ringSize = basal1.size();
1563 double infHugeNumber = 100000;
1564 double leastDist = infHugeNumber;
1572 for (
int m = 0; m < ringSize; m++) {
1579 if (leastDist > dist) {
1587 if (leastDist < heightCutoff) {
double periodicDist(molSys::PointCloud< molSys::Point< double >, double > *yCloud, int iatom, int jatom)
Inline generic function for obtaining the unwrapped periodic distance between two particles,...
int getAtomTypesTopoBulk(std::vector< std::vector< int > > rings, std::vector< ring::strucType > ringType, std::vector< cage::iceType > *atomTypes)
bool notNeighboursOfRing(std::vector< std::vector< int > > nList, std::vector< int > *triplet, std::vector< int > *ring)
bool conditionTwoDDC(std::vector< std::vector< int > > rings, std::vector< int > *peripheralRings, int iring)
bool conditionOneDDC(std::vector< std::vector< int > > rings, std::vector< int > *peripheralRings, int iring)
bool basalPrismConditions(std::vector< std::vector< int > > nList, std::vector< int > *basal1, std::vector< int > *basal2)
bool basalConditions(std::vector< std::vector< int > > nList, std::vector< int > *basal1, std::vector< int > *basal2)
Tests whether two rings are basal rings (true) or not (false)
bool conditionThreeDDC(std::vector< std::vector< int > > rings, std::vector< int > *peripheralRings)
int topoBulkAnalysis(std::string path, std::vector< std::vector< int > > rings, std::vector< std::vector< int > > nList, molSys::PointCloud< molSys::Point< double >, double > *yCloud, int firstFrame, bool onlyTetrahedral=true)
int findBulkPrisms(std::vector< std::vector< int > > rings, std::vector< ring::strucType > *ringType, std::vector< std::vector< int > > nList, molSys::PointCloud< molSys::Point< double >, double > *yCloud, std::vector< double > *rmsdPerAtom, double heightCutoff=8)
Find out which rings are prisms.
int getStrucNumbers(std::vector< ring::strucType > ringType, std::vector< cage::Cage > cageList, int *numHC, int *numDDC, int *mixedRings, int *prismaticRings, int *basalRings)
Determines the number of HCs, DDCs, Mixed rings, prismatic and basal rings.
bool basalNeighbours(std::vector< std::vector< int > > nList, std::vector< int > *triplet, int atomOne, int atomTwo)
std::vector< int > findDDC(std::vector< std::vector< int > > rings, std::vector< strucType > *ringType, std::vector< int > listHC, std::vector< cage::Cage > *cageList)
bool basalRingsSeparation(molSys::PointCloud< molSys::Point< double >, double > *yCloud, std::vector< int > basal1, std::vector< int > basal2, double heightCutoff=8)
Check to see that candidate basal prisms are not really far from each other.
bool relaxedPrismConditions(std::vector< std::vector< int > > nList, std::vector< int > *basal1, std::vector< int > *basal2)
int bulkPolygonRingAnalysis(std::string path, std::vector< std::vector< int > > rings, std::vector< std::vector< int > > nList, molSys::PointCloud< molSys::Point< double >, double > *yCloud, int maxDepth, int firstFrame)
std::vector< int > findHC(std::vector< std::vector< int > > rings, std::vector< strucType > *ringType, std::vector< std::vector< int > > nList, std::vector< cage::Cage > *cageList)
int findPrismatic(std::vector< std::vector< int > > rings, std::vector< int > *listHC, std::vector< strucType > *ringType, int iring, int jring, std::vector< int > *prismaticRings)
Finds the prismatic rings from basal rings iring and jring.
std::vector< int > findMixedRings(std::vector< std::vector< int > > rings, std::vector< strucType > *ringType, std::vector< int > *listDDC, std::vector< int > *listHC)
bool commonElementsInThreeRings(std::vector< int > ring1, std::vector< int > ring2, std::vector< int > ring3)
Common elements in 3 rings.
bool findTripletInRing(std::vector< int > ring, std::vector< int > triplet)
Searches a particular ring for a triplet.
int assignPolygonType(std::vector< std::vector< int > > rings, std::vector< int > *atomTypes, std::vector< int > nRings)
int clearRingList(std::vector< std::vector< int > > &rings)
Erases memory for a vector of vectors for a list of rings.
bool hasCommonElements(std::vector< int > ring1, std::vector< int > ring2)
std::vector< std::vector< int > > getSingleRingSize(std::vector< std::vector< int > > rings, int ringSize)
Returns a vector of vectors of rings of a single size.
std::vector< int > findsCommonElements(std::vector< int > ring1, std::vector< int > ring2)
Returns the common elements of two rings.
@ HCbasal
The ring belongs only to a hexagonal cage (HC). Specifically, the ring is purely a basal ring of an H...
@ DDC
The ring belongs to a double-diamond cage (DDC).
@ bothPrismatic
The ring belongs to both a DDC and HC and is, thus, a 'mixed' ring. The ring is also one of the prism...
@ Prism
The ring belongs to a prism block, classified according to the prism identification scheme.
@ bothBasal
The ring belongs to both a DDC and HC. It is a 'mixed' ring. The ring is also one of the basal rings ...
@ HCprismatic
The ring belongs only to a hexagonal cage (HC); specifically the ring is purely a prismatic ring of a...
@ unclassified
The ring is unclassified, which may be either water or a deformed type which cannot be classified by ...
bool matchUntetheredPrism(molSys::PointCloud< molSys::Point< double >, double > *yCloud, std::vector< std::vector< int > > nList, const Eigen::MatrixXd &refPoints, std::vector< int > *basal1, std::vector< int > *basal2, std::vector< double > *rmsdPerAtom)
Eigen::MatrixXd getPointSetRefRing(int n, int axialDim)
Topological network criteria functions.
int writeRingNumBulk(std::string path, int currentFrame, std::vector< int > nRings, int maxDepth, int firstFrame)
int writeLAMMPSdataAllRings(molSys::PointCloud< molSys::Point< double >, double > *yCloud, std::vector< std::vector< int > > nList, std::vector< int > atomTypes, int maxDepth, std::string path, bool isMonolayer=true)
Write a data file for rings of every type for a monolayer.
int writeTopoBulkData(std::string path, int currentFrame, int numHC, int numDDC, int mixedRings, int basalRings, int prismaticRings, int firstFrame)
int writeLAMMPSdataTopoBulk(molSys::PointCloud< molSys::Point< double >, double > *yCloud, std::vector< std::vector< int > > nList, std::vector< cage::iceType > atomTypes, std::string path, bool bondsBetweenDummy=false)
This contains a collection of points; contains information for a particular frame.
This contains per-particle information.
File containing functions used specific to bulk topological network critera.
Copy