GPUE  v1.0
GPU Gross-Pitaevskii Equation numerical solver for Bose-Einstein condensates
lattice.cu
Go to the documentation of this file.
1 
2 //######################################################################################################################
3 
4 #include "../include/lattice.h"
5 #include <iostream>
6 
7 using namespace LatticeGraph;
8 
9 //######################################################################################################################
10 //#################################### Ceiling Cat & Basement Cat ###############################################
11 //######################################################################################################################
12 
13 Lattice::Lattice(){
14 }
15 
16 Lattice::~Lattice(){
17  this->getVortices().clear();
18  this->getEdges().clear();
19 }
20 
21 //######################################################################################################################
22 //#################################### Get stuff ###############################################
23 //######################################################################################################################
24 
25 std::vector< std::shared_ptr<Node> >& Lattice::getVortices(){
26  return this->vortices;
27 }
28 
29 std::shared_ptr<Node> Lattice::getVortexIdx(unsigned int idx){
30  return getVortices().at(idx);
31 }
32 
33 /***
34  * Gets the location of the Node with UID uid.
35  */
36 unsigned int Lattice::getVortexIdxUid(unsigned int uid){
37  for (size_t ii=0; ii< getVortices().size(); ++ii){
38  if(this->Lattice::getVortexIdx(ii)->getUid()== uid){
39  return ii;
40  }
41  }
42  return -1;
43 }
44 
45 /***
46  * Gets the the Node with UID uid. Assumes Node exists.
47  */
48 std::shared_ptr<Node> Lattice::getVortexUid(unsigned int uid){
49  for (std::shared_ptr<Node> n : this->Lattice::getVortices()){
50  if(n->getUid()== uid){
51  return n;
52  }
53  }
54  return std::shared_ptr<Node>();
55 }
56 
57 double Lattice::getVortexDistance(std::shared_ptr<Node> n1, std::shared_ptr<Node> n2){
58  return sqrt(pow(n1->getData().getCoords().x - n2->getData().getCoords().x,2)
59  + pow(n1->getData().getCoords().y - n2->getData().getCoords().y,2));
60 }
61 
62 double Lattice::getVortexDistanceD(std::shared_ptr<Node> n1, std::shared_ptr<Node> n2){
63  return sqrt(pow(n1->getData().getCoordsD().x - n2->getData().getCoordsD().x,2)
64  + pow(n1->getData().getCoordsD().y - n2->getData().getCoordsD().y,2));
65 }
66 
67 std::shared_ptr<Edge> Lattice::getEdgeIdx(unsigned int idx){
68  return getEdges().at(idx);
69 }
70 
71 /***
72  * Gets the location of the Edge with UID uid.
73  */
74 unsigned int Lattice::getEdgeIdxUid(unsigned int uid){
75  for (size_t ii=0; ii< getEdges().size(); ++ii){
76  if(this->Lattice::getEdgeIdx(ii)->getUid()== uid){
77  return ii;
78  }
79  }
80  return -1;
81 }
82 
83 /***
84  * Gets the the Edge with UID uid. Assumes Node exists.
85  */
86 std::shared_ptr<Edge> Lattice::getEdgeUid(unsigned int uid){
87  for (std::shared_ptr<Edge> e : this->Lattice::getEdges()){
88  if(e->getUid()== uid){
89  return e;
90  }
91  }
92  return NULL;
93 }
94 
95 std::vector< std::shared_ptr<Edge> >& Lattice::getEdges(){
96  return this->edges;
97 }
98 
99 //######################################################################################################################
100 //#################################### Set stuff ###############################################
101 //######################################################################################################################
102 
103 void Lattice::setVortex(unsigned int idx, std::shared_ptr<Node> n){
104  this->Lattice::getVortices().at(idx)=(n);
105 }
106 
107 void Lattice::setEdge(unsigned int idx, std::shared_ptr<Edge> e){
108  this->Lattice::getEdges().at(idx)=(e);
109 }
110 
111 //######################################################################################################################
112 //#################################### + stuff ###############################################
113 //######################################################################################################################
114 
115 
116 void Lattice::createEdges(unsigned int radius){
117  std::shared_ptr<Edge> e;
118  double dist = 0.0;
119  for(size_t ii=0; ii< this->Lattice::getVortices().size(); ++ii){
120  //std::cout << "Got here ii " << ii << std::endl;
121  for(size_t jj=ii+1; jj < this->Lattice::getVortices().size(); ++jj){
122  dist = Lattice::getVortexDistance(this->getVortexIdx(ii),this->getVortexIdx(jj));
123  if(dist < radius ) {
124  //std::cout << "Got here jj " << jj << std::endl;
125  e.reset(new Edge ( this->getVortexIdx(ii), this->getVortexIdx(jj) ));
126  e->setWeight(dist);
127  this->Lattice::addEdge(e,this->getVortexIdx(ii),this->getVortexIdx(jj));
128  }
129  }
130  }
131 }
132 void Lattice::createEdges(double radius){
133  std::shared_ptr<Edge> e;
134  double dist = 0.0;
135  for(size_t ii=0; ii< this->Lattice::getVortices().size(); ++ii){
136  //std::cout << "Got here ii " << ii << std::endl;
137  for(size_t jj=ii+1; jj < this->Lattice::getVortices().size(); ++jj){
138  dist = Lattice::getVortexDistance(this->getVortexIdx(ii),this->getVortexIdx(jj));
139  if( dist < radius ) {
140  //std::cout << "Got here jj " << jj << std::endl;
141  e.reset(new Edge ( this->getVortexIdx(ii), this->getVortexIdx(jj) ));
142  e->setWeight(dist);
143  this->Lattice::addEdge(e,this->getVortexIdx(ii),this->getVortexIdx(jj));
144  }
145  }
146  }
147 }
148 
149 void Lattice::addVortex(std::shared_ptr<Node> n){
150  this->Lattice::getVortices().push_back((n));
151 }
152 
153 void Lattice::addEdge(std::shared_ptr<Edge> e){
154  this->addEdge(e, e->getVortex(0).lock(), e->getVortex(1).lock());
155 }
156 
157 void Lattice::addEdge(std::shared_ptr<Edge> e, std::shared_ptr<Node> n1, std::shared_ptr<Node> n2){
158  this->Lattice::getEdges().push_back(e);
159  std::weak_ptr<Edge> e1 = e;
160  std::weak_ptr<Edge> e2 = e;
161  n1->addEdge(e1);
162  n2->addEdge(e2);
163 }
164 
165 //######################################################################################################################
166 //#################################### - stuff ###############################################
167 //######################################################################################################################
168 
169 void Lattice::removeVortex(std::shared_ptr<Node> n){
170  for(std::weak_ptr<Edge> e : n->getEdges()){
171  if(e.lock()){
172  std::cout << "UID: Removing Vortex{" << n->getUid() <<"}." << std::endl;
173  this->removeEdge(e.lock());
174  this->Lattice::getVortices().erase(this->Lattice::getVortices().begin() + this->getVortexIdxUid(n->getUid()));
175  }
176  else{
177  std::cout << "Cannot remove UID:Edge{"<< e.lock()->getUid() << "}, does not exist." << std::endl;
178  }
179  }
180 }
181 
182 void Lattice::removeVortexUid(unsigned int uid){
183  auto vtx = this->getVortexUid(uid);
184  if(vtx){
185  this->Lattice::removeVortex(vtx);
186  }
187  else{
188  std::cout << "Cannot remove UID:Vortex{"<< uid << "}, does not exist." << std::endl;
189  }
190 }
191 
192 void Lattice::removeVortexIdx(unsigned int idx){
193  auto vtx = this->getVortexIdx(idx);
194  if(vtx){
195  this->Lattice::removeVortex(vtx);
196  }
197  else{
198  std::cout << "Cannot remove IDX:Vortex["<< idx << "], does not exist." << std::endl;
199  }
200 }
201 
202 void Lattice::removeEdge(std::shared_ptr<Edge> e){
203  std::cout << "Removing Edge{" << e->getUid() <<"} connecting Node{" << e->getVortex(0).lock()->getUid() << "} and Node{" << e->getVortex(1).lock()->getUid() << "}." << std::endl;
204  e->getVortex(0).lock()->removeEdgeUid(e->getUid());
205  e->getVortex(1).lock()->removeEdgeUid(e->getUid());
206  this->Lattice::getEdges().erase(this->Lattice::getEdges().begin() + this->Lattice::getEdgeIdxUid(e->getUid()));
207 }
208 
209 void Lattice::removeEdgeIdx(unsigned int idx){
210  std::weak_ptr<Edge> e = this->getEdgeIdx(idx);
211  if (auto el = e.lock()) {
212  this->Lattice::removeEdge(el);
213  }
214  else{
215  std::cout << "Cannot remove IDX:Edge[" << idx << "], does not exist." << std::endl;
216  }
217 }
218 
219 void Lattice::removeEdgeUid(unsigned int uid) {
220  std::weak_ptr<Edge> e = this->getEdgeUid(uid);
221  if (auto el = e.lock()) {
222  this->Lattice::removeEdge(el);
223  }
224  else{
225  std::cout << "Cannot remove UID:Edge{" << uid << "}, does not exist." << std::endl;
226  }
227 }
228 
229 void Lattice::removeEdge(std::shared_ptr<Node> n1, std::shared_ptr<Node> n2){
230  std::weak_ptr<Edge> e = this->Lattice::isConnected(n1,n2);
231  if(e.lock()){
232  this->Lattice::removeEdge(e.lock());
233  }
234  else{
235  std::cout << "Node{" << n1->getUid() << "} and Node{" << n2->getUid() << "} were unconnected." << std::endl;
236  }
237 
238 }
239 
240 void Lattice::removeEdges(std::shared_ptr<Node> n1){
241  //n1->removeEdges();
242 }
243 
244 
245 void Lattice::createVortex(double posx, double posy, int winding){
246 
247 }
248 
249 void Lattice::destroyVortex(unsigned int uid){
250  this->Lattice::getVortexUid(uid);
251 }
252 
253 
254 
255 //######################################################################################################################
256 //#################################### Generate stuff ###############################################
257 //######################################################################################################################
258 
259 /**
260  * Create adjacency matrix
261  */
262 void Lattice::genAdjMat(unsigned int *mat){
263  int idx1, idx2, idx;
264  idx1 = 0; idx2 = 0; idx=0;
265  for(std::shared_ptr<Node> n : this->Lattice::getVortices()){
266  idx1=this->getVortexIdxUid(n->getUid());
267  for(std::weak_ptr<Edge> e : n->getEdges()){
268  idx2 = this->getVortexIdxUid(n->getConnectedNode(e.lock())->getUid());
269  //std::cout << "this=" << n->getUid() << " connected=" << n->getConnectedNode(e.lock())->getUid() << std::endl;
270  idx = idx1*this->Lattice::getVortices().size() + idx2;
271  //std::cout << "idx1=" << idx1 << " idx2=" << idx2 << " idx=" << idx << "\n" << std::endl;
272  mat[idx] = 1;
273  }
274  }
275 }
276 
277 void Lattice::genAdjMat(double *mat){
278  int idx1, idx2, idx;
279  idx1 = 0; idx2 = 0; idx=0;
280  for(std::shared_ptr<Node> n : this->Lattice::getVortices()){
281  idx1=this->getVortexIdxUid(n->getUid());
282  for(std::weak_ptr<Edge> e : n->getEdges()){
283  idx2 = this->getVortexIdxUid(n->getConnectedNode(e.lock())->getUid());
284  //std::cout << "this=" << n->getUid() << " connected=" << n->getConnectedNode(e.lock())->getUid() << std::endl;
285  idx = idx1*this->Lattice::getVortices().size() + idx2;
286  //std::cout << "idx1=" << idx1 << " idx2=" << idx2 << " idx=" << idx << "\n" << std::endl;
287  mat[idx] = this->Lattice::getVortexDistance(n, this->getVortexIdx(idx2));
288  }
289  }
290 }
291 
292 /**
293  *
294  * Outputs adjacency matrix in format for copy/paste into Mathematica.
295  */
296 void Lattice::adjMatMtca(unsigned int *mat){
297  unsigned int size = this->Lattice::getVortices().size();
298  std::cout << "{";
299  for(size_t ii = 0; ii < size; ++ii){
300  std::cout << "{";
301  for(size_t jj = 0; jj < size; ++jj){
302  std::cout << mat[ii*size + jj];
303  if(jj<size-1)
304  std::cout <<",";
305  else
306  std::cout << "}";
307  }
308  if(ii<size-1)
309  std::cout <<",";
310  std::cout << std::endl;
311  }
312  std::cout << "}" << std::endl;
313 }
314 void Lattice::adjMatMtca(double *mat){
315  unsigned int size = this->Lattice::getVortices().size();
316  std::cout << "{";
317  for(size_t ii = 0; ii < size; ++ii){
318  std::cout << "{";
319  for(size_t jj = 0; jj < size; ++jj){
320  std::cout << mat[ii*size + jj];
321  if(jj<size-1)
322  std::cout <<",";
323  else
324  std::cout << "}";
325  }
326  if(ii<size-1)
327  std::cout <<",";
328  std::cout << std::endl;
329  }
330  std::cout << "}" << std::endl;
331 }
332 
333 //######################################################################################################################
334 //#################################### Check stuff ###############################################
335 //######################################################################################################################
336 
337 std::weak_ptr<Edge> Lattice::isConnected(std::shared_ptr<Node> n1, std::shared_ptr<Node> n2){
338 
339  if(n1->getUid() != n2->getUid()){
340  for(std::weak_ptr<Edge> e1 : n1->getEdges()){
341  if(e1.lock()->isMember(n2)){
342  return e1;
343  }
344  }
345  }
346  return std::weak_ptr<Edge> ();
347 }
348 
349 //######################################################################################################################
350 //#################################### Modify stuff ###############################################
351 //######################################################################################################################
352 
353 void Lattice::swapIdxUid(unsigned int uid1, unsigned int uid2) {
354  Lattice::swapIdx(this->getVortexIdxUid(uid1),this->getVortexIdxUid(uid2));
355 }
356 void Lattice::swapIdx(unsigned int idx1, unsigned int idx2) {
357  std::swap(this->getVortices().at(idx1),this->getVortices().at(idx2));
358 }
359 //void Lattice::swapVort(std::shared_ptr<Node> v1, std::shared_ptr<Node> v2) {
360 
361 //}
362 
363 //######################################################################################################################