CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > OpenFOAM Programming & Development

Understanding code of inletOutlet / outletInlet

Register Blogs Members List Search Today's Posts Mark Forums Read

Like Tree6Likes
  • 5 Post By ngj
  • 1 Post By Tobi

Reply
 
LinkBack Thread Tools Display Modes
Old   May 4, 2013, 09:54
Default Understanding code of inletOutlet / outletInlet
  #1
Senior Member
 
HECKMANN Frédéric
Join Date: Jul 2010
Posts: 236
Rep Power: 8
fredo490 is on a distinguished road
Hello everybody,
I would like to create a new boundary condition derived from the outletInlet. I want a "zeroGradient" as outlet and a "slip" / "symmetry" as inlet. But before coding this, I went to study the source code of inletOutlet and outletInlet.

I know that depending of the sign of "phi" (flux on the patch field), the code switch from one or the other boundary. However, I cannot understand the piece of code in charge of this process.

For the inletOutlet:
(opt/openfoam220/src/finiteVolume/fields/fvPatchFields/derived/inletOutlet/inletOutletFvPatchField.C)
Code:
template<class Type>
Foam::inletOutletFvPatchField<Type>::inletOutletFvPatchField
(
    const fvPatch& p,
    const DimensionedField<Type, volMesh>& iF,
    const dictionary& dict
)
:
    mixedFvPatchField<Type>(p, iF),
    phiName_(dict.lookupOrDefault<word>("phi", "phi")) // get the flux name
{
    this->refValue() = Field<Type>("inletValue", dict, p.size()); // get the desired fixed value at the inlet

    if (dict.found("value")) // ??? if the flux go outside the domain ???
    {
        fvPatchField<Type>::operator=
        (
            Field<Type>("value", dict, p.size()) // the patch get the field value 
        );
    }
    else // ??? if the flux go inside the domain ???
    {
        fvPatchField<Type>::operator=(this->refValue()); // the patch get the desired fixed value
    }

    this->refGrad() = pTraits<Type>::zero; // set the zero gradient vector
    this->valueFraction() = 0.0; // ??? for multiphase flow ? ???
}
And for the outletInlet
(opt/openfoam220/src/finiteVolume/fields/fvPatchFields/derived/inletOutlet/inletOutletFvPatchField.C)
Code:
template<class Type>
Foam::outletInletFvPatchField<Type>::outletInletFvPatchField
(
    const fvPatch& p,
    const DimensionedField<Type, volMesh>& iF,
    const dictionary& dict
)
:
    mixedFvPatchField<Type>(p, iF),
    phiName_(dict.lookupOrDefault<word>("phi", "phi")) // get the flux name
{
    this->refValue() = Field<Type>("outletValue", dict, p.size()); // get the desired fixed value at the inlet

    if (dict.found("value")) // ??? if the flux go inside the domain ???
    {
        fvPatchField<Type>::operator=
        (
            Field<Type>("value", dict, p.size()) // the patch get the field value 
        );
    }
    else // ??? if the flux go outside the domain ???
    {
        fvPatchField<Type>::operator=(this->refValue()); // the patch get the desired fixed value
    }

    this->refGrad() = pTraits<Type>::zero;  // set the zero gradient vector
    this->valueFraction() = 0.0; // ??? for multiphase flow ? ???
}
My problem is that the same code should do two opposite things:
inletOutlet:
Code:
if (dict.found("value")) // ??? if the flux go outside the domain ???
outletInlet:
Code:
if (dict.found("value")) // ??? if the flux go inside the domain ???
The only difference I have found is in the member function.
inletOutlet:
Code:
template<class Type>
void Foam::inletOutletFvPatchField<Type>::updateCoeffs()
{
    if (this->updated())
    {
        return;
    }

    const Field<scalar>& phip =
        this->patch().template lookupPatchField<surfaceScalarField, scalar>
        (
            phiName_
        );

    this->valueFraction() = 1.0 - pos(phip); // The difference is here

    mixedFvPatchField<Type>::updateCoeffs();
}
outletInlet
Code:
template<class Type>
void Foam::outletInletFvPatchField<Type>::updateCoeffs()
{
    if (this->updated())
    {
        return;
    }

    const fvsPatchField<scalar>& phip =
        this->patch().template lookupPatchField<surfaceScalarField, scalar>
        (
            phiName_
        );

    this->valueFraction() = pos(phip); // The difference is here

    mixedFvPatchField<Type>::updateCoeffs();
}
Does anyone know how this code works ? I am a bit lost
fredo490 is offline   Reply With Quote

Old   May 6, 2013, 12:54
Default
  #2
Senior Member
 
HECKMANN Frédéric
Join Date: Jul 2010
Posts: 236
Rep Power: 8
fredo490 is on a distinguished road
a small up
fredo490 is offline   Reply With Quote

Old   June 12, 2013, 06:10
Default
  #3
New Member
 
pastilha's Avatar
 
Pedro Pastilha
Join Date: Mar 2013
Location: Madrid
Posts: 3
Rep Power: 4
pastilha is on a distinguished road
Hi,

I just started looking into this BC and I am also struggling a bit with the code.

In my case, I would like to apply a profile (which is dependant on patch point coordinates) when the flux is positive (entering the domain) and keep zeroGradient when the flux is negative (exiting the domain). I have already implemented the profile boundary condition as an fvPatchVectorField, but now I would like to (ambitiously) merge it with inletOutlet.

Frédéric, have you been able to shed some light into this? Anyone? Any help would be kindly appreciated. I will share anything I can work out on my own!

I've had a couple of half-witted yet successful atempts at customizing boundary conditions in the past (fvPatchVectorFields and fvPatchFields mostly), but clearly my feeble OpenFoam/C++ skills have reached a wall with this one...

Cheers,

Pedro
pastilha is offline   Reply With Quote

Old   June 12, 2013, 06:17
Default
  #4
Senior Member
 
HECKMANN Frédéric
Join Date: Jul 2010
Posts: 236
Rep Power: 8
fredo490 is on a distinguished road
Sorry, I haven't been able to learn more about it... I didn't really have time so I gave up. But if you succeed, please leave me a comment
fredo490 is offline   Reply With Quote

Old   June 12, 2013, 06:57
Default
  #5
Senior Member
 
Tobi's Avatar
 
Tobias Holzmann
Join Date: Oct 2010
Location: Leoben (Austria)
Posts: 1,100
Blog Entries: 6
Rep Power: 19
Tobi will become famous soon enough
Send a message via ICQ to Tobi Send a message via Skype™ to Tobi
Hi all,

that code you posted it not the code you Need couse you posted the Constructor of that function

Code:
 
// Constructor type with three arguments
 
Foam::inletOutletFvPatchField<Type>::inletOutletFvPatchField
(
    constfvPatch& ,                            // Argument 1                           
    const DimensionedField<Type, volMesh>& iF, // Argument 2
    const dictionary& dict                     // Argument 3
)
:
    mixedFvPatchField<Type>(p, iF),                         // init var
    phiName_(dict.lookupOrDefault<word>("phi", "phi"))    // init var
 
// Constructor functions - what to do at the beginning (if you create that class)
{
    this->refValue() = Field<Type>("inletValue", dict, p.size()); // inletOultet value
 
    if (dict.found("value"))        // looking if the user that the initial value; if yes do the following
    {
        fvPatchField<Type>::operator=
        (
            Field<Type>("value", dict, p.size())
        );
    }
    else      // if no - set the inletOutlet value
    {
        fvPatchField<Type>::operator=(this->refValue()); 
    }
 
    this->refGrad() = pTraits<Type>::zero;    
    this->valueFraction() = 0.0;                   
}
// Constructor functions end 
 
Here are the member functions for the class like:
 
Foam::inletOutletFvPatchField<Type>::calculate()
{
              // Here is the function you are searching for!
}
This step is working at the beginning of your solver. After you get into the iterations this steps never repeat.

What you Need is the correct or calculate function!!!

PS: You should learn how C++ and functions or classes are working. With that knowledge it s very easy to read the code!

So far
Tobi
Tobi is offline   Reply With Quote

Old   June 12, 2013, 07:54
Default
  #6
Senior Member
 
HECKMANN Frédéric
Join Date: Jul 2010
Posts: 236
Rep Power: 8
fredo490 is on a distinguished road
The member functions are given at the end of my first post (the 2 last code quotes):
Code:
void Foam::inletOutletFvPatchField<Type>::updateCoeffs()
...
And I can read and reread the functions, I still don't get how the function switch from one case of the other.

Edit, it is the OF 2.2 source code
fredo490 is offline   Reply With Quote

Old   June 12, 2013, 11:57
Default
  #7
Senior Member
 
Tobi's Avatar
 
Tobias Holzmann
Join Date: Oct 2010
Location: Leoben (Austria)
Posts: 1,100
Blog Entries: 6
Rep Power: 19
Tobi will become famous soon enough
Send a message via ICQ to Tobi Send a message via Skype™ to Tobi
/* - - - */

Last edited by Tobi; June 13, 2013 at 10:04. Reason: Delete entry due to nonsence
Tobi is offline   Reply With Quote

Old   June 12, 2013, 12:09
Default
  #8
Senior Member
 
HECKMANN Frédéric
Join Date: Jul 2010
Posts: 236
Rep Power: 8
fredo490 is on a distinguished road
No problem, thx anyway for trying to help me !
I will take a look again this summer when I have some free time.
fredo490 is offline   Reply With Quote

Old   June 12, 2013, 13:56
Default
  #9
ngj
Senior Member
 
Niels Gjoel Jacobsen
Join Date: Mar 2009
Location: Deltares, Delft, The Netherlands
Posts: 1,619
Rep Power: 25
ngj will become famous soon enoughngj will become famous soon enough
Hello Frederic,

All the "magic" happen in the parent class mixed<something>, which you will probably be able to find in the fvPatchField/basic folder, if I am not mistaken.

You are indeed pointing to the important point in the code, because the valueFraction field is essentially a switch between the Dirichlet and Neumann conditions. Again, if I recall correctly, then if the valueFraction takes a value of 1, then the Dirichlet condition is used, where the Neumann is used for a value of 0.

The
Code:
pos(phi)
returns either 0 or 1 depending on the sign of the argument, so the code does the spatial switch between Dirichlet and Neumann automatically for you each time step. Remember that on a boundary a positive flux (phi) means that the flux is outbound.

I hope that this has clarified some things.

Kind regards

Niels
ngj is offline   Reply With Quote

Old   June 13, 2013, 07:02
Default
  #10
Senior Member
 
Tobi's Avatar
 
Tobias Holzmann
Join Date: Oct 2010
Location: Leoben (Austria)
Posts: 1,100
Blog Entries: 6
Rep Power: 19
Tobi will become famous soon enough
Send a message via ICQ to Tobi Send a message via Skype™ to Tobi
Hi Niels,

thanks for the replay.

Here I found the Definition of pos():
Code:
Positive (boolean)        pos(s)
scalar.H
Code:
00115 inline Scalar pos(const Scalar s)
00116 {
00117     return (s >= 0)? 1: 0;
00118 }
luiscardona likes this.

Last edited by Tobi; June 13, 2013 at 10:07.
Tobi is offline   Reply With Quote

Old   June 13, 2013, 12:45
Default
  #11
ngj
Senior Member
 
Niels Gjoel Jacobsen
Join Date: Mar 2009
Location: Deltares, Delft, The Netherlands
Posts: 1,619
Rep Power: 25
ngj will become famous soon enoughngj will become famous soon enough
Hi

I do know that some of the functions are outdated, but the following document (especially pp. 23-25) give a nice overview of the different functionalities and their return value:

http://sourceforge.net/p/openfoam-ex...mmersGuide.pdf

Kind regards

NIels
ngj is offline   Reply With Quote

Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
The FOAM Documentation Project - SHUT-DOWN holger_marschall OpenFOAM 242 March 7, 2013 13:30
understanding kEpsilon model source code jet OpenFOAM Programming & Development 5 November 15, 2009 09:52
Understanding k-omega SST model source code tmhonka OpenFOAM Programming & Development 1 September 8, 2009 07:33
Design Integration with CFD? John C. Chien Main CFD Forum 19 May 17, 2001 15:56
What is the Better Way to Do CFD? John C. Chien Main CFD Forum 54 April 23, 2001 08:10


All times are GMT -4. The time now is 17:43.