CoEulerDdtScheme.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 | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011-2018 OpenFOAM Foundation
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26\*---------------------------------------------------------------------------*/
27
28#include "CoEulerDdtScheme.H"
29#include "surfaceInterpolate.H"
30#include "fvcDiv.H"
31#include "fvMatrices.H"
32
33// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
34
35namespace Foam
36{
37
38// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
39
40namespace fv
41{
42
43// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
44
45template<class Type>
46tmp<volScalarField> CoEulerDdtScheme<Type>::CorDeltaT() const
47{
48 const surfaceScalarField cofrDeltaT(CofrDeltaT());
49
50 tmp<volScalarField> tcorDeltaT
51 (
53 (
54 IOobject
55 (
56 "CorDeltaT",
57 cofrDeltaT.instance(),
58 mesh()
59 ),
60 mesh(),
61 dimensionedScalar(cofrDeltaT.dimensions(), Zero),
62 extrapolatedCalculatedFvPatchScalarField::typeName
63 )
64 );
65
66 volScalarField& corDeltaT = tcorDeltaT.ref();
67
68 const labelUList& owner = mesh().owner();
69 const labelUList& neighbour = mesh().neighbour();
70
71 forAll(owner, facei)
72 {
73 corDeltaT[owner[facei]] =
74 max(corDeltaT[owner[facei]], cofrDeltaT[facei]);
75
76 corDeltaT[neighbour[facei]] =
77 max(corDeltaT[neighbour[facei]], cofrDeltaT[facei]);
78 }
79
80 const surfaceScalarField::Boundary& cofrDeltaTbf =
81 cofrDeltaT.boundaryField();
82
83 forAll(cofrDeltaTbf, patchi)
84 {
85 const fvsPatchScalarField& pcofrDeltaT = cofrDeltaTbf[patchi];
86 const fvPatch& p = pcofrDeltaT.patch();
87 const labelUList& faceCells = p.patch().faceCells();
88
89 forAll(pcofrDeltaT, patchFacei)
90 {
91 corDeltaT[faceCells[patchFacei]] = max
92 (
93 corDeltaT[faceCells[patchFacei]],
94 pcofrDeltaT[patchFacei]
95 );
96 }
97 }
98
99 corDeltaT.correctBoundaryConditions();
100
101 return tcorDeltaT;
102}
103
104
105template<class Type>
106tmp<surfaceScalarField> CoEulerDdtScheme<Type>::CofrDeltaT() const
107{
108 const dimensionedScalar& deltaT = mesh().time().deltaT();
109
110 const surfaceScalarField& phi =
111 static_cast<const objectRegistry&>(mesh())
112 .lookupObject<surfaceScalarField>(phiName_);
113
114 if (phi.dimensions() == dimensionSet(0, 3, -1, 0, 0))
115 {
117 (
119 *(mag(phi)/mesh().magSf())
120 *deltaT
121 );
122
123 return max(Co/maxCo_, scalar(1))/deltaT;
124 }
125 else if (phi.dimensions() == dimensionSet(1, 0, -1, 0, 0))
126 {
127 const volScalarField& rho =
128 static_cast<const objectRegistry&>(mesh())
129 .lookupObject<volScalarField>(rhoName_).oldTime();
130
132 (
134 *(mag(phi)/(fvc::interpolate(rho)*mesh().magSf()))
135 *deltaT
136 );
137
138 return max(Co/maxCo_, scalar(1))/deltaT;
139 }
140
142 << "Incorrect dimensions of phi: " << phi.dimensions()
143 << abort(FatalError);
144
145 return nullptr;
146}
147
148
149template<class Type>
150tmp<GeometricField<Type, fvPatchField, volMesh>>
152(
153 const dimensioned<Type>& dt
154)
155{
156 const volScalarField rDeltaT(CorDeltaT());
157
158 IOobject ddtIOobject
159 (
160 "ddt("+dt.name()+')',
161 mesh().time().timeName(),
162 mesh()
163 );
164
165 if (mesh().moving())
166 {
168 (
170 (
171 ddtIOobject,
172 mesh(),
174 )
175 );
176
177 tdtdt.ref().primitiveFieldRef() =
178 rDeltaT.primitiveField()*dt.value()
179 *(1.0 - mesh().Vsc0()/mesh().Vsc());
180
181 return tdtdt;
182 }
183 else
184 {
186 (
188 (
189 ddtIOobject,
190 mesh(),
193 )
194 );
195 }
196}
197
198
199template<class Type>
202(
204)
205{
206 const volScalarField rDeltaT(CorDeltaT());
207
208 IOobject ddtIOobject
209 (
210 "ddt("+vf.name()+')',
211 mesh().time().timeName(),
212 mesh()
213 );
214
215 if (mesh().moving())
216 {
218 (
220 (
221 ddtIOobject,
222 mesh(),
223 rDeltaT.dimensions()*vf.dimensions(),
224 rDeltaT.primitiveField()*
225 (
226 vf.primitiveField()
227 - vf.oldTime().primitiveField()*mesh().Vsc0()/mesh().Vsc()
228 ),
229 rDeltaT.boundaryField()*
230 (
231 vf.boundaryField() - vf.oldTime().boundaryField()
232 )
233 )
234 );
235 }
236 else
237 {
239 (
241 (
242 ddtIOobject,
243 rDeltaT*(vf - vf.oldTime())
244 )
245 );
246 }
247}
248
249
250template<class Type>
253(
254 const dimensionedScalar& rho,
256)
257{
258 const volScalarField rDeltaT(CorDeltaT());
259
260 IOobject ddtIOobject
261 (
262 "ddt("+rho.name()+','+vf.name()+')',
263 mesh().time().timeName(),
264 mesh()
265 );
266
267 if (mesh().moving())
268 {
270 (
272 (
273 ddtIOobject,
274 mesh(),
275 rDeltaT.dimensions()*rho.dimensions()*vf.dimensions(),
276 rDeltaT.primitiveField()*rho.value()*
277 (
278 vf.primitiveField()
279 - vf.oldTime().primitiveField()*mesh().Vsc0()/mesh().Vsc()
280 ),
281 rDeltaT.boundaryField()*rho.value()*
282 (
283 vf.boundaryField() - vf.oldTime().boundaryField()
284 )
285 )
286 );
287 }
288 else
289 {
291 (
293 (
294 ddtIOobject,
295 rDeltaT*rho*(vf - vf.oldTime())
296 )
297 );
298 }
299}
300
301
302template<class Type>
305(
306 const volScalarField& rho,
308)
309{
310 const volScalarField rDeltaT(CorDeltaT());
311
312 IOobject ddtIOobject
313 (
314 "ddt("+rho.name()+','+vf.name()+')',
315 mesh().time().timeName(),
316 mesh()
317 );
318
319 if (mesh().moving())
320 {
322 (
324 (
325 ddtIOobject,
326 mesh(),
327 rDeltaT.dimensions()*rho.dimensions()*vf.dimensions(),
328 rDeltaT.primitiveField()*
329 (
330 rho.primitiveField()*vf.primitiveField()
331 - rho.oldTime().primitiveField()
332 *vf.oldTime().primitiveField()*mesh().Vsc0()/mesh().Vsc()
333 ),
334 rDeltaT.boundaryField()*
335 (
336 rho.boundaryField()*vf.boundaryField()
337 - rho.oldTime().boundaryField()
338 *vf.oldTime().boundaryField()
339 )
340 )
341 );
342 }
343 else
344 {
346 (
348 (
349 ddtIOobject,
350 rDeltaT*(rho*vf - rho.oldTime()*vf.oldTime())
351 )
352 );
353 }
354}
355
356
357template<class Type>
360(
361 const volScalarField& alpha,
362 const volScalarField& rho,
364)
365{
366 const volScalarField rDeltaT(CorDeltaT());
367
368 IOobject ddtIOobject
369 (
370 "ddt("+alpha.name()+','+rho.name()+','+vf.name()+')',
371 mesh().time().timeName(),
372 mesh()
373 );
374
375 if (mesh().moving())
376 {
378 (
380 (
381 ddtIOobject,
382 mesh(),
383 rDeltaT.dimensions()
384 *alpha.dimensions()*rho.dimensions()*vf.dimensions(),
385 rDeltaT.primitiveField()*
386 (
387 alpha.primitiveField()
388 *rho.primitiveField()
389 *vf.primitiveField()
390
391 - alpha.oldTime().primitiveField()
392 *rho.oldTime().primitiveField()
393 *vf.oldTime().primitiveField()*mesh().Vsc0()/mesh().Vsc()
394 ),
395 rDeltaT.boundaryField()*
396 (
397 alpha.boundaryField()
398 *rho.boundaryField()
399 *vf.boundaryField()
400
401 - alpha.oldTime().boundaryField()
402 *rho.oldTime().boundaryField()
403 *vf.oldTime().boundaryField()
404 )
405 )
406 );
407 }
408 else
409 {
411 (
413 (
414 ddtIOobject,
415 rDeltaT
416 *(
417 alpha*rho*vf
418 - alpha.oldTime()*rho.oldTime()*vf.oldTime()
419 )
420 )
421 );
422 }
423}
424
425
426template<class Type>
429(
431)
432{
434 (
436 (
437 vf,
439 )
440 );
441
442 fvMatrix<Type>& fvm = tfvm.ref();
443
444 scalarField rDeltaT(CorDeltaT()().primitiveField());
445
446 fvm.diag() = rDeltaT*mesh().Vsc();
447
448 if (mesh().moving())
449 {
450 fvm.source() = rDeltaT*vf.oldTime().primitiveField()*mesh().Vsc0();
451 }
452 else
453 {
454 fvm.source() = rDeltaT*vf.oldTime().primitiveField()*mesh().Vsc();
455 }
456
457 return tfvm;
458}
459
460
461template<class Type>
464(
465 const dimensionedScalar& rho,
467)
468{
470 (
472 (
473 vf,
474 rho.dimensions()*vf.dimensions()*dimVol/dimTime
475 )
476 );
477 fvMatrix<Type>& fvm = tfvm.ref();
478
479 scalarField rDeltaT(CorDeltaT()().primitiveField());
480
481 fvm.diag() = rDeltaT*rho.value()*mesh().Vsc();
482
483 if (mesh().moving())
484 {
485 fvm.source() = rDeltaT
486 *rho.value()*vf.oldTime().primitiveField()*mesh().Vsc0();
487 }
488 else
489 {
490 fvm.source() = rDeltaT
491 *rho.value()*vf.oldTime().primitiveField()*mesh().Vsc();
492 }
493
494 return tfvm;
495}
496
497
498template<class Type>
501(
502 const volScalarField& rho,
504)
505{
507 (
509 (
510 vf,
511 rho.dimensions()*vf.dimensions()*dimVol/dimTime
512 )
513 );
514 fvMatrix<Type>& fvm = tfvm.ref();
515
516 scalarField rDeltaT(CorDeltaT()().primitiveField());
517
518 fvm.diag() = rDeltaT*rho.primitiveField()*mesh().Vsc();
519
520 if (mesh().moving())
521 {
522 fvm.source() = rDeltaT
523 *rho.oldTime().primitiveField()
524 *vf.oldTime().primitiveField()*mesh().Vsc0();
525 }
526 else
527 {
528 fvm.source() = rDeltaT
529 *rho.oldTime().primitiveField()
530 *vf.oldTime().primitiveField()*mesh().Vsc();
531 }
532
533 return tfvm;
534}
535
536
537template<class Type>
540(
541 const volScalarField& alpha,
542 const volScalarField& rho,
544)
545{
547 (
549 (
550 vf,
551 alpha.dimensions()*rho.dimensions()*vf.dimensions()*dimVol/dimTime
552 )
553 );
554 fvMatrix<Type>& fvm = tfvm.ref();
555
556 scalarField rDeltaT(CorDeltaT()().primitiveField());
557
558 fvm.diag() =
559 rDeltaT*alpha.primitiveField()*rho.primitiveField()*mesh().Vsc();
560
561 if (mesh().moving())
562 {
563 fvm.source() = rDeltaT
564 *alpha.oldTime().primitiveField()
565 *rho.oldTime().primitiveField()
566 *vf.oldTime().primitiveField()*mesh().Vsc0();
567 }
568 else
569 {
570 fvm.source() = rDeltaT
571 *alpha.oldTime().primitiveField()
572 *rho.oldTime().primitiveField()
573 *vf.oldTime().primitiveField()*mesh().Vsc();
574 }
575
576 return tfvm;
577}
578
579
580template<class Type>
583(
586)
587{
588 const surfaceScalarField rDeltaT(fvc::interpolate(CorDeltaT()));
589
590 fluxFieldType phiUf0(mesh().Sf() & Uf.oldTime());
591 fluxFieldType phiCorr
592 (
593 phiUf0 - fvc::dotInterpolate(mesh().Sf(), U.oldTime())
594 );
595
596 return tmp<fluxFieldType>
597 (
598 new fluxFieldType
599 (
601 (
602 "ddtCorr(" + U.name() + ',' + Uf.name() + ')',
603 mesh().time().timeName(),
604 mesh()
605 ),
606 this->fvcDdtPhiCoeff(U.oldTime(), phiUf0, phiCorr)
607 *rDeltaT*phiCorr
608 )
609 );
610}
611
612
613template<class Type>
616(
618 const fluxFieldType& phi
619)
620{
621 const surfaceScalarField rDeltaT(fvc::interpolate(CorDeltaT()));
622
623 fluxFieldType phiCorr
624 (
625 phi.oldTime() - fvc::dotInterpolate(mesh().Sf(), U.oldTime())
626 );
627
628 return tmp<fluxFieldType>
629 (
630 new fluxFieldType
631 (
633 (
634 "ddtCorr(" + U.name() + ',' + phi.name() + ')',
635 mesh().time().timeName(),
636 mesh()
637 ),
638 this->fvcDdtPhiCoeff(U.oldTime(), phi.oldTime(), phiCorr)
639 *rDeltaT*phiCorr
640 )
641 );
642}
643
644
645template<class Type>
648(
649 const volScalarField& rho,
652)
653{
654 const surfaceScalarField rDeltaT(fvc::interpolate(CorDeltaT()));
655
656 if
657 (
658 U.dimensions() == dimVelocity
659 && Uf.dimensions() == dimDensity*dimVelocity
660 )
661 {
663 (
664 rho.oldTime()*U.oldTime()
665 );
666
667 fluxFieldType phiUf0(mesh().Sf() & Uf.oldTime());
668 fluxFieldType phiCorr(phiUf0 - fvc::dotInterpolate(mesh().Sf(), rhoU0));
669
670 return tmp<fluxFieldType>
671 (
672 new fluxFieldType
673 (
675 (
676 "ddtCorr("
677 + rho.name() + ',' + U.name() + ',' + Uf.name() + ')',
678 mesh().time().timeName(),
679 mesh()
680 ),
681 this->fvcDdtPhiCoeff(rhoU0, phiUf0, phiCorr, rho.oldTime())
682 *rDeltaT*phiCorr
683 )
684 );
685 }
686 else if
687 (
688 U.dimensions() == dimDensity*dimVelocity
689 && Uf.dimensions() == dimDensity*dimVelocity
690 )
691 {
692 fluxFieldType phiUf0(mesh().Sf() & Uf.oldTime());
693 fluxFieldType phiCorr
694 (
695 phiUf0 - fvc::dotInterpolate(mesh().Sf(), U.oldTime())
696 );
697
698 return tmp<fluxFieldType>
699 (
700 new fluxFieldType
701 (
703 (
704 "ddtCorr("
705 + rho.name() + ',' + U.name() + ',' + Uf.name() + ')',
706 mesh().time().timeName(),
707 mesh()
708 ),
709 this->fvcDdtPhiCoeff
710 (
711 U.oldTime(),
712 phiUf0,
713 phiCorr,
714 rho.oldTime()
715 )*rDeltaT*phiCorr
716 )
717 );
718 }
719 else
720 {
722 << "dimensions of Uf are not correct"
723 << abort(FatalError);
724
725 return fluxFieldType::null();
726 }
727}
728
729
730template<class Type>
733(
734 const volScalarField& rho,
736 const fluxFieldType& phi
737)
738{
739 dimensionedScalar rDeltaT = 1.0/mesh().time().deltaT();
740
741 if
742 (
743 U.dimensions() == dimVelocity
744 && phi.dimensions() == rho.dimensions()*dimVelocity*dimArea
745 )
746 {
748 (
749 rho.oldTime()*U.oldTime()
750 );
751
752 fluxFieldType phiCorr
753 (
754 phi.oldTime() - fvc::dotInterpolate(mesh().Sf(), rhoU0)
755 );
756
757 return tmp<fluxFieldType>
758 (
759 new fluxFieldType
760 (
762 (
763 "ddtCorr("
764 + rho.name() + ',' + U.name() + ',' + phi.name() + ')',
765 mesh().time().timeName(),
766 mesh()
767 ),
768 this->fvcDdtPhiCoeff
769 (
770 rhoU0,
771 phi.oldTime(),
772 phiCorr,
773 rho.oldTime()
774 )*rDeltaT*phiCorr
775 )
776 );
777 }
778 else if
779 (
780 U.dimensions() == rho.dimensions()*dimVelocity
781 && phi.dimensions() == rho.dimensions()*dimVelocity*dimArea
782 )
783 {
784 fluxFieldType phiCorr
785 (
786 phi.oldTime() - fvc::dotInterpolate(mesh().Sf(), U.oldTime())
787 );
788
789 return tmp<fluxFieldType>
790 (
791 new fluxFieldType
792 (
794 (
795 "ddtCorr("
796 + rho.name() + ',' + U.name() + ',' + phi.name() + ')',
797 mesh().time().timeName(),
798 mesh()
799 ),
800 this->fvcDdtPhiCoeff
801 (
802 U.oldTime(),
803 phi.oldTime(),
804 phiCorr,
805 rho.oldTime()
806 )*rDeltaT*phiCorr
807 )
808 );
809 }
810 else
811 {
813 << "dimensions of phi are not correct"
814 << abort(FatalError);
815
816 return fluxFieldType::null();
817 }
818}
819
820
821template<class Type>
823(
825)
826{
828 (
830 (
832 (
833 "meshPhi",
834 mesh().time().timeName(),
835 mesh(),
838 false
839 ),
840 mesh(),
842 )
843 );
844
845 tmeshPhi.ref().setOriented();
846
847 return tmeshPhi;
848}
849
850
851// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
852
853} // End namespace fv
854
855// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
856
857} // End namespace Foam
858
859// ************************************************************************* //
surfaceScalarField & phi
const dimensionSet & dimensions() const
Return dimensions.
const GeometricField< Type, PatchField, GeoMesh > & oldTime() const
Return old time field.
const Internal::FieldType & primitiveField() const
Return a const-reference to the internal field.
Internal & ref(const bool updateAccessTime=true)
Return a reference to the dimensioned internal field.
GeometricBoundaryField< scalar, fvsPatchField, surfaceMesh > Boundary
Type of boundary fields.
const Boundary & boundaryField() const
Return const-reference to the boundary field.
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:170
const word & name() const noexcept
Return the object name.
Definition: IOobjectI.H:65
This boundary condition is not designed to be evaluated; it is assmued that the value is assigned via...
Generic dimensioned Type class.
const dimensionSet & dimensions() const
Return const reference to dimensions.
const Type & value() const
Return const reference to value.
const word & name() const
Return const reference to name.
A special matrix type and solver, designed for finite volume solutions of scalar equations....
Definition: fvMatrix.H:121
Field< Type > & source() noexcept
Definition: fvMatrix.H:458
tmp< fluxFieldType > fvcDdtUfCorr(const GeometricField< Type, fvPatchField, volMesh > &U, const GeometricField< Type, fvsPatchField, surfaceMesh > &Uf)
tmp< GeometricField< Type, fvPatchField, volMesh > > fvcDdt(const dimensioned< Type > &)
tmp< fluxFieldType > fvcDdtPhiCorr(const GeometricField< Type, fvPatchField, volMesh > &U, const fluxFieldType &phi)
tmp< fvMatrix< Type > > fvmDdt(const GeometricField< Type, fvPatchField, volMesh > &)
tmp< surfaceScalarField > meshPhi(const GeometricField< Type, fvPatchField, volMesh > &)
scalarField & diag()
Definition: lduMatrix.C:192
virtual const surfaceScalarField & deltaCoeffs() const
Return reference to cell-centre difference coefficients.
A class for managing temporary objects.
Definition: tmp.H:65
T & ref() const
Definition: tmpI.H:227
U
Definition: pEqn.H:72
volScalarField & p
dynamicFvMesh & mesh
autoPtr< surfaceVectorField > Uf
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
A special matrix type and solver, designed for finite volume solutions of scalar equations.
Calculate the divergence of the given field.
word timeName
Definition: getTimeIndex.H:3
static tmp< GeometricField< Type, fvsPatchField, surfaceMesh > > interpolate(const GeometricField< Type, fvPatchField, volMesh > &tvf, const surfaceScalarField &faceFlux, Istream &schemeData)
Interpolate field onto faces using scheme given by Istream.
static tmp< GeometricField< typename innerProduct< vector, Type >::type, fvsPatchField, surfaceMesh > > dotInterpolate(const surfaceVectorField &Sf, const GeometricField< Type, fvPatchField, volMesh > &tvf)
Interpolate field onto faces.
Namespace for OpenFOAM.
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
const dimensionSet dimTime(0, 0, 1, 0, 0, 0, 0)
Definition: dimensionSets.H:53
GeometricField< scalar, fvPatchField, volMesh > volScalarField
Definition: volFieldsFwd.H:82
const dimensionSet dimArea(sqr(dimLength))
Definition: dimensionSets.H:59
const dimensionSet dimVelocity
GeometricField< scalar, fvsPatchField, surfaceMesh > surfaceScalarField
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
errorManip< error > abort(error &err)
Definition: errorManip.H:144
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
error FatalError
const dimensionSet dimVolume(pow3(dimLength))
Definition: dimensionSets.H:60
const dimensionSet dimDensity
UList< label > labelUList
A UList of labels.
Definition: UList.H:85
fvsPatchField< scalar > fvsPatchScalarField
const dimensionSet dimVol(dimVolume)
Older spelling for dimVolume.
Definition: dimensionSets.H:64
labelList fv(nPoints)
volScalarField & alpha
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333