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;
138 bool onlyTetrahedral) {
157 int numHC, numDDC, mixedRings, prismaticRings, basalRings;
160 bool doShapeMatching =
true;
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,
290 int totalRingNum = rings.
size();
292 bool cond1, cond2, cond3;
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) {
370 for (
int j = 0; j < peripheralRings.
size(); j++) {
371 jring = peripheralRings[j];
386 notEquatorial[jring] =
true;
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) {
460 (*peripheralRings).
size();
461 sort((*peripheralRings).begin(), (*peripheralRings).end());
463 (*peripheralRings).begin() + numElements);
465 (*peripheralRings).resize(
std::distance((*peripheralRings).begin(), ip));
499 for (
int k = 0; k < ringSize; k++) {
502 for (
int i = k; i < k + 3; i++) {
514 for (
int m = 0; m < (*peripheralRings).size(); m++) {
515 jring = (*peripheralRings)[m];
534 (*peripheralRings).swap(newPeripherals);
538 if ((*peripheralRings).size() > 6) {
540 <<
"There are more than 6 peripheral rings. The code will fail. \n";
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) {
656 int totalRingNum = rings.
size();
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) {
725 prismaticRings.
clear();
729 for (
int k = 0; k < prismaticRings.
size(); k++) {
742 isPrismatic[kring] =
true;
788 int l1 = (*basal1)[0];
789 int l2 = (*basal1)[1];
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]);
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()) {
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()) {
1026 int ringSize = rings[0].size();
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];
1073 if (it == iTriplet.
end()) {
1083 if (common.
size() == 3) {
1085 (*listHC).push_back(kring);
1086 (*prismaticRings).push_back(kring);
1122 int dummyValue = -10;
1126 for (
int iring = 0; iring < (*ringType).size(); 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()) {
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;
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;
1333 int totalRingNum = rings.size();
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);
1432 int l1 = (*basal1)[0];
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]) {
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()) {
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,...
bool notNeighboursOfRing(std::vector< std::vector< int >> nList, std::vector< int > *triplet, std::vector< int > *ring)
bool conditionOneDDC(std::vector< std::vector< int >> rings, std::vector< int > *peripheralRings, int iring)
bool basalNeighbours(std::vector< std::vector< int >> nList, std::vector< int > *triplet, int atomOne, int atomTwo)
bool relaxedPrismConditions(std::vector< std::vector< int >> nList, std::vector< int > *basal1, std::vector< int > *basal2)
std::vector< int > findDDC(std::vector< std::vector< int >> rings, std::vector< strucType > *ringType, std::vector< int > listHC, std::vector< cage::Cage > *cageList)
bool conditionTwoDDC(std::vector< std::vector< int >> rings, std::vector< int > *peripheralRings, int iring)
int getAtomTypesTopoBulk(std::vector< std::vector< int >> rings, std::vector< ring::strucType > ringType, std::vector< cage::iceType > *atomTypes)
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 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 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)
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)
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.
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)
bool conditionThreeDDC(std::vector< std::vector< int >> rings, std::vector< int > *peripheralRings)
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.
std::vector< int > findMixedRings(std::vector< std::vector< int >> rings, std::vector< strucType > *ringType, std::vector< int > *listDDC, std::vector< int > *listHC)
bool basalPrismConditions(std::vector< std::vector< int >> nList, std::vector< int > *basal1, std::vector< int > *basal2)
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)
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 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)
int assignPolygonType(std::vector< std::vector< int >> rings, std::vector< int > *atomTypes, std::vector< int > nRings)
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.