ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-2.0/test/brains/RigidBody.cpp
(Generate patch)

Comparing trunk/OOPSE-2.0/test/brains/RigidBody.cpp (file contents):
Revision 1682 by tim, Thu Oct 28 22:34:01 2004 UTC vs.
Revision 1684 by tim, Fri Oct 29 16:20:50 2004 UTC

# Line 34 | Line 34 | void RigidBody::setPrevA(const RotMat3x3d& a) {
34   void RigidBody::setPrevA(const RotMat3x3d& a) {
35      (snapshotMan_->getPrevSnapshot())->storage_->aMat[localIndex_] = a;
36      (snapshotMan_->getPrevSnapshot())->storage_->unitVector[localIndex_] = a.inverse() * sU_.getColum(2);
37 +
38 +    std::vector<Atom*>::iterator i;
39 +    for (i = atoms_.begin(); i != atoms_.end(); ++i) {
40 +        if ((*i)->isDirectional()) {
41 +            (*i)->setPrevA(a * (*i)->getPrevA());
42 +        }
43 +    }
44 +
45   }
46  
47        
48   void RigidBody::setA(const RotMat3x3d& a) {
49      (snapshotMan_->getCurrentSnapshot())->storage_->aMat[localIndex_] = a;
50      (snapshotMan_->getCurrentSnapshot())->storage_->unitVector[localIndex_] = a.inverse() * sU_.getColum(2);
51 +
52 +    std::vector<Atom*>::iterator i;
53 +    for (i = atoms_.begin(); i != atoms_.end(); ++i) {
54 +        if ((*i)->isDirectional()) {
55 +            (*i)->setA(a * (*i)->getA());
56 +        }
57 +    }
58   }    
59      
60   void RigidBody::setA(const RotMat3x3d& a, int snapshotNo) {
61      (snapshotMan_->getSnapshot(snapshotNo))->storage_->aMat[localIndex_] = a;
62      (snapshotMan_->getSnapshot(snapshotNo))->storage_->unitVector[localIndex_] = a.inverse() * sU_.getColum(2);    
63 +
64 +    std::vector<Atom*>::iterator i;
65 +    for (i = atoms_.begin(); i != atoms_.end(); ++i) {
66 +        if ((*i)->isDirectional()) {
67 +            (*i)->setA(a * (*i)->getA(snapshotNo), snapshotNo);
68 +        }
69 +    }
70 +
71   }  
72  
73 + void  DirectionalAtom::setUnitFrameFromEuler(double phi, double theta, double psi) {
74 +    sU_.setupRotMat(phi,theta,psi);
75 + }
76 +
77   Mat3x3d RigidBody::getI() {
78      return inertiaTensor_;
79   }    
# Line 111 | Line 138 | void RigidBody::accept(BaseVisitor* v) {
138   void RigidBody::accept(BaseVisitor* v) {
139      v->visit(this);
140   }    
141 +
142 + void  RigidBody::calcRefCoords() {
143 +  /*
144 +  double mtmp;
145 +  vec3 apos;
146 +  double refCOM[3];
147 +  vec3 ptmp;
148 +  double Itmp[3][3];
149 +  double evals[3];
150 +  double evects[3][3];
151 +  double r, r2, len;
152 +
153 +  // First, find the center of mass:
154 +  
155 +  mass = 0.0;
156 +  for (j=0; j<3; j++)
157 +    refCOM[j] = 0.0;
158 +  
159 +  for (i = 0; i < atoms_.size(); i++) {
160 +    mtmp = atoms_[i]->getMass();
161 +    mass += mtmp;
162 +
163 +    apos = refCoords[i];
164 +    
165 +    for(j = 0; j < 3; j++) {
166 +      refCOM[j] += apos[j]*mtmp;    
167 +    }    
168 +  }
169 +  
170 +  for(j = 0; j < 3; j++)
171 +    refCOM[j] /= mass;
172 +
173 + // Next, move the origin of the reference coordinate system to the COM:
174 +
175 +  for (i = 0; i < atoms_.size(); i++) {
176 +    apos = refCoords[i];
177 +    for (j=0; j < 3; j++) {
178 +      apos[j] = apos[j] - refCOM[j];
179 +    }
180 +    refCoords[i] = apos;
181 +  }
182 +
183 + // Moment of Inertia calculation
184 +
185 +  for (i = 0; i < 3; i++)
186 +    for (j = 0; j < 3; j++)
187 +      Itmp[i][j] = 0.0;  
188 +  
189 +  for (it = 0; it < atoms_.size(); it++) {
190 +
191 +    mtmp = atoms_[it]->getMass();
192 +    ptmp = refCoords[it];
193 +    r= norm3(ptmp.vec);
194 +    r2 = r*r;
195 +    
196 +    for (i = 0; i < 3; i++) {
197 +      for (j = 0; j < 3; j++) {
198 +        
199 +        if (i==j) Itmp[i][j] += mtmp * r2;
200 +
201 +        Itmp[i][j] -= mtmp * ptmp.vec[i]*ptmp.vec[j];
202 +      }
203 +    }
204 +  }
205 +  
206 +  diagonalize3x3(Itmp, evals, sU);
207 +  
208 +  // zero out I and then fill the diagonals with the moments of inertia:
209 +
210 +  n_linear_coords = 0;
211 +
212 +  for (i = 0; i < 3; i++) {
213 +    for (j = 0; j < 3; j++) {
214 +      I[i][j] = 0.0;  
215 +    }
216 +    I[i][i] = evals[i];
217 +
218 +    if (fabs(evals[i]) < momIntTol) {
219 +      is_linear = true;
220 +      n_linear_coords++;
221 +      linear_axis = i;
222 +    }
223 +  }
224 +
225 +  if (n_linear_coords > 1) {
226 +          sprintf( painCave.errMsg,
227 +               "RigidBody error.\n"
228 +               "\tOOPSE found more than one axis in this rigid body with a vanishing \n"
229 +               "\tmoment of inertia.  This can happen in one of three ways:\n"
230 +               "\t 1) Only one atom was specified, or \n"
231 +               "\t 2) All atoms were specified at the same location, or\n"
232 +               "\t 3) The programmers did something stupid.\n"
233 +               "\tIt is silly to use a rigid body to describe this situation.  Be smarter.\n"
234 +               );
235 +      painCave.isFatal = 1;
236 +      simError();
237 +  }
238 +  
239 +  // renormalize column vectors:
240 +  
241 +  for (i=0; i < 3; i++) {
242 +    len = 0.0;
243 +    for (j = 0; j < 3; j++) {
244 +      len += sU[i][j]*sU[i][j];
245 +    }
246 +    len = sqrt(len);
247 +    for (j = 0; j < 3; j++) {
248 +      sU[i][j] /= len;
249 +    }
250 +  }
251 +  */
252 + }
253 +
254 + void  RigidBody::calcForcesAndTorques() {
255 +    unsigned int i;
256 +    unsigned int j;
257 +    //Vector3d apos;
258 +    Vector3d afrc;
259 +    Vector3d atrq;
260 +    Vector3d rpos;
261 +    Vector3d frc;
262 +    Vector3d trq;
263 +    //Vector3d pos;
264 +
265 +    zeroForces();
266 +    
267 +    //pos = getPos();
268 +    frc = getFrc();
269 +    trq = getTrq();
270 +
271 +    for (i = 0; i < atoms_.size(); i++) {
272 +
273 +        afrc = atoms_[i]->getFrc();
274  
275 +        //apos = atoms_[i]->getPos(apos);
276 +        //rpos = apos - pos;
277 +        rpos = refCoords_[i];
278 +        
279 +        frc += afrc;
280 +
281 +        trq[0] += rpos[1]*afrc[2] - rpos[2]*afrc[1];
282 +        trq[1] += rpos[2]*afrc[0] - rpos[0]*afrc[2];
283 +        trq[2] += rpos[0]*afrc[1] - rpos[1]*afrc[0];
284 +
285 +        // If the atom has a torque associated with it, then we also need to
286 +        // migrate the torques onto the center of mass:
287 +
288 +        if (atoms_[i]->isDirectional()) {
289 +            atrq = atoms_[i]->getTrq();
290 +            trq += atrq;
291 +        }
292 +        
293 +    }
294 +    
295 +    setFrc(frc);
296 +    setTrq(trq);
297 +    
298   }
299  
300 + void  RigidBody::updateAtoms() {
301 +    unsigned int i;
302 +    unsigned int j;
303 +    Vector3d ref;
304 +    Vector3d apos;
305 +    DirectionalAtom* dAtom;
306 +    Vector3d pos = getPos();
307 +    RotMat3x3d A = getA();
308 +    
309 +    for (i = 0; i < atoms_.size(); i++) {
310 +    
311 +        ref = body2Lab(refCoords_[i]);
312 +
313 +        apos = pos + ref;
314 +
315 +        atoms_[i]->setPos(apos);
316 +
317 +        if (atoms_[i]->isDirectional()) {
318 +          
319 +          dAtom = (DirectionalAtom *) atoms_[i];
320 +          dAtom->rotateBy( A );      
321 +        }
322 +
323 +    }
324 +  
325 + }
326 +
327 +
328 + bool RigidBody::getAtomPos(Vector3d& pos, unsigned int index) {
329 +    if (index < atoms_.size() {
330 +
331 +        Vector3d ref = body2Lab(refCoords_[index]);
332 +        pos = getPos() + ref;
333 +        return true
334 +    } else {
335 +        std::cerr << index << " is an invalid index, current rigid body contains "
336 +                      << atoms_.size() << "atoms" << std::endl;
337 +        return false;
338 +    }    
339 + }
340 +
341 + bool RigidBody::getAtomPos(Vector3d& pos, Atom* atom) {
342 +    std::vector<Atom*>::iterator i;
343 +    i = find(atoms_.begin(), atoms_.end(), atom);
344 +    if (i != atoms_.end()) {
345 +        //RigidBody class makes sure refCoords_ and atoms_ match each other
346 +        Vector3d ref = body2Lab(refCoords_[i - atoms_.begin()]);
347 +        pos = getPos() + ref;
348 +        return true;
349 +    } else {
350 +        std::cerr << "Atom " << atom->getGlobalIndex()
351 +                      <<" does not belong to Rigid body "<< getGlobalIndex() << std::endl;
352 +    }
353 + }
354 + bool RigidBody::getAtomVel(Vector3d& vel, unsigned int index) {
355 +
356 +    //velRot = $(A\cdot skew(I^{-1}j))^{T}refCoor$
357 +
358 +    if (index < atoms_.size() {
359 +
360 +        Vector3d ref;
361 +        Vector3d velRot;
362 +        Mat3x3d skewMat;;
363 +        Vector3d ref = refCoords_[index];
364 +        Vector3d ji = getJ();
365 +        Mat3x3d I =  getI();
366 +
367 +        skewMat(0, 0) =0;
368 +        skewMat(0, 1) = ji[2] /I(2, 2);
369 +        skewMat(0, 2) = -ji[1] /I(1, 1);
370 +
371 +        skewMat(1, 0) = -ji[2] /I(2, 2);
372 +        skewMat(1, 1) = 0;
373 +        skewMat(1, 2) = ji[0]/I(0, 0);
374 +
375 +        skewMat(2, 0) =ji[1] /I(1, 1);
376 +        skewMat(2, 1) = -ji[0]/I(0, 0);
377 +        skewMat(2, 2) = 0;
378 +
379 +        velRot = (getA() * skewMat).transpose() * ref;
380 +
381 +        vel =getVel() + velRot;
382 +        
383 +    } else {
384 +        std::cerr << "Atom " << atom->getGlobalIndex()
385 +                      <<" does not belong to Rigid body "<< getGlobalIndex() << std::endl;
386 +        return false;
387 +    }
388 + }
389 +
390 + bool RigidBody::getAtomVel(Vector3d& vel, Atom* atom) {
391 +
392 +    std::vector<Atom*>::iterator i;
393 +    i = find(atoms_.begin(), atoms_.end(), atom);
394 +    if (i != atoms_.end()) {
395 +        return getAtomVel(vel, i - atoms_.begin());
396 +    } else {
397 +        std::cerr << "Atom " << atom->getGlobalIndex()
398 +                      <<" does not belong to Rigid body "<< getGlobalIndex() << std::endl;    
399 +        return false;
400 +    }    
401 + }
402 +
403 + bool RigidBody::getAtomRefCoor(Vector3d& coor, unsigned int index) {
404 +    if (index < atoms_.size() {
405 +
406 +        coor = refCoords_[index];
407 +        return true
408 +    } else {
409 +        std::cerr << index << " is an invalid index, current rigid body contains "
410 +                      << atoms_.size() << "atoms" << std::endl;
411 +        return false;
412 +    }
413 +
414 + }
415 +
416 + bool RigidBody::getAtomRefCoor(Vector3d& coor, Atom* atom) {
417 +    std::vector<Atom*>::iterator i;
418 +    i = find(atoms_.begin(), atoms_.end(), atom);
419 +    if (i != atoms_.end()) {
420 +        //RigidBody class makes sure refCoords_ and atoms_ match each other
421 +        coor = refCoords_[i - atoms_.begin()];
422 +        return true;
423 +    } else {
424 +        std::cerr << "Atom " << atom->getGlobalIndex()
425 +                      <<" does not belong to Rigid body "<< getGlobalIndex() << std::endl;    
426 +        return false;
427 +    }
428 +
429 + }
430 +
431 + }
432 +

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines