BUG: UListIO: byteSize overflowing on really big faceLists
[OpenFOAM-2.0.x.git] / src / lagrangian / molecularDynamics / molecule / moleculeCloud / moleculeCloudI.H
blob2cf2e52bb1995915b1bf8b70a29ffe95c03be8ed
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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
19     for more details.
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
34     molecule& molI,
35     molecule& molJ
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();
62     forAll(siteIdsI, sI)
63     {
64         label idsI(siteIdsI[sI]);
66         forAll(siteIdsJ, sJ)
67         {
68             label idsJ(siteIdsJ[sJ]);
70             if (pairPotentialSitesI[sI] && pairPotentialSitesJ[sJ])
71             {
72                 vector rsIsJ =
73                     molI.sitePositions()[sI] - molJ.sitePositions()[sJ];
75                 scalar rsIsJMagSq = magSqr(rsIsJ);
77                 if (pairPot.rCutSqr(idsI, idsJ, rsIsJMagSq))
78                 {
79                     scalar rsIsJMag = mag(rsIsJ);
81                     vector fsIsJ =
82                         (rsIsJ/rsIsJMag)
83                        *pairPot.force(idsI, idsJ, rsIsJMag);
85                     molI.siteForces()[sI] += fsIsJ;
87                     molJ.siteForces()[sJ] += -fsIsJ;
89                     scalar potentialEnergy
90                     (
91                         pairPot.energy(idsI, idsJ, rsIsJMag)
92                     );
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;
106                 }
107             }
109             if (electrostaticSitesI[sI] && electrostaticSitesJ[sJ])
110             {
111                 vector rsIsJ =
112                 molI.sitePositions()[sI] - molJ.sitePositions()[sJ];
114                 scalar rsIsJMagSq = magSqr(rsIsJ);
116                 if (rsIsJMagSq <= electrostatic.rCutSqr())
117                 {
118                     scalar rsIsJMag = mag(rsIsJ);
120                     scalar chargeI = constPropI.siteCharges()[sI];
122                     scalar chargeJ = constPropJ.siteCharges()[sJ];
124                     vector fsIsJ =
125                         (rsIsJ/rsIsJMag)
126                        *chargeI*chargeJ*electrostatic.force(rsIsJMag);
128                     molI.siteForces()[sI] += fsIsJ;
130                     molJ.siteForces()[sJ] += -fsIsJ;
132                     scalar potentialEnergy =
133                         chargeI*chargeJ
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;
148                 }
149             }
150         }
151     }
155 inline bool Foam::moleculeCloud::evaluatePotentialLimit
157     molecule& molI,
158     molecule& molJ
159 ) const
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();
185     forAll(siteIdsI, sI)
186     {
187         label idsI(siteIdsI[sI]);
189         forAll(siteIdsJ, sJ)
190         {
191             label idsJ(siteIdsJ[sJ]);
193             if (pairPotentialSitesI[sI] && pairPotentialSitesJ[sJ])
194             {
195                 vector rsIsJ =
196                     molI.sitePositions()[sI] - molJ.sitePositions()[sJ];
198                 scalar rsIsJMagSq = magSqr(rsIsJ);
200                 if (pairPot.rCutSqr(idsI, idsJ, rsIsJMagSq))
201                 {
202                     scalar rsIsJMag = mag(rsIsJ);
204                     // Guard against pairPot.energy being evaluated
205                     // if rIJMag < SMALL. A floating point exception will
206                     // happen otherwise.
208                     if (rsIsJMag < SMALL)
209                     {
210                         WarningIn("moleculeCloud::removeHighEnergyOverlaps()")
211                             << "Molecule site pair closer than "
212                             << SMALL
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."
218                             << endl;
220                         return true;
221                     }
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))
227                     {
228                         return true;
229                     }
231                     if
232                     (
233                         mag(pairPot.energy(idsI, idsJ, rsIsJMag))
234                       > pot_.potentialEnergyLimit()
235                     )
236                     {
237                         return true;
238                     };
239                 }
240             }
242             if (electrostaticSitesI[sI] && electrostaticSitesJ[sJ])
243             {
244                 vector rsIsJ =
245                     molI.sitePositions()[sI] - molJ.sitePositions()[sJ];
247                 scalar rsIsJMagSq = magSqr(rsIsJ);
249                 if (pairPot.rCutMaxSqr(rsIsJMagSq))
250                 {
251                     scalar rsIsJMag = mag(rsIsJ);
253                     // Guard against pairPot.energy being evaluated
254                     // if rIJMag < SMALL. A floating point exception will
255                     // happen otherwise.
257                     if (rsIsJMag < SMALL)
258                     {
259                         WarningIn("moleculeCloud::removeHighEnergyOverlaps()")
260                             << "Molecule site pair closer than "
261                             << SMALL
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."
267                             << endl;
269                         return true;
270                     }
272                     if (rsIsJMag < electrostatic.rMin())
273                     {
274                         return true;
275                     }
277                     scalar chargeI = constPropI.siteCharges()[sI];
279                     scalar chargeJ = constPropJ.siteCharges()[sJ];
281                     if
282                     (
283                         mag(chargeI*chargeJ*electrostatic.energy(rsIsJMag))
284                       > pot_.potentialEnergyLimit()
285                     )
286                     {
287                         return true;
288                     };
289                 }
290             }
291         }
292     }
294     return false;
298 inline Foam::vector Foam::moleculeCloud::equipartitionLinearVelocity
300     scalar temperature,
301     scalar mass
304     return sqrt(physicoChemical::k.value()*temperature/mass)*vector
305     (
306         rndGen_.GaussNormal(),
307         rndGen_.GaussNormal(),
308         rndGen_.GaussNormal()
309     );
313 inline Foam::vector Foam::moleculeCloud::equipartitionAngularMomentum
315     scalar temperature,
316     const molecule::constantProperties& cP
319     scalar sqrtKbT = sqrt(physicoChemical::k.value()*temperature);
321     if (cP.linearMolecule())
322     {
323         return sqrtKbT*vector
324         (
325             0.0,
326             sqrt(cP.momentOfInertia().yy())*rndGen_.GaussNormal(),
327             sqrt(cP.momentOfInertia().zz())*rndGen_.GaussNormal()
328         );
329     }
330     else
331     {
332         return sqrtKbT*vector
333         (
334             sqrt(cP.momentOfInertia().xx())*rndGen_.GaussNormal(),
335             sqrt(cP.momentOfInertia().yy())*rndGen_.GaussNormal(),
336             sqrt(cP.momentOfInertia().zz())*rndGen_.GaussNormal()
337         );
338     }
342 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
344 inline const Foam::polyMesh& Foam::moleculeCloud::mesh() const
346     return mesh_;
350 inline const Foam::potential& Foam::moleculeCloud::pot() const
352     return pot_;
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
366     return il_;
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()
386     return rndGen_;
390 // ************************************************************************* //