CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   OpenFOAM Programming & Development (https://www.cfd-online.com/Forums/openfoam-programming-development/)
-   -   The effect of write precision on CFD solution with codeStream (https://www.cfd-online.com/Forums/openfoam-programming-development/241194-effect-write-precision-cfd-solution-codestream.html)

theBananaTrick February 13, 2022 13:01

The effect of write precision on CFD solution with codeStream
 
Hi,

Following my previous post, https://www.cfd-online.com/Forums/op...operators.html, I met another "funny" thing. I am new to OF and did not find this information anywhere so I decided to share it. I am using OF2106.

If one is using codeStream/setExprField, and I guess coded boundaries conditions. The writePrecision parameter in controlDict can have some significance!

I have the following codestream code for defining the internalField in p:
Code:


dimensions      [1 -1 -2 0 0 0 0];

internalField nonuniform #codeStream
{
    codeInclude
    #{
        #include "fvCFD.H"
    #};

    codeOptions
    #{
        -I$(LIB_SRC)/finiteVolume/lnInclude \
        -I$(LIB_SRC)/meshTools/lnInclude
    #};

    codeLibs
    #{
        -lmeshTools \
        -lfiniteVolume
    #};

    code
    #{
        const IOdictionary& d = static_cast<const IOdictionary&>(dict);
        const fvMesh& mesh = refCast<const fvMesh>(d.db());
        scalarField myInteriorField(mesh.nCells(), 0.0);
        const volVectorField& C = mesh.C();

        forAll(myInteriorField, cellI)
        {
            const scalar x = C[cellI].x();
            const scalar y = C[cellI].y();
            const scalar tmp0 = (5.0/4.0)*M_PI;
            myInteriorField[cellI] = 1000.0*Foam::sin(tmp0*y) + 1000.0*Foam::cos(tmp0*x) + 100000.0;
        }

        os.writeEntry("", myInteriorField);
    #};
};

Inside the code I am computing the difference between a dummy field and the pressure field. The dummy field has the same value as the pressureField.
Code:


const volVectorField& C = mesh.C();

volScalarField dummyField
(
    IOobject
    (
        "dummyField",
        runTime.timeName(),
        mesh,
        IOobject::NO_READ,
        IOobject::AUTO_WRITE
    ),
    mesh,
    dimensionedScalar("dummyScalar", dimless, 0.0)
);

forAll(dummyField,  cellI)         
    {                             
        const scalar x = C[cellI].x();
        const scalar y = C[cellI].y();
                           
        const scalar tmp0 = (5.0/4.0)*M_PI;
        const scalar solution = 1000.0*Foam::sin(tmp0*y) + 1000.0*Foam::cos(tmp0*x) + 100000.0;
                                                               
        dummyField[cellI] = mag(solution - p[cellI]);
    }

And finally computing the L2 error norm as:

Code:

const scalarField& V = mesh.V(); 

Info << "Error is "    << Foam::sqrt( gSum(dummyField*dummyField*V)/gSum(V) )    << endl;

One would expect for the norm to be zero.. but the value differs depending on the value of writePrecision... The default value is 6, so if I proceed I will get a L2 value of 0.22. I only get a value of 0 with 17 decimal cases. I was under the impression that writePrecision would control the amount of decimal cases for output information of the field. But apparently it also has an effect on the input given.

olesen February 16, 2022 13:10

You need to adjust your expectations and/or find another way to handle the problem. The codeStream bits work by outputting to StringStream and then reparsing that to get tokens to populate the dictionary contents. These are the tokens that are actually used to populate the field.



Yes, you are correct to think that this sounds ugly!

quarkz April 7, 2022 02:11

Hi,

I just found this out too after a week plus of debugging. Besides increasing precision for writePrecision and maybe timePrecision, there may also be a need to increase the read/write precision for reading/writing files:

Code:

while(MyReadFile.good() && (getline(MyReadFile, line)))
                        {
                                istringstream iss(line);

                                iss >> std::fixed >> std::setprecision(8) >> time_saved >> old_incoming_vel;

                        }

                        MyReadFile.close();

This is because default c++ precision is also 6. Hope this helps.


All times are GMT -4. The time now is 00:01.