GPUE  v1.0
GPU Gross-Pitaevskii Equation numerical solver for Bose-Einstein condensates
vort.cu
Go to the documentation of this file.
1 #include "../include/vort.h"
2 
3 
4 //@todo Implement this
5 namespace Vtx {
6 
7  Vortex::Vortex():uid(-1){ }
8  Vortex::Vortex(int2 coords, double2 coordsD, int winding, bool isOn, std::size_t timeStep):uid(-1){
9  this->coords = coords; //Coords to the grid
10  this->coordsD = coordsD; //Subgrid coords
11  this->winding = winding; //Charge of vortex
12  this->isOn = isOn; //Whether the vortex still exists, or has died/gone outside boundary
13  this->timeStep = timeStep;
14  }
15  Vortex::~Vortex(){ }
16 
17  void Vortex::updateUID(int uid){
18  this->uid = uid;
19  }
20  void Vortex::updateWinding(int winding){
21  this->winding = winding;
22  }
23  void Vortex::updateIsOn(bool isOn){
24  this->isOn = isOn;
25  }
26  void Vortex::updateCoords(int2 coords){
27  this->coords = coords;
28  }
29  void Vortex::updateCoordsD(double2 coordsD){
30  this->coordsD = coordsD;
31  }
32  void Vortex::updateTimeStep(std::size_t timeStep){
33  this->timeStep = timeStep;
34  }
35 
36  int Vortex::getUID() const{
37  return this->uid;
38  }
39  int Vortex::getWinding() const{
40  return this->winding;
41  }
42  bool Vortex::getIsOn() const{
43  return this->isOn;
44  }
45  int2 Vortex::getCoords() const{
46  return this->coords;
47  }
48  double2 Vortex::getCoordsD() const{
49  return this->coordsD;
50  }
51  std::size_t Vortex::getTimeStep() const{
52  return this->timeStep;
53  }
54 
55 
56 //######################################################################################################################
57 //######################################################################################################################
58 
59  VtxList::VtxList():suid(0) {
60  }
61  VtxList::VtxList(std::size_t reserveSize):suid(0) {
62  vortices.reserve(reserveSize);
63  }
64  VtxList::~VtxList() {
65  this->getVortices().clear();
66  }
67 
68  //Add vortex to end of list.
69  void VtxList::addVtx(std::shared_ptr<Vtx::Vortex> vtx) {
70  this->suid++;
71  this->getVortices().push_back(vtx);
72  }
73  //Add vortex to list at the given idx
74  void VtxList::addVtx(std::shared_ptr<Vtx::Vortex> vtx, std::size_t idx) {
75  vtx->updateUID(++this->suid);
76  this->getVortices().insert(this->vortices.begin() + idx, vtx);
77  }
78 
79  //Will return nullptr if idx is outside the range. Otherwise, removes element at idx, and returns a shared_ptr to it
80  std::shared_ptr<Vtx::Vortex> VtxList::removeVtx(size_t idx) {
81  std::shared_ptr<Vtx::Vortex> v = nullptr;
82  if(idx < this->vortices.size()){
83  v = this->vortices[idx];
84  this->vortices.erase(VtxList::vortices.begin() + idx);
85  }
86  return v;
87  }
88 
89  std::vector<std::shared_ptr<Vtx::Vortex> >& VtxList::getVortices(){
90  return this->vortices;
91  }
92 
93  //Assumes UID exists.
94  std::shared_ptr<Vtx::Vortex> VtxList::getVtx_Uid(int uid){
95  for(auto a : this->vortices){
96  if(a->getUID() != uid){
97  continue;
98  }
99  else
100  return a;
101  }
102  return nullptr;
103  }
104 
105  std::shared_ptr<Vtx::Vortex> VtxList::getVtx_Idx(std::size_t idx) {
106  return this->vortices[idx];
107  }
108 
109  //Assumes UID exists
110  std::size_t VtxList::getVtxIdx_Uid(int uid){
111  for(std::size_t t = 0; t < this->vortices.size(); ++t){
112  if(this->vortices[t]->getUID() != uid){
113  continue;
114  }
115  else
116  return t;
117  }
118  }
119 
120  std::size_t& VtxList::getMax_Uid(){
121  return this->suid;
122  }
123 
124  //Compare the distances between vtx and the vortex list. Used for time-based tracking
125  std::shared_ptr<Vtx::Vortex> VtxList::getVtxMinDist(std::shared_ptr<Vortex> vtx){
126  double dist = std::numeric_limits<double>::max(), distTmp=0.; // Start large
127  double2 pos0 = vtx->getCoordsD(), pos1;
128  std::size_t idx=0;
129  for(std::size_t i=0; i < this->vortices.size(); ++i){
130  pos1 = this->vortices[i]->getCoordsD();
131  distTmp = sqrt(pow(pos0.x-pos1.x,2) + pow(pos0.y - pos1.y,2));
132  if( dist > distTmp && distTmp > 0){
133  dist = distTmp;
134  idx = i;
135  }
136  }
137  return this->vortices[idx];
138  }
139 
140  void VtxList::swapUid(std::shared_ptr<Vtx::Vortex> v1, std::shared_ptr<Vtx::Vortex> v2){
141  std::size_t uid1 = v1->getUID();
142  v1->updateUID(v2->getUID());
143  v2->updateUID(uid1);
144  }
145 
146  void VtxList::swapUid_Idx(std::size_t idx0, std::size_t idx1){
147  std::size_t uid0 = this->vortices[idx0]->getUID();
148  this->vortices[idx0]->updateUID(this->vortices[idx1]->getUID());
149  this->vortices[idx1]->updateUID(uid0);
150  }
151 
152  void VtxList::sortVtxUID(){
153  std::sort(this->getVortices().begin(), this->getVortices().end(),
154  [](std::shared_ptr<Vtx::Vortex> v0, std::shared_ptr<Vtx::Vortex> v1)
155  ->
156  bool{
157  return (v0->getUID() < v1->getUID());
158  }
159  );
160  }
161 
162  void VtxList::setUIDs(std::set<std::shared_ptr<Vtx::Vortex> > &v){
163  for (auto e : this->getVortices()){
164  if(1){
165 
166  }
167  }
168  }
169 
170  void VtxList::arrangeVtx(std::vector<std::shared_ptr<Vtx::Vortex> > &vPrev){
171  std::set<std::shared_ptr<Vtx::Vortex> > sVtx_d01, sVtx_d10, sVtx_inter;
172  //Find the intersection of the UIDs, as well as elements unique to prev or current
173  std::set_intersection(
174  this->getVortices().begin(), this->getVortices().end(),
175  vPrev.begin(), vPrev.end(),
176  std::inserter(sVtx_inter,sVtx_inter.begin()),
177  [](std::shared_ptr<Vtx::Vortex> v0, std::shared_ptr<Vtx::Vortex> v1)
178  ->
179  bool{
180  return (v0->getUID() < v1->getUID());
181  }
182  );
183  std::set_difference(
184  this->getVortices().begin(), this->getVortices().end(),
185  vPrev.begin(), vPrev.end(),
186  std::inserter(sVtx_d01,sVtx_d01.begin()),
187  [](std::shared_ptr<Vtx::Vortex> v0, std::shared_ptr<Vtx::Vortex> v1)
188  ->
189  bool{
190  return (v0->getUID() < v1->getUID());
191  }
192  );
193  std::set_difference(
194  vPrev.begin(), vPrev.end(),
195  this->getVortices().begin(), this->getVortices().end(),
196  std::inserter(sVtx_d10,sVtx_d10.begin()),
197  [](std::shared_ptr<Vtx::Vortex> v0, std::shared_ptr<Vtx::Vortex> v1)
198  ->
199  bool{
200  return (v0->getUID() < v1->getUID());
201  }
202  );
203 
204  std::cout << "####Inter####\n";
205  for (auto e : sVtx_inter){
206  std::cout << (e)->getUID() << std::endl;
207  }
208  std::cout << "####Diff01####\n";
209  for (auto e : sVtx_d01){
210  std::cout << (e)->getUID() << std::endl;
211  }
212  std::cout << "####Diff10####\n";
213  for (auto e : sVtx_d10){
214  std::cout << (e)->getUID() << std::endl;
215  }
216  std::cout << "#######\n";
217 
218 
219  }
220 
221  /* Generate and return a pairing of the distance and closest vortex to vtx */
222  std::pair<double,std::shared_ptr<Vortex>> VtxList::minDistPair(std::shared_ptr<Vortex> vtx, double minRange){
223  /* Ensure the vortex is turned on in the previous run. If not, cannot find a corresponding vortex */
224  if(!vtx->getIsOn())
225  return {-1.,nullptr};
226 
227  /* Vortices are paired with their distance to the respective test candidate vtx */
228  std::vector< std::pair<double, std::shared_ptr<Vortex>> > r_uid;
229  r_uid.reserve(this->getVortices().size());
230 
231  /* Lambda for pairing the vortices and distances */
232  auto pairRDist = [&vtx,&r_uid](VtxList *vL) {
233  for (auto v : vL->getVortices()) {
234  r_uid.push_back(
235  std::make_pair(
236  pow(v->coordsD.x - vtx->coordsD.x, 2)
237  +
238  pow(v->coordsD.y - vtx->coordsD.y, 2),
239  v
240  )
241  );
242  //std::cout << "UIDin=" << vtx->getUID() << " UIDout=" << v->getUID() << " R=" << pow(v->coordsD.x - vtx->coordsD.x, 2) + pow(v->coordsD.y - vtx->coordsD.y, 2) << "\n" ;
243  }
244  };
245  pairRDist(this);
246 
247  /* Lambda for comparison of the vortex distances, to return the vortex with minimum distance */
248  auto compMin = []( std::pair<double,std::shared_ptr<Vortex> >& p0,
249  std::pair<double,std::shared_ptr<Vortex> >& p1
250  ) -> double {
251  return p0.first < p1.first;
252  };
253 
254  /* Need to ensure that the vortex is within the minimal allowed distance for pairing.
255  * Outside of this range, the vortex is considered a different vortex, and so returns
256  * a nullptr, meaning that no vortex is found. */
257  auto pairMin = std::min_element( r_uid.begin(), r_uid.end(), compMin);
258  return {pairMin->first,(pairMin->first <= minRange && pairMin->second->getWinding() == vtx->getWinding()) ? pairMin->second : nullptr};
259  }
260 
261 
262 
263 
264  /*void VtxList::increaseList(){
265  }*/
266 }
267