00001 #include "virtual_disp.h"
00002
00003 #include <iostream>
00004 #include <cmath>
00005 #include <cassert>
00006
00007 #include "container.h"
00008 #include "gain_schedule.h"
00009 #include "misc.h"
00010 #include "object.h"
00011 #include "vertex.h"
00012
00013 using std::cout;
00014 using std::endl;
00015
00016 Virtual_Disp * Virtual_Disp::only_one = NULL;
00017
00018 Virtual_Disp & Virtual_Disp::instance(void)
00019 {
00020
00021
00022 if (only_one == NULL)
00023 only_one = new Virtual_Disp();
00024
00025 return *only_one;
00026 }
00027
00028 Virtual_Disp::Virtual_Disp (const Virtual_Disp & rhs)
00029 :topN(),old(),tvi()
00030 {
00031 cout << "Copy constructor prohibited on instances of Virtual_Disp class.\n";
00032 cout << "Virtual_Disp " << rhs.topN.size() << endl;
00033 exit(0);
00034 }
00035
00036 Virtual_Disp::Virtual_Disp (void)
00037 :topN(),old(),tvi()
00038 {
00039 }
00040
00041 Virtual_Disp& Virtual_Disp::operator= (const Virtual_Disp& rhs)
00042 {
00043 cout << "Copy assignment operator prohibited on instances of Virtual_Disp class.\n";
00044 cout << "Virtual_Disp " << rhs.topN.size() << endl;
00045 exit(0);
00046 }
00047
00048 void Virtual_Disp::saveOld (void)
00049 {
00050 old.clear();
00051
00052 for(tv_it i=topN.begin();i!=topN.end();i++)
00053 {
00054 assert((*i).second!=NULL);
00055
00056 old[(*i).second]=(*i).first;
00057 }
00058 }
00059
00060 void Virtual_Disp::updateTopN (Vertex * const v,double const vd_old,double const vd_new,bool const flag)
00061 {
00062 if (flag)
00063 {
00064 tv_it t;
00065
00066 if (entryInTopN(v,vd_old,t))
00067 {
00068
00069 topN.erase(t);
00070 } else {
00071 }
00072 }
00073
00074 topN.insert(std::make_pair(vd_new,v));
00075 }
00076
00077 bool Virtual_Disp::entryInTopN (Vertex * const v,double const vd_old,tv_it &j)
00078 {
00079
00080 std::pair<tv_it,tv_it> p;
00081 p=topN.equal_range(vd_old);
00082
00083 if(p.first==p.second){return false;}
00084
00085 else
00086 {
00087
00088 for(tv_it i=p.first;i!=p.second;i++)
00089 {
00090
00091 if(v==(*i).second)
00092 {
00093
00094 j = i;
00095 return true;
00096 }
00097 }
00098 cout.precision(9);
00099 cout << "\n\nVirtual_Disp::entryInTopN: Error. Matching multimap element not found.\n";
00100 v->print(std::cout);
00101 cout << "\nold vd " << vd_old << endl << endl;
00102
00103 for(tv_it i=p.first;i!=p.second;i++)
00104 {
00105 assert((*i).second!=NULL);
00106 if ((*i).second==NULL)
00107 {
00108 cout << "topN contains ["
00109 << (*i).first << " , NULL]\n";
00110 }
00111 else
00112 {
00113 cout << "topN contains ["
00114 << (*i).first << " , "
00115 << (*i).second->getIndex() << "]\n";
00116 }
00117 }
00118 bool booyah=true;
00119 for(tv_it i=topN.begin();i!=topN.end();i++)
00120 {
00121 if((*i).second==v)
00122 {
00123 cout << "current vertex found in topN: "
00124 << " vertex " << (*i).second->getIndex()
00125 << " " << (*i).first << endl << endl;
00126 booyah = false;
00127 }
00128 }
00129 if(booyah==true)
00130 {
00131 cout << "Problem vertex was NOT found anywhere in topN.\n";
00132 }
00133 exit(0);
00134 }
00135 }
00136
00137 void Virtual_Disp::updateOld (Vertex * const v,double const new_vd)
00138 {
00139 old[v]=new_vd;
00140 }
00141
00142 void Virtual_Disp::loadTopN (void)
00143 {
00144 cout << "Computing vertex virtual displacements.........";
00145 cout.flush();
00146 topN.clear();
00147
00148 for(o_it j=Container::instance().o.begin();j!=Container::instance().o.end();j++)
00149 {
00150
00151 for(v_it i=j->v.begin();i!=j->v.end();i++)
00152 {
00153
00154 if(i->getFace()!=NULL)
00155 {
00156
00157
00158
00159 vec_d p = i->getNewPos(Gain_Schedule::instance().getGain());
00160
00161 double vd = (p[0]-i->getCoord(0))*(p[0]-i->getCoord(0))+
00162 (p[1]-i->getCoord(1))*(p[1]-i->getCoord(1))+
00163 (p[2]-i->getCoord(2))*(p[2]-i->getCoord(2));
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 if(i->getFace()==NULL)
00177 {
00178 cout << "WHAT THE! It just had a closest and now it doesn't. What changed?\n";
00179 exit(0);
00180 }
00181 topN.insert(std::make_pair(vd,&(*i)));
00182
00183 }
00184 }
00185 }
00186 cout << "complete.\n";
00187 cout.flush();
00188 }
00189
00190 void Virtual_Disp::updateVirtualDisp (Vertex * const v,bool const flag)
00191 {
00192
00193 if(flag)
00194 {
00195
00196 updateSets(v,v->getSqVirtualDisp(Gain_Schedule::instance().getGain()));
00197 }
00198 else
00199 {
00200
00201 removeVertex(v);
00202 }
00203 }
00204
00205 void Virtual_Disp::updateSets (Vertex * const v,double const new_sqD)
00206 {
00207 assert(new_sqD<1E10);
00208
00209 if(old.find(v)!=old.end())
00210 {
00211 updateTopN(v,old[v],new_sqD,true);
00212 }
00213
00214 else
00215 {
00216 updateTopN(v,0.0,new_sqD,false);
00217 }
00218 updateOld(v,new_sqD);
00219 }
00220
00221 void Virtual_Disp::cleanTopN (Vertex * const v,double const vd_old)
00222 {
00223 tv_it t;
00224
00225 if (entryInTopN(v,vd_old,t))
00226 {
00227
00228 if(v->isMatch(TARGET_VERTEX_INDEX_1,TARGET_VERTEX_NAME_1)==true)
00229 {
00230 cout << "Virtual_Disp::cleanTopN: target vertex was removed from topN.\n";
00231 }
00232
00233
00234 topN.erase(t);
00235 }
00236 }
00237
00238 void Virtual_Disp::prep (void)
00239 {
00240 loadTopN();
00241 saveOld();
00242 }
00243
00244 bool Virtual_Disp::findTopN (Vertex * const vv,tv_it &tt,int &rank)
00245 {
00246
00247
00248 bool found=false;
00249 rank=0;
00250
00251 for(tv_it i=topN.begin();i!=topN.end();i++)
00252 {
00253
00254 if((*i).second==vv)
00255 {
00256 tt=i;
00257 found=true;
00258 break;
00259 }
00260 rank++;
00261 }
00262 return found;
00263 }
00264
00265 void Virtual_Disp::validateMultimap (void) const
00266 {
00268
00269 v_set uniq_set;
00270
00271 for(tv_cit i=topN.begin();i!=topN.end();i++)
00272 {
00273
00274 uniq_set.insert((*i).second);
00275 }
00276
00277
00278 if(uniq_set.size()!=topN.size())
00279 {
00280 cout << "\n\nVirtual_Disp::validateMultimap: "
00281 << "Error! topN likely contains duplicate vertex* entries.\n";
00282 exit(0);
00283 }
00285
00286 bool flag = false;
00287 for(tv_cit i=topN.begin();i!=topN.end();i++)
00288 {
00289 if((*i).second->getFace()==NULL)
00290 {
00291 cout << "\n\nVirtual_Disp::validateMultimap: "
00292 << "Error! topN contains vertex* ("
00293 << (*i).second->getIndex() << ") with no closest point.\n";
00294 flag=true;
00295 }
00296 }
00297 if(flag==true){exit(0);}
00298 }
00299
00300 void Virtual_Disp::validateOld (void)
00301 {
00302 tv_it j;
00303
00304 for(td_it i=old.begin();i!=old.end();i++)
00305 {
00306 assert((*i).first!=NULL);
00307 if(!entryInTopN((*i).first,(*i).second,j))
00308 {
00309 cout << "\n\nVirtual_Disp::validateOld: "
00310 << "Error! old contains element (vertex->"
00311 << (*i).first->getIndex() << ", vd=" << (*i).second
00312 << ") not found in TopN.\n";
00313 exit(0);
00314 }
00315 }
00316 }
00317
00318 void Virtual_Disp::validateTopN2 (void)
00319 {
00320 for(tv_it i=topN.begin();i!=topN.end();i++)
00321 {
00322 assert((*i).first==(*i).first);
00323
00324 assert((*i).second!=NULL);
00325 if((*i).first > 1E100)
00326 {
00327 cout << "\n\n Virtual_Disp::validateTopN2: ERROR. "
00328 << "virtual displacement > 1e100.\n";
00329 if ((*i).second!=NULL)
00330 {
00331 (*i).second->print(cout);
00332 cout << endl;
00333 }
00334 else
00335 {
00336 cout << "Virtual_Disp::validateTopN2: ERROR. "
00337 << "Vertex is NULL.\n\n";
00338 }
00339 exit(0);
00340 }
00341
00342
00343
00344
00345
00346
00347 }
00348 }
00349
00350 void Virtual_Disp::validateTopN (void)
00351 {
00352 for(tv_it i=topN.begin();i!=topN.end();i++)
00353 {
00354 if((*i).second->getFace()==NULL)
00355 {
00356 cout << "ERROR. vertex: " << (*i).second->getObject()->getName() << "->" << (*i).second->getIndex() << " in topN has no closest point.\n";
00357 exit(0);
00358 }
00359
00360
00361
00362 vec_d p = (*i).second->getNewPos(Gain_Schedule::instance().getGain());
00363
00364 double vd = (p[0]-(*i).second->getCoord(0))*(p[0]-(*i).second->getCoord(0))+
00365 (p[1]-(*i).second->getCoord(1))*(p[1]-(*i).second->getCoord(1))+
00366 (p[2]-(*i).second->getCoord(2))*(p[2]-(*i).second->getCoord(2));
00367
00368 if(distinguishable(vd,(*i).first))
00369 {
00370 cout << "ERROR. computed vd (" << vd << ") of vertex (" << (*i).second->getObject()->getName() << "->" << (*i).second->getIndex()
00371 << ") differs from stored value (" << (*i).first << ") in topN.\n";
00372 exit(0);
00373 }
00374 }
00375 }
00376
00377 void Virtual_Disp::groupInit (void)
00378 {
00379
00380 prep();
00381
00382 tvi = topN.rbegin();
00383 }
00384
00385 void Virtual_Disp::incrementIterator (void)
00386 {
00387 tvi++;
00388 }
00389
00390 void Virtual_Disp::resetIterator (void)
00391 {
00392 tvi = topN.rbegin();
00393 }
00394
00395 tv_cit Virtual_Disp::beginTopN (void)
00396 {
00397 return topN.begin();
00398 }
00399
00400 tv_crit Virtual_Disp::rendTopN (void)
00401 {
00402 return topN.rend();
00403 }
00404
00405 tv_cit Virtual_Disp::endTopN (void)
00406 {
00407 return topN.end();
00408 }
00409
00410 tv_crit Virtual_Disp::getIterator (void)
00411 {
00412 return tvi;
00413 }
00414
00415 void Virtual_Disp::removeVertex (Vertex *v)
00416 {
00417
00418 if(old.find(v)!=old.end())
00419 {
00420
00421 cout << "\nVirtual_Disp::removeVertex: "
00422 << "vertex is being removed from virtual displacement maps.\n";
00423 v->print(cout);
00424 cout << endl;
00425
00426
00427 cleanTopN(v,old[v]);
00428
00429 old.erase(v);
00430 }
00431 }
00432
00433 int Virtual_Disp::getSizeTopN (void)
00434 {
00435 return topN.size();
00436 }