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

If-else looping issue

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

Reply
 
LinkBack Thread Tools Display Modes
Old   September 12, 2013, 10:47
Default If-else looping issue
  #1
Member
 
Tayo
Join Date: Aug 2012
Location: FL
Posts: 94
Rep Power: 5
tayo is on a distinguished road
I want to include if-else loop in my interPhaseChangeFoam solver. This is supposed to be easy but it's taking some time now. Below is an illustration of the code.

Code:
Foam::volScalarField Foam::phaseChangeTwoPhaseMixture::Random::dotAlpha() const
{
 const volScalarField& p = alpha1_.db().lookupObject<volScalarField>("p");
 volScalarField x = this->x();
 forAll(p, celli)
 {
   if (p[celli] <= pSat_.value())
   {
     return volScalarField
     (
       x/y_*(p - pSat_)*(1 - alpha1_)
     );
   else
   {
     return volScalarField
     (
       x*(p - pSat_)*alpha1_
     );
   }
 }
}
pSat_ and y_ are dimensionedScalar.

Notice that I didn't index volScalarfields p and x in the if-else statement because I noticed that indexing makes it dimensionless afterwards. It however compiles the way it is now (ofcourse not correct) but gives the warning "control reaches end of non-void function". Please how do I fix this if-else loop? Thanks in advance.

Last edited by wyldckat; September 15, 2013 at 17:43. Reason: fixed broken code delimiter from [\CODE] to [/CODE]
tayo is offline   Reply With Quote

Old   September 13, 2013, 17:11
Default
  #2
Senior Member
 
Joachim Herb
Join Date: Sep 2010
Posts: 295
Rep Power: 9
jherb is on a distinguished road
Your function returns in the first iteration of your for loop. You can create a temporary field in which you store your values and return that field (or a reference to it). (Perhaps also this bug report might be of interest what can go wrong http://www.openfoam.org/mantisbt/view.php?id=912 )
jherb is online now   Reply With Quote

Old   September 15, 2013, 15:07
Default
  #3
Member
 
Tayo
Join Date: Aug 2012
Location: FL
Posts: 94
Rep Power: 5
tayo is on a distinguished road
Quote:
Originally Posted by jherb View Post
Your function returns in the first iteration of your for loop. You can create a temporary field in which you store your values and return that field (or a reference to it). (Perhaps also this bug report might be of interest what can go wrong http://www.openfoam.org/mantisbt/view.php?id=912 )
Hi Jherb, I don't really get what you mean, Please explain with an example. Thank you
tayo is offline   Reply With Quote

Old   September 15, 2013, 16:09
Default
  #4
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
Also, since you do not modify x, I suggest that you make it into a const reference. The fact that you are copying x will also include some unnecessary overhead.

As already stated, you loop over all cells, but it is the value of the pressure in the first cell, which completely determines the outcome of your method. You should revise the location of your return statements.

Kind regards

Niels
__________________
Please note that I do not use the Friend-feature, so do not be offended, if I do not accept a request.
ngj is offline   Reply With Quote

Old   September 17, 2013, 13:34
Default
  #5
Member
 
Tayo
Join Date: Aug 2012
Location: FL
Posts: 94
Rep Power: 5
tayo is on a distinguished road
Thanks Niels & Joachim, I made the corrections to the loop and return statement as advised. The code now compiles.

Code:
Foam::volScalarField Foam::phaseChangeTwoPhaseMixture::Random::dotAlpha() const
{
 const volScalarField& p = alpha1_.db().lookupObject<volScalarField>("p");
 volScalarField x = this->x();
 forAll(p, celli)
 {
   if (p[celli] <= pSat_.value())
   {
       dotAlpha() = x/y_*(p[celli] - pSat_.value())*(1 - alpha1_);
   }
   else
   {
       dotAlpha() = x/y_*(p[celli] - pSat_.value())*alpha1_;
   }
 }
 return dotAlpha();
}
However, due to the indexing of pressure and pSat_, the dimension of the returned dotAlpha() becomes inconsistent. i.e. (p[celli] - pSat_.value()) in the equation becomes dimensionless. Because of this, it is not able to fully run. How do I ensure that dotAlpha() keeps the intended dimension after indexing p? Thanks
tayo is offline   Reply With Quote

Old   September 17, 2013, 13:55
Default
  #6
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
But you still change the entire field based on a single if statement on the pressure, so now it looks like the pressure in the final cell in the computational domain controls the return value.

I am, however, not certain, because there is some weird recursive nature going on with calls to dotAlpha() inside its own function, so in worst case it will scale with number of elements squared, do an immense amount of copying of memory and still return the wrong result.

As an easy starting point, you must initialise the return variable, populate the data in each element corresponding to each cell and then return the field. To initialise a vol-field, you could look in createFields.H in your favourite solver.

Kind regards

Niels
__________________
Please note that I do not use the Friend-feature, so do not be offended, if I do not accept a request.
ngj is offline   Reply With Quote

Old   September 18, 2013, 14:43
Default
  #7
Member
 
Tayo
Join Date: Aug 2012
Location: FL
Posts: 94
Rep Power: 5
tayo is on a distinguished road
Hi Niels, you're right. My earlier loop (though compiled0 was recursive and thus cannot run beyond the continuity equation in the first iteration. So to initialize dotAlpha, I created a volScalarField (mAlpha) in createfield.H as shown below.

Code:
volScalarField mAlpha
(
  IOobject
  (
    "mAlpha",
    runTime.time(),
    mesh,
    IOobject::NO_READ,
    IOobject::NO_WRITE
  ),
  mesh,
  dimensionedScalar("mAlpha",dimensionSet(1,-3,-1,0,0,0,0),0)
);
mAlpha is then computed in the loop below and returned so that it will be equal to dotAlpha(). However, when I compile this way, it indicates that "mAlpha is not declared in this scope". I don't know how to call mAlpha (from createfield.H) into the loop.

Code:
Foam::volScalarField Foam::phaseChangeTwoPhaseMixture::Random::dotAlpha() const
{
 const volScalarField& p = alpha1_.db().lookupObject<volScalarField>("p");
 volScalarField x = this->x();
 forAll(p, celli)
 {
   if (p[celli] <= pSat_.value())
   {
       mAlpha = x/y_*(p[celli] - pSat_.value())*(1 - alpha1_);
   }
   else
   {
       mAlpha = x/y_*(p[celli] - pSat_.value())*alpha1_;
   }
 }
 return mAlpha;
}
Attempts to call mAlpha in the loop has only led back to the recursive iteration. Please how do correct this? Also, kindly correct if you still notice any error in the way I'm looping. Thanks
tayo is offline   Reply With Quote

Old   September 21, 2013, 12:50
Default
  #8
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
Well, when you define the variable in createFields.H, it is out of scope (aka unknown) for your function. I merely referred to createFields.H for your inspiration.

The following should work, no optimally, but it will do what you need. Please note that I have not tried compiling it:

Code:
Foam::volScalarField foam::phaseChangeTwoPhaseMixture::Random::dotAlpha() const
{
  volScalarField mAlpha
  (
    IOobject
    (
       "mAlpha",
       alpha_.mesh().time().timeName(),
       alpha_.mesh(),
       IOobject::NO_READ,
       IOobject::NO_WRITE
    ),
    alpha_.mesh(),
    dimensionedScalar("null", dimensionSet(1,-3,1,0,0,0,0),0),
    "zeroGradient"
  );
 
  const volScalarField& p = alpha_.db().lookupObject<volScalarField>("p");
  const volScalarField& x = this->x();

  forAll (p, celli)
  {
    if (p[celli] <= pSat_.value())
    {
        mAlpha[celli] = x[celli]/y_[celli]*(p[celli] - pSat_.value())*(1 - alpha1_[celli]);
    }
    else
    {
        mAlpha[celli] = x[celli]/y_[celli]*(p[celli] - pSat_.value())*alpha_[celli];
    }
  }
  return mAlpha;
}
__________________
Please note that I do not use the Friend-feature, so do not be offended, if I do not accept a request.
ngj is offline   Reply With Quote

Old   September 24, 2013, 13:39
Default
  #9
Member
 
Tayo
Join Date: Aug 2012
Location: FL
Posts: 94
Rep Power: 5
tayo is on a distinguished road
Hi Niels, it worked after making some adjustments. Thank you .
tayo 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
Strange issue while launching ANSYS workbench in CentOS 6.4 Philip_C ANSYS 11 August 29, 2013 06:44
CyclicAMI Issue In OpenFOAM 2.2.0 prasant OpenFOAM Running, Solving & CFD 17 March 16, 2013 03:00
Pressure boundary condition issue Vijay FLUENT 0 April 6, 2012 13:35
Meshing related issue in Flow EFD appu FloEFD, FloWorks & FloTHERM 1 May 22, 2011 08:27
Issue 4 of adapco-online Sreenadh Jonnavithula Main CFD Forum 8 January 5, 2001 14:40


All times are GMT -4. The time now is 14:33.