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-2026 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  return readModeCoefficients(this->type(), name, dims);
49 }
50 
51 
52 template<class BasicMomentumTransportModel>
55 (
56  const word& type,
57  const word& name,
58  const dimensionSet& dims
59 ) const
60 {
61  PtrList<dimensionedScalar> modeCoeffs(nModes_);
62 
63  if (modeCoefficients_.size())
64  {
65  if (this->typeDict(type).found(name))
66  {
67  IOWarningInFunction(this->typeDict(type))
68  << "Using 'modes' list, '" << name << "' entry will be ignored."
69  << endl;
70  }
71 
72  label modei = 0;
73  forAllConstIter(dictionary, modeCoefficients_, iter)
74  {
75  modeCoeffs.set
76  (
77  modei++,
79  (
80  name,
81  dims,
82  iter().dict().lookup(name)
83  )
84  );
85  }
86  }
87  else
88  {
89  modeCoeffs.set
90  (
91  0,
93  (
94  name,
95  dims,
96  this->typeDict(type).lookup(name)
97  )
98  );
99  }
100 
101  return modeCoeffs;
102 }
103 
104 
105 template<class BasicMomentumTransportModel>
108 (
109  const PtrList<dimensionedScalar>& nuM
110 ) const
111 {
112  dimensionedScalar nuMSum(nuM[0]);
113 
114  if (modeCoefficients_.size())
115  {
116  for(label modei=1; modei<modeCoefficients_.size(); modei++)
117  {
118  nuMSum += nuM[modei];
119  }
120  }
121 
122  return nuMSum;
123 }
124 
125 
126 template<class BasicMomentumTransportModel>
128 (
129  const label modei,
131 ) const
132 {
133  return -fvm::Sp(this->alpha_*this->rho_/lambdas_[modei], sigma);
134 }
135 
136 
137 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
138 
139 template<class BasicMomentumTransportModel>
141 (
142  const alphaField& alpha,
143  const rhoField& rho,
144  const volVectorField& U,
145  const surfaceScalarField& alphaRhoPhi,
146  const surfaceScalarField& phi,
147  const viscosity& viscosity,
148  const word& type
149 )
150 :
151  laminarModel<BasicMomentumTransportModel>
152  (
153  type,
154  alpha,
155  rho,
156  U,
157  alphaRhoPhi,
158  phi,
159  viscosity
160  ),
161 
162  modeCoefficients_(this->typeDict(type).subOrEmptyDict("modes")),
163 
164  nModes_(modeCoefficients_.size() ? modeCoefficients_.size() : 1),
165 
166  nuM_(readModeCoefficients("nuM", dimKinematicViscosity)),
167 
168  lambdas_(readModeCoefficients("lambda", dimTime)),
169 
170  nuMSum_(sumNuM(nuM_)),
171 
172  sigma_
173  (
174  IOobject
175  (
176  this->groupName("sigma"),
177  this->runTime_.name(),
178  this->mesh_,
179  IOobject::MUST_READ,
180  IOobject::AUTO_WRITE
181  ),
182  this->mesh_
183  )
184 {
185  if (nModes_ > 1)
186  {
187  sigmas_.setSize(nModes_);
188 
189  forAll(sigmas_, modei)
190  {
192  (
193  this->groupName("sigma" + name(modei)),
194  this->runTime_.name(),
195  this->mesh_,
197  );
198 
199  // Check if mode field exists and can be read
200  if (header.headerOk())
201  {
202  Info<< " Reading mode stress field "
203  << header.name() << endl;
204 
205  sigmas_.set
206  (
207  modei,
209  (
210  IOobject
211  (
212  header.name(),
213  this->runTime_.name(),
214  this->mesh_,
217  ),
218  this->mesh_
219  )
220  );
221  }
222  else
223  {
224  sigmas_.set
225  (
226  modei,
228  (
229  IOobject
230  (
231  header.name(),
232  this->runTime_.name(),
233  this->mesh_,
236  ),
237  sigma_
238  )
239  );
240  }
241  }
242  }
243 }
244 
245 
246 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
247 
248 template<class BasicMomentumTransportModel>
250 {
252  {
253  if (modeCoefficients_.size())
254  {
255  this->typeDict().lookup("modes") >> modeCoefficients_;
256  }
257 
258  nuM_ = readModeCoefficients("nuM", dimKinematicViscosity);
259  lambdas_ = readModeCoefficients("lambda", dimTime);
260  nuMSum_ = sumNuM(nuM_);
261 
262  return true;
263  }
264  else
265  {
266  return false;
267  }
268 }
269 
270 
271 template<class BasicMomentumTransportModel>
273 {
274  return volScalarField::New
275  (
276  this->groupName("nuEff"),
277  this->nu()
278  );
279 }
280 
281 
282 template<class BasicMomentumTransportModel>
284 (
285  const label patchi
286 ) const
287 {
288  return this->nu(patchi);
289 }
290 
291 
292 template<class BasicMomentumTransportModel>
294 {
295  const surfaceVectorField nf(this->mesh().nf());
296 
298  (
299  this->groupName("devTau"),
301  (
302  nf,
303  this->alpha_*this->rho_*this->nuMSum_*fvc::grad(this->U_)
304  )
306  (
307  nf,
308  this->alpha_*this->rho_*sigma_
309  )
311  (
312  nf,
313  this->alpha_*this->rho_*this->nu()*dev2(T(fvc::grad(this->U_)))
314  )
315  - fvc::interpolate(this->alpha_*this->rho_*nu0())*fvc::snGrad(this->U_)
316  );
317 }
318 
319 
320 template<class BasicMomentumTransportModel>
321 template<class RhoFieldType>
324 (
325  const RhoFieldType& rho,
327 ) const
328 {
329  return
330  (
331  fvc::div(this->alpha_*rho*this->nuMSum_*fvc::grad(U))
332  + fvc::div(this->alpha_*rho*sigma_)
333  - fvc::div(this->alpha_*rho*this->nu()*dev2(T(fvc::grad(U))))
334  - fvm::laplacian(this->alpha_*rho*nu0(), U)
335  );
336 }
337 
338 
339 template<class BasicMomentumTransportModel>
341 (
343 ) const
344 {
345  return DivDevTau(this->rho_, U);
346 }
347 
348 
349 template<class BasicMomentumTransportModel>
352 (
353  const volScalarField& rho,
355 ) const
356 {
357  return DivDevTau(rho, U);
358 }
359 
360 
361 template<class BasicMomentumTransportModel>
363 {
364  // Local references
365  const alphaField& alpha = this->alpha_;
366  const rhoField& rho = this->rho_;
367  const surfaceScalarField& alphaRhoPhi = this->alphaRhoPhi_;
368  const volVectorField& U = this->U_;
369  const Foam::fvModels& fvModels(Foam::fvModels::New(this->mesh_));
371  (
372  Foam::fvConstraints::New(this->mesh_)
373  );
374 
376 
378  const volTensorField& gradU = tgradU();
379 
380  forAll(lambdas_, modei)
381  {
382  volSymmTensorField& sigma = nModes_ == 1 ? sigma_ : sigmas_[modei];
383 
384  uniformDimensionedScalarField rLambda
385  (
386  IOobject
387  (
388  this->groupName
389  (
390  "rLambda"
391  + (nModes_ == 1 ? word::null : name(modei))
392  ),
393  this->runTime_.constant(),
394  this->mesh_
395  ),
396  1/lambdas_[modei]
397  );
398 
399  // Note sigma is positive on lhs of momentum eqn
400  const volSymmTensorField P
401  (
402  twoSymm(sigma & gradU)
403  - nuM_[modei]*rLambda*twoSymm(gradU)
404  );
405 
406  // Viscoelastic stress equation
407  fvSymmTensorMatrix sigmaEqn
408  (
410  + fvm::div
411  (
412  alphaRhoPhi,
413  sigma,
414  "div(" + alphaRhoPhi.name() + ',' + sigma_.name() + ')'
415  )
416  ==
417  alpha*rho*P
418  + sigmaSource(modei, sigma)
420  );
421 
422  sigmaEqn.relax();
423  fvConstraints.constrain(sigmaEqn);
424  sigmaEqn.solve("sigma");
426  }
427 
428  if (sigmas_.size())
429  {
430  volSymmTensorField sigmaSum("sigmaSum", sigmas_[0]);
431 
432  for (label modei = 1; modei<sigmas_.size(); modei++)
433  {
434  sigmaSum += sigmas_[modei];
435  }
436 
437  sigma_ == sigmaSum;
438  }
439 }
440 
441 
442 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
443 
444 } // End namespace laminarModels
445 } // End namespace Foam
446 
447 // ************************************************************************* //
bool found
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:492
static fvModels & New(const word &name, const fvMesh &mesh)
Construct and return the named DemandDrivenMeshObject.
Generic GeometricField class.
static tmp< GeometricField< Type, GeoMesh, PrimitiveField > > New(const word &name, const Internal &, const PtrList< Patch > &, const HashPtrTable< Source > &=HashPtrTable< Source >())
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:307
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:62
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
Dimension set for the base types.
Definition: dimensionSet.H:125
Finite volume constraints.
Definition: fvConstraints.H:68
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:602
SolverPerformance< Type > solve(const dictionary &)
Solve segregated or coupled returning the solution statistics.
Definition: fvMatrixSolve.C:58
Finite volume models.
Definition: fvModels.H:69
tmp< fvMatrix< Type > > source(const VolField< Type > &field) const
Return source for an equation.
Templated abstract base class for laminar transport models.
Definition: laminarModel.H:52
BasicMomentumTransportModel::alphaField alphaField
Definition: laminarModel.H:70
virtual void correct()
Predict the laminar viscosity.
Definition: laminarModel.C:275
BasicMomentumTransportModel::rhoField rhoField
Definition: laminarModel.H:71
Generalised Maxwell model for viscoelasticity using the upper-convected time derivative of the stress...
Definition: Maxwell.H:79
volSymmTensorField sigma_
Single or mode sum viscoelastic stress.
Definition: Maxwell.H:116
virtual tmp< fvSymmTensorMatrix > sigmaSource(const label modei, volSymmTensorField &sigma) const
Definition: Maxwell.C:128
virtual void correct()
Correct the Maxwell stress.
Definition: Maxwell.C:362
label nModes_
Number of modes.
Definition: Maxwell.H:101
virtual tmp< volScalarField > nuEff() const
Return the effective viscosity, i.e. the laminar viscosity.
Definition: Maxwell.C:272
virtual tmp< fvVectorMatrix > divDevTau(volVectorField &U) const
Return the source term for the momentum equation.
Definition: Maxwell.C:341
virtual tmp< surfaceVectorField > devTau() const
Return the effective surface stress.
Definition: Maxwell.C:293
PtrList< volSymmTensorField > sigmas_
Mode viscoelastic stresses.
Definition: Maxwell.H:119
dimensionedScalar sumNuM(const PtrList< dimensionedScalar > &nuM) const
Return the sum of the given list of mode viscosities.
Definition: Maxwell.C:108
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:141
PtrList< dimensionedScalar > readModeCoefficients(const word &name, const dimensionSet &dims) const
Read a coefficient for all modes and return as a list.
Definition: Maxwell.C:43
virtual bool read()
Read model coefficients if they have changed.
Definition: Maxwell.C:249
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:545
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:63
static const word null
An empty word.
Definition: word.H:78
Foam::fvConstraints & fvConstraints(Foam::fvConstraints::New(mesh))
Foam::fvModels & fvModels(Foam::fvModels::New(mesh))
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
label patchi
U
Definition: pEqn.H:72
rho
Definition: pEqn.H:1
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].
static tmp< SurfaceField< Type > > interpolate(const VolField< Type > &tvf, const surfaceScalarField &faceFlux, Istream &schemeData)
Interpolate field onto faces using scheme given by Istream.
static tmp< SurfaceField< typename innerProduct< vector, Type >::type > > dotInterpolate(const surfaceVectorField &Sf, const VolField< Type > &tvf)
Interpolate field onto faces.
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< SurfaceField< Type > > snGrad(const VolField< Type > &vf, const word &name)
Definition: fvcSnGrad.C:45
tmp< fvMatrix< Type > > laplacian(const VolField< Type > &vf, const word &name)
Definition: fvmLaplacian.C:47
tmp< fvMatrix< Type > > div(const surfaceScalarField &flux, const VolField< Type > &vf, const word &name)
Definition: fvmDiv.C:48
tmp< fvMatrix< Type > > Sp(const volScalarField::Internal &, const VolField< Type > &)
tmp< fvMatrix< Type > > ddt(const VolField< Type > &vf)
Definition: fvmDdt.C:46
const unitSet & lookup(const word &unitName)
Lookup and return the named unit from the table.
Definition: units.C:346
Namespace for OpenFOAM.
const dimensionSet & dimKinematicViscosity
Definition: dimensions.C:171
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:288
messageStream Info
void dev2(pointPatchField< tensor > &, const pointPatchField< tensor > &)
const dimensionSet & dimTime
Definition: dimensions.C:142
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
void twoSymm(pointPatchField< tensor > &, const pointPatchField< tensor > &)
void T(GeometricField< Type, GeoMesh, PrimitiveField1 > &gf, const GeometricField< Type, GeoMesh, PrimitiveField2 > &gf1)
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Definition: POSIX.C:488
dictionary dict
Typedefs for UniformDimensionedField.