initial commit for version 1.6.x patch release
[OpenFOAM-1.6.x.git] / src / finiteVolume / finiteVolume / ddtSchemes / backwardDdtScheme / backwardDdtScheme.C
blob8a121b2d44737ea23d1170a7de5ab65ef680af17
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
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 the
13     Free Software Foundation; either version 2 of the License, or (at your
14     option) any later version.
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.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM; if not, write to the Free Software Foundation,
23     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "backwardDdtScheme.H"
28 #include "surfaceInterpolate.H"
29 #include "fvcDiv.H"
30 #include "fvMatrices.H"
32 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
34 namespace Foam
37 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
39 namespace fv
42 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
44 template<class Type>
45 scalar backwardDdtScheme<Type>::deltaT_() const
47     return mesh().time().deltaT().value();
51 template<class Type>
52 scalar backwardDdtScheme<Type>::deltaT0_() const
54     return mesh().time().deltaT0().value();
58 template<class Type>
59 template<class GeoField>
60 scalar backwardDdtScheme<Type>::deltaT0_(const GeoField& vf) const
62     if (vf.nOldTimes() < 2)
63     {
64         return GREAT;
65     }
66     else
67     {
68         return deltaT0_();
69     }
73 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
75 template<class Type>
76 tmp<GeometricField<Type, fvPatchField, volMesh> >
77 backwardDdtScheme<Type>::fvcDdt
79     const dimensioned<Type>& dt
82     dimensionedScalar rDeltaT = 1.0/mesh().time().deltaT();
84     IOobject ddtIOobject
85     (
86         "ddt("+dt.name()+')',
87         mesh().time().timeName(),
88         mesh()
89     );
91     scalar deltaT = deltaT_();
92     scalar deltaT0 = deltaT0_();
94     scalar coefft   = 1 + deltaT/(deltaT + deltaT0);
95     scalar coefft00 = deltaT*deltaT/(deltaT0*(deltaT + deltaT0));
96     scalar coefft0  = coefft + coefft00;
98     if (mesh().moving())
99     {
100         tmp<GeometricField<Type, fvPatchField, volMesh> > tdtdt
101         (
102             new GeometricField<Type, fvPatchField, volMesh>
103             (
104                 ddtIOobject,
105                 mesh(),
106                 dimensioned<Type>
107                 (
108                     "0",
109                     dt.dimensions()/dimTime,
110                     pTraits<Type>::zero
111                 )
112             )
113         );
115         tdtdt().internalField() = rDeltaT.value()*dt.value()*
116         (
117             coefft - (coefft0*mesh().V0() - coefft00*mesh().V00())/mesh().V()
118         );
120         return tdtdt;
121     }
122     else
123     {
124         return tmp<GeometricField<Type, fvPatchField, volMesh> >
125         (
126             new GeometricField<Type, fvPatchField, volMesh>
127             (
128                 ddtIOobject,
129                 mesh(),
130                 dimensioned<Type>
131                 (
132                     "0",
133                     dt.dimensions()/dimTime,
134                     pTraits<Type>::zero
135                 ),
136                 calculatedFvPatchField<Type>::typeName
137             )
138         );
139     }
143 template<class Type>
144 tmp<GeometricField<Type, fvPatchField, volMesh> >
145 backwardDdtScheme<Type>::fvcDdt
147     const GeometricField<Type, fvPatchField, volMesh>& vf
150     dimensionedScalar rDeltaT = 1.0/mesh().time().deltaT();
152     IOobject ddtIOobject
153     (
154         "ddt("+vf.name()+')',
155         mesh().time().timeName(),
156         mesh()
157     );
159     scalar deltaT = deltaT_();
160     scalar deltaT0 = deltaT0_(vf);
162     scalar coefft   = 1 + deltaT/(deltaT + deltaT0);
163     scalar coefft00 = deltaT*deltaT/(deltaT0*(deltaT + deltaT0));
164     scalar coefft0  = coefft + coefft00;
166     if (mesh().moving())
167     {
168         return tmp<GeometricField<Type, fvPatchField, volMesh> >
169         (
170             new GeometricField<Type, fvPatchField, volMesh>
171             (
172                 ddtIOobject,
173                 mesh(),
174                 rDeltaT.dimensions()*vf.dimensions(),
175                 rDeltaT.value()*
176                 (
177                     coefft*vf.internalField() -
178                     (
179                         coefft0*vf.oldTime().internalField()*mesh().V0()
180                       - coefft00*vf.oldTime().oldTime().internalField()
181                        *mesh().V00()
182                     )/mesh().V()
183                 ),
184                 rDeltaT.value()*
185                 (
186                     coefft*vf.boundaryField() -
187                     (
188                         coefft0*vf.oldTime().boundaryField()
189                       - coefft00*vf.oldTime().oldTime().boundaryField()
190                     )
191                 )
192             )
193         );
194     }
195     else
196     {
197         return tmp<GeometricField<Type, fvPatchField, volMesh> >
198         (
199             new GeometricField<Type, fvPatchField, volMesh>
200             (
201                 ddtIOobject,
202                 rDeltaT*
203                 (
204                     coefft*vf
205                   - coefft0*vf.oldTime()
206                   + coefft00*vf.oldTime().oldTime()
207                 )
208             )
209         );
210     }
214 template<class Type>
215 tmp<GeometricField<Type, fvPatchField, volMesh> >
216 backwardDdtScheme<Type>::fvcDdt
218     const dimensionedScalar& rho,
219     const GeometricField<Type, fvPatchField, volMesh>& vf
222     dimensionedScalar rDeltaT = 1.0/mesh().time().deltaT();
224     IOobject ddtIOobject
225     (
226         "ddt("+rho.name()+','+vf.name()+')',
227         mesh().time().timeName(),
228         mesh()
229     );
231     scalar deltaT = deltaT_();
232     scalar deltaT0 = deltaT0_(vf);
234     scalar coefft   = 1 + deltaT/(deltaT + deltaT0);
235     scalar coefft00 = deltaT*deltaT/(deltaT0*(deltaT + deltaT0));
236     scalar coefft0  = coefft + coefft00;
238     if (mesh().moving())
239     {
240         return tmp<GeometricField<Type, fvPatchField, volMesh> >
241         (
242             new GeometricField<Type, fvPatchField, volMesh>
243             (
244                 ddtIOobject,
245                 mesh(),
246                 rDeltaT.dimensions()*rho.dimensions()*vf.dimensions(),
247                 rDeltaT.value()*rho.value()*
248                 (
249                     coefft*vf.internalField() -
250                     (
251                         coefft0*vf.oldTime().internalField()*mesh().V0()
252                       - coefft00*vf.oldTime().oldTime().internalField()
253                        *mesh().V00()
254                     )/mesh().V()
255                 ),
256                 rDeltaT.value()*rho.value()*
257                 (
258                     coefft*vf.boundaryField() -
259                     (
260                         coefft0*vf.oldTime().boundaryField()
261                       - coefft00*vf.oldTime().oldTime().boundaryField()
262                     )
263                 )
264             )
265         );
266     }
267     else
268     {
269         return tmp<GeometricField<Type, fvPatchField, volMesh> >
270         (
271             new GeometricField<Type, fvPatchField, volMesh>
272             (
273                 ddtIOobject,
274                 rDeltaT*rho*
275                 (
276                     coefft*vf
277                   - coefft0*vf.oldTime()
278                  + coefft00*vf.oldTime().oldTime()
279                 )
280             )
281         );
282     }
285 template<class Type>
286 tmp<GeometricField<Type, fvPatchField, volMesh> >
287 backwardDdtScheme<Type>::fvcDdt
289     const volScalarField& rho,
290     const GeometricField<Type, fvPatchField, volMesh>& vf
293     dimensionedScalar rDeltaT = 1.0/mesh().time().deltaT();
295     IOobject ddtIOobject
296     (
297         "ddt("+rho.name()+','+vf.name()+')',
298         mesh().time().timeName(),
299         mesh()
300     );
302     scalar deltaT = deltaT_();
303     scalar deltaT0 = deltaT0_(vf);
305     scalar coefft   = 1 + deltaT/(deltaT + deltaT0);
306     scalar coefft00 = deltaT*deltaT/(deltaT0*(deltaT + deltaT0));
307     scalar coefft0  = coefft + coefft00;
309     if (mesh().moving())
310     {
311         return tmp<GeometricField<Type, fvPatchField, volMesh> >
312         (
313             new GeometricField<Type, fvPatchField, volMesh>
314             (
315                 ddtIOobject,
316                 mesh(),
317                 rDeltaT.dimensions()*rho.dimensions()*vf.dimensions(),
318                 rDeltaT.value()*
319                 (
320                     coefft*rho.internalField()*vf.internalField() -
321                     (
322                         coefft0*rho.oldTime().internalField()
323                        *vf.oldTime().internalField()*mesh().V0()
324                       - coefft00*rho.oldTime().oldTime().internalField()
325                        *vf.oldTime().oldTime().internalField()*mesh().V00()
326                     )/mesh().V()
327                 ),
328                 rDeltaT.value()*
329                 (
330                     coefft*rho.boundaryField()*vf.boundaryField() -
331                     (
332                         coefft0*rho.oldTime().boundaryField()
333                        *vf.oldTime().boundaryField()
334                       - coefft00*rho.oldTime().oldTime().boundaryField()
335                        *vf.oldTime().oldTime().boundaryField()
336                     )
337                 )
338             )
339         );
340     }
341     else
342     {
343         return tmp<GeometricField<Type, fvPatchField, volMesh> >
344         (
345             new GeometricField<Type, fvPatchField, volMesh>
346             (
347                 ddtIOobject,
348                 rDeltaT*
349                 (
350                     coefft*rho*vf
351                   - coefft0*rho.oldTime()*vf.oldTime()
352                   + coefft00*rho.oldTime().oldTime()*vf.oldTime().oldTime()
353                 )
354             )
355         );
356     }
360 template<class Type>
361 tmp<fvMatrix<Type> >
362 backwardDdtScheme<Type>::fvmDdt
364     GeometricField<Type, fvPatchField, volMesh>& vf
367     tmp<fvMatrix<Type> > tfvm
368     (
369         new fvMatrix<Type>
370         (
371             vf,
372             vf.dimensions()*dimVol/dimTime
373         )
374     );
376     fvMatrix<Type>& fvm = tfvm();
378     scalar rDeltaT = 1.0/deltaT_();
380     scalar deltaT = deltaT_();
381     scalar deltaT0 = deltaT0_(vf);
383     scalar coefft   = 1 + deltaT/(deltaT + deltaT0);
384     scalar coefft00 = deltaT*deltaT/(deltaT0*(deltaT + deltaT0));
385     scalar coefft0  = coefft + coefft00;
387     fvm.diag() = (coefft*rDeltaT)*mesh().V();
389     if (mesh().moving())
390     {
391         fvm.source() = rDeltaT*
392         (
393             coefft0*vf.oldTime().internalField()*mesh().V0()
394           - coefft00*vf.oldTime().oldTime().internalField()
395            *mesh().V00()
396         );
397     }
398     else
399     {
400         fvm.source() = rDeltaT*mesh().V()*
401         (
402             coefft0*vf.oldTime().internalField()
403           - coefft00*vf.oldTime().oldTime().internalField()
404         );
405     }
407     return tfvm;
411 template<class Type>
412 tmp<fvMatrix<Type> >
413 backwardDdtScheme<Type>::fvmDdt
415     const dimensionedScalar& rho,
416     GeometricField<Type, fvPatchField, volMesh>& vf
419     tmp<fvMatrix<Type> > tfvm
420     (
421         new fvMatrix<Type>
422         (
423             vf,
424             rho.dimensions()*vf.dimensions()*dimVol/dimTime
425         )
426     );
427     fvMatrix<Type>& fvm = tfvm();
429     scalar rDeltaT = 1.0/deltaT_();
431     scalar deltaT = deltaT_();
432     scalar deltaT0 = deltaT0_(vf);
434     scalar coefft   = 1 + deltaT/(deltaT + deltaT0);
435     scalar coefft00 = deltaT*deltaT/(deltaT0*(deltaT + deltaT0));
436     scalar coefft0  = coefft + coefft00;
438     fvm.diag() = (coefft*rDeltaT*rho.value())*mesh().V();
440     if (mesh().moving())
441     {
442         fvm.source() = rDeltaT*rho.value()*
443         (
444             coefft0*vf.oldTime().internalField()*mesh().V0()
445           - coefft00*vf.oldTime().oldTime().internalField()
446            *mesh().V00()
447         );
448     }
449     else
450     {
451         fvm.source() = rDeltaT*mesh().V()*rho.value()*
452         (
453             coefft0*vf.oldTime().internalField()
454           - coefft00*vf.oldTime().oldTime().internalField()
455         );
456     }
458     return tfvm;
462 template<class Type>
463 tmp<fvMatrix<Type> >
464 backwardDdtScheme<Type>::fvmDdt
466     const volScalarField& rho,
467     GeometricField<Type, fvPatchField, volMesh>& vf
470     tmp<fvMatrix<Type> > tfvm
471     (
472         new fvMatrix<Type>
473         (
474             vf,
475             rho.dimensions()*vf.dimensions()*dimVol/dimTime
476         )
477     );
478     fvMatrix<Type>& fvm = tfvm();
480     scalar rDeltaT = 1.0/deltaT_();
482     scalar deltaT = deltaT_();
483     scalar deltaT0 = deltaT0_(vf);
485     scalar coefft   = 1 + deltaT/(deltaT + deltaT0);
486     scalar coefft00 = deltaT*deltaT/(deltaT0*(deltaT + deltaT0));
487     scalar coefft0  = coefft + coefft00;
489     fvm.diag() = (coefft*rDeltaT)*rho.internalField()*mesh().V();
491     if (mesh().moving())
492     {
493         fvm.source() = rDeltaT*
494         (
495             coefft0*rho.oldTime().internalField()
496            *vf.oldTime().internalField()*mesh().V0()
497           - coefft00*rho.oldTime().oldTime().internalField()
498            *vf.oldTime().oldTime().internalField()*mesh().V00()
499         );
500     }
501     else
502     {
503         fvm.source() = rDeltaT*mesh().V()*
504         (
505             coefft0*rho.oldTime().internalField()
506            *vf.oldTime().internalField()
507           - coefft00*rho.oldTime().oldTime().internalField()
508            *vf.oldTime().oldTime().internalField()
509         );
510     }
512     return tfvm;
516 template<class Type>
517 tmp<typename backwardDdtScheme<Type>::fluxFieldType>
518 backwardDdtScheme<Type>::fvcDdtPhiCorr
520     const volScalarField& rA,
521     const GeometricField<Type, fvPatchField, volMesh>& U,
522     const fluxFieldType& phi
525     dimensionedScalar rDeltaT = 1.0/mesh().time().deltaT();
527     IOobject ddtIOobject
528     (
529         "ddtPhiCorr(" + rA.name() + ',' + U.name() + ',' + phi.name() + ')',
530         mesh().time().timeName(),
531         mesh()
532     );
534     scalar deltaT = deltaT_();
535     scalar deltaT0 = deltaT0_(U);
537     scalar coefft   = 1 + deltaT/(deltaT + deltaT0);
538     scalar coefft00 = deltaT*deltaT/(deltaT0*(deltaT + deltaT0));
539     scalar coefft0  = coefft + coefft00;
541     return tmp<fluxFieldType>
542     (
543         new fluxFieldType
544         (
545             ddtIOobject,
546             rDeltaT*fvcDdtPhiCoeff(U.oldTime(), phi.oldTime())
547            *(
548                 fvc::interpolate(rA)
549                *(
550                    coefft0*phi.oldTime()
551                  - coefft00*phi.oldTime().oldTime()
552                 )
553               - (
554                     fvc::interpolate
555                     (
556                         rA*
557                         (
558                             coefft0*U.oldTime()
559                           - coefft00*U.oldTime().oldTime()
560                         )
561                     ) & mesh().Sf()
562                 )
563             )
564         )
565     );
569 template<class Type>
570 tmp<typename backwardDdtScheme<Type>::fluxFieldType>
571 backwardDdtScheme<Type>::fvcDdtPhiCorr
573     const volScalarField& rA,
574     const volScalarField& rho,
575     const GeometricField<Type, fvPatchField, volMesh>& U,
576     const fluxFieldType& phiAbs
579     dimensionedScalar rDeltaT = 1.0/mesh().time().deltaT();
581     IOobject ddtIOobject
582     (
583         "ddtPhiCorr("
584       + rA.name() + ','
585       + rho.name() + ','
586       + U.name() + ','
587       + phiAbs.name() + ')',
588         mesh().time().timeName(),
589         mesh()
590     );
592     scalar deltaT = deltaT_();
593     scalar deltaT0 = deltaT0_(U);
595     scalar coefft   = 1 + deltaT/(deltaT + deltaT0);
596     scalar coefft00 = deltaT*deltaT/(deltaT0*(deltaT + deltaT0));
597     scalar coefft0  = coefft + coefft00;
599     if
600     (
601         U.dimensions() == dimVelocity
602      && phiAbs.dimensions() == dimVelocity*dimArea
603     )
604     {
605         return tmp<fluxFieldType>
606         (
607             new fluxFieldType
608             (
609                 ddtIOobject,
610                 rDeltaT*fvcDdtPhiCoeff(U.oldTime(), phiAbs.oldTime())
611                *(
612                     coefft0*fvc::interpolate(rA*rho.oldTime())
613                    *phiAbs.oldTime()
614                   - coefft00*fvc::interpolate(rA*rho.oldTime().oldTime())
615                    *phiAbs.oldTime().oldTime()
616                   - (
617                         fvc::interpolate
618                         (
619                             rA*
620                             (
621                                 coefft0*rho.oldTime()*U.oldTime()
622                               - coefft00*rho.oldTime().oldTime()
623                                *U.oldTime().oldTime()
624                             )
625                         ) & mesh().Sf()
626                     )
627                 )
628             )
629         );
630     }
631     else if
632     (
633         U.dimensions() == dimVelocity
634      && phiAbs.dimensions() == rho.dimensions()*dimVelocity*dimArea
635     )
636     {
637         return tmp<fluxFieldType>
638         (
639             new fluxFieldType
640             (
641                 ddtIOobject,
642                 rDeltaT
643                *fvcDdtPhiCoeff
644                 (
645                     U.oldTime(),
646                     phiAbs.oldTime()/fvc::interpolate(rho.oldTime())
647                 )
648                *(
649                     fvc::interpolate(rA*rho.oldTime())
650                    *(
651                        coefft0*phiAbs.oldTime()
652                       /fvc::interpolate(rho.oldTime())
653                      - coefft00*phiAbs.oldTime().oldTime()
654                       /fvc::interpolate(rho.oldTime().oldTime())
655                     )
656                   - (
657                         fvc::interpolate
658                         (
659                             rA*rho.oldTime()*
660                             (
661                                 coefft0*U.oldTime()
662                               - coefft00*U.oldTime().oldTime()
663                             )
664                         ) & mesh().Sf()
665                     )
666                 )
667             )
668         );
669     }
670     else if
671     (
672         U.dimensions() == rho.dimensions()*dimVelocity
673      && phiAbs.dimensions() == rho.dimensions()*dimVelocity*dimArea
674     )
675     {
676         return tmp<fluxFieldType>
677         (
678             new fluxFieldType
679             (
680                 ddtIOobject,
681                 rDeltaT
682                *fvcDdtPhiCoeff(rho.oldTime(), U.oldTime(), phiAbs.oldTime())
683                *(
684                     fvc::interpolate(rA)
685                    *(
686                        coefft0*phiAbs.oldTime()
687                      - coefft00*phiAbs.oldTime().oldTime()
688                     )
689                   - (
690                         fvc::interpolate
691                         (
692                             rA*
693                             (
694                                 coefft0*U.oldTime()
695                               - coefft00*U.oldTime().oldTime()
696                             )
697                         ) & mesh().Sf()
698                     )
699                 )
700             )
701         );
702     }
703     else
704     {
705         FatalErrorIn
706         (
707             "backwardDdtScheme<Type>::fvcDdtPhiCorr"
708         )   << "dimensions of phiAbs are not correct"
709             << abort(FatalError);
711         return fluxFieldType::null();
712     }
716 template<class Type>
717 tmp<surfaceScalarField> backwardDdtScheme<Type>::meshPhi
719     const GeometricField<Type, fvPatchField, volMesh>& vf
722     scalar deltaT = deltaT_();
723     scalar deltaT0 = deltaT0_(vf);
725     // Coefficient for t-3/2 (between times 0 and 00)
726     scalar coefft0_00 = deltaT/(deltaT + deltaT0);
728     // Coefficient for t-1/2 (between times n and 0)
729     scalar coefftn_0 = 1 + coefft0_00;
731     return coefftn_0*mesh().phi() - coefft0_00*mesh().phi().oldTime();
735 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
737 } // End namespace fv
739 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
741 } // End namespace Foam
743 // ************************************************************************* //