|
[Sponsors] |
September 29, 2022, 13:43 |
Implement backward time scheme manually
|
#1 |
Senior Member
|
Suppose the backward ddtSchme is used in fvSchemes file, then we can assemble the momentum equation as follows:
Code:
fvVectorMatrix UEqn ( fvm::ddt(U) + fvm::div(phi, U) + turbulence->divDevReff(U) == - fvc::grad(p) ); Code:
fvVectorMatrix UEqn ( fvm::div(phi, U) + turbulence->divDevReff(U) == - fvc::grad(p) - fvm::Sp(1.5/dt, U) + (2*U.oldTime() - U.oldTime().oldTime())/dt ); Regards, Michael |
|
September 30, 2022, 01:11 |
|
#2 | |
Member
Join Date: Jan 2022
Location: Germany
Posts: 72
Rep Power: 4 |
Quote:
Code:
fvVectorMatrix UEqn ( fvm::div(phi, U) + turbulence->divDevReff(U) == - fvc::grad(p) - fvm::Sp(1.5/dt, U) + (2*U.oldTime() - 0.5*U.oldTime(2))/dt ); |
||
September 30, 2022, 11:37 |
|
#3 |
Senior Member
|
überschwupper, thank you for your reply! Yes, I missed the factor of 0.5. It's good to know the syntax of U.oldTime(2), but it seems to be not available in OF v2106. What version are you using?
I found there is still a difference between the two approaches. Code:
fvVectorMatrix UEqn ( fvm::Sp(1.5/dt, U) == (2*U.oldTime() - 0.5*U.oldTime(2)/dt // U.oldTime(2) not available though in OFv2106 ); fvVectorMatrix UEqnDdt ( fvm::ddt(U) // backward in controlDict ); Info << UEqnDdt - UEqn << endl; Info << UEqnDdt.source() - UEqn.source() << endl; How does it come? |
|
October 12, 2022, 05:16 |
|
#4 |
Member
Join Date: Jan 2022
Location: Germany
Posts: 72
Rep Power: 4 |
sorry for the late reply, have you found a solution?
I checked the API Guide, unfortunately the ESI Version has not the overloaded function of oldTimes(). In OFv9 there is such a function. - deleted some part, I will again think about it Last edited by überschwupper; October 12, 2022 at 05:25. Reason: deleted (havent read precisely) |
|
October 12, 2022, 10:51 |
|
#5 |
Senior Member
|
I should have mentioned that I only tested for the first time step.
In the source code of ddt(backward) at https://www.openfoam.com/documentati...ce.html#l00444 Code:
template<class Type> tmp<fvMatrix<Type>> backwardDdtScheme<Type>::fvmDdt ( const GeometricField<Type, fvPatchField, volMesh>& vf ) { tmp<fvMatrix<Type>> tfvm ( new fvMatrix<Type> ( vf, vf.dimensions()*dimVol/dimTime ) ); fvMatrix<Type>& fvm = tfvm.ref(); scalar rDeltaT = 1.0/deltaT_(); scalar deltaT = deltaT_(); scalar deltaT0 = deltaT0_(vf); scalar coefft = 1 + deltaT/(deltaT + deltaT0); scalar coefft00 = deltaT*deltaT/(deltaT0*(deltaT + deltaT0)); scalar coefft0 = coefft + coefft00; fvm.diag() = (coefft*rDeltaT)*mesh().V(); if (mesh().moving()) { fvm.source() = ... } else { fvm.source() = ... } return tfvm; } coefft = 1 + deltaT/(deltaT + deltaT0) = 1.5 coefft00 = deltaT*deltaT/(deltaT0*(deltaT + deltaT0)) = 0.5 coefft0 = coefft + coefft0 = 2.0 fvm.diag() = (coefft*rDeltaT)*mesh().V() = However, in the manually implemented version fvm::Sp(1.5/dt, U) will be set the diagonal entry to be fvm.diag() = Here is a difference , which partially explains why they are different, though I found the difference is twice of this one. Please let me know if you found some errors in my derivation or have any thoughts. |
|
October 13, 2022, 04:40 |
|
#7 | |
Member
Join Date: Jan 2022
Location: Germany
Posts: 72
Rep Power: 4 |
Quote:
I was also looking inside the code, but had no time yesterday. I have found an error. You made an mistake while setting in values inside the code equation. The factor is 1.5 not 2.0. It is correct at this point. there has to be another reason, Maybe treatment of Sp()? I hope finding time to dig into it this evening |
||
October 13, 2022, 09:52 |
|
#8 |
Senior Member
|
That's good catch! I did not notice that it is coefft not coefft0 is used to calculate the diagonal entries.
fvm.diag() = (coefft*rDeltaT)*mesh().V(); The questions remain. At the first time step, Backward scheme in OpenFOAM actually is which is not expected. Still need to figure out why there is the difference between OpenFOAM and the manual implementation. |
|
October 13, 2022, 10:20 |
|
#9 |
Senior Member
|
I just noticed
Code:
scalar deltaT0 = deltaT0_(vf); Code:
scalar coefft = 1 + deltaT/(deltaT + deltaT0) Code:
template<class Type> template<class GeoField> scalar backwardDdtScheme<Type>::deltaT0_(const GeoField& vf) const { if (mesh().time().timeIndex() < 2) { return GREAT; } else { return deltaT0_(); } } |
|
October 13, 2022, 10:51 |
|
#10 |
Member
Join Date: Jan 2022
Location: Germany
Posts: 72
Rep Power: 4 |
Quote:
Good job! i was thinking that this was a definition and not a function call.. But deltaT0 is GREAT and GREAT is 10^6, which would set coefft to 1, coeft00 becomes zero for time indizes below 2, which is logical. The difference between both is then dependend on what ever oldTime() is storing in the first time steps. Since every time step afterwards is dependend on the previous ones, the error is accumulating. |
|
October 17, 2022, 17:03 |
|
#11 |
Senior Member
|
I just confirmed the difference between the two implementations for the first time step:
backward in OpenFOAM turns to be Euler, so ap1 = source1 = manually backward implementation ap2 = source2 = The following is confirmed. ap2 - ap1 = source2 - source1 = This means my explicit implementation of fvm::ddt(backward) is correct but remedy should be introduced for the first time step as OpenFoam does. |
|
Tags |
backward time scheme |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
courant number increases to rather large values | 6863523 | OpenFOAM Running, Solving & CFD | 22 | July 5, 2023 23:48 |
laplacianFoam with source term | Herwig | OpenFOAM Running, Solving & CFD | 17 | November 19, 2019 13:47 |
Inconsistencies in reading .dat file during run time in new injection model | Scram_1 | OpenFOAM | 0 | March 23, 2018 22:29 |
mixerVesselAMI2D's mass is not balancing | sharonyue | OpenFOAM Running, Solving & CFD | 6 | June 10, 2013 09:34 |
Upgraded from Karmic Koala 9.10 to Lucid Lynx10.04.3 | bookie56 | OpenFOAM Installation | 8 | August 13, 2011 04:03 |