00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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
00068
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
00082
00083 siteReferencePositions_[0] = vector::zero;
00084
00085 momentOfInertia_ = diagTensor(-1, -1, -1);
00086 }
00087 else if(linearMoleculeTest())
00088 {
00089
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
00102
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
00135
00136
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
00161
00162
00163 momOfInertia /= eigenValues(momOfInertia).x();
00164
00165 tensor e = eigenVectors(momOfInertia);
00166
00167
00168
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
00174
00175 siteReferencePositions_ = (Q & siteReferencePositions_);
00176
00177
00178
00179
00180
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
00194
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
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
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
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
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