FreeFOAM The Cross-Platform CFD Toolkit
advectiveFvPatchField.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) 1991-2010 OpenCFD Ltd.
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 "advectiveFvPatchField.H"
29 #include <finiteVolume/volFields.H>
33 
34 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
35 
36 namespace Foam
37 {
38 
39 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
40 
41 template<class Type>
43 (
44  const fvPatch& p,
46 )
47 :
49  phiName_("phi"),
50  rhoName_("rho"),
51  fieldInf_(pTraits<Type>::zero),
52  lInf_(0.0)
53 {
54  this->refValue() = pTraits<Type>::zero;
55  this->refGrad() = pTraits<Type>::zero;
56  this->valueFraction() = 0.0;
57 }
58 
59 
60 template<class Type>
62 (
63  const advectiveFvPatchField& ptf,
64  const fvPatch& p,
66  const fvPatchFieldMapper& mapper
67 )
68 :
69  mixedFvPatchField<Type>(ptf, p, iF, mapper),
70  phiName_(ptf.phiName_),
71  rhoName_(ptf.rhoName_),
72  fieldInf_(ptf.fieldInf_),
73  lInf_(ptf.lInf_)
74 {}
75 
76 
77 template<class Type>
79 (
80  const fvPatch& p,
82  const dictionary& dict
83 )
84 :
86  phiName_(dict.lookupOrDefault<word>("phi", "phi")),
87  rhoName_(dict.lookupOrDefault<word>("rho", "rho")),
88  fieldInf_(pTraits<Type>::zero),
89  lInf_(0.0)
90 {
91  if (dict.found("value"))
92  {
94  (
95  Field<Type>("value", dict, p.size())
96  );
97  }
98  else
99  {
100  fvPatchField<Type>::operator=(this->patchInternalField());
101  }
102 
103  this->refValue() = *this;
104  this->refGrad() = pTraits<Type>::zero;
105  this->valueFraction() = 0.0;
106 
107  if (dict.readIfPresent("lInf", lInf_))
108  {
109  dict.lookup("fieldInf") >> fieldInf_;
110 
111  if (lInf_ < 0.0)
112  {
114  (
115  "advectiveFvPatchField<Type>::"
116  "advectiveFvPatchField"
117  "(const fvPatch&, const Field<Type>&, const dictionary&)",
118  dict
119  ) << "unphysical lInf specified (lInf < 0)\n"
120  << " on patch " << this->patch().name()
121  << " of field " << this->dimensionedInternalField().name()
122  << " in file " << this->dimensionedInternalField().objectPath()
123  << exit(FatalIOError);
124  }
125  }
126 }
127 
128 
129 template<class Type>
131 (
132  const advectiveFvPatchField& ptpsf
133 )
134 :
136  phiName_(ptpsf.phiName_),
137  rhoName_(ptpsf.rhoName_),
138  fieldInf_(ptpsf.fieldInf_),
139  lInf_(ptpsf.lInf_)
140 {}
141 
142 
143 template<class Type>
145 (
146  const advectiveFvPatchField& ptpsf,
148 )
149 :
150  mixedFvPatchField<Type>(ptpsf, iF),
151  phiName_(ptpsf.phiName_),
152  rhoName_(ptpsf.rhoName_),
153  fieldInf_(ptpsf.fieldInf_),
154  lInf_(ptpsf.lInf_)
155 {}
156 
157 
158 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
159 
160 template<class Type>
162 {
163  const surfaceScalarField& phi =
164  this->db().objectRegistry::lookupObject<surfaceScalarField>(phiName_);
165 
166  fvsPatchField<scalar> phip = this->patch().lookupPatchField
167  (
168  phiName_,
169  reinterpret_cast<const surfaceScalarField*>(0),
170  reinterpret_cast<const scalar*>(0)
171  );
172 
174  {
175  const fvPatchScalarField& rhop = this->patch().lookupPatchField
176  (
177  rhoName_,
178  reinterpret_cast<const volScalarField*>(0),
179  reinterpret_cast<const scalar*>(0)
180  );
181 
182  return phip/(rhop*this->patch().magSf());
183  }
184  else
185  {
186  return phip/this->patch().magSf();
187  }
188 }
189 
190 
191 template<class Type>
193 {
194  if (this->updated())
195  {
196  return;
197  }
198 
199  word ddtScheme
200  (
201  this->dimensionedInternalField().mesh()
202  .ddtScheme(this->dimensionedInternalField().name())
203  );
204  scalar deltaT = this->db().time().deltaT().value();
205 
207  this->db().objectRegistry:: lookupObject<GeometricField<Type, fvPatchField, volMesh> >
208  (
209  this->dimensionedInternalField().name()
210  );
211 
212  // Calculate the advection speed of the field wave
213  // If the wave is incoming set the speed to 0.
214  scalarField w = Foam::max(advectionSpeed(), scalar(0));
215 
216  // Calculate the field wave coefficient alpha (See notes)
217  scalarField alpha = w*deltaT*this->patch().deltaCoeffs();
218 
219  label patchi = this->patch().index();
220 
221  // Non-reflecting outflow boundary
222  // If lInf_ defined setup relaxation to the value fieldInf_.
223  if (lInf_ > SMALL)
224  {
225  // Calculate the field relaxation coefficient k (See notes)
226  scalarField k = w*deltaT/lInf_;
227 
228  if
229  (
232  )
233  {
234  this->refValue() =
235  (
236  field.oldTime().boundaryField()[patchi] + k*fieldInf_
237  )/(1.0 + k);
238 
239  this->valueFraction() = (1.0 + k)/(1.0 + alpha + k);
240  }
241  else if (ddtScheme == fv::backwardDdtScheme<scalar>::typeName)
242  {
243  this->refValue() =
244  (
245  2.0*field.oldTime().boundaryField()[patchi]
246  - 0.5*field.oldTime().oldTime().boundaryField()[patchi]
247  + k*fieldInf_
248  )/(1.5 + k);
249 
250  this->valueFraction() = (1.5 + k)/(1.5 + alpha + k);
251  }
252  else
253  {
255  (
256  "advectiveFvPatchField<Type>::updateCoeffs()"
257  ) << " Unsupported temporal differencing scheme : "
258  << ddtScheme
259  << "\n on patch " << this->patch().name()
260  << " of field " << this->dimensionedInternalField().name()
261  << " in file " << this->dimensionedInternalField().objectPath()
262  << exit(FatalError);
263  }
264  }
265  else
266  {
267  if
268  (
271  )
272  {
273  this->refValue() = field.oldTime().boundaryField()[patchi];
274 
275  this->valueFraction() = 1.0/(1.0 + alpha);
276  }
277  else if (ddtScheme == fv::backwardDdtScheme<scalar>::typeName)
278  {
279  this->refValue() =
280  (
281  2.0*field.oldTime().boundaryField()[patchi]
282  - 0.5*field.oldTime().oldTime().boundaryField()[patchi]
283  )/1.5;
284 
285  this->valueFraction() = 1.5/(1.5 + alpha);
286  }
287  else
288  {
290  (
291  "advectiveFvPatchField<Type>::updateCoeffs()"
292  ) << " Unsupported temporal differencing scheme : "
293  << ddtScheme
294  << "\n on patch " << this->patch().name()
295  << " of field " << this->dimensionedInternalField().name()
296  << " in file " << this->dimensionedInternalField().objectPath()
297  << exit(FatalError);
298  }
299  }
300 
302 }
303 
304 
305 template<class Type>
307 {
309 
310  if (phiName_ != "phi")
311  {
312  os.writeKeyword("phi") << phiName_ << token::END_STATEMENT << nl;
313  }
314  if (rhoName_ != "rho")
315  {
316  os.writeKeyword("rho") << rhoName_ << token::END_STATEMENT << nl;
317  }
318 
319  if (lInf_ > SMALL)
320  {
321  os.writeKeyword("fieldInf") << fieldInf_
322  << token::END_STATEMENT << nl;
323  os.writeKeyword("lInf") << lInf_
324  << token::END_STATEMENT << nl;
325  }
326 
327  this->writeEntry("value", os);
328 }
329 
330 
331 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
332 
333 } // End namespace Foam
334 
335 // ************************ vim: set sw=4 sts=4 et: ************************ //
336