ENH: autoLayerDriver: better layering information message
[OpenFOAM-2.0.x.git] / src / lagrangian / intermediate / submodels / Kinematic / PatchInteractionModel / LocalInteraction / LocalInteraction.C
blob4ff52cf17b01b3510fddb1281465f70e5be4c560
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 "LocalInteraction.H"
28 // * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //
30 template<class CloudType>
31 void Foam::LocalInteraction<CloudType>::readProps()
33     if (!this->owner().solution().transient())
34     {
35         return;
36     }
38     IOobject propsDictHeader
39     (
40         "localInteractionProperties",
41         this->owner().db().time().timeName(),
42         "uniform"/cloud::prefix/this->owner().name(),
43         this->owner().db(),
44         IOobject::MUST_READ_IF_MODIFIED,
45         IOobject::NO_WRITE,
46         false
47     );
49     if (propsDictHeader.headerOk())
50     {
51         const IOdictionary propsDict(propsDictHeader);
52         propsDict.readIfPresent("nEscape", nEscape0_);
53         propsDict.readIfPresent("massEscape", massEscape0_);
54         propsDict.readIfPresent("nStick", nStick0_);
55         propsDict.readIfPresent("massStick", massStick0_);
56     }
60 template<class CloudType>
61 void Foam::LocalInteraction<CloudType>::writeProps
63     const labelList& nEscape,
64     const scalarList& massEscape,
65     const labelList& nStick,
66     const scalarList& massStick
67 ) const
69     if (!this->owner().solution().transient())
70     {
71         return;
72     }
74     if (this->owner().db().time().outputTime())
75     {
76         IOdictionary propsDict
77         (
78             IOobject
79             (
80                 "localInteractionProperties",
81                 this->owner().db().time().timeName(),
82                 "uniform"/cloud::prefix/this->owner().name(),
83                 this->owner().db(),
84                 IOobject::NO_READ,
85                 IOobject::NO_WRITE,
86                 false
87             )
88         );
90         propsDict.add("nEscape", nEscape);
91         propsDict.add("massEscape", massEscape);
92         propsDict.add("nStick", nStick);
93         propsDict.add("massStick", massStick);
95         propsDict.writeObject
96         (
97             IOstream::ASCII,
98             IOstream::currentVersion,
99             this->owner().db().time().writeCompression()
100         );
101     }
105 // * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * * //
107 template<class CloudType>
108 Foam::LocalInteraction<CloudType>::LocalInteraction
110     const dictionary& dict,
111     CloudType& cloud
114     PatchInteractionModel<CloudType>(dict, cloud, typeName),
115     patchData_(cloud.mesh(), this->coeffDict()),
116     nEscape0_(patchData_.size(), 0),
117     massEscape0_(patchData_.size(), 0.0),
118     nStick0_(patchData_.size(), 0),
119     massStick0_(patchData_.size(), 0.0),
120     nEscape_(patchData_.size(), 0),
121     massEscape_(patchData_.size(), 0.0),
122     nStick_(patchData_.size(), 0),
123     massStick_(patchData_.size(), 0.0)
125     // check that interactions are valid/specified
126     forAll(patchData_, patchI)
127     {
128         const word& interactionTypeName =
129             patchData_[patchI].interactionTypeName();
130         const typename PatchInteractionModel<CloudType>::interactionType& it =
131             this->wordToInteractionType(interactionTypeName);
133         if (it == PatchInteractionModel<CloudType>::itOther)
134         {
135             const word& patchName = patchData_[patchI].patchName();
136             FatalErrorIn("LocalInteraction(const dictionary&, CloudType&)")
137                 << "Unknown patch interaction type "
138                 << interactionTypeName << " for patch " << patchName
139                 << ". Valid selections are:"
140                 << this->PatchInteractionModel<CloudType>::interactionTypeNames_
141                 << nl << exit(FatalError);
142         }
143     }
145     readProps();
149 template<class CloudType>
150 Foam::LocalInteraction<CloudType>::LocalInteraction
152     const LocalInteraction<CloudType>& pim
155     PatchInteractionModel<CloudType>(pim),
156     patchData_(pim.patchData_),
157     nEscape0_(pim.nEscape0_),
158     massEscape0_(pim.massEscape0_),
159     nStick0_(pim.nStick0_),
160     massStick0_(pim.massStick0_),
161     nEscape_(pim.nEscape_),
162     massEscape_(pim.massEscape_),
163     nStick_(pim.nStick_),
164     massStick_(pim.massStick_)
168 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
170 template<class CloudType>
171 Foam::LocalInteraction<CloudType>::~LocalInteraction()
175 // * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
177 template<class CloudType>
178 bool Foam::LocalInteraction<CloudType>::correct
180     typename CloudType::parcelType& p,
181     const polyPatch& pp,
182     bool& keepParticle,
183     const scalar trackFraction,
184     const tetIndices& tetIs
187     vector& U = p.U();
189     bool& active = p.active();
191     label patchI = patchData_.applyToPatch(pp.index());
193     if (patchI >= 0)
194     {
195         typename PatchInteractionModel<CloudType>::interactionType it =
196             this->wordToInteractionType
197             (
198                 patchData_[patchI].interactionTypeName()
199             );
201         switch (it)
202         {
203             case PatchInteractionModel<CloudType>::itEscape:
204             {
205                 keepParticle = false;
206                 active = false;
207                 U = vector::zero;
208                 nEscape_[patchI]++;
209                 massEscape_[patchI] += p.mass()*p.nParticle();
210                 break;
211             }
212             case PatchInteractionModel<CloudType>::itStick:
213             {
214                 keepParticle = true;
215                 active = false;
216                 U = vector::zero;
217                 nStick_[patchI]++;
218                 massStick_[patchI] += p.mass()*p.nParticle();
219                 break;
220             }
221             case PatchInteractionModel<CloudType>::itRebound:
222             {
223                 keepParticle = true;
224                 active = true;
226                 vector nw;
227                 vector Up;
229                 this->patchData(p, pp, trackFraction, tetIs, nw, Up);
231                 // Calculate motion relative to patch velocity
232                 U -= Up;
234                 scalar Un = U & nw;
235                 vector Ut = U - Un*nw;
237                 if (Un > 0)
238                 {
239                     U -= (1.0 + patchData_[patchI].e())*Un*nw;
240                 }
242                 U -= patchData_[patchI].mu()*Ut;
244                 // Return velocity to global space
245                 U += Up;
247                 break;
248             }
249             default:
250             {
251                 FatalErrorIn
252                 (
253                     "bool LocalInteraction<CloudType>::correct"
254                     "("
255                         "typename CloudType::parcelType&, "
256                         "const polyPatch&, "
257                         "bool&, "
258                         "scalar&, "
259                         "const tetIndices&"
260                     ") const"
261                 )   << "Unknown interaction type "
262                     << patchData_[patchI].interactionTypeName()
263                     << "(" << it << ") for patch "
264                     << patchData_[patchI].patchName()
265                     << ". Valid selections are:" << this->interactionTypeNames_
266                     << endl << abort(FatalError);
267             }
268         }
270         return true;
271     }
273     return false;
277 template<class CloudType>
278 void Foam::LocalInteraction<CloudType>::info(Ostream& os) const
280     labelList npe(nEscape_);
281     Pstream::listCombineGather(npe, plusEqOp<label>());
282     npe = npe + nEscape0_;
284     scalarList mpe(massEscape_);
285     Pstream::listCombineGather(mpe, plusEqOp<scalar>());
286     mpe = mpe + massEscape0_;
288     labelList nps(nStick_);
289     Pstream::listCombineGather(nps, plusEqOp<label>());
290     nps = nps + nStick0_;
292     scalarList mps(massStick_);
293     Pstream::listCombineGather(mps, plusEqOp<scalar>());
294     mps = mps + massStick0_;
297     forAll(patchData_, i)
298     {
299         os  << "    Parcel fate (number, mass)      : patch "
300             <<  patchData_[i].patchName() << nl
301             << "      - escape                      = " << npe[i]
302             << ", " << mpe[i] << nl
303             << "      - stick                       = " << nps[i]
304             << ", " << mps[i] << nl;
305     }
307     writeProps(npe, mpe, nps, mps);
311 // ************************************************************************* //