HG-MD
1
|
00001 00002 00003 00004 00005 00006 #ifndef CWALL_H 00007 #define CWALL_H 00008 00009 #include "CParticle.h" 00010 #include <algorithm> 00011 using std::min; 00012 00013 00014 00024 class CWall 00025 { 00026 public: 00028 CWall() { 00029 indSpecies = 0; 00030 is_hopper = false; 00031 isAxisymmetric = false; 00032 velocity.set_zero(); 00033 } 00034 00035 void set_is_hopper(){is_hopper=true;} 00036 00038 void set(Vec3D normal_, Mdouble position_) 00039 { 00040 //factor is used to set n to unit length 00041 factor = 1. / sqrt(Dot(normal_, normal_)); 00042 normal = normal_ * factor; 00043 position = position_ * factor; 00044 //this makes it a standard wall 00045 finite_walls.resize(0); 00046 } 00047 00048 void is_finite() {finite_walls.resize(0);} 00049 00051 void add_finite_wall(Vec3D normal, Vec3D point) { 00052 add_finite_wall(normal,Dot(normal,point)); 00053 } 00054 00056 void add_finite_wall(Vec3D normal_, Mdouble position_) 00057 { 00058 //n is the index of the new wall 00059 int n = finite_walls.size(); 00060 finite_walls.resize(n+1); 00061 finite_walls[n].set(normal_,position_); 00062 00063 // AB[n*(n-1)/2+m] is the direction of the intersecting line between walls m and n, m<n 00064 // A[n*(n-1)/2+m] is a point on the intersecting line between walls m and n, m<n 00065 // See http://www.netcomuk.co.uk/~jenolive/vect18d.html for finding the line where two planes meet 00066 AB.resize(n*(n+1)/2); 00067 A.resize (n*(n+1)/2); 00068 for(int m=0; m<n; m++) 00069 { 00070 int id = (n-1)*n/2+m; 00071 //first we cross the wall normals and normalize to obtain AB 00072 AB[id] = Cross(finite_walls[m].normal, finite_walls[n].normal); 00073 AB[id] /= sqrt(AB[id].GetLength2()); 00074 //then we find a point A (using AB*x=0 as a third plane) 00075 Mdouble invdet = 1.0/(+finite_walls[n].normal.X*(finite_walls[m].normal.Y*AB[id].Z-AB[id].Y*finite_walls[m].normal.Z) 00076 -finite_walls[n].normal.Y*(finite_walls[m].normal.X*AB[id].Z-finite_walls[m].normal.Z*AB[id].X) 00077 +finite_walls[n].normal.Z*(finite_walls[m].normal.X*AB[id].Y-finite_walls[m].normal.Y*AB[id].X)); 00078 A[id] = Vec3D(+(finite_walls[m].normal.Y*AB[id].Z-AB[id].Y*finite_walls[m].normal.Z)*finite_walls[n].position 00079 -(finite_walls[n].normal.Y*AB[id].Z-finite_walls[n].normal.Z*AB[id].Y)*finite_walls[m].position 00080 +(finite_walls[n].normal.Y*finite_walls[m].normal.Z-finite_walls[n].normal.Z*finite_walls[m].normal.Y)*0.0, 00081 -(finite_walls[m].normal.X*AB[id].Z-finite_walls[m].normal.Z*AB[id].X)*finite_walls[n].position 00082 +(finite_walls[n].normal.X*AB[id].Z-finite_walls[n].normal.Z*AB[id].X)*finite_walls[m].position 00083 -(finite_walls[n].normal.X*finite_walls[m].normal.Z-finite_walls[m].normal.X*finite_walls[n].normal.Z)*0.0, 00084 +(finite_walls[m].normal.X*AB[id].Y-AB[id].X*finite_walls[m].normal.Y)*finite_walls[n].position 00085 -(finite_walls[n].normal.X*AB[id].Y-AB[id].X*finite_walls[n].normal.Y)*finite_walls[m].position 00086 +(finite_walls[n].normal.X*finite_walls[m].normal.Y-finite_walls[m].normal.X*finite_walls[n].normal.Y)*0.0 ) * invdet; 00087 } 00088 00089 // C[(n-2)*(n-1)*n/6+(m-1)*m/2+l] is a point intersecting walls l, m and n, l<m<n 00090 C.resize((n-1)*n*(n+1)/6); 00091 for(int m=0; m<n; m++) 00092 { 00093 for(int l=0; l<m; l++) 00094 { 00095 int id = (n-2)*(n-1)*n/6+(m-1)*m/2+l; 00096 Mdouble invdet = 1.0/(+finite_walls[n].normal.X*(finite_walls[m].normal.Y*finite_walls[l].normal.Z-finite_walls[l].normal.Y*finite_walls[m].normal.Z) 00097 -finite_walls[n].normal.Y*(finite_walls[m].normal.X*finite_walls[l].normal.Z-finite_walls[m].normal.Z*finite_walls[l].normal.X) 00098 +finite_walls[n].normal.Z*(finite_walls[m].normal.X*finite_walls[l].normal.Y-finite_walls[m].normal.Y*finite_walls[l].normal.X)); 00099 C[id] = Vec3D(+(finite_walls[m].normal.Y*finite_walls[l].normal.Z-finite_walls[l].normal.Y*finite_walls[m].normal.Z)*finite_walls[n].position 00100 -(finite_walls[n].normal.Y*finite_walls[l].normal.Z-finite_walls[n].normal.Z*finite_walls[l].normal.Y)*finite_walls[m].position 00101 +(finite_walls[n].normal.Y*finite_walls[m].normal.Z-finite_walls[n].normal.Z*finite_walls[m].normal.Y)*finite_walls[l].position, 00102 -(finite_walls[m].normal.X*finite_walls[l].normal.Z-finite_walls[m].normal.Z*finite_walls[l].normal.X)*finite_walls[n].position 00103 +(finite_walls[n].normal.X*finite_walls[l].normal.Z-finite_walls[n].normal.Z*finite_walls[l].normal.X)*finite_walls[m].position 00104 -(finite_walls[n].normal.X*finite_walls[m].normal.Z-finite_walls[m].normal.X*finite_walls[n].normal.Z)*finite_walls[l].position, 00105 +(finite_walls[m].normal.X*finite_walls[l].normal.Y-finite_walls[l].normal.X*finite_walls[m].normal.Y)*finite_walls[n].position 00106 -(finite_walls[n].normal.X*finite_walls[l].normal.Y-finite_walls[l].normal.X*finite_walls[n].normal.Y)*finite_walls[m].position 00107 +(finite_walls[n].normal.X*finite_walls[m].normal.Y-finite_walls[m].normal.X*finite_walls[n].normal.Y)*finite_walls[l].position ) * invdet; 00108 } 00109 } 00110 } 00111 00113 void move(Mdouble position_) { 00114 position=position_*factor; 00115 //cout << "pos " << position << endl; 00116 } 00117 00119 void move(Vec3D velocity_, Mdouble dt) { 00120 velocity=velocity_; 00121 position+=Dot(velocity,normal)*dt; 00122 //cout << "pos " << position << "vel " << velocity << endl; 00123 } 00124 00127 Mdouble get_distance(Vec3D &Position) {return position - Dot(Position, normal);} 00128 00130 bool get_distance_and_normal(Particle &P, Mdouble &distance, Vec3D &normal_return) { 00131 if (isAxisymmetric) return get_distance_and_normal_for_axissymmetric_wall(P, distance, normal_return); 00132 static Mdouble distance_new; 00133 static Mdouble distance2; 00134 static Mdouble distance3; 00135 static int id; 00136 static int id2; 00137 static int id3; 00138 00139 if(is_hopper){//this is first becuase i dont know what it does if not 00140 // Three posible normals for the hopper, they are averaged 00141 // when a particle touch 2 walls 00142 Vec3D normalOuterCylinder = Vec3D(0,0,0); 00143 Vec3D normalInnerCylinder = Vec3D(0,0,0); 00144 Vec3D normalBase = Vec3D(0,0,0); 00145 00146 00147 //Radial coordinate of the particle 00148 Mdouble particleRadius = sqrt(sqr(P.get_Position().X) + sqr(P.get_Position().Y)); 00149 Mdouble innerRadius = 20*P.get_Radius();// hardcoded geometry for the moment 00150 Mdouble outerRadius = 50*P.get_Radius(); 00151 Mdouble distanceOuterCylinder = 0.0; 00152 Mdouble distanceInnerCylinder = 0.0; 00153 Mdouble distanceBase = 0.0; 00154 00155 //cout << "Mass of particles: " << P.get_restitution_coefficient() << endl; 00156 //set normal outer cilinder 00157 if(particleRadius + P.get_Radius() > outerRadius){ 00158 normalOuterCylinder = Vec3D(P.get_Position().X, P.get_Position().Y, 0.0)/particleRadius; 00159 distanceOuterCylinder = outerRadius - particleRadius; 00160 //cout << "Outer Cylinder "<< endl; 00161 } 00162 00163 //\todo set a real hopper with two more walls 00164 /* if (P.get_Position().Z - P.Radius < 0.0 && particleRadius + P.Radius >= innerRadius */ 00165 /* && P.get_Position().Z > 0){// the particle feels the ground */ 00166 /* normalBase = Vec3D(0.0,0.0,-1.0);//normalized normal outer to the geometry */ 00167 /* distanceBase = P.get_Position().Z;//the distance to the wall from the center of the particle */ 00168 /* //cout << "Base "<< endl; */ 00169 /* } */ 00170 //\todo set a real hopper with two more walls 00171 if (abs(P.get_Position().Z) - P.get_Radius() < 0.0 00172 && particleRadius > innerRadius){// the particle feels the ground 00173 00174 normalBase = Vec3D(0.0,0.0,-1.0)*SIGN(P.get_Position().Z); 00175 distanceBase = P.get_Position().Z; 00176 } 00177 Vec3D dr = Vec3D(P.get_Position().X, P.get_Position().Y, 0.0)*innerRadius/particleRadius 00178 - P.get_Position(); 00179 if(dr.GetLength() < P.get_Radius() ){ 00180 cout << " toy en el borde" << endl; 00181 distanceBase = dr.GetLength(); 00182 normalBase = dr/distanceBase; 00183 } 00184 00185 /* if(particleRadius + P.Radius > innerRadius */ 00186 /* && P.get_Position().Z > -40*P.Radius */ 00187 /* && P.get_Position().Z + P.Radius < 0.0 ){//inside wall */ 00188 /* normalInnerCylinder = Vec3D(-P.get_Position().X, -P.get_Position().Y, 0.0)/particleRadius; */ 00189 /* distanceInnerCylinder = innerRadius - particleRadius; */ 00190 /* //cout << "Inner Cylinder "<< endl; */ 00191 /* } */ 00192 00193 /* if(P.get_Position().Z > 0.0 && P.get_Position().Z - P.Radius < 0.0 && particleRadius < innerRadius ){// Colliding with line */ 00194 /* normal_return = Vec3D(P.get_Position().X,P.get_Position().Y,0)*(innerRadius/particleRadius - 1.0)+ */ 00195 /* Vec3D(0.0,0.0,-P.get_Position().Z); */ 00196 /* distance = normal_return.GetLength(); */ 00197 /* normal_return /= normal_return.GetLength(); */ 00198 /* if(distance < P.Radius){ */ 00199 /* cout << "Border normal " << normal_return << " distance " << distance<< endl; */ 00200 /* return true; */ 00201 /* } */ 00202 /* } */ 00203 00204 if(distanceOuterCylinder != 0.0 || distanceBase != 0.0){ 00205 //average normals 00206 00207 normal_return = distanceOuterCylinder*normalOuterCylinder 00208 + distanceInnerCylinder*normalInnerCylinder 00209 + distanceBase*normalBase; 00210 normal_return /= normal_return.GetLength(); 00211 // distance = sqrt(SQR(distanceBase) + SQR(distanceOuterCylinder) 00212 // + SQR(distanceInnerCylinder)); 00213 distance = 0.5*(distanceBase + distanceOuterCylinder); 00214 //cout << "normal " << normal_return << " distance " << distance<< endl; 00215 return true; 00216 } 00217 00218 /* if(distanceBase != 0 || distanceInnerCylinder != 0.0){ //collision with inner walls */ 00219 /* //average normals */ 00220 00221 /* normal_return = distanceInnerCylinder*normalInnerCylinder */ 00222 /* + distanceBase*normalBase; */ 00223 /* normal_return /= normal_return.GetLength(); */ 00224 /* // distance = sqrt(SQR(distanceBase) + SQR(distanceOuterCylinder) */ 00225 /* // + SQR(distanceInnerCylinder)); */ 00226 /* distance = 0.5*(distanceBase + distanceInnerCylinder); */ 00227 /* //cout << "normal " << normal_return << " distance " << distance<< endl; */ 00228 /* return true; */ 00229 /* } */ 00230 00231 00232 //cout << "False " << endl; 00233 //getchar(); 00234 // no collision, so return false 00235 return false; 00236 00237 } 00238 00239 00240 00241 if (!finite_walls.size()) { 00242 //for standard walls this function sets normal_return and distance and returns true if the particle is in contact 00243 distance = get_distance(P.get_Position()); 00244 if (distance>=P.get_Radius()) return false; 00245 normal_return = normal; return true; 00246 } 00247 00248 00249 00250 //if we are here, this is a finite wall 00251 distance = -1e20; 00252 distance2 = -1e20; 00253 distance3 = -1e20; 00254 //for all finite walls 00255 for (unsigned int i=0; i<finite_walls.size(); i++) { 00256 //calculate the distance to the particle 00257 distance_new = finite_walls[i].get_distance(P.get_Position()); 00258 //return false if the distance to any one wall is too large (i.e. no contact) 00259 if (distance_new>=P.get_Radius()) return false; 00260 //store the minimum distance and the respective wall in "distance" and "id" 00261 //and store up to two walls (id2, id3) and their distances (distance2, distance3), if the possible contact point is near the intersection between id and id2 (and id3) 00262 if (distance_new>distance) { 00263 if (distance>-P.get_Radius()) { 00264 if (distance2>-P.get_Radius()) {distance3 = distance; id3 = id;} 00265 else {distance2 = distance; id2 = id;} 00266 } 00267 distance = distance_new; id = i; 00268 } else if (distance_new>-P.get_Radius()) { 00269 if (distance2>-P.get_Radius()) {distance3 = distance_new; id3 = i;} 00270 else {distance2 = distance_new; id2 = i;} 00271 } 00272 } 00273 00274 //if we are here, the closest wall is id; 00275 //if distance2>-P.Radius (and distance3>-P.Radius), the possible contact point is near the intersection between id and id2 (and id3) 00276 if (distance2>-P.get_Radius()) { 00277 //D is the point on wall id closest to P 00278 Vec3D D = P.get_Position() + finite_walls[id].normal * distance; 00279 //If the distance of D to id2 is positive, the contact is with the intersection 00280 bool intersection_with_id2 = (finite_walls[id2].get_distance(D)>0.0); 00281 00282 if (distance3>-P.get_Radius()&&(finite_walls[id3].get_distance(D)>0.0)) { 00283 if (intersection_with_id2) { //possible contact is with intersection of id,id2,id3 00284 //we know id2<id3 00285 int index = 00286 (id<id2)?( (id3-2)*(id3-1)*id3/6+(id2-1)*id2/2+id ): 00287 (id<id3)?( (id3-2)*(id3-1)*id3/6+(id -1)*id /2+id2 ): 00288 ( (id -2)*(id -1)*id /6+(id3-1)*id3/2+id2 ); 00289 normal_return = P.get_Position() - C[index]; 00290 distance = sqrt(normal_return.GetLength2()); 00291 if (distance>=P.get_Radius()) return false; //no contact 00292 normal_return /= -distance; 00293 return true; //contact with id,id2,id3 00294 } else { intersection_with_id2 = true; distance2 = distance3; id2 = id3; } 00295 } 00296 00297 if (intersection_with_id2) { //possible contact is with intersection of id,id2 00298 int index = (id>id2)?((id-1)*id/2+id2):((id2-1)*id2/2+id); 00299 Vec3D AC = P.get_Position() - A[index]; 00300 normal_return = AC - AB[index] * Dot(AC,AB[index]); 00301 distance = sqrt(normal_return.GetLength2()); 00302 if (distance>=P.get_Radius()) return false; //no contact 00303 normal_return /= -distance; 00304 return true; //contact with two walls 00305 } 00306 } 00307 //contact is with id 00308 normal_return = finite_walls[id].normal; 00309 return true; 00310 00311 } 00312 00314 friend inline std::ostream& operator<<(std::ostream& os, CWall &w) 00315 { 00316 os << "numFiniteWalls " << w.finite_walls.size(); 00317 if (w.finite_walls.size()) { 00318 for (vector<CWall>::iterator it = w.finite_walls.begin(); it!=w.finite_walls.end(); ++it) { 00319 os << " normal " << it->normal << " position " << it->position; 00320 } 00321 } else { 00322 os << " normal " << w.normal << " position " << w.position; 00323 //optional output 00324 if (w.velocity.GetLength2()) os << " velocity " << w.velocity; 00325 } 00326 return os; 00327 } 00328 00330 friend inline std::istream& operator>>(std::istream& is, CWall &w) 00331 { 00332 int n; 00333 is >> n; 00334 if (n!=0) { 00335 Vec3D normal; 00336 Mdouble position; 00337 for (int i=0; i<n; i++) { 00338 is >> normal >> position; 00339 w.add_finite_wall(normal,position); 00340 } 00341 } else { 00342 is >> w.normal >> w.position; 00343 } 00344 return is; 00345 } 00346 00348 void read(std::istream& is) { 00349 string dummy; 00350 int n; 00351 is >> dummy >> n; 00352 if (n!=0) { 00353 Vec3D normal; 00354 Mdouble position; 00355 for (int i=0; i<n; i++) { 00356 is >> dummy >> normal >> dummy >> position; 00357 add_finite_wall(normal,position); 00358 } 00359 } else { 00360 //use stringstream to ensure that old restart files w/o velocity don't break the code 00361 stringstream ss(""); 00362 string s; 00363 getline(is,s); 00364 ss << s; 00365 ss >> dummy >> normal >> dummy >> position >> dummy >> velocity; 00366 00367 } 00368 } 00369 00371 void print(std::ostream& os) { 00372 if (finite_walls.size()) { 00373 os << "finite_wall( "; 00374 for (vector<CWall>::iterator it = finite_walls.begin(); it!=finite_walls.end(); ++it) 00375 os << "normal:" << it->get_normal() << ", position:" << it->get_position() << " "; 00376 os << " )"; 00377 } else os << "wall( normal:" << normal << ", position:" << position << ")"; 00378 } 00379 00381 Vec3D get_normal() {return normal;} 00382 void set_normal(Vec3D new_) {normal=new_;} 00383 00385 Mdouble get_position() {return position;} 00386 00387 00389 Vec3D get_velocity() {return velocity;} 00391 void set_velocity(Vec3D new_) {velocity = new_;} 00392 00394 bool get_distance_and_normal_for_axissymmetric_wall(Particle &P, Mdouble &distance, Vec3D &normal_return) { 00395 //transform to axisymmetric coordinates 00396 Vec3D PO = P.get_Position() - axisOrigin; 00397 P.get_Position().Z = Dot(axisOrientation,PO); 00398 P.get_Position().Y = 0.0; 00399 Vec3D tangential = PO-P.get_Position().Z*axisOrientation; 00400 P.get_Position().X = tangential.GetLength(); 00401 tangential /= P.get_Position().X; 00402 Vec3D normal_axisymmetric_coordinates; 00403 //determine wall distance, normal and contact in axosymmetric coordinates 00404 isAxisymmetric = false; 00405 bool retval = get_distance_and_normal(P, distance, normal_axisymmetric_coordinates); 00406 isAxisymmetric = true; 00407 //transform from axisymmetric coordinates 00408 normal_return = normal_axisymmetric_coordinates.Z * axisOrientation 00409 + tangential*normal_axisymmetric_coordinates.X; 00410 P.set_Position(PO + axisOrigin); 00411 return retval; 00412 } 00413 00415 void setSymmetryAxis(Vec3D new_axisOrigin, Vec3D new_axisOrientation) { 00416 axisOrigin = new_axisOrigin; 00417 axisOrientation = new_axisOrientation; 00418 axisOrientation.normalize(); 00419 isAxisymmetric = true; 00420 cout 00421 << "axisOrigin" << axisOrigin 00422 << "axisOrientation" << axisOrientation 00423 << "isAxisymmetric" << isAxisymmetric 00424 << endl; 00425 } 00426 00428 void removeSymmetryAxis() { 00429 isAxisymmetric = false; 00430 } 00431 00432 private: 00433 vector<CWall> finite_walls; 00434 vector<Vec3D> A; //<A[n*(n-1)/2+m] is a point on the intersecting line between walls m and n, m<n 00435 vector<Vec3D> AB; //<AB[n*(n-1)/2+m] is the direction of the intersecting line between walls m and n, m<n 00436 vector<Vec3D> C; //<C[(n-2)*(n-1)*n/6+(m-1)*m/2+l] is a point intersecting walls l, m and n, l<m<n 00437 00438 Vec3D normal; //<outward unit normal vector 00439 Mdouble position; //<position n*x=p 00440 Mdouble factor; //<This is the normal to rescale to unit vectoers. 00441 00442 00443 public: 00444 Vec3D velocity; 00445 int indSpecies; 00446 bool is_hopper; 00447 00448 00449 bool isAxisymmetric; 00450 Vec3D axisOrigin; 00451 Vec3D axisOrientation; 00452 00453 }; 00454 00455 00459 class CWallPeriodic 00460 { 00461 public: 00462 00463 CWallPeriodic() {} 00464 00465 CWallPeriodic(const CWallPeriodic &p) { 00466 left_wall = p.left_wall; 00467 normal = p.normal; 00468 position_left = p.position_left; 00469 position_right = p.position_right; 00470 factor = p.factor; 00471 shift = p.shift; 00472 } 00473 00479 void set(Vec3D normal_, Mdouble position_left_, Mdouble position_right_) { 00480 // factor is used to set normal to unit length 00481 factor = 1. / sqrt(Dot(normal_, normal_)); 00482 normal = normal_ * factor; 00483 position_left = position_left_ * factor; 00484 position_right = position_right_ * factor; 00485 shift = normal * (position_right - position_left); 00486 } 00487 00490 void set(Vec3D normal_, Mdouble position_left_, Mdouble position_right_, Vec3D shift_direction) { 00491 // factor is used to set normal to unit length 00492 factor = 1. / sqrt(Dot(normal_, normal_)); 00493 normal = normal_ * factor; 00494 position_left = position_left_ * factor; 00495 position_right = position_right_ * factor; 00496 // factor is used to set shift vector to correct length 00497 factor = (position_right - position_left) * Dot(shift_direction, normal); 00498 shift = shift_direction * factor; 00499 } 00500 00502 void move_left(Mdouble position_) 00503 { 00504 position_left=position_*factor; 00505 shift = normal * (position_right - position_left); 00506 } 00507 00509 void move_right(Mdouble position_) 00510 { 00511 position_right=position_*factor; 00512 shift = normal * (position_right - position_left); 00513 } 00514 00515 00523 Mdouble distance(Particle &P) { 00524 return distance(P.get_Position()); 00525 } 00526 00527 Mdouble distance(Vec3D &P) { 00528 Mdouble position = Dot(P, normal); 00529 00530 if (position - position_left < position_right - position) { 00531 left_wall = true; 00532 return position - position_left; 00533 } else { 00534 left_wall = false; 00535 return position_right - position; 00536 } 00537 } 00538 00540 void shift_position(Vec3D &Position) { 00541 if (left_wall) { 00542 Position += shift; 00543 left_wall = false; 00544 } 00545 else { 00546 Position -= shift; 00547 left_wall = true; 00548 } 00549 } 00550 00552 Vec3D get_shifted_position(Vec3D &Position) { 00553 if (left_wall) { 00554 return Position + shift; 00555 } 00556 else { 00557 return Position - shift; 00558 } 00559 } 00560 00562 void shift_positions(Vec3D &PI, Vec3D &PJ) { 00563 if (left_wall) { 00564 PI += shift; 00565 PJ += shift; 00566 left_wall = false; 00567 } 00568 else { 00569 PI -= shift; 00570 PJ -= shift; 00571 left_wall = true; 00572 } 00573 } 00574 00576 void get_close_together(Vec3D &P,Vec3D &Q) { 00577 Mdouble PQdotn = Dot(P-Q, normal); 00578 Mdouble shift_norm2 = shift.GetLength2(); 00579 //Check if P is so far from Q that a shift would move it closer 00580 if (sqr(PQdotn) > .25 * shift_norm2) { 00581 //Now determine the direction of the shift 00582 if (PQdotn>0.0) P -= shift; 00583 else P += shift; 00584 } 00585 } 00586 00588 friend inline std::ostream& operator<<(std::ostream& os, const CWallPeriodic &w) 00589 { 00590 os<< "normal " << w.normal 00591 << " pos_left " << w.position_left 00592 << " pos_right " << w.position_right 00593 << " shift " << w.shift; 00594 return os; 00595 } 00596 00598 friend inline std::istream& operator>>(std::istream& is, CWallPeriodic &w) 00599 { 00600 is >> w.normal >> w.position_left >> w.position_right >> w.shift; 00601 return is; 00602 } 00603 00605 void read(std::istream& is) { 00606 string dummy; 00607 is >> dummy >> normal >> dummy >> position_left >> dummy >> position_right >> dummy >> shift; 00608 } 00609 00611 void print(std::ostream& os, bool print_all=false) { 00612 os << "periodic_wall( normal:" << normal 00613 << ", position_left:" << position_left 00614 << ", position_right:" << position_right; 00615 if (print_all) os << ", shift:" << shift << ", left_wall:" << left_wall; 00616 os << ")"; 00617 } 00618 00619 Vec3D& get_normal() {return normal;} 00620 void set_normal(Vec3D new_) {normal=new_;} 00621 //~ Vec3D get_normal() const {return normal;} 00622 bool get_left_wall() const {return left_wall;} 00623 00624 private: 00625 bool left_wall; 00626 Vec3D normal; 00627 Mdouble position_left; 00628 Mdouble position_right; 00629 Mdouble factor; 00630 Vec3D shift; 00631 }; 00632 00633 #endif