EulerDdtScheme.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) 2011-2018 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 "EulerDdtScheme.H"
27 #include "surfaceInterpolate.H"
28 #include "fvcDiv.H"
29 #include "fvMatrices.H"
30 
31 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
32 
33 namespace Foam
34 {
35 
36 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
37 
38 namespace fv
39 {
40 
41 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
42 
43 template<class Type>
44 tmp<GeometricField<Type, fvPatchField, volMesh>>
46 (
47  const dimensioned<Type>& dt
48 )
49 {
50  dimensionedScalar rDeltaT = 1.0/mesh().time().deltaT();
51 
52  IOobject ddtIOobject
53  (
54  "ddt("+dt.name()+')',
55  mesh().time().timeName(),
56  mesh()
57  );
58 
59  if (mesh().moving())
60  {
62  (
64  (
65  ddtIOobject,
66  mesh(),
68  (
69  "0",
70  dt.dimensions()/dimTime,
71  Zero
72  )
73  )
74  );
75 
76  tdtdt.ref().primitiveFieldRef() =
77  rDeltaT.value()*dt.value()*(1.0 - mesh().Vsc0()/mesh().Vsc());
78 
79  return tdtdt;
80  }
81  else
82  {
84  (
86  (
87  ddtIOobject,
88  mesh(),
90  (
91  "0",
92  dt.dimensions()/dimTime,
93  Zero
94  ),
96  )
97  );
98  }
99 }
100 
101 
102 template<class Type>
105 (
107 )
108 {
109  dimensionedScalar rDeltaT = 1.0/mesh().time().deltaT();
110 
111  IOobject ddtIOobject
112  (
113  "ddt("+vf.name()+')',
114  mesh().time().timeName(),
115  mesh()
116  );
117 
118  if (mesh().moving())
119  {
121  (
123  (
124  ddtIOobject,
125  rDeltaT*
126  (
127  vf()
128  - vf.oldTime()()*mesh().Vsc0()/mesh().Vsc()
129  ),
130  rDeltaT.value()*
131  (
132  vf.boundaryField() - vf.oldTime().boundaryField()
133  )
134  )
135  );
136  }
137  else
138  {
140  (
142  (
143  ddtIOobject,
144  rDeltaT*(vf - vf.oldTime())
145  )
146  );
147  }
148 }
149 
150 
151 template<class Type>
154 (
155  const dimensionedScalar& rho,
157 )
158 {
159  dimensionedScalar rDeltaT = 1.0/mesh().time().deltaT();
160 
161  IOobject ddtIOobject
162  (
163  "ddt("+rho.name()+','+vf.name()+')',
164  mesh().time().timeName(),
165  mesh()
166  );
167 
168  if (mesh().moving())
169  {
171  (
173  (
174  ddtIOobject,
175  rDeltaT*rho*
176  (
177  vf()
178  - vf.oldTime()()*mesh().Vsc0()/mesh().Vsc()
179  ),
180  rDeltaT.value()*rho.value()*
181  (
182  vf.boundaryField() - vf.oldTime().boundaryField()
183  )
184  )
185  );
186  }
187  else
188  {
190  (
192  (
193  ddtIOobject,
194  rDeltaT*rho*(vf - vf.oldTime())
195  )
196  );
197  }
198 }
199 
200 
201 template<class Type>
204 (
205  const volScalarField& rho,
207 )
208 {
209  dimensionedScalar rDeltaT = 1.0/mesh().time().deltaT();
210 
211  IOobject ddtIOobject
212  (
213  "ddt("+rho.name()+','+vf.name()+')',
214  mesh().time().timeName(),
215  mesh()
216  );
217 
218  if (mesh().moving())
219  {
221  (
223  (
224  ddtIOobject,
225  rDeltaT*
226  (
227  rho()*vf()
228  - rho.oldTime()()
229  *vf.oldTime()()*mesh().Vsc0()/mesh().Vsc()
230  ),
231  rDeltaT.value()*
232  (
233  rho.boundaryField()*vf.boundaryField()
234  - rho.oldTime().boundaryField()
235  *vf.oldTime().boundaryField()
236  )
237  )
238  );
239  }
240  else
241  {
243  (
245  (
246  ddtIOobject,
247  rDeltaT*(rho*vf - rho.oldTime()*vf.oldTime())
248  )
249  );
250  }
251 }
252 
253 
254 template<class Type>
257 (
258  const volScalarField& alpha,
259  const volScalarField& rho,
261 )
262 {
263  dimensionedScalar rDeltaT = 1.0/mesh().time().deltaT();
264 
265  IOobject ddtIOobject
266  (
267  "ddt("+alpha.name()+','+rho.name()+','+vf.name()+')',
268  mesh().time().timeName(),
269  mesh()
270  );
271 
272  if (mesh().moving())
273  {
275  (
277  (
278  ddtIOobject,
279  rDeltaT*
280  (
281  alpha()
282  *rho()
283  *vf()
284 
285  - alpha.oldTime()()
286  *rho.oldTime()()
287  *vf.oldTime()()*mesh().Vsc0()/mesh().Vsc()
288  ),
289  rDeltaT.value()*
290  (
291  alpha.boundaryField()
292  *rho.boundaryField()
293  *vf.boundaryField()
294 
295  - alpha.oldTime().boundaryField()
296  *rho.oldTime().boundaryField()
297  *vf.oldTime().boundaryField()
298  )
299  )
300  );
301  }
302  else
303  {
305  (
307  (
308  ddtIOobject,
309  rDeltaT
310  *(
311  alpha*rho*vf
312  - alpha.oldTime()*rho.oldTime()*vf.oldTime()
313  )
314  )
315  );
316  }
317 }
318 
319 
320 template<class Type>
323 (
325 )
326 {
327  dimensionedScalar rDeltaT = 1.0/mesh().time().deltaT();
328 
329  IOobject ddtIOobject
330  (
331  "ddt("+sf.name()+')',
332  mesh().time().timeName(),
333  mesh()
334  );
335 
337  (
339  (
340  ddtIOobject,
341  rDeltaT*(sf - sf.oldTime())
342  )
343  );
344 }
345 
346 
347 template<class Type>
350 (
352 )
353 {
354  tmp<fvMatrix<Type>> tfvm
355  (
356  new fvMatrix<Type>
357  (
358  vf,
360  )
361  );
362 
363  fvMatrix<Type>& fvm = tfvm.ref();
364 
365  scalar rDeltaT = 1.0/mesh().time().deltaTValue();
366 
367  fvm.diag() = rDeltaT*mesh().Vsc();
368 
369  if (mesh().moving())
370  {
371  fvm.source() = rDeltaT*vf.oldTime().primitiveField()*mesh().Vsc0();
372  }
373  else
374  {
375  fvm.source() = rDeltaT*vf.oldTime().primitiveField()*mesh().Vsc();
376  }
377 
378  return tfvm;
379 }
380 
381 
382 template<class Type>
385 (
386  const dimensionedScalar& rho,
388 )
389 {
390  tmp<fvMatrix<Type>> tfvm
391  (
392  new fvMatrix<Type>
393  (
394  vf,
396  )
397  );
398  fvMatrix<Type>& fvm = tfvm.ref();
399 
400  scalar rDeltaT = 1.0/mesh().time().deltaTValue();
401 
402  fvm.diag() = rDeltaT*rho.value()*mesh().Vsc();
403 
404  if (mesh().moving())
405  {
406  fvm.source() = rDeltaT
407  *rho.value()*vf.oldTime().primitiveField()*mesh().Vsc0();
408  }
409  else
410  {
411  fvm.source() = rDeltaT
412  *rho.value()*vf.oldTime().primitiveField()*mesh().Vsc();
413  }
414 
415  return tfvm;
416 }
417 
418 
419 template<class Type>
422 (
423  const volScalarField& rho,
425 )
426 {
427  tmp<fvMatrix<Type>> tfvm
428  (
429  new fvMatrix<Type>
430  (
431  vf,
433  )
434  );
435  fvMatrix<Type>& fvm = tfvm.ref();
436 
437  scalar rDeltaT = 1.0/mesh().time().deltaTValue();
438 
439  fvm.diag() = rDeltaT*rho.primitiveField()*mesh().Vsc();
440 
441  if (mesh().moving())
442  {
443  fvm.source() = rDeltaT
444  *rho.oldTime().primitiveField()
445  *vf.oldTime().primitiveField()*mesh().Vsc0();
446  }
447  else
448  {
449  fvm.source() = rDeltaT
450  *rho.oldTime().primitiveField()
451  *vf.oldTime().primitiveField()*mesh().Vsc();
452  }
453 
454  return tfvm;
455 }
456 
457 
458 template<class Type>
461 (
462  const volScalarField& alpha,
463  const volScalarField& rho,
465 )
466 {
467  tmp<fvMatrix<Type>> tfvm
468  (
469  new fvMatrix<Type>
470  (
471  vf,
472  alpha.dimensions()*rho.dimensions()*vf.dimensions()*dimVol/dimTime
473  )
474  );
475  fvMatrix<Type>& fvm = tfvm.ref();
476 
477  scalar rDeltaT = 1.0/mesh().time().deltaTValue();
478 
479  fvm.diag() =
480  rDeltaT*alpha.primitiveField()*rho.primitiveField()*mesh().Vsc();
481 
482  if (mesh().moving())
483  {
484  fvm.source() = rDeltaT
485  *alpha.oldTime().primitiveField()
486  *rho.oldTime().primitiveField()
487  *vf.oldTime().primitiveField()*mesh().Vsc0();
488  }
489  else
490  {
491  fvm.source() = rDeltaT
492  *alpha.oldTime().primitiveField()
493  *rho.oldTime().primitiveField()
494  *vf.oldTime().primitiveField()*mesh().Vsc();
495  }
496 
497  return tfvm;
498 }
499 
500 
501 template<class Type>
504 (
507 )
508 {
509  dimensionedScalar rDeltaT = 1.0/mesh().time().deltaT();
510 
511  fluxFieldType phiUf0(mesh().Sf() & Uf.oldTime());
512  fluxFieldType phiCorr
513  (
514  phiUf0 - fvc::dotInterpolate(mesh().Sf(), U.oldTime())
515  );
516 
517  return tmp<fluxFieldType>
518  (
519  new fluxFieldType
520  (
521  IOobject
522  (
523  "ddtCorr(" + U.name() + ',' + Uf.name() + ')',
524  mesh().time().timeName(),
525  mesh()
526  ),
527  this->fvcDdtPhiCoeff(U.oldTime(), phiUf0, phiCorr)
528  *rDeltaT*phiCorr
529  )
530  );
531 }
532 
533 
534 template<class Type>
537 (
539  const fluxFieldType& phi
540 )
541 {
542  dimensionedScalar rDeltaT = 1.0/mesh().time().deltaT();
543 
544  fluxFieldType phiCorr
545  (
546  phi.oldTime() - fvc::dotInterpolate(mesh().Sf(), U.oldTime())
547  );
548 
549  return tmp<fluxFieldType>
550  (
551  new fluxFieldType
552  (
553  IOobject
554  (
555  "ddtCorr(" + U.name() + ',' + phi.name() + ')',
556  mesh().time().timeName(),
557  mesh()
558  ),
559  this->fvcDdtPhiCoeff(U.oldTime(), phi.oldTime(), phiCorr)
560  *rDeltaT*phiCorr
561  )
562  );
563 }
564 
565 
566 template<class Type>
569 (
570  const volScalarField& rho,
573 )
574 {
575  dimensionedScalar rDeltaT = 1.0/mesh().time().deltaT();
576 
577  if
578  (
579  U.dimensions() == dimVelocity
580  && Uf.dimensions() == rho.dimensions()*dimVelocity
581  )
582  {
584  (
585  rho.oldTime()*U.oldTime()
586  );
587 
588  fluxFieldType phiUf0(mesh().Sf() & Uf.oldTime());
589  fluxFieldType phiCorr(phiUf0 - fvc::dotInterpolate(mesh().Sf(), rhoU0));
590 
591  return tmp<fluxFieldType>
592  (
593  new fluxFieldType
594  (
595  IOobject
596  (
597  "ddtCorr("
598  + rho.name() + ',' + U.name() + ',' + Uf.name() + ')',
599  mesh().time().timeName(),
600  mesh()
601  ),
602  this->fvcDdtPhiCoeff(rhoU0, phiUf0, phiCorr, rho.oldTime())
603  *rDeltaT*phiCorr
604  )
605  );
606  }
607  else if
608  (
609  U.dimensions() == rho.dimensions()*dimVelocity
610  && Uf.dimensions() == rho.dimensions()*dimVelocity
611  )
612  {
613  fluxFieldType phiUf0(mesh().Sf() & Uf.oldTime());
614  fluxFieldType phiCorr
615  (
616  phiUf0 - fvc::dotInterpolate(mesh().Sf(), U.oldTime())
617  );
618 
619  return tmp<fluxFieldType>
620  (
621  new fluxFieldType
622  (
623  IOobject
624  (
625  "ddtCorr("
626  + rho.name() + ',' + U.name() + ',' + Uf.name() + ')',
627  mesh().time().timeName(),
628  mesh()
629  ),
630  this->fvcDdtPhiCoeff
631  (
632  U.oldTime(),
633  phiUf0,
634  phiCorr,
635  rho.oldTime()
636  )*rDeltaT*phiCorr
637  )
638  );
639  }
640  else
641  {
643  << "dimensions of Uf are not correct"
644  << abort(FatalError);
645 
646  return fluxFieldType::null();
647  }
648 }
649 
650 
651 template<class Type>
654 (
655  const volScalarField& rho,
657  const fluxFieldType& phi
658 )
659 {
660  dimensionedScalar rDeltaT = 1.0/mesh().time().deltaT();
661 
662  if
663  (
664  U.dimensions() == dimVelocity
665  && phi.dimensions() == rho.dimensions()*dimVelocity*dimArea
666  )
667  {
669  (
670  rho.oldTime()*U.oldTime()
671  );
672 
673  fluxFieldType phiCorr
674  (
675  phi.oldTime() - fvc::dotInterpolate(mesh().Sf(), rhoU0)
676  );
677 
678  return tmp<fluxFieldType>
679  (
680  new fluxFieldType
681  (
682  IOobject
683  (
684  "ddtCorr("
685  + rho.name() + ',' + U.name() + ',' + phi.name() + ')',
686  mesh().time().timeName(),
687  mesh()
688  ),
689  this->fvcDdtPhiCoeff
690  (
691  rhoU0,
692  phi.oldTime(),
693  phiCorr,
694  rho.oldTime()
695  )*rDeltaT*phiCorr
696  )
697  );
698  }
699  else if
700  (
701  U.dimensions() == rho.dimensions()*dimVelocity
702  && phi.dimensions() == rho.dimensions()*dimVelocity*dimArea
703  )
704  {
705  fluxFieldType phiCorr
706  (
707  phi.oldTime() - fvc::dotInterpolate(mesh().Sf(), U.oldTime())
708  );
709 
710  return tmp<fluxFieldType>
711  (
712  new fluxFieldType
713  (
714  IOobject
715  (
716  "ddtCorr("
717  + rho.name() + ',' + U.name() + ',' + phi.name() + ')',
718  mesh().time().timeName(),
719  mesh()
720  ),
721  this->fvcDdtPhiCoeff
722  (
723  U.oldTime(),
724  phi.oldTime(),
725  phiCorr,
726  rho.oldTime()
727  )*rDeltaT*phiCorr
728  )
729  );
730  }
731  else
732  {
734  << "dimensions of phi are not correct"
735  << abort(FatalError);
736 
737  return fluxFieldType::null();
738  }
739 }
740 
741 
742 template<class Type>
744 (
746 )
747 {
748  return mesh().phi();
749 }
750 
751 
752 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
753 
754 } // End namespace fv
755 
756 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
757 
758 } // End namespace Foam
759 
760 // ************************************************************************* //
const GeometricField< Type, PatchField, GeoMesh > & oldTime() const
Return old time field.
const word & name() const
Return name.
Definition: IOobject.H:295
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
const Boundary & boundaryField() const
Return const-reference to the boundary field.
T & ref() const
Return non-const reference or generate a fatal error.
Definition: tmpI.H:174
static tmp< GeometricField< typename innerProduct< vector, Type >::type, fvsPatchField, surfaceMesh > > dotInterpolate(const surfaceVectorField &Sf, const GeometricField< Type, fvPatchField, volMesh > &tvf)
Interpolate field onto faces.
const dimensionSet dimVol(dimVolume)
Definition: dimensionSets.H:59
virtual tmp< GeometricField< Type, fvPatchField, volMesh > > fvcDdt(const dimensioned< Type > &)
const Internal::FieldType & primitiveField() const
Return a const-reference to the internal field.
Generic GeometricField class.
Generic dimensioned Type class.
const dimensionSet & dimensions() const
Return dimensions.
dynamicFvMesh & mesh
virtual tmp< fluxFieldType > fvcDdtPhiCorr(const GeometricField< Type, fvPatchField, volMesh > &U, const fluxFieldType &phi)
virtual tmp< surfaceScalarField > meshPhi(const GeometricField< Type, fvPatchField, volMesh > &)
labelList fv(nPoints)
This boundary condition is not designed to be evaluated; it is assmued that the value is assigned via...
const Type & value() const
Return const reference to value.
A special matrix type and solver, designed for finite volume solutions of scalar equations. Face addressing is used to make all matrix assembly and solution loops vectorise.
Definition: fvPatchField.H:72
static const zero Zero
Definition: zero.H:97
errorManip< error > abort(error &err)
Definition: errorManip.H:131
virtual tmp< fluxFieldType > fvcDdtUfCorr(const GeometricField< Type, fvPatchField, volMesh > &U, const GeometricField< Type, fvsPatchField, surfaceMesh > &Uf)
Calculate the divergence of the given field.
Field< Type > & source()
Definition: fvMatrix.H:292
const word & name() const
Return const reference to name.
const dimensionSet dimTime(0, 0, 1, 0, 0, 0, 0)
Definition: dimensionSets.H:51
A special matrix type and solver, designed for finite volume solutions of scalar equations.
const dimensionSet & dimensions() const
Return const reference to dimensions.
volScalarField alpha(IOobject("alpha", runTime.timeName(), mesh, IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE), lambda *max(Ua &U, zeroSensitivity))
mesh Sf()
A class for managing temporary objects.
Definition: PtrList.H:53
scalarField & diag()
Definition: lduMatrix.C:186
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:92
virtual tmp< fvMatrix< Type > > fvmDdt(const GeometricField< Type, fvPatchField, volMesh > &)
const dimensionSet dimArea(sqr(dimLength))
Definition: dimensionSets.H:57
Namespace for OpenFOAM.
const dimensionSet dimVelocity