View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0003000 | OpenFOAM | Bug | public | 2018-07-05 16:48 | 2018-07-06 10:50 |
Reporter | cvr | Assigned To | henry | ||
Priority | normal | Severity | major | Reproducibility | have not tried |
Status | closed | Resolution | no change required | ||
Platform | GNU/Linux | OS | Debian | OS Version | 4.9.88-1+deb9u1 |
Summary | 0003000: Pressure-velocity coupling in transient simulation: ddtCorr(U, phi) and fvcDdtUfCorr | ||||
Description | I am studying a bit of some pressure-coupling procedures used in OpenFOAM. For the moment I am using version 4.x in github but I have confirmed that version 5.x shares the same formulation. I've come across some parts of the code which I'm not fully grasping. In several transient solvers (including icoFoam, which I'll use as reference here for simplicity) the phiHbyA field is the flux of HbyA (thus interpolation to faces and dot product with respective face normal vector) and a correction to avoid an unwanted dependency on the time-step (following Choi (1999) Numerical Heat Transfer A, 36:545-550 and discussed also in Yu et al (2002) Numerical Heat Transfer B, 42:141-166). In solvers/incompressible/icoFoam/icoFoam.C we find: ________________________________ volScalarField rAU(1.0/UEqn.A()); volVectorField HbyA(constrainHbyA(rAU*UEqn.H(), U, p)); surfaceScalarField phiHbyA ( "phiHbyA", fvc::flux(HbyA) + fvc::interpolate(rAU)*fvc::ddtCorr(U, phi) ); ________________________________ So we have phiHbyA as the flux of HbyA and a correction related to the times cheme used, ddtCorr(U, phi). Correct me if I'm wrong: in practice as as this is an incompressible solver, phi = Uf·Sf, meaning the mass flux and so it is a quantity defined at each face (i.e. phi = fvc::interpolate(U) & mesh.Sf()). In finiteVolume/finiteVolume/fvc/fvcDdt.C: ________________________________ ddtCorr ( const GeometricField<Type, fvPatchField, volMesh>& U, const GeometricField<Type, fvsPatchField, surfaceMesh>& Uf ) { return fv::ddtScheme<Type>::New ( U.mesh(), U.mesh().ddtScheme("ddt(" + U.name() + ')') ).ref().fvcDdtUfCorr(U, Uf); } ________________________________ Following the source code and going to a simple time scheme such as Euler to better grasp what is going on, in finiteVolume/finiteVolume/ddtSchemes/EulerDdtScheme/EulerDdtScheme.C: ________________________________ EulerDdtScheme<Type>::fvcDdtUfCorr ( const GeometricField<Type, fvPatchField, volMesh>& U, const GeometricField<Type, fvsPatchField, surfaceMesh>& Uf ) { dimensionedScalar rDeltaT = 1.0/mesh().time().deltaT(); fluxFieldType phiUf0(mesh().Sf() & Uf.oldTime()); fluxFieldType phiCorr ( phiUf0 - fvc::dotInterpolate(mesh().Sf(), U.oldTime()) ); return tmp<fluxFieldType> ( new fluxFieldType ( IOobject ( "ddtCorr(" + U.name() + ',' + Uf.name() + ')', mesh().time().timeName(), mesh() ), this->fvcDdtPhiCoeff(U.oldTime(), phiUf0, phiCorr) *rDeltaT*phiCorr ) ); } ________________________________ Keeping the original names of the arguments, in the above expressions we start with: 1. ddtCorr(U, phi), which leads to 2. fvcDdtUfCorr(U, phi), then to 3. Sf & phi.oldTime, and lastly 4. Sf & phi.oldTime - Sf & interpolate(U.oldTime) Considering phi = Sf & interpolate(U), then the 3rd and 4th step would be substituted by Sf & (Sf & interpolate(U).oldTime), thus phi is being multiplied twice by Sf, which seems incorrect. So either there is something I'm failing to grasp or there is an erroneous dot product of a scalar (phi) with the face-area vector (Sf). | ||||
Additional Information | If confirmed, this affects all of the time *DdtScheme.C files in finiteVolume/finiteVolume/ddtSchemes/, namely: CoEulerDdtScheme/CoEulerDdtScheme.C EulerDdtScheme/EulerDdtScheme.C backwardDdtScheme/backwardDdtScheme.C SLTSDdtScheme/SLTSDdtScheme.C CrankNicolsonDdtScheme/CrankNicolsonDdtScheme.C localEulerDdtScheme/localEulerDdtScheme.C The simplest way to solve this (without changing anything) would be to feed the face-velocity vector field to ddtCorr, so ddtCorr(U, Uf) instead of ddtCorr(U, phi). Even so, the ddtCorr would still be affected by fvcDdtPhiCoeff procedure (which was described as an ad-hoc inclusion due to the fact that fvcDdtPhiCoeff=1 would result in instabilities, vide www.cfd-online.com/Forums/openfoam-solving/60096-ddtphicorr.html#post516511). Another way would be to change in each of the *DdtScheme.C file the "phiUf0(mesh().Sf() & Uf.oldTime())" line to "phiUf0(Uf.oldtime())" and to remove the call to "fvcDdtPhiCoeff". | ||||
Tags | pimpleControl, pressure-velocity coupling | ||||
Date Modified | Username | Field | Change |
---|---|---|---|
2018-07-05 16:48 | cvr | New Issue | |
2018-07-05 16:48 | cvr | Tag Attached: pimpleControl | |
2018-07-05 16:48 | cvr | Tag Attached: pressure-velocity coupling | |
2018-07-05 17:22 | henry | Assigned To | => henry |
2018-07-05 17:22 | henry | Status | new => closed |
2018-07-05 17:22 | henry | Resolution | open => no change required |
2018-07-05 17:22 | henry | Note Added: 0009843 |