FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

moleculeI.H

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 2008-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00027 
00028 inline Foam::molecule::constantProperties::constantProperties()
00029 :
00030     siteReferencePositions_(Field<vector>(0)),
00031     siteMasses_(List<scalar>(0)),
00032     siteCharges_(List<scalar>(0)),
00033     siteIds_(List<label>(0)),
00034     pairPotentialSites_(List<bool>(false)),
00035     electrostaticSites_(List<bool>(false)),
00036     momentOfInertia_(diagTensor(0, 0, 0)),
00037     mass_(0)
00038 {}
00039 
00040 
00041 inline Foam::molecule::constantProperties::constantProperties
00042 (
00043     const dictionary& dict
00044 )
00045 :
00046     siteReferencePositions_(dict.lookup("siteReferencePositions")),
00047     siteMasses_(dict.lookup("siteMasses")),
00048     siteCharges_(dict.lookup("siteCharges")),
00049     siteIds_(List<word>(dict.lookup("siteIds")).size(), -1),
00050     pairPotentialSites_(),
00051     electrostaticSites_(),
00052     momentOfInertia_(),
00053     mass_()
00054 {
00055     checkSiteListSizes();
00056 
00057     setInteracionSiteBools
00058     (
00059         List<word>(dict.lookup("siteIds")),
00060         List<word>(dict.lookup("pairPotentialSiteIds"))
00061     );
00062 
00063     mass_ = sum(siteMasses_);
00064 
00065     vector centreOfMass(vector::zero);
00066 
00067     // Calculate the centre of mass of the body and subtract it from each
00068     // position
00069 
00070     forAll(siteReferencePositions_, i)
00071     {
00072         centreOfMass += siteReferencePositions_[i]*siteMasses_[i];
00073     }
00074 
00075     centreOfMass /= mass_;
00076 
00077     siteReferencePositions_ -= centreOfMass;
00078 
00079     if(siteIds_.size() == 1)
00080     {
00081         // Single site molecule - no rotational motion.
00082 
00083         siteReferencePositions_[0] = vector::zero;
00084 
00085         momentOfInertia_ = diagTensor(-1, -1, -1);
00086     }
00087     else if(linearMoleculeTest())
00088     {
00089         // Linear molecule.
00090 
00091         Info<< nl << "Linear molecule." << endl;
00092 
00093         vector dir = siteReferencePositions_[1] - siteReferencePositions_[0];
00094 
00095         dir /= mag(dir);
00096 
00097         tensor Q = rotationTensor(dir, vector(1,0,0));
00098 
00099         siteReferencePositions_ = (Q & siteReferencePositions_);
00100 
00101         // The rotation was around the centre of mass but remove any
00102         // components that have crept in due to floating point errors
00103 
00104         centreOfMass = vector::zero;
00105 
00106         forAll(siteReferencePositions_, i)
00107         {
00108             centreOfMass += siteReferencePositions_[i]*siteMasses_[i];
00109         }
00110 
00111         centreOfMass /= mass_;
00112 
00113         siteReferencePositions_ -= centreOfMass;
00114 
00115         diagTensor momOfInertia = diagTensor::zero;
00116 
00117         forAll(siteReferencePositions_, i)
00118         {
00119             const vector& p(siteReferencePositions_[i]);
00120 
00121             momOfInertia +=
00122                 siteMasses_[i]*diagTensor(0, p.x()*p.x(), p.x()*p.x());
00123         }
00124 
00125         momentOfInertia_ = diagTensor
00126          (
00127              -1,
00128              momOfInertia.yy(),
00129              momOfInertia.zz()
00130          );
00131     }
00132     else
00133     {
00134         // Fully 6DOF molecule
00135 
00136         // Calculate the inertia tensor in the current orientation
00137 
00138         tensor momOfInertia(tensor::zero);
00139 
00140         forAll(siteReferencePositions_, i)
00141         {
00142             const vector& p(siteReferencePositions_[i]);
00143 
00144             momOfInertia += siteMasses_[i]*tensor
00145             (
00146                 p.y()*p.y() + p.z()*p.z(), -p.x()*p.y(), -p.x()*p.z(),
00147                 -p.y()*p.x(), p.x()*p.x() + p.z()*p.z(), -p.y()*p.z(),
00148                 -p.z()*p.x(), -p.z()*p.y(), p.x()*p.x() + p.y()*p.y()
00149             );
00150         }
00151 
00152         if (eigenValues(momOfInertia).x() < VSMALL)
00153         {
00154             FatalErrorIn("molecule::constantProperties::constantProperties")
00155                 << "An eigenvalue of the inertia tensor is zero, the molecule "
00156                 << dict.name() << " is not a valid 6DOF shape."
00157                 << nl << abort(FatalError);
00158         }
00159 
00160         // Normalise the inertia tensor magnitude to avoid SMALL numbers in the
00161         // components causing problems
00162 
00163         momOfInertia /= eigenValues(momOfInertia).x();
00164 
00165         tensor e = eigenVectors(momOfInertia);
00166 
00167         // Calculate the transformation between the principle axes to the
00168         // global axes
00169 
00170         tensor Q =
00171             vector(1,0,0)*e.x() + vector(0,1,0)*e.y() + vector(0,0,1)*e.z();
00172 
00173         // Transform the site positions
00174 
00175         siteReferencePositions_ = (Q & siteReferencePositions_);
00176 
00177         // Recalculating the moment of inertia with the new site positions
00178 
00179         // The rotation was around the centre of mass but remove any
00180         // components that have crept in due to floating point errors
00181 
00182         centreOfMass = vector::zero;
00183 
00184         forAll(siteReferencePositions_, i)
00185         {
00186             centreOfMass += siteReferencePositions_[i]*siteMasses_[i];
00187         }
00188 
00189         centreOfMass /= mass_;
00190 
00191         siteReferencePositions_ -= centreOfMass;
00192 
00193         // Calculate the moment of inertia in the principle component
00194         // reference frame
00195 
00196         momOfInertia = tensor::zero;
00197 
00198         forAll(siteReferencePositions_, i)
00199         {
00200             const vector& p(siteReferencePositions_[i]);
00201 
00202             momOfInertia += siteMasses_[i]*tensor
00203             (
00204                 p.y()*p.y() + p.z()*p.z(), -p.x()*p.y(), -p.x()*p.z(),
00205                 -p.y()*p.x(), p.x()*p.x() + p.z()*p.z(), -p.y()*p.z(),
00206                 -p.z()*p.x(), -p.z()*p.y(), p.x()*p.x() + p.y()*p.y()
00207             );
00208         }
00209 
00210         momentOfInertia_ = diagTensor
00211         (
00212             momOfInertia.xx(),
00213             momOfInertia.yy(),
00214             momOfInertia.zz()
00215         );
00216     }
00217 }
00218 
00219 
00220 inline Foam::molecule::molecule
00221 (
00222     const Cloud<molecule>& c,
00223     const vector& position,
00224     const label celli,
00225     const tensor& Q,
00226     const vector& v,
00227     const vector& a,
00228     const vector& pi,
00229     const vector& tau,
00230     const vector& specialPosition,
00231     const constantProperties& constProps,
00232     const label special,
00233     const label id
00234 
00235 )
00236 :
00237     Particle<molecule>(c, position, celli),
00238     Q_(Q),
00239     v_(v),
00240     a_(a),
00241     pi_(pi),
00242     tau_(tau),
00243     specialPosition_(specialPosition),
00244     potentialEnergy_(0.0),
00245     rf_(tensor::zero),
00246     special_(special),
00247     id_(id),
00248     siteForces_(constProps.nSites(), vector::zero),
00249     sitePositions_(constProps.nSites())
00250 {
00251     setSitePositions(constProps);
00252 }
00253 
00254 
00255 // * * * constantProperties Private Member Functions * * * * * * * * * * * * //
00256 
00257 
00258 inline void Foam::molecule::constantProperties::checkSiteListSizes() const
00259 {
00260     if
00261     (
00262         siteIds_.size() != siteReferencePositions_.size()
00263      || siteIds_.size() != siteCharges_.size()
00264     )
00265     {
00266         FatalErrorIn("molecule::constantProperties::checkSiteListSizes")
00267             << "Sizes of site id, charge and "
00268             << "referencePositions are not the same. "
00269             << nl << abort(FatalError);
00270     }
00271 }
00272 
00273 
00274 inline void Foam::molecule::constantProperties::setInteracionSiteBools
00275 (
00276     const List<word>& siteIds,
00277     const List<word>& pairPotSiteIds
00278 )
00279 {
00280     pairPotentialSites_.setSize(siteIds_.size());
00281 
00282     electrostaticSites_.setSize(siteIds_.size());
00283 
00284     forAll(siteIds_, i)
00285     {
00286         const word& id(siteIds[i]);
00287 
00288         pairPotentialSites_[i] = (findIndex(pairPotSiteIds, id) > -1);
00289 
00290         electrostaticSites_[i] = (mag(siteCharges_[i]) > VSMALL);
00291     }
00292 }
00293 
00294 
00295 inline bool Foam::molecule::constantProperties::linearMoleculeTest() const
00296 {
00297     if (siteIds_.size() == 2)
00298     {
00299         return true;
00300     }
00301 
00302     vector refDir = siteReferencePositions_[1] - siteReferencePositions_[0];
00303 
00304     refDir /= mag(refDir);
00305 
00306     for
00307     (
00308         label i = 2;
00309         i < siteReferencePositions_.size();
00310         i++
00311     )
00312     {
00313         vector dir = siteReferencePositions_[i] - siteReferencePositions_[i-1];
00314 
00315         dir /= mag(dir);
00316 
00317         if (mag(refDir & dir) < 1 - SMALL)
00318         {
00319             return false;
00320         }
00321     }
00322 
00323     return true;
00324 }
00325 
00326 
00327 // * * * * * * * constantProperties Member Functions * * * * * * * * * * * * //
00328 
00329 inline const Foam::Field<Foam::vector>&
00330 Foam::molecule::constantProperties::siteReferencePositions() const
00331 {
00332     return siteReferencePositions_;
00333 }
00334 
00335 
00336 inline const Foam::List<Foam::scalar>&
00337 Foam::molecule::constantProperties::siteMasses() const
00338 {
00339     return siteMasses_;
00340 }
00341 
00342 
00343 inline const Foam::List<Foam::scalar>&
00344 Foam::molecule::constantProperties::siteCharges() const
00345 {
00346     return siteCharges_;
00347 }
00348 
00349 
00350 inline const Foam::List<Foam::label>&
00351 Foam::molecule::constantProperties::siteIds() const
00352 {
00353     return siteIds_;
00354 }
00355 
00356 
00357 inline Foam::List<Foam::label>&
00358 Foam::molecule::constantProperties::siteIds()
00359 {
00360     return siteIds_;
00361 }
00362 
00363 
00364 inline const Foam::List<bool>&
00365 Foam::molecule::constantProperties::pairPotentialSites() const
00366 {
00367     return pairPotentialSites_;
00368 }
00369 
00370 
00371 inline bool Foam::molecule::constantProperties::pairPotentialSite
00372 (
00373     label sId
00374 ) const
00375 {
00376     label s = findIndex(siteIds_, sId);
00377 
00378     if (s == -1)
00379     {
00380         FatalErrorIn("moleculeI.H") << nl
00381             << sId << " site not found."
00382             << nl << abort(FatalError);
00383     }
00384 
00385     return pairPotentialSites_[s];
00386 }
00387 
00388 
00389 inline const Foam::List<bool>&
00390 Foam::molecule::constantProperties::electrostaticSites() const
00391 {
00392     return electrostaticSites_;
00393 }
00394 
00395 inline bool Foam::molecule::constantProperties::electrostaticSite
00396 (
00397     label sId
00398 ) const
00399 {
00400     label s = findIndex(siteIds_, sId);
00401 
00402     if (s == -1)
00403     {
00404         FatalErrorIn
00405         (
00406             "molecule::constantProperties::electrostaticSite(label)"
00407         )   << sId << " site not found."
00408             << nl << abort(FatalError);
00409     }
00410 
00411     return electrostaticSites_[s];
00412 }
00413 
00414 
00415 inline const Foam::diagTensor&
00416 Foam::molecule::constantProperties::momentOfInertia() const
00417 {
00418     return momentOfInertia_;
00419 }
00420 
00421 
00422 inline bool Foam::molecule::constantProperties::linearMolecule() const
00423 {
00424     return ((momentOfInertia_.xx() < 0) && (momentOfInertia_.yy() > 0));
00425 }
00426 
00427 
00428 inline bool Foam::molecule::constantProperties::pointMolecule() const
00429 {
00430     return (momentOfInertia_.zz() < 0);
00431 }
00432 
00433 
00434 inline Foam::label Foam::molecule::constantProperties::degreesOfFreedom() const
00435 {
00436     if (linearMolecule())
00437     {
00438         return 5;
00439     }
00440     else if (pointMolecule())
00441     {
00442         return 3;
00443     }
00444     else
00445     {
00446         return 6;
00447     }
00448 }
00449 
00450 
00451 inline Foam::scalar Foam::molecule::constantProperties::mass() const
00452 {
00453     return mass_;
00454 }
00455 
00456 
00457 inline Foam::label Foam::molecule::constantProperties::nSites() const
00458 {
00459     return siteIds_.size();
00460 
00461 }
00462 
00463 // * * * * * * * * * * *  trackData Member Functions * * * * * * * * * * * * //
00464 
00465 inline Foam::moleculeCloud& Foam::molecule::trackData::molCloud()
00466 {
00467     return molCloud_;
00468 }
00469 
00470 
00471 inline Foam::label Foam::molecule::trackData::part() const
00472 {
00473     return part_;
00474 }
00475 
00476 
00477 // * * * * * * * * * * * * molecule Member Functions * * * * * * * * * * * * //
00478 
00479 inline const Foam::tensor& Foam::molecule::Q() const
00480 {
00481     return Q_;
00482 }
00483 
00484 
00485 inline Foam::tensor& Foam::molecule::Q()
00486 {
00487     return Q_;
00488 }
00489 
00490 
00491 inline const Foam::vector& Foam::molecule::v() const
00492 {
00493     return v_;
00494 }
00495 
00496 
00497 inline Foam::vector& Foam::molecule::v()
00498 {
00499     return v_;
00500 }
00501 
00502 
00503 inline const Foam::vector& Foam::molecule::a() const
00504 {
00505     return a_;
00506 }
00507 
00508 
00509 inline Foam::vector& Foam::molecule::a()
00510 {
00511     return a_;
00512 }
00513 
00514 
00515 inline const Foam::vector& Foam::molecule::pi() const
00516 {
00517     return pi_;
00518 }
00519 
00520 
00521 inline Foam::vector& Foam::molecule::pi()
00522 {
00523     return pi_;
00524 }
00525 
00526 
00527 inline const Foam::vector& Foam::molecule::tau() const
00528 {
00529     return tau_;
00530 }
00531 
00532 
00533 inline Foam::vector& Foam::molecule::tau()
00534 {
00535     return tau_;
00536 }
00537 
00538 
00539 inline const Foam::List<Foam::vector>& Foam::molecule::siteForces() const
00540 {
00541     return siteForces_;
00542 }
00543 
00544 
00545 inline Foam::List<Foam::vector>& Foam::molecule::siteForces()
00546 {
00547     return siteForces_;
00548 }
00549 
00550 
00551 inline const Foam::List<Foam::vector>& Foam::molecule::sitePositions() const
00552 {
00553     return sitePositions_;
00554 }
00555 
00556 
00557 inline Foam::List<Foam::vector>& Foam::molecule::sitePositions()
00558 {
00559     return sitePositions_;
00560 }
00561 
00562 
00563 inline const Foam::vector& Foam::molecule::specialPosition() const
00564 {
00565     return specialPosition_;
00566 }
00567 
00568 
00569 inline Foam::vector& Foam::molecule::specialPosition()
00570 {
00571     return specialPosition_;
00572 }
00573 
00574 
00575 inline Foam::scalar Foam::molecule::potentialEnergy() const
00576 {
00577     return potentialEnergy_;
00578 }
00579 
00580 
00581 inline Foam::scalar& Foam::molecule::potentialEnergy()
00582 {
00583     return potentialEnergy_;
00584 }
00585 
00586 
00587 inline const Foam::tensor& Foam::molecule::rf() const
00588 {
00589     return rf_;
00590 }
00591 
00592 
00593 inline Foam::tensor& Foam::molecule::rf()
00594 {
00595     return rf_;
00596 }
00597 
00598 
00599 inline Foam::label Foam::molecule::special() const
00600 {
00601     return special_;
00602 }
00603 
00604 
00605 inline bool Foam::molecule::tethered() const
00606 {
00607     return special_ == SPECIAL_TETHERED;
00608 }
00609 
00610 
00611 inline Foam::label Foam::molecule::id() const
00612 {
00613     return id_;
00614 }
00615 
00616 
00617 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines