Maxwell.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2016-2023 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 "Maxwell.H"
27 #include "fvModels.H"
28 #include "fvConstraints.H"
30 
31 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
32 
33 namespace Foam
34 {
35 namespace laminarModels
36 {
37 
38 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
39 
40 template<class BasicMomentumTransportModel>
41 PtrList<dimensionedScalar>
43 (
44  const word& name,
45  const dimensionSet& dims
46 ) const
47 {
48  PtrList<dimensionedScalar> modeCoeffs(nModes_);
49 
50  if (modeCoefficients_.size())
51  {
52  if (this->coeffDict().found(name))
53  {
54  IOWarningInFunction(this->coeffDict())
55  << "Using 'modes' list, '" << name << "' entry will be ignored."
56  << endl;
57  }
58 
59  forAll(modeCoefficients_, modei)
60  {
61  modeCoeffs.set
62  (
63  modei,
65  (
66  name,
67  dims,
68  modeCoefficients_[modei].lookup(name)
69  )
70  );
71  }
72  }
73  else
74  {
75  modeCoeffs.set
76  (
77  0,
79  (
80  name,
81  dims,
82  this->coeffDict_.lookup(name)
83  )
84  );
85  }
86 
87  return modeCoeffs;
88 }
89 
90 
91 template<class BasicMomentumTransportModel>
93 (
94  const label modei,
96 ) const
97 {
98  return -fvm::Sp(this->alpha_*this->rho_/lambdas_[modei], sigma);
99 }
100 
101 
102 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
103 
104 template<class BasicMomentumTransportModel>
106 (
107  const alphaField& alpha,
108  const rhoField& rho,
109  const volVectorField& U,
110  const surfaceScalarField& alphaRhoPhi,
111  const surfaceScalarField& phi,
112  const viscosity& viscosity,
113  const word& type
114 )
115 :
116  laminarModel<BasicMomentumTransportModel>
117  (
118  type,
119  alpha,
120  rho,
121  U,
122  alphaRhoPhi,
123  phi,
124  viscosity
125  ),
126 
127  modeCoefficients_
128  (
129  this->coeffDict().found("modes")
131  (
132  this->coeffDict().lookup("modes")
133  )
134  : PtrList<dictionary>()
135  ),
136 
137  nModes_(modeCoefficients_.size() ? modeCoefficients_.size() : 1),
138 
139  nuM_("nuM", dimViscosity, this->coeffDict_.lookup("nuM")),
140 
141  lambdas_(readModeCoefficients("lambda", dimTime)),
142 
143  sigma_
144  (
145  IOobject
146  (
147  this->groupName("sigma"),
148  this->runTime_.name(),
149  this->mesh_,
150  IOobject::MUST_READ,
151  IOobject::AUTO_WRITE
152  ),
153  this->mesh_
154  )
155 {
156  if (nModes_ > 1)
157  {
158  sigmas_.setSize(nModes_);
159 
160  forAll(sigmas_, modei)
161  {
163  (
164  this->groupName("sigma" + name(modei)),
165  this->runTime_.name(),
166  this->mesh_,
168  );
169 
170  // Check if mode field exists and can be read
171  if (header.headerOk())
172  {
173  Info<< " Reading mode stress field "
174  << header.name() << endl;
175 
176  sigmas_.set
177  (
178  modei,
180  (
181  IOobject
182  (
183  header.name(),
184  this->runTime_.name(),
185  this->mesh_,
188  ),
189  this->mesh_
190  )
191  );
192  }
193  else
194  {
195  sigmas_.set
196  (
197  modei,
199  (
200  IOobject
201  (
202  header.name(),
203  this->runTime_.name(),
204  this->mesh_,
207  ),
208  sigma_
209  )
210  );
211  }
212  }
213  }
214 
215  if (type == typeName)
216  {
217  this->printCoeffs(type);
218  }
219 }
220 
221 
222 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
223 
224 template<class BasicMomentumTransportModel>
226 {
228  {
229  if (modeCoefficients_.size())
230  {
231  this->coeffDict().lookup("modes") >> modeCoefficients_;
232  }
233 
234  nuM_.read(this->coeffDict());
235 
236  lambdas_ = readModeCoefficients("lambda", dimTime);
237 
238  return true;
239  }
240  else
241  {
242  return false;
243  }
244 }
245 
246 
247 template<class BasicMomentumTransportModel>
249 {
250  return volScalarField::New
251  (
252  this->groupName("nuEff"),
253  this->nu()
254  );
255 }
256 
257 
258 template<class BasicMomentumTransportModel>
260 (
261  const label patchi
262 ) const
263 {
264  return this->nu(patchi);
265 }
266 
267 
268 template<class BasicMomentumTransportModel>
270 {
271  return sigma_;
272 }
273 
274 
275 template<class BasicMomentumTransportModel>
277 {
279  (
280  this->groupName("devTau"),
281  this->alpha_*this->rho_*sigma_
282  - (this->alpha_*this->rho_*this->nu())
283  *dev(twoSymm(fvc::grad(this->U_)))
284  );
285 }
286 
287 
288 template<class BasicMomentumTransportModel>
290 (
292 ) const
293 {
294  return
295  (
296  fvc::div
297  (
298  this->alpha_*this->rho_*this->nuM_*fvc::grad(U)
299  )
300  + fvc::div(this->alpha_*this->rho_*sigma_)
301  - fvc::div(this->alpha_*this->rho_*this->nu()*dev2(T(fvc::grad(U))))
302  - fvm::laplacian(this->alpha_*this->rho_*nu0(), U)
303  );
304 }
305 
306 
307 template<class BasicMomentumTransportModel>
310 (
311  const volScalarField& rho,
313 ) const
314 {
315  return
316  (
317  fvc::div
318  (
319  this->alpha_*rho*this->nuM_*fvc::grad(U)
320  )
321  + fvc::div(this->alpha_*rho*sigma_)
322  - fvc::div(this->alpha_*rho*this->nu()*dev2(T(fvc::grad(U))))
323  - fvm::laplacian(this->alpha_*rho*nu0(), U)
324  );
325 }
326 
327 
328 template<class BasicMomentumTransportModel>
330 {
331  // Local references
332  const alphaField& alpha = this->alpha_;
333  const rhoField& rho = this->rho_;
334  const surfaceScalarField& alphaRhoPhi = this->alphaRhoPhi_;
335  const volVectorField& U = this->U_;
336  const Foam::fvModels& fvModels(Foam::fvModels::New(this->mesh_));
338  (
339  Foam::fvConstraints::New(this->mesh_)
340  );
341 
343 
345  const volTensorField& gradU = tgradU();
346 
347  forAll(lambdas_, modei)
348  {
349  volSymmTensorField& sigma = nModes_ == 1 ? sigma_ : sigmas_[modei];
350 
352  (
353  IOobject
354  (
355  this->groupName
356  (
357  "rLambda"
358  + (nModes_ == 1 ? word::null : name(modei))
359  ),
360  this->runTime_.constant(),
361  this->mesh_
362  ),
363  1/lambdas_[modei]
364  );
365 
366  // Note sigma is positive on lhs of momentum eqn
367  const volSymmTensorField P
368  (
369  twoSymm(sigma & gradU)
370  - nuM_*rLambda*twoSymm(gradU)
371  );
372 
373  // Viscoelastic stress equation
374  fvSymmTensorMatrix sigmaEqn
375  (
377  + fvm::div
378  (
379  alphaRhoPhi,
380  sigma,
381  "div(" + alphaRhoPhi.name() + ',' + sigma_.name() + ')'
382  )
383  ==
384  alpha*rho*P
385  + sigmaSource(modei, sigma)
386  + fvModels.source(alpha, rho, sigma)
387  );
388 
389  sigmaEqn.relax();
390  fvConstraints.constrain(sigmaEqn);
391  sigmaEqn.solve("sigma");
393  }
394 
395  if (sigmas_.size())
396  {
397  volSymmTensorField sigmaSum("sigmaSum", sigmas_[0]);
398 
399  for (label modei = 1; modei<sigmas_.size(); modei++)
400  {
401  sigmaSum += sigmas_[modei];
402  }
403 
404  sigma_ == sigmaSum;
405  }
406 }
407 
408 
409 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
410 
411 } // End namespace laminarModels
412 } // End namespace Foam
413 
414 // ************************************************************************* //
bool found
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
Generic GeometricField class.
static tmp< GeometricField< Type, PatchField, GeoMesh > > New(const word &name, const Internal &, const PtrList< PatchField< Type >> &)
Return a temporary field constructed from name,.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
const word & name() const
Return name.
Definition: IOobject.H:310
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Definition: PtrList.H:75
bool set(const label) const
Is element set.
Definition: PtrListI.H:65
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:160
static autoPtr< dictionary > New(Istream &)
Construct top-level dictionary on freestore from Istream.
Definition: dictionaryIO.C:100
Dimension set for the base types.
Definition: dimensionSet.H:122
Finite volume constraints.
Definition: fvConstraints.H:62
bool constrain(fvMatrix< Type > &eqn) const
Apply constraints to an equation.
A special matrix type and solver, designed for finite volume solutions of scalar equations....
Definition: fvMatrix.H:118
void relax(const scalar alpha)
Relax matrix (for steady-state solution).
Definition: fvMatrix.C:604
SolverPerformance< Type > solve(const dictionary &)
Solve segregated or coupled returning the solution statistics.
Definition: fvMatrixSolve.C:58
Finite volume models.
Definition: fvModels.H:65
Templated abstract base class for laminar transport models.
Definition: laminarModel.H:52
BasicMomentumTransportModel::alphaField alphaField
Definition: laminarModel.H:76
virtual void printCoeffs(const word &type)
Print model coefficients.
Definition: laminarModel.C:33
virtual void correct()
Predict the laminar viscosity.
Definition: laminarModel.C:267
BasicMomentumTransportModel::rhoField rhoField
Definition: laminarModel.H:77
volSymmTensorField sigma_
Single or mode sum viscoelastic stress.
Definition: Maxwell.H:99
virtual tmp< fvSymmTensorMatrix > sigmaSource(const label modei, volSymmTensorField &sigma) const
Definition: Maxwell.C:93
virtual tmp< volSymmTensorField > sigma() const
Return the stress tensor [m^2/s^2].
Definition: Maxwell.C:269
virtual void correct()
Correct the Maxwell stress.
Definition: Maxwell.C:329
virtual tmp< volScalarField > nuEff() const
Return the effective viscosity, i.e. the laminar viscosity.
Definition: Maxwell.C:248
virtual tmp< fvVectorMatrix > divDevTau(volVectorField &U) const
Return the source term for the momentum equation.
Definition: Maxwell.C:290
PtrList< volSymmTensorField > sigmas_
Mode viscoelastic stresses.
Definition: Maxwell.H:102
Maxwell(const alphaField &alpha, const rhoField &rho, const volVectorField &U, const surfaceScalarField &alphaRhoPhi, const surfaceScalarField &phi, const viscosity &viscosity, const word &type=typeName)
Construct from components.
Definition: Maxwell.C:106
PtrList< dimensionedScalar > readModeCoefficients(const word &name, const dimensionSet &dims) const
Definition: Maxwell.C:43
virtual tmp< volSymmTensorField > devTau() const
Return the effective stress tensor.
Definition: Maxwell.C:276
virtual bool read()
Read model coefficients if they have changed.
Definition: Maxwell.C:225
A class for managing temporary objects.
Definition: tmp.H:55
Templated form of IOobject providing type information for file reading and header type checking.
Definition: IOobject.H:531
bool headerOk()
Read header (uses typeGlobalFile to find file) and check.
Abstract base class for all fluid physical properties.
Definition: viscosity.H:50
A class for handling words, derived from string.
Definition: word.H:62
static const word null
An empty word.
Definition: word.H:77
Foam::fvConstraints & fvConstraints(Foam::fvConstraints::New(mesh))
Foam::fvModels & fvModels(Foam::fvModels::New(mesh))
label patchi
U
Definition: pEqn.H:72
volScalarField alpha(IOobject("alpha", runTime.name(), mesh, IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE), lambda *max(Ua &U, zeroSensitivity))
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
const dimensionedScalar sigma
Stefan-Boltzmann constant: default SI units: [W/m^2/K^4].
tmp< VolField< typename outerProduct< vector, Type >::type > > grad(const SurfaceField< Type > &ssf)
Definition: fvcGrad.C:46
tmp< VolField< Type > > div(const SurfaceField< Type > &ssf)
Definition: fvcDiv.C:47
tmp< fvMatrix< Type > > laplacian(const VolField< Type > &vf, const word &name)
Definition: fvmLaplacian.C:47
tmp< fvMatrix< Type > > Sp(const volScalarField::Internal &, const VolField< Type > &)
tmp< fvMatrix< Type > > div(const surfaceScalarField &flux, const VolField< Type > &vf, const word &name)
Definition: fvmDiv.C:48
tmp< fvMatrix< Type > > ddt(const VolField< Type > &vf)
Definition: fvmDdt.C:46
Namespace for OpenFOAM.
const dimensionSet dimViscosity
dimensionedSymmTensor dev2(const dimensionedSymmTensor &dt)
dimensionedSymmTensor dev(const dimensionedSymmTensor &dt)
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
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
dimensionedSymmTensor twoSymm(const dimensionedSymmTensor &dt)
messageStream Info
const dimensionSet dimTime
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Definition: POSIX.C:488