virtual_disp.cc

Go to the documentation of this file.
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   // Not thread-safe.
00021   // -- lock mutex
00022   if (only_one == NULL)
00023     only_one = new Virtual_Disp();
00024   // -- unlock mutex
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   // find vertex in topN
00052   for(tv_it i=topN.begin();i!=topN.end();i++)
00053   {
00054     assert((*i).second!=NULL);
00055     // add to old
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     // if find table entry with old se
00066     if (entryInTopN(v,vd_old,t))
00067     {
00068       // remove entry
00069       topN.erase(t);
00070     } else {
00071     }
00072   }
00073   // add new se entry to table
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   // topN has descending order by key (double, squared virtual displacement)
00080   std::pair<tv_it,tv_it> p;
00081   p=topN.equal_range(vd_old);
00082   // if not found, then return false
00083   if(p.first==p.second){return false;}
00084   // else was found
00085   else
00086   {
00087     // for each entry in range
00088     for(tv_it i=p.first;i!=p.second;i++)
00089     { 
00090       // if the data element on entry is equal to v
00091       if(v==(*i).second)
00092       {
00093         // set j and return true
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     // for each entry in range
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   // for each object in model
00148   for(o_it j=Container::instance().o.begin();j!=Container::instance().o.end();j++)
00149   {
00150     // for each vertex in object
00151     for(v_it i=j->v.begin();i!=j->v.end();i++)
00152     {
00153       // if vertex has a closest point
00154       if(i->getFace()!=NULL)
00155       {
00156         // compute new vertex coords
00157         // load energy map
00158         // p = new holding position coordinates (x,y,z)
00159         vec_d p = i->getNewPos(Gain_Schedule::instance().getGain());
00160         // compute virtual displacement
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         // DEBUG
00165         //if(vd>1E10 || (isnan(vd)==true))
00166         //{
00167         //  cout << "Virtual_Disp::loadTopN: Error: "
00168         //        << "vd = " << vd << endl << endl;
00169         //  i->print(cout);
00170         //  exit(0);
00171         //}
00172         //assert(vd<1E10);
00173         //assert(vd==vd);
00174         // DEBUG
00175         // add virtual squared displacement to topN
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   // if closest point was found
00193   if(flag)
00194   {
00195     // update sets with vertex squared virtual displacement
00196     updateSets(v,v->getSqVirtualDisp(Gain_Schedule::instance().getGain()));
00197   }
00198   else
00199   {
00200     // vertex has no closest point
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   // if vertex* found in old remove first
00209   if(old.find(v)!=old.end())
00210   {
00211     updateTopN(v,old[v],new_sqD,true);
00212   }
00213   // else just add to topN
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   // if find table entry with old se
00225   if (entryInTopN(v,vd_old,t))
00226   {
00227     // DEBUG
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     // DEBUG
00233     // remove entry
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   // topN is of type table_v
00247   //multimap<double,Vertex*> table_v;
00248   bool found=false;
00249   rank=0;
00250   // for each pair in topN
00251   for(tv_it i=topN.begin();i!=topN.end();i++)
00252   {
00253     // if vertex* matches target
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   // instantiate set of vertex*
00269   v_set uniq_set;
00270   // for each pair in topN
00271   for(tv_cit i=topN.begin();i!=topN.end();i++)
00272   {
00273     // load v_set
00274     uniq_set.insert((*i).second);
00275   }
00276   // if the two sets are not the same size
00277   // then topN likely contains duplicate vertex* entries
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   // for each pair in topN
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   // for each pair in old
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     //assert((*i).first<1E100);
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     //if((*i).second==NULL)
00342     //{
00343     //  cout << "\n\n Virtual_Disp::validateTopN2: ERROR. "
00344     //        << "Vertex pointer == NULL in topN.\n\n";
00345     //  exit(0);
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     // compute new vertex coords
00360     // p = new holding position coordinates (x,y,z)
00361     // load energy map
00362     vec_d p = (*i).second->getNewPos(Gain_Schedule::instance().getGain());
00363     // compute virtual displacement
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     // if vd differs from topN value
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   // load topN, save old, and initialize avg
00380   prep();
00381   // point multimap iterator to pair with largest separation error
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   // if vertex* found in old
00418   if(old.find(v)!=old.end())
00419   {
00420     // DEBUG
00421     cout << "\nVirtual_Disp::removeVertex: "
00422           << "vertex is being removed from virtual displacement maps.\n";
00423     v->print(cout);
00424     cout << endl;
00425     // DEBUG
00426     // remove vertex* from topN
00427     cleanTopN(v,old[v]);
00428     // remove vertex* from old
00429     old.erase(v);
00430   }
00431 }
00432 
00433 int Virtual_Disp::getSizeTopN (void)
00434 {
00435   return topN.size();
00436 }

Generated on Fri Jul 18 19:43:40 2008 for meshmorph by  doxygen 1.5.1