00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "CrankNicholsonDdtScheme.H"
00027 #include <finiteVolume/surfaceInterpolate.H>
00028 #include <finiteVolume/fvcDiv.H>
00029 #include <finiteVolume/fvMatrices.H>
00030
00031
00032
00033 namespace Foam
00034 {
00035
00036
00037
00038 namespace fv
00039 {
00040
00041
00042
00043 template<class Type>
00044 template<class GeoField>
00045 CrankNicholsonDdtScheme<Type>::DDt0Field<GeoField>::DDt0Field
00046 (
00047 const IOobject& io,
00048 const fvMesh& mesh
00049 )
00050 :
00051 GeoField(io, mesh),
00052 startTimeIndex_(-2)
00053
00054 {
00055
00056
00057 this->timeIndex() = mesh.time().startTimeIndex();
00058 }
00059
00060
00061 template<class Type>
00062 template<class GeoField>
00063 CrankNicholsonDdtScheme<Type>::DDt0Field<GeoField>::DDt0Field
00064 (
00065 const IOobject& io,
00066 const fvMesh& mesh,
00067 const dimensioned<typename GeoField::value_type>& dimType
00068 )
00069 :
00070 GeoField(io, mesh, dimType),
00071 startTimeIndex_(mesh.time().timeIndex())
00072 {}
00073
00074
00075 template<class Type>
00076 template<class GeoField>
00077 label CrankNicholsonDdtScheme<Type>::DDt0Field<GeoField>::
00078 startTimeIndex() const
00079 {
00080 return startTimeIndex_;
00081 }
00082
00083
00084 template<class Type>
00085 template<class GeoField>
00086 GeoField& CrankNicholsonDdtScheme<Type>::DDt0Field<GeoField>::
00087 operator()()
00088 {
00089 return *this;
00090 }
00091
00092
00093 template<class Type>
00094 template<class GeoField>
00095 void CrankNicholsonDdtScheme<Type>::DDt0Field<GeoField>::
00096 operator=(const GeoField& gf)
00097 {
00098 GeoField::operator=(gf);
00099 }
00100
00101
00102 template<class Type>
00103 template<class GeoField>
00104 CrankNicholsonDdtScheme<Type>::DDt0Field<GeoField>&
00105 CrankNicholsonDdtScheme<Type>::ddt0_
00106 (
00107 const word& name,
00108 const dimensionSet& dims
00109 )
00110 {
00111 if (!mesh().objectRegistry::foundObject<GeoField>(name))
00112 {
00113 const Time& runTime = mesh().time();
00114 word startTimeName = runTime.timeName(runTime.startTime().value());
00115
00116 if
00117 (
00118 (
00119 runTime.timeIndex() == runTime.startTimeIndex()
00120 || runTime.timeIndex() == runTime.startTimeIndex() + 1
00121 )
00122 && IOobject
00123 (
00124 name,
00125 startTimeName,
00126 mesh()
00127 ).headerOk()
00128 )
00129 {
00130 regIOobject::store
00131 (
00132 new DDt0Field<GeoField>
00133 (
00134 IOobject
00135 (
00136 name,
00137 startTimeName,
00138 mesh(),
00139 IOobject::MUST_READ,
00140 IOobject::AUTO_WRITE
00141 ),
00142 mesh()
00143 )
00144 );
00145 }
00146 else
00147 {
00148 regIOobject::store
00149 (
00150 new DDt0Field<GeoField>
00151 (
00152 IOobject
00153 (
00154 name,
00155 mesh().time().timeName(),
00156 mesh(),
00157 IOobject::NO_READ,
00158 IOobject::AUTO_WRITE
00159 ),
00160 mesh(),
00161 dimensioned<typename GeoField::value_type>
00162 (
00163 "0",
00164 dims/dimTime,
00165 pTraits<typename GeoField::value_type>::zero
00166 )
00167 )
00168 );
00169 }
00170 }
00171
00172 DDt0Field<GeoField>& ddt0 = static_cast<DDt0Field<GeoField>&>
00173 (
00174 const_cast<GeoField&>
00175 (
00176 mesh().objectRegistry::lookupObject<GeoField>(name)
00177 )
00178 );
00179
00180 return ddt0;
00181 }
00182
00183
00184 template<class Type>
00185 template<class GeoField>
00186 bool CrankNicholsonDdtScheme<Type>::evaluate
00187 (
00188 const DDt0Field<GeoField>& ddt0
00189 ) const
00190 {
00191 return ddt0.timeIndex() != mesh().time().timeIndex();
00192 }
00193
00194 template<class Type>
00195 template<class GeoField>
00196 scalar CrankNicholsonDdtScheme<Type>::coef_
00197 (
00198 const DDt0Field<GeoField>& ddt0
00199 ) const
00200 {
00201 if (mesh().time().timeIndex() - ddt0.startTimeIndex() > 0)
00202 {
00203 return 1.0 + ocCoeff_;
00204 }
00205 else
00206 {
00207 return 1.0;
00208 }
00209 }
00210
00211
00212 template<class Type>
00213 template<class GeoField>
00214 scalar CrankNicholsonDdtScheme<Type>::coef0_
00215 (
00216 const DDt0Field<GeoField>& ddt0
00217 ) const
00218 {
00219 if (mesh().time().timeIndex() - ddt0.startTimeIndex() > 1)
00220 {
00221 return 1.0 + ocCoeff_;
00222 }
00223 else
00224 {
00225 return 1.0;
00226 }
00227 }
00228
00229
00230 template<class Type>
00231 template<class GeoField>
00232 dimensionedScalar CrankNicholsonDdtScheme<Type>::rDtCoef_
00233 (
00234 const DDt0Field<GeoField>& ddt0
00235 ) const
00236 {
00237 return coef_(ddt0)/mesh().time().deltaT();
00238 }
00239
00240
00241 template<class Type>
00242 template<class GeoField>
00243 dimensionedScalar CrankNicholsonDdtScheme<Type>::rDtCoef0_
00244 (
00245 const DDt0Field<GeoField>& ddt0
00246 ) const
00247 {
00248 return coef0_(ddt0)/mesh().time().deltaT0();
00249 }
00250
00251
00252 template<class Type>
00253 template<class GeoField>
00254 tmp<GeoField> CrankNicholsonDdtScheme<Type>::offCentre_
00255 (
00256 const GeoField& ddt0
00257 ) const
00258 {
00259 if (ocCoeff_ < 1.0)
00260 {
00261 return ocCoeff_*ddt0;
00262 }
00263 else
00264 {
00265 return ddt0;
00266 }
00267 }
00268
00269
00270 template<class Type>
00271 const FieldField<fvPatchField, Type>& ff
00272 (
00273 const FieldField<fvPatchField, Type>& bf
00274 )
00275 {
00276 return bf;
00277 }
00278
00279
00280
00281
00282 template<class Type>
00283 tmp<GeometricField<Type, fvPatchField, volMesh> >
00284 CrankNicholsonDdtScheme<Type>::fvcDdt
00285 (
00286 const dimensioned<Type>& dt
00287 )
00288 {
00289 DDt0Field<GeometricField<Type, fvPatchField, volMesh> >& ddt0 =
00290 ddt0_<GeometricField<Type, fvPatchField, volMesh> >
00291 (
00292 "ddt0(" + dt.name() + ')',
00293 dt.dimensions()
00294 );
00295
00296 IOobject ddtIOobject
00297 (
00298 "ddt(" + dt.name() + ')',
00299 mesh().time().timeName(),
00300 mesh()
00301 );
00302
00303 tmp<GeometricField<Type, fvPatchField, volMesh> > tdtdt
00304 (
00305 new GeometricField<Type, fvPatchField, volMesh>
00306 (
00307 ddtIOobject,
00308 mesh(),
00309 dimensioned<Type>
00310 (
00311 "0",
00312 dt.dimensions()/dimTime,
00313 pTraits<Type>::zero
00314 )
00315 )
00316 );
00317
00318 dimensionedScalar rDtCoef = rDtCoef_(ddt0);
00319
00320 if (mesh().moving())
00321 {
00322 if (evaluate(ddt0))
00323 {
00324 dimensionedScalar rDtCoef0 = rDtCoef0_(ddt0);
00325
00326 ddt0.dimensionedInternalField() =
00327 (
00328 (rDtCoef0*dt)*(mesh().V0() - mesh().V00())
00329 - mesh().V00()*offCentre_(ddt0.dimensionedInternalField())
00330 )/mesh().V0();
00331 }
00332
00333 tdtdt().dimensionedInternalField() =
00334 (
00335 (rDtCoef*dt)*(mesh().V() - mesh().V0())
00336 - mesh().V0()*offCentre_(ddt0.dimensionedInternalField())
00337 )/mesh().V();
00338 }
00339
00340 return tdtdt;
00341 }
00342
00343
00344 template<class Type>
00345 tmp<GeometricField<Type, fvPatchField, volMesh> >
00346 CrankNicholsonDdtScheme<Type>::fvcDdt
00347 (
00348 const GeometricField<Type, fvPatchField, volMesh>& vf
00349 )
00350 {
00351 DDt0Field<GeometricField<Type, fvPatchField, volMesh> >& ddt0 =
00352 ddt0_<GeometricField<Type, fvPatchField, volMesh> >
00353 (
00354 "ddt0(" + vf.name() + ')',
00355 vf.dimensions()
00356 );
00357
00358 IOobject ddtIOobject
00359 (
00360 "ddt(" + vf.name() + ')',
00361 mesh().time().timeName(),
00362 mesh()
00363 );
00364
00365 dimensionedScalar rDtCoef = rDtCoef_(ddt0);
00366
00367 if (mesh().moving())
00368 {
00369 if (evaluate(ddt0))
00370 {
00371 scalar rDtCoef0 = rDtCoef0_(ddt0).value();
00372
00373 ddt0.internalField() =
00374 (
00375 rDtCoef0*
00376 (
00377 mesh().V0()*vf.oldTime().internalField()
00378 - mesh().V00()*vf.oldTime().oldTime().internalField()
00379 ) - mesh().V00()*offCentre_(ddt0.internalField())
00380 )/mesh().V0();
00381
00382 ddt0.boundaryField() =
00383 (
00384 rDtCoef0*
00385 (
00386 vf.oldTime().boundaryField()
00387 - vf.oldTime().oldTime().boundaryField()
00388 ) - offCentre_(ff(ddt0.boundaryField()))
00389 );
00390 }
00391
00392 return tmp<GeometricField<Type, fvPatchField, volMesh> >
00393 (
00394 new GeometricField<Type, fvPatchField, volMesh>
00395 (
00396 ddtIOobject,
00397 mesh(),
00398 rDtCoef.dimensions()*vf.dimensions(),
00399 (
00400 rDtCoef.value()*
00401 (
00402 mesh().V()*vf.internalField()
00403 - mesh().V0()*vf.oldTime().internalField()
00404 ) - mesh().V0()*offCentre_(ddt0.internalField())
00405 )/mesh().V(),
00406 rDtCoef.value()*
00407 (
00408 vf.boundaryField() - vf.oldTime().boundaryField()
00409 ) - offCentre_(ff(ddt0.boundaryField()))
00410 )
00411 );
00412 }
00413 else
00414 {
00415 if (evaluate(ddt0))
00416 {
00417 ddt0 = rDtCoef0_(ddt0)*(vf.oldTime() - vf.oldTime().oldTime())
00418 - offCentre_(ddt0());
00419 }
00420
00421 return tmp<GeometricField<Type, fvPatchField, volMesh> >
00422 (
00423 new GeometricField<Type, fvPatchField, volMesh>
00424 (
00425 ddtIOobject,
00426 rDtCoef*(vf - vf.oldTime()) - offCentre_(ddt0())
00427 )
00428 );
00429 }
00430 }
00431
00432
00433 template<class Type>
00434 tmp<GeometricField<Type, fvPatchField, volMesh> >
00435 CrankNicholsonDdtScheme<Type>::fvcDdt
00436 (
00437 const dimensionedScalar& rho,
00438 const GeometricField<Type, fvPatchField, volMesh>& vf
00439 )
00440 {
00441 DDt0Field<GeometricField<Type, fvPatchField, volMesh> >& ddt0 =
00442 ddt0_<GeometricField<Type, fvPatchField, volMesh> >
00443 (
00444 "ddt0(" + rho.name() + ',' + vf.name() + ')',
00445 rho.dimensions()*vf.dimensions()
00446 );
00447
00448 IOobject ddtIOobject
00449 (
00450 "ddt(" + rho.name() + ',' + vf.name() + ')',
00451 mesh().time().timeName(),
00452 mesh()
00453 );
00454
00455 dimensionedScalar rDtCoef = rDtCoef_(ddt0);
00456
00457 if (mesh().moving())
00458 {
00459 if (evaluate(ddt0))
00460 {
00461 scalar rDtCoef0 = rDtCoef0_(ddt0).value();
00462
00463 ddt0.internalField() =
00464 (
00465 rDtCoef0*rho.value()*
00466 (
00467 mesh().V0()*vf.oldTime().internalField()
00468 - mesh().V00()*vf.oldTime().oldTime().internalField()
00469 ) - mesh().V00()*offCentre_(ddt0.internalField())
00470 )/mesh().V0();
00471
00472 ddt0.boundaryField() =
00473 (
00474 rDtCoef0*rho.value()*
00475 (
00476 vf.oldTime().boundaryField()
00477 - vf.oldTime().oldTime().boundaryField()
00478 ) - offCentre_(ff(ddt0.boundaryField()))
00479 );
00480 }
00481
00482 return tmp<GeometricField<Type, fvPatchField, volMesh> >
00483 (
00484 new GeometricField<Type, fvPatchField, volMesh>
00485 (
00486 ddtIOobject,
00487 mesh(),
00488 rDtCoef.dimensions()*rho.dimensions()*vf.dimensions(),
00489 (
00490 rDtCoef.value()*rho.value()*
00491 (
00492 mesh().V()*vf.internalField()
00493 - mesh().V0()*vf.oldTime().internalField()
00494 ) - mesh().V0()*offCentre_(ddt0.internalField())
00495 )/mesh().V(),
00496 rDtCoef.value()*rho.value()*
00497 (
00498 vf.boundaryField() - vf.oldTime().boundaryField()
00499 ) - offCentre_(ff(ddt0.boundaryField()))
00500 )
00501 );
00502 }
00503 else
00504 {
00505 if (evaluate(ddt0))
00506 {
00507 ddt0 = rDtCoef0_(ddt0)*rho*(vf.oldTime() - vf.oldTime().oldTime())
00508 - offCentre_(ddt0());
00509 }
00510
00511 return tmp<GeometricField<Type, fvPatchField, volMesh> >
00512 (
00513 new GeometricField<Type, fvPatchField, volMesh>
00514 (
00515 ddtIOobject,
00516 rDtCoef*rho*(vf - vf.oldTime()) - offCentre_(ddt0())
00517 )
00518 );
00519 }
00520 }
00521
00522
00523 template<class Type>
00524 tmp<GeometricField<Type, fvPatchField, volMesh> >
00525 CrankNicholsonDdtScheme<Type>::fvcDdt
00526 (
00527 const volScalarField& rho,
00528 const GeometricField<Type, fvPatchField, volMesh>& vf
00529 )
00530 {
00531 DDt0Field<GeometricField<Type, fvPatchField, volMesh> >& ddt0 =
00532 ddt0_<GeometricField<Type, fvPatchField, volMesh> >
00533 (
00534 "ddt0(" + rho.name() + ',' + vf.name() + ')',
00535 rho.dimensions()*vf.dimensions()
00536 );
00537
00538 IOobject ddtIOobject
00539 (
00540 "ddt(" + rho.name() + ',' + vf.name() + ')',
00541 mesh().time().timeName(),
00542 mesh()
00543 );
00544
00545 dimensionedScalar rDtCoef = rDtCoef_(ddt0);
00546
00547 if (mesh().moving())
00548 {
00549 if (evaluate(ddt0))
00550 {
00551 scalar rDtCoef0 = rDtCoef0_(ddt0).value();
00552
00553 ddt0.internalField() =
00554 (
00555 rDtCoef0*
00556 (
00557 mesh().V0()*rho.oldTime().internalField()
00558 *vf.oldTime().internalField()
00559 - mesh().V00()*rho.oldTime().oldTime().internalField()
00560 *vf.oldTime().oldTime().internalField()
00561 ) - mesh().V00()*offCentre_(ddt0.internalField())
00562 )/mesh().V0();
00563
00564 ddt0.boundaryField() =
00565 (
00566 rDtCoef0*
00567 (
00568 rho.oldTime().boundaryField()
00569 *vf.oldTime().boundaryField()
00570 - rho.oldTime().oldTime().boundaryField()
00571 *vf.oldTime().oldTime().boundaryField()
00572 ) - offCentre_(ff(ddt0.boundaryField()))
00573 );
00574 }
00575
00576 return tmp<GeometricField<Type, fvPatchField, volMesh> >
00577 (
00578 new GeometricField<Type, fvPatchField, volMesh>
00579 (
00580 ddtIOobject,
00581 mesh(),
00582 rDtCoef.dimensions()*rho.dimensions()*vf.dimensions(),
00583 (
00584 rDtCoef.value()*
00585 (
00586 mesh().V()*rho.internalField()*vf.internalField()
00587 - mesh().V0()*rho.oldTime().internalField()
00588 *vf.oldTime().internalField()
00589 ) - mesh().V00()*offCentre_(ddt0.internalField())
00590 )/mesh().V(),
00591 rDtCoef.value()*
00592 (
00593 rho.boundaryField()*vf.boundaryField()
00594 - rho.oldTime().boundaryField()*vf.oldTime().boundaryField()
00595 ) - offCentre_(ff(ddt0.boundaryField()))
00596 )
00597 );
00598 }
00599 else
00600 {
00601 if (evaluate(ddt0))
00602 {
00603 ddt0 = rDtCoef0_(ddt0)*
00604 (
00605 rho.oldTime()*vf.oldTime()
00606 - rho.oldTime().oldTime()*vf.oldTime().oldTime()
00607 ) - offCentre_(ddt0());
00608 }
00609
00610 return tmp<GeometricField<Type, fvPatchField, volMesh> >
00611 (
00612 new GeometricField<Type, fvPatchField, volMesh>
00613 (
00614 ddtIOobject,
00615 rDtCoef*(rho*vf - rho.oldTime()*vf.oldTime())
00616 - offCentre_(ddt0())
00617 )
00618 );
00619 }
00620 }
00621
00622
00623 template<class Type>
00624 tmp<fvMatrix<Type> >
00625 CrankNicholsonDdtScheme<Type>::fvmDdt
00626 (
00627 GeometricField<Type, fvPatchField, volMesh>& vf
00628 )
00629 {
00630 DDt0Field<GeometricField<Type, fvPatchField, volMesh> >& ddt0 =
00631 ddt0_<GeometricField<Type, fvPatchField, volMesh> >
00632 (
00633 "ddt0(" + vf.name() + ')',
00634 vf.dimensions()
00635 );
00636
00637 tmp<fvMatrix<Type> > tfvm
00638 (
00639 new fvMatrix<Type>
00640 (
00641 vf,
00642 vf.dimensions()*dimVol/dimTime
00643 )
00644 );
00645
00646 fvMatrix<Type>& fvm = tfvm();
00647
00648 scalar rDtCoef = rDtCoef_(ddt0).value();
00649
00650 fvm.diag() = rDtCoef*mesh().V();
00651
00652 vf.oldTime().oldTime();
00653
00654 if (mesh().moving())
00655 {
00656 if (evaluate(ddt0))
00657 {
00658 scalar rDtCoef0 = rDtCoef0_(ddt0).value();
00659
00660 ddt0.internalField() =
00661 (
00662 rDtCoef0*
00663 (
00664 mesh().V0()*vf.oldTime().internalField()
00665 - mesh().V00()*vf.oldTime().oldTime().internalField()
00666 )
00667 - mesh().V00()*offCentre_(ddt0.internalField())
00668 )/mesh().V0();
00669
00670 ddt0.boundaryField() =
00671 (
00672 rDtCoef0*
00673 (
00674 vf.oldTime().boundaryField()
00675 - vf.oldTime().oldTime().boundaryField()
00676 )
00677 - offCentre_(ff(ddt0.boundaryField()))
00678 );
00679 }
00680
00681 fvm.source() =
00682 (
00683 rDtCoef*vf.oldTime().internalField()
00684 + offCentre_(ddt0.internalField())
00685 )*mesh().V0();
00686 }
00687 else
00688 {
00689 if (evaluate(ddt0))
00690 {
00691 ddt0 = rDtCoef0_(ddt0)*(vf.oldTime() - vf.oldTime().oldTime())
00692 - offCentre_(ddt0());
00693 }
00694
00695 fvm.source() =
00696 (
00697 rDtCoef*vf.oldTime().internalField()
00698 + offCentre_(ddt0.internalField())
00699 )*mesh().V();
00700 }
00701
00702 return tfvm;
00703 }
00704
00705
00706 template<class Type>
00707 tmp<fvMatrix<Type> >
00708 CrankNicholsonDdtScheme<Type>::fvmDdt
00709 (
00710 const dimensionedScalar& rho,
00711 GeometricField<Type, fvPatchField, volMesh>& vf
00712 )
00713 {
00714 DDt0Field<GeometricField<Type, fvPatchField, volMesh> >& ddt0 =
00715 ddt0_<GeometricField<Type, fvPatchField, volMesh> >
00716 (
00717 "ddt0(" + rho.name() + ',' + vf.name() + ')',
00718 rho.dimensions()*vf.dimensions()
00719 );
00720
00721 tmp<fvMatrix<Type> > tfvm
00722 (
00723 new fvMatrix<Type>
00724 (
00725 vf,
00726 rho.dimensions()*vf.dimensions()*dimVol/dimTime
00727 )
00728 );
00729 fvMatrix<Type>& fvm = tfvm();
00730
00731 scalar rDtCoef = rDtCoef_(ddt0).value();
00732 fvm.diag() = rDtCoef*rho.value()*mesh().V();
00733
00734 vf.oldTime().oldTime();
00735
00736 if (mesh().moving())
00737 {
00738 if (evaluate(ddt0))
00739 {
00740 scalar rDtCoef0 = rDtCoef0_(ddt0).value();
00741
00742 ddt0.internalField() =
00743 (
00744 rDtCoef0*rho.value()*
00745 (
00746 mesh().V0()*vf.oldTime().internalField()
00747 - mesh().V00()*vf.oldTime().oldTime().internalField()
00748 )
00749 - mesh().V00()*offCentre_(ddt0.internalField())
00750 )/mesh().V0();
00751
00752 ddt0.boundaryField() =
00753 (
00754 rDtCoef0*rho.value()*
00755 (
00756 vf.oldTime().boundaryField()
00757 - vf.oldTime().oldTime().boundaryField()
00758 )
00759 - offCentre_(ff(ddt0.boundaryField()))
00760 );
00761 }
00762
00763 fvm.source() =
00764 (
00765 rDtCoef*rho.value()*vf.oldTime().internalField()
00766 + offCentre_(ddt0.internalField())
00767 )*mesh().V0();
00768 }
00769 else
00770 {
00771 if (evaluate(ddt0))
00772 {
00773 ddt0 = rDtCoef0_(ddt0)*rho*(vf.oldTime() - vf.oldTime().oldTime())
00774 - offCentre_(ddt0());
00775 }
00776
00777 fvm.source() =
00778 (
00779 rDtCoef*rho.value()*vf.oldTime().internalField()
00780 + offCentre_(ddt0.internalField())
00781 )*mesh().V();
00782 }
00783
00784 return tfvm;
00785 }
00786
00787
00788 template<class Type>
00789 tmp<fvMatrix<Type> >
00790 CrankNicholsonDdtScheme<Type>::fvmDdt
00791 (
00792 const volScalarField& rho,
00793 GeometricField<Type, fvPatchField, volMesh>& vf
00794 )
00795 {
00796 DDt0Field<GeometricField<Type, fvPatchField, volMesh> >& ddt0 =
00797 ddt0_<GeometricField<Type, fvPatchField, volMesh> >
00798 (
00799 "ddt0(" + rho.name() + ',' + vf.name() + ')',
00800 rho.dimensions()*vf.dimensions()
00801 );
00802
00803 tmp<fvMatrix<Type> > tfvm
00804 (
00805 new fvMatrix<Type>
00806 (
00807 vf,
00808 rho.dimensions()*vf.dimensions()*dimVol/dimTime
00809 )
00810 );
00811 fvMatrix<Type>& fvm = tfvm();
00812
00813 scalar rDtCoef = rDtCoef_(ddt0).value();
00814 fvm.diag() = rDtCoef*rho.internalField()*mesh().V();
00815
00816 vf.oldTime().oldTime();
00817 rho.oldTime().oldTime();
00818
00819 if (mesh().moving())
00820 {
00821 if (evaluate(ddt0))
00822 {
00823 scalar rDtCoef0 = rDtCoef0_(ddt0).value();
00824
00825 ddt0.internalField() =
00826 (
00827 rDtCoef0*
00828 (
00829 mesh().V0()*rho.oldTime().internalField()
00830 *vf.oldTime().internalField()
00831 - mesh().V00()*rho.oldTime().oldTime().internalField()
00832 *vf.oldTime().oldTime().internalField()
00833 )
00834 - mesh().V00()*offCentre_(ddt0.internalField())
00835 )/mesh().V0();
00836
00837 ddt0.boundaryField() =
00838 (
00839 rDtCoef0*
00840 (
00841 rho.oldTime().boundaryField()
00842 *vf.oldTime().boundaryField()
00843 - rho.oldTime().oldTime().boundaryField()
00844 *vf.oldTime().oldTime().boundaryField()
00845 )
00846 - offCentre_(ff(ddt0.boundaryField()))
00847 );
00848 }
00849
00850 fvm.source() =
00851 (
00852 rDtCoef*rho.internalField()*vf.oldTime().internalField()
00853 + offCentre_(ddt0.internalField())
00854 )*mesh().V0();
00855 }
00856 else
00857 {
00858 if (evaluate(ddt0))
00859 {
00860 ddt0 = rDtCoef0_(ddt0)*
00861 (
00862 rho.oldTime()*vf.oldTime()
00863 - rho.oldTime().oldTime()*vf.oldTime().oldTime()
00864 ) - offCentre_(ddt0());
00865 }
00866
00867 fvm.source() =
00868 (
00869 rDtCoef*rho.oldTime().internalField()*vf.oldTime().internalField()
00870 + offCentre_(ddt0.internalField())
00871 )*mesh().V();
00872 }
00873
00874 return tfvm;
00875 }
00876
00877
00878
00879 template<class Type>
00880 tmp<typename CrankNicholsonDdtScheme<Type>::fluxFieldType>
00881 CrankNicholsonDdtScheme<Type>::fvcDdtPhiCorr
00882 (
00883 const volScalarField& rA,
00884 const GeometricField<Type, fvPatchField, volMesh>& U,
00885 const fluxFieldType& phi
00886 )
00887 {
00888 DDt0Field<GeometricField<Type, fvPatchField, volMesh> >& dUdt0 =
00889 ddt0_<GeometricField<Type, fvPatchField, volMesh> >
00890 (
00891 "ddt0(" + U.name() + ')',
00892 U.dimensions()
00893 );
00894
00895 DDt0Field<fluxFieldType>& dphidt0 =
00896 ddt0_<fluxFieldType>
00897 (
00898 "ddt0(" + phi.name() + ')',
00899 phi.dimensions()
00900 );
00901
00902 IOobject ddtIOobject
00903 (
00904 "ddtPhiCorr(" + rA.name() + ',' + U.name() + ',' + phi.name() + ')',
00905 mesh().time().timeName(),
00906 mesh()
00907 );
00908
00909 dimensionedScalar rDtCoef = rDtCoef_(dUdt0);
00910
00911 if (mesh().moving())
00912 {
00913 return tmp<fluxFieldType>
00914 (
00915 new fluxFieldType
00916 (
00917 ddtIOobject,
00918 mesh(),
00919 dimensioned<typename flux<Type>::type>
00920 (
00921 "0",
00922 rDtCoef.dimensions()*rA.dimensions()*phi.dimensions(),
00923 pTraits<typename flux<Type>::type>::zero
00924 )
00925 )
00926 );
00927 }
00928 else
00929 {
00930 if (evaluate(dUdt0))
00931 {
00932 dUdt0 =
00933 rDtCoef0_(dUdt0)*(U.oldTime() - U.oldTime().oldTime())
00934 - offCentre_(dUdt0());
00935 }
00936
00937 if (evaluate(dphidt0))
00938 {
00939 dphidt0 =
00940 rDtCoef0_(dphidt0)*(phi.oldTime() - phi.oldTime().oldTime())
00941 - offCentre_(dphidt0());
00942 }
00943
00944 return tmp<fluxFieldType>
00945 (
00946 new fluxFieldType
00947 (
00948 ddtIOobject,
00949 this->fvcDdtPhiCoeff(U.oldTime(), phi.oldTime())
00950 *fvc::interpolate(rA)
00951 *(
00952 (rDtCoef*phi.oldTime() + offCentre_(dphidt0()))
00953 - (
00954 fvc::interpolate
00955 (
00956 (rDtCoef*U.oldTime() + offCentre_(dUdt0()))
00957 ) & mesh().Sf()
00958 )
00959 )
00960 )
00961 );
00962 }
00963 }
00964
00965
00966 template<class Type>
00967 tmp<typename CrankNicholsonDdtScheme<Type>::fluxFieldType>
00968 CrankNicholsonDdtScheme<Type>::fvcDdtPhiCorr
00969 (
00970 const volScalarField& rA,
00971 const volScalarField& rho,
00972 const GeometricField<Type, fvPatchField, volMesh>& U,
00973 const fluxFieldType& phi
00974 )
00975 {
00976 DDt0Field<GeometricField<Type, fvPatchField, volMesh> >& dUdt0 =
00977 ddt0_<GeometricField<Type, fvPatchField, volMesh> >
00978 (
00979 "ddt0(" + U.name() + ')',
00980 U.dimensions()
00981 );
00982
00983 DDt0Field<fluxFieldType>& dphidt0 =
00984 ddt0_<fluxFieldType>
00985 (
00986 "ddt0(" + phi.name() + ')',
00987 U.dimensions()*dimArea
00988 );
00989
00990 IOobject ddtIOobject
00991 (
00992 "ddtPhiCorr("
00993 + rA.name() + ',' + rho.name() + ',' + U.name() + ',' + phi.name() + ')',
00994 mesh().time().timeName(),
00995 mesh()
00996 );
00997
00998 dimensionedScalar rDtCoef = rDtCoef_(dUdt0);
00999
01000 if (mesh().moving())
01001 {
01002 return tmp<fluxFieldType>
01003 (
01004 new fluxFieldType
01005 (
01006 ddtIOobject,
01007 mesh(),
01008 dimensioned<typename flux<Type>::type>
01009 (
01010 "0",
01011 rA.dimensions()*rho.dimensions()*phi.dimensions()/dimTime,
01012 pTraits<typename flux<Type>::type>::zero
01013 )
01014 )
01015 );
01016 }
01017 else
01018 {
01019 if
01020 (
01021 U.dimensions() == dimVelocity
01022 && phi.dimensions() == dimVelocity*dimArea
01023 )
01024 {
01025 if (evaluate(dUdt0))
01026 {
01027 dUdt0 = rDtCoef0_(dUdt0)*
01028 (
01029 U.oldTime() - U.oldTime().oldTime()
01030 ) - offCentre_(dUdt0());
01031 }
01032
01033 if (evaluate(dphidt0))
01034 {
01035 dphidt0 = rDtCoef0_(dphidt0)*
01036 (
01037 phi.oldTime()
01038 - fvc::interpolate(rho.oldTime().oldTime()/rho.oldTime())
01039 *phi.oldTime().oldTime()
01040 ) - offCentre_(dphidt0());
01041 }
01042
01043 return tmp<fluxFieldType>
01044 (
01045 new fluxFieldType
01046 (
01047 ddtIOobject,
01048 this->fvcDdtPhiCoeff(U.oldTime(), phi.oldTime())*
01049 (
01050 fvc::interpolate(rA*rho.oldTime())
01051 *(rDtCoef*phi.oldTime() + offCentre_(dphidt0()))
01052 - (
01053 fvc::interpolate
01054 (
01055 rA*rho.oldTime()
01056 *(rDtCoef*U.oldTime() + offCentre_(dUdt0()))
01057 ) & mesh().Sf()
01058 )
01059 )
01060 )
01061 );
01062 }
01063 else if
01064 (
01065 U.dimensions() == dimVelocity
01066 && phi.dimensions() == rho.dimensions()*dimVelocity*dimArea
01067 )
01068 {
01069 if (evaluate(dUdt0))
01070 {
01071 dUdt0 = rDtCoef0_(dUdt0)*
01072 (
01073 U.oldTime() - U.oldTime().oldTime()
01074 ) - offCentre_(dUdt0());
01075 }
01076
01077 if (evaluate(dphidt0))
01078 {
01079 dphidt0 = rDtCoef0_(dphidt0)*
01080 (
01081 phi.oldTime()
01082 /fvc::interpolate(rho.oldTime())
01083 - phi.oldTime().oldTime()
01084 /fvc::interpolate(rho.oldTime().oldTime())
01085 ) - offCentre_(dphidt0());
01086 }
01087
01088 return tmp<fluxFieldType>
01089 (
01090 new fluxFieldType
01091 (
01092 ddtIOobject,
01093 this->fvcDdtPhiCoeff
01094 (
01095 U.oldTime(),
01096 phi.oldTime()/fvc::interpolate(rho.oldTime())
01097 )
01098 *(
01099 fvc::interpolate(rA*rho.oldTime())
01100 *(
01101 rDtCoef*phi.oldTime()/fvc::interpolate(rho.oldTime())
01102 + offCentre_(dphidt0())
01103 )
01104 - (
01105 fvc::interpolate
01106 (
01107 rA*rho.oldTime()
01108 *(rDtCoef*U.oldTime() + offCentre_(dUdt0()))
01109 ) & mesh().Sf()
01110 )
01111 )
01112 )
01113 );
01114 }
01115 else if
01116 (
01117 U.dimensions() == rho.dimensions()*dimVelocity
01118 && phi.dimensions() == rho.dimensions()*dimVelocity*dimArea
01119 )
01120 {
01121 if (evaluate(dUdt0))
01122 {
01123 dUdt0 = rDtCoef0_(dUdt0)*
01124 (
01125 U.oldTime() - U.oldTime().oldTime()
01126 ) - offCentre_(dUdt0());
01127 }
01128
01129 if (evaluate(dphidt0))
01130 {
01131 dphidt0 = rDtCoef0_(dphidt0)*
01132 (
01133 phi.oldTime() - phi.oldTime().oldTime()
01134 ) - offCentre_(dphidt0());
01135 }
01136
01137 return tmp<fluxFieldType>
01138 (
01139 new fluxFieldType
01140 (
01141 ddtIOobject,
01142 this->fvcDdtPhiCoeff
01143 (
01144 rho.oldTime(),
01145 U.oldTime(),
01146 phi.oldTime()
01147 )
01148 *(
01149 fvc::interpolate(rA)
01150 *(rDtCoef*phi.oldTime() + offCentre_(dphidt0()))
01151 - (
01152 fvc::interpolate
01153 (
01154 rA*(rDtCoef*U.oldTime() + offCentre_(dUdt0()))
01155 ) & mesh().Sf()
01156 )
01157 )
01158 )
01159 );
01160 }
01161 else
01162 {
01163 FatalErrorIn
01164 (
01165 "CrankNicholsonDdtScheme<Type>::fvcDdtPhiCorr"
01166 ) << "dimensions of phi are not correct"
01167 << abort(FatalError);
01168
01169 return fluxFieldType::null();
01170 }
01171 }
01172 }
01173
01174
01175 template<class Type>
01176 tmp<surfaceScalarField> CrankNicholsonDdtScheme<Type>::meshPhi
01177 (
01178 const GeometricField<Type, fvPatchField, volMesh>& vf
01179 )
01180 {
01181 DDt0Field<surfaceScalarField>& meshPhi0 = ddt0_<surfaceScalarField>
01182 (
01183 "meshPhiCN_0",
01184 dimVolume
01185 );
01186
01187 if (evaluate(meshPhi0))
01188 {
01189 meshPhi0 =
01190 coef0_(meshPhi0)*mesh().phi().oldTime() - offCentre_(meshPhi0());
01191 }
01192
01193 return coef_(meshPhi0)*mesh().phi() - offCentre_(meshPhi0());
01194 }
01195
01196
01197
01198
01199 }
01200
01201
01202
01203 }
01204
01205