File size: 6,599 Bytes
8efb4bd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#include "Interface.h"

Interface::Interface(): adjacencyCounter(0){}

void Interface::addAdjacency(unsigned int index1, unsigned int index2, float dist){
  //If an exact entry exists (both indexes are found) - update distance if needed
  InterfaceAdjacency::iterator it1=interfaceAdjacency.find(index1);
  if(it1!=interfaceAdjacency.end()) {//index1 exists
     ParticleAdjacency& pAdjacency = it1->second;
     ParticleAdjacency::iterator it2=pAdjacency.find(index2);
     if(it2!= pAdjacency.end()) {//index2 exists
       if((it2->second).dist() > dist) { // update distance
	 (it2->second).setDistance(dist);
       }
       return;
     }
     else{//index2 does not exist
       Adjacency adjacency(index1, index2, dist);
       adjacencyCounter++;
       pAdjacency[index2]= adjacency;
     }
  }
  else{//index1 doesn't exist
    Adjacency adjacency(index1, index2, dist);
    adjacencyCounter++;
    ParticleAdjacency particleAdjacency;
    particleAdjacency[index2]= adjacency;
    interfaceAdjacency [index1]=particleAdjacency;
  }
}

void Interface::buildHigherLevel(Interface& highLevelInterface,

				 const std::vector<unsigned int>& group1,

				 const std::vector<unsigned int>& group2) {
  for(iterator iter = begin(); iter!= end(); ++iter) {
    const Adjacency& adj=*iter;
    int first = group1[adj.first()];
    int second = group2[adj.second()];
    highLevelInterface.addAdjacency(first, second, adj.dist());
  }
}

bool Interface::isAdjacent(unsigned int index1, unsigned int index2) const {
  InterfaceAdjacency::const_iterator interfaceIt=interfaceAdjacency.find(index1);
  if(interfaceIt!=interfaceAdjacency.end()) {
    ParticleAdjacency::const_iterator particleIt = interfaceIt->second.find(index2);
    if(particleIt!=interfaceIt->second.end())
      return true;
  }
  return false;
}

bool Interface::isInterface(unsigned int index1) const {
  InterfaceAdjacency::const_iterator it=interfaceAdjacency.find(index1);
  if(it!=interfaceAdjacency.end())
    return true;
  return false;
}

unsigned int Interface::size() const {
  return interfaceAdjacency.size();
}

unsigned int Interface::neighboursNumber(unsigned int index1) const {
  InterfaceAdjacency::const_iterator it=interfaceAdjacency.find(index1);
  if(it==interfaceAdjacency.end())
    return 0;
  return it->second.size();
}

void Interface::adjacencies(std::vector<Adjacency>& vAdj, unsigned int index1) const {
  InterfaceAdjacency::const_iterator interfaceIt=interfaceAdjacency.find(index1);
  if(interfaceIt != interfaceAdjacency.end()) {
    vAdj.reserve(interfaceIt->second.size());
    for(ParticleAdjacency::const_iterator particleIt = interfaceIt->second.begin();
	particleIt!=interfaceIt->second.end(); particleIt++)
      vAdj.push_back(particleIt->second);
  }
}

const Interface::ParticleAdjacency& Interface::adjacencies(unsigned int index1) const {
  InterfaceAdjacency::const_iterator interfaceIt=interfaceAdjacency.find(index1);
  static const ParticleAdjacency empty;
  if(interfaceIt != interfaceAdjacency.end())
    return interfaceIt->second;
  return empty;
}

void Interface::neighboursIntersection(const Interface::ParticleAdjacency& pa1,

				       const Interface::ParticleAdjacency& pa2,

				       std::vector<unsigned int>& intersection) const {
  if(pa1.size() > pa2.size())
    return neighboursIntersection(pa2, pa1, intersection);
  intersection.reserve(pa1.size());
  for(ParticleAdjacency::const_iterator it = pa1.begin(); it!=pa1.end(); it++)
    if(pa2.find(it->first)!= pa2.end())
      intersection.push_back(it->first);
}

void Interface::neighboursIntersection(unsigned int index1, unsigned int index2,

				       std::vector<unsigned int>& intersection) const {
  neighboursIntersection(adjacencies(index1), adjacencies(index2), intersection);
}

void Interface::neighboursUnion(const Interface::ParticleAdjacency& pa1,

				const Interface::ParticleAdjacency& pa2,

				std::vector<unsigned int>& nUnion) const {
  if(pa1.size() > pa2.size())
    return neighboursUnion(pa2, pa1, nUnion);
  nUnion.reserve(pa1.size() + pa2.size());
  for(ParticleAdjacency::const_iterator it = pa1.begin(); it!=pa1.end(); it++)
    nUnion.push_back(it->first);
  for(ParticleAdjacency::const_iterator it = pa2.begin(); it!=pa2.end(); it++)
    if(pa1.find(it->first) == pa1.end())
      nUnion.push_back(it->first);
}

void Interface::neighboursUnion(unsigned int index1, unsigned int index2,

				std::vector<unsigned int>& nUnion) const {
  neighboursUnion(adjacencies(index1), adjacencies(index2), nUnion);
}

Interface::iterator::iterator(InterfaceAdjacency::iterator iInterfaceAdjIt,
			      ParticleAdjacency::iterator iParticleAdjIt,
			      InterfaceAdjacency::iterator iInterfaceAdjacencyEnd) {
  interfaceAdjIt=iInterfaceAdjIt;
  particleAdjIt=iParticleAdjIt;
  interfaceAdjacencyEnd=iInterfaceAdjacencyEnd;
}

Interface::iterator Interface::iterator::operator++() {
  if ( ++particleAdjIt == interfaceAdjIt->second.end() )//promote line index. if end of line than
    if( (++interfaceAdjIt) != interfaceAdjacencyEnd )//promote to next line. If not the last line than
      particleAdjIt=interfaceAdjIt->second.begin();//set line index to beginning of line
  return *this;
}

const Interface::Adjacency& Interface::iterator::operator*() const{
  return particleAdjIt->second;
}

inline bool Interface::iterator::operator==(const Interface::iterator& it1) const{
  if(it1.interfaceAdjIt == it1.interfaceAdjacencyEnd &&
     this->interfaceAdjIt == this->interfaceAdjacencyEnd)
    return true;
  else
    return (it1.interfaceAdjIt == this->interfaceAdjIt &&
	    it1.particleAdjIt == this->particleAdjIt );
}

bool Interface::iterator::operator!=(const Interface::iterator& it1) const{
  return !(it1 == *this);
}


Interface::iterator Interface::begin() {
  InterfaceAdjacency::iterator interfaceStart=interfaceAdjacency.begin();
  if ( interfaceAdjacency.empty() ){//interface hash map empty
    ParticleAdjacency::iterator emptyParticleIt=ParticleAdjacency::iterator();
    return iterator(interfaceStart, emptyParticleIt, interfaceStart );
  }
  return iterator( interfaceStart, (interfaceStart->second).begin(), interfaceAdjacency.end() );
}

Interface::iterator Interface::end() {
  InterfaceAdjacency::iterator interfaceEnd=interfaceAdjacency.end();
  ParticleAdjacency::iterator emptyParticleIt=ParticleAdjacency::iterator();
  return iterator( interfaceEnd, emptyParticleIt, interfaceEnd );
}