1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "constants.H"
28 using namespace Foam::constant;
30 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
32 inline void Foam::moleculeCloud::evaluatePair
38 const pairPotentialList& pairPot = pot_.pairPotentials();
40 const pairPotential& electrostatic = pairPot.electrostatic();
42 label idI = molI.id();
44 label idJ = molJ.id();
46 const molecule::constantProperties& constPropI(constProps(idI));
48 const molecule::constantProperties& constPropJ(constProps(idJ));
50 List<label> siteIdsI = constPropI.siteIds();
52 List<label> siteIdsJ = constPropJ.siteIds();
54 List<bool> pairPotentialSitesI = constPropI.pairPotentialSites();
56 List<bool> electrostaticSitesI = constPropI.electrostaticSites();
58 List<bool> pairPotentialSitesJ = constPropJ.pairPotentialSites();
60 List<bool> electrostaticSitesJ = constPropJ.electrostaticSites();
64 label idsI(siteIdsI[sI]);
68 label idsJ(siteIdsJ[sJ]);
70 if (pairPotentialSitesI[sI] && pairPotentialSitesJ[sJ])
73 molI.sitePositions()[sI] - molJ.sitePositions()[sJ];
75 scalar rsIsJMagSq = magSqr(rsIsJ);
77 if (pairPot.rCutSqr(idsI, idsJ, rsIsJMagSq))
79 scalar rsIsJMag = mag(rsIsJ);
83 *pairPot.force(idsI, idsJ, rsIsJMag);
85 molI.siteForces()[sI] += fsIsJ;
87 molJ.siteForces()[sJ] += -fsIsJ;
89 scalar potentialEnergy
91 pairPot.energy(idsI, idsJ, rsIsJMag)
94 molI.potentialEnergy() += 0.5*potentialEnergy;
96 molJ.potentialEnergy() += 0.5*potentialEnergy;
98 vector rIJ = molI.position() - molJ.position();
100 tensor virialContribution =
101 (rsIsJ*fsIsJ)*(rsIsJ & rIJ)/rsIsJMagSq;
103 molI.rf() += virialContribution;
105 molJ.rf() += virialContribution;
109 if (electrostaticSitesI[sI] && electrostaticSitesJ[sJ])
112 molI.sitePositions()[sI] - molJ.sitePositions()[sJ];
114 scalar rsIsJMagSq = magSqr(rsIsJ);
116 if (rsIsJMagSq <= electrostatic.rCutSqr())
118 scalar rsIsJMag = mag(rsIsJ);
120 scalar chargeI = constPropI.siteCharges()[sI];
122 scalar chargeJ = constPropJ.siteCharges()[sJ];
126 *chargeI*chargeJ*electrostatic.force(rsIsJMag);
128 molI.siteForces()[sI] += fsIsJ;
130 molJ.siteForces()[sJ] += -fsIsJ;
132 scalar potentialEnergy =
134 *electrostatic.energy(rsIsJMag);
136 molI.potentialEnergy() += 0.5*potentialEnergy;
138 molJ.potentialEnergy() += 0.5*potentialEnergy;
140 vector rIJ = molI.position() - molJ.position();
142 tensor virialContribution =
143 (rsIsJ*fsIsJ)*(rsIsJ & rIJ)/rsIsJMagSq;
145 molI.rf() += virialContribution;
147 molJ.rf() += virialContribution;
155 inline bool Foam::moleculeCloud::evaluatePotentialLimit
161 const pairPotentialList& pairPot = pot_.pairPotentials();
163 const pairPotential& electrostatic = pairPot.electrostatic();
165 label idI = molI.id();
167 label idJ = molJ.id();
169 const molecule::constantProperties& constPropI(constProps(idI));
171 const molecule::constantProperties& constPropJ(constProps(idJ));
173 List<label> siteIdsI = constPropI.siteIds();
175 List<label> siteIdsJ = constPropJ.siteIds();
177 List<bool> pairPotentialSitesI = constPropI.pairPotentialSites();
179 List<bool> electrostaticSitesI = constPropI.electrostaticSites();
181 List<bool> pairPotentialSitesJ = constPropJ.pairPotentialSites();
183 List<bool> electrostaticSitesJ = constPropJ.electrostaticSites();
187 label idsI(siteIdsI[sI]);
191 label idsJ(siteIdsJ[sJ]);
193 if (pairPotentialSitesI[sI] && pairPotentialSitesJ[sJ])
196 molI.sitePositions()[sI] - molJ.sitePositions()[sJ];
198 scalar rsIsJMagSq = magSqr(rsIsJ);
200 if (pairPot.rCutSqr(idsI, idsJ, rsIsJMagSq))
202 scalar rsIsJMag = mag(rsIsJ);
204 // Guard against pairPot.energy being evaluated
205 // if rIJMag < SMALL. A floating point exception will
208 if (rsIsJMag < SMALL)
210 WarningIn("moleculeCloud::removeHighEnergyOverlaps()")
211 << "Molecule site pair closer than "
213 << ": mag separation = " << rsIsJMag
214 << ". These may have been placed on top of each"
215 << " other by a rounding error in mdInitialise in"
216 << " parallel or a block filled with molecules"
217 << " twice. Removing one of the molecules."
223 // Guard against pairPot.energy being evaluated if rIJMag <
224 // rMin. A tabulation lookup error will occur otherwise.
226 if (rsIsJMag < pairPot.rMin(idsI, idsJ))
233 mag(pairPot.energy(idsI, idsJ, rsIsJMag))
234 > pot_.potentialEnergyLimit()
242 if (electrostaticSitesI[sI] && electrostaticSitesJ[sJ])
245 molI.sitePositions()[sI] - molJ.sitePositions()[sJ];
247 scalar rsIsJMagSq = magSqr(rsIsJ);
249 if (pairPot.rCutMaxSqr(rsIsJMagSq))
251 scalar rsIsJMag = mag(rsIsJ);
253 // Guard against pairPot.energy being evaluated
254 // if rIJMag < SMALL. A floating point exception will
257 if (rsIsJMag < SMALL)
259 WarningIn("moleculeCloud::removeHighEnergyOverlaps()")
260 << "Molecule site pair closer than "
262 << ": mag separation = " << rsIsJMag
263 << ". These may have been placed on top of each"
264 << " other by a rounding error in mdInitialise in"
265 << " parallel or a block filled with molecules"
266 << " twice. Removing one of the molecules."
272 if (rsIsJMag < electrostatic.rMin())
277 scalar chargeI = constPropI.siteCharges()[sI];
279 scalar chargeJ = constPropJ.siteCharges()[sJ];
283 mag(chargeI*chargeJ*electrostatic.energy(rsIsJMag))
284 > pot_.potentialEnergyLimit()
298 inline Foam::vector Foam::moleculeCloud::equipartitionLinearVelocity
304 return sqrt(physicoChemical::k.value()*temperature/mass)*vector
306 rndGen_.GaussNormal(),
307 rndGen_.GaussNormal(),
308 rndGen_.GaussNormal()
313 inline Foam::vector Foam::moleculeCloud::equipartitionAngularMomentum
316 const molecule::constantProperties& cP
319 scalar sqrtKbT = sqrt(physicoChemical::k.value()*temperature);
321 if (cP.linearMolecule())
323 return sqrtKbT*vector
326 sqrt(cP.momentOfInertia().yy())*rndGen_.GaussNormal(),
327 sqrt(cP.momentOfInertia().zz())*rndGen_.GaussNormal()
332 return sqrtKbT*vector
334 sqrt(cP.momentOfInertia().xx())*rndGen_.GaussNormal(),
335 sqrt(cP.momentOfInertia().yy())*rndGen_.GaussNormal(),
336 sqrt(cP.momentOfInertia().zz())*rndGen_.GaussNormal()
342 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
344 inline const Foam::polyMesh& Foam::moleculeCloud::mesh() const
350 inline const Foam::potential& Foam::moleculeCloud::pot() const
356 inline const Foam::List<Foam::DynamicList<Foam::molecule*> >&
357 Foam::moleculeCloud::cellOccupancy() const
359 return cellOccupancy_;
363 inline const Foam::InteractionLists<Foam::molecule>&
364 Foam::moleculeCloud::il() const
370 inline const Foam::List<Foam::molecule::constantProperties>
371 Foam::moleculeCloud::constProps() const
373 return constPropList_;
377 inline const Foam::molecule::constantProperties&
378 Foam::moleculeCloud::constProps(label id) const
380 return constPropList_[id];
384 inline Foam::Random& Foam::moleculeCloud::rndGen()
390 // ************************************************************************* //