Go to the documentation of this file.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 void Foam::moleculeCloud::evaluatePair
00029 (
00030 molecule* molI,
00031 molecule* molJ
00032 )
00033 {
00034 const pairPotentialList& pairPot = pot_.pairPotentials();
00035
00036 const pairPotential& electrostatic = pairPot.electrostatic();
00037
00038 label idI = molI->id();
00039
00040 label idJ = molJ->id();
00041
00042 const molecule::constantProperties& constPropI(constProps(idI));
00043
00044 const molecule::constantProperties& constPropJ(constProps(idJ));
00045
00046 List<label> siteIdsI = constPropI.siteIds();
00047
00048 List<label> siteIdsJ = constPropJ.siteIds();
00049
00050 List<bool> pairPotentialSitesI = constPropI.pairPotentialSites();
00051
00052 List<bool> electrostaticSitesI = constPropI.electrostaticSites();
00053
00054 List<bool> pairPotentialSitesJ = constPropJ.pairPotentialSites();
00055
00056 List<bool> electrostaticSitesJ = constPropJ.electrostaticSites();
00057
00058 forAll(siteIdsI, sI)
00059 {
00060 label idsI(siteIdsI[sI]);
00061
00062 forAll(siteIdsJ, sJ)
00063 {
00064 label idsJ(siteIdsJ[sJ]);
00065
00066 if (pairPotentialSitesI[sI] && pairPotentialSitesJ[sJ])
00067 {
00068 vector rsIsJ =
00069 molI->sitePositions()[sI] - molJ->sitePositions()[sJ];
00070
00071 scalar rsIsJMagSq = magSqr(rsIsJ);
00072
00073 if(pairPot.rCutSqr(idsI, idsJ, rsIsJMagSq))
00074 {
00075 scalar rsIsJMag = mag(rsIsJ);
00076
00077 vector fsIsJ =
00078 (rsIsJ/rsIsJMag)
00079 *pairPot.force(idsI, idsJ, rsIsJMag);
00080
00081 molI->siteForces()[sI] += fsIsJ;
00082
00083 molJ->siteForces()[sJ] += -fsIsJ;
00084
00085 scalar potentialEnergy
00086 (
00087 pairPot.energy(idsI, idsJ, rsIsJMag)
00088 );
00089
00090 molI->potentialEnergy() += 0.5*potentialEnergy;
00091
00092 molJ->potentialEnergy() += 0.5*potentialEnergy;
00093
00094 vector rIJ = molI->position() - molJ->position();
00095
00096 tensor virialContribution =
00097 (rsIsJ*fsIsJ)*(rsIsJ & rIJ)/rsIsJMagSq;
00098
00099 molI->rf() += virialContribution;
00100
00101 molJ->rf() += virialContribution;
00102
00103
00104
00105
00106 }
00107 }
00108
00109 if (electrostaticSitesI[sI] && electrostaticSitesJ[sJ])
00110 {
00111 vector rsIsJ =
00112 molI->sitePositions()[sI] - molJ->sitePositions()[sJ];
00113
00114 scalar rsIsJMagSq = magSqr(rsIsJ);
00115
00116 if(rsIsJMagSq <= electrostatic.rCutSqr())
00117 {
00118 scalar rsIsJMag = mag(rsIsJ);
00119
00120 scalar chargeI = constPropI.siteCharges()[sI];
00121
00122 scalar chargeJ = constPropJ.siteCharges()[sJ];
00123
00124 vector fsIsJ =
00125 (rsIsJ/rsIsJMag)
00126 *chargeI*chargeJ*electrostatic.force(rsIsJMag);
00127
00128 molI->siteForces()[sI] += fsIsJ;
00129
00130 molJ->siteForces()[sJ] += -fsIsJ;
00131
00132 scalar potentialEnergy =
00133 chargeI*chargeJ
00134 *electrostatic.energy(rsIsJMag);
00135
00136 molI->potentialEnergy() += 0.5*potentialEnergy;
00137
00138 molJ->potentialEnergy() += 0.5*potentialEnergy;
00139
00140 vector rIJ = molI->position() - molJ->position();
00141
00142 tensor virialContribution =
00143 (rsIsJ*fsIsJ)*(rsIsJ & rIJ)/rsIsJMagSq;
00144
00145 molI->rf() += virialContribution;
00146
00147 molJ->rf() += virialContribution;
00148
00149
00150
00151
00152 }
00153 }
00154 }
00155 }
00156 }
00157
00158
00159 inline void Foam::moleculeCloud::evaluatePair
00160 (
00161 molecule* molReal,
00162 referredMolecule* molRef
00163 )
00164 {
00165 const pairPotentialList& pairPot = pot_.pairPotentials();
00166
00167 const pairPotential& electrostatic = pairPot.electrostatic();
00168
00169 label idReal = molReal->id();
00170
00171 label idRef = molRef->id();
00172
00173 const molecule::constantProperties& constPropReal(constProps(idReal));
00174
00175 const molecule::constantProperties& constPropRef(constProps(idRef));
00176
00177 List<label> siteIdsReal = constPropReal.siteIds();
00178
00179 List<label> siteIdsRef = constPropRef.siteIds();
00180
00181 List<bool> pairPotentialSitesReal = constPropReal.pairPotentialSites();
00182
00183 List<bool> electrostaticSitesReal = constPropReal.electrostaticSites();
00184
00185 List<bool> pairPotentialSitesRef = constPropRef.pairPotentialSites();
00186
00187 List<bool> electrostaticSitesRef = constPropRef.electrostaticSites();
00188
00189 forAll(siteIdsReal, sReal)
00190 {
00191 label idsReal(siteIdsReal[sReal]);
00192
00193 forAll(siteIdsRef, sRef)
00194 {
00195 label idsRef(siteIdsRef[sRef]);
00196
00197 if (pairPotentialSitesReal[sReal] && pairPotentialSitesRef[sRef])
00198 {
00199 vector rsRealsRef =
00200 molReal->sitePositions()[sReal]
00201 - molRef->sitePositions()[sRef];
00202
00203 scalar rsRealsRefMagSq = magSqr(rsRealsRef);
00204
00205 if (pairPot.rCutSqr(idsReal, idsRef, rsRealsRefMagSq))
00206 {
00207 scalar rsRealsRefMag = mag(rsRealsRef);
00208
00209 vector fsRealsRef =
00210 (rsRealsRef/rsRealsRefMag)
00211 *pairPot.force(idsReal, idsRef, rsRealsRefMag);
00212
00213 molReal->siteForces()[sReal] += fsRealsRef;
00214
00215 scalar potentialEnergy
00216 (
00217 pairPot.energy(idsReal, idsRef, rsRealsRefMag)
00218 );
00219
00220 molReal->potentialEnergy() += 0.5*potentialEnergy;
00221
00222 vector rRealRef = molReal->position() - molRef->position();
00223
00224 molReal->rf() +=
00225 (rsRealsRef*fsRealsRef)
00226 *(rsRealsRef & rRealRef)
00227 /rsRealsRefMagSq;
00228
00229
00230
00231 }
00232 }
00233
00234 if (electrostaticSitesReal[sReal] && electrostaticSitesRef[sRef])
00235 {
00236 vector rsRealsRef =
00237 molReal->sitePositions()[sReal]
00238 - molRef->sitePositions()[sRef];
00239
00240 scalar rsRealsRefMagSq = magSqr(rsRealsRef);
00241
00242 if (rsRealsRefMagSq <= electrostatic.rCutSqr())
00243 {
00244 scalar rsRealsRefMag = mag(rsRealsRef);
00245
00246 scalar chargeReal = constPropReal.siteCharges()[sReal];
00247
00248 scalar chargeRef = constPropRef.siteCharges()[sRef];
00249
00250 vector fsRealsRef =
00251 (rsRealsRef/rsRealsRefMag)
00252 *chargeReal*chargeRef
00253 *electrostatic.force(rsRealsRefMag);
00254
00255 molReal->siteForces()[sReal] += fsRealsRef;
00256
00257 scalar potentialEnergy =
00258 chargeReal*chargeRef
00259 *electrostatic.energy(rsRealsRefMag);
00260
00261 molReal->potentialEnergy() += 0.5*potentialEnergy;
00262
00263 vector rRealRef = molReal->position() - molRef->position();
00264
00265 molReal->rf() +=
00266 (rsRealsRef*fsRealsRef)
00267 *(rsRealsRef & rRealRef)
00268 /rsRealsRefMagSq;
00269
00270
00271 }
00272 }
00273 }
00274 }
00275 }
00276
00277
00278 inline bool Foam::moleculeCloud::evaluatePotentialLimit
00279 (
00280 molecule* molI,
00281 molecule* molJ
00282 ) const
00283 {
00284 const pairPotentialList& pairPot = pot_.pairPotentials();
00285
00286 const pairPotential& electrostatic = pairPot.electrostatic();
00287
00288 label idI = molI->id();
00289
00290 label idJ = molJ->id();
00291
00292 const molecule::constantProperties& constPropI(constProps(idI));
00293
00294 const molecule::constantProperties& constPropJ(constProps(idJ));
00295
00296 List<label> siteIdsI = constPropI.siteIds();
00297
00298 List<label> siteIdsJ = constPropJ.siteIds();
00299
00300 List<bool> pairPotentialSitesI = constPropI.pairPotentialSites();
00301
00302 List<bool> electrostaticSitesI = constPropI.electrostaticSites();
00303
00304 List<bool> pairPotentialSitesJ = constPropJ.pairPotentialSites();
00305
00306 List<bool> electrostaticSitesJ = constPropJ.electrostaticSites();
00307
00308 forAll(siteIdsI, sI)
00309 {
00310 label idsI(siteIdsI[sI]);
00311
00312 forAll(siteIdsJ, sJ)
00313 {
00314 label idsJ(siteIdsJ[sJ]);
00315
00316 if (pairPotentialSitesI[sI] && pairPotentialSitesJ[sJ])
00317 {
00318 vector rsIsJ =
00319 molI->sitePositions()[sI] - molJ->sitePositions()[sJ];
00320
00321 scalar rsIsJMagSq = magSqr(rsIsJ);
00322
00323 if (pairPot.rCutSqr(idsI, idsJ, rsIsJMagSq))
00324 {
00325 scalar rsIsJMag = mag(rsIsJ);
00326
00327
00328
00329
00330
00331 if (rsIsJMag < SMALL)
00332 {
00333 WarningIn("moleculeCloud::removeHighEnergyOverlaps()")
00334 << "Molecule site pair closer than "
00335 << SMALL
00336 << ": mag separation = " << rsIsJMag
00337 << ". These may have been placed on top of each"
00338 << " other by a rounding error in mdInitialise in"
00339 << " parallel or a block filled with molecules"
00340 << " twice. Removing one of the molecules."
00341 << endl;
00342
00343 return true;
00344 }
00345
00346
00347
00348
00349 if (rsIsJMag < pairPot.rMin(idsI, idsJ))
00350 {
00351 return true;
00352 }
00353
00354 if
00355 (
00356 mag(pairPot.energy(idsI, idsJ, rsIsJMag))
00357 > pot_.potentialEnergyLimit()
00358 )
00359 {
00360 return true;
00361 };
00362 }
00363 }
00364
00365 if (electrostaticSitesI[sI] && electrostaticSitesJ[sJ])
00366 {
00367 vector rsIsJ =
00368 molI->sitePositions()[sI] - molJ->sitePositions()[sJ];
00369
00370 scalar rsIsJMagSq = magSqr(rsIsJ);
00371
00372 if (pairPot.rCutMaxSqr(rsIsJMagSq))
00373 {
00374 scalar rsIsJMag = mag(rsIsJ);
00375
00376
00377
00378
00379
00380 if (rsIsJMag < SMALL)
00381 {
00382 WarningIn("moleculeCloud::removeHighEnergyOverlaps()")
00383 << "Molecule site pair closer than "
00384 << SMALL
00385 << ": mag separation = " << rsIsJMag
00386 << ". These may have been placed on top of each"
00387 << " other by a rounding error in mdInitialise in"
00388 << " parallel or a block filled with molecules"
00389 << " twice. Removing one of the molecules."
00390 << endl;
00391
00392 return true;
00393 }
00394
00395 if (rsIsJMag < electrostatic.rMin())
00396 {
00397 return true;
00398 }
00399
00400 scalar chargeI = constPropI.siteCharges()[sI];
00401
00402 scalar chargeJ = constPropJ.siteCharges()[sJ];
00403
00404 if
00405 (
00406 mag(chargeI*chargeJ*electrostatic.energy(rsIsJMag))
00407 > pot_.potentialEnergyLimit()
00408 )
00409 {
00410 return true;
00411 };
00412 }
00413 }
00414 }
00415 }
00416
00417 return false;
00418 }
00419
00420
00421 inline bool Foam::moleculeCloud::evaluatePotentialLimit
00422 (
00423 molecule* molReal,
00424 referredMolecule* molRef
00425 ) const
00426 {
00427 const pairPotentialList& pairPot = pot_.pairPotentials();
00428
00429 const pairPotential& electrostatic = pairPot.electrostatic();
00430
00431 label idReal = molReal->id();
00432
00433 label idRef = molRef->id();
00434
00435 const molecule::constantProperties& constPropReal(constProps(idReal));
00436
00437 const molecule::constantProperties& constPropRef(constProps(idRef));
00438
00439 List<label> siteIdsReal = constPropReal.siteIds();
00440
00441 List<label> siteIdsRef = constPropRef.siteIds();
00442
00443 List<bool> pairPotentialSitesReal = constPropReal.pairPotentialSites();
00444
00445 List<bool> electrostaticSitesReal = constPropReal.electrostaticSites();
00446
00447 List<bool> pairPotentialSitesRef = constPropRef.pairPotentialSites();
00448
00449 List<bool> electrostaticSitesRef = constPropRef.electrostaticSites();
00450
00451 forAll(siteIdsReal, sReal)
00452 {
00453 label idsReal(siteIdsReal[sReal]);
00454
00455 forAll(siteIdsRef, sRef)
00456 {
00457 label idsRef(siteIdsRef[sRef]);
00458
00459 if (pairPotentialSitesReal[sReal] && pairPotentialSitesRef[sRef])
00460 {
00461 vector rsRealsRef =
00462 molReal->sitePositions()[sReal]
00463 - molRef->sitePositions()[sRef];
00464
00465 scalar rsRealsRefMagSq = magSqr(rsRealsRef);
00466
00467 if (pairPot.rCutSqr(idsReal, idsRef, rsRealsRefMagSq))
00468 {
00469 scalar rsRealsRefMag = mag(rsRealsRef);
00470
00471
00472
00473
00474
00475 if (rsRealsRefMag < SMALL)
00476 {
00477 WarningIn("moleculeCloud::removeHighEnergyOverlaps()")
00478 << "Molecule site pair closer than "
00479 << SMALL
00480 << ": mag separation = " << rsRealsRefMag
00481 << ". These may have been placed on top of each"
00482 << " other by a rounding error in mdInitialise in"
00483 << " parallel or a block filled with molecules"
00484 << " twice. Removing one of the molecules."
00485 << endl;
00486
00487 return true;
00488 }
00489
00490
00491
00492
00493
00494 if (rsRealsRefMag < pairPot.rMin(idsReal, idsRef))
00495 {
00496 return true;
00497 }
00498
00499 if
00500 (
00501 mag(pairPot.energy(idsReal, idsRef, rsRealsRefMag))
00502 > pot_.potentialEnergyLimit()
00503 )
00504 {
00505 return true;
00506 };
00507 }
00508 }
00509
00510 if (electrostaticSitesReal[sReal] && electrostaticSitesRef[sRef])
00511 {
00512 vector rsRealsRef =
00513 molReal->sitePositions()[sReal]
00514 - molRef->sitePositions()[sRef];
00515
00516 scalar rsRealsRefMagSq = magSqr(rsRealsRef);
00517
00518 if (pairPot.rCutMaxSqr(rsRealsRefMagSq))
00519 {
00520 scalar rsRealsRefMag = mag(rsRealsRef);
00521
00522
00523
00524
00525
00526 if (rsRealsRefMag < SMALL)
00527 {
00528 WarningIn("moleculeCloud::removeHighEnergyOverlaps()")
00529 << "Molecule site pair closer than "
00530 << SMALL
00531 << ": mag separation = " << rsRealsRefMag
00532 << ". These may have been placed on top of each"
00533 << " other by a rounding error in mdInitialise in"
00534 << " parallel or a block filled with molecules"
00535 << " twice. Removing one of the molecules."
00536 << endl;
00537
00538 return true;
00539 }
00540
00541 if (rsRealsRefMag < electrostatic.rMin())
00542 {
00543 return true;
00544 }
00545
00546 scalar chargeReal = constPropReal.siteCharges()[sReal];
00547
00548 scalar chargeRef = constPropRef.siteCharges()[sRef];
00549
00550 if
00551 (
00552 mag
00553 (
00554 chargeReal
00555 *chargeRef
00556 *electrostatic.energy(rsRealsRefMag)
00557 )
00558 > pot_.potentialEnergyLimit()
00559 )
00560 {
00561 return true;
00562 };
00563 }
00564 }
00565 }
00566 }
00567
00568 return false;
00569 }
00570
00571
00572 inline Foam::vector Foam::moleculeCloud::equipartitionLinearVelocity
00573 (
00574 scalar temperature,
00575 scalar mass
00576 )
00577 {
00578 return sqrt(kb*temperature/mass)*vector
00579 (
00580 rndGen_.GaussNormal(),
00581 rndGen_.GaussNormal(),
00582 rndGen_.GaussNormal()
00583 );
00584 }
00585
00586
00587 inline Foam::vector Foam::moleculeCloud::equipartitionAngularMomentum
00588 (
00589 scalar temperature,
00590 const molecule::constantProperties& cP
00591 )
00592 {
00593 scalar sqrtKbT = sqrt(kb*temperature);
00594
00595 if (cP.linearMolecule())
00596 {
00597 return sqrtKbT*vector
00598 (
00599 0.0,
00600 sqrt(cP.momentOfInertia().yy())*rndGen_.GaussNormal(),
00601 sqrt(cP.momentOfInertia().zz())*rndGen_.GaussNormal()
00602 );
00603 }
00604 else
00605 {
00606 return sqrtKbT*vector
00607 (
00608 sqrt(cP.momentOfInertia().xx())*rndGen_.GaussNormal(),
00609 sqrt(cP.momentOfInertia().yy())*rndGen_.GaussNormal(),
00610 sqrt(cP.momentOfInertia().zz())*rndGen_.GaussNormal()
00611 );
00612 }
00613 }
00614
00615
00616
00617
00618 inline const Foam::polyMesh& Foam::moleculeCloud::mesh() const
00619 {
00620 return mesh_;
00621 }
00622
00623
00624 inline const Foam::potential& Foam::moleculeCloud::pot() const
00625 {
00626 return pot_;
00627 }
00628
00629
00630 inline const Foam::List<Foam::DynamicList<Foam::molecule*> >&
00631 Foam::moleculeCloud::cellOccupancy() const
00632 {
00633 return cellOccupancy_;
00634 }
00635
00636
00637 inline const Foam::interactionLists&
00638 Foam::moleculeCloud::il() const
00639 {
00640 return il_;
00641 }
00642
00643
00644 inline const Foam::List<Foam::molecule::constantProperties>
00645 Foam::moleculeCloud::constProps() const
00646 {
00647 return constPropList_;
00648 }
00649
00650
00651 inline const Foam::molecule::constantProperties&
00652 Foam::moleculeCloud::constProps(label id) const
00653 {
00654 return constPropList_[id];
00655 }
00656
00657
00658 inline Foam::Random& Foam::moleculeCloud::rndGen()
00659 {
00660 return rndGen_;
00661 }
00662
00663
00664