molecule.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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.
15 
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.
20 
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/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "moleculeCloud.H"
27 #include "molecule.H"
28 #include "Random.H"
29 #include "Time.H"
30 
31 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
32 
33 Foam::tensor Foam::molecule::rotationTensorX(scalar phi) const
34 {
35  return tensor
36  (
37  1, 0, 0,
38  0, Foam::cos(phi), -Foam::sin(phi),
39  0, Foam::sin(phi), Foam::cos(phi)
40  );
41 }
42 
43 
44 Foam::tensor Foam::molecule::rotationTensorY(scalar phi) const
45 {
46  return tensor
47  (
48  Foam::cos(phi), 0, Foam::sin(phi),
49  0, 1, 0,
50  -Foam::sin(phi), 0, Foam::cos(phi)
51  );
52 }
53 
54 
55 Foam::tensor Foam::molecule::rotationTensorZ(scalar phi) const
56 {
57  return tensor
58  (
59  Foam::cos(phi), -Foam::sin(phi), 0,
60  Foam::sin(phi), Foam::cos(phi), 0,
61  0, 0, 1
62  );
63 }
64 
65 
66 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
67 
68 bool Foam::molecule::move(molecule::trackingData& td, const scalar trackTime)
69 {
70  td.switchProcessor = false;
71  td.keepParticle = true;
72 
73  const constantProperties& constProps(td.cloud().constProps(id_));
74 
75  if (td.part() == 0)
76  {
77  // First leapfrog velocity adjust part, required before tracking+force
78  // part
79 
80  v_ += 0.5*trackTime*a_;
81 
82  pi_ += 0.5*trackTime*tau_;
83  }
84  else if (td.part() == 1)
85  {
86  // Leapfrog tracking part
87 
88  while (td.keepParticle && !td.switchProcessor && stepFraction() < 1)
89  {
90  const scalar f = 1 - stepFraction();
91  trackToFace(f*trackTime*v_, f, td);
92  }
93  }
94  else if (td.part() == 2)
95  {
96  // Leapfrog orientation adjustment, carried out before force calculation
97  // but after tracking stage, i.e. rotation carried once linear motion
98  // complete.
99 
100  if (!constProps.pointMolecule())
101  {
102  const diagTensor& momentOfInertia(constProps.momentOfInertia());
103 
104  tensor R;
105 
106  if (!constProps.linearMolecule())
107  {
108  R = rotationTensorX(0.5*trackTime*pi_.x()/momentOfInertia.xx());
109  pi_ = pi_ & R;
110  Q_ = Q_ & R;
111  }
112 
113  R = rotationTensorY(0.5*trackTime*pi_.y()/momentOfInertia.yy());
114  pi_ = pi_ & R;
115  Q_ = Q_ & R;
116 
117  R = rotationTensorZ(trackTime*pi_.z()/momentOfInertia.zz());
118  pi_ = pi_ & R;
119  Q_ = Q_ & R;
120 
121  R = rotationTensorY(0.5*trackTime*pi_.y()/momentOfInertia.yy());
122  pi_ = pi_ & R;
123  Q_ = Q_ & R;
124 
125  if (!constProps.linearMolecule())
126  {
127  R = rotationTensorX(0.5*trackTime*pi_.x()/momentOfInertia.xx());
128  pi_ = pi_ & R;
129  Q_ = Q_ & R;
130  }
131  }
132 
133  setSitePositions(constProps);
134  }
135  else if (td.part() == 3)
136  {
137  // Second leapfrog velocity adjust part, required after tracking+force
138  // part
139 
140  scalar m = constProps.mass();
141 
142  a_ = Zero;
143 
144  tau_ = Zero;
145 
146  forAll(siteForces_, s)
147  {
148  const vector& f = siteForces_[s];
149 
150  a_ += f/m;
151 
152  tau_ += (constProps.siteReferencePositions()[s] ^ (Q_.T() & f));
153  }
154 
155  v_ += 0.5*trackTime*a_;
156 
157  pi_ += 0.5*trackTime*tau_;
158 
159  if (constProps.pointMolecule())
160  {
161  tau_ = Zero;
162 
163  pi_ = Zero;
164  }
165 
166  if (constProps.linearMolecule())
167  {
168  tau_.x() = 0.0;
169 
170  pi_.x() = 0.0;
171  }
172  }
173  else
174  {
176  << td.part() << " is an invalid part of the integration method."
177  << abort(FatalError);
178  }
179 
180  return td.keepParticle;
181 }
182 
183 
185 {
187 
188  Q_ = T & Q_;
189 
190  v_ = transform(T, v_);
191 
192  a_ = transform(T, a_);
193 
194  pi_ = Q_.T() & transform(T, Q_ & pi_);
195 
196  tau_ = Q_.T() & transform(T, Q_ & tau_);
197 
198  rf_ = transform(T, rf_);
199 
200  sitePositions_ = position() + (T & (sitePositions_ - position()));
201 
202  siteForces_ = T & siteForces_;
203 }
204 
205 
207 {
208  particle::transformProperties(separation);
209 
210  if (special_ == SPECIAL_TETHERED)
211  {
212  specialPosition_ += separation;
213  }
214 
215  sitePositions_ = sitePositions_ + separation;
216 }
217 
218 
220 {
221  sitePositions_ = position() + (Q_ & constProps.siteReferencePositions());
222 }
223 
224 
226 {
227  sitePositions_.setSize(size);
228 
229  siteForces_.setSize(size);
230 }
231 
232 
234 (
235  const polyPatch&,
236  trackingData&,
237  const label,
238  const scalar,
239  const tetIndices&
240 )
241 {
242  return false;
243 }
244 
245 
247 (
248  const processorPolyPatch&,
249  trackingData& td
250 )
251 {
252  td.switchProcessor = true;
253 }
254 
255 
257 (
258  const wallPolyPatch& wpp,
259  trackingData& td,
260  const tetIndices& tetIs
261 )
262 {
263  // Use of the normal from tetIs is not required as
264  // hasWallImpactDistance for a moleculeCloud is false.
265  vector nw = normal();
266  nw /= mag(nw);
267 
268  scalar vn = v_ & nw;
269 
270  // Specular reflection
271  if (vn > 0)
272  {
273  v_ -= 2*vn*nw;
274  }
275 }
276 
277 
279 (
280  const polyPatch&,
281  trackingData& td
282 )
283 {
284  td.keepParticle = false;
285 }
286 
287 
288 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
void hitProcessorPatch(const processorPolyPatch &, trackingData &td)
Overridable function to handle the particle hitting a processorPatch.
Definition: molecule.C:247
Class to hold molecule constant properties.
Definition: molecule.H:89
void setSitePositions(const constantProperties &constProps)
Definition: molecule.C:219
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
scalar trackToFace(const vector &displacement, const scalar fraction)
As particle::track, but also stops on internal faces.
Definition: particle.C:622
Tensor< Cmpt > T() const
Return transpose.
Definition: TensorI.H:321
virtual void transformProperties(const tensor &T)
Transform the physical properties of the particle.
Definition: particle.C:978
const Cmpt & y() const
Definition: VectorI.H:81
Neighbour processor patch.
vector normal() const
Return the normal of the tri on tetFacei_ for the.
Definition: particleI.H:168
CloudType & cloud()
Return a reference to the cloud.
Definition: particle.H:138
const Field< vector > & siteReferencePositions() const
Definition: moleculeI.H:366
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
dimensionedScalar cos(const dimensionedScalar &ds)
void hitWallPatch(const wallPolyPatch &, trackingData &td, const tetIndices &)
Overridable function to handle the particle hitting a wallPatch.
Definition: molecule.C:257
Foam::wallPolyPatch.
Definition: wallPolyPatch.H:48
bool move(trackingData &, const scalar trackTime)
Definition: molecule.C:68
static const zero Zero
Definition: zero.H:91
Storage and named access for the indices of a tet which is part of the decomposition of a cell...
Definition: tetIndices.H:81
bool keepParticle
Flag to indicate whether to keep particle (false = delete)
Definition: particle.H:125
virtual void transformProperties(const tensor &T)
Transform the physical properties of the particle.
Definition: molecule.C:184
errorManip< error > abort(error &err)
Definition: errorManip.H:131
const Cmpt & x() const
Definition: VectorI.H:75
dimensionedScalar sin(const dimensionedScalar &ds)
labelList f(nPoints)
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
scalar stepFraction() const
Return the fraction of time-step completed.
Definition: particleI.H:81
void setSize(const label)
Reset size of List.
Definition: List.C:281
bool hitPatch(const polyPatch &, trackingData &td, const label patchi, const scalar trackFraction, const tetIndices &tetIs)
Overridable function to handle the particle hitting a patch.
Definition: molecule.C:234
#define R(A, B, C, D, E, F, K, M)
Class used to pass tracking data to the trackToFace function.
Definition: molecule.H:165
void setSiteSizes(label size)
Definition: molecule.C:225
dimensioned< scalar > mag(const dimensioned< Type > &)
const List< molecule::constantProperties > constProps() const
Calculates the inertia tensor and principal axes and moments of a polyhedra/cells/triSurfaces. Inertia can either be of the solid body or of a thin shell.
bool switchProcessor
Flag to switch processor.
Definition: particle.H:122
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:66
vector position() const
Return current particle position.
Definition: particleI.H:204
Tensor< scalar > tensor
Tensor of scalars.
Definition: tensor.H:51
label nw
Definition: createFields.H:25
dimensionSet transform(const dimensionSet &)
Definition: dimensionSet.C:477