00001 #include "refractory.h"
00002
00003 #include <cmath>
00004 #include <iostream>
00005
00006 #include "container.h"
00007 #include "edge.h"
00008 #include "face.h"
00009 #include "gain_schedule.h"
00010 #include "intersecting_faces.h"
00011 #include "object.h"
00012 #include "state.h"
00013 #include "vertex.h"
00014 #include "vertex_schedule.h"
00015
00016 using std::cout;
00017 using std::endl;
00018
00019 Refractory * Refractory::only_one = NULL;
00020
00021 Refractory & Refractory::instance()
00022 {
00023
00024
00025 if (only_one == NULL)
00026 only_one = new Refractory();
00027
00028 return *only_one;
00029 }
00030
00031 Refractory::Refractory (const Refractory& rhs)
00032 :refrac_s(),refrac_l(),pun_n(),pun_int(),
00033 pun_ang(),pun_com(),touch_map()
00034 {
00035 cout << "Copy constructor prohibited on instances of Refractory class.\n";
00036 cout << "Refractory " << rhs.touch_map.size() << endl;
00037 exit(0);
00038 }
00039
00040 Refractory::Refractory (void)
00041 :refrac_s(),refrac_l(),pun_n(),pun_int(),
00042 pun_ang(),pun_com(),touch_map()
00043 {
00044 }
00045
00046 Refractory& Refractory::operator= (const Refractory& rhs)
00047 {
00048 cout << "Copy assignment operator prohibited on instances of Refractory class.\n";
00049 cout << "Refractory " << rhs.touch_map.size() << endl;
00050 exit(0);
00051 }
00052
00053 bool Refractory::isPunished (Vertex * const v)
00054 {
00055 return (pun_n.find(v)!=pun_n.end() ||
00056 pun_int.find(v)!=pun_int.end() ||
00057 pun_com.find(v)!=pun_com.end() ||
00058 pun_ang.find(v)!=pun_ang.end());
00059 }
00060
00061 void Refractory::punishN (Vertex * const v,int const time_out)
00062 {
00063 pun_n[v]=time_out;
00064 }
00065
00066 void Refractory::punishInt (Vertex * const v,int const time_out)
00067 {
00068 pun_int[v]=time_out;
00069 }
00070
00071 void Refractory::punishCom (Vertex * const v,int const time_out)
00072 {
00073 pun_com[v]=time_out;
00074 }
00075
00076 void Refractory::punishAng (Vertex *v,int time_out)
00077 {
00078 pun_ang[v]=time_out;
00079 }
00080
00081 void Refractory::updateTouchMap (Vertex * const v)
00082 {
00083
00084 if(touch_map.find(v)!=touch_map.end()){ touch_map[v]++; }
00085
00086 else { touch_map[v]=1; }
00087 }
00088
00089 void Refractory::punishIfOverTouched (Vertex * const v)
00090 {
00091
00092 if(touch_map[v]>MAX_TOUCHES){punishN(v,static_cast<int>(GROUP_SIZE));}
00093 }
00094
00095 void Refractory::initRefrac (void)
00096 {
00097 refrac_s.clear();
00098 refrac_l.clear();
00099 }
00100
00101 bool Refractory::Refracted (Vertex * const v)
00102 {
00103 if (refrac_s.find(v)!=refrac_s.end()){return true;}
00104 else {return false;}
00105 }
00106
00107 void Refractory::updateRefractoryWindow (Vertex * const v)
00108 {
00110 if(refrac_l.size()==REFRACTORY_PERIOD)
00111 {
00112 refrac_s.erase(refrac_l.front());
00113 refrac_l.pop_front();
00114 }
00116 refrac_l.push_back(v);
00117 refrac_s.insert(v);
00118 }
00119
00120 bool Refractory::vertexIsMoveCandidate (Vertex * const v)
00121 {
00122
00123
00124
00125
00126 return (v->getFace()!=NULL) && (isPunished(v)==false) && !Refracted(v)
00127 && (Container::instance().vertexIsFrozen(v)==false);
00128 }
00129
00130 void Refractory::screenDisp (Vertex * const ccvv,vec_d & PT)
00131 {
00132
00133 double d[3]={PT[0]-ccvv->getCoord(0),PT[1]-ccvv->getCoord(1),PT[2]-ccvv->getCoord(2)};
00134
00135 double disp = sqrt(d[0]*d[0]+d[1]*d[1]+d[2]*d[2]);
00136
00137 double min_edge_length = 1e30;
00138
00139 for(fp_cit i=ccvv->begin();i!=ccvv->end();i++)
00140 {
00141
00142 for(int j=0;j<3;j++)
00143 {
00144 if((*i)->getEdge(j)->getOriginalLength() < min_edge_length)
00145 {
00146 min_edge_length = (*i)->getEdge(j)->getOriginalLength();
00147 }
00148 }
00149 }
00150 double MAX_ACTUAL_DISPL = min_edge_length*MAX_ACTUAL_DISPL_FRACTION;
00151
00152 if(disp>MAX_ACTUAL_DISPL)
00153 {
00154 double a = MAX_ACTUAL_DISPL/disp;
00155 for(int k=0;k<3;k++)
00156 {
00157 PT[k] = ccvv->getCoord(k)+a*d[k];
00158 }
00159 }
00160 }
00161
00162 vp_cit Refractory::detectPunishableVertex (vp_cit i,bool const int_flag,bool const ang_flag)
00163 {
00164 if(State::instance().getVD2()<MIN_DISPLACEMENT_SQ*SCALE*SCALE)
00165 {
00166 cout << "\nvertex: " << Vertex_Schedule::instance().getCurrentVertex()->getObject()->getName() << "->" << Vertex_Schedule::instance().getCurrentVertex()->getIndex() << " was punished.\n"
00167 << "virtual displacement sqd(" << State::instance().getVD2() << ")"
00168 << " < threshold(" << MIN_DISPLACEMENT_SQ*SCALE*SCALE << ")\n";
00169 Vertex_Schedule::instance().getCurrentVertex()->print(std::cout);
00170 cout << endl;
00171
00172 if (int_flag==true){ punishInt(Vertex_Schedule::instance().getCurrentVertex(),static_cast<int>(GROUP_SIZE));}
00173 else if(ang_flag==true){ punishAng(Vertex_Schedule::instance().getCurrentVertex(),static_cast<int>(GROUP_SIZE));}
00174 else { punishCom(Vertex_Schedule::instance().getCurrentVertex(),static_cast<int>(GROUP_SIZE));}
00175
00176 Gain_Schedule::instance().resetGain();
00177
00178 i++;
00179 }
00180 else
00181 {
00182
00183 Gain_Schedule::instance().halveGain();
00184 }
00185 return i;
00186 }
00187
00188 void Refractory::updateStats (void)
00189 {
00190
00191 if(STRICT_FACE_INTERSECTION_PREVENTION==false)
00192 {
00193 if(DETECT_COMPLETE_SEPARATION==true)
00194 {
00195 if(Intersecting_Faces::instance().getCountOfIntFaces(false)==0){STRICT_FACE_INTERSECTION_PREVENTION=true;}
00196 }
00197 }
00198
00199 updateTouchMap(Vertex_Schedule::instance().getCurrentVertex());
00200
00201 punishIfOverTouched(Vertex_Schedule::instance().getCurrentVertex());
00202
00203 updateRefractoryWindow(Vertex_Schedule::instance().getCurrentVertex());
00204 }
00205
00206 void Refractory::groupInit (void)
00207 {
00208
00209
00210 initRefrac();
00211
00212 pun_n.clear();
00213 pun_int.clear();
00214 pun_com.clear();
00215 pun_ang.clear();
00216
00217 touch_map.clear();
00218 }
00219
00220 vhm_it Refractory::findVertexInTouchMap (Vertex *v)
00221 {
00222 return touch_map.find(v);
00223 }
00224
00225 bool Refractory::vertexInTouchMap (Vertex *v)
00226 {
00227 return touch_map.find(v)!=touch_map.end();
00228 }
00229
00230 int Refractory::numVertexTouches (Vertex * v)
00231 {
00232 return touch_map[v];
00233 }
00234
00235 int Refractory::numPunishedN (void) const
00236 {
00237 return pun_n.size();
00238 }
00239
00240 vhm_cit Refractory::beginN (void) const
00241 {
00242 return pun_n.begin();
00243 }
00244
00245 vhm_cit Refractory::endN (void) const
00246 {
00247 return pun_n.end();
00248 }
00249
00250 int Refractory::numPunishedInt (void) const
00251 {
00252 return pun_int.size();
00253 }
00254
00255 vhm_cit Refractory::beginInt (void) const
00256 {
00257 return pun_int.begin();
00258 }
00259
00260 vhm_cit Refractory::endInt (void) const
00261 {
00262 return pun_int.end();
00263 }
00264
00265 int Refractory::numPunishedAng (void) const
00266 {
00267 return pun_ang.size();
00268 }
00269
00270 vhm_cit Refractory::beginAng (void) const
00271 {
00272 return pun_ang.begin();
00273 }
00274
00275 vhm_cit Refractory::endAng (void) const
00276 {
00277 return pun_ang.end();
00278 }
00279
00280 int Refractory::numPunishedCom (void) const
00281 {
00282 return pun_com.size();
00283 }
00284
00285 vhm_cit Refractory::beginCom (void) const
00286 {
00287 return pun_com.begin();
00288 }
00289
00290 vhm_cit Refractory::endCom (void) const
00291 {
00292 return pun_com.end();
00293 }
00294