27 #include "surfaceInterpolate.H"
45 template<
class GeoField>
46 CrankNicolsonDdtScheme<Type>::DDt0Field<GeoField>::DDt0Field
58 this->
timeIndex() = mesh.time().startTimeIndex();
63 template<
class GeoField>
64 CrankNicolsonDdtScheme<Type>::DDt0Field<GeoField>::DDt0Field
68 const dimensioned<typename GeoField::value_type>& dimType
71 GeoField(io,
mesh, dimType),
77 template<
class GeoField>
78 label CrankNicolsonDdtScheme<Type>::DDt0Field<GeoField>::
79 startTimeIndex()
const
81 return startTimeIndex_;
86 template<
class GeoField>
87 GeoField& CrankNicolsonDdtScheme<Type>::DDt0Field<GeoField>::
95 template<
class GeoField>
99 GeoField::operator=(gf);
104 template<
class GeoField>
105 typename CrankNicolsonDdtScheme<Type>::template DDt0Field<GeoField>&
108 const word& unTypedName,
114 if (!
mesh().objectRegistry::template foundObject<GeoField>(
name))
135 new DDt0Field<GeoField>
153 new DDt0Field<GeoField>
175 DDt0Field<GeoField>&
ddt0 =
static_cast<DDt0Field<GeoField>&
>
177 mesh().objectRegistry::template lookupObjectRef<GeoField>(
name)
185 template<
class GeoField>
188 const DDt0Field<GeoField>&
ddt0
196 template<
class GeoField>
197 scalar CrankNicolsonDdtScheme<Type>::coef_
199 const DDt0Field<GeoField>&
ddt0
204 return 1 + ocCoeff();
214 template<
class GeoField>
215 scalar CrankNicolsonDdtScheme<Type>::coef0_
217 const DDt0Field<GeoField>&
ddt0
222 return 1 + ocCoeff();
232 template<
class GeoField>
235 const DDt0Field<GeoField>&
ddt0
243 template<
class GeoField>
246 const DDt0Field<GeoField>&
ddt0
254 template<
class GeoField>
255 tmp<GeoField> CrankNicolsonDdtScheme<Type>::offCentre_
262 return ocCoeff()*
ddt0;
287 ocCoeff_(new Function1s::Constant<scalar>(
"ocCoeff", 1))
307 token firstToken(is);
313 if (ocCoeff < 0 || ocCoeff > 1)
316 <<
"Off-centreing coefficient = " <<
ocCoeff
317 <<
" should be >= 0 and <= 1"
356 DDt0Field<VolField<Type>>&
ddt0 =
357 ddt0_<VolField<Type>>
359 "ddt0(" + dt.
name() +
')',
363 const word ddtName(
"ddt(" + dt.
name() +
')');
388 ddt0.internalFieldRef() =
395 tdtdt.
ref().internalFieldRef() =
398 -
mesh().
V0()*offCentre_(
ddt0.internalField())
413 DDt0Field<VolField<Type>>&
ddt0 =
414 ddt0_<VolField<Type>>
416 "ddt0(" + vf.
name() +
')',
420 const word ddtName(
"ddt(" + vf.
name() +
')');
428 const scalar rDtCoef0 = rDtCoef0_(
ddt0).value();
430 ddt0.primitiveFieldRef() =
439 ddt0.boundaryFieldRef() =
444 - vf.
oldTime().oldTime().boundaryField()
445 ) - offCentre_(
ff(
ddt0.boundaryField()))
457 ) -
mesh().V0()*offCentre_(
ddt0()())
462 ) - offCentre_(
ff(
ddt0.boundaryField()))
470 - offCentre_(
ddt0());
490 DDt0Field<VolField<Type>>&
ddt0 =
491 ddt0_<VolField<Type>>
493 "ddt0(" +
rho.name() +
',' + vf.
name() +
')',
497 const word ddtName(
"ddt(" +
rho.name() +
',' + vf.
name() +
')');
505 const scalar rDtCoef0 = rDtCoef0_(
ddt0).value();
507 ddt0.primitiveFieldRef() =
509 rDtCoef0*
rho.value()*
516 ddt0.boundaryFieldRef() =
518 rDtCoef0*
rho.value()*
521 - vf.
oldTime().oldTime().boundaryField()
522 ) - offCentre_(
ff(
ddt0.boundaryField()))
534 ) -
mesh().V0()*offCentre_(
ddt0())()
539 ) - offCentre_(
ff(
ddt0.boundaryField()))
547 - offCentre_(
ddt0());
567 DDt0Field<VolField<Type>>&
ddt0 =
568 ddt0_<VolField<Type>>
570 "ddt0(" +
rho.name() +
',' + vf.
name() +
')',
574 const word ddtName(
"ddt(" +
rho.name() +
',' + vf.
name() +
')');
582 const scalar rDtCoef0 = rDtCoef0_(
ddt0).value();
584 ddt0.primitiveFieldRef() =
588 mesh().
V0()*
rho.oldTime().primitiveField()
590 -
mesh().
V00()*
rho.oldTime().oldTime().primitiveField()
591 *vf.
oldTime().oldTime().primitiveField()
595 ddt0.boundaryFieldRef() =
599 rho.oldTime().boundaryField()
601 -
rho.oldTime().oldTime().boundaryField()
602 *vf.
oldTime().oldTime().boundaryField()
603 ) - offCentre_(
ff(
ddt0.boundaryField()))
616 ) -
mesh().V00()*offCentre_(
ddt0())()
621 -
rho.oldTime().boundaryField()*vf.
oldTime().boundaryField()
622 ) - offCentre_(
ff(
ddt0.boundaryField()))
632 -
rho.oldTime().oldTime()*vf.
oldTime().oldTime()
633 ) - offCentre_(
ddt0());
654 DDt0Field<VolField<Type>>&
ddt0 =
655 ddt0_<VolField<Type>>
657 "ddt0(" +
alpha.name() +
',' +
rho.name() +
',' + vf.
name() +
')',
663 "ddt(" +
alpha.name() +
',' +
rho.name() +
',' + vf.
name() +
')'
672 const scalar rDtCoef0 = rDtCoef0_(
ddt0).value();
674 ddt0.primitiveFieldRef() =
679 *
alpha.oldTime().primitiveField()
680 *
rho.oldTime().primitiveField()
684 *
alpha.oldTime().oldTime().primitiveField()
685 *
rho.oldTime().oldTime().primitiveField()
686 *vf.
oldTime().oldTime().primitiveField()
690 ddt0.boundaryFieldRef() =
694 alpha.oldTime().boundaryField()
695 *
rho.oldTime().boundaryField()
698 -
alpha.oldTime().oldTime().boundaryField()
699 *
rho.oldTime().oldTime().boundaryField()
700 *vf.
oldTime().oldTime().boundaryField()
701 ) - offCentre_(
ff(
ddt0.boundaryField()))
713 ) -
mesh().V00()*offCentre_(
ddt0())()
717 alpha.boundaryField()
721 -
alpha.oldTime().boundaryField()
722 *
rho.oldTime().boundaryField()
724 ) - offCentre_(
ff(
ddt0.boundaryField()))
737 -
alpha.oldTime().oldTime()
738 *
rho.oldTime().oldTime()
740 ) - offCentre_(
ddt0());
764 DDt0Field<VolField<Type>>&
ddt0 =
765 ddt0_<VolField<Type>>
767 "ddt0(" + vf.
name() +
')',
782 const scalar rDtCoef = rDtCoef_(
ddt0).value();
791 const scalar rDtCoef0 = rDtCoef0_(
ddt0).value();
793 ddt0.primitiveFieldRef() =
803 ddt0.boundaryFieldRef() =
808 - vf.
oldTime().oldTime().boundaryField()
810 - offCentre_(
ff(
ddt0.boundaryField()))
816 rDtCoef*vf.
oldTime().primitiveField()
817 + offCentre_(
ddt0.primitiveField())
825 - offCentre_(
ddt0());
830 rDtCoef*vf.
oldTime().primitiveField()
831 + offCentre_(
ddt0.primitiveField())
847 DDt0Field<VolField<Type>>&
ddt0 =
848 ddt0_<VolField<Type>>
850 "ddt0(" +
rho.name() +
',' + vf.
name() +
')',
864 const scalar rDtCoef = rDtCoef_(
ddt0).value();
873 const scalar rDtCoef0 = rDtCoef0_(
ddt0).value();
875 ddt0.primitiveFieldRef() =
877 rDtCoef0*
rho.value()*
885 ddt0.boundaryFieldRef() =
887 rDtCoef0*
rho.value()*
890 - vf.
oldTime().oldTime().boundaryField()
892 - offCentre_(
ff(
ddt0.boundaryField()))
898 rDtCoef*
rho.value()*vf.
oldTime().primitiveField()
899 + offCentre_(
ddt0.primitiveField())
907 - offCentre_(
ddt0());
912 rDtCoef*
rho.value()*vf.
oldTime().primitiveField()
913 + offCentre_(
ddt0.primitiveField())
929 DDt0Field<VolField<Type>>&
ddt0 =
930 ddt0_<VolField<Type>>
932 "ddt0(" +
rho.name() +
',' + vf.
name() +
')',
946 const scalar rDtCoef = rDtCoef_(
ddt0).value();
950 rho.oldTime().oldTime();
956 const scalar rDtCoef0 = rDtCoef0_(
ddt0).value();
958 ddt0.primitiveFieldRef() =
962 mesh().
V0()*
rho.oldTime().primitiveField()
964 -
mesh().
V00()*
rho.oldTime().oldTime().primitiveField()
965 *vf.
oldTime().oldTime().primitiveField()
970 ddt0.boundaryFieldRef() =
974 rho.oldTime().boundaryField()
976 -
rho.oldTime().oldTime().boundaryField()
977 *vf.
oldTime().oldTime().boundaryField()
979 - offCentre_(
ff(
ddt0.boundaryField()))
985 rDtCoef*
rho.oldTime().primitiveField()*vf.
oldTime().primitiveField()
986 + offCentre_(
ddt0.primitiveField())
996 -
rho.oldTime().oldTime()*vf.
oldTime().oldTime()
997 ) - offCentre_(
ddt0());
1002 rDtCoef*
rho.oldTime().primitiveField()*vf.
oldTime().primitiveField()
1003 + offCentre_(
ddt0.primitiveField())
1011 template<
class Type>
1020 DDt0Field<VolField<Type>>&
ddt0 =
1021 ddt0_<VolField<Type>>
1023 "ddt0(" +
alpha.name() +
',' +
rho.name() +
',' + vf.
name() +
')',
1041 const scalar rDtCoef = rDtCoef_(
ddt0).value();
1045 alpha.oldTime().oldTime();
1046 rho.oldTime().oldTime();
1048 if (
mesh().moving())
1052 const scalar rDtCoef0 = rDtCoef0_(
ddt0).value();
1054 ddt0.primitiveFieldRef() =
1059 *
alpha.oldTime().primitiveField()
1060 *
rho.oldTime().primitiveField()
1061 *vf.
oldTime().primitiveField()
1064 *
alpha.oldTime().oldTime().primitiveField()
1065 *
rho.oldTime().oldTime().primitiveField()
1066 *vf.
oldTime().oldTime().primitiveField()
1071 ddt0.boundaryFieldRef() =
1075 alpha.oldTime().boundaryField()
1076 *
rho.oldTime().boundaryField()
1079 -
alpha.oldTime().oldTime().boundaryField()
1080 *
rho.oldTime().oldTime().boundaryField()
1081 *vf.
oldTime().oldTime().boundaryField()
1083 - offCentre_(
ff(
ddt0.boundaryField()))
1090 *
alpha.oldTime().primitiveField()
1091 *
rho.oldTime().primitiveField()
1092 *vf.
oldTime().primitiveField()
1093 + offCentre_(
ddt0.primitiveField())
1106 -
alpha.oldTime().oldTime()
1107 *
rho.oldTime().oldTime()
1109 ) - offCentre_(
ddt0());
1115 *
alpha.oldTime().primitiveField()
1116 *
rho.oldTime().primitiveField()
1117 *vf.
oldTime().primitiveField()
1118 + offCentre_(
ddt0.primitiveField())
1126 template<
class Type>
1134 DDt0Field<VolField<Type>>&
ddt0 =
1135 ddt0_<VolField<Type>>
1137 "ddtCorrDdt0(" +
U.name() +
')',
1141 DDt0Field<SurfaceField<Type>>& dUfdt0 =
1142 ddt0_<SurfaceField<Type>>
1144 "ddtCorrDdt0(" + Uf.
name() +
')',
1153 rDtCoef0_(
ddt0)*(
U.oldTime() -
U.oldTime().oldTime())
1154 - offCentre_(
ddt0());
1161 - offCentre_(dUfdt0());
1166 "ddtCorr(" +
U.name() +
',' + Uf.
name() +
')',
1167 this->fvcDdtPhiCoeff(
U.oldTime(),
mesh().Sf() & Uf.
oldTime())
1171 (rDtCoef*Uf.
oldTime() + offCentre_(dUfdt0()))
1179 template<
class Type>
1187 DDt0Field<VolField<Type>>&
ddt0 =
1188 ddt0_<VolField<Type>>
1190 "ddtCorrDdt0(" +
U.name() +
')',
1194 DDt0Field<fluxFieldType>& dphidt0 =
1195 ddt0_<fluxFieldType>
1197 "ddtCorrDdt0(" + phi.
name() +
')',
1206 rDtCoef0_(
ddt0)*(
U.oldTime() -
U.oldTime().oldTime())
1207 - offCentre_(
ddt0());
1214 - offCentre_(dphidt0());
1219 "ddtCorr(" +
U.name() +
',' + phi.
name() +
')',
1220 this->fvcDdtPhiCoeff(
U.oldTime(), phi.
oldTime())
1222 (rDtCoef*phi.
oldTime() + offCentre_(dphidt0()))
1226 rDtCoef*
U.oldTime() + offCentre_(
ddt0())
1233 template<
class Type>
1248 DDt0Field<VolField<Type>>&
ddt0 =
1249 ddt0_<VolField<Type>>
1251 "ddtCorrDdt0(" +
rho.name() +
',' +
U.name() +
')',
1252 rho.dimensions()*
U.dimensions()
1255 DDt0Field<SurfaceField<Type>>& drhoUfdt0 =
1256 ddt0_<SurfaceField<Type>>
1258 "ddtCorrDdt0(" + rhoUf.
name() +
')',
1266 rho.oldTime()*
U.oldTime()
1273 *(rhoU0 -
rho.oldTime().oldTime()*
U.oldTime().oldTime())
1274 - offCentre_(
ddt0());
1280 rDtCoef0_(drhoUfdt0)
1282 - offCentre_(drhoUfdt0());
1287 "ddtCorr(" +
rho.name() +
',' +
U.name() +
',' + rhoUf.
name() +
')',
1288 this->fvcDdtPhiCoeff
1297 (rDtCoef*rhoUf.
oldTime() + offCentre_(drhoUfdt0()))
1309 DDt0Field<VolField<Type>>&
ddt0 =
1310 ddt0_<VolField<Type>>
1312 "ddtCorrDdt0(" +
U.name() +
')',
1316 DDt0Field<SurfaceField<Type>>& drhoUfdt0 =
1317 ddt0_<SurfaceField<Type>>
1319 "ddtCorrDdt0(" + rhoUf.
name() +
')',
1328 rDtCoef0_(
ddt0)*(
U.oldTime() -
U.oldTime().oldTime())
1329 - offCentre_(
ddt0());
1335 rDtCoef0_(drhoUfdt0)
1337 - offCentre_(drhoUfdt0());
1342 "ddtCorr(" +
U.name() +
',' + rhoUf.
name() +
')',
1343 this->fvcDdtPhiCoeff
1352 (rDtCoef*rhoUf.
oldTime() + offCentre_(drhoUfdt0()))
1355 rDtCoef*
U.oldTime() + offCentre_(
ddt0())
1364 <<
"dimensions of rhoUf are not correct"
1367 return fluxFieldType::null();
1372 template<
class Type>
1387 DDt0Field<VolField<Type>>&
ddt0 =
1388 ddt0_<VolField<Type>>
1390 "ddtCorrDdt0(" +
rho.name() +
',' +
U.name() +
')',
1391 rho.dimensions()*
U.dimensions()
1394 DDt0Field<fluxFieldType>& dphidt0 =
1395 ddt0_<fluxFieldType>
1397 "ddtCorrDdt0(" + phi.
name() +
')',
1405 rho.oldTime()*
U.oldTime()
1412 *(rhoU0 -
rho.oldTime().oldTime()*
U.oldTime().oldTime())
1413 - offCentre_(
ddt0());
1421 - offCentre_(dphidt0());
1426 "ddtCorr(" +
rho.name() +
',' +
U.name() +
',' + phi.
name() +
')',
1427 this->fvcDdtPhiCoeff(rhoU0, phi.
oldTime(),
rho.oldTime())
1429 (rDtCoef*phi.
oldTime() + offCentre_(dphidt0()))
1433 rDtCoef*rhoU0 + offCentre_(
ddt0())
1444 DDt0Field<VolField<Type>>&
ddt0 =
1445 ddt0_<VolField<Type>>
1447 "ddtCorrDdt0(" +
U.name() +
')',
1451 DDt0Field<fluxFieldType>& dphidt0 =
1452 ddt0_<fluxFieldType>
1454 "ddtCorrDdt0(" + phi.
name() +
')',
1463 rDtCoef0_(
ddt0)*(
U.oldTime() -
U.oldTime().oldTime())
1464 - offCentre_(
ddt0());
1471 - offCentre_(dphidt0());
1476 "ddtCorr(" +
U.name() +
',' + phi.
name() +
')',
1477 this->fvcDdtPhiCoeff(
U.oldTime(), phi.
oldTime(),
rho.oldTime())
1479 (rDtCoef*phi.
oldTime() + offCentre_(dphidt0()))
1483 rDtCoef*
U.oldTime() + offCentre_(
ddt0())
1491 <<
"dimensions of phi are not correct"
1494 return fluxFieldType::null();
1499 template<
class Type>
1505 DDt0Field<surfaceScalarField>& meshPhi0 =
1506 ddt0_<surfaceScalarField>(
"meshPhi0",
dimVolume);
1511 coef0_(meshPhi0)*
mesh().
phi().
oldTime() - offCentre_(meshPhi0());
1517 coef_(meshPhi0)*
mesh().phi() - offCentre_(meshPhi0())
1522 template<
class Type>
1529 DDt0Field<surfaceScalarField>& meshPhi0 =
1530 ddt0_<surfaceScalarField>(
"meshPhi0",
dimVolume);
1535 coef0_(meshPhi0)*
mesh().
phi().
oldTime() - offCentre_(meshPhi0());
1540 coef_(meshPhi0)*
mesh().phi().boundaryField()[
patchi]
const dimensionSet & dimensions() const
Return dimensions.
static autoPtr< Function1< Type > > New(const word &name, const Function1s::unitConversions &units, const dictionary &dict)
Select from dictionary.
Templated function that returns a constant value.
Generic GeometricField class.
const Boundary & boundaryField() const
Return const-reference to the boundary field.
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...
const word & name() const
Return name.
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
void putBack(const token &)
Put back token.
const Field0Type & oldTime() const
Return the old-time field.
label timeIndex() const
Return current time index.
dimensionedScalar deltaT0() const
Return old time step.
dimensionedScalar deltaT() const
Return time step.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
const unitConversion & userUnits() const
Return the user-time unit conversion.
virtual dimensionedScalar startTime() const
Return start time.
static word timeName(const scalar, const int precision=curPrecision_)
Return time name of given scalar time.
virtual label startTimeIndex() const
Return start time index.
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Dimension set for the base types.
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....
Mesh data needed to do the Finite Volume discretisation.
const Time & time() const
Return the top-level database.
const DimensionedField< scalar, volMesh > & V() const
Return cell volumes.
const DimensionedField< scalar, volMesh > & V00() const
Return old-old-time cell volumes.
const surfaceScalarField & phi() const
Return cell face motion fluxes.
const DimensionedField< scalar, volMesh > & V0() const
Return old-time cell volumes.
Second-oder Crank-Nicolson implicit ddt using the current and previous time-step fields as well as th...
virtual tmp< fvMatrix< Type > > fvmDdt(const VolField< Type > &)
const fvMesh & mesh() const
Return mesh reference.
scalar ocCoeff() const
Return the current off-centering coefficient.
virtual tmp< fluxFieldType > fvcDdtPhiCorr(const VolField< Type > &U, const fluxFieldType &phi)
virtual tmp< surfaceScalarField > meshPhi(const VolField< Type > &)
virtual tmp< fluxFieldType > fvcDdtUfCorr(const VolField< Type > &U, const SurfaceField< Type > &Uf)
void operator=(const CrankNicolsonDdtScheme &)=delete
Disallow default bitwise assignment.
virtual tmp< VolField< Type > > fvcDdt(const dimensioned< Type > &)
CrankNicolsonDdtScheme(const fvMesh &mesh)
Construct from mesh.
Abstract base class for ddt schemes.
bool moving() const
Is mesh moving.
void store()
Transfer ownership of this object to its registry.
A class for managing temporary objects.
T & ref() const
Return non-const reference or generate a fatal error.
A token holds items read from Istream.
Templated form of IOobject providing type information for file reading and header type checking.
A class for handling words, derived from string.
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
A special matrix type and solver, designed for finite volume solutions of scalar equations.
Calculate the divergence of the given field.
volScalarField alpha(IOobject("alpha", runTime.name(), mesh, IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE), lambda *max(Ua &U, zeroSensitivity))
tmp< LagrangianEqn< Type > > ddt0(const LagrangianSubScalarField &deltaT, const LagrangianSubSubField< Type > &psi)
autoPtr< CompressibleMomentumTransportModel > New(const volScalarField &rho, const volVectorField &U, const surfaceScalarField &phi, const viscosity &viscosity)
const FieldField< volMesh::PatchField, Type > & ff(const FieldField< volMesh::PatchField, Type > &bf)
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.
errorManipArg< error, int > exit(error &err, const int errNo=1)
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
const dimensionSet dimVolumetricFlux
errorManip< error > abort(error &err)
const dimensionSet dimTime
void evaluate(GeometricField< Type, GeoMesh > &result, const Function1< Type > &func, const GeometricField< Type, GeoMesh > &x)
const dimensionSet dimVolume
word typedName(Name name)
Return the name of the object within the given type.
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
const dimensionSet dimVelocity
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
const unitConversion unitFraction