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/)
-   -   How the boundary conditions are called in the OpenFOAM solvers? (https://www.cfd-online.com/Forums/openfoam-programming-development/129271-how-boundary-conditions-called-openfoam-solvers.html)

openfoammaofnepo February 1, 2014 09:05

How the boundary conditions are called in the OpenFOAM solvers?
 
Dear All,

I was wondering how the boundary conditions subroutines are called ?

Let us take an example:

Code:

OpenFOAM/OpenFOAM-2.1.1/tutorials/compressible/rhoPimpleFoam/les/pitzDaily
In the file:

Code:

U/0
we have the following boundary conditions for the inlet:

Code:

    inlet
    {
        type            turbulentInlet;
        referenceField  uniform (10 0 0);
        fluctuationScale (0.02 0.01 0.01);
        value          uniform (10 0 0);
    }

Does anybody know in which part of the solver is calling the turbulentInlet's subroutine? I am asking this questions because I would like to implement my own BC type in openfoam.

Thank you in advance!

hjasak February 3, 2014 00:54

Easy:
- on correctBoundaryConditions() for a field
- on updateCoeffs() at matrix creation

correctBoundaryConditions is also called after the linear solver call automatically.


Enjoy,

Hrv

openfoammaofnepo February 3, 2014 11:16

Thank you so much, Hrvoje!

About the first one, I get it in the
Code:

src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.C
I can get the following lines of codes:
Code:

// Correct the boundary conditions
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::
correctBoundaryConditions()
{
    this->setUpToDate();
    storeOldTimes();
    boundaryField_.evaluate();
}

Here about the function evaluation(), I cannot find where it is defined. In the following source file:

Code:

src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.H
It is declared as

Code:

            //- Evaluate boundary conditions
            void evaluate();

But it is virtual function here. Could you please give me some hints about where it is defined assuming we are still talking about the turbulentInlet? Thank you very much.

openfoammaofnepo February 3, 2014 11:21

About the updateCoeffs in the turbulentInlet boundary conditions

Code:

OpenFOAM/OpenFOAM-2.1.1/src/finiteVolume/fields/fvPatchFields/derived/turbulentInlet
It has the following specific forms:
Code:

template<class Type>
void turbulentInletFvPatchField<Type>::updateCoeffs()
{
    if (this->updated())
    {
        return;
    }

    if (curTimeIndex_ != this->db().time().timeIndex())
    {
        Field<Type>& patchField = *this;

        Field<Type> randomField(this->size());

        forAll(patchField, facei)
        {
            ranGen_.randomise(randomField[facei]);
        }

        // Correction-factor to compensate for the loss of RMS fluctuation
        // due to the temporal correlation introduced by the alpha parameter.
        scalar rmsCorr = sqrt(12*(2*alpha_ - sqr(alpha_)))/alpha_;

        patchField =
            (1 - alpha_)*patchField
          + alpha_*
            (
                referenceField_
              + rmsCorr*cmptMultiply
                (
                    randomField - 0.5*pTraits<Type>::one,
                    fluctuationScale_
                )*mag(referenceField_)
            );

        curTimeIndex_ = this->db().time().timeIndex();
    }

    fixedValueFvPatchField<Type>::updateCoeffs();
}

In the above mentioned codes, the updateCoeffs() from the fixedValue boundary conditions type is used

Code:

fixedValueFvPatchField<Type>::updateCoeffs();
What is the role of this line? in the source files for fixedValue, I did not find any information about the relevant definitions there. Could anybody share some information about this problem? Thank you so much.

++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++
As a record how I understand this, I put the answer here:

evaluate() is defined in

Code:

src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C
The structure is:

Code:

template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricBoundaryField::
evaluate()
{
    if (debug)
    {
        Info<< "GeometricField<Type, PatchField, GeoMesh>::"
              "GeometricBoundaryField::"
              "evaluate()" << endl;
    }

    if
    (
        Pstream::defaultCommsType == Pstream::blocking
    || Pstream::defaultCommsType == Pstream::nonBlocking
    )
    {
        label nReq = Pstream::nRequests();

        forAll(*this, patchi)
        {
            this->operator[](patchi).initEvaluate(Pstream::defaultCommsType);
        }

        // Block for any outstanding requests
        if
        (
            Pstream::parRun()
        && Pstream::defaultCommsType == Pstream::nonBlocking
        )
        {
            Pstream::waitRequests(nReq);
        }

        forAll(*this, patchi)
        {
            this->operator[](patchi).evaluate(Pstream::defaultCommsType);
        }
    }
    else if (Pstream::defaultCommsType == Pstream::scheduled)
    {
        const lduSchedule& patchSchedule =
            bmesh_.mesh().globalData().patchSchedule();

        forAll(patchSchedule, patchEvali)
        {
            if (patchSchedule[patchEvali].init)
            {
                this->operator[](patchSchedule[patchEvali].patch)
                    .initEvaluate(Pstream::scheduled);
            }
            else
            {
                this->operator[](patchSchedule[patchEvali].patch)
                    .evaluate(Pstream::scheduled);

            }
        }
    }
    else
    {
        FatalErrorIn("GeometricBoundaryField::evaluate()")
            << "Unsuported communications type "
            << Pstream::commsTypeNames[Pstream::defaultCommsType]
            << exit(FatalError);
    }
}


openfoammaofnepo February 5, 2014 06:50

No Body also interested in this issue?

peteryuan February 5, 2014 09:27

As a newbie I asked a similar question in my latest post:
http://www.cfd-online.com/Forums/ope...tempratur.html
Quote:

"In externalCoupledMixedFvPatchField.C line 698 there is this evaluate() function defined. I supose that is the function at the top level and would do all the actual works for this class, like readData, writeData and so on. Now for example an object of this class is created with /0/T file and during runtime this evaluate() function is executed (I think). Could anyone tell me where is this function called during runtime? I use chtMultiRegionFoam, searched a lot in the code but still do not have a clue where this or any of the functions from that class is called. "
Here I find my key word "evaluate()":
Code:

correctBoundaryConditions() {
    this->setUpToDate();
    storeOldTimes();
    boundaryField_.evaluate(); }

I guess that all classes for BC have this .evaluate() member function... During runtime of a solver, after an object being created, the evaluate() functions are called with this correctBoundaryConditions(). Each BC class has a different .evaluate().
Am I right?

openfoammaofnepo February 5, 2014 17:33

Yes, I agree with you. I also did some digging into the source files. But do you know the role of the following lines:
Code:

fixedValueFvPatchField<Type>::updateCoeffs();

openfoammaofnepo February 20, 2014 15:46

I did not find this function in the source:

fixedValueFvPatchField.H

Sorry for my limit C++ skills. Does anybody know where I can find this function,
Code:

fixedValueFvPatchField<Type>::updateCoeffs();
?


Quote:

Originally Posted by openfoammaofnepo (Post 473643)
Yes, I agree with you. I also did some digging into the source files. But do you know the role of the following lines:
Code:

fixedValueFvPatchField<Type>::updateCoeffs();


hjasak February 20, 2014 16:02

Please read up on virtual functions - this is basic C++

Hrv

openfoammaofnepo April 10, 2014 06:30

For my record, actually, the following lines:

Code:

fixedValueFvPatchField<Type>::updateCoeffs();
did nothing but just to set the bool variable update() to be true.

The function updateCoeffs is defined in:

Code:

fvPatchField.H
Quote:

Originally Posted by openfoammaofnepo (Post 473156)
About the updateCoeffs in the turbulentInlet boundary conditions

Code:

OpenFOAM/OpenFOAM-2.1.1/src/finiteVolume/fields/fvPatchFields/derived/turbulentInlet
It has the following specific forms:
Code:

template<class Type>
void turbulentInletFvPatchField<Type>::updateCoeffs()
{
    if (this->updated())
    {
        return;
    }

    if (curTimeIndex_ != this->db().time().timeIndex())
    {
        Field<Type>& patchField = *this;

        Field<Type> randomField(this->size());

        forAll(patchField, facei)
        {
            ranGen_.randomise(randomField[facei]);
        }

        // Correction-factor to compensate for the loss of RMS fluctuation
        // due to the temporal correlation introduced by the alpha parameter.
        scalar rmsCorr = sqrt(12*(2*alpha_ - sqr(alpha_)))/alpha_;

        patchField =
            (1 - alpha_)*patchField
          + alpha_*
            (
                referenceField_
              + rmsCorr*cmptMultiply
                (
                    randomField - 0.5*pTraits<Type>::one,
                    fluctuationScale_
                )*mag(referenceField_)
            );

        curTimeIndex_ = this->db().time().timeIndex();
    }

    fixedValueFvPatchField<Type>::updateCoeffs();
}

In the above mentioned codes, the updateCoeffs() from the fixedValue boundary conditions type is used

Code:

fixedValueFvPatchField<Type>::updateCoeffs();
What is the role of this line? in the source files for fixedValue, I did not find any information about the relevant definitions there. Could anybody share some information about this problem? Thank you so much.

++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++
As a record how I understand this, I put the answer here:

evaluate() is defined in

Code:

src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C
The structure is:

Code:

template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricBoundaryField::
evaluate()
{
    if (debug)
    {
        Info<< "GeometricField<Type, PatchField, GeoMesh>::"
              "GeometricBoundaryField::"
              "evaluate()" << endl;
    }

    if
    (
        Pstream::defaultCommsType == Pstream::blocking
    || Pstream::defaultCommsType == Pstream::nonBlocking
    )
    {
        label nReq = Pstream::nRequests();

        forAll(*this, patchi)
        {
            this->operator[](patchi).initEvaluate(Pstream::defaultCommsType);
        }

        // Block for any outstanding requests
        if
        (
            Pstream::parRun()
        && Pstream::defaultCommsType == Pstream::nonBlocking
        )
        {
            Pstream::waitRequests(nReq);
        }

        forAll(*this, patchi)
        {
            this->operator[](patchi).evaluate(Pstream::defaultCommsType);
        }
    }
    else if (Pstream::defaultCommsType == Pstream::scheduled)
    {
        const lduSchedule& patchSchedule =
            bmesh_.mesh().globalData().patchSchedule();

        forAll(patchSchedule, patchEvali)
        {
            if (patchSchedule[patchEvali].init)
            {
                this->operator[](patchSchedule[patchEvali].patch)
                    .initEvaluate(Pstream::scheduled);
            }
            else
            {
                this->operator[](patchSchedule[patchEvali].patch)
                    .evaluate(Pstream::scheduled);

            }
        }
    }
    else
    {
        FatalErrorIn("GeometricBoundaryField::evaluate()")
            << "Unsuported communications type "
            << Pstream::commsTypeNames[Pstream::defaultCommsType]
            << exit(FatalError);
    }
}



openfoammaofnepo April 10, 2014 06:32

Dear Dr Jasak,

The second item you mentioned:

Code:

updateCoeffs()
is just to set the bool quantity update() to be true, no any math manipulations are done in this function. Is my understanding correct?

OFFO


Quote:

Originally Posted by hjasak (Post 473051)
Easy:
- on correctBoundaryConditions() for a field
- on updateCoeffs() at matrix creation

correctBoundaryConditions is also called after the linear solver call automatically.


Enjoy,

Hrv


peteryuan April 16, 2014 17:54

my understanding so far is:

Those BC types that need updating and evaluation at each time step, they either have updateCoeffs() or evaluate() in the class definition, virtual of course.
When a fvMatrix<type> Eqn is created, the updateCoeffs() is called in its constructor. Then in Eqn().solve() the function correctBoundaryConditions() is called, which contains evaluate().
Now the two functions are implemented differently in every BC, and the solver would also execute different things out according to each BC type defined.

Thanks for corrections and improvement.
peter

abtinansari December 19, 2014 01:26

My understanding is that functions like updateCoeffs() and evaluate() are defined first in the upper code level virtually like in GeometricBoundaryField.C and overloaded(redefined) later in specific derived classes where actual math manipulation is done. For example lets look at fixedGradientFvPatchField.C in /src/finiteVolume/fields/fvPatchFields/basic/fixedGradient :

template<class Type>
void fixedGradientFvPatchField<Type>::evaluate(const Pstream::commsTypes)
{
if (!this->updated())
{
this->updateCoeffs();
}

Field<Type>::operator=
(
this->patchInternalField() + gradient_/this->patch().deltaCoeffs()
);

fvPatchField<Type>::evaluate();
}

Here , the value is updated based on specified gradient in BC file. Can somebody please verify since I'm I also new to C++?

openfoammaofnepo December 19, 2014 12:38

I think what you said is correct. :D

Quote:

Originally Posted by abtinansari (Post 524615)
My understanding is that functions like updateCoeffs() and evaluate() are defined first in the upper code level virtually like in GeometricBoundaryField.C and overloaded(redefined) later in specific derived classes where actual math manipulation is done. For example lets look at fixedGradientFvPatchField.C in /src/finiteVolume/fields/fvPatchFields/basic/fixedGradient :

template<class Type>
void fixedGradientFvPatchField<Type>::evaluate(const Pstream::commsTypes)
{
if (!this->updated())
{
this->updateCoeffs();
}

Field<Type>::operator=
(
this->patchInternalField() + gradient_/this->patch().deltaCoeffs()
);

fvPatchField<Type>::evaluate();
}

Here , the value is updated based on specified gradient in BC file. Can somebody please verify since I'm I also new to C++?


kkamau April 2, 2019 12:30

How to call updateCoeff on UEqn. I tried UEqn.updateCoeff() but openfoam returned a compiler error

gaza February 11, 2020 04:28

Quote:

Originally Posted by openfoammaofnepo (Post 473156)
About the updateCoeffs in the turbulentInlet boundary conditions

Code:

OpenFOAM/OpenFOAM-2.1.1/src/finiteVolume/fields/fvPatchFields/derived/turbulentInlet
It has the following specific forms:
Code:

template<class Type>
void turbulentInletFvPatchField<Type>::updateCoeffs()
{
    if (this->updated())
    {
        return;
    }

    if (curTimeIndex_ != this->db().time().timeIndex())
    {
        Field<Type>& patchField = *this;

        Field<Type> randomField(this->size());

        forAll(patchField, facei)
        {
            ranGen_.randomise(randomField[facei]);
        }

        // Correction-factor to compensate for the loss of RMS fluctuation
        // due to the temporal correlation introduced by the alpha parameter.
        scalar rmsCorr = sqrt(12*(2*alpha_ - sqr(alpha_)))/alpha_;

        patchField =
            (1 - alpha_)*patchField
          + alpha_*
            (
                referenceField_
              + rmsCorr*cmptMultiply
                (
                    randomField - 0.5*pTraits<Type>::one,
                    fluctuationScale_
                )*mag(referenceField_)
            );

        curTimeIndex_ = this->db().time().timeIndex();
    }

    fixedValueFvPatchField<Type>::updateCoeffs();
}

In the above mentioned codes, the updateCoeffs() from the fixedValue boundary conditions type is used

Code:

fixedValueFvPatchField<Type>::updateCoeffs();
What is the role of this line? in the source files for fixedValue, I did not find any information about the relevant definitions there. Could anybody share some information about this problem? Thank you so much.

++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++
As a record how I understand this, I put the answer here:

evaluate() is defined in

Code:

src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C
The structure is:

Code:

template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricBoundaryField::
evaluate()
{
    if (debug)
    {
        Info<< "GeometricField<Type, PatchField, GeoMesh>::"
              "GeometricBoundaryField::"
              "evaluate()" << endl;
    }

    if
    (
        Pstream::defaultCommsType == Pstream::blocking
    || Pstream::defaultCommsType == Pstream::nonBlocking
    )
    {
        label nReq = Pstream::nRequests();

        forAll(*this, patchi)
        {
            this->operator[](patchi).initEvaluate(Pstream::defaultCommsType);
        }

        // Block for any outstanding requests
        if
        (
            Pstream::parRun()
        && Pstream::defaultCommsType == Pstream::nonBlocking
        )
        {
            Pstream::waitRequests(nReq);
        }

        forAll(*this, patchi)
        {
            this->operator[](patchi).evaluate(Pstream::defaultCommsType);
        }
    }
    else if (Pstream::defaultCommsType == Pstream::scheduled)
    {
        const lduSchedule& patchSchedule =
            bmesh_.mesh().globalData().patchSchedule();

        forAll(patchSchedule, patchEvali)
        {
            if (patchSchedule[patchEvali].init)
            {
                this->operator[](patchSchedule[patchEvali].patch)
                    .initEvaluate(Pstream::scheduled);
            }
            else
            {
                this->operator[](patchSchedule[patchEvali].patch)
                    .evaluate(Pstream::scheduled);

            }
        }
    }
    else
    {
        FatalErrorIn("GeometricBoundaryField::evaluate()")
            << "Unsuported communications type "
            << Pstream::commsTypeNames[Pstream::defaultCommsType]
            << exit(FatalError);
    }
}



Hi
I am trying to see a value of a variable inside BC.
I tried standard Info statement:
Code:

Info<< "variable = " << variable << endl;
but it does not give any output in log file.
I tried also
Code:

if (debug)

{
  Info<< "GeometricField<Type, PatchField, GeoMesh>::"             
    "GeometricBoundaryField::"
    "evaluate()" << endl;
}

but it does not work either. Can anybody help?


All times are GMT -4. The time now is 07:02.